Bad, vile and meaningless: Working on sidplay2 from Alan's clob

Emulating 6581 nonlinear distortion

I'm working on emulating C64's nonlinear distortion. Pay attention to the contents of directory c64-sw on my account.


The 6581 sound chip is beloved synthesized chip of Commodore 64. Currently, sidplay2 is the best emulator for the 6581 chip. However, due to several process deficiencies 6581 chips all have unique properties, most notable differences being in the makeup of the SID filter.

The SID filter is an analog circuit with controllable resonance (which you can think as filter amplificating a narrow band in the frequency response at the filter center frequency), controllable center frequency and 3 distinct outputs, the lowpass, the bandpass and the highpass.

The resultant design, operates correctly for low volumes, but as the chip drives greater resonances and more volume, the active components in the filter design go into "overdrive" and distort the sound heavily. This distortion is unique in every chip, but generally appears as hard edge in the sound. The distortion can get very heavy and almost completely drown every other sound.

To whet your appetite, here is the code required to simulate the linear or "perfect" part of the filter. For 3 outputs, only 3 lines of code are required:

    # the input is in Vi
    Vhp = Vbp / Q - Vlp - Vi
    Vlp -= w0 * Vbp
    Vbp -= w0 * Vhp

The values w0 and Q are the center and resonance in certain units. Typical values for these variables are w0 ~ 0.5 and Q ~ 1.0.

The nonlinear parts need some insight into the SID filter design. For these purposes, the circuit diagram of the filter has been discovered. The nonlinearities specifically arise because Bob Yannes did not use proper operational amplifiers in the design, but rather things called NMOS inverters, which can be made to act like amplifiers if a small bias voltage is applied to their input signal. However, when they go into "overdrive" they apparently react rather harshly.

Improvements in ReSID code so far suggested for Dag Lem

The frequency register to center frequency mapper was quite significantly incorrect, at least as far as I could determine based on the samplings from a 6581 I was able to obtain. (I actually wrote a small C64 basic program in ViCE emulator to determine the frequency response in different filter settings which somebody then ran on his C64 and sampled the output.)

The resonance register mapping to Q value in the ReSID library has rather small range, only from 0.707 to 1.707 (about +6 dB). A more appropriate range is from 0.9 to about 2.5 (about +10 dB), although I've so far not simulated this and the true range may be a bit different.

The order of computations in the filter simulation was subtly wrong, causing ripples in filter response where there probably should have been none.

The SID output stage mixes filter outputs with different weight factors compared to the output signal: bass approximately 3 dB attenuated, the bandpass approximately 4 dB attenuated, and the highpass approximately 6 dB attenuated.

Improvements in the nonlinear section

Under progress... Dag Lem does not want code which is not more or less provably correct. It may mean that I will maintain a separate nonlinearity patch against sidplay for all eternity, unless I can convince him of the approaches validity. Time will tell, I only started this on Saturday...

At the moment, I'm putting Vbp, Vlp and Vhp through tanh function after the values have been computed in such a fashion that values above 1.0 (or the maximum value) become severely clipped. In addition, I add a small 0.05 bias to produce asymmetric clipping of filter state variables.

The purpose of this emulation is to simulate the active components' nonlinearities as function of the difference in input and output. However, this simplistic approach has not yet yielded any useful results. Ideally, I was hoping that doing this would have significantly sifted the filter center frequency as the nonlinearities kick in, but the changes have been rather small and I must rethink this approach.

The most promising results so far have been obtained without touching the filter state! I added a nonlinearity term into the final output of this type:

    Vf += pow((Vlp - Vbp) / c, 3)

It seems that a 3rd degree polynomial has an acceptable shape. To spell this out, and ignoring the fudge factor c, we are raising the difference in outputs of the bandpass and lowpass path (with bandpass taken negative) to the third power and adding it into the output. This distorts the sound beautifully and quite authentically!

Now, my next step will probably be to combine this fact with the filter state computation, that is, adding a nonlinearity term, probably into Vbp, that is of the same type. This hopefully causes also the massive filter shape changes that have been observed.

Interesting test sids

Hardware to plug SID chips in

Catweasel Mk4 -- PCI card which can swallow two SID chips. On Linux, use hardsid drivers. Sidplay2 can play through them with --hardsid switch. On Windows, player called Acid64 can play the stuff.

Hardsid -- ISA card that can eat up to 4 SID chips. Same on Linux as CW MK4.

I was unlucky with my Catweasel cards. Jens Schönfield, the designer of the card said that 40 broken cards were released into the wild which have an incorrect resistor near the DC-DC inverter causing 6581 chips on such sids to not play correctly. Symptoms are things like heavy distortion, quiet sound, lacking some of the voices when filter is turned on, etc. (In general the 6581 behaves very oddly when it's not supplied with enough voltage to operate with.)

The solution is to tell the jens at ami dot ga about the problem, he'll repair the card for free. If you are good with soldering iron and do not fear surface mounted stuff, you can try replacing the faulty resistor yourself, but you better ask Jens for the details as I don't know them.

Debian's sidplay does not include support for using hardsid. You have to know your way around Debian a bit and find the hardsid-builder library and install it on your system manually, then recompile sidplay2 so it takes advantage of the hardsid library if available.

For hardsid kernel driver, go for and get the CVS release. You may still need to chmod /dev/sid for your user/group, that part of the install didn't seem to work automatically.