.wav再生(DirectSound)

「.wav再生(DirectSound)」の編集履歴(バックアップ)一覧はこちら

.wav再生(DirectSound)」(2012/12/18 (火) 15:51:21) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p><strong>DirectSound で .wav を再生します。</strong></p> <div><strong>これまでと同様にウインドウハンドルを取得すれば</strong></div> <div><strong>freeglut と DirectSound を組み合わせて使用できます。</strong></div> <p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=17&amp;file=hellow.png" /></p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td> </td> </tr></tbody></table>
<p><strong>DirectSound で .wav を再生します。</strong></p> <div><strong>これまでと同様にウインドウハンドルを取得すれば</strong></div> <div><strong>freeglut と DirectSound を組み合わせて使用できます。</strong></div> <p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=218&amp;file=ds.png" /></p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td><span style="font-size:small;">#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")</span> <div><span style="font-size:small;">#pragma comment(lib,"winmm.lib")</span></div> <div><span style="font-size:small;">#pragma comment(lib,"dsound.lib")</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">#include &lt;GL/freeglut/freeglut.h&gt;</span></div> <div><span style="font-size:small;">#include &lt;mmsystem.h&gt;</span></div> <div><span style="font-size:small;">#include &lt;dsound.h&gt;</span></div> <div><span style="font-size:small;">#include &lt;stdio.h&gt;</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">#define SAFE_RELEASE(p) {if(p){(p)-&gt;Release();(p)=NULL;}}//安全に解放する</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">#define FileName L"test.wav"</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">#define WIDTH 320</span></div> <div><span style="font-size:small;">#define HEIGHT 240</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">HWND hWnd2=NULL;        //ウィンドウハンドル</span></div> <div><span style="font-size:small;">HINSTANCE hinstance;       //インスタンスのハンドル</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">LPDIRECTSOUND8 lpDS = NULL; // DirectSound8</span></div> <div><span style="font-size:small;">LPDIRECTSOUNDBUFFER lpPrimary = NULL; // プライマリサウンドバッファ</span></div> <div><span style="font-size:small;">LPDIRECTSOUNDBUFFER lpSecondary = NULL; // セカンダリサウンドバッファ</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">//ウィンドウを検索してHWNDとHINSTANCEを得る</span></div> <div><span style="font-size:small;">BOOL CALLBACK enumWindowsProc(HWND hWnd,LPARAM lParam)</span></div> <div><span style="font-size:small;">{</span></div> <div><span style="font-size:small;"> HANDLE hModule=(HANDLE)GetWindowLong(hWnd,GWL_HINSTANCE);</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;"> if(GetModuleHandle(NULL)==hModule){</span></div> <div><span style="font-size:small;">  wchar_t ClassName[256];</span></div> <div><span style="font-size:small;">  GetClassNameW(hWnd,ClassName,sizeof(ClassName)/sizeof(ClassName[0]));</span></div> <div><span style="font-size:small;">  if(wcsncmp(ClassName,L"FREEGLUT",wcslen(ClassName))==0){</span></div> <div><span style="font-size:small;">   hWnd2=hWnd;</span></div> <div><span style="font-size:small;">   hinstance=(HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE);</span></div> <div><span style="font-size:small;">   return FALSE;</span></div> <div><span style="font-size:small;">  }</span></div> <div><span style="font-size:small;"> }</span></div> <div><span style="font-size:small;"> return TRUE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// DirectSound初期化</span></div> <div><span style="font-size:small;">bool InitDS( void ){</span></div> <div><span style="font-size:small;">HRESULT ret;</span></div> <div><span style="font-size:small;">// DirectSound8を作成</span></div> <div><span style="font-size:small;">ret = DirectSoundCreate8( NULL,&amp;lpDS,NULL );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf("サウンドオブジェクト作成失敗\n");</span></div> <div><span style="font-size:small;">return false;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">// 強調モード</span></div> <div><span style="font-size:small;">ret = lpDS-&gt;SetCooperativeLevel( hWnd2,DSSCL_EXCLUSIVE|DSSCL_PRIORITY );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf("強調レベル設定失敗\n");</span></div> <div><span style="font-size:small;">return false;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">return true;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// プライマリサウンドバッファの作成</span></div> <div><span style="font-size:small;">bool CreatePrimaryBuffer( void ){</span></div> <div><span style="font-size:small;">HRESULT ret;</span></div> <div><span style="font-size:small;">WAVEFORMATEX wf;</span></div> <div><span style="font-size:small;">// プライマリサウンドバッファの作成</span></div> <div><span style="font-size:small;">DSBUFFERDESC dsdesc;</span></div> <div><span style="font-size:small;">ZeroMemory( &amp;dsdesc,sizeof(DSBUFFERDESC) );</span></div> <div><span style="font-size:small;">dsdesc.dwSize = sizeof( DSBUFFERDESC );</span></div> <div><span style="font-size:small;">dsdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;</span></div> <div><span style="font-size:small;">dsdesc.dwBufferBytes = 0;</span></div> <div><span style="font-size:small;">dsdesc.lpwfxFormat = NULL;</span></div> <div><span style="font-size:small;">ret = lpDS-&gt;CreateSoundBuffer( &amp;dsdesc,&amp;lpPrimary,NULL );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf("プライマリサウンドバッファ作成失敗\n");</span></div> <div><span style="font-size:small;">return false;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">// プライマリバッファのステータスを決定</span></div> <div><span style="font-size:small;">wf.cbSize = sizeof( WAVEFORMATEX );</span></div> <div><span style="font-size:small;">wf.wFormatTag = WAVE_FORMAT_PCM;</span></div> <div><span style="font-size:small;">wf.nChannels = 2;</span></div> <div><span style="font-size:small;">wf.nSamplesPerSec = 44100;</span></div> <div><span style="font-size:small;">wf.wBitsPerSample = 16;</span></div> <div><span style="font-size:small;">wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8;</span></div> <div><span style="font-size:small;">wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;</span></div> <div><span style="font-size:small;">ret = lpPrimary-&gt;SetFormat( &amp;wf );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf("プライマリバッファのステータス失敗\n");</span></div> <div><span style="font-size:small;">return false;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">return true;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// サウンドバッファの作成</span></div> <div><span style="font-size:small;">BOOL CreateSoundBuffer( LPDIRECTSOUNDBUFFER *dsb,LPWSTR file )</span></div> <div><span style="font-size:small;">{</span></div> <div><span style="font-size:small;">HRESULT ret;</span></div> <div><span style="font-size:small;">MMCKINFO mSrcWaveFile;</span></div> <div><span style="font-size:small;">MMCKINFO mSrcWaveFmt;</span></div> <div><span style="font-size:small;">MMCKINFO mSrcWaveData;</span></div> <div><span style="font-size:small;">LPWAVEFORMATEX wf;</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// WAVファイルをロード</span></div> <div><span style="font-size:small;">HMMIO hSrc;</span></div> <div><span style="font-size:small;">hSrc = mmioOpen( file,NULL,MMIO_ALLOCBUF|MMIO_READ|MMIO_COMPAT );</span></div> <div><span style="font-size:small;">if( !hSrc ) {</span></div> <div><span style="font-size:small;">printf( "WAVファイルロードエラー\n");</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// 'WAVE'チャンクチェック</span></div> <div><span style="font-size:small;">ZeroMemory( &amp;mSrcWaveFile,sizeof(mSrcWaveFile) );</span></div> <div><span style="font-size:small;">ret = mmioDescend( hSrc,&amp;mSrcWaveFile,NULL,MMIO_FINDRIFF );</span></div> <div><span style="font-size:small;">if( mSrcWaveFile.fccType!=mmioFOURCC('W','A','V','E') ) {</span></div> <div><span style="font-size:small;">printf( "WAVEチャンクチェックエラー\n");</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// 'fmt 'チャンクチェック</span></div> <div><span style="font-size:small;">ZeroMemory( &amp;mSrcWaveFmt,sizeof(mSrcWaveFmt) );</span></div> <div><span style="font-size:small;">ret = mmioDescend( hSrc,&amp;mSrcWaveFmt,&amp;mSrcWaveFile,MMIO_FINDCHUNK );</span></div> <div><span style="font-size:small;">if( mSrcWaveFmt.ckid!=mmioFOURCC('f','m','t',' ') ) {</span></div> <div><span style="font-size:small;">printf( "fmt チャンクチェックエラー\n");</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// ヘッダサイズの計算</span></div> <div><span style="font-size:small;">int iSrcHeaderSize = mSrcWaveFmt.cksize;</span></div> <div><span style="font-size:small;">if( iSrcHeaderSize&lt;sizeof(WAVEFORMATEX) )</span></div> <div><span style="font-size:small;">iSrcHeaderSize=sizeof(WAVEFORMATEX);</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// ヘッダメモリ確保</span></div> <div><span style="font-size:small;">wf = (LPWAVEFORMATEX)malloc( iSrcHeaderSize );</span></div> <div><span style="font-size:small;">if( !wf ) {</span></div> <div><span style="font-size:small;">printf( "メモリ確保エラー\n");</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">ZeroMemory( wf,iSrcHeaderSize );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// WAVEフォーマットのロード</span></div> <div><span style="font-size:small;">ret = mmioRead( hSrc,(char*)wf,mSrcWaveFmt.cksize );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf( "WAVEフォーマットロードエラー\n");</span></div> <div><span style="font-size:small;">free( wf );</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">printf( "チャンネル数       = %d\n",wf-&gt;nChannels );</span></div> <div><span style="font-size:small;">printf( "サンプリングレート = %d\n",wf-&gt;nSamplesPerSec );</span></div> <div><span style="font-size:small;">printf( "ビットレート       = %d\n",wf-&gt;wBitsPerSample );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// fmtチャンクに戻る</span></div> <div><span style="font-size:small;">mmioAscend( hSrc,&amp;mSrcWaveFmt,0 );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// dataチャンクを探す</span></div> <div><span style="font-size:small;">while(1) {</span></div> <div><span style="font-size:small;">// 検索</span></div> <div><span style="font-size:small;">ret = mmioDescend( hSrc,&amp;mSrcWaveData,&amp;mSrcWaveFile,0 );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf( "dataチャンクが見つからない\n");</span></div> <div><span style="font-size:small;">free( wf );</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">if( mSrcWaveData.ckid==mmioStringToFOURCC(L"data",0) )</span></div> <div><span style="font-size:small;">break;</span></div> <div><span style="font-size:small;">// 次のチャンクへ</span></div> <div><span style="font-size:small;">ret = mmioAscend( hSrc,&amp;mSrcWaveData,0 );</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;">printf( "データサイズ       = %d\n",mSrcWaveData.cksize );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// サウンドバッファの作成</span></div> <div><span style="font-size:small;">DSBUFFERDESC dsdesc;</span></div> <div><span style="font-size:small;">ZeroMemory( &amp;dsdesc,sizeof(DSBUFFERDESC) );</span></div> <div><span style="font-size:small;">dsdesc.dwSize = sizeof( DSBUFFERDESC );</span></div> <div><span style="font-size:small;">dsdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STATIC | DSBCAPS_LOCDEFER;</span></div> <div><span style="font-size:small;">dsdesc.dwBufferBytes = mSrcWaveData.cksize;</span></div> <div><span style="font-size:small;">dsdesc.lpwfxFormat = wf;</span></div> <div><span style="font-size:small;">dsdesc.guid3DAlgorithm = DS3DALG_DEFAULT;</span></div> <div><span style="font-size:small;">ret = lpDS-&gt;CreateSoundBuffer( &amp;dsdesc,dsb,NULL );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf( "サウンドバッファの作成エラー\n");</span></div> <div><span style="font-size:small;">free( wf );</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// ロック開始</span></div> <div><span style="font-size:small;">LPVOID pMem1,pMem2;</span></div> <div><span style="font-size:small;">DWORD dwSize1,dwSize2;</span></div> <div><span style="font-size:small;">ret = (*dsb)-&gt;Lock( 0,mSrcWaveData.cksize,&amp;pMem1,&amp;dwSize1,&amp;pMem2,&amp;dwSize2,0 );</span></div> <div><span style="font-size:small;">if( FAILED(ret) ) {</span></div> <div><span style="font-size:small;">printf( "ロック失敗\n");</span></div> <div><span style="font-size:small;">free( wf );</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;">return FALSE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// データ書き込み</span></div> <div><span style="font-size:small;">mmioRead( hSrc,(char*)pMem1,dwSize1 );</span></div> <div><span style="font-size:small;">mmioRead( hSrc,(char*)pMem2,dwSize2 );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// ロック解除</span></div> <div><span style="font-size:small;">(*dsb)-&gt;Unlock( pMem1,dwSize1,pMem2,dwSize2 );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// ヘッダ用メモリを開放</span></div> <div><span style="font-size:small;">free( wf );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">// WAVを閉じる</span></div> <div><span style="font-size:small;">mmioClose( hSrc,0 );</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">return TRUE;</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">void Exit()</span></div> <div><span style="font-size:small;">{</span></div> <div><span style="font-size:small;">SAFE_RELEASE(lpSecondary);</span></div> <div><span style="font-size:small;">SAFE_RELEASE(lpPrimary);</span></div> <div><span style="font-size:small;">SAFE_RELEASE(lpDS);</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">void display(void)</span></div> <div><span style="font-size:small;">{</span></div> <div><span style="font-size:small;"> glClearColor(1.0, 1.0, 1.0, 1.0);</span></div> <div><span style="font-size:small;"> glClear(GL_COLOR_BUFFER_BIT);</span></div> <div><span style="font-size:small;"> glutSwapBuffers();</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">void init()</span></div> <div><span style="font-size:small;">{</span></div> <div><span style="font-size:small;">EnumWindows(enumWindowsProc,0);</span></div> <div><span style="font-size:small;">// DirectSound</span></div> <div><span style="font-size:small;">if(!InitDS())Exit();</span></div> <div><span style="font-size:small;">// プライマリサウンドバッファ</span></div> <div><span style="font-size:small;">if(!CreatePrimaryBuffer())Exit();</span></div> <div><span style="font-size:small;">// サウンドバッファ</span></div> <div><span style="font-size:small;">if(!CreateSoundBuffer(&amp;lpSecondary,FileName))Exit();</span></div> <div><span style="font-size:small;">// 起動時の再生</span></div> <div><span style="font-size:small;">lpSecondary-&gt;Play( 0,0,0 );</span></div> <div><span style="font-size:small;">}</span></div> <div><span style="font-size:small;"><br /></span></div> <div><span style="font-size:small;">int main(int argc, char *argv[])</span></div> <div><span style="font-size:small;">{</span></div> <div><span style="font-size:small;"> glutInitWindowPosition(100, 100);</span></div> <div><span style="font-size:small;"> glutInitWindowSize(WIDTH, HEIGHT);</span></div> <div><span style="font-size:small;"> glutInitDisplayMode(GLUT_RGBA);</span></div> <div><span style="font-size:small;"> glutInit(&amp;argc, argv);</span></div> <div><span style="font-size:small;"> glutCreateWindow("Hellow DirectSound World !!");</span></div> <div><span style="font-size:small;"> glutDisplayFunc(display);</span></div> <div><span style="font-size:small;"> init();</span></div> <div><span style="font-size:small;"> glutMainLoop();</span></div> <div><span style="font-size:small;"> Exit();</span></div> <div><span style="font-size:small;"> return 0;</span></div> <div><span style="font-size:small;">}</span></div> </td> </tr></tbody></table>

表示オプション

横に並べて表示:
変化行の前後のみ表示: