最近开始做音频方面的一些编程,遇到一些问题,请教各位。程序的大致结构是:在主线程上调用WaveIn系列函数来控制音频设备,单开一个线程来处理音频消息,在MM_WIM_OPEN消息的处理过程中初始化缓冲区(waveInPrepareHeader),在MM_WIM_CLOSE消息的处理过程中释放缓冲区(waveInUnprepareHeader)。主要问题如下:1. 一定比例的测试中,waveInPrepareHeader会出错,错误是MMSYSERR_INVALHANDLE。请教原因。
2. WaveInReset之后,是不是应该等待所有缓冲区都被返回给应用程序之后,才能调用WaveInClose?缓冲区都被返回给应用程序是不是只是向音频线程发送MM_WIM_DATA消息而与是否对缓冲区调用waveInUnprepareHeader无关?在我的测试中,准备了十个缓冲区,若在WaveInReset之后立即WaveInClose,音频线程总是无法收到或只能收到几个MM_WIM_DATA消息。3. 根据上一个问题,WaveInOpen,WaveInReset,WaveInClose是否都是“非阻塞函数”,在设备完成相应的处理之前,函数就会返回?在我看来,这些函数的返回值无疑都是有意义的,那么这些函数就应该是“阻塞函数”。

解决方案 »

  1.   

    1、在调用之前,waveInUnprepareHeader 调用了没?2、我找到的代码是调用 waveInReset 之后 Sleep(500) 再调用 waveInClose;3、个人觉得是阻塞的。
      

  2.   

    1. 调用waveInPrepareHeader之前需要调用waveInUnprepareHeader么?
    2. 我这也是加了Sleep,如果不加的话,线程似乎会在调用WaveInClose时异常退出。
      

  3.   

    我也不大清楚这个技术细节,但是看到别人的成功的代码是调用了 Unprepare 的。
      

  4.   

    此问题已解决,经过测试:
    waveInUnprepareHeader,waveInPrepareHeader,waveInAddBuffer都只能在设备处于打开状态时使用,否则将出现错误:“指定的设备句柄无效”。
    调用waveInReset将导致所有缓冲区都返回给应用程序,即设备向音频消息处理过发送N个MM_WIM_DATA消息,N为调用waveInReset时设备中的缓冲区数量。waveInReset直至发送完所有消息(并非处理完)才返回。在设备返回所有缓冲区前,程序调用waveInClose将出现错误:播放媒体数据时,无法执行这项操作。请重置该设备,或等到数据播放完毕再执行。第一问题所述的waveInUnprepareHeader出现MMSYSERR_INVALHANDLE错误原因尚不清楚,一些不大可能的原因是设备前一次未正确关闭或距离上次关闭的时间过短。
      

  5.   

    waveInReset是阻塞函数,在其返回前,它会向音频处理线程发送所有的WM_WIM_DATA消息。
      

  6.   

    楼主好!
       我最近在写关于 网络语音通讯的功能 研究快3个星期了 也没什么进展 可否将您的代码发给我看看 万分感激 
       我的邮箱:[email protected]
               
    先谢了。
      

  7.   

    不错,原来函数waveInReset的调用是阻塞的