「.wav再生(DirectSound)」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
<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&act=open&pageid=17&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&act=open&pageid=218&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
<GL/freeglut/freeglut.h></span></div>
<div><span style="font-size:small;">#include <mmsystem.h></span></div>
<div><span style="font-size:small;">#include <dsound.h></span></div>
<div><span style="font-size:small;">#include <stdio.h></span></div>
<div><span style="font-size:small;"><br /></span></div>
<div><span style="font-size:small;">#define SAFE_RELEASE(p)
{if(p){(p)->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,&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->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(
&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->CreateSoundBuffer(
&dsdesc,&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->SetFormat( &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(
&mSrcWaveFile,sizeof(mSrcWaveFile) );</span></div>
<div><span style="font-size:small;">ret = mmioDescend(
hSrc,&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(
&mSrcWaveFmt,sizeof(mSrcWaveFmt) );</span></div>
<div><span style="font-size:small;">ret = mmioDescend(
hSrc,&mSrcWaveFmt,&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<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->nChannels );</span></div>
<div><span style="font-size:small;">printf( "サンプリングレート =
%d\n",wf->nSamplesPerSec );</span></div>
<div><span style="font-size:small;">printf( "ビットレート =
%d\n",wf->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,&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,&mSrcWaveData,&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,&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(
&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->CreateSoundBuffer(
&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)->Lock(
0,mSrcWaveData.cksize,&pMem1,&dwSize1,&pMem2,&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)->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(&lpSecondary,FileName))Exit();</span></div>
<div><span style="font-size:small;">// 起動時の再生</span></div>
<div><span style="font-size:small;">lpSecondary->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(&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>