code wiki / _hdl_build / nx_nv1_lpc_gate.nx
nx_nv1_lpc_gate.nx source
↩ module page · 270 lines · 9464 B
1// nx_nv1_lpc_gate.nx -- ENGINEER gate for the NV1 LPC rung (nx_nv1_lpc.nx).
2// Evidence-driven, re-runnable, no network. Proves:
3// 1. BIT-EXACT round-trip (decode(encode(x)) == x byte-for-byte) on every
4// signal class: silence, DC, ramp, triangle, full-range LCG noise,
5// speech-ish (triangle + dither), alternating extremes, tiny blocks.
6// 2. FLAC-CLASS compression measured in permil of raw bytes (asserted
7// ceilings per class; printed so the ratio is ON the log).
8// 3. The verbatim escape: noise NEVER expands past 6 + 2n.
9// 4. Container integration: an 'L' chunk validates under nv1_validate
10// and its samples are counted.
11// 5. Every decoder rejection class fires its named negative.
12// license_tier: ORIGINAL
13
14import "nx_nv1_lpc.nx"
15import "nx_g_check_lib.nx"
16import "nx_g_puts_lib.nx"
17
18func g_dec(v: i64) -> i64 {
19 let d: *u8 = sys_mmap(32)
20 let t: *u8 = sys_mmap(32)
21 if v == 0 { d[0] = 48 as u8; sys_write(1, d, 1); return 0 }
22 var x: i64 = v
23 var n: i64 = 0
24 while x > 0 { t[n] = (48 + x % 10) as u8; x = x / 10; n = n + 1 }
25 var i: i64 = 0
26 while i < n { d[i] = t[n - 1 - i]; i = i + 1 }
27 sys_write(1, d, n)
28 return 0
29}
30
31// encode -> decode -> byte-compare; returns payload len, or a negative
32// (-100x encode fail, -200 wrong count, -300 byte mismatch)
33func g_rt(pcm: *u8, n: i64, pay: *u8, dec: *u8) -> i64 {
34 let el: i64 = nv1l_encode(pcm, n, pay, 6 + 2 * n + 64)
35 if el < 0 { return 0 - 1000 + el }
36 let dn: i64 = nv1l_decode(pay, el, dec, 2 * n + 64)
37 if dn != n { return 0 - 200 }
38 var i: i64 = 0
39 var ok: i64 = 1
40 while i < 2 * n {
41 if dec[i] != pcm[i] { ok = 0; i = 2 * n } else { i = i + 1 }
42 }
43 if ok == 0 { return 0 - 300 }
44 return el
45}
46
47func g_wr_i16(b: *u8, idx: i64, v: i64) -> i64 {
48 var u: i64 = v
49 if u < 0 { u = u + 65536 }
50 b[idx * 2] = (u & 255) as u8
51 b[idx * 2 + 1] = ((u / 256) & 255) as u8
52 return 0
53}
54
55// triangle wave sample: amp ~8128, period 256 (corner-rich = LPC stress)
56func g_tri(i: i64) -> i64 {
57 let ph: i64 = i % 256
58 if ph >= 128 { return 8128 - (ph - 128) * 127 }
59 return ph * 127 - 8128
60}
61
62func g_ratio_line(name: *u8, paylen: i64, rawlen: i64) -> i64 {
63 g_puts(" RATIO " as *u8); g_puts(name)
64 g_puts(" payload=" as *u8); g_dec(paylen)
65 g_puts("B raw=" as *u8); g_dec(rawlen)
66 g_puts("B permil=" as *u8); g_dec((paylen * 1000) / rawlen)
67 g_puts("\n" as *u8)
68 return (paylen * 1000) / rawlen
69}
70
71func main() -> i64 {
72 g_puts("nx_nv1_lpc gate (NV1 FLAC-class LPC rung)\n" as *u8)
73 var pass: i64 = 0
74 var total: i64 = 0
75 let N: i64 = 4096
76 let pcm: *u8 = sys_mmap(2 * N + 64)
77 let pay: *u8 = sys_mmap(2 * N + 256)
78 let dec: *u8 = sys_mmap(2 * N + 256)
79 var i: i64 = 0
80 var el: i64 = 0
81 var pm: i64 = 0
82
83 // ---- 1. silence ----
84 i = 0
85 while i < 2 * N { pcm[i] = 0 as u8; i = i + 1 }
86 el = g_rt(pcm, N, pay, dec)
87 pass = pass + g_check("silence round-trip bit-exact" as *u8, el > 0)
88 total = total + 1
89 pm = g_ratio_line("silence" as *u8, el, 2 * N)
90 pass = pass + g_check("silence permil <= 120" as *u8, pm <= 120)
91 total = total + 1
92
93 // ---- 2. DC 1000 ----
94 i = 0
95 while i < N { g_wr_i16(pcm, i, 1000); i = i + 1 }
96 el = g_rt(pcm, N, pay, dec)
97 pass = pass + g_check("DC round-trip bit-exact" as *u8, el > 0)
98 total = total + 1
99
100 // ---- 3. ramp (order-2 territory) ----
101 i = 0
102 while i < N { g_wr_i16(pcm, i, i * 8 - 16384); i = i + 1 }
103 el = g_rt(pcm, N, pay, dec)
104 pass = pass + g_check("ramp round-trip bit-exact" as *u8, el > 0)
105 total = total + 1
106 var predicted: i64 = 0
107 if el > 0 { if (pay[0] & 0xff) != 255 { predicted = 1 } }
108 pass = pass + g_check("ramp uses a predictor (mode != verbatim)" as *u8, predicted)
109 total = total + 1
110 pm = g_ratio_line("ramp" as *u8, el, 2 * N)
111 pass = pass + g_check("ramp permil <= 100" as *u8, pm <= 100)
112 total = total + 1
113
114 // ---- 4. triangle wave (corner-rich; ~311 permil expected) ----
115 i = 0
116 while i < N { g_wr_i16(pcm, i, g_tri(i)); i = i + 1 }
117 el = g_rt(pcm, N, pay, dec)
118 pass = pass + g_check("triangle round-trip bit-exact" as *u8, el > 0)
119 total = total + 1
120 pm = g_ratio_line("triangle" as *u8, el, 2 * N)
121 pass = pass + g_check("triangle permil <= 400" as *u8, pm <= 400)
122 total = total + 1
123
124 // ---- 5. full-range LCG noise: verbatim escape, never expands ----
125 var seed: i64 = 12345
126 i = 0
127 while i < N {
128 seed = (seed * 1103515245 + 12345) & 0x7fffffff
129 g_wr_i16(pcm, i, ((seed >> 8) % 65536) - 32768)
130 i = i + 1
131 }
132 el = g_rt(pcm, N, pay, dec)
133 pass = pass + g_check("noise round-trip bit-exact" as *u8, el > 0)
134 total = total + 1
135 pass = pass + g_check("noise never expands (<= 6 + 2n)" as *u8, el <= 6 + 2 * N)
136 total = total + 1
137
138 // ---- 6. speech-ish: triangle + small dither ----
139 seed = 777
140 i = 0
141 while i < N {
142 seed = (seed * 1103515245 + 12345) & 0x7fffffff
143 g_wr_i16(pcm, i, g_tri(i) + ((seed >> 8) & 127) - 64)
144 i = i + 1
145 }
146 el = g_rt(pcm, N, pay, dec)
147 pass = pass + g_check("speech-ish round-trip bit-exact" as *u8, el > 0)
148 total = total + 1
149 pm = g_ratio_line("speechish" as *u8, el, 2 * N)
150 pass = pass + g_check("speech-ish permil <= 700 (FLAC-class)" as *u8, pm <= 700)
151 total = total + 1
152
153 // ---- 7. alternating extremes (zigzag/k stress) ----
154 i = 0
155 while i < N {
156 var av: i64 = 32767
157 if (i & 1) == 1 { av = 0 - 32768 }
158 g_wr_i16(pcm, i, av)
159 i = i + 1
160 }
161 el = g_rt(pcm, N, pay, dec)
162 pass = pass + g_check("alternating extremes bit-exact" as *u8, el > 0)
163 total = total + 1
164
165 // ---- 8. tiny blocks n=1,2,3 ----
166 var tiny: i64 = 1
167 g_wr_i16(pcm, 0, 0 - 12345)
168 g_wr_i16(pcm, 1, 31000)
169 g_wr_i16(pcm, 2, 0 - 1)
170 var tn: i64 = 1
171 while tn < 4 {
172 if g_rt(pcm, tn, pay, dec) < 0 { tiny = 0 }
173 tn = tn + 1
174 }
175 pass = pass + g_check("tiny blocks n=1,2,3 bit-exact" as *u8, tiny)
176 total = total + 1
177
178 // ---- 9. n=0 ----
179 el = nv1l_encode(pcm, 0, pay, 64)
180 var z: i64 = 0
181 if el == 6 { if nv1l_decode(pay, 6, dec, 64) == 0 { z = 1 } }
182 pass = pass + g_check("empty block encodes to 6B, decodes to 0" as *u8, z)
183 total = total + 1
184
185 // ---- 10. container: L chunk validates + samples counted ----
186 i = 0
187 while i < 1024 { g_wr_i16(pcm, i, g_tri(i)); i = i + 1 }
188 el = nv1l_encode(pcm, 1024, pay, 6 + 2048 + 64)
189 let cbuf: *u8 = sys_mmap(65536)
190 var w: i64 = nv1_write_header(cbuf, 48000)
191 w = nv1_write_chunk(cbuf, w, 76, 0, pay, el)
192 w = nv1_write_end(cbuf, w, 21)
193 let info: *i64 = sys_mmap(64) as *i64
194 var rc: i64 = nv1_validate(cbuf, w, info)
195 var cok: i64 = 0
196 if rc == 0 { if info[1] == 1 { if info[2] == 1024 { cok = 1 } } }
197 pass = pass + g_check("container with L chunk: rc=0, 1024 samples counted" as *u8, cok)
198 total = total + 1
199
200 // L chunk with len < 6 sub-header -> -9
201 w = nv1_write_header(cbuf, 48000)
202 w = nv1_write_chunk(cbuf, w, 76, 0, pay, 4)
203 w = nv1_write_end(cbuf, w, 1)
204 rc = nv1_validate(cbuf, w, info)
205 pass = pass + g_check("L chunk shorter than sub-header -> -9" as *u8, rc == 0 - 9)
206 total = total + 1
207
208 // ---- 11. decoder rejection classes ----
209 rc = nv1l_decode(pay, 5, dec, 8192)
210 pass = pass + g_check("payload < 6 -> -1" as *u8, rc == 0 - 1)
211 total = total + 1
212
213 // rebuild a known-good payload (triangle 1024 from above is in pay/el)
214 let save0: i64 = pay[0] & 0xff
215 pay[0] = 7 as u8
216 rc = nv1l_decode(pay, el, dec, 8192)
217 pass = pass + g_check("bad mode 7 -> -2" as *u8, rc == 0 - 2)
218 total = total + 1
219 pay[0] = save0 as u8
220
221 let save1: i64 = pay[1] & 0xff
222 pay[1] = 31 as u8
223 rc = nv1l_decode(pay, el, dec, 8192)
224 pass = pass + g_check("k=31 -> -3" as *u8, rc == 0 - 3)
225 total = total + 1
226 pay[1] = save1 as u8
227
228 rc = nv1l_decode(pay, el, dec, 100)
229 pass = pass + g_check("output cap overrun -> -4" as *u8, rc == 0 - 4)
230 total = total + 1
231
232 rc = nv1l_decode(pay, el / 2, dec, 8192)
233 pass = pass + g_check("truncated bitstream -> -5" as *u8, rc == 0 - 5)
234 total = total + 1
235
236 // mode >= nsamples -> -6 (hand-built: mode 3, ns 2)
237 pay[0] = 3 as u8
238 pay[1] = 0 as u8
239 nv1_wr_u32(pay, 2, 2)
240 rc = nv1l_decode(pay, 16, dec, 8192)
241 pass = pass + g_check("order >= nsamples -> -6" as *u8, rc == 0 - 6)
242 total = total + 1
243
244 // out-of-range reconstruction -> -7 (mode 1, k 0, ns 2, warmup 32767,
245 // residual +1 => 32768): bitstream u=2 (LSB-first 1,1,0) = 0x03
246 pay[0] = 1 as u8
247 pay[1] = 0 as u8
248 nv1_wr_u32(pay, 2, 2)
249 g_wr_i16(pay, 3, 32767) // warmup at byte offset 6 = idx 3
250 pay[8] = 3 as u8
251 rc = nv1l_decode(pay, 9, dec, 8192)
252 pass = pass + g_check("out-of-range reconstruction -> -7 (tamper-evident)" as *u8, rc == 0 - 7)
253 total = total + 1
254
255 // verbatim shorter than claimed -> -6
256 pay[0] = 255 as u8
257 pay[1] = 0 as u8
258 nv1_wr_u32(pay, 2, 100)
259 rc = nv1l_decode(pay, 50, dec, 8192)
260 pass = pass + g_check("verbatim shorter than claimed -> -6" as *u8, rc == 0 - 6)
261 total = total + 1
262
263 g_puts("---- nv1_lpc gate: passed " as *u8)
264 g_dec(pass)
265 g_puts(" / " as *u8)
266 g_dec(total)
267 g_puts(" ----\n" as *u8)
268 if pass == total { return 0 }
269 return 1
270}