//以下为回放:
BOOL CRecord::StartPlay(WAVEFORMATEX waveFmt)
{
if (::waveOutOpen(&m_hWaveOut,WAVE_MAPPER,&waveFmt,(DWORD) WaveOutCallBackFunc,(DWORD)this,CALLBACK_FUNCTION)==MMSYSERR_NOERROR)
{
m_waveOutHdr.lpData          = (LPTSTR)m_lpWaveData ;
m_waveOutHdr.dwBufferLength  = m_dwWaveDataLen ;
m_waveOutHdr.dwBytesRecorded = 0 ;
m_waveOutHdr.dwUser          = 0 ;
m_waveOutHdr.dwFlags         = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
m_waveOutHdr.dwLoops         = 1;
m_waveOutHdr.lpNext          = NULL ;
m_waveOutHdr.reserved        = 0 ;


if (:: waveOutPrepareHeader (m_hWaveOut, &m_waveOutHdr, sizeof (WAVEHDR)) ==MMSYSERR_NOERROR)
{

if (:: waveOutWrite (m_hWaveOut, &m_waveOutHdr, sizeof (WAVEHDR)) ==MMSYSERR_NOERROR)
{

return TRUE;
}
}

}}
以下是停止回放:
CRecord::EndPlay()
{
::waveOutReset(m_hWaveOut); //执行到这里就停住了。
::waveOutUnprepareHeader (m_hWaveOut,&m_waveOutHdr,sizeof(WAVEHDR));
::waveOutClose(m_hWaveOut);
}
换成以下的代码也不行:
CRecord::EndPlay()
{
::waveOutUnprepareHeader (m_hWaveOut,&m_waveOutHdr,sizeof(WAVEHDR));//执行到这里也停住了。    ::waveOutReset(m_hWaveOut); 
::waveOutClose(m_hWaveOut);
}

解决方案 »

  1.   

    我曾经也遇到过这样的问题,解决如下:
    回调函数:void CALLBACK _waveInProc(
      HWAVEIN hwi,       
      UINT uMsg,         
      DWORD dwInstance,  
      DWORD dwParam1,    
      DWORD dwParam2     
    )
    {
    wchar_t strErr[100];memset(strErr,0,sizeof(strErr));
    WAVEHDR *wanHdr;
    DWORD dLen;
    MMRESULT ret;
    CPlayer *pPlayer;
    switch(uMsg)
    {
    case WIM_OPEN:
    break;
    case WIM_DATA:
    {
    wanHdr = (WAVEHDR*)dwParam1;
    pPlayer = (CPlayer*)wanHdr->dwUser;
    ::WriteFile((void*)pPlayer->m_hFile_TMP,wanHdr->lpData,wanHdr->dwBufferLength,
    &dLen,0);
    memset(wanHdr->lpData,0,512);
    if(!pPlayer->m_bStop)
    {
    if(ret = waveInAddBuffer(hwi,wanHdr,sizeof(WAVEHDR)))
    {
    waveInGetErrorTextW(ret,strErr,100);
    MessageBoxW(0,strErr,OLESTR("录音失败"),MB_OK | MB_ICONSTOP | MB_APPLMODAL);
    }
    }
    else
    {
    //pPlayer->_StopRecord(0);
    pPlayer->m_bStop = false;
    }
    }
    break;
    case WIM_CLOSE://PCMWAVEFORMAT
    break;
    }
    }
    结束:
    m_bStop = true;
    while(m_bStop)
        SleepEx(1000,TRUE);
    MMRESULT ret = waveInUnprepareHeader(m_hWavIn, &m_wavData, sizeof(WAVEHDR));
    ret = waveInStop(m_hWavIn);
    ret = waveInClose(m_hWavIn);
      

  2.   

    由于播放缓冲被系统锁定,必须等待系统播放完毕释放后才能调用waveOutReset()
      

  3.   

    谢谢!!!!!!!!!MSND里没有对waveIn**和waveOut**的一系列函数作详细的说明,
    也没有例子,所以对这些函数不是很了解。有没有一些现成录音方面的类?
      

  4.   

    http://www.vckbase.com/code/
    VC知识库 代码仓库 可以找到
      

  5.   


     tlg007() 我现在不是录音时有问题,而是回放的时候有问题。
     我从VCKBASE上下载的代码都不行。
      

  6.   

    你应该设置一个标志,在回调函数中根据这个标志的值(true/false)来决定是否继续锁定播放缓冲,
    你仔细看一下我的代码就会明白,否则回调函数始终锁定播放缓冲,没有机会来释放,所以::waveOutReset等函数就会停住。
      

  7.   

    我在回放之前就已经成功地调用了waveInReset和waveInClose()
    ,在回放时并没有调用回调函数也没有盥锁定播放缓冲的函数。
      

  8.   

    一般问题都出在回调函数里,因为调用::waveOutReset(m_hWaveOut);时,所有播放缓冲区被标志为完成,这时系统就会调用回调函数。如果你在回调函数里面又调用了waveOutPrepareHeader 和waveOutWrite ,变成又在播放缓冲队列里面加入了缓冲,这样就出问题了。
        所以可以在播放的回调函数里面设一个播放停止标志,在EndPlay里把该标志设为停止,而回调函数里可以判断该标志位,若为停止状态,则不再调用waveOutPrepareHeader 和waveOutWrite ,等到把所有未完成的缓冲区都播放完后就停止。
        你上面贴的代码只使用了单缓冲,这样播放时会有停顿吧?
      

  9.   

    dog_in_yellow(dog.in.yellow)回复的正是我所要的,非常感谢。
     我想知道你如何了解得那么详细,我翻遍MSDN也找不到相关的资料。
      

  10.   

    呵,有一段时间我一直在做声卡数据采集的工作,也曾经碰到类似的问题。MSDN对这些潜在的问题确实没有提及。你试试在google上搜索waveInReset或waveOutReset,应该可以找到一些相关的东西的,不过基本上都是英文的。