2012-04-03 118 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()文檔建議它關閉所有緩衝區並返回到系統,因此爲了處理我的應用程序中的停止按鈕,我使用了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);