音频播放处理(openal、dsound、waveout)

音量控制

WaveOut

WaveOut在音量上是左右声道单独控制的。

waveOutSetVolume(HWAVEOUT,DWORD);可以设定指定设备的音量。这是左右声道一起设置的,其左右声道的范围都是0x0000~0xFFFF。可以映射到0~100中,便于使用。

waveOutGetVolume(LPDWORD);可以得到当前音量。DWORD的低16位表示左声道的音量,高16位表示右声道的音量。

DSound

Dsound在音量上使用的单位是dB,可以使用公式映射成0~100。如果Dsound的音量为dsVol那么经过公式

pow(10, (double)dsVol/ 2000.0) * 100

之后就可以映射到PC机上的音量了。

IDirectSoundBuffer::GetVolume和IDirectSoundBuffer::SetVolume获取和设置buffer的音量。

OpenAl

alGetSourcef(…,AL_GAIN, …);获取音量,其得到的值是一个0.0~1.0之间的浮点型音量,扩大100倍即可在使用三者统一。

alSourcef(…,AL_GAIN, …);设置音量。

播放速度

三种渲染引擎都可以使用改变声音的采样频率来达到加快和减慢播放速度,然后这种方式会使音调改变,相应的会引入断断续续的噪音。前面提到播放缓冲区的大小选取,它是受采样率、声道数以及位宽影响的,也就是受nAvgBytesPerSec(比特率)影响,如果更换准备数据的时间大于BUFFERSIZE/nAvgBytesPerSec的值会产生很多噪音;如果远小于这个值那么会浪费缓冲区的空间。必须要注意的是使用改变频率来改变播放速率在WaveOut中不一定有效,它是和设备有关的,如果设备不支持那么是改变不了频率和速率的。其实WaveOut在频率和速率上分开的,都提供了相应的API,里面的实质具体是不是一样的不清楚;但是在Dsound、OpenAl中是没有找到单独设置速率的函数。另外播放的速率可以通过对PCM数据插值的软件方式来实现。

软混音

求和钳值C = A + B 对C进行检查溢出取最大或者最小值。在没有溢出的情况下得到的效果很好,没有对任何一个声音进行衰减,但是溢出均取最大值或者是最小值会引进噪音还有一些爆破声等。求和均值C = (A + B) / N 不需要做溢出处理,同时即使引入了噪音也会被柔化,简单的处理得到的效果很好;缺点是特别是多路情况下衰减太大,得到的音量较小 。衰减系数 A = A1 + A2 + A3 + … + AN; A = A * f; if A > MAX then f = MAX / A; A = MAX; endif if A < MIN then f = MIN / A; A = MIN; endif if f < 1 then f += (1-f) / 32 endif使用一个可变的衰减因子对语音进行衰减。这个衰减因子也就代表语音的权重,,衰减因子随着音频数据的变化而变化,所以称为自适应加权混音。当溢出时,衰减因子变小,使得溢出的数据在衰减后能够处于临界值以内,而在没有溢出时,又让衰减因子慢慢增大,使数据较为平缓的变化。该方法可以对多路音频进行混音。Newlc(好像是Symbian上的混音) if A < 0 and B < 0 then C = A + B + (A * B) / (2^(n-1) – 1); Otherwise C = A + B – (A * B) / 2^(n-1); endif其中n表示混音的音频采样使用的位宽,该算法是Newlc上用于Symbian的混音,效果也不错。

左右声道播放

单声道音频 对于可以硬件混音的引擎(Dsound/OpenAl),单声道音频实现左右声道播放是可以直接通过把另外一个声道的音量设为0即可。 Dsound可以使用IDirectSoundBuffer::SetPan设置左右声道的差值,如果把这个差值设置为当前的音量值即可把其中一个声道的音量设置为静音。 OpenAl可以设置听者或者是声音源的位置,例如设置声音源在(-1.0, 0.0, 0.0),那么就只有左声道有声音。可使用alSourcefv(m_uiSource, AL_POSITION, fPos);来设置。应该特别注意的是这仅且只能在单声道中有效。 至于WaveOut上述方法也是可以使用的,但是会有一个问题:播放多个声音的时候会出现只能左声道或者只能右声道输出。这是WaveOut直接操作设备的原因,而Dsound、OpenAl是对声音Buffer操作,多个声音播放时不会互相影响。 前面提到了立体声的左右声道数据存放,利用这个特点,单声道音频WaveOut可以通过插值改造成立体声道播放,将单声道音频只拷贝到立体声的左声道或者右声道来播放。

立体声音频

立体声道音频左声道或者右声道输出,可以把立体声道音频当做单声道播放,不过这样处理会丢掉其中一个声道的声音。这对于立体感不是很强的音频是没有太大的影响的。更好的处理办法是将两个声道进行混音成单声道的音频。这样的处理对于不管左右声道的音频是否有很大的延时或者多好的立体感都会得到一种很好的效果。处理过后的音频在单声道输出时除了没有那种立体感之外没有任何的差别。使用之前提到的软混音方法即可完成,下面是使用求和均值的混音处理示意图。

仅作为自己的总结~~~

可我,仍在旅行的路上徘徊。等待着每一辆经过的车,让我走到更远的地方。

音频播放处理(openal、dsound、waveout)

相关文章:

你感兴趣的文章:

标签云: