1、 输入两路16bit 音频,分别0.5倍增益后混音。
2、 左声道audio 1sample 乘以 0.5 倍增益,右声道 audio 1 sample 乘以 0.5倍增益
左声道audio 2 sample 乘以 0.5 倍增益,右声道 audio 2 sample 乘以 0.5倍增益
3、 控制每个经过增益处理的的sample值不超过 S16范围(-32767 ,32767),因为增益可能是N倍,可能增益处理后超出S16范围。
4、 Output audio 左声道sample =audio 1 增益后的左声道sample + audio 2 增益后的左声道sample
Output audio 右声道sample =audio 1 增益后的右声道sample + audio 2 增益后的右声道sample
5、 如果outputaudio > MAX(32767),则gain = MAX/output
如果output audio < MIN(-32767),则gain = MIN/output
其他 gain = 1;
6、 Output audio sample乘以gain,得到混合后的sample值
样例代码
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#define SAMPLE_SIZE 4
#define SAMPLE_GAIN (2147483647.0f)
#define CHECK_MAX_VALUE(value) ((value > 32767) ? 32767 : value)
#define CHECK_MIN_VALUE(value) ((value < -32767) ? -32767 : value)
int MixAudio2(short* sourceData1, short* sourceData2, float fBackgroundGain, float fWordsGain, short *outputData) {
int const MAX = 32767;
int const MIN = -32767;
double f = 1.0;
float fLeftValue1 = 0;
float fRightValue1 = 0;
float fLeftValue2 = 0;
float fRightValue2 = 0;
float fLeftValue = 0;
float fRightValue = 0;
int output = 0;
int iIndex = 0;
/*audio source 1 left channel sample*/
fLeftValue1 = (float)(sourceData1[0]);
/*audio source 1 right channel sample*/
fRightValue1 = (float)(sourceData1[1]);
/*audio source 2 left channel sample*/
fLeftValue2 = (float)(sourceData2[0]);
/*audio source 2 right channel sample*/
fRightValue2 = (float)(sourceData2[1]);
//fprintf(stderr,"sample (%f,%f)(%f,%f).\n",
// fLeftValue1,fRightValue1,fLeftValue2,fRightValue2);
if((fLeftValue1 > 32767)||(fLeftValue1 < -32767))
fprintf(stderr,"sample (%f).\n",fLeftValue1);
if((fRightValue1 > 32767)||(fRightValue1 < -32767))
fprintf(stderr,"sample (%f).\n",fRightValue1);
if((fLeftValue2 > 32767)||(fLeftValue2 < -32767))
fprintf(stderr,"sample (%f).\n",fLeftValue2);
if((fRightValue2 > 32767)||(fRightValue2 < -32767))
fprintf(stderr,"sample (%f).\n",fRightValue2);
/*sample * gain*/
fLeftValue1 = fLeftValue1*fBackgroundGain;
fRightValue1 = fRightValue1*fBackgroundGain;
fLeftValue2 = fLeftValue2*fWordsGain;
fRightValue2 = fRightValue2*fWordsGain;
/*source sample domain(-32767,32767)*/
/*(sample * gain) may beyond this S16 domain*/
/*limit limit sample value in domain (-32767,32767)*/
fLeftValue1 = CHECK_MAX_VALUE(fLeftValue1);
fLeftValue1 = CHECK_MIN_VALUE(fLeftValue1);
fRightValue1 = CHECK_MAX_VALUE(fRightValue1);
fRightValue1 = CHECK_MIN_VALUE(fRightValue1);
fLeftValue2 = CHECK_MAX_VALUE(fLeftValue2);
fLeftValue2 = CHECK_MIN_VALUE(fLeftValue2);
fRightValue2 = CHECK_MAX_VALUE(fRightValue2);
fRightValue2 = CHECK_MIN_VALUE(fRightValue2);
/*mix source 1 and source 2 left channel sample*/
fLeftValue = fLeftValue1 + fLeftValue2;
/*mix source 1 and source 2 right channel sample*/
fRightValue = fRightValue1 + fRightValue2;
for (iIndex = 0; iIndex < 2; iIndex++)
{
/*multiply gain f*/
if (iIndex == 0) {
output = (int)(fLeftValue*f);
}
else {
output = (int)(fRightValue*f);
}
if (output>MAX)
{
/*change gain if mix sample is beyond S16 domain*/
f = (double)MAX / (double)(output);
output = MAX;
}
if (output<MIN)
{
/*change gain if mix sample is beyond S16 domain*/
f = (double)MIN / (double)(output);
output = MIN;
}
if (f<1)
{
f += ((double)1 - f) / (double)32;
}
outputData[iIndex] = (short)output;
}
return 1;
}