3
$\begingroup$

I’m new to DSP and I have to do an audio equalizer in c++.
I did a lot of research about it and tried some stuff in the last month, but I’m a little overwhelmed with all those informations and it’s not working yet.

I decided to start over and for now, all I got is a function which fills the audio buffer with a sin wave (1kHz). And I’m trying to apply a filter with those values to it.

<Filter>
    <Bands num-bands="28">
        <band0    freq="31.25"      width="7.23625"     gain="0" />
        <band1    freq="39.3725"    width="9.1171"      gain="0" />
        <band2    freq="49.6063"    width="11.4868"     gain="0" />
        <band3    freq="62.5"       width="14.4725"     gain="0" />
        <band4    freq="78.7451"    width="18.2342"     gain="0" />
        <band5    freq="99.2126"    width="22.9737"     gain="0" />
        <band6    freq="125"        width="28.945"      gain="0" />
        <band7    freq="157.49"     width="36.4684"     gain="0" />
        <band8    freq="198.425"    width="45.9473"     gain="0" />
        <band9    freq="250"        width="57.89"       gain="0" />
        <band10   freq="314.98"     width="72.9368"     gain="0" />
        <band11   freq="396.85"     width="91.8946"     gain="0" />
        <band12   freq="500"        width="115.78"      gain="0" />
        <band13   freq="629.961"    width="145.874"     gain="0" />
        <band14   freq="793.701"    width="183.789"     gain="0" />
        <band15   freq="1000"       width="231.56"      gain="6" />
        <band16   freq="1259.92"    width="291.747"     gain="0" />
        <band17   freq="1587.4"     width="367.579"     gain="0" />
        <band18   freq="2000"       width="463.12"      gain="0" />
        <band19   freq="2519.84"    width="583.495"     gain="0" />
        <band20   freq="3174.8"     width="735.157"     gain="0" />
        <band21   freq="4000"       width="926.24"      gain="0" />
        <band22   freq="5039.68"    width="1166.99"     gain="0" />
        <band23   freq="6349.6"     width="1470.31"     gain="0" />
        <band24   freq="8000"       width="1852.48"     gain="0" />
        <band25   freq="10079.4"    width="2333.98"     gain="0" />
        <band26   freq="12699.2"    width="2940.63"     gain="0" />
        <band27   freq="16000"      width="3704.96"     gain="0" />
    </Bands>
</Filter>

So here are my questions :

  1. In which domain should I apply the filter ? I started in the frequency domain, but this blog (here and here) shows me that it’s not the best and only solution.

  2. Which kind of filter should I use ? I’m lost with all those high pass, low pass, peaking, shelving filters; and I don’t know which one to choose.

  3. I only found “tutorial” to create a filter which modify only one frequency / band. Is it possible to create a filter that is a sum of multiples filters ? Or applying multiples filters in series to the signal ?

Feel free to ask if I forgot something that might help to understand my problem.
Thanks for your time.

PS : Sorry if this post is not very specific, but I want to clear that out before posting specifics problems or code.

$\endgroup$
3
  • $\begingroup$ Why those particular (peculiar) frequencies? They don't (quite) seem to line up to the standard musical octaves. $\endgroup$
    – JRE
    Commented Jun 10, 2015 at 10:34
  • $\begingroup$ At first I was using the 1/3 Octave bands here but I thought using the formulas here to generate the bands would be a good idea. Apparently it wasn't ^^' $\endgroup$
    – Khaz42
    Commented Jun 10, 2015 at 12:11
  • $\begingroup$ Not that it matters, it just seemed so oddly specific. Especially since the transitions cannot be that sharp. $\endgroup$
    – JRE
    Commented Jun 10, 2015 at 12:14

2 Answers 2

5
$\begingroup$

Simply put, you need a bank of passband filters. You feed your signal through each of the filters, and sum up the outputs from the filters.

Designing the filters is where the fun comes in.

First off, assuming this is just audio (music or the like) then there's no need of special filters. You can use the simplest and fastest and not worry too much about phase and ripple.
You will want to use IIR filters, as they require the least amount of calculation - since you have 28 bands and presumably are working in stereo, you will want to reduce the load on the CPU else the computer won't be able to do much else. IIR uses less CPU time than FIR filters.

There are online tools that you can use to create the needed coefficients for the filters. Matlab or Gnu Octave can also be used. You will need to look up algorithms for implementing IIR Filters, and how to make use of the calculated coefficients.

Specifying the bands is the next fun step. When a filter passes audio, it doesn't simply remove everything out side of its passband. It just isn't possible to do so. Frequencies outside of the passband of a filter sort of slope off down towards zero amplitude.
At some frequency outside of its passband, the audio amplitude will drop by one half. This is the -3dB point, and is used in specifying filters.
What you want to do is to arrange your passbands such that the -3dB points of adjacant filters are at the same frequency. Say you have two filters. One should pass frequencies from 500 to 1000Hz and the next from 1000 to 2000Hz. You would want to make the high cutoff of the lower filter to be 1000Hz, and the low cutoff of the high filter also be 1000Hz. Design the filters such that 1000Hz is down by half in each filter (usually, just specifying it as the cutoff is enough.) When you now sum the outputs of the two, they add up to just the audio from 500 to 200Hz, with everything in that range at (more or less) the same amplitude as before.

Now, with your audio split into banks, you can multiply the output of each filter with some constant to dampen or emphasize that band. This image demonstrates what I mean about the way the bands have to be layed out. equalizer

$\endgroup$
4
  • $\begingroup$ Thanks, I've look into that and at least I know what to do now ! I used the RBJ Cookbook to calculate the coefficient and it seems to be good. So I think my problem comes from the bands I use. I guess I shouldn't use them, but I have a question about that : Shouldn't the Center Frequency be at equal distance from the Lower and Upper band limit ? I thought 1/3 octave was a norm in audio, but it don't seems to be good either... $\endgroup$
    – Khaz42
    Commented Jun 11, 2015 at 9:32
  • $\begingroup$ "Center frequency" is called that because it is in the middle of the upper and lower cutoff. There are filter design methods that take a center frequency and bandwidth, while other methods call for the upper and lower limits. If you are doing an equalizer for listening to music, then it isn't as important exactly which ranges you use. If you are doing some kind of measurements or scientific work, then you'l probably want to use the octaves or 1/3 octaves - but keep in mind that "cutoffs" are more like "mush offs," so don't expect filters to work at like 0.1Hz accuracy. $\endgroup$
    – JRE
    Commented Jun 11, 2015 at 9:40
  • $\begingroup$ By the way, RBJ is here on the signal processing stackexchange and often answers questions. $\endgroup$
    – JRE
    Commented Jun 11, 2015 at 9:43
  • $\begingroup$ Well thanks, I'm gonna look into that for some time and I'll be back if I have other questions. $\endgroup$
    – Khaz42
    Commented Jun 11, 2015 at 9:55
0
$\begingroup$

first of all if you want to test your equalizer you should not use a sine wave as input signal, but a signal with a richer spectrum. In this way you can compare the input and output spectrum and check the equalizer performance.

1) It is not true that the time domain always outperforms the frequency domain. However, if you are a beginner this should not be your first problem. Start with the easiest solution and when the eq works focus on performances.

2 and 3) I think you are looking for a filterbank, which is a group of filters that are applied in parallel. In this case you want a bank of bandpass filter, where each filter has the center frequency and the width that you specified above.

$\endgroup$
1
  • $\begingroup$ I didn't mention it but I usually generate a pink noise; I use a sin wave as a test to be sure that I modify the good frequencies. 1) It wasn't really about performances, I thought that it would be great if I needed to apply those filters to an audio stream, since there is no need to fill a buffer in the time domain (from what I understood). 2-3) Thanks, I'm gonna look into that as suggested by JRE ! $\endgroup$
    – Khaz42
    Commented Jun 10, 2015 at 13:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.