实现音频pcm数据播放(window平台)

    流程概述:初始化音频输出设备->往设备输入音频数据->关闭音频输出设备。

     流程解析:在播放流程中,音频输出设备只需要初始化一次,主要是配置音频参数,比如采样率、位宽、通道数、音频数据类型等;接着连续往此设备输入正确的音频数据,需要注意每次输入的数据长度是否有限制;播放完成后关闭音频输出设备,结束单次的音频播放。

    流程实现:window平台直接使用Winmm.dll库,库中提供现成的音频设备操作api,比如: waveOutOpenwaveOutClose等。本次使用中主要用到以下几个: waveOutGetNumDevs、waveOutOpenwaveOutResetwaveOutClosewaveOutPrepareHeaderwaveOutUnprepareHeaderwaveOutWrite。

    waveOutGetNumDevs获取播放设备个数,如果返回值为0,说明没有可用于播放输出的设备,接下来没必要执行其它与输出设备相关的操作了。
    waveOutOpen:初始化音频输出设备,包括设置采样率、位宽、通道数等参数,如果open成功,则可以获得输出设备对应的操作句柄,用于后续对此设备进行别的操作。
    waveOutReset:重置播放队列,将播放缓存清空,为接下来执行close做准备。
    waveOutClose:关闭音频输出设备,释放设备的控制权。
    waveOutPrepareHeader:将此段音频数据置为可播放状态,为接下来执行write做准备。
    waveOutUnprepareHeader将此段音频数据置为不可播放状态。
    waveOutWrite:将音频数据放入播放队列中。

    1、(初始化设备) waveOutGetNumDevs-> waveOutOpen->
    2、(输入数据)waveOutPrepareHeader->waveOutWrite->(重复此环节)
    3、(关闭设备)waveOutUnprepareHeader->waveOutReset->waveOutClose


    注意事项与建议:
1、 上述提到的api都自带互斥锁,必须防备死锁的出现,否则会导致播放阻塞。
2、 放入播放队列中的缓存不能立即取走或做其它用途,因为播放需要时间,只有在回调中抛出的缓存才是播放完成的。所以必须要有一个合适大小的缓存队列,以保证数据缓存与播放缓存两不误。

3、 执行 waveOutOpen 时建议注册回调函数,回调可以接收到相应的播放消息,比如每次(帧)数据播放完都会有 WOM_DONE消息,此时根据需要是否对已经使用完的资源回收。
4、音频播放速度是固定的(音频参数不变的情况下),为了减少出现因数据不及时(特别是实时的音频数据)出现的播放卡顿现象,建议增加音频数据缓存,比如一次性缓存到32k才放入播放队列等。

你可能感兴趣的:(程序设计原理)