为什么WaveOutClose之后收不到WOM_CLOSE消息

sivenyu 2012-01-09 06:43:54
在用waveOutXXX接口写一个简单PCM播放器,用callback方式,点击播放按钮后,就准备4块缓存,写进去,然后再回调函数里收到WOM_DONE后继续写下一块,这样播放没有问题,但是完毕后就是收不到WOM_CLOSE,请问原因在哪?
...全文
154 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
blancell 2012-01-12
  • 打赏
  • 举报
回复
你把关闭的功能(waveOutClose( m_hWaveOut ),waveOutReset( m_hWaveOut ))放到回调函数外来
一下如何?
sivenyu 2012-01-09
  • 打赏
  • 举报
回复
后来参照AndyHai的《用Multi-Media Library制作流式音频播放器》http://www.cnblogs.com/AndyHai/archive/2007/07/07/809883.html
跑是能跑正确,但还是不知到原因,我写法和AndyHai的写法很接近了,都是另开一个线程负责写入数据的,因为我最终的应用要复杂一些,主要是流的源数据块先用链表存起来,然后在收到DONE消息后再写进去。

先谢过各位,还在求真解!
sivenyu 2012-01-09
  • 打赏
  • 举报
回复
我也想在waveOutClose之前调用waveOutReset,但是这样会卡死;如果直接调waveOutClose则返回十进制的33。我还试过更加不靠谱的,连WOM_DONE消息都收不到!真是郁闷。。。
sivenyu 2012-01-09
  • 打赏
  • 举报
回复
粘上代码:
void CMyWavePlayerDlg::OnBnClickedButtonPlayAndStop()
{
// TODO: Add your control notification handler code here

if(m_nPlayerState != PLAYING)
{
//---------------------------------------------------//
// To Play
//---------------------------------------------------//

m_waveformat.wFormatTag = WAVE_FORMAT_PCM;
m_waveformat.nChannels = 2;
m_waveformat.nSamplesPerSec = 44100;
m_waveformat.nAvgBytesPerSec = 44100*16*2/8;
m_waveformat.nBlockAlign = 4;
m_waveformat.wBitsPerSample = 16;
m_waveformat.cbSize = 0;
m_dwCurPosition = 44;// wave head size

if( ::waveOutGetNumDevs() <= 0 )
{
::MessageBox( NULL, _T("没有可用的音频设备!"), _T("错误"), MB_OK | MB_ICONERROR );
return;
}

if( MMSYSERR_NOERROR != ::waveOutOpen(&m_hWaveOut,WAVE_MAPPER,&m_waveformat(DWORD_PTR)waveOutProc,(DWORD_PTR)this,CALLBACK_FUNCTION ) )
{
::MessageBox( NULL, _T("不能打开音频设备!"), _T("错误"), MB_OK | MB_ICONERROR );
return;
}

::waveOutSetVolume( m_hWaveOut, 0xFFFFFFFF/2 );
for(int i=0; i<BUF_SUM; i++)
{
::memset(&m_header[i], 0, sizeof(WAVEHDR) );
m_header[i].lpData = &m_Buf[BUF_SIZE*i];

DWORD copySize = BUF_SIZE;
if(m_dwWaveSize-m_dwCurPosition < BUF_SIZE)
copySize = m_dwWaveSize-m_dwCurPosition;
memcpy(&m_Buf[BUF_SIZE*i], m_pWavBuffer+m_dwCurPosition, copySize);
m_header[i].dwBufferLength = copySize;
m_dwCurPosition += copySize;

::waveOutPrepareHeader( m_hWaveOut, &m_header[i], sizeof(WAVEHDR) );
::waveOutWrite( m_hWaveOut, &m_header[i], sizeof(WAVEHDR) );
}
m_CurBufIdx=0; //当前缓冲区索引


GetDlgItem(IDC_BUTTON_PLAY_AND_STOP)->SetWindowText(_T("Pause"));
m_nPlayerState = PLAYING;

}
else
{
//---------------------------------------------------//
// To Stop
//---------------------------------------------------//
//system("pause");

GetDlgItem(IDC_BUTTON_PLAY_AND_STOP)->SetWindowText(_T("Play"));

m_nPlayerState = STOP;
}
}


// 放音回调函数
void CALLBACK waveOutProc( HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
{
switch(uMsg)
{
case WOM_OPEN:
TRACE("WOM_OPEN\n");
break;
case WOM_CLOSE:
TRACE("WOM_CLOSE\n");
break;

case WOM_DONE:
{
TRACE("WOM_DONE - ");
LPWAVEHDR lpHdr = (LPWAVEHDR)dwParam1;
if(lpHdr == NULL)
return;

CMyWavePlayerDlg *pMainDlg = reinterpret_cast<CMyWavePlayerDlg*>(dwInstance);

::waveOutUnprepareHeader(m_hWaveOut, lpHdr, sizeof(WAVEHDR));
::memset(&m_header[m_CurBufIdx], 0 , sizeof(WAVEHDR));


DWORD copySize = BUF_SIZE;
if(pMainDlg->m_dwWaveSize - pMainDlg->m_dwCurPosition < BUF_SIZE)
copySize = pMainDlg->m_dwWaveSize - pMainDlg->m_dwCurPosition;
memcpy(&m_Buf[BUF_SIZE*m_CurBufIdx], pMainDlg->m_pWavBuffer+pMainDlg->m_dwCurPosition, copySize);

m_header[m_CurBufIdx].lpData = &m_Buf[BUF_SIZE*m_CurBufIdx];
m_header[m_CurBufIdx].dwBufferLength = copySize;

if( m_header[m_CurBufIdx].dwBufferLength <= 0 )
{
::waveOutClose( m_hWaveOut );
::waveOutReset( m_hWaveOut );
TRACE("end of the wav, closed!\n");
}

::waveOutPrepareHeader( m_hWaveOut, &m_header[m_CurBufIdx], sizeof(WAVEHDR) );
::waveOutWrite( m_hWaveOut, &m_header[m_CurBufIdx], sizeof(WAVEHDR) );
TRACE("render %d bytes!\n", copySize);

pMainDlg->m_dwCurPosition += copySize;
m_CurBufIdx++;
if( m_CurBufIdx == BUF_SUM )
m_CurBufIdx = 0;

}
}
}
Ei 2012-01-09
  • 打赏
  • 举报
回复
waveOutClose之前须调用waveOutReset
还有看看你的waveOutClose 返回值是什么
jazka346704803 2012-01-09
  • 打赏
  • 举报
回复
你说到收不到是通过那句trace来判断到吗?换其他方式试试,比如加入调试代码等,首先确认是没有收到这个消息。
woshi_ziyu 2012-01-09
  • 打赏
  • 举报
回复
应该会有 只是你没检测到
WOM_CLOSE message
waveOutOpen 函数说明

19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧