Expand description
High-level PS1 SPU (Sound Processing Unit) API.
Turns SPU-programming-by-magic-numbers into typed primitives:
Voice– typed voice index in0..24.Pitch– Q5.12 sample-rate multiplier;Pitch::UNITY= 44100 Hz (one sample per SPU tick).Volume– per-voice / main-output signed linear gain.CdVolume– CD-DA / XA input signed Q15 gain.Adsr– typed envelope descriptor; builds the two-word SPU envelope register pair.SpuAddr– 8-byte-aligned SPU RAM pointer (the only shape voice-start / loop / transfer registers accept).
Typical boot sequence:
ⓘ
spu::init(); // turn the SPU on, sensible defaults
spu::set_main_volume(Volume::MAX, Volume::MAX);
spu::upload_adpcm(SpuAddr::new(0x1010), &TONE_SAMPLE);
let v = Voice::V0;
v.set_volume(Volume::MAX, Volume::MAX);
v.set_pitch(Pitch::UNITY);
v.set_start_addr(SpuAddr::new(0x1010));
v.set_adsr(Adsr::default_tone());
Voice::start(v.mask()); // start the tone§What this crate owns vs doesn’t
- Owns: typed register access, key-on/off masks, the ADPCM byte-stream upload path, ADSR encoding helpers, sample-start address alignment.
- Doesn’t own (yet): ADPCM encoder (ship pre-baked samples
instead – see
vendor/tone_*.adpcm, or cook.psauwithpsxed audio-pack), reverb preset tables, DMA-based sample upload. Those land as the ladder pulls them in.
§Q-format conventions
- Pitch: Q5.12 in a u16.
0x1000= 1.0 = the sample plays at its recorded rate (44100 Hz). Halving to0x0800drops an octave;0x2000raises one. Pitch field is 14 bits on hardware; values above0x3FFFclamp. - Volumes: i16. Sign carries, the magnitude is linear. Max
output is
0x3FFF(= 1.0);Volume::MAXalready uses this. Negative means “phase-inverted,” used for stereo tricks we don’t wire up here yet. - CD volumes: signed Q15. Max input gain is
0x7FFF, exposed asCdVolume::MAX. - SPU RAM addresses: stored in registers as
addr / 8,SpuAddrdoes the divide so the caller passes byte offsets.
Structs§
- Adsr
- ADSR envelope descriptor. Builds the pair of 16-bit envelope registers the SPU needs.
- CdVolume
- CD-DA / XA input volume.
- Pitch
- Q5.12 pitch / sample-rate multiplier.
0x1000= play at the sample’s recorded rate. Halving = one octave down, doubling = one octave up. - Spu
- The SPU’s memory-moving driver: it owns the SPU’s DMA channel, so the one operation that copies RAM into sound RAM, the ADPCM upload, is a method here and the borrow checker sees a second uploader.
- SpuAddr
- An 8-byte-aligned SPU RAM address.
- Voice
- A typed voice index in
0..24. Construct via theV0..V23constants orVoice::new. All per-voice operations are methods on this type. - Volume
- A 16-bit signed SPU voice/main volume.
Constants§
- SILENCE_
BLOCK - One ADPCM block of silence that loops on itself, for every one-shot’s
repeat address to point at. See [
SILENCE_BLOCK_BYTES].
Functions§
- enable_
cd_ audio - Enable or disable routing CD-DA/XA input into the SPU mixer.
- enable_
irq - Enable or disable the SPU’s address IRQ without changing other controls. Disabling clears the SPU latch. Acknowledging the CPU interrupt controller remains the caller’s responsibility, so ISR and polled users can differ.
- init
Deprecated - Reset the SPU to a sane playable state.
- irq_
pending Deprecated - Renamed to
is_irq_pending. - is_
irq_ pending - Whether the SPU’s address IRQ latch is set.
- set_
cd_ volume - Set the SPU CD input volume.
- set_
irq_ address - Set the sound RAM address that raises the SPU IRQ when accessed.
Address units are encoded by
SpuAddr; this does not enable the IRQ. - set_
main_ volume - Set the main L/R output volume that every voice mixes through.
- set_
noise_ clock - Set the shared noise-generator clock, SPUCNT bits 8..=13:
shift(0..=15) halves the frequency per step, 0 = highest pitch;step(0..=3) selects the +4..+7 fine increment. Applies to every voice routed to noise viaVoice::set_noise_mask. - upload_
adpcm Deprecated - Upload ADPCM sample bytes to SPU RAM.