Parametric EQ — HLE + bytecode
Parametric EQ — HLE reconstruction and DSP bytecode
DSPHLE selector 0x01 · program image prog39_parametric_eq · Intervention-pinned (a panel control was driven and the moving C-RAM cell identified).
5-band RBJ biquad from decoded design params (FREQ=0x03, GAIN=0x01); spectral A/B PASS.
This page pairs the bytecode the effect runs on the NEC µPD6383GF with the high-level reconstruction that makes it audible in MAME. The reconstruction is not the chip’s microcode — it is a textbook DSP block built from the decoded meaning of that microcode, and reading the two together is how the bytecode is understood (and, in time, driven toward a faithful low-level emulation). See also the signal-flow flowchart.
The bytecode below is the source of truth; the HLE reconstruction is not. The HLE is our best current interpretation and may contain mistakes — where the two disagree, the bytecode wins, and a better HLE should be updated here. This page is the permanent archive of the reference HLE: it is kept here even after the code is eventually removed from the MAME sources.
DSP bytecode (reverse-engineered microprogram)
The disassembled image the chip executes for this effect. Source (regenerable):
dsp/disasm/prog39_parametric_eq.dsm.
; Reverse-engineered disassembly of the KN5000 effects-DSP microcode
; (NEC uPD6383GF), recovered from the original firmware. The microcode is the
; work of its original authors; this is a disassembly for preservation and
; interoperability, and no claim of copyright is made over the disassembled program.
; KN5000 effects-DSP program -- PARAMETRIC EQ
; image rep algo 39 | slots 39 | unit 0 (I-RAM load 84)
; family eq | confidence SOLVED | 105 words, 60 class-A multiplies (60 named)
; role: parametric EQ: 5 bands x 2 channels, Direct-Form-I bilinear biquad (decoded to the bit); the reference program
; coefficient cursor base 0x00
;
; GENERATED by dsp/tools/gen_dsp_disasm.py -- DO NOT EDIT.
; Put labels/comments in the matching dsp/sym/*.sym; analysis in dsp/algorithms/.
w0 000020B1CD ld (p),(p)+11
w1 000020040E ld acc,(p)+0
w2 0212200000 mac.b (p)0,(p)+0 ; mem[p]<-acc, acc=0
w3 002A200000 ?word 0x002A200000 ; 02A.2.00.000 hi12{f31=5 ?5 res=020} [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
w4 0000240407 ld.st acc,(p)+64
Band0_Section:
w5 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x00] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x00] = biquad b1 (role EQ, PROVEN)
; P = b1*S0 ; latch A <- S0
w6 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x01] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x01] = biquad b0 (role EQ, PROVEN)
; S0 <- x ; acc = P ; P = b0*x
w7 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x02] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x02] = biquad b2 (role EQ, PROVEN)
; acc += P ; P = b2*S1
w8 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x03] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x03] = biquad -a1 (role EQ, PROVEN)
; acc += P ; P = -a1*S2 ; latch B <- S2
w9 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x04] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x04] = biquad -a2 (role EQ, PROVEN)
; acc += P ; P = -a2*S3
w10 01022FF687 mac.st tb,(p)-1
; acc += P ; S3 <- latch B (class-2 store)
w11 0804816415 post acc,c
; class-8 post-sum step -- OPERATION UNKNOWN
w12 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x05] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x05] = biquad makeup (role EQ, PROVEN)
; S2 <- acc ; P = makeup*acc
w13 0000203647 ld.st ta,(p)+3
; acc <- P ; S1 <- latch A (class-2 store)
w14 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x06] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x06] = biquad b1 (role EQ, PROVEN)
w15 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x07] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x07] = biquad b0 (role EQ, PROVEN)
w16 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x08] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x08] = biquad b2 (role EQ, PROVEN)
w17 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x09] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x09] = biquad -a1 (role EQ, PROVEN)
w18 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x0A] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0A] = biquad -a2 (role EQ, PROVEN)
w19 01022FF687 mac.st tb,(p)-1
w20 0804816415 post acc,c
w21 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x0B] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0B] = biquad makeup (role EQ, PROVEN)
w22 0000203647 ld.st ta,(p)+3
w23 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x0C] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0C] = biquad b1 (role EQ, PROVEN)
w24 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x0D] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0D] = biquad b0 (role EQ, PROVEN)
w25 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x0E] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0E] = biquad b2 (role EQ, PROVEN)
w26 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x0F] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0F] = biquad -a1 (role EQ, PROVEN)
w27 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x10] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x10] = biquad -a2 (role EQ, PROVEN)
w28 01022FF687 mac.st tb,(p)-1
w29 0804816415 post acc,c
w30 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x11] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x11] = biquad makeup (role EQ, PROVEN)
w31 0000203647 ld.st ta,(p)+3
w32 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x12] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x12] = biquad b1 (role EQ, PROVEN)
w33 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x13] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x13] = biquad b0 (role EQ, PROVEN)
w34 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x14] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x14] = biquad b2 (role EQ, PROVEN)
w35 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x15] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x15] = biquad -a1 (role EQ, PROVEN)
w36 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x16] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x16] = biquad -a2 (role EQ, PROVEN)
w37 01022FF687 mac.st tb,(p)-1
w38 0804816415 post acc,c
w39 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x17] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x17] = biquad makeup (role EQ, PROVEN)
w40 0000203647 ld.st ta,(p)+3
w41 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x18] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x18] = biquad b1 (role EQ, PROVEN)
w42 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x19] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x19] = biquad b0 (role EQ, PROVEN)
w43 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x1A] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1A] = biquad b2 (role EQ, PROVEN)
w44 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x1B] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1B] = biquad -a1 (role EQ, PROVEN)
w45 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x1C] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1C] = biquad -a2 (role EQ, PROVEN)
w46 01022FF687 mac.st tb,(p)-1
w47 0804816415 post acc,c
w48 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x1D] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1D] = biquad makeup (role EQ, PROVEN)
w49 00002AD647 ld.st ta,(p)-83
w50 0028200000 ?word 0x0028200000 ; 028.2.00.000 hi12{f31=4 ?5 res=020} [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
w51 0880130407 dly.r dsc[k],p+48
w52 00002F7000 nop
w53 000020A1CD ld (p),(p)+10
w54 00002FF1CE ld (p),(p)-1
w55 0212202000 mac.b (p)0,(p)+2 ; mem[p]<-acc, acc=0
w56 002A200000 ?word 0x002A200000 ; 02A.2.00.000 hi12{f31=5 ?5 res=020} [SPECULATIVE (prospective, not measured): SRC 0x00 = mem[ptr]/delay-RAM read]
w57 0000254407 ld.st acc,(p)+84
w58 0801000021 rstcur
w59 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x00] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x00] = biquad b1 (role EQ, PROVEN)
w60 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x01] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x01] = biquad b0 (role EQ, PROVEN)
w61 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x02] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x02] = biquad b2 (role EQ, PROVEN)
w62 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x03] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x03] = biquad -a1 (role EQ, PROVEN)
w63 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x04] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x04] = biquad -a2 (role EQ, PROVEN)
w64 01022FF687 mac.st tb,(p)-1
w65 0804816415 post acc,c
w66 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x05] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x05] = biquad makeup (role EQ, PROVEN)
w67 0000203647 ld.st ta,(p)+3
w68 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x06] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x06] = biquad b1 (role EQ, PROVEN)
w69 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x07] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x07] = biquad b0 (role EQ, PROVEN)
w70 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x08] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x08] = biquad b2 (role EQ, PROVEN)
w71 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x09] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x09] = biquad -a1 (role EQ, PROVEN)
w72 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x0A] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0A] = biquad -a2 (role EQ, PROVEN)
w73 01022FF687 mac.st tb,(p)-1
w74 0804816415 post acc,c
w75 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x0B] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0B] = biquad makeup (role EQ, PROVEN)
w76 0000203647 ld.st ta,(p)+3
w77 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x0C] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0C] = biquad b1 (role EQ, PROVEN)
w78 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x0D] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0D] = biquad b0 (role EQ, PROVEN)
w79 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x0E] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0E] = biquad b2 (role EQ, PROVEN)
w80 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x0F] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x0F] = biquad -a1 (role EQ, PROVEN)
w81 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x10] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x10] = biquad -a2 (role EQ, PROVEN)
w82 01022FF687 mac.st tb,(p)-1
w83 0804816415 post acc,c
w84 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x11] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x11] = biquad makeup (role EQ, PROVEN)
w85 0000203647 ld.st ta,(p)+3
w86 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x12] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x12] = biquad b1 (role EQ, PROVEN)
w87 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x13] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x13] = biquad b0 (role EQ, PROVEN)
w88 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x14] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x14] = biquad b2 (role EQ, PROVEN)
w89 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x15] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x15] = biquad -a1 (role EQ, PROVEN)
w90 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x16] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x16] = biquad -a2 (role EQ, PROVEN)
w91 01022FF687 mac.st tb,(p)-1
w92 0804816415 post acc,c
w93 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x17] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x17] = biquad makeup (role EQ, PROVEN)
w94 0000203647 ld.st ta,(p)+3
w95 0000A001D3 ld.ta (p),c+,(p)+0
; C-RAM[0x18] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x18] = biquad b1 (role EQ, PROVEN)
w96 0212A01412 mac acc,c+,(p)+1 ; mem[p]<-acc, acc=0
; C-RAM[0x19] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x19] = biquad b0 (role EQ, PROVEN)
w97 0202A011D5 mac (p),c+,(p)+1
; C-RAM[0x1A] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1A] = biquad b2 (role EQ, PROVEN)
w98 0202A011D4 mac.tb (p),c+,(p)+1
; C-RAM[0x1B] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1B] = biquad -a1 (role EQ, PROVEN)
w99 0202A001D5 mac (p),c+,(p)+0
; C-RAM[0x1C] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1C] = biquad -a2 (role EQ, PROVEN)
w100 01022FF687 mac.st tb,(p)-1
w101 0804816415 post acc,c
w102 0212AFF407 mac.st acc,c+,(p)-1 ; mem[p]<-acc, acc=0
; C-RAM[0x1D] (coeff, base 0x00 MEASURED)
; coeff C-RAM[0x1D] = biquad makeup (role EQ, PROVEN)
w103 0880130647 dly.r dsc[k],p+48
w104 042810E000 ?word 0x042810E000 ; 428.1.0E.000 hi12{END f31=4 ?5 res=020} [END OF BLOCK, unit 0 -- CALL/RETURN -- and still performs the rest of the word]
HLE reconstruction (MAME, kn5000_tonegen.cpp)
The decode of the bytecode above, rebuilt as audible DSP. Two parts: the parameter refresh
(reads the decoded C-RAM coefficient cells once per update) and the per-sample insert (the
signal processing). Default OFF, behind the DSPHLE research port. Source:
src/mame/matsushita/kn5000_tonegen.cpp.
Parameter refresh (decode the C-RAM coefficients):
const bool eq_hle = (dsphle == 1);
if (eq_hle)
{
// The raw C-RAM cells are NOT direct-form biquad coefficients: eq_spectral_ab.py
// proved no permutation of {cell0..5} -> {b0,b1,b2,a1,a2} yields a valid peaking
// response (that needs the undecoded x/y-history realization, walled N2). But the
// DESIGN PARAMETERS are recoverable from the cells, and building textbook RBJ
// peaking biquads from them is the validated HLE route (dsp/hle/). Per band:
// * FREQUENCY (SOLID, MEASURED, N1'): cell 0x03 == 2*cos w0 -> w0 = acos(c3/2).
// Cross-checked: cell 0x00 == -c3/2 == -cos w0 in every capture, and band 1's
// 0x03 gives 966 Hz (== N1' band-1 centre). Universal across bands.
// * GAIN (MEASURED per band): A^2 == 1 + G[band]*(c1-0.5). Cell base+1 is
// EXACTLY 0.5 (0x200000) at 0 dB -- for every band, and under a frequency-only edit
// -- and deviates only under a gain edit; so (c1-0.5) is the pure, frequency-
// INDEPENDENT gain signal (unlike (c1-c2), which an FC edit would misread as
// +31 dB). Each band's slope G was fit by driving THAT band's gain +12 dB on the
// panel and reading its cell (dsp/tools/eq_band_gain_calibrate.py): the slope is
// NOT uniform -- it roughly HALVES per band (the gain cell moves ~2x further per dB
// as the band centre rises), so a single constant is wrong for bands 1-4.
// * Q (ASSUMED): 2.0. Q sets bandwidth only; the peak height that the
// spectral A/B checks == the designed dB regardless of Q.
// Coefficients are RBJ (Audio EQ Cookbook), normalised by a0. Default OFF; validated
// offline (eq_rbj_reconstruct_ab.py) and by in-emulator spectral A/B at bands 0 and 2
// (+~11 dB at the band centre, flat elsewhere). See N1-EQ-COEFFICIENT-MEMORY note.
constexpr double GAIN_G[5] = { 465.8, 225.8, 114.2, 58.3, 30.5 }; // per-band A^2 slope
constexpr double QVAL = 2.0; // assumed band Q (documented)
auto q22 = [](uint32_t v) -> double {
int32_t s = (v & 0x800000) ? int32_t(v) - 0x1000000 : int32_t(v);
return double(s) / 4194304.0; };
for (int band = 0; band < 5; band++)
{
const uint8_t base = uint8_t(band * 6);
const u32 r1 = m_dsp1->cram_read(base + 1);
const u32 r3 = m_dsp1->cram_read(base + 3);
double c1 = q22(r1); // gain cell
double c3 = q22(r3); // frequency cell
// m_cram is read at one of two scales that differ by exactly 2x (N1':
// "operand = C-RAM cell >> 1"). The capture dumps recorded the CELL scale
// (0x03 = 2*cos w0, gain baseline 0.5); at runtime, when the EQ insert reads
// m_cram without the LLE having executed (the normal HLE case, DSPCFG off),
// m_cram holds the firmware-uploaded OPERAND scale -- exactly half (0x03 =
// cos w0, baseline 0.25). Detect via the frequency cell: all five fixed band
// centres (673..3219 Hz) have cos w0 in 0.89..0.995, so |c3|<=1 is operand
// scale (double both cells back to the cell scale the formula is calibrated on);
// |c3|>1 is already cell scale. MEASURED: runtime c3=0.9954, c1=0.2532 (+12 dB)
// == exactly half the dump's 1.9908 / 0.50654.
const double norm = (std::fabs(c3) <= 1.0) ? 2.0 : 1.0;
c1 *= norm; c3 *= norm;
const double cosw0 = std::clamp(c3 * 0.5, -0.9995, 0.9995);
const double asq = 1.0 + GAIN_G[band] * (c1 - 0.5); // A^2; >1 boost, <1 cut
if (KN5000_EQHLE_DEBUG)
{
static u32 dbgcall = 0; static int dbgn = 0; static bool dbgthis = false;
if (band == 0) { dbgthis = ((dbgcall++ % 400) == 0 && dbgn < 40); if (dbgthis) dbgn++; }
if (dbgthis)
fprintf(stderr, "### EQHLE t=%.2f b%d r1=%06X r3=%06X c1=%.4f c3=%.4f asq=%.3f\n",
machine().time().as_double(), band, r1, r3, c1, c3, asq);
}
// A band is ACTIVE only if its cells are a plausible peaking design: c3 is a
// real 2*cos w0 (|c3|<=2) and asq is a sane gain (about -17..+34 dB). Zeroed or
// not-yet-uploaded C-RAM (c1=c3=0 -> asq=-226) or garbage -> unity passthrough,
// so a missing/idle EQ can never turn into the broadband cut that a raw A=0.1
// cascade would produce.
if (std::fabs(c3) > 2.001 || asq < 0.02 || asq > 50.0 ||
std::fabs(asq - 1.0) < 1e-4) // out-of-range / 0 dB / unused -> passthrough
{
m_eq_l[band].set_coeffs(1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
m_eq_r[band].set_coeffs(1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
continue;
}
const double A = std::sqrt(std::max(asq, 0.01));
const double w0 = std::acos(cosw0);
const double alpha = std::sin(w0) / (2.0 * QVAL);
const double b0 = 1.0 + alpha * A;
const double b1 = -2.0 * cosw0;
const double b2 = 1.0 - alpha * A;
const double a0 = 1.0 + alpha / A;
const double a1 = -2.0 * cosw0;
const double a2 = 1.0 - alpha / A;
m_eq_l[band].set_coeffs(b0 / a0, b1 / a0, b2 / a0, a1 / a0, a2 / a0, 1.0);
m_eq_r[band].set_coeffs(b0 / a0, b1 / a0, b2 / a0, a1 / a0, a2 / a0, 1.0);
}
}
Per-sample insert (the reconstructed signal path):
if (eq_hle)
{
double yl = double(mix_l) / 32768.0;
double yr = double(mix_r) / 32768.0;
for (int band = 0; band < 5; band++)
{
yl = m_eq_l[band].process_one(yl);
yr = m_eq_r[band].process_one(yr);
}
mix_l = int32_t(yl * 32768.0);
mix_r = int32_t(yr * 32768.0);
}