Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
spu [2024/07/01 11:27] – removed - external edit (Unknown date) 127.0.0.1 | spu [2025/02/08 17:48] (current) – [Beat interrupts] simer | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | The sound controller has 16 channels with configurable replay frequencies, | ||
+ | |||
+ | ====== Channel register map ====== | ||
+ | |||
+ | ^ Address ^ Function | ||
+ | | 30x0 | Channel X sample address | | ||
+ | | 30x1 | Channel X control (bit 14: 16M, 13-12: ToneMode, 11-6: Loop address segment, 5-0: sample address segment) | | ||
+ | | 30x2 | Channel X loop address | ||
+ | | 30x3 | Channel X panning and volume (7 bits each) | | ||
+ | | 30x4 | Channel X envelope target volume and increment | | ||
+ | | 30x5 | Channel X envelope CNT and EDD (?) | | ||
+ | | 30x6 | Channel X repeat count (bits 15-9), repeat enable (8), Envelope load (7-0) | | ||
+ | | 30x7 | Channel X IRQ address (15-9), IRQ enable, envelope segment (6-0) | | ||
+ | | 30x8 | Channel X envelope address | ||
+ | | 30x9 | Channel X wave data 0 | | ||
+ | | 30xA | Channel X ramp down offset (15-9) and envelope address offset (8-0) | | ||
+ | | 30xB | Channel X wave data | | ||
+ | | 32x0 | Phase high bits (2-0) | | ||
+ | | 32x1 | Phase accumulator high (2-0) | | ||
+ | | 32x2 | Target phase high (2-0) | | ||
+ | | 32x3 | Ramp down clock | | ||
+ | | 32x4 | Phase low bits | | ||
+ | | 32x5 | Phase accumulator low bits | | ||
+ | | 32x6 | Target phase low bits | | ||
+ | | 32x7 | Phase control: time step (15-13), sign (12), offset (11-0) | ||
+ | |||
+ | ====== Global register map ====== | ||
+ | |||
+ | ^ Address ^ Function | ||
+ | | 3400 | Channel enable (1 bit per channel) | ||
+ | | 3401 | Main volume (7 bits) | | ||
+ | | 3402 | Channel FIQ enable | ||
+ | | 3403 | Channel FIQ status | ||
+ | | 3404 | Beat base counter | ||
+ | | 3405 | Beat counter (13-0), IRQ enable (15) and status (14) | | ||
+ | | 3406 | Envelope interval, channels 0-3 | | ||
+ | | 3407 | ... channels 4-7 | | ||
+ | | 3408 | ... channels 8-11 | | ||
+ | | 3409 | ... channels 12-15 | | ||
+ | | 340A | Envelope fast ramp-down | ||
+ | | 340B | Channel stop status (1 bit per channel) | ||
+ | | 340C | Zero cross enable (1 bit per channel) | ||
+ | | 340D | Control flags: NoInt (9), LPEn (8), HVol(7-6), SOF (5), Init (3), PCM (2) | | ||
+ | | 340F | Channels status | ||
+ | | 3410 | Left mixer input | | ||
+ | | 3411 | Right mixer input | | ||
+ | | 3412 | Left mixer output | ||
+ | | 3413 | Right mixer output | ||
+ | | 3414 | Channel repeat enable (1 bit per channel) | | ||
+ | | 3415 | Channel envelope mode | | ||
+ | | 3416 | Channel tone release control | ||
+ | | 3417 | Channel envelope IRQ status | ||
+ | | 3418 | Channel pitch band enable | ||
+ | |||
+ | ====== Sound formats and tone modes ====== | ||
+ | The formats supported by the SPU is IMA ADPCM, 8-bit unsigned PCM and 16-bit unsigned PCM. | ||
+ | |||
+ | The sound format and tone mode used for each channel are controlled by the channel mode register (30x1), which contains the following fields: | ||
+ | |||
+ | * IMA ADPCM enabled (bit 15) | ||
+ | * Sample bit depth (bit 14) | ||
+ | * 0 - 8-bit PCM | ||
+ | * 1 - 16-bit PCM (should also be used for ADPCM) | ||
+ | * Tone mode (bits 12-13) | ||
+ | * 00 - software mode (software writes samples manually to wave data register) | ||
+ | * 01 - auto-end mode | ||
+ | * 10 - auto-repeat mode | ||
+ | * 11 - reserved | ||
+ | * High bits (16-21) of loop address (bits 6-11) | ||
+ | * High bits (16-21) of wave address (bits 0-5) | ||
+ | |||
+ | The low 16 bits of the wave address and loop address are stored in 30x0 and 30x2 respectively. | ||
+ | |||
+ | The auto-end and auto-repeat modes automatically fetch samples during play from the value address pointed at by the wave address register, | ||
+ | which is automatically incremented by hardware during playing. | ||
+ | When an end marker value is fetched (FF in any of the word halves for 8-bit PCM and FFFF for 16-bit PCM and ADPCM), the hardware will either | ||
+ | stop the channel when in auto-end mode or reset the wave address to the value of the loop address when in auto-repeat mode. | ||
+ | |||
+ | ===== Channel phase logic ===== | ||
+ | The Phase (32x0, 32x4) and Phase Accumulator (32x1, 32x5) registers are 19-bit registers used for | ||
+ | linearly interpolating between samples and controlling the sample rate of each channel when in auto-end or auto-repeat mode. | ||
+ | |||
+ | For each 281250 Hz tick (27 MHz/96), the Phase Accumulator register for each active channel is increased | ||
+ | by the value of the Phase register. If the Phase Accumulator register wraps around, the next | ||
+ | sample is loaded from the wave address into the Wave Data register of the channel and the previous one | ||
+ | is moved into the Wave Data 0 register. | ||
+ | |||
+ | If interpolation is turned on in the control flag register (340D), the channel output is generated | ||
+ | by the linear interpolation formula '' | ||
+ | The exact precision used in the interpolation is currently unknown. | ||
+ | |||
+ | The phase value to use for a sample can be calculated from the audio sample rate with the formula '' | ||
+ | |||
+ | When initializing a channel, Wave Data and Wave Data 0 should be set to 0x8000 if 16-bit or ADPCM, or 0x8080 if 8-bit to avoid buggy interpolation in the initial sample. | ||
+ | |||
+ | FIXME Document the optional phase pitch bend feature | ||
+ | |||
+ | |||
+ | ====== Beat interrupts ====== | ||
+ | The SPU provides a beat interrupt which can be used to drive sequenced music tracks. | ||
+ | |||
+ | Beat interrupts are enabled by writing to the enable bit (bit 15) of the beat count register (0x3405). | ||
+ | |||
+ | When enabled, the beat count will decrease at a regular rate governed by the beat base count register. When the beat count reaches zero, the beat interrupt will trigger IRQ4 in the CPU. The interrupt is acknowledged by writing 1 to the status bit (bit 14). The beat count is not automatically reset, instead the program should fill the beat count field with a new value. | ||
+ | |||
+ | The beat base count register (0x3404) defines the rate in which the beat count is automatically decreased as '' | ||