我正在编写一个用于进行动态范围压缩的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;
}
}
Run Code Online (Sandbox Code Playgroud)
我用threshold10.0 db到30.0 db之间的值和1.5到4.0之间的值来调用它.此功能肯定会产生更响亮的整体声音,但具有不可接受的失真水平,即使在低阈值和低比率时也是如此.
任何人都可以看到这个功能有什么问题吗?我是否正确处理立体声方面(该功能假定立体声输入)?当我(模糊地)理解事物时,我不想单独压缩两个通道,所以我的代码试图压缩"虚拟"单声道样本值,然后分别对L和R样本值应用相同程度的压缩.但是,不确定我做得对.
我认为问题的一部分可能是我的功能的"硬拐点",当超过阈值时,它突然开始压缩.我想我可能需要像这样使用"软膝盖":
alt text http://www.freeimagehosting.net/uploads/4c1040fda8.jpg
任何人都可以建议修改我的功能来产生柔软的膝盖曲线吗?
我认为您对如何进行压缩的基本理解是错误的(抱歉;))。这不是关于“压缩”单个样本值;而是关于“压缩”单个样本值。这将从根本上改变波形并产生严重的谐波失真。您需要评估许多样本的输入信号量(我必须通过 Google 搜索正确的公式),并使用它对输入样本应用更加渐进变化的乘数以生成输出。
如果您很难找到常用技术,kvraudio.com/forum 上的 DSP 论坛可能会为您指明正确的方向。
| 归档时间: |
|
| 查看次数: |
4450 次 |
| 最近记录: |