sU32 __stdcall dsInit(DSIOCALLBACK *callback, void *parm, void *hwnd) { static const WAVEFORMATEX wfxprimary = { WAVE_FORMAT_PCM, 2, 44100, 44100*2*2, 2*2, 16, 0 }; //static const WAVEFORMATEX wfxprimary = { WAVE_FORMAT_PCM, 2, 48000, 48000*2*2, 2*2, 16, 0 }; static const DSBUFFERDESC primdesc = { sizeof(DSBUFFERDESC), DSBCAPS_PRIMARYBUFFER, 0, 0, 0 }; static const DSBUFFERDESC streamdesc = { sizeof(DSBUFFERDESC), DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS, BUFFERLEN, 0, (WAVEFORMATEX*)&wfxprimary }; ZeroMemory(&g_dsound, sizeof(g_dsound)); g_dsound.callback = callback; g_dsound.cbparm = parm; void *buf1, *buf2; DWORD len1, len2; if (DirectSoundCreate(0, &g_dsound.dssd, 0) != S_OK || // create DSound instance g_dsound.dssd->SetCooperativeLevel((HWND)hwnd, DSSCL_PRIORITY) != S_OK || // cooperative level g_dsound.dssd->CreateSoundBuffer(&primdesc, &g_dsound.pbuf, 0) != S_OK || // primary buffer g_dsound.dssd->CreateSoundBuffer(&streamdesc, &g_dsound.sbuf, 0) != S_OK || // secondary buffer g_dsound.pbuf->SetFormat(&wfxprimary) != S_OK || // set primary buf format g_dsound.sbuf->Lock(0, 0, &buf1, &len1, &buf2, &len2, DSBLOCK_ENTIREBUFFER) != S_OK) // lock secondary buf goto bad; // clear secondary buffer memset(buf1, 0, len1); memset(buf2, 0, len2); if (g_dsound.sbuf->Unlock(buf1, len1, buf2, len2) != S_OK) goto bad; g_dsound.bufcnt = -BUFFERLEN; g_dsound.ltg = -BUFFERLEN; g_dsound.tickev = CreateEvent(0, FALSE, FALSE, 0); g_dsound.exitev = CreateEvent(0, FALSE, FALSE, 0); InitializeCriticalSection(&g_dsound.crsec); if (g_dsound.sbuf->Play(0, 0, DSBPLAY_LOOPING) != S_OK) goto bad; dsSetVolume(1.0f); // start sound thread g_dsound.thndl = CreateThread(0, 0, threadfunc, 0, 0, &len1); SetThreadPriority(g_dsound.thndl, THREAD_PRIORITY_ABOVE_NORMAL); return 0; bad: dsClose(); return ~0u; }
//-------------------------------------------------------------------------------------------- // 関数名 : dsPlay_FadeIn // 作成者 : 植山沙欧 // 作成日 : 2002.06.24 // 機能 : フェードインで再生を開始します // 機能効果 : 「numBuffer」バッファを「dwPlayFlag」の形式で再生します // 引数 : <入力>numBuffer ロードするバッファ番号 // <入力>dwPlayFlag IDirectSoundBuffer8::Playの第三引数を指定します // 使用変数 : HRESULT hRet 戻り値を格納します // 使用関数 : IDirectSoundBuffer8::Play バッファデータを再生します // dsSetVolume ボリュームを調整します // 戻り値 : IDirectSoundBuffer8::Playの戻り値が返ります // 更新履歴 : 2002.06.24 Ver1.00 植山沙欧 機能の実現 // 2003.10.27 Ver1.01 植山沙欧 初期化されていない場合に呼び出すと // 不正処理になるバグを解消 //-------------------------------------------------------------------------------------------- HRESULT dsPlay_FadeIn(int numBuffer, DWORD dwPlayFlag, int iValue, bool restart) { HRESULT hRet = S_OK; // 初期化されていない場合は再生しない if(g_ds.sec_ptr[numBuffer] == NULL) { return DSERR_INVALIDCALL; } if (restart) { hRet = g_ds.sec_ptr[numBuffer]->Play(0, 0, dwPlayFlag); dsSetVolume(numBuffer, DS_VOLUME_MIN); g_sinfo[numBuffer].iVolume = DS_VOLUME_MIN; } g_sinfo[numBuffer].effectflag = eEFFECTDS_FADEIN; g_sinfo[numBuffer].iFade = iValue; return hRet; }
//-------------------------------------------------------------------------------------------- // 関数名 : dsPlay_Normal // 作成者 : 植山沙欧 // 作成日 : 2002.06.24 // 機能 : ロードしたバッファを再生します // 機能効果 : 「numBuffer」バッファを「dwPlayFlag」の形式で再生します // 引数 : <入力>numBuffer ロードするバッファ番号 // <入力>bLoop ループ再生するかどうか // 使用変数 : HRESULT hRet 戻り値を格納します // 使用関数 : dsLoadStream ストリーミングを行ないます // IDirectSoundBuffer8::Play バッファデータを再生します // dsSetVolume ボリュームを調整します // 戻り値 : IDirectSoundBuffer8::Playの戻り値が返ります // 更新履歴 : 2002.06.24 Ver1.00 植山沙欧 機能の実現 // 2003.10.27 Ver1.01 植山沙欧 初期化されていない場合に呼び出すと // 不正処理になるバグを解消 // 2007.02.09 Ver1.02 植山沙欧 再生フラグ設定方法の変更 //-------------------------------------------------------------------------------------------- HRESULT dsPlay_Normal(int numBuffer, bool bLoop) { HRESULT hRet; DWORD dwPlayFlag = 0; // 初期化されていない場合は再生しない if(g_ds.sec_ptr[numBuffer]==NULL) { return DSERR_INVALIDCALL; } // 再生 g_ds.sec_ptr[numBuffer]->SetCurrentPosition(0); if(bLoop || g_sinfo[numBuffer].bStream) { dwPlayFlag = DSBPLAY_LOOPING; } hRet = g_ds.sec_ptr[numBuffer]->Play(0, 0, dwPlayFlag); // ボリュームやエフェクトの初期化 dsSetVolume(numBuffer, DSBVOLUME_MAX); g_sinfo[numBuffer].bLoop = bLoop; g_sinfo[numBuffer].iVolume = DSBVOLUME_MAX; g_sinfo[numBuffer].effectflag = eEFFECTDS_NOTHING; return hRet; }
//-------------------------------------------------------------------------------------------- // 関数名 : dsCheck_Stream // 作成者 : 植山沙欧 // 作成日 : 2002.06.24 // 機能 : ストリーミングをチェックします // 必ず毎フレーム呼び出してください // 引数 : ありません // 使用変数 : int iCnt ループカウンタ // DWORD dwStatus 再生フラグを格納します // DWORD dwPos 再生ポジションを格納します // 使用関数 : IDirectSoundBuffer8::GetStatus バッファの状態を取得します // IDirectSoundBuffer8::GetCurrentPosition 現在のバッファの再生ポジションを取得します // dsLoadStream ストリームングを行ないます // dsStop 再生中のバッファを停止させます // dsSetVolume ボリュームを調整します(フェードイン、アウト用) // 戻り値 : ありません // 更新履歴 : 2002.06.24 Ver1.00 植山沙欧 機能の実現 // 2002.10.27 Ver1.01 植山沙欧 ストリーミングしないサウンドをサポート //-------------------------------------------------------------------------------------------- void dsCheck_Stream(void) { int iCnt; // ループカウンタ DWORD dwStatus; // 再生フラグを格納 DWORD dwPos; // 再生ポジションを格納 // 読み込みタイミングを調べる for(iCnt=0;iCnt<DS_MAX_BUFFER;iCnt++) { // 初期化が終わっていない場合 if(!g_ds.sec_ptr[iCnt]) { continue; } // エフェクトを管理 if(g_sinfo[iCnt].effectflag == eEFFECTDS_FADEOUT) { g_sinfo[iCnt].iVolume -= g_sinfo[iCnt].iFade;//DS_VALUE_FADE; if(g_sinfo[iCnt].iVolume < DS_VOLUME_MIN) { if (g_sinfo[iCnt].fadeout_stop) dsStop(iCnt); g_sinfo[iCnt].effectflag = eEFFECTDS_NOTHING; } dsSetVolume(iCnt, g_sinfo[iCnt].iVolume); } if(g_sinfo[iCnt].effectflag == eEFFECTDS_FADEIN) { g_sinfo[iCnt].iVolume += g_sinfo[iCnt].iFade;//DS_VALUE_FADE; if(g_sinfo[iCnt].iVolume > DSBVOLUME_MAX) { g_sinfo[iCnt].iVolume = DSBVOLUME_MAX; g_sinfo[iCnt].effectflag = eEFFECTDS_NOTHING; } dsSetVolume(iCnt, g_sinfo[iCnt].iVolume); } // ストリーミング再生が許可されていない if(!g_sinfo[iCnt].bStream) { continue; } // バッファは再生中かどうかを調べる g_ds.sec_ptr[iCnt]->GetStatus(&dwStatus); if(!(dwStatus & DSBSTATUS_PLAYING)) { continue; } // 読み込みタイミングかどうかをチェック g_ds.sec_ptr[iCnt]->GetCurrentPosition(&dwPos, NULL); // 再生ポジションフラグが0で、かつ0-11025なら22050-44100のデータを更新する。 if((g_sinfo[iCnt].iStreamPos == 0) && (dwPos > 0) && (dwPos < (g_ds.dwBufferSize / 2))) { dsLoadStream(iCnt, g_ds.dwBufferSize, 1); } // 再生ポジションフラグが1で、かつ22050-33075なら0-22050のデータを更新。 if((g_sinfo[iCnt].iStreamPos == 1) && (dwPos > g_ds.dwBufferSize)) { dsLoadStream(iCnt, 0, 0); } } }