Search code examples
c++signal-processingfftspectrum

How do I obtain the power per octave of a Pink noise (Using Aquila DSP library)?


My goal is to make a sound equalizer software; after a little bit of research, I found out that I would need to generate a pink noise, record it with a microphone, and compare the two spectrums.

So far, I only have generated a Pink Noise with the Aquila library in C++ which use the Voss algorithm, it sound fine though a little less loud that the sample on Wikipedia which is “normalized to -1 dBFS peak”.

I wanted to obtain the power per ⅓ Octave Band, here is a pseudo code of what I’ve done, using this post which helped me a lot:

Aquila::PinkNoiseGenerator pinkNoise(44100);    // sampleFrequency = 44.1 kHz

PinkNoise.setAmplitude(65536 / 2);          // sampleAmplitude = 65536
PinkNoise.generate(32768);                  // http://goo.gl/85R4wm

Aquila::SpectrumType spectrum = Aquila::fft(PinkNoise); // contain ComplexeType(real, imaginary)
double  frequency, db;

for (i = 0; i <= (32768 / 2); i++)
{
      frequency = (i * 44100) / 32768;  
      foreach (thirdOctave : o)
      {
            if (frequency >= o.min && frequency < o.max)
            {
                   db = Aquila::db(spectrum[i]);    // How it’s done : http://goo.gl/tkRicN 
                   o.result += db;
            }
      }
}

foreach(thirdOctave : o)
    print(“From “ + o.min + “ Hz to “ + o.max + “ Hz - Result = “ + o.result);

Here are what is displayed :

From 14.1 Hz to 17.8 Hz - Result = 393.421

From 17.8 Hz to 22.4 Hz - Result = 375.055

From 22.4 Hz to 28.2 Hz - Result = 520.531

[...]

From 891 Hz to 1122 Hz - Result = 19048.2

From 1122 Hz to 1413 Hz - Result = 23770.9

From 1413 Hz to 1778 Hz - Result = 29700.3

[...]

From 11220 Hz to 14130 Hz - Result = 214689

From 14130 Hz to 17780 Hz - Result = 268036

Which leads to my questions :

1 - From what I understood each result should be approximately the same, which is clearly not the case here. Is there something (probably simple) that I’m doing wrong ?

2 - The db value that I’m getting are between 100 and 130, but on every graphic that I’m looking the values are negative. Same question as above, is there something I should do in addition to the Aquila::db method ?

Thanks for your time.

PS : I’d like to point out that signal processing is a new thing for me and I did some research, but I might have use some terms in the wrong way.


Solution

  • You want to first add up the spectrum magnitudes, and then take the db (your code seems to do the opposite.) The log of a sum is very different from the sum of the log values.

    dB is often reported for magnitudes below some reference level. Since that ratio will be less than 100%, the log of that ratio will be negative.