java归一化混音_改进型归一化混音算法

本文介绍了一种改进的归一化混音算法,适用于处理线性PCM格式的音频。通过调整衰减因子f,确保混合后的音频样本值在最大值MAX和最小值MIN之间,从而避免溢出。算法考虑了衰减后值溢出的情况,使得衰减因子变化更平滑,提高语言平滑度。
摘要由CSDN通过智能技术生成

改进型归一化混音算法

linear PCM格式的音频混音

音频混音的原理:量化的语音信号的叠加等价于空气中声波的叠加。

0818b9ca8b590ca3270a3433284dd417.png

反应到PCM音频数据上,也就是把同一个声道的数值进行简单的相加,但是这样同时会产生一个问题,那就是相加的结果可能会溢出,当然为了解决这个问题已经有很多方案了.

假设音频文件采样率、通道数、采样精度一样。

另外要注意的是,在源音频数据中是按照little-endian的顺序来排放的,PCM值为0表示没声音(振幅为0)。 源码如下:

bufferA 音频A的首地址

bufferB音频B的首地址

static void pcmAudioMix(SInt16 *bufferA, SInt16 *bufferB, UInt32 bufferLength){

char * sourseFile[2];

sourseFile[0] = (char *)bufferA;

sourseFile[1] = (char *)bufferB;

bufferLength *= 2;

Mix(sourseFile, 2, (char *)bufferB, bufferLength);

}

static void Mix(char ** sourseFile,int number,char *objectFile, UInt32 bufferLength){

//归一化混音

int const MAX = 32767;

int const MIN = -32768;

double f = 1;

int output;

for (int i = 0; i < bufferLength/2; i++)

{

int temp = 0;

for (int j = 0; j < number; j++)

{

char *point = sourseFile[j];

if (j == 0) {

int mixTemp = *(short *)(point + i*2);

temp += (int)(mixTemp);

}else{

temp += *(short *)(point + i*2);

}

}

output = (int)(temp * f);

if (output > MAX)

{

f = (double)MAX / (double)(output);

output = MAX;

}

if (output < MIN)

{

f = (double)MIN / (double)(output);

output = MIN;

}

if (f < 1)

{

//此处取SETPSIZE 为 32

f += ((double)1 - f) / (double)32;

}

*(short *)(objectFile + i*2) = (short)output;

}

}

算法如下所述:

1. f 初始化为1.

2.对于一帧中的样本按顺序处理:

(a) output[i] = mixing[i] × f.

(b) 如果output[i] > MAX,求得最大的 f0满足 output[i] × f0< MAX,然后 f = f0, output[i] = MAX.

(c) 如果output[i] < MIN,求得最大的 f0满足 output[i]×f0> MIN,然后 f = f0, output[i] = MIN.

3. 如果f < 1, 则f = f + STEPSIZE. 继续处理下一帧, 转2.

其中f为衰减因子,f0为新的衰减因子;mixing[]为所有音频流的某一帧线性叠加值,实际实现的时候如式(4)所示;output[]为归一化以后的输出帧. MAX为正的最大值;MIN 为负的最大值. STEPSIZE为f变化的步长,通常取为(1 − f)/16或者(1 − f)/32.

SETPSIZE为f的变化步长,通常的取值为(1-f)/VALUE其中(1-f)为固定值只是后面的VALUE值可以取8,16,32,64,128. SETPSIZE取值较大时,运算复杂度低,但语言平滑度不够细腻,STEPSIZE取值较小时,运算复杂度高,但语言平滑度比较细腻。

特别的,就是在衰减以后的值溢出的情况下,求新的衰减因子f0的方法不同,新的f0需要满足output[i]× f0< MAX或者output[i]× f0> MIN,而不是直接使用mixing[i].也就是说,使用衰减以后的值output[i]来计算f0,而不是原始值mixing[i],这样将使得衰减因子的变化更为平滑.

用数学来表达,S为溢出的一个样本值,在S × f仍然溢出的情况下,可以比较一下计算出来的新衰减因子的大小:假设是上溢,forig是原始算法计算出的新的衰减因子,则f`orig(S × f),所以(MAX/S)

参考文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值