Audio System
Created by: phil, Last modification: Sun 09 of Aug, 2009 (11:48 UTC)
Quick Links:
The sound system has four channels which play signed eight bit samples. The frequency (period) of each channel can be independently set and has a resolution of 1 clock cycle (62.5 nS). There are 4 ports assigned to each channel covering location, length, period and volume.
Location:
- Sample data needs to be in signed raw 8 bit format and should be loaded into pages 4:7 of system memory (ie: $20000-$3FFFF). The location ports hold a 16 bit value which is an offset in words from the start of the section of memory, therefore samples must be start on even addresses.
Length:
- The length ports hold a 16 bit value equal to the number of words in each sample, therefore samples must always be an even number of bytes long.
Period:
- The period ports hold a 16 bit value equal to the number of systems clocks that must pass between each sample byte:
How to calculate the period:
Period = 16,000,000 / desired sample output rate
The minimum period value is around 512 (corresponds to a sample rate of ~31KHz) - this is because the hardware pre-fetches 2 samples during DMA per scanline (and there is a couple of cycles overhead etc)
For pure tones, the output frequency depends on the number of samples in your waveform that constitute one cycle, so if the sample has EG: 16 bytes in one cycle, the period value required to play it at a desired frequency is calculated thus:
Period = 16,000,000 / (samples per cycle * frequency)
Period = 16,000,000 / desired sample output rate
The minimum period value is around 512 (corresponds to a sample rate of ~31KHz) - this is because the hardware pre-fetches 2 samples during DMA per scanline (and there is a couple of cycles overhead etc)
For pure tones, the output frequency depends on the number of samples in your waveform that constitute one cycle, so if the sample has EG: 16 bytes in one cycle, the period value required to play it at a desired frequency is calculated thus:
Period = 16,000,000 / (samples per cycle * frequency)
Volume:
- The volume ports hold a single byte value in the range $00 (silence) to $40 (full volume) - in linear steps).
Samples are set up to play in a similar way to the Amiga Hardware, ie: You set the location, length, period and volume registers of a sound channel, then start the channel playing (with the relevant sys_audio_enable port bit). Once the channel is playing, its location and length registers can be updated - the channel will only fetch the new values once its original length value has counted down to zero (or you stop the channel for a while and restart it). If the registers are not changed, the channel simply loops around playing the same sample data until it is stopped.
Because of the way the sound hardware pre-fetches sample data, some care needs to be taken when setting up the registers. The recommended audio register setup procedure is as follows:
1. Wait for post-audio DMA time (EG: wait for bit 6 of vreg_read to change)
2. Stop the relevant audio channel(s), write the location, length, period and volume.
3. Wait for next post-audio DMA time (IE: At least one scanline delay)
4. Start the relevant audio channel(s)
1. Wait for post-audio DMA time (EG: wait for bit 6 of vreg_read to change)
2. Stop the relevant audio channel(s), write the location, length, period and volume.
3. Wait for next post-audio DMA time (IE: At least one scanline delay)
4. Start the relevant audio channel(s)
Advanced:
Its possible to use an interrupt to seamlessly switch between two or more sample buffers in order to play long samples without worrying about the exact timing. To do this you would start a channel playing, reload it with the second buffer ready for the first loop as normal, and then set up the audio interrupt so that it occurs upon the first loop (IE: just as the second buffer starts to play). In the IRQ service routine, you would set the channel location and length to point back to the first buffer, and on subsequent IRQs switch between the two buffers.
Note: The four audio loop flags are OR'd into a single interrupt source. It is up to the IRQ service routine to read bits 4:7 of the sys_audio_enable port, see which bits are set (and clear them on exit from the IRQ).