code wiki / (root) / nx_polypitch_gate.nx

nx_polypitch_gate.nx source

↩ module page · 134 lines · 4634 B

1// nx_polypitch_gate.nx -- REFEREE for LG-3 polyphony (nx_polypitch). 2// 3// Synthesizes chords as sums of pure sine tones and checks the detected NOTE SET: 4// single A3 (220) -> {57} (neg-control: 1 note, not a chord) 5// A major (220,277,330) -> {57,61,64} (A3, C#4, E4) 6// power chord (220,330) -> {57,64} (A3, E4) 7// C major (261,330,392) -> {60,64,67} (C4, E4, G4) -- different chord, different set 8// 9// Evidence -> stdout + knowledge/status/polypitch_gate.log. Exit 0 GREEN / 1 RED. 10// Sovereign x86_64 throughout. license_tier: ORIGINAL 11import "nx_syscalls_x86_64.nx" 12import "nx_polypitch.nx" 13import "nx_note.nx" 14 15const N: i64 = 1024 16const FS: i64 = 8000 17const MLO: i64 = 50 18const MHI: i64 = 72 19const AMP: i64 = 10000 20const TWO_PI: i64 = 411775 21 22func gp(logfd: i64, s: *u8) -> i64 { 23 var n: i64 = 0 24 while s[n] != (0 as u8) { n = n + 1 } 25 sys_write(1, s, n) 26 if logfd > 0 { sys_write(logfd, s, n) } 27 return 0 28} 29func gn(logfd: i64, v: i64) -> i64 { 30 let bb: *u8 = sys_mmap(28) 31 var m: i64 = v 32 if m < 0 { sys_write(1, "-\x00" as *u8, 1); if logfd > 0 { sys_write(logfd, "-\x00" as *u8, 1) } m = 0 - m } 33 let t: *u8 = sys_mmap(28) 34 var k: i64 = 0 35 if m == 0 { t[0] = 48 as u8; k = 1 } 36 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 37 var i: i64 = 0 38 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 39 sys_write(1, bb, k) 40 if logfd > 0 { sys_write(logfd, bb, k) } 41 return 0 42} 43 44func add_sine(acc: *i64, f: i64, amp: i64) -> i64 { 45 if f <= 0 { return 0 } 46 let dph: i64 = (TWO_PI * f) / FS 47 var ph: i64 = 0 48 var n: i64 = 0 49 while n < N { 50 acc[n] = acc[n] + ((amp * nx_pp_sinfull(ph)) >> 16) 51 ph = ph + dph 52 if ph >= TWO_PI { ph = ph - TWO_PI } 53 n = n + 1 54 } 55 return 0 56} 57func make_chord(acc: *i64, buf: *u8, f1: i64, f2: i64, f3: i64) -> i64 { 58 var n: i64 = 0 59 while n < N { acc[n] = 0; n = n + 1 } 60 add_sine(acc, f1, AMP) 61 add_sine(acc, f2, AMP) 62 add_sine(acc, f3, AMP) 63 var mx: i64 = 1 64 n = 0 65 while n < N { var v: i64 = acc[n]; if v < 0 { v = 0 - v } if v > mx { mx = v } n = n + 1 } 66 n = 0 67 while n < N { 68 var s: i64 = acc[n] * 16000 / mx 69 if s > 32000 { s = 32000 } 70 if s < -32000 { s = -32000 } 71 var x: i64 = s 72 if x < 0 { x = x + 0x10000 } 73 buf[n * 2] = (x & 0xff) as u8 74 buf[n * 2 + 1] = ((x >> 8) & 0xff) as u8 75 n = n + 1 76 } 77 return 0 78} 79func pdet(logfd: i64, label: *u8, det: *i64, cnt: i64) -> i64 { 80 gp(logfd, label) 81 gp(logfd, " detected=\x00" as *u8); gn(logfd, cnt); gp(logfd, " [\x00" as *u8) 82 var i: i64 = 0 83 while i < cnt { gn(logfd, det[i]); gp(logfd, " \x00" as *u8); i = i + 1 } 84 gp(logfd, "]\n\x00" as *u8) 85 return 0 86} 87 88func main() -> i64 { 89 let logfd: i64 = sys_openat_append("knowledge/status/polypitch_gate.log\x00" as *u8, 0x1a4) 90 gp(logfd, "POLYPITCH-GATE LG-3 (chords)\n\x00" as *u8) 91 92 let tbl: *i64 = sys_mmap(128 * 8) as *i64 93 nx_note_table(tbl) 94 let acc: *i64 = sys_mmap(N * 8) as *i64 95 let buf: *u8 = sys_mmap(N * 2) 96 let det: *i64 = sys_mmap(8 * 8) as *i64 97 98 var ok: i64 = 1 99 100 make_chord(acc, buf, 220, 0, 0) 101 let c1: i64 = nx_polypitch(buf, 0, N, FS, tbl, MLO, MHI, det, 8) 102 pdet(logfd, " single A3 \x00" as *u8, det, c1) 103 if c1 != 1 { ok = 0 } 104 if c1 >= 1 { if det[0] != 57 { ok = 0 } } 105 106 make_chord(acc, buf, 220, 277, 330) 107 let c2: i64 = nx_polypitch(buf, 0, N, FS, tbl, MLO, MHI, det, 8) 108 pdet(logfd, " A maj triad \x00" as *u8, det, c2) 109 if c2 != 3 { ok = 0 } 110 if c2 == 3 { if det[0] != 57 { ok = 0 } if det[1] != 61 { ok = 0 } if det[2] != 64 { ok = 0 } } 111 112 make_chord(acc, buf, 220, 330, 0) 113 let c3: i64 = nx_polypitch(buf, 0, N, FS, tbl, MLO, MHI, det, 8) 114 pdet(logfd, " power 5th \x00" as *u8, det, c3) 115 if c3 != 2 { ok = 0 } 116 if c3 == 2 { if det[0] != 57 { ok = 0 } if det[1] != 64 { ok = 0 } } 117 118 make_chord(acc, buf, 261, 330, 392) 119 let c4: i64 = nx_polypitch(buf, 0, N, FS, tbl, MLO, MHI, det, 8) 120 pdet(logfd, " C maj triad \x00" as *u8, det, c4) 121 if c4 != 3 { ok = 0 } 122 if c4 == 3 { if det[0] != 60 { ok = 0 } if det[1] != 64 { ok = 0 } if det[2] != 67 { ok = 0 } } 123 124 if ok == 1 { 125 gp(logfd, "POLYPITCH-GATE result=ALL-PASS verdict=GREEN\n\x00" as *u8) 126 if logfd > 0 { sys_close(logfd) } 127 sys_exit(0) 128 return 0 129 } 130 gp(logfd, "POLYPITCH-GATE result=FAIL verdict=RED\n\x00" as *u8) 131 if logfd > 0 { sys_close(logfd) } 132 sys_exit(1) 133 return 1 134}