libsidplayfp
1.8.7
|
#include <Filter6581.h>
Public Member Functions | |
int | clock (int voice1, int voice2, int voice3) |
void | input (int sample) |
void | updatedCenterFrequency () |
void | updatedResonance () |
void | updatedMixing () |
void | setFilterCurve (double curvePosition) |
![]() | |
void | enable (bool enable) |
void | reset () |
void | writeFC_LO (unsigned char fc_lo) |
void | writeFC_HI (unsigned char fc_hi) |
void | writeRES_FILT (unsigned char res_filt) |
void | writeMODE_VOL (unsigned char mode_vol) |
Additional Inherited Members | |
![]() | |
unsigned int | fc |
Filter cutoff frequency. | |
unsigned char | res |
Filter resonance. | |
unsigned char | vol |
Current volume. | |
bool | filt1 |
Routing to filter or outside filter. | |
bool | filt2 |
bool | filt3 |
bool | filtE |
bool | voice3off |
Switch voice 3 off. | |
bool | hp |
Highpass, bandpass, and lowpass filter modes. | |
bool | bp |
bool | lp |
The SID filter is modeled with a two-integrator-loop biquadratic filter, which has been confirmed by Bob Yannes to be the actual circuit used in the SID chip.
Measurements show that excellent emulation of the SID filter is achieved, except when high resonance is combined with high sustain levels. In this case the SID op-amps are performing less than ideally and are causing some peculiar behavior of the SID filter. This however seems to have more effect on the overall amplitude than on the color of the sound.
The theory for the filter circuit can be found in "Microelectric Circuits" by Adel S. Sedra and Kenneth C. Smith. The circuit is modeled based on the explanation found there except that an additional inverter is used in the feedback from the bandpass output, allowing the summer op-amp to operate in single-ended mode. This yields filter outputs with levels independent of Q, which corresponds with the results obtained from a real SID.
We have been able to model the summer and the two integrators of the circuit to form components of an IIR filter. Vhp is the output of the summer, Vbp is the output of the first integrator, and Vlp is the output of the second integrator in the filter circuit.
According to Bob Yannes, the active stages of the SID filter are not really op-amps. Rather, simple NMOS inverters are used. By biasing an inverter into its region of quasi-linear operation using a feedback resistor from input to output, a MOS inverter can be made to act like an op-amp for small signals centered around the switching threshold.
In 2008, Michael Huth facilitated closer investigation of the SID 6581 filter circuit by publishing high quality microscope photographs of the die. Tommi Lempinen has done an impressive work on re-vectorizing and annotating the die photographs, substantially simplifying further analysis of the filter circuit.
The filter schematics below are reverse engineered from these re-vectorized and annotated die photographs. While the filter first depicted in reSID 0.9 is a correct model of the basic filter, the schematics are now completed with the audio mixer and output stage, including details on intended relative resistor values. Also included are schematics for the NMOS FET voltage controlled resistors (VCRs) used to control cutoff frequency, the DAC which controls the VCRs, the NMOS op-amps, and the output buffer.
| | | –1R1– -- D7 | | —R1– | | | | | | |–2R1– --| D6 | | ---------—<A]--—| | $17 | | | |–4R1– --| D5 1=open | (3.5R1) | | | | | | | –8R1– --| D4 | (7.0R1) | | | | $17 | | (CAP2B) | (CAP1B) | 0=to mixer | –R8– —R8– —C—| —C—| 1=to filter | | | | | | | | ---—R8–|--—[A>–|–Rw--—[A>–|–Rw--—[A>–| ve (EXT IN) | | | | D3 \ ------------—R8–| | | (CAP2A) | (CAP1A) | v3 | | vhp | vbp | vlp D2 | \ --------—R8–| --— | | | | v2 | | | | D1 | | \ ----—R8–| | -------------— | | | | v1 | | | | D0 | | | \ —R8– | | ------------------------— | | | | | | | R6 R6 R6 R6 R6 R6 R6 | | | | $18 | | | $18 | \ | | D7: 1=open \ \ \ D6 - D4: 0=open | | | | | | | ------------------------------— 12V | | D3 –/ –1R2– | | —R8– | | —R2– | | | | D2 |–/ –2R2–| | | ||– ---—[A>------—| |--—[A>--—|| D1 |–/ –4R2–| (4.25R2) ||– $18 | | | 0=open D0 –/ –8R2– (8.75R2) |
vo (AUDIO OUT)
v1 - voice 1 v2 - voice 2 v3 - voice 3 ve - ext in vhp - highpass output vbp - bandpass output vlp - lowpass output vo - audio out [A> - single ended inverting op-amp (self-biased NMOS inverter) Rn - "resistors", implemented with custom NMOS FETs Rw - cutoff frequency resistor (VCR) C - capacitor
Vw
| | R1 | –R1–| | __|__ | --— | | | vi -------— -----— vo | | -—R24-—
vi - input vo - output Rn - "resistors", implemented with custom NMOS FETs Vw - voltage from 11-bit DAC (frequency cutoff control)
12V 10 9 8 7 6 5 4 3 2 1 0 VGND | | | | | | | | | | | | | Missing 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R termination | | | | | | | | | | | | | Vw -—R—R—R—R—R—R—R—R—R—R—R– —
Bit on: 12V Bit off: 5V (VGND)
12V | -----------| | | | ------| | | | | | ||-- | --|| | ||-- ||-- |
vi --—|| |------— vo
– | ||
---|---|---|
----— | ||
– | ||
– |
–|| | | | ||– | | | | | | | --------—| | | | | | | | GND |
vi - input vo - output
12V | | ||--
vi --—|| ||– | |---— vo | (AUDIO Rext OUT) | |
GND
vi - input vo - output Rext - external resistor, 1kOhm ~~~ Notes:
The external resistor Rext is needed to complete the NMOS voltage follower, this resistor has a recommended value of 1kOhm.
Die photographs show that actually, two NMOS transistors are used in the voltage follower. However the two transistors are coupled in parallel (all terminals are pairwise common), which implies that we can model the two transistors as one.
|
virtual |
SID clocking - 1 cycle
v1 | voice 1 in |
v2 | voice 2 in |
v3 | voice 3 in |
Implements reSIDfp::Filter.
void reSIDfp::Filter6581::setFilterCurve | ( | double | curvePosition | ) |
Set filter curve type based on single parameter.
curvePosition | 0 .. 1, where 0 sets center frequency high ("light") and 1 sets it low ("dark"), default is 0.5 |
|
virtual |
Set filter cutoff frequency.
Implements reSIDfp::Filter.
|
virtual |
Mixing configuration modified (offsets change)
Implements reSIDfp::Filter.
|
inlinevirtual |
Set filter resonance.
In the MOS 6581, 1/Q is controlled linearly by res.
Implements reSIDfp::Filter.