直播系統原始碼,常見的混音演算法有哪些?

zhibo系統開發發表於2023-12-09

聲音是由於物體的振動對周圍的空氣產生壓力而傳播的一種壓力波,轉成電訊號後經過抽樣,量化,仍然是連續平滑的波形訊號,量化後的波形訊號的頻率與聲音的頻率對應,振幅與聲音的音量對應,在直播系統原始碼中,量化的語音訊號的疊加等價於空氣中聲波的疊加,所以當取樣率一致時,混音可以實現為將各對應訊號的取樣資料線性疊加。反應到直播系統原始碼的音訊資料上,也就是把同一個聲道的數值進行簡單的相加而問題的關鍵就是如何處理疊加後溢位問題。


所以在直播系統原始碼中進行混音之前要先保證需要混合的音訊 取樣率、通道數、取樣精度一樣。


一、平均法

將直播系統原始碼中的每一路的語音線性相加,再除以通道數,該方法雖然不會引入噪聲,但是隨著通道數成員的增多,各路語音的衰減將愈加嚴重。具體體現在隨著通道數成員的增多,各路音量會逐步變小。



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;  
    }  
}


以上就是直播系統原始碼,常見的混音演算法有哪些的全部內容了,更多內容歡迎關注後續的文章


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2999410/,如需轉載,請註明出處,否則將追究法律責任。

相關文章