Skip to content

Add SPU mips tests (test on HW help needed)#2018

Draft
Xeeynamo wants to merge 8 commits into
grumpycoders:mainfrom
Xeeynamo:spu-mips-tests
Draft

Add SPU mips tests (test on HW help needed)#2018
Xeeynamo wants to merge 8 commits into
grumpycoders:mainfrom
Xeeynamo:spu-mips-tests

Conversation

@Xeeynamo

Copy link
Copy Markdown

I am experimenting a SPU regression suite on a SPCH-5552 to raise the base line to which emulators should adhere to reproduce PS1 sounds accurately.

As of today, tests are non-exhaustive and they occasionally suffer from synchronization issues. These tests aim to purely focus on ADPCM decoding, resampling and the rate ADSR envelopes change the voice volume given a certain set-up. These tests should not depend to accurate CPU cycles, as it would defeat their purpose.

The PR is in draft. I am mostly requesting for feedback. The SPU synchronization is imperfect, and both ADPCM and voice tests might occasionally fail on real hardware. These tests have not been tested on older or newer PS1 revisions, on a PS2 or arcade boards. Tests hang on PCSX Redux due to the SPU Status bit11 flip not being implemented.

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 729087f0-a563-4df0-a016-572b4789f314

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nicolasnoble

Copy link
Copy Markdown
Member

I think this generally speaking looks good. We may want to avoid the run target in the Makefile and leave it to the operator to decide how to actually run those, given there's multiple harnesses around, but that's my only very small nit.

@Xeeynamo

Xeeynamo commented May 24, 2026

Copy link
Copy Markdown
Author

I think this generally speaking looks good. We may want to avoid the run target in the Makefile and leave it to the operator to decide how to actually run those, given there's multiple harnesses around, but that's my only very small nit.

Thanks for the feedback. I removed the run but kept spu_dump for simplicity. Let me know if you want that to be removed as well.

For the tests themselves, I reached a point where I am happy with what I wrote so far. I am happy to make further changes where I missed the mark.

These tests have been tested only on one console. Before I have the confidence to mark the PR as ready, I'd like help to collect the test run results from other consoles as well.

@Xeeynamo Xeeynamo changed the title [RFC] Add SPU mips tests Add SPU mips tests (test on HW help needed) May 25, 2026
The SPUVoice ad/sr fields became adsrLo/adsrHi in main; update the SPU
tests so they build against current main.

Signed-off-by: Nicolas 'Pixel' Noble <nicolas@nobis-crew.org>
Two bugs kept dump mode from working: a duplicate static is_pcdrv_init
broke the build, and spu_dump_pcm wrote warmup+period from uninitialized
locals instead of the analyzed header, so dumps were a bare 16-byte
header with no samples. Use hdr.warmup/hdr.period.

Signed-off-by: Nicolas 'Pixel' Noble <nicolas@nobis-crew.org>
The capture window starts within ~1 sample of the bit-11 edge, and which
boundary it lands on varies per boot and per console revision. Checked a
SCPH-5501 against the 5552 goldens: samples are bit-identical, off by one
capture tick. Byte-exact comparison from sample 0 can't survive that, so
find the best integer-sample alignment in a small window first. The
periodicity check is now shift-invariant.

Signed-off-by: Nicolas 'Pixel' Noble <nicolas@nobis-crew.org>
The bit-11 sync and the busy-wait-timed envelope reads are jitter-
sensitive; an interrupt mid-measurement mis-syncs a capture or skews an
envx read. Disable interrupts for the suite, as the cop0/cpu/timer tests
do.

Signed-off-by: Nicolas 'Pixel' Noble <nicolas@nobis-crew.org>
@nicolasnoble

Copy link
Copy Markdown
Member

Pushed a few commits to your branch: merged main (the SPUVoice ad/sr fields got renamed to adsrLo/adsrHi, so it wasn't building), fixed the SPU_DUMP path (a duplicate static plus it was writing uninitialized warmup/period, so the dumps came out header-only), made the golden compare tolerate the capture-start offset, and disabled interrupts during the measurements.

On the offset: I ran this on a 5501 against your 5552 goldens. The decoded samples are bit-identical, just shifted by one capture tick - the bit-11 sync only pins the start to ~1 sample, and which boundary it lands on differs per boot and per console revision. So a byte-exact compare was never going to be portable; the new one finds the integer-sample alignment first.

Two things still flaky on real hardware, more in your court since they're test-design calls:

  • The ADSR rate tests use a ±2 envx tolerance, which can't survive ~1 sample of sync jitter at the faster rates - they miss on most boots here. Probably wants a wider band, or to gate the envx reads on the bit-11 edge more tightly.
  • The drain/bit-11 sync occasionally misses by more than a sample (~1 in 5-6 boots), throwing the whole capture off. Disabling interrupts helped (got a clean 23/23 once) but didn't eliminate it.

6-boot sweep on the 5501 after these changes: 23/23, 19/23, 19/23, 14/23, 11/23, 21/23 - the sub-19 ones are the gross sync misses, the 19-21 ones are just the ADSR tolerances.

Comment thread src/mips/tests/spu/spu.c
// envx read past its tolerance. Disable interrupts for the suite, as the
// cop0/cpu/timer tests do.
CESTER_BEFORE_ALL(spu_tests,
s_interruptsWereEnabled = enterCriticalSection();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolasnoble very clever, thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants