混音算法的学习与研究

来源:互联网 发布:qq留言软件 编辑:程序博客网 时间:2024/05/16 02:32


混音算法的学习与研究

金庆 2007.10.31
(转载请注明来源于金庆的专栏)

想把原来一个旧程序中的混音算法改善一下,就大致研究了一下混音算法。

原来的混音是直接加和,因为音源音量很小,连溢出也没考虑。
出来的效果只能是大概有个响动,不过程序应用的领域只需达到这点就足够了。
现在音源音质改善了一点,有必要也对混音算法做点改进了。

主要还是曾经看到这样一篇混音新算法的转载文章[3],一直想应用一下。
再次翻到那篇文章,算法很简单,表达也很清晰,就是不知道原理。

算法简述如下:
For n-bit sampling audio signal
   If both A and B are negative       Y = A + B - (A * B / (-(2 pow(n-1) -1)))
   Else                               Y = A + B - (A * B / (2 pow(n-1))

注意代码与算法稍有不符。代码中两种情况都除以(-(2 pow(n-1) -1))),根据算法,大部分情况下都应该除以(2 pow(n-1))。是否减1有什么作用?如果不必减1,对于整数运算就可以用移位实现。

如果对多路混音该如何扩展算法呢?

算法的出处未注明,所以我搜索了一下,找到一篇论坛帖子(但与原文中引文并不一致):
http://www.dsprelated.com/showmessage/27372/1.php

从中可以看到,算法并没有什么数学根据,而且从两路扩展到多路效果并不好。回贴的没有一个赞同这一算法的。

看来不能盲目照搬没有根据的算法。

[3]中还有一个NOKIA的代码下载,根据所附链接,下载了这个NOKIA的例子,其中混音的代码在CMixerThread::FillBuffer()中,发现只是简单的加和再限值,没有什么利用价值。

后来终于找到该算法的出处:
http://newlc.com/topic-10064
作者自己说,该算法对于5个通道以上就不太好,算法的好处是不会溢出。但有人反映声音有饱和的趋向。

总结一下我对混音算法的学习,大概有以下几种方式:
1. 直接加和
2. 加和后再除以混音通道数,防止溢出
3. 加和并箝位,如有溢出就设最大值
4. 饱和处理,接近最大值时进行扭曲(“软件混音的实现”一文算法就是这类)
5. 归一化处理,全部乘个系数,使幅值归一化。(只适用于文件)
6. 衰减因子法,用衰减因子限制幅值[1]。

直接加和,或除以通道数的混音方法有严重缺陷,效果可能很差。箝位法最大混音数大约是4个,饱和处理最大混音数可能再高几个。对于大量的混音,应该采用衰减因子法。

文献[2]提出了一个自对齐权重法(align-to-self weighted,简称ASW),以一个时间帧为单位进行衰减,可能在帧之间有断续,效果应该不如平滑的衰减。

如果[1]中的衰减因子计算时能考虑整个时间片的数据,而不仅仅是当前点,那样效果会更好吧。

(转载请注明来源于金庆的专栏)

参考文献:
[1] 视频会议中关于混音算法的一些笔记
[2] 多媒体会议中的快速实时自适应混音方案研究 (PDF)
[3] 软件混音的实现 
点击打开链接

0 0