code wiki / (root) / nx_audio_wav_test.nx

nx_audio_wav_test.nx source

↩ module page · 70 lines · 3484 B

1// nx_audio_wav_test.nx -- KAT gate for the sovereign WAV writer (audio R4). 2// (1) byte-exact header vs the RIFF/WAVE spec, (2) renders a REAL 440Hz tone to 3// /tmp/demo.wav (a playable artifact). expect_exit: 0. 4 5import "nx_syscalls.nx" 6import "nx_audio_osc.nx" 7import "nx_audio_wav.nx" 8 9func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 10func wn(v: i64) -> i64 { 11 let b: *u8 = sys_mmap(28); var m: i64 = v 12 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 13 let t: *u8 = sys_mmap(28); var k: i64 = 0 14 if m == 0 { t[0] = 48 as u8; k = 1 } 15 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 16 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 17 sys_write(1, b, k); return 0 18} 19func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 { 20 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) } 21 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) } 22 return 0 23} 24func byteq(buf: *u8, off: i64, v: i64) -> i64 { if (buf[off] as i64) == v { return 1 } return 0 } 25 26func main() -> i64 { 27 let pass: *i64 = (sys_mmap(8)) as *i64 28 let fail: *i64 = (sys_mmap(8)) as *i64 29 pass[0] = 0 30 fail[0] = 0 31 w("=== nx_audio_wav KAT (sovereign WAV writer, R4) ===\n" as *u8) 32 33 // ---- byte-exact header on a tiny 2-frame stereo render @8000 ---- 34 let L: *i64 = (sys_mmap(64)) as *i64 35 let R: *i64 = (sys_mmap(64)) as *i64 36 L[0] = 1000; L[1] = 0 - 1000 37 R[0] = 500; R[1] = 0 - 500 38 let buf: *u8 = sys_mmap(256) 39 let total: i64 = wav_render_stereo(L, R, 2, 8000, buf) 40 41 chk(total == 52, pass, fail, "total = 44 + 2*4 = 52" as *u8) 42 chk(byteq(buf, 0, 82) == 1, pass, fail, "byte0 'R'" as *u8) // 'R'=82 43 chk(byteq(buf, 1, 73) == 1, pass, fail, "byte1 'I'" as *u8) // 'I'=73 44 chk(byteq(buf, 8, 87) == 1, pass, fail, "byte8 'W' (WAVE)" as *u8) // 'W'=87 45 chk(byteq(buf, 12, 102) == 1, pass, fail, "byte12 'f' (fmt )" as *u8) // 'f'=102 46 chk(byteq(buf, 20, 1) == 1, pass, fail, "fmt = PCM(1)" as *u8) 47 chk(byteq(buf, 22, 2) == 1, pass, fail, "channels = 2" as *u8) 48 chk(byteq(buf, 24, 64) == 1, pass, fail, "rate lo = 64 (8000=0x1F40)" as *u8) 49 chk(byteq(buf, 25, 31) == 1, pass, fail, "rate hi = 31" as *u8) 50 chk(byteq(buf, 34, 16) == 1, pass, fail, "bits = 16" as *u8) 51 chk(byteq(buf, 36, 100) == 1, pass, fail, "byte36 'd' (data)" as *u8) // 'd'=100 52 chk(byteq(buf, 40, 8) == 1, pass, fail, "data_size = 8" as *u8) 53 // first sample L[0]=1000 -> 1000%256=232, 1000/256=3 54 chk(byteq(buf, 44, 232) == 1, pass, fail, "L[0] lo = 232" as *u8) 55 chk(byteq(buf, 45, 3) == 1, pass, fail, "L[0] hi = 3" as *u8) 56 57 // ---- render a REAL 440Hz square tone, 0.25s @8000, stereo -> /tmp/demo.wav ---- 58 let tone: *i64 = (sys_mmap(2048 * 8)) as *i64 59 osc_square(tone, 2000, 440, 8000, 8000) 60 let big: *u8 = sys_mmap(16384) 61 let tb: i64 = wav_render_stereo(tone, tone, 2000, 8000, big) 62 let wr: i64 = wav_save("/tmp/demo.wav" as *u8, big, tb) 63 w("rendered /tmp/demo.wav bytes=" as *u8); wn(wr); w(" (expect " as *u8); wn(tb); w(")\n" as *u8) 64 chk(wr == tb, pass, fail, "demo.wav written fully" as *u8) 65 chk(tb == 44 + 2000 * 4, pass, fail, "demo.wav size = 44 + 2000*4" as *u8) 66 67 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8) 68 if fail[0] == 0 { return 0 } 69 return 1 70}