DSP - 如何在频域中应用增益?

时间:2015-06-23 09:27:59

标签: c++ audio filtering signal-processing fft

我是DSP的初学者,我必须制作音频均衡器。 我做了一些研究并在过去一个月里尝试过很多东西,但最后,它没有用,而且我对所有这些信息(我当然不能很好地解释)感到有些不知所措。

我有两个主要类:广播(产生粉红噪声,并对其应用增益)和记录(分析麦克风的输入并从中扣除增益)。

我两个都有些麻烦,但我要把这篇文章限制在广播方面。

我正在使用Aquila DSP Library,因此我使用了this example并扩展了它的逻辑。

/* Constructor */
Broadcast::Broadcast() :
_Info(44100, 2, 2),                 // 44100 Hz, 2 channels, sample size : 2 octet
_pinkNoise(_Info.GetFrequency()),   // Init the Aquila::PinkNoiseGenerator
_thirdOctave()                      // list of “Octave” class, containing min, center, and max frequency of each [⅓ octave band](http://goo.gl/365ZFN)
{
    _pinkNoise.setAmplitude(65536);
}


/* This method is called in a loop and fills the buffer with the pink noise */ 
bool Broadcast::BuildBuffer(char * Buffer, int BufferSize, int & BufferCopiedSize)
{
    if (BufferSize < 131072)
        return false;
    int SampleCount = 131072 / _Info.GetSampleSize();
    int signalSize = SampleCount / _Info.GetChannelCount();

    _pinkNoise.generate(signalSize);

    auto fft = Aquila::FftFactory::getFft(signalSize);
    Aquila::SpectrumType spectrum = fft->fft(_pinkNoise.toArray());

    Aquila::SpectrumType ampliSpectrum(signalSize);
    std::list<Octave>::iterator it;
    double gain, fl, fh;

    /* [1.] - The gains are applied in this loop */
    for (it = _thirdOctave.begin(); it != _thirdOctave.end(); it++)
    {
        /* Test values */
        if ((*it).getCtr() >= 5000)
            gain = 6.0;
        else
            gain = 0.0;
        fl = (signalSize * (*it).getMin() / _Info.GetFrequency());
        fh = (signalSize * (*it).getMax() / _Info.GetFrequency());

        /* [2.] - THIS is the part that I think is wrong */
        for (int i = 0; i < signalSize; i++)
        {
            if (i >= fl && i < fh)
                ampliSpectrum[i] = std::pow(10, gain / 20);
            else
                ampliSpectrum[i] = 1.0;
        }

        /* [3.] - Multiply each bin of spectrum with ampliSpectrum */
        std::transform(
            std::begin(spectrum),
            std::end(spectrum),
            std::begin(ampliSpectrum),
            std::begin(spectrum),
            [](Aquila::ComplexType x, Aquila::ComplexType y) { return x * y; });  // Aquila::ComplexType is an std::complex<double>
    }

    /* Put the IFFT result in a new buffer */
    boost::scoped_ptr<double> s(new double[signalSize]);
    fft->ifft(spectrum, s.get());

    int val;
    for (int i = 0; i < signalSize; i++)
    {
        val = int(s.get()[i]);

        /* Fills the two channels with the same value */
        reinterpret_cast<int*>(Buffer)[i * 2] = val;
        reinterpret_cast<int*>(Buffer)[i * 2 + 1] = val;
    }
    BufferCopiedSize = SampleCount * _Info.GetSampleSize();
    return true;
}

我正在使用gStreamer的粉红噪音和equalizer-nbands module来比较我的输出 将所有增益设置为0.0时,输出相同 但是只要我增加一些增益,输出听起来就不一样了(即使我的输出仍然听起来像粉红色的声音,并且似乎在正确的位置有所增加)。

所以我的问题是:

如何将我的增益应用于频域中的每个⅓倍频带 我的研究表明我应该做一个带通滤波器的滤波器组,但是如何用FFT的结果呢?

感谢您的时间。

0 个答案:

没有答案