声音是由于物体的振动对周围的空气产生压力而传播的一种压力波,转成电信号后经过抽样,量化,仍然是连续平滑的波形信号,量化后的波形信号的频率与声音的频率对应,振幅与声音的音量对应,在直播系统源码中,量化的语音信号的叠加等价于空气中声波的叠加,所以当采样率一致时,混音可以实现为将各对应信号的采样数据线性叠加。反应到直播系统源码的音频数据上,也就是把同一个声道的数值进行简单的相加而问题的关键就是如何处理叠加后溢出问题。
所以在直播系统源码中进行混音之前要先保证需要混合的音频 采样率、通道数、采样精度一样。
一、平均法
将直播系统源码中的每一路的语音线性相加,再除以通道数,该方法虽然不会引入噪声,但是随着通道数成员的增多,各路语音的衰减将愈加严重。具体体现在随着通道数成员的增多,各路音量会逐步变小。
public static short[] mixRawAudioBytes(short[][] inputAudios) { int coloum = finalLength;//最终合成的音频长度 // 音轨叠加 short[] realMixAudio = new short[coloum]; int mixVal; for (int trackOffset = 0; trackOffset < coloum; ++trackOffset) { mixVal = (inputAudios[0][trackOffset]+inputAudios[1][trackOffset])/2; realMixAudio[trackOffset] = (short) (mixVal); } return realMixAudio; }
二、归一化
全部乘个系数因子,使幅值归一化,但是个人认为这个归一化因子是不好确认的。
public static short[] mixRawAudioBytes(short[][] inputAudios) { int coloum = finalLength;//最终合成的音频长度 float f = divisor;//归一化因子 // 音轨叠加 short[] realMixAudio = new short[coloum]; float mixVal; for (int trackOffset = 0; trackOffset < coloum; ++trackOffset) { mixVal = (inputAudios[0][trackOffset]+inputAudios[1][trackOffset])*f; realMixAudio[trackOffset] = (short) (mixVal); } return realMixAudio; }
三、 改进后的归一化
使用可变的衰减因子对直播系统源码的语音进行衰减,该衰减因子代表了语音的权重,该衰减因子随着数据的变化而变化,当数据溢出时,则相应的使衰减因子变小,使后续的数据在衰减后处于临界值以内,没有溢出时,让衰减因子慢慢增大,使数据变化相对平滑。
public static short[] mixRawAudioBytes(short[][] inputAudios) { int coloum = finalLength;//最终合成的音频长度 float f = 1;//衰减因子 初始值为1 //混音溢出边界 int MAX = 32767; int MIN = -32768; // 音轨叠加 short[] realMixAudio = new short[coloum]; float mixVal; for (int trackOffset = 0; trackOffset < coloum; ++trackOffset) { mixVal = (inputAudios[0][trackOffset]+inputAudios[1][trackOffset])*f; if (mixVal>MAX){ f = MAX/mixVal; mixVal = MAX; } if (mixVal<MIN){ f = MIN/mixVal; mixVal = MIN; } if (f < 1) { //SETPSIZE为f的变化步长,通常的取值为(1-f)/VALUE,此处取SETPSIZE 为 32 VALUE值可以取 8, 16, 32,64,128. f += (1 - f) / 32; } realMixAudio[trackOffset] = (short) (mixVal); } return realMixAudio; }
四、newlc算法
if A < 0 && B < 0
Y = A + B - (A * B / (-(2 pow(n-1) -1)))
else
Y = A + B - (A * B / (2 pow(n-1))
void Mix(char sourseFile[10][SIZE_AUDIO_FRAME],int number,char *objectFile) { //归一化混音 int const MAX=32767; int const MIN=-32768; double f=1; int output; int i = 0,j = 0; for (i=0;i<SIZE_AUDIO_FRAME/2;i++) { int temp=0; for (j=0;j<number;j++) { temp+=*(short*)(sourseFile[j]+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) { f+=((double)1-f)/(double)32; } *(short*)(objectFile+i*2)=(short)output; } }
以上就是直播系统源码,常见的混音算法有哪些的全部内容了,更多内容欢迎关注后续的文章
标签:short,int,mixVal,trackOffset,直播,混音,coloum,inputAudios,源码 From: https://www.cnblogs.com/yunbaomengnan/p/17891102.html