nx_audio_sfx_test.nx source
↩ module page · 78 lines · 3554 B
1// nx_audio_sfx_test.nx -- KAT gate for the sovereign SFX library.
2// Each sound is audible + in i16 range; noise is measurably noisier than a tone
3// (zero-crossings); renders a real /tmp/coin.wav. expect_exit: 0.
4
5import "nx_syscalls.nx"
6import "nx_audio_mix.nx"
7import "nx_audio_synth.nx"
8import "nx_audio_fx.nx"
9import "nx_audio_sfx.nx"
10import "nx_audio_wav.nx"
11
12func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13func wn(v: i64) -> i64 {
14 let b: *u8 = sys_mmap(28); var m: i64 = v
15 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) }
16 let t: *u8 = sys_mmap(28); var k: i64 = 0
17 if m == 0 { t[0] = 48 as u8; k = 1 }
18 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
19 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
20 sys_write(1, b, k); return 0
21}
22func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 {
23 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) }
24 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) }
25 return 0
26}
27func maxabs(buf: *i64, n: i64) -> i64 { var m: i64 = 0; var i: i64 = 0; while i < n { var v: i64 = buf[i]; if v < 0 { v = 0 - v } if v > m { m = v } i = i + 1 } return m }
28func zerocross(buf: *i64, n: i64) -> i64 {
29 var c: i64 = 0; var i: i64 = 1
30 while i < n { let a: i64 = buf[i - 1]; let b: i64 = buf[i]; if a >= 0 { if b < 0 { c = c + 1 } } else { if b >= 0 { c = c + 1 } } i = i + 1 }
31 return c
32}
33func audible(buf: *i64, n: i64, lbl: *u8, pass: *i64, fail: *i64) -> i64 {
34 let m: i64 = maxabs(buf, n)
35 w(" " as *u8); w(lbl); w(" peak=" as *u8); wn(m); w(" zc=" as *u8); wn(zerocross(buf, n)); w("\n" as *u8)
36 chk(m > 1000, pass, fail, lbl)
37 chk(m <= 32767, pass, fail, " ^ in i16 range" as *u8)
38 return 0
39}
40
41func main() -> i64 {
42 let pass: *i64 = (sys_mmap(8)) as *i64
43 let fail: *i64 = (sys_mmap(8)) as *i64
44 pass[0] = 0
45 fail[0] = 0
46 w("=== nx_audio_sfx KAT (sovereign game SFX library) ===\n" as *u8)
47 let rate: i64 = 8000
48 let N: i64 = 4000
49 let buf: *i64 = (sys_mmap(N * 8 + 64)) as *i64
50
51 sfx_beep(buf, N, rate); audible(buf, N, "beep" as *u8, pass, fail)
52 sfx_coin(buf, N, rate); audible(buf, N, "coin" as *u8, pass, fail)
53 sfx_laser(buf, N, rate); audible(buf, N, "laser" as *u8, pass, fail)
54 sfx_explosion(buf, N, rate); audible(buf, N, "explosion" as *u8, pass, fail)
55
56 // character: noise is much noisier than a pure tone
57 let tone: *i64 = (sys_mmap(N * 8 + 64)) as *i64
58 sfx_tone(tone, N, 880, rate, 9000)
59 let zc_tone: i64 = zerocross(tone, N)
60 let noise: *i64 = (sys_mmap(N * 8 + 64)) as *i64
61 sfx_noise(noise, N, 9000, 12345)
62 let zc_noise: i64 = zerocross(noise, N)
63 w(" tone zc=" as *u8); wn(zc_tone); w(" noise zc=" as *u8); wn(zc_noise); w("\n" as *u8)
64 chk(zc_noise > zc_tone + 300, pass, fail, "noise noisier than tone (zc)" as *u8)
65 chk(maxabs(noise, N) > 1000, pass, fail, "noise audible" as *u8)
66
67 // render a real coin SFX artifact
68 sfx_coin(buf, N, rate)
69 let out: *u8 = sys_mmap(N * 4 + 128)
70 let tb: i64 = wav_render_stereo(buf, buf, N, rate, out)
71 let wr: i64 = wav_save("/tmp/coin.wav" as *u8, out, tb)
72 w(" rendered /tmp/coin.wav bytes=" as *u8); wn(wr); w("\n" as *u8)
73 chk(wr == tb, pass, fail, "coin.wav written" as *u8)
74
75 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8)
76 if fail[0] == 0 { return 0 }
77 return 1
78}