Taking another crack at basic filtering

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

thevinn wrote:Why the number 20? Shouldn't that be 10? Where did 20 come from? I thought a decibel was a tenth of a bel and not a twentieth...
it was arbritrarily chosen by the definitors (if that's a valid term) such that 1 dB roughly corresponds to a just noticable difference in amplitude. when you see formulas where the factor is 10 instead of 20, then they are mostly dealing with powers instead of raw amplitudes. powers are proportional to amplitude squared, and that squaring inside the logarithm was dragged out of the logarithm by using 2 as pre-factor
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Your function worked great! My results are almost identical:

Image

My measured output is the orange line, whereas the green line is the returned value from getBiquadMagnitudeAt(). As you can see they are virtually identical.

The y axis is using the formula 20*log10(a) where a is the magnitude response.

I'm not sure why the frequency on the X axis appears to make no sense. Maybe its a bug in my calculation of the apparent samplke rate. Or perhaps it is a bug with my mapping function:

Code: Select all

double p=log10( freqHi-freqLo );
float freq=freqLo+::pow( 10, p*screenXCoordinate/(screenWidth1) );
In my image the filter's frequency is set to 6253Hz but in the graph it looks like its between 250Hz and 500Hz.

Post

Robin from www.rs-met.com wrote:it was arbritrarily chosen by the definitors (if that's a valid term) such that 1 dB roughly corresponds to a just noticable difference in amplitude.
So for example lets say I am implementing a knob that controls the master output gain, and the units are -100dB to +10dB. I would use

Code: Select all

double scaleFactor=::pow( 10, dB/20.0 );
Or should that be a 10.0 instead of 20.0?

Its a knob, so the idea of providing the user with enough control to create "just noticable differences" seems appealing and therefore the number 20.0 would be appropriate as per your definition.

Post

thevinn wrote:Your function worked great! My results are almost identical:

...big image ...

My measured output is the orange line, whereas the green line is the returned value from getBiquadMagnitudeAt(). As you can see they are virtually identical.

The y axis is using the formula 20*log10(a) where a is the magnitude response.
congrats! differences are possibly due to the mentioned artifacts from the truncation. now is it fun to see math at work? ...and doing the expected things, that is :hihi:

In my image the filter's frequency is set to 6253Hz but in the graph it looks like its between 250Hz and 500Hz.
dunno. maybe something with the normalized frequencies 'n stuff?
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

So as I was saying. In my implementation I am producing a full sine wave, once, and then using the same wave over and over again as input to the filter. Since most filters require the sample rate to be known (to calculate the normalized frequency from the frequency parameter), I just adjust the sample rate so that my sine wave appears to be a different frequency. I call this "apparent frequency".

In the calculation for sample rate I use

Code: Select all

float sampleRate = freq * nSamples
where freq is the coordinate in the X axis for the magnitude response graph, and nSamples is the number of samples in the sine buffer.

When the pre-generated sine buffer is large enough, everything looks cool. But for kicks (and speed) when I lower the size of the buffer to something like, say 128 or 256 samples, I get this result:

Image

The orange line is the result of my algorithm, and the green line is the ideal magnitude response predicted by getBiquadMagnitudeAt() for the given biquad coefficients.

You can clearly see the aliasing (is that what it is?). If I start tweaking the Q and frequency value of the filter I get reflections and copies of the distorted parts at the lower end of the frequency spectrum.

Post

Forgot to mention, in the graph above Q~=10 and freq=2417(of the biquad).

Post

thevinn wrote:So for example lets say I am implementing a knob that controls the master output gain, and the units are -100dB to +10dB. I would use

Code: Select all

double scaleFactor=::pow( 10, dB/20.0 );
looks about correct.
Its a knob, so the idea of providing the user with enough control to create "just noticable differences" seems appealing and therefore the number 20.0 would be appropriate as per your definition.
these just notable differences were probably measured with average subjects - your user is probably more sensitive (as s/he is presumably a musician/audio engineer). i think of a tenth of a dB as a good resolution/stepsize in practice. sometimes i provide even a 1/100 dB. ...if a stepsize is necesarry (or convenient) at all
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

thevinn wrote:When the pre-generated sine buffer is large enough, everything looks cool. But for kicks (and speed) when I lower the size of the buffer to something like, say 128 or 256 samples, I get this result:

Image

The orange line is the result of my algorithm, and the green line is the ideal magnitude response predicted by getBiquadMagnitudeAt() for the given biquad coefficients.
i you'd be FFTing the impulse-response, i'd say truncation artifacts. if you feed in a sine and measure the maximum output amplitude, i'd say transient response artifacts.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

So as it turns out, some of the "crappy" DSP algorithms I was using (like the 3 band eq from I forget where) actually look quite good if my frequency response graph is to be believed (aside from the obvious bug with the units in the X axis).

I think the problem was in the way I was using them. For example the 3-band eq takes as its units for low, mid, and high, a scale factor. If low, mid, and high are set to 1 you get output=input. If you set low to zero, you cut all the lows. If you set hi to two, you double all the highs. By doubling I mean that the output level gets scaled by a factor of two. Which corresponds to a 3dB increase (is that correct?).

I am taking a knob that has values from -1 (all the way counterclockwise) to 1 (all the way clockwise) running linearly with the middle value of course being zero and corresponding to no change in level.

I want the ability to cut the output completely (i.e. set low scale to 0 in the 3-band eq). But if I just map the knob's values into the range 0..2 (corresponding to complete cut, then unity at 1, and 3dB increase at 2) the result is unsatisfying.

The reason being that for a very small change in the knob you get a big change in the level.

What would be a good way to map a knob for purposes of controlling the scale factor as a parameter to the 3-band equalizer?

Post

thevinn wrote:What would be a good way to map a knob for purposes of controlling the scale factor as a parameter to the 3-band equalizer?
i'd go for dB. if you really want to allow a total cut down to zero amplitude (corresponding to minus infinity decibels), i'd make the filter mode switchable (to notch, in this case). i'd be wary with zero gain-factors in eq-coefficient calculations anyway. RBJ cookbock EQ would do a division by zero here.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

thevinn wrote:If you set low to zero, you cut all the lows. If you set hi to two, you double all the highs. By doubling I mean that the output level gets scaled by a factor of two. Which corresponds to a 3dB increase (is that correct?).
6 dB.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Question: how is the 3-band EQ structured? Is is series of three filters, or is it some parallel structure? If you're attempting to split the input into three independent bands, then scale each, then sum back together, you will have to take care of matching the phase (after scaling too!) which can be non-trivial.

Post

mystran wrote:Question: how is the 3-band EQ structured? Is is series of three filters, or is it some parallel structure? If you're attempting to split the input into three independent bands, then scale each, then sum back together, you will have to take care of matching the phase (after scaling too!) which can be non-trivial.
indeed. i was assuming a cascade of bell-filters. a parallel connection of bandpasses is also popular for EQs. but i don't really like the approach - that's why i immediately thought of a cascade structure here.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

mystran wrote:Question: how is the 3-band EQ structured? Is is series of three filters, or is it some parallel structure?
I'm not sure. Its the one from here:

"3 band equaliser"

http://www.musicdsp.org/archive.php?classid=3#236

From the frequency response it seems to work rather well. I just need to map the knob interface into an appropriate range of values.

I'm using 550 and 8000 as the transition frequencies.

Post

What's a good setting for the "Q" value for a low pass biquad? I keep raising it and I am finding that around Q=6000 I am seeing the frequency response starting to approximate the ideal, but there are ripples in the passband. I can find lots of stuff about biquads and all kinds of obscure formula but nowhere do I see a discussion of good values for "Q" :-(


Here is the latest result, with the filter frequency set to 8025 Hz and Q=6333. The orange is the filter's measured frequency response, while green is the "ideal" response. The green line is produced by outputting 1 if the sampled frequency is less than the filter's cut-off frequency, else outputting 0. A side effect of this graph is that it proves the X-axis coordinates are properly mapped (the green line is correctly drawn through the 8000 Hz marker). So the labels were right all along apparently, but the results I got were unexpected:

Image


It seems like the filter's magnitude reponse is falling off early (i.e. before reaching the filter frequency). I thought it was supposed to be closer. And should I care about the ripples?

Post Reply

Return to “DSP and Plugin Development”