最近项目上需要混音算法,上网查阅了四种常用的混音算法,用python运行来做测试,测试完成的语音数据放在结尾可以下载

混音算法一:加权平均

这种方法很简单,直接将两个PCM样本相加,为了防止溢出再除以二,但是这种方式会导致声音细节丢失声音会变小,并且混入通道数越多,声音衰减越严重,毕竟原始音频直接右移了八位,实际测试下来也是如此,实现方法为:

for i in range(0,sample_nums):
    sig_out[i] = (sig1[i] +sig2[i])/2
#这里的sig_out为最终输出的PCM,sig1和sig2为原始数据,后面同理

混音算法二:newlc中的一段算法

这是网上流传很多的一种混音算法,公式为:C=A+B-(A*B/32767),我推理不出来,谁能推理一下这个公式请在下方留言,真是不知道啥意思,效果也不错,实现方式为:

for i in range(0,sample_nums):
    if( sig1[i] < 0 and sig2[i] < 0):
        sig_out[i] = sig1[i]+sig2[i] - (sig1[i] * sig2[i] / -(32767))
    else:
        sig_out[i] = sig1[i]+sig2[i] - (sig1[i] * sig2[i] / (32767))

混音算法三:自适应混音加权(衰减因子法)

这种方法的实现原理是先设定一个系数为1,设定为f,将PCM直接相加后乘以f,如果溢出,下一个样本就降低f,如果没有溢出,后面的样本计算时就增大f,达到一个动态调整的效果。实际测试效果也不错,但是直觉感觉这种方法PCM样本数越多越好,太少的话噪声可能比较大,实现代码如下:

for i in range(0,sample_nums):
    temp = sig1[i] + sig2[i]
    out_put = temp*f
    if(out_put>32767):
        f = 32767/(out_put)
        out_put = 32767

    if(out_put<-32768):
        f = -32768/(out_put)
        out_put = -32768
    
    if(f<1):
        f+=(1-f)/32
    sig_out[i] = out_put

混音算法四:时间片分割法

时间片分割法就是将两段音频交替混合,不做加减运算,实际测试这种方式噪音较大,实现方式如下:

for i in range(0,sample_nums):
    if(i%2 == 0):
        sig_out[i] = sig1[i]
    else :
        sig_out[i] = sig2[i]

测试完成的音频,wav1和wav2为原始数据,output1、2、3、4分别对应四种算法:mixAudio.rar

文章目录