2012-04-03 11 views
0

「.wav」ファイルを再生するオーディオプレーヤーを構築していますが、waveOutOpen()APIから呼び出されるコールバック関数に問題があります。再生のための出力オーディオデバイスを開くwaveOutOpen()APIのコールバック関数

MMRESULT mRes = waveOutOpen(m_hWO,WAVE_MAPPER,&wFmt,(DWORD)&waveOutProc,(DWORD)this, CALLBACK_FUNCTION); 

コールバック関数の実装:

void CPlayWave::waveOutProc(HWAVEOUT m_hWO,UINT uMsg,DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) 
{ 
    MMRESULT mmRes; 
    CPlayWave *pPW = (CPlayWave*)dwInstance; 
    switch(uMsg) 
    { 
    case MM_WOM_DONE:  //playback finished 
     mmRes = waveOutUnprepareHeader(m_hWO, &pPW->m_WHdr, sizeof(WAVEHDR)); 
     if(mmRes!=MMSYSERR_NOERROR) 
     { 
      //error handling 
      ..... 
     } 
     mmRes = waveOutClose(m_hWO); 
     if(mmRes!=MMSYSERR_NOERROR) 
     { 
      //error handling 
      ..... 
     } 
     AfxMessageBox("Finished playing the file"); 
     m_bPlay = FALSE;  //boolean flag used for pausing 
     break; 
    case WIM_DATA: 
     //for recording completion 
     break; 
    } 
} 

問題はMM_WOM_DONEが決して発生しないと、コールバック関数は、再生後に呼び出されることはありませんですファイルが完成しました。コールバック関数の代わりにスレッドを使用する必要がある場合、コールバックスレッドを使用する方法(ネット上に見つからない)に関する簡単な例を教えてください。

また、waveOutReset()のドキュメントでは、すべてのバッファを閉じてシステムに戻るので、アプリケーションのStopボタンを処理するためにwaveOutReset()関数を使用しましたが、アプリケーションがフリーズしました。なぜこうなった?バッファがまだ再生のためにキューに入っている間、再生を停止する代替方法はありますか?

答えて

1

おそらくコールバック関数は、クラスCPlayWave自体のメソッドにはなりません。要求されたプロトタイプを使ってクラスから単純な関数でなければなりません。

void CALLBACK waveOutProc(HWAVEOUT m_hWO, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { 
    ... 
} 

waveOutOpen()を呼び出す前に、必ず宣言/定義する必要があります。また、関数名はポインタそのものであり、アンパサンド&は必要ありません。したがって、waveOutOpen()の呼び出しは、

MMRESULT mRes = waveOutOpen(m_hWO, WAVE_MAPPER, &wFmt, (DWORD_PTR) waveOutProc, (DWORD_PTR) this, CALLBACK_FUNCTION | WAVE_ALLOWSYNC); 
である必要があります。