Skip to content

audio: schedule SPU IRQ samples by guest clock; prime the SPU scheduler before the first sample deadline - #239

Merged
mstan merged 4 commits into
mstan:masterfrom
Alexbeav:pr/spu-scheduler-guest-clock
Aug 28, 2026
Merged

audio: schedule SPU IRQ samples by guest clock; prime the SPU scheduler before the first sample deadline#239
mstan merged 4 commits into
mstan:masterfrom
Alexbeav:pr/spu-scheduler-guest-clock

Conversation

@Alexbeav

Copy link
Copy Markdown
Contributor

Summary

SPU IRQ sample events are scheduled on the guest cycle clock (768 CPU cycles per 44.1 kHz sample) rather than host frames, and the scheduler is primed before the first deadline so the first service cannot establish a shifted epoch. Fixes audio pitch/skew on titles whose SPU IRQ drives streaming (measured 27 kHz -> 59 kHz effective on Gran Turismo).

Commits

  • 6262888 audio: prime SPU scheduler before first sample deadline
  • a74fd9f runtime: schedule SPU IRQ samples by guest clock

Scope

6 files changed, 148 insertions(+)

Validation

Cherry-picked from the Alexbeav/psxrecomp main line, where the same changes pass the recompiler/runtime/runtime-ui ctest gates with only the pre-existing failures (aot_overlay_discovery, release_zip, gte_register_access_test link). This branch was also built on mstan/master as of 01c647e with the same result.

Amendment

The branch now also carries db2c638a (SPU sample-event test stubs + PAL-aware load-accel guard) — without it psx_cycle_event_boundaries_test does not link on the pristine base. Rebuilt at a36b504d: only the accepted gte_register_access_test link fails; psx_cycle_event_boundaries_test passes; test_mod_load_acceleration.py and test_spu_sample_scheduler_default.py pass.

Pegasus and others added 3 commits August 26, 2026 21:43
…bs; PAL-aware frame period in load-accel guard)

(cherry picked from commit db2c638)
@mstan

mstan commented Aug 27, 2026

Copy link
Copy Markdown
Owner

I think there may be one idle-skip gap here, but I want to check whether you agree.

The new SPU sample event is included in the internal device slicer, but not in the idle-skip observable-event path. devices_cycles_to_next_idle_event() still considers VBlank/timer/CD/DMA/SIO only. If idle_skip is enabled and guest code is in a pure poll loop waiting on SPU IRQ9, it looks like the skip can advance across multiple 768-cycle SPU sample boundaries before guest code gets a chance to acknowledge and re-arm IRQ9.

Does that seem like a real gap to you? If so, would it make sense to include the SPU sample deadline in the idle-skip event distance when IRQ_SPU is unmasked, and add a regression test showing idle-skip stops at the first SPU sample boundary instead of crossing several?

The SPU sample event was part of the internal device slicer but not of the
idle-skip observable-event distance, so a poll loop waiting on SPU IRQ9 could
be skipped across several 768-cycle sample boundaries before it could
acknowledge and re-arm. Include the sample deadline in
devices_cycles_to_next_idle_event() when IRQ_SPU is unmasked (mask-gated like
the other sources), expose the distance through
psx_idle_cycles_to_next_observable_event() for tests, and extend
psx_cycle_event_boundaries_test: masked IRQ9 does not bound the skip; unmasked
IRQ9 stops it at the first sample boundary, never across later ones.
@Alexbeav

Copy link
Copy Markdown
Contributor Author

Yes, that is a real gap — the sample event was in the internal device slicer but not in the observable-event distance, so an idle-skip could cross several sample boundaries before the guest could acknowledge and re-arm IRQ9. Pushed e9f834d: devices_cycles_to_next_idle_event() now includes the SPU sample deadline when IRQ_SPU is unmasked (mask-gated like the other sources), the distance is exposed via psx_idle_cycles_to_next_observable_event() for tests, and psx_cycle_event_boundaries_test gained the regression case: with IRQ9 masked the deadline does not bound the skip; with it unmasked the skip stops at the first 768-cycle sample boundary and never crosses a later one.

@mstan
mstan merged commit 9436be3 into mstan:master Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants