A SID file is a program, so playing it means running it. The explorer’s player runs the tune in an emulated C64 and records what the tune does to the SID chips, then turns that into sound with an emulated SID. It is written for this site from the public descriptions of the hardware; the open players (libsidplayfp and its reSIDfp engine) were read as references and were run, in a build kept outside the site, to check the result.
The options bar
| Option | Values | Effect |
|---|---|---|
| Song | 1 to the number of songs; the start song is the default | The accumulator for init is the song number minus one, and the song’s speed bit chooses the raster or the CIA interrupt. |
| Video clock | From the header, PAL, NTSC | The processor clock (985,248 or 1,022,727 Hz), the raster timing and the pitch. The header’s “unknown” and “both” play as PAL. |
| SID model | From the header, 6581, 8580 | Waveform and filter behaviour, and the size of the volume-register click. The header’s “unknown” plays as a 6581; for versions 3 and 4 each chip has its own model. |
| Length | 1 to 300 seconds, 30 by default | How much of the song is played out and analysed. A SID file does not say how long a song lasts. |
| Mute voice 1, 2, 3 | on or off | Silences that voice of every SID chip in the mix (the voice tracks are silent for a muted voice too). |
Changing an option reads the file again; the sound is made when the Registers or Playback tab is first shown.
What is emulated
- The 6510 and the C64 around it (C64 environment).
- Each SID oscillator and envelope is stepped on every processor cycle: the 24-bit phase counters with sync, ring modulation and the test bit, the 23-bit noise register, the 15-bit envelope rate counter with its exponential stages and the delay bug (SID registers).
- The output is made at four times the sample rate (176,400 Hz): waveforms and the filter are evaluated at that rate and a 64-tap windowed-sinc filter takes the result down to 44,100 Hz, so the high harmonics of a sawtooth or a pulse do not fold back as noise. A 16 Hz high-pass takes out the constant level, as the chip’s output stage does.
- The mix goes to one channel for one SID and to two for several, by the panning of the header (several SID chips).
The Playback tab shows the mix and each voice of the first chip alone (before the filter, at the level it has in the mix), and plays them with the browser’s audio. The Registers tab shows what the tune did to the registers. An analysis of 30 seconds takes a few seconds on an ordinary computer: the player runs several times faster than real time.
How it was checked
The reference is sidplayfp 3.2.3 with libsidplayfp 3.1.2 and libresidfp 1.3.0 (the reSIDfp engine), built from source and run on the same files to make 44.1 kHz mono WAV files. Two kinds of file were compared:
- Small tunes built for the purpose (62 were built, 31 in the final comparison): one voice with each waveform, narrow pulse, an envelope, three voices, sync, ring modulation, noise through the filter at 23 cutoff settings on the 6581 and 13 on the 8580, with resonance, band-pass and high-pass, and the volume register toggled at a few hundred hertz.
- 60 real tunes from the High Voltage SID Collection, picked at regular steps through the collection’s list: PSID and RSID, versions 2, 3 and 4, with two and three chips, with samples, 10 seconds of each.
Waveforms cannot be compared sample by sample: the two players differ by about 0.02 per cent in pitch and start their voices at different instants, and two voices at different pitches drift apart in phase. The comparison is of the energy in 36 frequency bands from 60 Hz to 16 kHz in frames of 2,048 samples, after taking out the overall level difference.
| Result | What was found |
|---|---|
| One voice (triangle, sawtooth, pulse, noise, envelope, 6581 and 8580) | Level within 0.1 dB (noise 0.6 dB); median band difference 0.2 to 0.7 dB; sample-wise correlation of 0.996 to 0.999 in windows of 0.1 s. |
| Several voices, sync and ring modulation | Level within 0.5 dB; median band difference 0.3 to 0.7 dB. |
| 6581 low-pass, cutoff $080 to $7FF | Level within 0.5 dB; median band difference 0.4 to 1.6 dB. |
| 8580 low-pass, cutoff $100 to $7FF | Level within 0.3 dB; median band difference 0.3 to 0.4 dB. |
| 6581 band-pass and high-pass | Level 3 and 6 dB high; median band difference 0.7 and 2.6 dB. |
| The volume register as a sample output | Level within 1.5 dB; the spectrum of the square wave differs more (a median band difference of 7 dB). |
| 60 real tunes | Level difference: median 0.5 dB, worst 4 dB. Median band difference of a tune: median 1.7 dB, 90th percentile 3.7 dB, worst 8.4 dB. |
The processor was run through Klaus Dormann’s 6502 functional test (all documented instructions, flags, addressing modes and decimal mode) and passes.
Two real tunes showed missing behaviour that is now in: the write-back in read-modify-write instructions (a tune acknowledged its raster interrupt with it) and the
read of the byte after an instruction with no operand (a tune acknowledged its NMI by running RTI from $DD0C).
How the filter was fitted
The filter is a two-pole state-variable filter, evaluated at 176,400 Hz, with low-pass, band-pass and high-pass outputs and a resonance from a quality of 0.71 (resonance 0) to 1.7. Its cutoff for each cutoff-register value was found by playing filtered noise through the reference and finding, for each register value, the cutoff at which this filter’s spectrum matched the reference’s best: 23 points for the 6581 and 13 for the 8580, with the values between interpolated. The fits agree with the reference to within 1.3 dB for the 6581 and 0.3 dB for the 8580 at those points. On the 6581 the reference lets less through at low cutoffs, which is corrected by a gain that depends on the cutoff, and a small part of the input is added to each output (about 1 per cent for the low-pass, 15 to 28 per cent for the high-pass and band-pass) because the reference’s band-pass and high-pass do not stop low frequencies completely. These are fitted numbers, not a model of the analogue circuit.
Where it differs from a real C64 and from the reference
- Combined waveforms (two or more of triangle, sawtooth and pulse) are the AND of the single waveforms; a real chip gives different values that differ between the 6581 and the 8580 and between chips. Noise combined with another waveform is silent.
- The filter has no distortion and no chip-to-chip differences; the 6581 band-pass and high-pass modes and a high resonance (the reference is 3 to 10 dB different at some settings) are fitted less well than the low-pass.
- The processor takes whole instructions: an interrupt or a register write falls on an instruction boundary, and the VIC-II takes no cycles from it (no bad lines, no sprites). A tune whose digitised sound depends on the exact cycle is not exact.
- Unstable undocumented instructions (XAA, LAX #, SHA, SHX, SHY, TAS) are approximated with the usual constants.
- No BASIC ROM (RSID tunes that run BASIC are not played), no character ROM and no real KERNAL: a tune that calls KERNAL routines other than the interrupt entries gets a return at once.
- The volume-register sample playback is approximate in the spectrum, as the table shows.