如何使用带通滤波器正确实现均衡

时间:2014-06-02 21:50:28

标签: c# signal-processing equalizer

我正在研究均衡器,并试图了解如何使用均衡器。

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

我已经拥有的东西:

  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)
        };
    
  6. 第三个参数是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),它就可以工作。

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

    result = X + Y - X * Y其中X = input [i],Y = bandpassfiltered [i]

    我想我也做错了。

    这也是一个很大的问题,如何处理负值?如果你试图像微笑一样放置乐队,那么你可以将几个乐队拉到中间水平并且具有负值。如何用BPF实现它?

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

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

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

1 个答案:

答案 0 :(得分: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是center_frequency / bandwidth;你希望带宽小于中心频率(否则滤波器接近一直向下延伸到零频率),所以看到Q小于2是不常见的。

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

你称之为“负值”(拉动“低于中间”的水平)实际上是一个小于1(但大于零)的乘法增益值。如果我们以dB为单位描述增益,它将作为负值。