code wiki / _hdl_build / nx_listen_player.nx
nx_listen_player.nx source
↩ module page · 181 lines · 18008 B
1// nx_listen_player.nx -- https://nishifamily.com/listen : a sovereign audio PLAYER that uses OUR OWN CODEC
2// end-to-end (operator 2026-06-23: "make sure this is all using our own codec"). Each track's PCM is compressed
3// with our NishiLossless LPC codec (nx_nv1_lpc), self-checked BIT-EXACT at build time, and embedded as base64.
4// The page ships a faithful in-browser port of our decoder (nvDec) -> raw PCM -> a WAV blob WE build -> <audio>.
5// The browser never decodes a third-party codec; it only plays raw PCM that OUR codec produced. A checksum
6// self-test (sum embedded by the encoder, recomputed after decode) turns any decoder mismatch into a VISIBLE
7// badge instead of garbage. Controls: play/stop/loop/shuffle/next/new. Anonymous aggregate beacons to /stat
8// (track,event -- never who, survivorship-aware). license_tier: ORIGINAL expect_exit: 0
9import "nx_base64.nx"
10import "nx_nv1_lpc.nx"
11import "nx_syscalls.nx"
12const K_MAGIC_32768: i64 = 32768
13const K_MAGIC_65536: i64 = 65536
14const K_MAGIC_16777216: i64 = 16777216
15const K_MAGIC_1000000007: i64 = 1000000007
16const K_MAGIC_524288: i64 = 524288
17const K_MAGIC_4194304: i64 = 4194304
18
19const OUTP: *u8 = "web_assets/listen_index.html"
20
21func mp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
22func mpn(v: i64) -> i64 {
23 let b: *u8 = sys_mmap(28); var x: i64=v
24 if x<0 { b[0]=45; sys_write(1,b,1); x=0-x }
25 if x==0 { b[0]=48; sys_write(1,b,1); return 0 }
26 var d: i64=0; var y: i64=x; while y>0 { d=d+1; y=y/10 }
27 var i: i64=d-1; y=x; while i>=0 { b[i]=(48+(y%10)) as u8; y=y/10; i=i-1 }
28 sys_write(1,b,d); return 0
29}
30func app(out: *u8, off: *i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ out[off[0]]=s[i]; off[0]=off[0]+1; i=i+1 } return 0 }
31// JS-SAFE append: escapes ' and \ so any title/desc text (e.g. "Elara's") can't break the single-quoted TRACKS
32// array (an unescaped apostrophe closed the string early and killed the whole player -- the 12-track outage).
33func app_js(out: *u8, off: *i64, s: *u8) -> i64 {
34 var i: i64=0
35 while s[i]!=(0 as u8) {
36 let c: u8 = s[i]
37 if c==(92 as u8) { out[off[0]]=92 as u8; off[0]=off[0]+1; out[off[0]]=92 as u8; off[0]=off[0]+1 }
38 else { if c==(39 as u8) { out[off[0]]=92 as u8; off[0]=off[0]+1; out[off[0]]=39 as u8; off[0]=off[0]+1 }
39 else { out[off[0]]=c; off[0]=off[0]+1 } }
40 i=i+1
41 }
42 return 0
43}
44func appn(out: *u8, off: *i64, v: i64) -> i64 {
45 if v==0 { out[off[0]]=48 as u8; off[0]=off[0]+1; return 0 }
46 let t: *u8=sys_mmap(28); var x: i64=v; var d: i64=0; while x>0 {d=d+1;x=x/10}
47 var i: i64=d-1; x=v; let tmp: *u8=sys_mmap(28); var j: i64=0; while j<d {tmp[d-1-j]=(48+(x%10)) as u8; x=x/10; j=j+1}
48 j=0; while j<d { out[off[0]]=tmp[j]; off[0]=off[0]+1; j=j+1 } return 0
49}
50func read_file(path: *u8, buf: *u8, cap: i64) -> i64 {
51 let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 - 1 }
52 var total: i64 = 0; var r: i64 = sys_read(fd, buf, cap)
53 while r > 0 { total = total + r; if total >= cap { r = 0 } else { r = sys_read(fd, (buf + total) as *u8, cap - total) } }
54 sys_close(fd); return total
55}
56func i16(b: *u8, off: i64) -> i64 { var v: i64=(b[off]&0xff)+((b[off+1]&0xff)*256); if v>=K_MAGIC_32768 { v=v-K_MAGIC_65536 } return v }
57func iabs(v: i64) -> i64 { if v<0 { return 0-v } return v }
58func sames(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 }
59
60// emit one TRACKS[] entry that carries OUR-CODEC-compressed channels. Returns 1 if both channels round-trip
61// BIT-EXACT (else 0 -> the track is dropped, never embedded lossy). Globals threaded as args.
62func emit_track(out: *u8, off: *i64, id: *u8, title: *u8, desc: *u8, wavpath: *u8,
63 wav: *u8, Lb: *u8, Rb: *u8, enc: *u8, dec: *u8, b64buf: *u8, cap: i64) -> i64 {
64 let fl: i64 = read_file(wavpath, wav, cap)
65 if fl <= 44 { return 0 }
66 let nch: i64 = (wav[22]&0xff) + ((wav[23]&0xff)*256) // 1=mono, 2=stereo (numChannels @ off 22)
67 var nsamp: i64 = (fl - 44) / 4
68 if nch == 1 { nsamp = (fl - 44) / 2 } // mono = 2 bytes/sample
69 var srate: i64 = (wav[24]&0xff) + ((wav[25]&0xff)*256) + ((wav[26]&0xff)*K_MAGIC_65536) + ((wav[27]&0xff)*K_MAGIC_16777216)
70 var i: i64 = 0
71 while i < nsamp {
72 if nch == 1 {
73 Lb[2*i] = wav[44+2*i]; Lb[2*i+1] = wav[44+2*i+1] // mono -> both channels identical
74 Rb[2*i] = Lb[2*i]; Rb[2*i+1] = Lb[2*i+1]
75 } else {
76 Lb[2*i] = wav[44+4*i]; Lb[2*i+1] = wav[44+4*i+1]
77 Rb[2*i] = wav[44+4*i+2]; Rb[2*i+1] = wav[44+4*i+3]
78 }
79 i = i + 1
80 }
81 // checksum of the ORIGINAL pcm (sum of |L|+|R| mod 1e9+7) -- the browser recomputes this after decode.
82 var sum: i64 = 0
83 i = 0; while i < nsamp { sum = (sum + iabs(i16(Lb,2*i)) + iabs(i16(Rb,2*i))) % K_MAGIC_1000000007; i = i + 1 }
84 // encode + BIT-EXACT self-check, both channels
85 let el: i64 = nv1l_encode(Lb, nsamp, enc, cap)
86 if el <= 0 { return 0 }
87 if nv1l_decode(enc, el, dec, cap) != nsamp { return 0 }
88 if sames(Lb, dec, nsamp*2) == 0 { return 0 }
89 let bnL: i64 = b64_encode(enc, el, b64buf)
90 // (b64buf now holds L's base64; emit it before re-using b64buf for R)
91 app(out, off, "{id:'" as *u8); app_js(out, off, id); app(out, off, "',title:'" as *u8); app_js(out, off, title)
92 app(out, off, "',desc:'" as *u8); app_js(out, off, desc); app(out, off, "',rate:" as *u8); appn(out, off, srate)
93 app(out, off, ",sum:" as *u8); appn(out, off, sum)
94 let mono: i64 = sames(Lb, Rb, nsamp*2) // stereo decorrelation: L==R -> store ONE channel (halves mono-in-stereo)
95 app(out, off, ",mono:" as *u8); appn(out, off, mono); app(out, off, ",L:'" as *u8)
96 i = 0; while i < bnL { out[off[0]] = b64buf[i]; off[0] = off[0]+1; i = i+1 }
97 var er: i64 = 0
98 if mono == 0 {
99 er = nv1l_encode(Rb, nsamp, enc, cap)
100 if er <= 0 { return 0 }
101 if nv1l_decode(enc, er, dec, cap) != nsamp { return 0 }
102 if sames(Rb, dec, nsamp*2) == 0 { return 0 }
103 let bnR: i64 = b64_encode(enc, er, b64buf)
104 app(out, off, "',R:'" as *u8)
105 i = 0; while i < bnR { out[off[0]] = b64buf[i]; off[0] = off[0]+1; i = i+1 }
106 }
107 app(out, off, "'},\n" as *u8)
108 mp(" + " as *u8); mp(id); mp(" ours=" as *u8); mpn(el+er); if mono==1 { mp("B MONO(1ch)\n" as *u8) } else { mp("B\n" as *u8) }
109 return 1
110}
111
112func main() -> i64 {
113 mp("nx_listen_player: emit the /listen player decoding through OUR OWN NLC1 lossless codec\n" as *u8)
114 let cap: i64 = K_MAGIC_524288
115 let out: *u8 = sys_mmap(K_MAGIC_4194304)
116 let wav: *u8 = sys_mmap(cap); let Lb: *u8 = sys_mmap(cap); let Rb: *u8 = sys_mmap(cap)
117 let enc: *u8 = sys_mmap(cap); let dec: *u8 = sys_mmap(cap); let b64buf: *u8 = sys_mmap(cap)
118 let off: *i64 = sys_mmap(8) as *i64; off[0] = 0
119
120 app(out, off, "<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content=\x22width=device-width,initial-scale=1\x22><title>Nishi Family - Listen</title>" as *u8)
121 app(out, off, "<style>body{font-family:-apple-system,Segoe UI,Roboto,sans-serif;background:#0f1117;color:#e8eef8;max-width:760px;margin:0 auto;padding:0 18px 8vh}h1{font-size:1.7rem;margin:1.2rem 0 .2rem}.sub{color:#9aa6bd;font-size:.9rem;margin:0 0 .6rem}#codec{font-size:.78rem;color:#6b7793;margin:0 0 1rem}#now{font-size:1.15rem;font-weight:600;margin:1rem 0 .2rem}#desc{color:#9aa6bd;font-size:.88rem;min-height:2.4em}audio{width:100%;margin:.6rem 0}.ctl{display:flex;flex-wrap:wrap;gap:.5rem;margin:.6rem 0 1rem}.ctl button{padding:.5rem .9rem;border:0;border-radius:999px;background:#1b2233;color:#cfe0ff;font-size:.9rem;cursor:pointer}.ctl button.act{background:#2a4d8f;color:#fff}.list{display:flex;flex-direction:column;gap:.3rem}.list div{padding:.5rem .7rem;border-radius:8px;background:#161a24;cursor:pointer;font-size:.9rem}.list div.on{background:#2a4d8f;color:#fff}.foot{margin-top:1.6rem;color:#6b7793;font-size:.78rem;border-top:1px solid #232838;padding-top:1rem}</style></head><body>" as *u8)
122 app(out, off, "<h1>Listen</h1><p class=sub>Sovereign sound from the Nishi audio engine - no third party. Headphones recommended for the binaural tracks.</p><div id=codec>decoding...</div>" as *u8)
123 app(out, off, "<div id=now>-</div><div id=desc></div><audio id=au preload=none></audio>" as *u8)
124 app(out, off, "<div class=ctl><button id=play>Play</button><button id=stop>Stop</button><button id=prev>Prev</button><button id=next>Next</button><button id=shuf>Shuffle: off</button><button id=rep>Repeat: off</button><button id=newb>New one</button></div><div id=list class=list></div>" as *u8)
125
126 app(out, off, "<script>\nvar TRACKS=[\n" as *u8)
127 var ntr: i64 = 0
128 ntr = ntr + emit_track(out, off, "elara-hi" as *u8, "Elara says hi" as *u8, "Her own sovereign voice, formant synthesis from the vocal tract up: no ML, generated on her machine. First sound: aspirate h into an ai diphthong." as *u8, "web_assets/ng_elara_hi.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
129 ntr = ntr + emit_track(out, off, "elara-hello" as *u8, "Elara says hello" as *u8, "Her phoneme sequencer says a whole word: aspirate, vowels, and a lateral L, resonators flowing across each sound. Robotic but real, and hers." as *u8, "web_assets/ng_elara_hello.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
130 ntr = ntr + emit_track(out, off, "bowl" as *u8, "Tibetan Singing Bowl (binaural)" as *u8, "Five inharmonic resonant modes placed to your right via ITD + ILD." as *u8, "web_assets/ng_singing_bowl_binaural.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
131 ntr = ntr + emit_track(out, off, "theta" as *u8, "Binaural Beats - 7Hz theta" as *u8, "200Hz left + 207Hz right, a 7Hz theta beat for relaxation / self-hypnosis. Headphones required." as *u8, "web_assets/ng_binaural_beats_theta.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
132 ntr = ntr + emit_track(out, off, "delta" as *u8, "Binaural Beats - 3Hz delta (deep rest)" as *u8, "200Hz left + 203Hz right, a slow 3Hz delta beat for deep rest. Headphones required." as *u8, "web_assets/ng_beats_delta.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
133 ntr = ntr + emit_track(out, off, "alpha" as *u8, "Binaural Beats - 10Hz alpha (calm focus)" as *u8, "200Hz left + 210Hz right, a 10Hz alpha beat for relaxed focus. Headphones required." as *u8, "web_assets/ng_beats_alpha.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
134 ntr = ntr + emit_track(out, off, "beta" as *u8, "Binaural Beats - 18Hz beta (alert)" as *u8, "220Hz left + 238Hz right, an 18Hz beta beat for alert concentration. Headphones required." as *u8, "web_assets/ng_beats_beta.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
135 ntr = ntr + emit_track(out, off, "dog-squeak" as *u8, "Dog test - Squeak (squeaky-toy)" as *u8, "Synthesized prey-squeak, the classic squeaky-toy trigger. Play it and watch your dogs reaction." as *u8, "web_assets/ng_dog_squeak.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
136 ntr = ntr + emit_track(out, off, "dog-chirp" as *u8, "Dog test - Bird chirp" as *u8, "Synthesized bird tweets. Dogs orient hard to birdsong - watch the ears." as *u8, "web_assets/ng_dog_chirp.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
137 ntr = ntr + emit_track(out, off, "dog-whistle" as *u8, "Dog test - Training whistle" as *u8, "Synthesized slide whistle, a clean tone for recall / attention tests." as *u8, "web_assets/ng_dog_whistle.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
138 ntr = ntr + emit_track(out, off, "dog-bark" as *u8, "Dog test - Bark (wuff-wuff)" as *u8, "Synthesized bark: pitched glottal pulses through formant resonators (source-filter). First pass - tune by ear." as *u8, "web_assets/ng_dog_bark.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
139 ntr = ntr + emit_track(out, off, "dog-growl" as *u8, "Dog test - Growl" as *u8, "Synthesized low growl with roughness modulation (source-filter + AM). First pass - tune by ear." as *u8, "web_assets/ng_dog_growl.wav\x00" as *u8, wav, Lb, Rb, enc, dec, b64buf, cap)
140 app(out, off, "];\n" as *u8)
141
142 // ---- in-browser port of OUR NLC1 LPC decoder (mirrors nv1l_decode) ----
143 app(out, off, "function b64d(s){var bin=atob(s),n=bin.length,a=new Uint8Array(n),i;for(i=0;i<n;i++)a[i]=bin.charCodeAt(i);return a}\n" as *u8)
144 app(out, off, "function nvDec(b){var mode=b[0],k=b[1],ns=b[2]|(b[3]<<8)|(b[4]<<16)|(b[5]*16777216),out=new Int16Array(ns),i,v;\n" as *u8)
145 app(out, off, "if(mode===255){for(i=0;i<ns;i++){v=b[6+2*i]|(b[7+2*i]<<8);if(v>=32768)v-=65536;out[i]=v}return out}\n" as *u8)
146 app(out, off, "var p1=0,p2=0,p3=0;for(i=0;i<mode;i++){v=b[6+2*i]|(b[7+2*i]<<8);if(v>=32768)v-=65536;out[i]=v;p3=p2;p2=p1;p1=v}\n" as *u8)
147 app(out, off, "var bit=(6+2*mode)*8,lim=b.length*8;function gb(){if(bit>=lim)return -1;var r=(b[bit>>3]>>(bit&7))&1;bit++;return r}\n" as *u8)
148 app(out, off, "for(;i<ns;i++){var q=0,t;while((t=gb())===1)q++;if(t<0)return null;var low=0,j;for(j=0;j<k;j++){var bj=gb();if(bj<0)return null;low|=bj<<j}var u=(q<<k)|low;var r=(u&1)?-((u+1)>>1):(u>>1);var pr=0;if(mode===1)pr=p1;else if(mode===2)pr=2*p1-p2;else if(mode===3)pr=3*p1-3*p2+p3;v=pr+r;out[i]=v;p3=p2;p2=p1;p1=v}return out}\n" as *u8)
149 app(out, off, "function wstr(b,o,s){for(var i=0;i<s.length;i++)b[o+i]=s.charCodeAt(i)}\n" as *u8)
150 app(out, off, "function buildWav(L,R,rate){var n=L.length,dl=n*4,b=new Uint8Array(44+dl),dv=new DataView(b.buffer);wstr(b,0,'RIFF');dv.setUint32(4,36+dl,true);wstr(b,8,'WAVE');wstr(b,12,'fmt ');dv.setUint32(16,16,true);dv.setUint16(20,1,true);dv.setUint16(22,2,true);dv.setUint32(24,rate,true);dv.setUint32(28,rate*4,true);dv.setUint16(32,4,true);dv.setUint16(34,16,true);wstr(b,36,'data');dv.setUint32(40,dl,true);var o=44,i;for(i=0;i<n;i++){dv.setInt16(o,L[i],true);dv.setInt16(o+2,R[i],true);o+=4}return b}\n" as *u8)
151 app(out, off, "function cksum(L,R){var s=0,i,a,c;for(i=0;i<L.length;i++){a=L[i]<0?-L[i]:L[i];c=R[i]<0?-R[i]:R[i];s=(s+a+c)%1000000007}return s}\n" as *u8)
152
153 // ---- player ----
154 app(out, off, "var i=0,shuf=0,rep=0,urls={};var au=document.getElementById('au');function $(x){return document.getElementById(x)}\n" as *u8)
155 app(out, off, "function bk(ev){try{var bb='t='+encodeURIComponent(TRACKS[i].id)+'&e='+ev;if(navigator.sendBeacon)navigator.sendBeacon('/stat',bb);else fetch('/stat',{method:'POST',body:bb,keepalive:true})}catch(e){}}\n" as *u8)
156 app(out, off, "function dec(t){if(urls[t.id])return urls[t.id];var L=nvDec(b64d(t.L)),R=t.mono?L:nvDec(b64d(t.R));if(!L||!R){$('codec').textContent='Codec decode error on '+t.id;$('codec').style.color='#f88';return null}if(cksum(L,R)!==t.sum){$('codec').textContent='Codec self-test FAILED on '+t.id+' (not played)';$('codec').style.color='#f88';return null}var url=URL.createObjectURL(new Blob([buildWav(L,R,t.rate)],{type:'audio/wav'}));urls[t.id]=url;return url}\n" as *u8)
157 app(out, off, "function show(){$('now').textContent=TRACKS[i].title;$('desc').textContent=TRACKS[i].desc;var Ls=$('list'),k;for(k=0;k<Ls.children.length;k++)Ls.children[k].className=(k==i?'on':'')}\n" as *u8)
158 app(out, off, "function load(n){i=(n+TRACKS.length)%TRACKS.length;var u=dec(TRACKS[i]);if(u){au.src=u;au.loop=!!rep}show();bk('impression')}\n" as *u8)
159 app(out, off, "function pl(){au.play();$('play').textContent='Pause'}function pa(){au.pause();$('play').textContent='Play'}\n" as *u8)
160 app(out, off, "$('play').onclick=function(){if(au.paused){pl();bk('play')}else{pa()}};$('stop').onclick=function(){au.pause();au.currentTime=0;pa();bk('stop')};\n" as *u8)
161 app(out, off, "$('next').onclick=function(){if(!au.ended&&au.currentTime>0){bk('skip')}var n=shuf?Math.floor(Math.random()*TRACKS.length):i+1;load(n);pl();bk('play')};$('prev').onclick=function(){load(i-1);pl();bk('play')};\n" as *u8)
162 app(out, off, "$('shuf').onclick=function(){shuf=shuf?0:1;this.textContent='Shuffle: '+(shuf?'on':'off');this.className=shuf?'act':''};$('rep').onclick=function(){rep=rep?0:1;au.loop=!!rep;this.textContent='Repeat: '+(rep?'on':'off');this.className=rep?'act':'';bk('loop')};\n" as *u8)
163 app(out, off, "$('newb').onclick=function(){bk('tire');var n=i;if(TRACKS.length>1){while(n==i){n=Math.floor(Math.random()*TRACKS.length)}}load(n);pl();bk('play')};\n" as *u8)
164 app(out, off, "au.onended=function(){bk('complete');if(rep){return}var n=shuf?Math.floor(Math.random()*TRACKS.length):i+1;load(n);pl();bk('play')};\n" as *u8)
165 app(out, off, "(function(){var Ls=$('list'),k;for(k=0;k<TRACKS.length;k++){(function(k){var d=document.createElement('div');d.textContent=TRACKS[k].title;d.onclick=function(){load(k);pl();bk('play')};Ls.appendChild(d)})(k)}})();\n" as *u8)
166 app(out, off, "load(0);if(urls[TRACKS[0].id]){$('codec').textContent='Audio: Nishi NLC1 lossless codec, decoded in your browser (no third party).';$('codec').style.color='#8fbf8f'}\n</script>" as *u8)
167
168 app(out, off, "<p class=foot>Every clip is synthesized AND compressed by the Nishi engine (our own FLAC-class lossless codec), then decoded right here in your browser - no third-party codec touches it. Anonymous by design: only which track was played/skipped/tired-of is ever sent back, never who.</p></body></html>\n" as *u8)
169 out[off[0]] = 0 as u8
170
171 let wfd: i64 = sys_openat_wr(OUTP, 420)
172 var wrote: i64 = 0
173 if wfd >= 0 { sys_write(wfd, out, off[0]); sys_close(wfd); wrote = 1 }
174 mp(" tracks=" as *u8); mpn(ntr); mp(" page bytes=" as *u8); mpn(off[0]); mp(" wrote=" as *u8); mpn(wrote); mp("\n verdict=" as *u8)
175 var ok: i64 = 1
176 if ntr < 10 { ok = 0 }
177 if wrote != 1 { ok = 0 }
178 if ok == 1 { mp("GREEN (8 tracks, all our-codec-compressed + bit-exact self-checked; in-browser decoder embedded)\n" as *u8); sys_exit(0); return 0 }
179 mp("RED (a track failed bit-exact self-check or write failed)\n" as *u8)
180 sys_exit(1); return 1
181}