2010-05-25 64 views
6

我寫做動態範圍壓縮一個C#函數(即基本上南瓜的瞬間峯值和放大一切以產生總響亮聲音的音頻效果)。我已經寫了,這是否一個功能(我認爲):幫助與動態範圍壓縮功能(音頻)

alt text http://www.freeimagehosting.net/uploads/feea390f84.jpg

public static void Compress(ref short[] input, double thresholdDb, double ratio) 
{ 
    double maxDb = thresholdDb - (thresholdDb/ratio); 
    double maxGain = Math.Pow(10, -maxDb/20.0); 

    for (int i = 0; i < input.Length; i += 2) 
    { 
     // convert sample values to ABS gain and store original signs 
     int signL = input[i] < 0 ? -1 : 1; 
     double valL = (double)input[i]/32768.0; 
     if (valL < 0.0) 
     { 
      valL = -valL; 
     } 
     int signR = input[i + 1] < 0 ? -1 : 1; 
     double valR = (double)input[i + 1]/32768.0; 
     if (valR < 0.0) 
     { 
      valR = -valR; 
     } 

     // calculate mono value and compress 
     double val = (valL + valR) * 0.5; 
     double posDb = -Math.Log10(val) * 20.0; 
     if (posDb < thresholdDb) 
     { 
      posDb = thresholdDb - ((thresholdDb - posDb)/ratio); 
     } 

     // measure L and R sample values relative to mono value 
     double multL = valL/val; 
     double multR = valR/val; 

     // convert compressed db value to gain and amplify 
     val = Math.Pow(10, -posDb/20.0); 
     val = val/maxGain; 

     // re-calculate L and R gain values relative to compressed/amplified 
     // mono value 
     valL = val * multL; 
     valR = val * multR; 

     double lim = 1.5; // determined by experimentation, with the goal 
      // being that the lines below should never (or rarely) be hit 
     if (valL > lim) 
     { 
      valL = lim; 
     } 
     if (valR > lim) 
     { 
      valR = lim; 
     } 

     double maxval = 32000.0/lim; 

     // convert gain values back to sample values 
     input[i] = (short)(valL * maxval); 
     input[i] *= (short)signL; 
     input[i + 1] = (short)(valR * maxval); 
     input[i + 1] *= (short)signR; 
    } 
} 

,我有1.5和4.0之間10.0分貝30.0 db和比之間threshold值調用它。這個功能肯定會產生更大的整體聲音,但即使在低閾值和低比率下,失真度也不可接受。

任何人都可以看到什麼毛病這個功能呢?我是否正確處理立體聲方面(該功能假設爲立體聲輸入)?當我(模糊地)理解事情時,我不想分別壓縮這兩個通道,所以我的代碼試圖壓縮「虛擬」單聲道採樣值,然後分別對L和R採樣值應用相同程度的壓縮。然而,我不知道我做得對。

我認爲問題的一部分,可能我的功能,這在踢時突然超過閾值時壓縮的「硬拐點」。我想我可能需要使用「軟拐點」是這樣的:

alt text http://www.freeimagehosting.net/uploads/4c1040fda8.jpg

任何人可以提出一個修改我的函數產生膝軟曲線?

回答

1

我想你怎麼辦壓縮基本的認識是錯誤的(對不起;))。這不是「壓縮」單個樣本值;從根本上改變波形併產生嚴重的諧波失真。您需要評估許多樣本的輸入信號量(我必須通過Google獲取正確的公式),然後使用它來對輸入樣本應用更加漸變的乘數,以生成輸出。如果你有一個很難找到的常用技術

在kvraudio.com/forum的DSP論壇可能指向你在正確的方向。

+0

我對範圍壓縮的理解在0到100%之間。 :)在這個特定的情況下,我不能做平均(至少很容易),因爲我試圖應用壓縮來分離更大塊音頻的塊,然後無縫地將壓縮的塊合併在一起。不過,我認爲你是對的,我需要將乘數應用於更多的漸變,否則一次壓縮更大的部分。 – MusiGenesis 2010-05-26 15:53:00

+0

我已經簽出了KVR論壇。我在尋找這類事情的代碼示例時面臨的主要問題是,我發現幾乎所有的東西都是針對實時效果的,而我試圖處理現有的WAV文件。 – MusiGenesis 2010-05-26 15:56:49

+0

我剛想到一種方法,我可以用我的單獨塊進行平均。我非常感謝鏈接到任何良好的資源/代碼。 – MusiGenesis 2010-05-26 16:03:34