1
$\begingroup$

Given a frequency response plot where gain is 0dB up to Fc and after Fc gain increases linearly by factor K (example chart below):

enter image description here

I am seeking how to arrive at its IIR/FIR equations so it can be implemented in a DSP processor, where Fc and K are variables in the equations that can be changed in real time while processing audio signals.

Can someone please point out if this is possible, and, if so, what steps do I need to take to accomplish this?

Thank you.

P.S. Sampling frequency is to be 48KHz

Edit(1): the purpose of this filter would be to compensate sloping hearing loss. The desire is that Fc and K can be changed in real time. In terms of ranges, ideally, 250Hz<Fc<4KHz and 0dB<K<XXdB - if possible, K should increase in small increments (not jump in 20dB/decade increments as n-order analog filters do - sloping hearing loss can have virtually any slope) There will be a very sharp low pass filter right at the input, filtering out everything above 10KHZ Edit(2): A thought - what about inversing a Fractional-Order Low Pass filter (to transform into High Pass)? Again, thanks for all the help!

$\endgroup$
7
  • 1
    $\begingroup$ Could you edit your question to make the filter specifications more rational? Reasons this filter may be unrealizable: 1) you're specifying a 50 dB/decade rise -- real filters 'like' integer multiple of 20 dB/decade; 2) you're not giving any tolerance -- real filters that have to exactly match some arbitrary amplitude response are hard; 3) you imply infinite high-frequency gain, and even the 60 dB that is explicitly called out is excessive; 4) you're not indicating whether or not the phase response matters. $\endgroup$
    – TimWescott
    Jul 21, 2023 at 23:04
  • $\begingroup$ That increasing ramp at the right half of your graph is not dB/Hz, but is dB/octave or dB/decade. Log frequency is a different scale than linear frequency as your graph almost shows (but 0 Hz is not what's on the left, it's 100 Hz). $\endgroup$ Jul 22, 2023 at 0:26
  • $\begingroup$ It would also help to specify the limits of the parameters, specifically how low can $Fc$ go and high large can $K$ get. Your filter as drawn will have about 85 dB of gain at the Nyquist frequency which is likely yo cause noise, aliasing or clipping problems. $\endgroup$
    – Hilmar
    Jul 22, 2023 at 11:52
  • $\begingroup$ Hi All. First of all, my sincere thank you for your replies, I truly appreciate all your time and effort!!! $\endgroup$
    – JCFS
    Jul 22, 2023 at 21:56
  • $\begingroup$ Ops, comment timed out, didn't post the rest of comment! @TimWescott, thanks for your input, I've edited the question adding important information, as to your numbered comments (1) true, but I am trying to go beyond analog (20*N)dB/decade by using DSP (2) since both Fc and K are to be real time adjustable variables, I believe tolerances and secondary, at least for now (3) yes, the way I plotted the graph it looks like infinite, but in reality 60~80dB is desirable as a limit (4) phase: yes, forgot to mention, this is for audio, so phase is not a limiting factor. $\endgroup$
    – JCFS
    Jul 22, 2023 at 23:48

2 Answers 2

3
$\begingroup$

Here is one way to do this:

You can implement a more or less constant slope by cascading high-shelf filters as described in the Audio EQ Cookbook.

  1. Create a list of frequencies. Start with a frequency that's about half an octave above $F_C$
  2. Add octaves until you are within maybe 70% of the Nyquist frequency.
  3. For each frequency: design a high-shelf with the target gain in dB/octave and a "suitable" Q. The Q will depend on the gain but that can either be implemented with a table lookup or a simple linear polynomial.
  4. Cascade all filters into a second order section structure.

Higher Qs will make the transition band smaller but the straight part of the slope will be more wiggly. You can adjust this to your liking.

Below are two examples: the first is your target (Fc = 500Hz, K = 15dB/oct) and and the second one is something more reasonable (Fc = 100Hz, K = 3dB/oct) which is essentially an inverse pink filter.

There are probably better ways of doing this, but this will work just fine in a pinch.

Original Target Filter

Inverse Pink Filter

$\endgroup$
5
  • $\begingroup$ Hay Hil, somebody did a nice pretty version of the cookbook. May I change the link in your answer? $\endgroup$ Jul 22, 2023 at 15:51
  • $\begingroup$ @robertbristow-johnson: yes please ! $\endgroup$
    – Hilmar
    Jul 22, 2023 at 20:25
  • $\begingroup$ Yes, I have used the Audio EQ Cookbook suggestion, albeit indirectly [wiki.analog.com/resources/tools-software/sigmastudio/toolbox/filters/general2ndorder]. I may be wrong, but as I understand the High-shelf equations are for 2nd order (biquad) filters and they use Fo (center frequency) and Q (sharpness of curve). I used these equations to arrive obtain several sets of {a0, a1, a2, b0, b1, b2} and ran them using ADI's SigmaStudio and ADAU1701. Maybe I did something wring, but it was very difficult to adjust the filter response to Fc and K (by changing Fo and Q) $\endgroup$
    – JCFS
    Jul 23, 2023 at 15:48
  • $\begingroup$ This prompted me to seek the filter equations in my question, which would use Fc and K directly. For now, using ADI's ADAU1701 DSP board, I've implemented high-shelf filters (four cascaded “General 2nd order w var Param/Lookup/Slew”, 20 curves, 15dB/each 60/dB/total gain, Q 0.7). This provides some flexibility in terms of variable gain via external potenciometer, but the frequency is fixed via SigmaStudio (no external control over Fc) $\endgroup$
    – JCFS
    Jul 23, 2023 at 15:50
  • $\begingroup$ For 15 dB/oct I would recommend a Q of 3. Doing this all on a single Sigma DSP chip would indeed by quite tedious. You will probably need some microcontroller to do the actual coefficient calculation $\endgroup$
    – Hilmar
    Jul 24, 2023 at 12:40
0
$\begingroup$

You can obtain an equiripple approximation to an arbitrary X db/decade rise by using interleaved real poles and zeros. If you have Matlab, find a good starting point by hand and then use lsqnonlin to match your target.

$\endgroup$

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.