2010-05-25 28 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