11.4.2020: work in progress - planned: overview over the sound routines used in the project. code excerpts of each class of routines, showing at least the main DSP loop. sound examples for each routine.

Sound Routines
General Structure
Routines involved:

$XXXX Init
$XXXX NmiHandler
$XXXX NoteNumberDisplay
$XXXX MarchingAnts

The sound generation software is started by calling its initialisation routine ('Init'). It does:

- set the screen characters to graphics mode
- set NMI jump address to the NmiHandler
- turn IRQ off
- set audio DACs initial value (0.0 Volt)
- sets digital out / filters to bypass
- calls ClearScreen routine
- displays 'Active' dot at left lower corner
- sets User Port direction register to input

Afterwards Init just runs a loop in which it checks for the ESC key and for the 'new note' flag, see below.

New Note Arrives

Sound routines are triggered from the sequencer via an NMI.

When an NMI arrives, the NMI handler routine sets a 'new note' flag by writing XX in memory address XXXX. It also stores the current state of the User Port at address XXXXX. This represents the 'note number', 256 possible ones from 00 to FF. However, the value FF cannot be reached since the sequencer uses it to indicate 'no note', and also a few other bytes have special functions: FE indicates 'turn all sound off' and 'FD' clears the computer screen.

Each sound routine must in very short intervals look at the new note flag and if it is raised, jump to the note shell routine. If not it continues to produce sound. The timing and latency of sound generation depends on how often the new note flag is tested.

The note shell routine fist resets the DACs and the VIA shift register to mute all sounds.

It resets the new note flag, and uses the stored User Port data to recall the start address of the now sound routine to be played. The assignment of note numbers to specific sound routines is done by two 256 byte lookup tables, containing their start addresses.

Each sound routine first calls a graphics routine which displays its 'note number' as two large hexadecimal digits on screen. Afterwards it executes the necessary initialisations and then starts executing the part which is responsible for actually making the sound.

Not each note calls a unique routine, most routines are triggered by multiple notes and use the individual note numbers to assign note-specific properties such as durations or pitches to each note.

Sound routines can either run continuous until interrupted by the next arriving note, or they can terminate after some time ('one-shot'). One-shot routines jump to the 'marching ants' routine, which horizontally scrolls two screen segments above and below the number display. The content of these segments are set by the least significant bit of the last incoming note, creating a pattern of either solid green or black characters. Scrolling can only happen as long as the CPU is idle. For continuous routines this is not possible and also some routines which create percussive sounds, for reasons of CPU efficiency still have to run continuous and cannot terminate into the marching ants.

For CBM 8032 AV several classes of sound routines have been developed.

DAC based:

* wavetable lookup oscillators
* decaying wavetables
* decaying wavetables with pitch envelope
* decaying noise, mono or stereo
* static noise, mono or stereo
* simple 256 sample one-shot playback
* Karplus-Strong algorithms

Shift Register based:

* simple beeps
* band limited noise and sample & hold
* complex evolving sounds

Some notes trigger step-sequencer-like progressions, to either rotate through different waveforms in wavetable lookup oscillators or to create arpeggios / melodic sequences triggered by a single note.

Noise Generator Routines
The CBM 8032 provides a pseudo random number generator (PRNG) routine, which is called from $XXXX. It returns four random bytes, located at $XXXX to $XXXX. A single call of this routine takes around XX microseconds. This implies the fastest possible noise generator could not reach a sample rate above XXXX Hz. Thus, we use a much simpler and efficient algorithm. It utilises four blocks of precomputed random numbers, located at $XXXX to $XXXX and also returns four more or less random bytes.

The quality of this PNRG is pretty low, with distinct patterns and repetitions. This would be bad for any 'normal' use of random numbers, but has the not entirely undesired side effect of causing audible artefacts such as distinct tonalities or repeated segments, giving the noise a characteristic 'digital' timbre.