code wiki / _hdl_build / nx_game_audio_gate.nx
nx_game_audio_gate.nx source
↩ module page · 80 lines · 5220 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_game_audio_gate.nx -- proves + gates the EXISTING sovereign game-audio engine (nx_audio_sfx + nx_audio_wav),
4// composing it (verify-don't-rebuild: the synth already exists). Generates a coin+laser+explosion demo -> a real
5// WAV (knowledge/sfx_demo.wav) + a min/max WAVEFORM PNG (knowledge/sfx_demo_waveform.png) for eyeball (we can't
6// hear here; sound is operator-confirmed by playing the WAV). Asserts: non-silent, oscillating, explosion decays.
7// expect_exit: 0 license_tier: ORIGINAL
8import "nx_audio_sfx.nx"
9import "nx_audio_wav.nx"
10import "nx_png.nx"
11import "nx_syscalls.nx"
12
13func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
14" as *u8); return ok }
15func iabs(v: i64) -> i64 { if v<0 { return 0-v } return v }
16func rgb(r: i64, g: i64, b: i64) -> i64 { return (r & 255) | ((g & 255) << 8) | ((b & 255) << 16) }
17
18func main() -> i64 {
19 gw("=== nx_game_audio_gate: prove the sovereign game-audio engine (compose nx_audio_sfx + nx_audio_wav) ===\n" as *u8)
20 var pass: i64 = 0; var total: i64 = 0
21 let rate: i64 = 22050
22 let big: *i64 = sys_mmap(rate * 8 * 4) as *i64 // up to ~4s
23 var pos: i64 = 0
24 let nc: i64 = (rate*220)/1000; sfx_coin(((big as i64) + pos*8) as *i64, nc, rate); pos = pos + nc
25 var sil: i64 = (rate*60)/1000; var z: i64=0; while z<sil { big[pos]=0; pos=pos+1; z=z+1 }
26 let nl: i64 = (rate*240)/1000; let lstart: i64 = pos; sfx_laser(((big as i64) + pos*8) as *i64, nl, rate); pos = pos + nl
27 z=0; while z<sil { big[pos]=0; pos=pos+1; z=z+1 }
28 let ne: i64 = (rate*420)/1000; let estart: i64 = pos; sfx_explosion(((big as i64) + pos*8) as *i64, ne, rate); pos = pos + ne
29 let totn: i64 = pos
30
31 // render to WAV (mono -> stereo via L=R)
32 let wbuf: *u8 = sys_mmap(64 + totn*4)
33 let wlen: i64 = wav_render_stereo(big, big, totn, rate, wbuf)
34 let sv: i64 = wav_save("knowledge/sfx_demo.wav" as *u8, wbuf, wlen)
35 gw(" (live evidence: WAV knowledge/sfx_demo.wav -- coin + laser + explosion, "); gn(totn); gw(" samples @ "); gn(rate); gw("Hz, "); gn(sv); gw(" bytes)\n" as *u8)
36
37 // min/max waveform PNG
38 let W: i64 = 480; let H: i64 = 160
39 let fb: *i64 = sys_mmap(W*H*8) as *i64
40 var p: i64=0; while p<W*H { fb[p]=rgb(12,14,22); p=p+1 }
41 var cx: i64=0; while cx<W { fb[80*W+cx]=rgb(40,46,60); cx=cx+1 } // center line
42 var x: i64=0
43 while x < W {
44 let s0: i64 = (x*totn)/W; var s1: i64 = ((x+1)*totn)/W; if s1<=s0 { s1=s0+1 }
45 var mn: i64=0; var mx: i64=0; var j: i64=s0
46 while j<s1 { if j<totn { let v: i64=big[j]; if v<mn {mn=v} if v>mx {mx=v} } j=j+1 }
47 var y0: i64 = 80 - (mx*78)/13000; var y1: i64 = 80 - (mn*78)/13000
48 if y0<0 {y0=0} if y1>=H {y1=H-1}
49 var y: i64=y0; while y<=y1 { fb[y*W+x]=rgb(90,210,122); y=y+1 }
50 x=x+1
51 }
52 write_png(fb, W, H, "knowledge/sfx_demo_waveform.png" as *u8)
53 gw(" (live evidence: PNG knowledge/sfx_demo_waveform.png -- coin / laser-chirp / explosion-decay envelope)\n" as *u8)
54
55 // T1: non-silent + oscillating (has + and - samples)
56 var mxabs: i64=0; var haspos: i64=0; var hasneg: i64=0; var i: i64=0
57 while i<totn { let v: i64=big[i]; let a: i64=iabs(v); if a>mxabs {mxabs=a} if v>2000 {haspos=1} if v<0-2000 {hasneg=1} i=i+1 }
58 var t1ok: i64=1; if mxabs<3000 {t1ok=0} if haspos!=1 {t1ok=0} if hasneg!=1 {t1ok=0}
59 total=total+1; if t1ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
60 gw("T1 audible+oscillating: peak amplitude "); gn(mxabs); gw(", swings +/- (haspos="); gn(haspos); gw(" hasneg="); gn(hasneg); gw(")\n" as *u8)
61
62 // T2: explosion decays (early energy > late energy in its region)
63 let eh: i64 = ne/2
64 var e_early: i64=0; var e_late: i64=0; i=0
65 while i<eh { e_early=e_early+iabs(big[estart+i]); e_late=e_late+iabs(big[estart+eh+i]); i=i+1 }
66 var t2ok: i64=1; if e_early <= e_late {t2ok=0}
67 total=total+1; if t2ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
68 gw("T2 explosion decays: early energy "); gn(e_early); gw(" > late energy "); gn(e_late); gw(" (ADSR envelope works)\n" as *u8)
69
70 // T3: laser is a pitch sweep (zero-crossing rate rises as pitch... actually falls 1400->200, so crossings DROP)
71 var xc_first: i64=0; var xc_last: i64=0; let lh: i64=nl/2; i=1
72 while i<lh { if (big[lstart+i-1]<0) != (big[lstart+i]<0) { xc_first=xc_first+1 } if (big[lstart+lh+i-1]<0) != (big[lstart+lh+i]<0) { xc_last=xc_last+1 } i=i+1 }
73 var t3ok: i64=1; if xc_first <= xc_last {t3ok=0} // descending pitch -> fewer crossings later
74 total=total+1; if t3ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
75 gw("T3 laser pitch-sweep: zero-crossings fall "); gn(xc_first); gw("->"); gn(xc_last); gw(" (descending 1400->200Hz)\n" as *u8)
76
77 gw("\n=== nx_game_audio_gate "); gn(pass); gw("/"); gn(total)
78 if pass==total { gw(" GREEN (sovereign game-audio engine PROVEN: real SFX WAV + waveform; audio is NOT a gap -- it needs WIRING to games)\n" as *u8); sys_exit(0); return 0 }
79 gw(" RED\n" as *u8); sys_exit(1); return 1
80}