ホーム < ゲームつくろー! < DirectX技術編(DirectSound)

その2 wavファイルから音を抽出:サンプルプログラム



 DirectX技術編DirectSoundその2「wavファイルから音を抽出」で説明した内容を踏まえたサンプルプログラムです。実行するとウィンドウが開き音が鳴ります。


サンプルスクリーンショット・・・音なのでね、何も出ないですよ(^-^;

 サンプルを動かすために必要なファイルはこちらからダウンロードできます(DSSmp_No2.lzh(2.58MB))。サイズが大きいのはテスト用のwavファイルが入っているためです。アーカイブに含まれているmain.cpp、waveファイルをプロジェクト直下に置いて、空のプロジェクトに実装ファイルを追加すると動かす事ができます。うまく動かない場合は掲示板にご連絡下さい。

 以下のコードをコピペしても動きます。可能な限りコードを削った「極短DirectSoundプログラム」です(^-^)

// 極短DirectSound基盤プログラム

#pragma comment ( lib, "dxguid.lib" )
#pragma comment ( lib, "dsound.lib" )
#pragma comment ( lib, "winmm.lib" )

#include <windows.h>
#include <tchar.h>
#include <dsound.h>
#include <mmsystem.h>

TCHAR gName[100] = _T("DirectSound Ultra Short Basical Program");

// Waveファイルオープン関数
bool openWave( TCHAR *filepath, WAVEFORMATEX &waveFormatEx, char** ppData, DWORD &dataSize ) {
        if ( filepath == 0 )
                return false;

        HMMIO hMmio = NULL;
        MMIOINFO mmioInfo;

        // Waveファイルオープン
        memset( &mmioInfo, 0, sizeof(MMIOINFO) );
        hMmio = mmioOpen( filepath, &mmioInfo, MMIO_READ );
        if( !hMmio )
                return false; // ファイルオープン失敗

        // RIFFチャンク検索
        MMRESULT mmRes;
        MMCKINFO riffChunk;
        riffChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E');
        mmRes = mmioDescend( hMmio, &riffChunk, NULL, MMIO_FINDRIFF );
        if( mmRes != MMSYSERR_NOERROR ) {
                mmioClose( hMmio, 0 );
                return false;
        }

        // フォーマットチャンク検索
        MMCKINFO formatChunk;
        formatChunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
        mmRes = mmioDescend( hMmio, &formatChunk, &riffChunk, MMIO_FINDCHUNK );
        if( mmRes != MMSYSERR_NOERROR ) {
                mmioClose( hMmio, 0 );
                return false;
        }
        DWORD fmsize = formatChunk.cksize;
        DWORD size = mmioRead( hMmio, (HPSTR)&waveFormatEx, fmsize );
        if( size != fmsize ) {
                mmioClose( hMmio, 0 );
                return false;
        }

        mmioAscend( hMmio, &formatChunk, 0 );

        // データチャンク検索
        MMCKINFO dataChunk;
        dataChunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
        mmRes = mmioDescend( hMmio, &dataChunk, &riffChunk, MMIO_FINDCHUNK );
        if( mmRes != MMSYSERR_NOERROR ) {
                mmioClose( hMmio, 0 );
                return false;
        }
        *ppData = new char[ dataChunk.cksize ];
        size = mmioRead( hMmio, (HPSTR)*ppData, dataChunk.cksize );
        if(size != dataChunk.cksize ) {
                delete[] *ppData;
                return false;
        }
        dataSize = size;

        // ハンドルクローズ
        mmioClose( hMmio, 0 );

        return true;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam){
        if(mes == WM_DESTROY) {PostQuitMessage(0); return 0;}
        return DefWindowProc(hWnd, mes, wParam, lParam);
}

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
        MSG msg; HWND hWnd;
        WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, NULL, NULL,
                                  (HBRUSH)(COLOR_WINDOW+1), NULL, (TCHAR*)gName, NULL};
        if(!RegisterClassEx(&wcex)) return 0;

        if(!(hWnd = CreateWindow(gName, gName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
                        NULL, NULL, hInstance, NULL)))
                return 0;

        // Waveファイルオープン
        WAVEFORMATEX wFmt;
        char *pWaveData = 0;
        DWORD waveSize = 0;
        if ( !openWave( _T("Techno_1.wav"), wFmt, &pWaveData, waveSize ) )
                return 0;

        // サウンドデバイス作成
        IDirectSound8 *pDS8;
        DirectSoundCreate8(NULL, &pDS8, NULL);
        pDS8->SetCooperativeLevel(hWnd, DSSCL_PRIORITY);

        DSBUFFERDESC DSBufferDesc;
        DSBufferDesc.dwSize = sizeof(DSBUFFERDESC);
        DSBufferDesc.dwFlags = 0;
        DSBufferDesc.dwBufferBytes = waveSize;
        DSBufferDesc.dwReserved = 0;
        DSBufferDesc.lpwfxFormat = &wFmt;
        DSBufferDesc.guid3DAlgorithm = GUID_NULL;

        IDirectSoundBuffer *ptmpBuf = 0;
        IDirectSoundBuffer8 *pDSBuffer;
        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, DSBLOCK_ENTIREBUFFER ) ) {
                memcpy( lpvWrite, pWaveData, dwLength);
                pDSBuffer->Unlock( lpvWrite, dwLength, NULL, 0);
        }
        delete[] pWaveData; // 元音はもういらない

        ShowWindow(hWnd, nCmdShow);

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

        // メッセージ ループ
        do {
                if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { 
                        DispatchMessage(&msg);
                }
        }while(msg.message != WM_QUIT);

        pDSBuffer->Release();
        pDS8->Release();

   return 0;
}