Forums

Orfanidis prescribed nyquist peak filter parameters

Started by Unknown June 22, 2016
First post! Advance apologies for newb-ness.

I've made a quick implementation of Orfanidis 'decramped' prescribed nyquist gain peaking filters in C++.

Seems okay but I would like to be able to specify...

Peak gain in dB
Peak frequency in Hz
Peak Q say 0.1 to 4

rather than...

(G0 = reference gain at DC = 1)
G = boost/cut gain
GB = bandwidth gain
w0 = center frequency in rads/sample
Dw = bandwidth in rads/sample

...that Orfanidis' calculator takes.

How do I map the parameters properly?


Thanks in advance,
John.
I think I have everything except the Q sorted...

    double linToHz (double lin)
    {
        return 20 * std::pow (10, 3 * lin); // 3 decades in freq scale
    }

    double hzToRadPerSamp (double hz)
    {
        return hz * ((2 * pi) / samplerate);
    }

    void calculate (double gain, double frequency, double bandwidth)
    {
        const double hzFrequency = linToHz (frequency);
        const double radSampFrequency = hzToRadPerSamp (hzFrequency);
        const double radSampBandwidth = bandwidth * radSampFrequency;

        calculateCoefficients (1, gain, gain/2., radSampFrequency, radSampBandwidth);
    }

(calculateCoefficients() is Orfanidis' calculating function, parameters as per previous post.)


So currently 'bandwidth' is just a generic scaling for frequency in rads/sample. It sets the width of the bell at height gain/2.

Anyone know how I would make 'bandwidth' correspond properly to Q factor?


Many thanks,
John.

I should mention that my GUI frequency slider is right now ranged 0 to 1. With centre 0.5 setting corresponding to 632Hz like this...

0 = 1Hz
0.5 = 632Hz
1 = 20kHz
On Wednesday, June 22, 2016 at 6:46:39 PM UTC-4, thejoh...@gmail.com wrote:
> First post! Advance apologies for newb-ness. > > I've made a quick implementation of Orfanidis 'decramped' prescribed nyquist gain peaking filters in C++. > > Seems okay but I would like to be able to specify... > > Peak gain in dB > Peak frequency in Hz > Peak Q say 0.1 to 4 > > rather than... > > (G0 = reference gain at DC = 1) > G = boost/cut gain > GB = bandwidth gain > w0 = center frequency in rads/sample > Dw = bandwidth in rads/sample > > ...that Orfanidis' calculator takes. > > How do I map the parameters properly? >
i think you'll find that Q (in terms of the EE definition) is Dw/w0. then, i believe you will get GB/G = 1/sqrt(2) . looks like you already have w0 = 2*pi*(peak frequency in Hz)/(sample rate in Hz). you might be interested in this at stack exchange: http://dsp.stackexchange.com/questions/19225/audio-eq-cookbook-without-frequency-warping/19253#19253 it sorta generalizes the Orfanidis thing (a la Knud Bank Christensen). you would still need to apply bilinear transform to get H(z). r b-j
> i think you'll find that Q (in terms of the EE definition) is Dw/w0. then, i believe you will get GB/G = 1/sqrt(2) .
Thanks Robert I am much closer. I now have a peak that behaves very well at 6dB gain. However, moving away from 6dB there is still some strange gain-Q interaction; when I push the gain up the resulting peak broadens. For example (using another EQ to null against): At +18dB, a 0.71Q setting on my peak broadens to an effective 0.26Q... https://s31.postimg.org/haxretvq3/Screen_Shot_2016_06_23_at_09_03_54.png (...please ignore GUI labels) My pre-Orfanidis calc code now looks like void calculate (double gain, double frequency, double q) { const double gainLin = Decibels::decibelsToGain (gain); const double bandwidthGain = gainLin / std::sqrt (2); const double hzFrequency = linToHz (frequency); const double radSampFrequency = hzToRadPerSamp (hzFrequency); const double radSampBandwidth = radSampFrequency / q; calculateCoefficients (1, gainLin, bandwidthGain, radSampFrequency, radSampBandwidth); } I'm sure there is something simple I am missing?
> you might be interested in this at stack exchange: http://dsp.stackexchange.com/questions/19225/audio-eq-cookbook-without-frequency-warping/19253#19253
Great I will try tackle that next project.
> void calculate (double gain, double frequency, double q) > { > const double gainLin = Decibels::decibelsToGain (gain); > const double bandwidthGain = gainLin / std::sqrt (2); > const double hzFrequency = linToHz (frequency); > const double radSampFrequency = hzToRadPerSamp (hzFrequency); > const double radSampBandwidth = radSampFrequency / q; > > calculateCoefficients (1, gainLin, bandwidthGain, radSampFrequency, radSampBandwidth); > } > > I'm sure there is something simple I am missing?
I see now I didn't have gain in the Q calculation at all This is closer but still a mess... const double radSampBandwidth = (radSampFrequency * 2) / (q * gainLin); https://s31.postimg.org/vewdvez4b/Screen_Shot_2016_06_23_at_09_42_42.png
All working now. Apologies for debugging out loud. (Will ask the duck the next time).

const double bandwidthGain = gainLin / std::sqrt (2);

...should have been...

const double bandwidthGain = dbToLin (gainDb / std::sqrt (2));


And Robert, thank you for all the work you've done in this field.


All the best, John.
On Monday, June 27, 2016 at 1:22:56 PM UTC-4, thejoh...@gmail.com wrote:
> All working now. Apologies for debugging out loud. (Will ask the duck the next time). > > const double bandwidthGain = gainLin / std::sqrt (2); > > ...should have been... > > const double bandwidthGain = dbToLin (gainDb / std::sqrt (2)); > > > And Robert, thank you for all the work you've done in this field. >
i coulda just sent you the C code i have for the Orfanidis thing. there is an even better EQ coefficient calculation by a guy named Ken Cooke than the Orfanidis correction. r b-j
> i coulda just sent you the C code i have for the Orfanidis thing. >
Ooh, I would still like to see the C code if you still have it?
> there is an even better EQ coefficient calculation by a guy named Ken Cooke than the Orfanidis correction. >
And this too? Is that coefficient calculation for the Orfanidis approach or a different approach entirely?
Back to this project after a long break.

I've gotten decent behaviour however when the peak frequency approaches Nyquist the bandwidth expands like so...

https://s13.postimg.io/pfj6t5tvb/orfanidis_near_nyquist_behaviour.gif

Any ideas of how to iron this out?

I've chosen 0.707*peak_gain to be the gain at which the bandwidth is measured at. I'm presuming something strange is happening when the rightmost bandwidth frequency is hits and exceeds Nyquist?

Many thanks,
John.