1

我正在研究均衡器并试图了解它应该如何工作。

请帮助了解我应该做什么。

我已经拥有的:

  1. C#

  2. 传入的 float[] 缓冲区(来自 CSCore 库,可以用 Nuget 下载)

  3. 一个实施和工作的带通滤波器(http://www.earlevel.com/main/2011/01/02/biquad-formulas/

  4. 一个十频段均衡器 31,62...16000

  5. 代码片段:

        var sampleFilters = new EqFilter[] 
        {
            new EqFilter(sampleRate, 31, 0.24205482f, defaultGain),
            new EqFilter(sampleRate, 62, 0.11142862f, defaultGain),
            new EqFilter(sampleRate, 125, -0.013698578f, defaultGain),
            new EqFilter(sampleRate, 250, -0.40285712f, defaultGain),
            new EqFilter(sampleRate, 500, -0.27534246f, defaultGain),
            new EqFilter(sampleRate, 1000, -0.15479457f, defaultGain),
            new EqFilter(sampleRate, 2000, 0.071232915f, defaultGain),
            new EqFilter(sampleRate, 4000, 0.28904116f, defaultGain),
            new EqFilter(sampleRate, 8000, 0.45027387f, defaultGain),
            new EqFilter(sampleRate, 16000, 0.6036986f, defaultGain)
        };
    

第三个参数是 Q,第四个是增益,但带通滤波器不使用它。

        int read = base.Read(buffer, offset, count);

        for (int c = 0; c < WaveFormat.Channels; c++)
        {
            for (int i = _sampleFilters.Count; i-- > 0; )
            {
                _sampleFilters[i].Filters[c].Process(buffer, offset, read, c, WaveFormat.Channels);
            }
        }

        for (int n = offset; n < count; n++)
        {
            buffer[n] = Math.Max(-1, Math.Min(buffer[n], 1));
        }

        return read;
    }

其中 Process 方法应用带通滤波器。

我试图理解我做错了什么,因为如果我尝试以这种方式应用过滤器,我就会有静音作为输出。如果想象一下过滤器对信号做了什么,这似乎是正确的。但是我应该如何正确应用它?同时,如果我只应用一个频率滤波器(例如 31Hz),它就可以工作。

一位好人告诉我低通滤波器,我应该将它混入“干”信号。我试图在这里做同样的事情但失败了。我再次得到沉默作为输出。我尝试保留输入缓冲区,然后为每个频率应用滤波器并将其与输入混合,并使用以下公式:

结果 = X + Y - X*Y 其中 X = input[i] 和 Y = bandpassfiltered[i]

我想我也做错了什么。

还有一个大问题是如何处理负值?如果您尝试放置像微笑这样的乐队,您会在中间水平以下拉几个乐队并且有负值。如何用 BPF 实现它?

同时均衡器的频段改变Q是否正确?那么,如果拉上或拉下一个乐队,我会改变什么?如果不是Q应该怎么改?它不是增益,因为算法不计算它。

有人可以帮我理解这一切吗?我究竟做错了什么?我该怎么做这些事情?

如果不清楚,我很抱歉。如果需要,我会尽力澄清。

4

1 回答 1

1

每个带通滤波器将首先去除其通带以外的频率中的所有能量。因此,将每个带通滤波器按顺序应用于同一信号将移除所有信号,因为通过一个带通滤波器的频率随后会被后续滤波器移除,而没有重叠的通带。

相反,您应该将每个带通滤波器应用于原始信号,然后对结果求和。类似的东西(忽略通道和偏移量):

    // Input signal is in buffer[0] to buffer[buffer.length-1]
    // accumulator[] and buffer2[] are also pre-allocated to the same length as buffer[].

    // Initialize output accumulator to zero
    for (int i = 0; i < accumulator.length; ++i)  accumulator[i] = 0;
    // Apply each bandpass filter to copies of the original input
    for (int i = _sampleFilters.Count; i-- > 0; ) {
        // Make a copy of the input
        for (int j = 0; j < buffer.length; ++j)  buffer2[j] = buffer[j];
        // Apply this filter in-place
        _sampleFilters[i].Filters[c].Process(buffer2, buffer2.length);
        // Accumulate the result
        for (int j = 0; j < accumulator.length; ++j)
            accumulator[j] += buffer2[j]
    }
    // Copy back into buffer for output
    for (int i = 0; i < buffer.length; ++i)  buffer[i] = accumulator[i];
}

相邻带通滤波器之间重叠频率的相位抵消会引起进一步的问题,但这应该可以帮助您入门。

我看到你的一些带通滤波器有负 Q。这对我来说没有任何意义。此外,即使是正 Q 也小于 1,这听起来也不对。Q 是中心频率/带宽;您希望带宽小于中心频率(否则滤波器会一直向下延伸到零频率),因此看到 Q 小于 2 是不寻常的。

而就不同频率增益的“负值”而言:我们通常会看到以 dB 或 20*log_10(gain) 为单位的均衡曲线,它可以是正值或负值。增益本身应该是非负的;将增益设置为零有效地消除了某个频率的所有能量,这会尽可能多地消除它。应用负增益不会消除能量,它只是翻转波形的极性。

你所说的“负值”(将水平拉到“中间以下”)实际上是一个小于 1(但大于零)的乘法增益值。如果我们以 dB 为单位来描述该增益,它将显示为负值。

于 2014-06-03T14:33:21.513 回答