Expand description
Sample playback and shared voice management on the SPU.
Four programs on the PSoXide demo disc grew their own copy of this: the
launcher, VoXide, NitroXide and the Celeste collection. Three of them are
not engine applications, so the helpers in psx-engine were out of reach
and each rewrote the same three things. That mattered more than the
duplication itself, because what they were rewriting is the part emulators
get wrong:
- A one-shot’s repeat address has to be written by hand. Silicon latches it
only from a block carrying the loop-start flag, and a one-shot has none,
so it otherwise keeps whatever the previous sound left there and the
voice ends up playing an unrelated sample. [
psx_spu::Voice:: configure_sample] does this now; going through it is the point. - A one-shot does not stop itself. END drops the voice into RELEASE at the
ADSR’s release rate rather than muting it, so a slow release leaves the
voice running audibly past its own data. A fast release hides that, which
is why the bug survived so long: the Celeste collection is inaudibly
wrong rather than right. The honest fix is to silence the voice on a
clock, which is what
Player::tickdoes. - Voices have to be shared out, or a new sound cuts off the one before it.
ⓘ
let mut bank = Bank::new(SpuAddr::new(0x1010));
let blip = bank.upload_on(&mut spu, include_bytes!("blip.psau"));
let mut player: Player<3> = Player::new([Voice::V0, Voice::V1, Voice::V2], 60);
// once a frame
player.tick(tick);
if pressed { player.play(&OneShot::new(blip, Volume::HALF), tick); }Map ambience whose ADPCM carries loop flags uses LoopingSample.
Structs§
- Bank
- A sequential SPU RAM allocator: uploads cooked
.psausamples one after another and hands back where each landed. - Looping
Sample - A resident ADPCM sample whose cooked block flags form a hardware loop.
- OneShot
- A sample with the settings it should be played at.
- Player
- Plays one-shots across a fixed set of voices, silencing each when its sample has run out.
- Sample
- A sample resident in SPU RAM.
Constants§
- PARKING_
TAIL - One ADPCM block of silence that loops onto itself, written after every uploaded sample so a voice running past its own END lands on nothing.