Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
spu-capture.c
Go to the documentation of this file.
1// ==========================================================================
2// Validate voice resampling
3// ==========================================================================
4
5CESTER_MAYBE_TEST(voice_sample_rates, spu_tests,
6 run_voice1_with_sample(kAdpcmSine, 0x0800);
7 SPU_ASSERT_GOLDEN(sine_pitch_0800);
8 run_voice1_with_sample(kAdpcmSine, 0x2000);
9 SPU_ASSERT_GOLDEN(sine_pitch_2000);
10 run_voice1_with_sample(kAdpcmSine, 0x3000);
11 SPU_ASSERT_GOLDEN(sine_pitch_3000);
12)
13
14// Every other rate in the suite (0x0800, 0x1000, 0x2000, 0x3000) is an exact
15// binary fraction of unity, so the 16.16 pitch counter's fractional part lands
16// on zero every step and the gaussian interpolation index is pinned at 0 - or
17// alternates 0/0x80 for 0x0800. The interpolator's rounding is therefore not
18// observable anywhere else in the suite. 0x1500 walks the index over the table
19// instead: 16 distinct values against the 1 every other rate provides.
20//
21// The rate cannot be just any non-dyadic value. What has to stay periodic is
22// the joint (pitch phase, ADPCM read position) state, and kAdpcmSine loops
23// every 112 samples. 0x1500 gives that pair a period of 256 output samples,
24// which fits inside the 512-sample capture ring; a rate whose period does not
25// fit leaves the golden unable to absorb a phase difference by rotation, and
26// the comparison silently becomes a test of absolute key-on phase.
27CESTER_MAYBE_TEST(voice_sample_rate_nondyadic, spu_tests,
28 run_voice1_with_sample(kAdpcmSine, 0x1500);
29 SPU_ASSERT_GOLDEN(sine_pitch_1500);
30)
31
32// 0x1500 above walks the index, but it cannot be compared: the golden absorbs a
33// key-on phase difference by rotating the capture ring, and a rotation by r moves
34// the source phase by num*r mod 28, where num/den is the rate in lowest terms and
35// 28 is the sample's decoded VALUE period. That reaches every phase only when
36// gcd(num, 28) == 1. For 0x1500, num is 21 and the gcd is 7, so a rotation reaches
37// 4 of the 28 phases and the comparison silently becomes a test of absolute key-on
38// phase - which is exactly what its measured spread against hardware is.
39//
40// 0x1400 is 5/4: gcd(5, 28) == 1, so every phase is reachable. It walks the index
41// over 4 values (0, 64, 128, 192) rather than 0x1500's 16, and that is the price of
42// fitting: distinct indices equal den, the joint period is den * 28, and warmup
43// depends on where in the run the capture lands - measured between 0 and 344
44// samples for one rate in one pass. den = 4 costs 112 samples of the 512-sample
45// ring, which survives the worst warmup seen; den = 8 and den = 16 do not, and both
46// were measured taking the no-period path.
47CESTER_MAYBE_TEST(voice_sample_rate_swept_index, spu_tests,
48 run_voice1_with_sample(kAdpcmSine, 0x1400);
49 SPU_ASSERT_GOLDEN(sine_pitch_1400);
50)
51
52// The same sweep at full resolution. kAdpcmSine7's decoded value period is 7
53// rather than 28, so 0x1300 (19/16) walks all sixteen gaussian indices for a
54// joint period of 16*7 = 112 - the same ring cost as the four-index capture
55// above, four times the coverage, and 400 samples of headroom for the warmup.
56// gcd(19, 7) = 1, so every source phase stays reachable by rotation.
57CESTER_MAYBE_TEST(voice_sample_rate_swept_index_full, spu_tests,
58 run_voice1_with_sample(kAdpcmSine7, 0x1300);
59 SPU_ASSERT_GOLDEN(sine7_pitch_1300);
60)
61
62CESTER_MAYBE_TEST(voice_volume_does_not_affect_capture, spu_tests,
63 SPU_VOICES[1].volumeLeft = 0x3fff;
64 SPU_VOICES[1].volumeRight = 0x3fff;
65 run_voice1_with_sample(kAdpcmTriangle, 0x1000);
66 SPU_ASSERT_GOLDEN(triangle);
67 SPU_VOICES[1].volumeLeft = 0;
68 SPU_VOICES[1].volumeRight = 0;
69 run_voice1_with_sample(kAdpcmTriangle, 0x1000);
70 SPU_ASSERT_GOLDEN(triangle);
71)
#define SPU_VOICES
Definition spu.h:42
#define CESTER_MAYBE_TEST
Definition cop0.c:34
spu_tests
Definition spu-adpcm-edge.c:189
run_voice1_with_sample(sample, 0x1000)
#define SPU_ASSERT_GOLDEN(name)
Definition spu.c:401