Algorithm to mix sound

后端 未结 20 2139
囚心锁ツ
囚心锁ツ 2020-11-29 16:55

I have two raw sound streams that I need to add together. For the purposes of this question, we can assume they are the same bitrate and bit depth (say 16 bit sample, 44.1k

20条回答
  •  广开言路
    2020-11-29 17:21

    Thank you everyone for sharing your ideas, recently i'm also doing some work related to sound mixing. I'm also have done experimenting thing on this issue, may it help you guys :).

    Note that i'm using 8Khz sample rate & 16 bit sample (SInt16) sound in ios RemoteIO AudioUnit.

    Along my experiments the best result i found was something different from all this answer, but the basic is the same (As Roddy suggest)

    "You should add them together, but clip the result to the allowable range to prevent over/underflow".

    But what should be the best way to adding without overflow/underflow ?

    Key Idea:: You have two sound wave say A & B, and the resultant wave C will the superposition of two wave A & B. Sample under limited bit range may cause it to overflow. So now we can calculate the maximum limit cross at the upside & minimum limit cross at the downside of the superposition wave form. Now we will subtract maximum upside limit cross to the upper portion of the superposition wave form and add minimum downside limit cross to the lower portion of the superposition wave form. VOILA ... you are done.

    Steps:

    1. First traverse your data loop once for the maximum value of upper limit cross & minimum value of lower limit cross.
    2. Make another traversal to the audio data, subtract the maximum value from the positive audio data portion and add minimum value to the negative portion of audio data.

    the following code would show the implementation.

    static unsigned long upSideDownValue = 0;
    static unsigned long downSideUpValue = 0;
    #define SINT16_MIN -32768
    #define SINT16_MAX 32767
    SInt16* mixTwoVoice (SInt16* RecordedVoiceData, SInt16* RealTimeData, SInt16 *OutputData, unsigned int dataLength){
    
    unsigned long tempDownUpSideValue = 0;
    unsigned long tempUpSideDownValue = 0;
    //calibrate maker loop
    for(unsigned int i=0;i 0)
        {
            OutputData[i] = summedValue - upSideDownValue;
        }
        else
        {
            OutputData[i] = summedValue;
        }
    }
    
    return OutputData;
    }
    

    it works fine for me, i have later intention gradually change the value of upSideDownValue & downSideUpValue to gain a smoother output.

提交回复
热议问题