code wiki / _hdl_build / nx_m4b_fixture.nx

nx_m4b_fixture.nx source

↩ module page · 70 lines · 4170 B

1// nx_m4b_fixture.nx -- build a tiny sovereign DRM-free M4B (MP4/ISOBMFF audiobook) so the M4B->.nmz rung can be 2// gated. MP4 = a tree of atoms (size:u32be + type:4 + payload). iTunes/audiobook metadata lives at 3// moov/udta/meta/ilst/<©nam|©ART|©alb>/data (meta is a FULLBOX: 4 version/flags bytes before its children). 4// Structure: ftyp + moov(udta(meta+vf(ilst(©nam,©ART,©alb)))) + mdat. expect_exit: 0 license_tier: ORIGINAL 5import "nx_syscalls.nx" 6const K_MAGIC_8192: i64 = 8192 7 8func mf_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 9func mf_p(s: *u8) -> i64 { sys_write(1, s, mf_slen(s)); return 0 } 10func mf_n(v: i64) -> i64 { let b: *u8=sys_mmap(24); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(24); var k: i64=0; if m==0{t[0]=48 as u8;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1}; sys_write(1,b,k); return 0 } 11func ensure_dir(path: *u8) -> i64 { __syscall(258, 0-100, path, 0x1ed, 0, 0, 0); return 0 } 12func put32(m: *u8, o: i64, v: i64) -> i64 { m[o]=((v>>24)&0xff) as u8; m[o+1]=((v>>16)&0xff) as u8; m[o+2]=((v>>8)&0xff) as u8; m[o+3]=(v&0xff) as u8; return o+4 } 13func puts(m: *u8, o: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ m[o+i]=s[i]; i=i+1 } return o+i } 14// write the 4-byte atom type at off (handles the © (0xA9) prefix via a raw byte buffer) 15func type4(m: *u8, o: i64, t: *u8) -> i64 { m[o]=t[0]; m[o+1]=t[1]; m[o+2]=t[2]; m[o+3]=t[3]; return o+4 } 16 17// emit a metadata atom: <type4>( data( typeflag=1[UTF-8] locale=0 <value> ) ). returns new offset. 18func emit_meta(m: *u8, o0: i64, t: *u8, value: *u8) -> i64 { 19 let astart: i64 = o0 20 var o: i64 = o0 + 4 // leave 4 bytes for atom size 21 o = type4(m, o, t) // atom type (e.g. ©nam) 22 let dstart: i64 = o 23 o = o + 4 // leave 4 for data-atom size 24 o = puts(m, o, "data" as *u8) 25 o = put32(m, o, 1) // well-known type 1 = UTF-8 text 26 o = put32(m, o, 0) // locale 27 o = puts(m, o, value) 28 put32(m, dstart, o - dstart) // backpatch data size 29 put32(m, astart, o - astart) // backpatch outer atom size 30 return o 31} 32 33func main() -> i64 { 34 ensure_dir("knowledge/fixtures" as *u8) 35 let m: *u8 = sys_mmap(K_MAGIC_8192) 36 let nam: *u8 = sys_mmap(8); nam[0]=0xa9 as u8; nam[1]=0x6e as u8; nam[2]=0x61 as u8; nam[3]=0x6d as u8 // ©nam 37 let art: *u8 = sys_mmap(8); art[0]=0xa9 as u8; art[1]=0x41 as u8; art[2]=0x52 as u8; art[3]=0x54 as u8 // ©ART 38 let alb: *u8 = sys_mmap(8); alb[0]=0xa9 as u8; alb[1]=0x61 as u8; alb[2]=0x6c as u8; alb[3]=0x62 as u8 // ©alb 39 40 var o: i64 = 0 41 // ftyp 42 let ftyp_s: i64 = o; o = o + 4 43 o = puts(m, o, "ftyp" as *u8); o = puts(m, o, "M4B " as *u8); o = put32(m, o, 0); o = puts(m, o, "M4B mp42" as *u8) 44 put32(m, ftyp_s, o - ftyp_s) 45 // moov 46 let moov_s: i64 = o; o = o + 4; o = puts(m, o, "moov" as *u8) 47 // udta 48 let udta_s: i64 = o; o = o + 4; o = puts(m, o, "udta" as *u8) 49 // meta (FULLBOX: 4 version/flags bytes before children) 50 let meta_s: i64 = o; o = o + 4; o = puts(m, o, "meta" as *u8); o = put32(m, o, 0) 51 // ilst 52 let ilst_s: i64 = o; o = o + 4; o = puts(m, o, "ilst" as *u8) 53 o = emit_meta(m, o, nam, "The Hobbit (Nishi M4B Fixture)" as *u8) 54 o = emit_meta(m, o, art, "J.R.R. Tolkien" as *u8) 55 o = emit_meta(m, o, alb, "Middle-earth M4B" as *u8) 56 put32(m, ilst_s, o - ilst_s) 57 put32(m, meta_s, o - meta_s) 58 put32(m, udta_s, o - udta_s) 59 put32(m, moov_s, o - moov_s) 60 // mdat (a few fake audio bytes) 61 let mdat_s: i64 = o; o = o + 4; o = puts(m, o, "mdat" as *u8) 62 var z: i64=0; while z<24 { m[o]=(0x40 + z) as u8; o=o+1; z=z+1 } 63 put32(m, mdat_s, o - mdat_s) 64 65 let fd: i64 = sys_openat_wr("knowledge/fixtures/nishi_audio.m4b" as *u8, 0x1a4) 66 if fd < 0 { mf_p("M4B-FIXTURE-FAIL open\n" as *u8); sys_exit(1); return 1 } 67 sys_write(fd, m, o); sys_close(fd) 68 mf_p("M4B-FIXTURE bytes=" as *u8); mf_n(o); mf_p(" -> knowledge/fixtures/nishi_audio.m4b\n" as *u8) 69 mf_p("M4B-FIXTURE-OK\n" as *u8); sys_exit(0); return 0 70}