2

I’m a beginner in DSP and I have to make an audio equalizer. I’ve done some research and tried a lot of thing in the past month but in the end, it’s not working and I’m a bit overwhelmed with all those informations (that I certainly don’t interpret well).

I have two main classes : Broadcast (which generate pink noise, and apply gain to it) and Record (which analyse the input of the microphone et deduct the gain from it).

I have some trouble with both, but I’m gonna limit this post to the Broadcast side.

I’m using Aquila DSP Library, so I used this example and extended the logic of it.

/* 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;
}

I’m using the pink noise of gStreamer along with the equalizer-nbands module to compare my output.
With all gain set to 0.0 the outputs are the same.
But as soon as I add some gain, the outputs sound different (even though my output still sound like a pink noise, and seems to have gain in the right spot).

So my question is :

How can I apply my gains to each ⅓ Octave band in the frequency domain.
My research shows that I should do a filter bank of band-pass filters, but how to do that with the result of an FFT ?

Thanks for your time.

Khaz42
  • 33
  • 5
  • The gstreamer module you are using is an IIR filter in time domain. It will be very difficult to obtain a bit-for-bit identical result using FFT filtering. Some clues here : http://dsp.stackexchange.com/questions/8911/why-do-we-use-window-in-time-domain-rather-than-do-fft-modify-the-spectrum-and-t?lq=1 – audionuma Jun 23 '15 at 12:41
  • Even if it's not the same as gStreamer; would I be able to obtain a result suitable for any future measurements with FFT filtering then ? Also, does that mean that my current code is good ? It doesn't seem right to me, especially the [2.] part... – Khaz42 Jun 23 '15 at 14:24

0 Answers0