我正在为我正在从事的开源项目(iStudio)创建一个 6(或更多)频段均衡器。我已经实现了 SkypeFx 均衡器,但它只有 3 段均衡器,但我想要一个更专业的均衡器。因此,我自己使用 Matlab 设计了几个滤波器,并为采样均衡器设计了 6 个 ARMA 滤波器。我当然需要实时过滤输出。因此,我继续为此目的实施微分方程。
private double[] Filter(float[] buffer, SignalFilter filter, float filterWeight, int count)
{
double[] y = new double[buffer.Length];
for (int n = 0; n < count; n++)
{
y[n] = 0.0f;
for (int k = 0; k < filter.B.Count; k++)
{
if (n - k >= 0)
{
y[n] = y[n] + filter.B[k] * (double)buffer[n - k];
}
}
for (int k = 1; k < filter.A.Count; k++)
{
if (n - k >= 0)
{
y[n] = y[n] - filter.A[k] * y[n - k];
}
}
}
return y;
}
这个功能非常简单。在缓冲区中,我存储实时样本,filter 是一个具有 2 个数组的类,其中包含 AR 和 MA 系数。该函数由进程函数调用,该函数仅将缓冲区通过所有可用的过滤器并将结果相加:
public void Process(float[] buffer, int offset, int count)
{
List<double[]> filtered = new List<double[]>();
for (int i = 0; i < _filters.Count - 5; i++)
{
filtered.Add(Filter(buffer, _filters[i], Values[i], count));
}
for (int i = 0; i < count; i++)
{
buffer[i] = 0.0f;
for (int x = 0; x < filtered.Count; x++)
{
buffer[i] += (float)(filtered[x][i] * ((Values[x] + 1) / 2));
}
}
}
代码稍微缩短了一点,但应该足够了。均衡器有点工作,但它有两个问题,第一个是它产生的延迟(可能需要优化)和声音失真。每个过滤后的缓冲区之间都有小刘海。
所以我的问题是:为什么声音会失真以及如何解决?
谢谢。