Files
psxrecomp/runtime/tests/test_spu_sample_scheduler_default.py
Pegasus 6262888ec6 audio: prime SPU scheduler before first sample deadline
(cherry picked from commit 54c26abcd4c97b726ceb9adcfa5608bc4080746a)
2026-08-26 21:43:28 +03:00

42 lines
1.8 KiB
Python

"""Guard the title-neutral SPU IRQ scheduling correction.
SPU RAM IRQ-address hits can occur more than once per video frame. The runtime
must let guest code acknowledge and re-arm IRQ9 between 44.1-kHz samples rather
than rendering a VBlank-sized chunk and collapsing the hits into one latch.
"""
from pathlib import Path
import re
ROOT = Path(__file__).resolve().parents[2]
INTERRUPTS = (ROOT / "runtime" / "src" / "interrupts.c").read_text(encoding="utf-8")
CYCLES = (ROOT / "runtime" / "src" / "psx_cycles.c").read_text(encoding="utf-8")
MAIN = (ROOT / "runtime" / "src" / "main.cpp").read_text(encoding="utf-8")
# Production defaults to faithful per-sample scheduling. Keep only an explicit
# zero-valued diagnostic opt-out for comparing old captures.
assert 'getenv("PSX_SPU_SAMPLE_EVENTS")' in INTERRUPTS
assert 'enabled = (!e || !*e || strcmp(e, "0") != 0) ? 1 : 0;' in INTERRUPTS
# The sample boundary must participate in the common device-deadline slicer and
# be serviced after each charged slice, otherwise the default above is inert.
assert "psx_spu_sample_event_cycles_to_next()" in CYCLES
assert "psx_spu_sample_event_service();" in CYCLES
# Register and prime the SPU pump in both the visible and headless frontends.
# A frame-count-only headless smoke must exercise the same sample epoch as the
# operator build, and the first service must not establish a shifted epoch.
prime = re.compile(
r"psx_set_midframe_audio_pump\(sdl_audio_pump_midframe\);"
r".{0,500}?sdl_audio_pump_midframe\(\);",
re.DOTALL,
)
assert len(prime.findall(MAIN)) >= 2
assert MAIN.index("if (g_headless) {\n audio_trace_init();") < MAIN.index(
'std::fprintf(stdout, "psxrecomp: headless frontend enabled\\n");'
)
# One hardware SPU output sample is exactly 768 CPU cycles.
assert "psx_get_cycle_count() % 768u" in INTERRUPTS