code wiki / (root) / nx_audio_mix_test.nx

nx_audio_mix_test.nx source

↩ module page · 71 lines · 3045 B

1// nx_audio_mix_test.nx -- KAT gate for the sovereign PCM mixer atom (audio R0). 2// Known samples + gains -> known mixed output, including clamp + gain cases. 3// expect_exit: 0. 4 5import "nx_syscalls.nx" 6import "nx_audio_mix.nx" 7 8func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 9func wn(v: i64) -> i64 { 10 let b: *u8 = sys_mmap(28); var m: i64 = v 11 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 12 let t: *u8 = sys_mmap(28); var k: i64 = 0 13 if m == 0 { t[0] = 48 as u8; k = 1 } 14 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 15 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 16 sys_write(1, b, k); return 0 17} 18func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 { 19 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) } 20 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) } 21 return 0 22} 23 24func main() -> i64 { 25 let pass: *i64 = (sys_mmap(8)) as *i64 26 let fail: *i64 = (sys_mmap(8)) as *i64 27 pass[0] = 0 28 fail[0] = 0 29 w("=== nx_audio_mix KAT (sovereign PCM mixer atom, R0) ===\n" as *u8) 30 31 // ---- clamp ---- 32 chk(ae_clamp(100) == 100, pass, fail, "clamp passthrough" as *u8) 33 chk(ae_clamp(40000) == 32767, pass, fail, "clamp +overflow -> 32767" as *u8) 34 chk(ae_clamp(0 - 40000) == (0 - 32768), pass, fail, "clamp -overflow -> -32768" as *u8) 35 36 // ---- mix2: sum two streams at unity gain, last sample clamps ---- 37 let a: *i64 = (sys_mmap(24)) as *i64 38 let b: *i64 = (sys_mmap(24)) as *i64 39 let o: *i64 = (sys_mmap(24)) as *i64 40 a[0] = 100; b[0] = 50 41 a[1] = 200; b[1] = 50 42 a[2] = 16000; b[2] = 20000 43 ae_mix2(a, b, 256, 256, o, 3) 44 chk(o[0] == 150, pass, fail, "mix2 100+50=150" as *u8) 45 chk(o[1] == 250, pass, fail, "mix2 200+50=250" as *u8) 46 chk(o[2] == 32767, pass, fail, "mix2 36000 clamps to 32767" as *u8) 47 48 // ---- gain: half-volume ---- 49 a[0] = 1000; b[0] = 0 50 ae_mix2(a, b, 128, 256, o, 1) // a*0.5 + b*1.0 = 500 51 chk(o[0] == 500, pass, fail, "gain 1000*0.5 = 500" as *u8) 52 53 // ---- mixn: 3 then 4 unity sources ---- 54 let s0: *i64 = (sys_mmap(8)) as *i64 55 let s1: *i64 = (sys_mmap(8)) as *i64 56 let s2: *i64 = (sys_mmap(8)) as *i64 57 let s3: *i64 = (sys_mmap(8)) as *i64 58 s0[0] = 10000; s1[0] = 10000; s2[0] = 10000; s3[0] = 10000 59 let srcs: *i64 = (sys_mmap(32)) as *i64 60 let gains: *i64 = (sys_mmap(32)) as *i64 61 srcs[0] = (s0) as i64; srcs[1] = (s1) as i64; srcs[2] = (s2) as i64; srcs[3] = (s3) as i64 62 gains[0] = 256; gains[1] = 256; gains[2] = 256; gains[3] = 256 63 ae_mixn(srcs, gains, 3, o, 1) 64 chk(o[0] == 30000, pass, fail, "mixn 3x10000 = 30000" as *u8) 65 ae_mixn(srcs, gains, 4, o, 1) 66 chk(o[0] == 32767, pass, fail, "mixn 4x10000 = 40000 clamps to 32767" as *u8) 67 68 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8) 69 if fail[0] == 0 { return 0 } 70 return 1 71}