处理MM_WIM_DATA消息的函数如下:
void CAudio2Dlg::OnMM_WIM_DATA(UINT wParam, LONG lParam) 
{
//open waveform audio for output
waveform.wFormatTag = WAVE_FORMAT_PCM;
waveform.nChannels = 1;
waveform.nSamplesPerSec =11025;
waveform.nAvgBytesPerSec=11025;
waveform.nBlockAlign =1;
waveform.wBitsPerSample =8;
waveform.cbSize =0;

if(!Outopen)
{
if (waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW))
{
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox("Audio output erro");
}
else Outopen = true;
} //////////////////////////////////////////////////////////////////////////
// Set up header
pWaveHdr1->lpData          = (LPTSTR)pSaveBuffer ;
pWaveHdr1->dwBufferLength  = dwDataLength ;
pWaveHdr1->dwBytesRecorded = 0 ;
pWaveHdr1->dwUser          = 0 ;
pWaveHdr1->dwFlags         = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
pWaveHdr1->dwLoops         = 1;
pWaveHdr1->lpNext          = NULL ;
pWaveHdr1->reserved        = 0 ; waveOutPrepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
waveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ; return ;


}

解决方案 »

  1.   

    // 输入输出设备在打开的时候,应该使用同一参数WAVEFORMATEXTENSIBLE
    void CAudio2Dlg::OnMM_WIM_DATA(UINT wParam, LONG lParam) 

        LPWAVEHDR pWaveIn = (LPWAVEHDR)lParam;
        ::waveInUnprepareHeader(m_deviceIn, pWaveIn, sizeof(WAVEHDR)); // 告诉录音设备该块内存暂不能使用     // 你的输出设备应该在外面打开(比如全局的), 要不然如果你的BUFFER很小,这一次根本不会播放出什么声音出来
         // 还有输入输出最好不要使用同一块内存, 这里另外分配一个同大小的内存pWaveOut给输出
        ::waveOutPrepareHeader(m_deviceOut, pWaveOut, sizeof(WAVEHDR));
        ::waveOutWrite(m_deviceOut, pWaveOut, sizeof(WAVEHDR));    // 把这块内存“还”给录音设备,不然它的内存块用完了,你也就录不成音了:(输出设备也同理)
        ::waveInPrepareHeader(m_deviceIn, pWaveIn, sizeof(WAVEHDR));
        ::waveInAddBuffer(m_deviceIn, pWaveIn, sizeof(WAVEHDR));
    }
      

  2.   

    TO 楼上:    ::waveOutPrepareHeader(m_deviceOut, pWaveOut, sizeof(WAVEHDR));
        ::waveOutWrite(m_deviceOut, pWaveOut, sizeof(WAVEHDR));
    为了效率就没有执行这个步骤,但是如果是这样是否会出现内存错误,但是并没有出现,还有如果单独分配内存那是不是没有必要,还有就是控制内存使用的同步问题可以单独加一个指示变量的
    // 把这块内存“还”给录音设备,不然它的内存块用完了,你也就录不成音了:(输出设备也同理)
        ::waveInPrepareHeader(m_deviceIn, pWaveIn, sizeof(WAVEHDR));
        ::waveInAddBuffer(m_deviceIn, pWaveIn, sizeof(WAVEHDR));这些我在播放完成这块内存的声音后执行
      

  3.   

    pWaveHdr1->dwBufferLength  = dwDataLength ; 
    pWaveHdr1->dwBytesRecorded = 0 ; 最先没仔细看你的代码,发现这两个参数设置错误!!!!!!
    pWaveHdr1->dwBufferLength  = dwDataLength ; // 这里应该为整个BUFFER的长度;
    pWaveHdr1->dwBytesRecorded = 0 ; // 这里为该BUFFER中实际存放的声音数据。你设置为“0”即表明没有数据,当然也不会播放声音了。
      

  4.   

    还有几个问题:1、你的输入输出设备应该用同样的“WAVEFORMATEXTENSIBLE”参数打开,否则你听到的只会是噪音;
    2、如果你连续录音并连续播放,并且不用“waveInUnprepareHeader”,那你在播放的这段内存随时可能被录音设备改写,你播放出来的也是一些声音碎片;
    3、你这段内存如果是通过消息参数传递过来的局部内存,小心在函数返回后被释放掉,导致程序崩溃;
    4、这两个参数至关重要:
    pWaveHdr1->dwBufferLength  = dwDataLength; 
    pWaveHdr1->dwBytesRecorded = dwDataLength; // 该数值大于“0”,放音设备才会播放声音出来
    5、其它问题就不说了:(