Help combining two biquads in cascade for reverse RIAA IIR EQ

Hi all,

Hope this is an easy answer. I’m not a programmer and did my best to find the answer searching various manuals. I want to have both of these Nyquist biquads applied to the waveform simultaneously. It seems that if you just run them sequentially, the second cancels out the first.

(biquad-m track 7.96825677e+00 -5.2724672934e+00 -1.4469430768e+00 1.0000000e+00 3.655731e-01 1.499662e-02)
(biquad-m track 1.10057904e+00 -6.653010318e-01 -4.302668967e-01 1.000000000e+00 -5.7552742e-01 -3.7960478e-01)

This is hyper-accurate reverse RIAA normalized at 1kHz - 0dB with a sample rate of 96kHz.

A template would be great.

For any interested, a single-biquad solution is as follows. I understand is slightly less accurate than running both of the above together:

(biquad-m track -7.599067e+000 1.418787e+001 -6.592028e+000 1.000000e+000 -9.677739e-001 0.000000e+000)


Your first biquad does not modify track.

(setf *track* (biquad-m *track* ...))
(biquad-m *track* ...)

Out of interest, did you calculate the values yourself, or get them from a published source?

Thanks, that worked. Much appreciated; would have taken me forever to figure that out.

The source is an article by Scott Wurcer in Linear Audio magazine. I’ve been corresponding with some more knowledgeable engineers on the diyaudio forum about this, too. A similar source for such a curve is Wayne Stegall’s website:
To get an inverse curve normalized for 1 kHz, you just set a gain value of -0.1.
Scroll down to heading: “Test waveforms for Scott Wurcer’s digital RIAA article in Volume 10”

Tables: sw app1 table a-1.xlsx

For more accurate correction using two separate biquads at 48 kHz and 96 kHz sample rates: sw Appendix 1b web.docx

Shouldn’t that be +0.1 dB?

I’ve tested the curve and it is accurate to about +/- 0.1 dB up to 36 kHz. That’s impressive for an IIR filter.

If you have any (very) old records, this page in the Audacity wiki may be of interest: Missing features - Audacity Support
Unfortunately those curve specifications are not directly compatible with current versions of Audacity, but there’s a “EQ XML to TXT Converter” in Audacity’s “Tools” menu to convert to the new format. More info here: EQ XML to TXT Converter - Audacity Manual

No matter. I’ll be using the dual-biquad solution, anyway. The exact specs of the various reverse RIAA curves are in this thread on page 3:

What would the syntax be for three or four biquads in cascade?

Separate question:

How possible is it to write a Nyquist plugin to do the following:

Take user input of sample rate (48, 96) and input (Flat, RIAA, or even something else like 250 bass / -5)

Then output based on desired turnover and rolloff.

All of the curves one would need are here:

I would be willing to pay a modest price for someone to write this for me–this would be a big timesaver in the long run, e.g. if I’ve transferred something at 250 / -5 but I realize later it would be better to have it set at 250 / -8.5 or if I use a displacement-sensitive cartridge with a hardwired RIAA integrated preamp to transfer a record from 1930 with a curve of 500 / -8.5 and want to conservatively get the curve correct without drastic gain changes. I could do it now, but it will take a lot of tedious templating. There are so many permutations that it would be better to have something that has the code built in.

This really should be baked into future versions of Audacity. While it’s probably true that the FIR filters are virtually the same, the famous Gary Galo article discussing FIR vs IIR filters and phase relationships and waveforms have me wanting to use IIR filters for all my re-EQing. All of the above curves are accurate to 0.005dB or thereabouts with roughly three degrees of phase accuracy.

Basically the same thing:

(setf *track* (code-to-modify-*track*))
(setf *track* (code-to-modify-*track*))
(setf *track* (code-to-modify-*track*))
(setf *track* (code-to-modify-*track*))

Though a more elegant solution might be to save the parameters in a list of lists:

(setf parameters (list (list b0 b1 b2 a0 a1 a2) (list b0 b1 b2 a0 a1 a2) ...))

using actual values in place of b0, b1, …

Then wrap the biquad in a function:

(defun mybiquad (sig p)
  (biquad-m sig (nth 0 p) (nth 1 p) (nth 2 p) (nth 3 p) (nth 4 p) (nth 5 p)))

so that you can then call it repeatedly in a loop:

(dolist (params parameters)
  (setf *track* (mybiquad *track* params)))

Sounds like a job for a multiple-choice widget: Missing features - Audacity Support

For an overview of making plug-ins, see: Missing features - Audacity Support