DirectSoundでMFCリソースのwavを再生

[戻る]
sleep 2014/01/30(木) 22:05:13
VisualStudioを使って、表題のようなことをやろうとしています。

いろいろなサイトを見ても、wavファイルを開いて再生する方法はありましたが、
表題のことをやる手段についての言及があまりありませんでした。

どうすればできますでしょうか。

仲澤@失業者 2014/01/31(金) 15:06:55
「MFCリソース」とは何のことでしょう。
単にリソースのことでしょうか。
そのように仮定する場合、一般に

1.任意のファイルをリソースに入れるには「カスタムリソース」を使用する。

ことになります。カスタムリソースは「ユーザー定義リソース」とも言われます。
これをリソースから取り出すには、

2.FindResource()、LoadResource()、LockResource()等で、リソースに取り込んだ
 ファイルのバイナリデータの先頭ポインタが得られる。

という方法を使用します。
1.2.ができたら、とりあえずsndPlaySound()で鳴らしてみましょう。

sleep 2014/01/31(金) 20:43:20
お返事ありがとうございます。

MFCリソースという言い回しは適切ではいようですね。
失礼しました。
単にリソースのことです。

ご指摘いただきました関数を用いてコードを書き、今のところ、

HRSRC hr = FindResource(NULL, MAKEINTRESOURCE(IDR_WAVE1), _T("WAVE") );
HGLOBAL hg = LoadResource(NULL, hr);
LPCWSTR lpcwstr=(LPCWSTR)LockResource(hg);
sndPlaySound(lpcwstr, SND_MEMORY | SND_ASYNC);

によって、IDR_WAVE1に登録したリソースの音を鳴らすことができました。

ただし、音を鳴らしているときに別の音を同時に出そうとすると、
前からなっていた音が消えてしまいました。

forty-five 2014/02/03(月) 18:37:28
仲澤@失業者さんは「こうすればリソースからバイナリデータが取れるので、とりあえず 
sndPlaySound() を使ってテストしてみては?」とおっしゃっている訳で、
後は sleep さんが自分でおっしゃっている「wavファイルを開いて再生する方法」で実装
すれば良いだけですよ。
ファイルにしろリソースにしろ結局バイナリデータは同じな訳ですからね。

ITO 2014/02/05(水) 10:00:32
> ただし、音を鳴らしているときに別の音を同時に出そうとすると、
> 前からなっていた音が消えてしまいました。
うーーん、それは無理じゃないかと思います。
後から鳴らすファイルがあるなら最初に設定しておかないとだめだと思います。

sleep 2014/02/08(土) 11:08:14
[[解決]]
皆様、お騒がせいたしました。

下記のプログラムにより、DirectSoundで、リソースから音を鳴らすことができました。
いろいろなところからソースを引っ張ってきましたが、何とか読み解くことも
できました。

    IDirectSound8 *pDS8;
    IDirectSoundBuffer8 *pDSBuffer;
    char *pWaveData = 0;
    DWORD waveSize = 0;

    HRSRC hr = NULL;

    LPBYTE pWave = NULL;

    hr = FindResource(NULL, MAKEINTRESOURCE(IDR_WAVE1), _T("WAVE"));
    HGLOBAL hg = LoadResource(NULL, hr);
    pWave = (LPBYTE)LockResource(hg);
    int *pi = (int *)(pWave + 16);
    waveSize = *(int *)(pWave + 16 + *pi + 8);

    // サウンドデバイス作成

    DirectSoundCreate8(NULL, &pDS8, NULL);
    pDS8->SetCooperativeLevel(this->GetSafeHwnd(), DSSCL_PRIORITY);

    DSBUFFERDESC DSBufferDesc;
    DSBufferDesc.dwSize = sizeof(DSBUFFERDESC);
    DSBufferDesc.dwFlags = 0;
    DSBufferDesc.dwBufferBytes = waveSize;
    DSBufferDesc.dwReserved = 0;
    DSBufferDesc.lpwfxFormat = (LPWAVEFORMATEX)(pWave + 20);
    DSBufferDesc.guid3DAlgorithm = GUID_NULL;

    IDirectSoundBuffer *ptmpBuf = 0;

    pDS8->CreateSoundBuffer(&DSBufferDesc, &ptmpBuf, NULL);
    ptmpBuf->QueryInterface(IID_IDirectSoundBuffer8, (void**)&pDSBuffer);
    ptmpBuf->Release();
    if (pDSBuffer == 0) {
        pDS8->Release();
        return 0;
    }

    // セカンダリバッファにWaveデータ書き込み
    LPVOID lpvWrite = 0;
    DWORD dwLength = 0;
    if (DS_OK == pDSBuffer->Lock(0, 0, &lpvWrite, &dwLength, NULL, NULL, DSB
LOCK_ENTIREBUFFER)) {
        memcpy(lpvWrite, (LPSTR)(pWave + 16 + 4 + *pi + 8), dwLength);
        pDSBuffer->Unlock(lpvWrite, dwLength, NULL, 0);
    }

    // 再生
    pDSBuffer->Play(0, 0, 0);

ご協力、感謝いたします。
同時に複数の音を鳴らす方法は、自分なりに研究してみます。

古いスレッドには追加発言できません。