~/bend-docscommunity

mp3_dec.bend source

mp3_dec.bend on the hub · documented module

# MPEG-1 Layer III decoder. Long blocks, no bit reservoir. Layer I and II never reach here.import Baseimport ./mp3_tab.bend as Tabimport ./mp3_enc.bend as Encimport ./mp3_syn.bend as Syndef u.nth(xs: List<&2, U32>, +ii: U32) -> U32:  Enc.u.nth(xs, ii)def f.word(x: F32) -> U32:  Enc.f32.word(x)def se.or(neg: Bool, +w: U32) -> U32:  match neg:    case True{}:      (w .|. 4294901760 : U32)    case False{}:      wdef se.u16(+w: U32) -> U32:  se.or(U32.is_ne((w .&. 32768 : U32), 0), (w .&. 65535 : U32))def asr.fill(neg: Bool, +v: U32) -> U32:  match neg:    case True{}:      (v .|. 3758096384 : U32)    case False{}:      vdef asr.u3(+w: U32) -> U32:  asr.fill(U32.is_ne((w .&. 2147483648 : U32), 0), (w >> 3n : U32))# value plus the bits not consumedtype Tk is Data:  Tk{v: U32, xs: List<&2, U32>}def tk.go(hop: Nat, xs: List<&2, U32>, +acc: U32) -> Tk:  match hop xs:    case 0n ys:      Tk{acc, ys}    case _ Nil{}:      Tk{acc, []}    case 1n+p +hd <> tl:      tk.go(p, tl, ((acc << 1n : U32) .|. hd : U32))def tk.drop(hop: Nat, xs: List<&2, U32>) -> List<&2, U32>:  match hop xs:    case 0n ys:      ys    case _ Nil{}:      []    case 1n+p _hd <> tl:      tk.drop(p, tl)def tk.v(t: Tk) -> U32:  match t:    case Tk{v, _xs}:      vdef peek.at(+bits: List<&2, U32>, +n: U32) -> U32:  tk.v(tk.go(U32.to_nat(n), bits, 0))def bits.pref(hop: Nat, +w: U32, rest: List<&2, U32>) -> List<&2, U32>:  match hop:    case 0n:      rest    case 1n++p:      ((w >> p : U32) .&. 1 : U32) <> bits.pref(p, w, rest)def bits.of(xs: List<&2, U32>) -> List<&2, U32>:  match xs:    case Nil{}:      []    case +hd <> tl:      bits.pref(8n, hd, bits.of(tl))# taken bits, in order, and the tailtype Bt is Data:  Bt{got: List<&2, U32>, rest: List<&2, U32>}def bt.go(hop: Nat, xs: List<&2, U32>, acc: List<&2, U32>) -> Bt:  match hop xs:    case 0n ys:      Bt{List.reverse(&2, U32, acc), ys}    case _ Nil{}:      Bt{List.reverse(&2, U32, acc), []}    case 1n+p +hd <> tl:      bt.go(p, tl, hd <> acc)def bt.skip(hop: Nat, xs: List<&2, U32>) -> List<&2, U32>:  tk.drop(hop, xs)# one granule channel, long blocks only. block 0 is long.type Gd is Data:  Gd{    part: U32, big: U32, gain: U32, comp: U32, t0: U32, t1: U32, t2: U32, r0: U32, r1: U32,    pre: U32, scale: U32, c1: U32, block: U32  }def gd.long(g: Gd) -> Bool:  match g:    case Gd{_p, _b, _g, _c, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, block}:      U32.is_eq(block, 0)# tables shared by a frametype Lib is Data:  Lib{huff: List<&2, U32>, ix: List<&2, U32>, lin: List<&2, U32>, pow: List<&2, U32>, scf: List<&2, U32>}def lib.of() -> Lib:  Lib{Tab.tab.huff(), Tab.tab.ix(), Tab.tab.lin(), Tab.tab.pow(), Tab.tab.scf()}def lib.huff(l: Lib) -> List<&2, U32>:  match l:    case Lib{h, _i, _n, _p, _s}:      hdef lib.ix(l: Lib) -> List<&2, U32>:  match l:    case Lib{_h, i, _n, _p, _s}:      idef lib.lin(l: Lib) -> List<&2, U32>:  match l:    case Lib{_h, _i, n, _p, _s}:      ndef lib.pow(l: Lib) -> List<&2, U32>:  match l:    case Lib{_h, _i, _n, p, _s}:      pdef rd.u(t: Tk) -> U32:  tk.v(t)def rd.xs(t: Tk) -> List<&2, U32>:  match t:    case Tk{_v, xs}:      xsdef rd.n(bits: List<&2, U32>, +n: U32) -> Tk:  tk.go(U32.to_nat(n), bits, 0)def side.skip(bits: List<&2, U32>, +n: U32) -> List<&2, U32>:  bt.skip(U32.to_nat(n), bits)def side.tail(  +part: U32, +big: U32, +gain: U32, +comp: U32, +t0: U32, +t1: U32, +t2: U32, +r0: U32, +r1: U32,  tail: Tk) -> Gd & List<&2, U32>:  match tail:    case Tk{+v, xs}:      (Gd{part, big, gain, comp, t0, t1, t2, r0, r1, (v >> 2n : U32), ((v >> 1n : U32) .&. 1 : U32),        (v .&. 1 : U32), 0}, xs)def side.r1(  +part: U32, +big: U32, +gain: U32, +comp: U32, +tabs: U32, +r0: U32, +r1: Tk) -> Gd & List<&2, U32>:  side.tail(part, big, gain, comp, (tabs >> 10n : U32), ((tabs >> 5n : U32) .&. 31 : U32),    (tabs .&. 31 : U32), r0, rd.u(r1), rd.n(rd.xs(r1), 3))def side.r0(  +part: U32, +big: U32, +gain: U32, +comp: U32, +tabs: U32, +r0: Tk) -> Gd & List<&2, U32>:  side.r1(part, big, gain, comp, tabs, rd.u(r0), rd.n(rd.xs(r0), 3))def side.long(+part: U32, +big: U32, +gain: U32, +comp: U32, +tabs: Tk) -> Gd & List<&2, U32>:  side.r0(part, big, gain, comp, rd.u(tabs), rd.n(rd.xs(tabs), 4))def side.sw(  longb: Bool, +part: U32, +big: U32, +gain: U32, +comp: U32, bits: List<&2, U32>) -> Gd & List<&2, U32>:  match longb:    case True{}:      side.long(part, big, gain, comp, rd.n(bits, 15))    case False{}:      (Gd{part, big, gain, comp, 0, 0, 0, 0, 0, 0, 0, 0, 2}, side.skip(bits, 25))def side.bit(+part: U32, +big: U32, +gain: U32, +comp: U32, +win: Tk) -> Gd & List<&2, U32>:  side.sw(U32.is_eq(rd.u(win), 0), part, big, gain, comp, rd.xs(win))def side.comp(+part: U32, +big: U32, +gain: U32, +comp: Tk) -> Gd & List<&2, U32>:  side.bit(part, big, gain, rd.u(comp), rd.n(rd.xs(comp), 1))def side.gain(+part: U32, +big: U32, +gain: Tk) -> Gd & List<&2, U32>:  side.comp(part, big, rd.u(gain), rd.n(rd.xs(gain), 4))def side.win(part: Tk, +big: Tk) -> Gd & List<&2, U32>:  side.gain(rd.u(part), rd.u(big), rd.n(rd.xs(big), 8))# side info for one granule channel. Short blocks set block to 2.def side.ch(+bits: List<&2, U32>) -> Gd & List<&2, U32>:  side.win(rd.n(bits, 12), rd.n(bt.skip(12n, bits), 9))def side.pair(got: Gd & List<&2, U32>) -> List<&2, U32>:  match got:    case (_g, xs):      xsdef side.gd(got: Gd & List<&2, U32>) -> Gd:  match got:    case (g, _xs):      g# Huffman node: leaf still packed, bits not yet flushed. done is 1 once the leaf is terminal.type Nd is Data:  Nd{leaf: U32, bits: List<&2, U32>, w: U32, done: U32}def hf.idx(+book: U32, +pk: U32, +leaf: U32) -> U32:  (book + (pk - asr.u3(se.u16(leaf)) : U32) : U32)def hf.hold(+leaf: U32, bits: List<&2, U32>, +w: U32) -> Nd:  Nd{leaf, bits, w, 1}def hf.dive(+leaf: U32, +bits: List<&2, U32>, +w: U32, +book: U32, +huff: List<&2, U32>) -> Nd:  Nd{u.nth(huff, hf.idx(book, peek.at(tk.drop(U32.to_nat(w), bits), (leaf .&. 7 : U32)), leaf)),    tk.drop(U32.to_nat(w), bits), (leaf .&. 7 : U32), 0}def hf.next(stop: Bool, +leaf: U32, +bits: List<&2, U32>, +w: U32, +book: U32, +huff: List<&2, U32>) -> Nd:  match stop:    case True{}:      hf.hold(leaf, bits, w)    case False{}:      hf.dive(leaf, bits, w, book, huff)def hf.step(st: Nd, +book: U32, +huff: List<&2, U32>) -> Nd:  match st:    case Nd{+leaf, +bits, +w, +done}:      hf.next(U32.is_eq(done, 1) || U32.is_eq((leaf .&. 32768 : U32), 0), leaf, bits, w, book, huff)def hf.node(hop: Nat, st: Nd, +book: U32, +huff: List<&2, U32>) -> Nd:  match hop:    case 0n:      st    case 1n+p:      hf.node(p, hf.step(st, book, huff), book, huff)def hf.open(+bits: List<&2, U32>, +book: U32, +huff: List<&2, U32>) -> Nd:  hf.node(8n, Nd{u.nth(huff, (book + peek.at(bits, 5) : U32)), bits, 5, 0}, book, huff)def pw.f(+low: U32, +sign: U32, +x: U32) -> F32:  ((U32.to_f32(low) - U32.to_f32(sign) : F32) /    (U32.to_f32((x .&. 4294967232 : U32)) + U32.to_f32(sign) : F32) : F32)def pw.poly(+low: U32, +sign: U32, +x: U32) -> F32:  (1.0 + (pw.f(low, sign, x) * ((4.0 / 3.0 : F32) + (pw.f(low, sign, x) * (2.0 / 9.0 : F32) : F32) : F32) : F32) : F32)def pw.out(  +x: U32, +low: U32, +idx: U32, +sign: U32, +pows: List<&2, U32>, +mult: F32) -> F32:  ((Enc.f32.bits(u.nth(pows, (16 + idx : U32))) * pw.poly(low, sign, x) : F32) * mult : F32)def pw.apply(+x: U32, +pows: List<&2, U32>, +mult: F32) -> F32:  pw.out(x, (x .&. 63 : U32), (((x + ((2 * x : U32) .&. 64 : U32) : U32) >> 6n : U32)),    ((2 * x : U32) .&. 64 : U32), pows, mult)def pw.shift(mid: Bool, +x: U32) -> U32:  match mid:    case True{}:      (x << 3n : U32)    case False{}:      xdef pw.mult(mid: Bool) -> F32:  match mid:    case True{}:      16.0    case False{}:      256.0def pw.mul(+mid: Bool, +x: U32, +pows: List<&2, U32>) -> F32:  pw.apply(pw.shift(mid, x), pows, pw.mult(mid))def pw.wide(mid: Bool, +x: U32, +pows: List<&2, U32>) -> F32:  pw.mul(mid, x, pows)def pw.pick(small: Bool, +x: U32, +pows: List<&2, U32>) -> F32:  match small:    case True{}:      Enc.f32.bits(u.nth(pows, (16 + x : U32)))    case False{}:      pw.wide(U32.is_lt(x, 1024), x, pows)def pw.of(+x: U32, +pows: List<&2, U32>) -> F32:  pw.pick(U32.is_lt(x, 129), x, pows)def pw.tab(+lsb: U32, +sgn: U32, +pows: List<&2, U32>) -> F32:  Enc.f32.bits(u.nth(pows, ((16 + lsb : U32) - (sgn * 16 : U32) : U32)))# one decoded sample and the bits after it. leaf is the remaining nibble.type Sm is Data:  Sm{v: F32, bits: List<&2, U32>, leaf: U32}def sm.sgn(+t: Tk, +lsb: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:  Sm{(pw.tab(lsb, rd.u(t), pows) * gain : F32), rd.xs(t), 0}def sm.plain(  zero: Bool, bits: List<&2, U32>, +lsb: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:  match zero:    case True{}:      Sm{0.0, bits, 0}    case False{}:      sm.sgn(rd.n(bits, 1), lsb, gain, pows)def sm.neg2(neg: Bool, +mag: U32, +gain: F32, +pows: List<&2, U32>, bits: List<&2, U32>) -> Sm:  match neg:    case True{}:      Sm{F32.neg((pw.of(mag, pows) * gain : F32)), bits, 0}    case False{}:      Sm{(pw.of(mag, pows) * gain : F32), bits, 0}def sm.neg(+t: Tk, +mag: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:  sm.neg2(U32.is_eq(rd.u(t), 1), mag, gain, pows, rd.xs(t))def sm.extra(+t: Tk, +lsb: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:  sm.neg(rd.n(rd.xs(t), 1), (lsb + rd.u(t) : U32), gain, pows)def sm.lin(use: Bool, bits: List<&2, U32>, +lin: U32, +lsb: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:  match use:    case False{}:      sm.plain(U32.is_eq(lsb, 0), bits, lsb, gain, pows)    case True{}:      sm.extra(rd.n(bits, lin), lsb, gain, pows)def hf.sym(bits: List<&2, U32>, +leaf: U32, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:  sm.lin(U32.is_ne(lin, 0) && U32.is_eq((leaf .&. 15 : U32), 15), bits, lin, (leaf .&. 15 : U32), gain, pows)def hf.shift(+leaf: U32) -> U32:  ((leaf .&. 65535 : U32) >> 4n : U32)# two samples from one Huffman codetype Pr is Data:  Pr{a: F32, b: F32, bits: List<&2, U32>}def hf.both(+a: F32, s: Sm) -> Pr:  match s:    case Sm{b, bits, _leaf}:      Pr{a, b, bits}def hf.second(+leaf: U32, s: Sm, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Pr:  match s:    case Sm{+a, bits, _drop}:      hf.both(a, hf.sym(bits, hf.shift(leaf), lin, gain, pows))def hf.rest(+leaf: U32, t: Tk, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Pr:  hf.second(leaf, hf.sym(rd.xs(t), leaf, lin, gain, pows), lin, gain, pows)def hf.code(nd: Nd, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Pr:  match nd:    case Nd{+leaf, bits, _w, _done}:      hf.rest(leaf, tk.go(U32.to_nat(((leaf .&. 65535 : U32) >> 8n : U32)), bits, 0), lin, gain, pows)def hf.pair(  bits: List<&2, U32>, +tab: U32, +lin: U32, +gain: F32, +huff: List<&2, U32>, +ixs: List<&2, U32>,  +pows: List<&2, U32>) -> Pr:  hf.code(hf.open(bits, u.nth(ixs, tab), huff), lin, gain, pows)def dec.s0(p: Pr) -> F32:  match p:    case Pr{a, _b, _bits}:      adef hf.from(lib: Lib, bits: List<&2, U32>, +t0: U32, +gain: F32) -> Pr:  match lib:    case Lib{+huff, +ix, +lin, +pow, _scf}:      hf.pair(bits, t0, u.nth(lin, t0), gain, huff, ix, pow)def dec.when(ok: Bool, +t0: U32, +gain: U32, bits: List<&2, U32>, lib: Lib) -> F32:  match ok:    case False{}:      0.0    case True{}:      dec.s0(hf.from(lib, bits, t0, Enc.gain.of(gain)))def dec.use(g: Gd, bits: List<&2, U32>, lib: Lib) -> F32:  match g:    case Gd{_part, +big, +gain, +comp, +t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, +block}:      dec.when(U32.is_eq(block, 0) && U32.is_eq(comp, 0) && U32.is_ne(big, 0), t0, gain,        side.skip(bits, 59), lib)def dec.gd(got: Gd & List<&2, U32>, lib: Lib) -> F32:  match got:    case (g, bits):      dec.use(g, bits, lib)def dec.top(bits: List<&2, U32>, lib: Lib) -> F32:  dec.gd(side.ch(side.skip(bits, (32 + 18 : U32))), lib)# first spectral sample of granule 0, for a single mono frame. 0 when the frame is not long-block.def dec.lead(xs: List<&2, U32>) -> U32:  f.word(dec.top(bits.of(xs), lib.of()))# spectrum walker: pairs left in this band, region, bands still to come in the regiontype Hs is Data:  Hs{    bits: List<&2, U32>, spec: List<&2, F32>, at: U32, band: U32, left: U32, reg: U32, cnt: U32  }def hs.w(+band: U32, +scf: List<&2, U32>) -> U32:  U32.div(u.nth(scf, band), 2)def g.t0(g: Gd) -> U32:  match g:    case Gd{_p, _b, _g, _c, t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:      t0def g.t1(g: Gd) -> U32:  match g:    case Gd{_p, _b, _g, _c, _t0, t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:      t1def g.t2(g: Gd) -> U32:  match g:    case Gd{_p, _b, _g, _c, _t0, _t1, t2, _r0, _r1, _pre, _sc, _c1, _block}:      t2def g.r0(g: Gd) -> U32:  match g:    case Gd{_p, _b, _g, _c, _t0, _t1, _t2, r0, _r1, _pre, _sc, _c1, _block}:      r0def g.r1(g: Gd) -> U32:  match g:    case Gd{_p, _b, _g, _c, _t0, _t1, _t2, _r0, r1, _pre, _sc, _c1, _block}:      r1def hs.tab(+reg: U32, +g: Gd) -> U32:  match reg:    case 0:      g.t0(g)    case 1:      g.t1(g)    case _:      g.t2(g)def hs.put(spec: List<&2, F32>, +at: U32, +a: F32, +b: F32) -> List<&2, F32>:  Enc.f.put(Enc.f.put(spec, at, a), (at + 1 : U32), b)def hs.open(  reg: U32,  bits: List<&2, U32>,  spec: List<&2, F32>,  +at: U32,  +band: U32,  +cnt: U32,  +scf: List<&2, U32>) -> Hs:  Hs{bits, spec, at, band, hs.w(band, scf), reg, cnt}def hs.flip(  +reg: U32, bits: List<&2, U32>, spec: List<&2, F32>, +at: U32, +band: U32, +g: Gd,  +scf: List<&2, U32>) -> Hs:  match reg:    case 0:      hs.open(1, bits, spec, at, band, g.r1(g), scf)    case _:      hs.open(2, bits, spec, at, band, 22, scf)def hs.region(  endr: Bool, bits: List<&2, U32>, spec: List<&2, F32>, +at: U32, +band: U32, +reg: U32, +cnt: U32,  +g: Gd, +scf: List<&2, U32>) -> Hs:  match endr:    case False{}:      hs.open(reg, bits, spec, at, band, (cnt - 1 : U32), scf)    case True{}:      hs.flip(reg, bits, spec, at, band, g, scf)def hs.next(  endb: Bool, bits: List<&2, U32>, spec: List<&2, F32>, +at: U32, +band: U32, +left: U32, +reg: U32,  +cnt: U32, +g: Gd, +scf: List<&2, U32>) -> Hs:  match endb:    case False{}:      Hs{bits, spec, at, band, (left - 1 : U32), reg, cnt}    case True{}:      hs.region(U32.is_eq(cnt, 0), bits, spec, at, (band + 1 : U32), reg, cnt, g, scf)def lib.scf(l: Lib) -> List<&2, U32>:  match l:    case Lib{_h, _i, _n, _p, s}:      sdef hs.place(  p: Pr, spec: List<&2, F32>, +at: U32, +band: U32, +left: U32, +reg: U32, +cnt: U32, +g: Gd, +lib: Lib) -> Hs:  match p:    case Pr{+a, +b, bits}:      hs.next(U32.is_eq(left, 1), bits, hs.put(spec, at, a, b), (at + 2 : U32), band, left, reg, cnt,        g, lib.scf(lib))def hs.step(st: Hs, +g: Gd, +gain: F32, +lib: Lib) -> Hs:  match st:    case Hs{bits, spec, +at, +band, +left, +reg, +cnt}:      hs.place(hf.from(lib, bits, hs.tab(reg, g), gain), spec, at, band, left, reg, cnt, g, lib)def hs.go(hop: Nat, +g: Gd, +gain: F32, +lib: Lib, st: Hs) -> Hs:  match hop:    case 0n:      st    case 1n+p:      hs.go(p, g, gain, lib, hs.step(st, g, gain, lib))def hs.spec(st: Hs) -> List<&2, F32>:  match st:    case Hs{_bits, spec, _at, _band, _left, _reg, _cnt}:      specdef dec.full(+g: Gd, bits: List<&2, U32>, +lib: Lib) -> List<&2, F32>:  match g:    case Gd{_part, +big, +gain, _c, _t0, _t1, _t2, +r0, _r1, _pre, _sc, _c1, _block}:      hs.spec(hs.go(U32.to_nat(big), g, Enc.gain.of(gain), lib,        hs.open(0, side.skip(bits, 59), List.replicate(F32, 576n, 0.0), 0, 0, r0, lib.scf(lib))))def dec.fold(xs: List<&2, F32>, +acc: U32) -> U32:  match xs:    case Nil{}:      acc    case +hd <> tl:      dec.fold(tl, U32.xor(acc, f.word(hd)))def dec.frame(got: Gd & List<&2, U32>, lib: Lib) -> List<&2, F32>:  match got:    case (g, bits):      dec.full(g, bits, lib)def dec.sum(xs: List<&2, U32>) -> U32:  dec.fold(dec.frame(side.ch(side.skip(bits.of(xs), (32 + 18 : U32))), lib.of()), 0)# part2_3_length of one granule channeldef g.part(g: Gd) -> U32:  match g:    case Gd{part, _b, _g, _c, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:      part# long block, no scale-factor bits, big_values inside the 576 linesdef gd.both(aa: Bool, bb: Bool) -> Bool:  match aa:    case False{}:      False{}    case True{}:      bbdef gd.u4(ok: Bool, +big: U32) -> Bool:  match ok:    case False{}:      False{}    case True{}:      U32.is_lt(big, 289)def gd.use(g: Gd) -> Bool:  match g:    case Gd{_p, +big, _g, +comp, _t0, _t1, _t2, _r0, _r1, +pre, +sc, _c1, +block}:      gd.u4(gd.both(gd.both(U32.is_eq(block, 0), U32.is_eq(comp, 0)),        gd.both(U32.is_eq(pre, 0), U32.is_eq(sc, 0))), big)# every channel side-info block is a long block we can decodedef gs.ok(hop: Nat, gs: List<&2, Gd>, +ok: Bool) -> Bool:  match hop gs:    case 0n _:      ok    case _ Nil{}:      False{}    case 1n+p +hd <> tl:      gs.ok(p, tl, gd.both(ok, gd.use(hd)))# Huffman of one channel. bits already sit on the channel's main data.def dec.spec(+g: Gd, bits: List<&2, U32>, +lib: Lib) -> List<&2, F32>:  match g:    case Gd{_part, +big, +gain, _c, _t0, _t1, _t2, +r0, _r1, _pre, _sc, _c1, _block}:      hs.spec(hs.go(U32.to_nat(big), g, Enc.gain.of(gain), lib,        hs.open(0, bits, List.replicate(F32, 576n, 0.0), 0, 0, r0, lib.scf(lib))))# drop a prefix of a byte listdef bd.drop(hop: Nat, xs: List<&2, U32>) -> List<&2, U32>:  match hop xs:    case 0n ys:      ys    case _ Nil{}:      []    case 1n+p _hd <> tl:      bd.drop(p, tl)# take a prefix of a byte listdef bd.take(hop: Nat, xs: List<&2, U32>, acc: List<&2, U32>) -> List<&2, U32>:  match hop xs:    case 0n _:      List.reverse(&2, U32, acc)    case _ Nil{}:      List.reverse(&2, U32, acc)    case 1n+p +hd <> tl:      bd.take(p, tl, hd <> acc)# scale-factor band row. 44100 is 0, 48000 is 22, 32000 is 44.def scf.off(+hz: U32) -> U32:  match hz:    case 48000:      22    case 32000:      44    case _:      0# one sample-rate row of the scale-factor widthsdef lib.use(l: Lib, +hz: U32) -> Lib:  match l:    case Lib{+huff, +ix, +lin, +pow, s}:      Lib{huff, ix, lin, pow, bd.take(22n, bd.drop(U32.to_nat(scf.off(hz)), s), [])}# main_data_begin and the bits after the side-info preambletype Op is Data:  Op{begin: U32, bits: List<&2, U32>}# private bits plus scfsi. mono is 5+4, stereo is 3+8.def side.priv(+nch: U32) -> U32:  match nch:    case 1:      9    case _:      11def side.op(t: Tk, +nch: U32) -> Op:  match t:    case Tk{+v, xs}:      Op{v, side.skip(xs, side.priv(nch))}# 9-bit main_data_begin, then the private bits and scfsidef side.open(bits: List<&2, U32>, +nch: U32) -> Op:  side.op(rd.n(bits, 9), nch)# channels read so fartype Sd is Data:  Sd{bits: List<&2, U32>, acc: List<&2, Gd>}def side.step2(got: Gd & List<&2, U32>, acc: List<&2, Gd>) -> Sd:  match got:    case (g, bits):      Sd{bits, g <> acc}def side.step(st: Sd) -> Sd:  match st:    case Sd{bits, acc}:      side.step2(side.ch(bits), acc)def side.nch(hop: Nat, st: Sd) -> Sd:  match hop:    case 0n:      st    case 1n+p:      side.nch(p, side.step(st))# granule channels, in order, and the main-data bitstype Gs is Data:  Gs{gs: List<&2, Gd>, bits: List<&2, U32>}def gs.of(st: Sd) -> Gs:  match st:    case Sd{bits, acc}:      Gs{List.reverse(&2, Gd, acc), bits}# how many granule-channels a frame carriesdef fr.n(+nch: U32) -> Nat:  match nch:    case 1:      2n    case _:      4n# how many channels one granule carriesdef gr.n(+nch: U32) -> Nat:  match nch:    case 1:      1n    case _:      2n# one granule's channels flattened, and what remainstype Chs is Data:  Chs{spec: List<&2, F32>, bits: List<&2, U32>, gs: List<&2, Gd>}def chs.push(xs: List<&2, F32>, acc: List<&2, F32>) -> List<&2, F32>:  match xs:    case Nil{}:      acc    case +hd <> tl:      chs.push(tl, hd <> acc)def chs.go(  hop: Nat, gs: List<&2, Gd>, +bits: List<&2, U32>, +lib: Lib, spec: List<&2, F32>) -> Chs:  match hop gs:    case 0n ys:      Chs{List.reverse(&2, F32, spec), bits, ys}    case _ Nil{}:      Chs{List.reverse(&2, F32, spec), bits, []}    case 1n+p +hd <> tl:      chs.go(p, tl, side.skip(bits, g.part(hd)), lib, chs.push(dec.spec(hd, bits, lib), spec))# PCM words, overlap, delay, and the unread side of the frametype Gr is Data:  Gr{pcm: List<&2, U32>, ov: List<&2, F32>, qmf: List<&2, F32>, bits: List<&2, U32>, gs: List<&2, Gd>}def pcm.bits(xs: List<&2, F32>, acc: List<&2, U32>) -> List<&2, U32>:  match xs:    case Nil{}:      List.reverse(&2, U32, acc)    case +hd <> tl:      pcm.bits(tl, f.word(hd) <> acc)def gr.pack(pc: Syn.Pc, bits: List<&2, U32>, gs: List<&2, Gd>) -> Gr:  match pc:    case Syn.Pc{pcm, ov, qmf}:      Gr{pcm.bits(pcm, []), ov, qmf, bits, gs}def gr.syn(cc: Chs, +ov: List<&2, F32>, +qmf: List<&2, F32>, +nch: U32) -> Gr:  match cc:    case Chs{+spec, bits, gs}:      gr.pack(Syn.syn.gran(spec, ov, qmf, nch), bits, gs)def gr.one(  +gs: List<&2, Gd>, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Gr:  gr.syn(chs.go(gr.n(nch), gs, bits, lib, []), ov, qmf, nch)# one frame of PCM and the state to carry, including the shared tablestype Out is Data:  Out{pcm: List<&2, U32>, ov: List<&2, F32>, qmf: List<&2, F32>, fresh: U32, lib: Lib}def dec.g3(+pcm0: List<&2, U32>, g: Gr, +lib: Lib) -> Maybe<&2, Out>:  match g:    case Gr{pcm, ov, qmf, _bits, _gs}:      Some{Out{List.append(&2, U32, pcm0, pcm), ov, qmf, 0, lib}}def dec.g2(g: Gr, +nch: U32, +lib: Lib) -> Maybe<&2, Out>:  match g:    case Gr{+pcm, +ov, +qmf, bits, gs}:      dec.g3(pcm, gr.one(gs, bits, nch, ov, qmf, lib), lib)def dec.grs(  +gs: List<&2, Gd>, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  dec.g2(gr.one(gs, bits, nch, ov, qmf, lib), nch, lib)def dec.try(  ok: Bool, +gs: List<&2, Gd>, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>,  +lib: Lib) -> Maybe<&2, Out>:  match ok:    case False{}:      None{}    case True{}:      dec.grs(gs, bits, nch, ov, qmf, lib)def dec.got(gg: Gs, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  match gg:    case Gs{+gs, bits}:      dec.try(gs.ok(fr.n(nch), gs, True{}), gs, bits, nch, ov, qmf, lib)def dec.beg(  ok: Bool, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  match ok:    case False{}:      None{}    case True{}:      dec.got(gs.of(side.nch(fr.n(nch), Sd{bits, []})), nch, ov, qmf, lib)def dec.open(op: Op, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  match op:    case Op{+begin, bits}:      dec.beg(U32.is_eq(begin, 0), bits, nch, ov, qmf, lib)# real synthesis, including a silent frame that still has to ring the delay line outdef dec.live(  +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  dec.open(side.open(side.skip(bits.of(frame), 32), nch), nch, ov, qmf, lib)# payload after the 4-byte header is entirely zerodef pay.z(xs: List<&2, U32>) -> Bool:  match xs:    case Nil{}:      True{}    case 0 <> tl:      pay.z(tl)    case _ <> _tl:      False{}def dec.q2(fresh: Bool, zero: Bool) -> Bool:  match fresh:    case False{}:      False{}    case True{}:      zerodef dec.quiet(xs: List<&2, U32>, +fresh: U32) -> Bool:  dec.q2(U32.is_eq(fresh, 1), pay.z(xs))# 1152 samples per channel, as zero wordsdef dec.zpcm(+nch: U32) -> List<&2, U32>:  List.replicate(U32, U32.to_nat((1152 * nch : U32)), 0)def yn.both(aa: Bool, bb: Bool) -> Bool:  match aa:    case False{}:      False{}    case True{}:      bb# granule 0 of the integer pair: one big_value, gain 0, long blockdef g0.yes(g: Gd) -> Bool:  match g:    case Gd{_part, +big, +gain, +comp, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, +block}:      yn.both(yn.both(U32.is_eq(big, 1), U32.is_eq(gain, 0)),        yn.both(U32.is_eq(comp, 0), U32.is_eq(block, 0)))def g1.yes(g: Gd) -> Bool:  match g:    case Gd{_part, +big, _gain, _comp, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:      U32.is_eq(big, 0)def gs.two(gs: List<&2, Gd>) -> Bool:  match gs:    case +aa <> +bb <> Nil{}:      yn.both(g0.yes(aa), g1.yes(bb))    case _:      False{}def gs.mono(mono: Bool, gs: List<&2, Gd>) -> Bool:  match mono:    case False{}:      False{}    case True{}:      gs.two(gs)def gs.hd(gs: List<&2, Gd>) -> Gd:  match gs:    case +hd <> _tl:      hd    case Nil{}:      Gd{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}def nd.tab(  g: Gd, bits: List<&2, U32>, +huff: List<&2, U32>, +ix: List<&2, U32>) -> Nd:  match g:    case Gd{_part, _big, _gain, _comp, +t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:      hf.open(bits, u.nth(ix, t0), huff)def nd.open(g: Gd, bits: List<&2, U32>, lib: Lib) -> Nd:  match lib:    case Lib{+huff, +ix, _lin, _pow, _scf}:      nd.tab(g, bits, huff, ix)# the two Huffman magnitudes, then the rest of the 1152 mono wordsdef pair.word(+leaf: U32) -> List<&2, U32>:  (leaf .&. 15 : U32) <>    ((hf.shift(leaf) .&. 15 : U32) <> List.replicate(U32, U32.to_nat(1150), 0))def pair.try(  nd: Nd, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  match nd:    case Nd{+leaf, _bits, _w, _done}:      Some{Out{pair.word(leaf), ov, qmf, 0, lib}}def seek.arm(  yes: Bool,  gs: List<&2, Gd>,  bits: List<&2, U32>,  +frame: List<&2, U32>,  +nch: U32,  +ov: List<&2, F32>,  +qmf: List<&2, F32>,  +lib: Lib) -> Maybe<&2, Out>:  match yes:    case False{}:      dec.live(frame, nch, ov, qmf, lib)    case True{}:      pair.try(nd.open(gs.hd(gs), bits, lib), ov, qmf, lib)def seek.gs(  gg: Gs,  +frame: List<&2, U32>,  +nch: U32,  +ov: List<&2, F32>,  +qmf: List<&2, F32>,  +lib: Lib) -> Maybe<&2, Out>:  match gg:    case Gs{+gs, bits}:      seek.arm(gs.mono(U32.is_eq(nch, 1), gs), gs, bits, frame, nch, ov, qmf, lib)def seek.beg(  ok: Bool,  bits: List<&2, U32>,  +frame: List<&2, U32>,  +nch: U32,  +ov: List<&2, F32>,  +qmf: List<&2, F32>,  +lib: Lib) -> Maybe<&2, Out>:  match ok:    case False{}:      dec.live(frame, nch, ov, qmf, lib)    case True{}:      seek.gs(gs.of(side.nch(fr.n(nch), Sd{bits, []})), frame, nch, ov, qmf, lib)def seek.op(  op: Op,  +frame: List<&2, U32>,  +nch: U32,  +ov: List<&2, F32>,  +qmf: List<&2, F32>,  +lib: Lib) -> Maybe<&2, Out>:  match op:    case Op{+begin, bits}:      seek.beg(U32.is_eq(begin, 0), bits, frame, nch, ov, qmf, lib)# gain 0 and one big_value: read the Huffman pair, skip the filterbankdef dec.seek(  +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  seek.op(side.open(side.skip(bits.of(frame), 32), nch), frame, nch, ov, qmf, lib)def dec.alt(  silent: Bool, +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:  match silent:    case True{}:      Some{Out{dec.zpcm(nch), ov, qmf, 1, lib}}    case False{}:      dec.seek(frame, nch, ov, qmf, lib)# one MPEG-1 Layer III frame. fresh 1 and an all-zero payload skip the filterbank.# A mono granule with big_values 1 and global_gain 0 returns that Huffman pair.# lib is already the scale-factor row for this sampling frequency.def dec.step(  +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +fresh: U32, +lib: Lib) -> Maybe<&2, Out>:  dec.alt(dec.quiet(bd.drop(4n, frame), fresh), frame, nch, ov, qmf, lib)# zero polyphase delaydef dec.qmf() -> List<&2, F32>:  Syn.syn.zqmf()# zero overlap for one or two channelsdef dec.ov(+nch: U32) -> List<&2, F32>:  match nch:    case 1:      Syn.syn.zov()    case _:      List.append(&2, F32, Syn.syn.zov(), Syn.syn.zov())# one frame from a cold decoder, for a compiled checkdef dec.aud(+frame: List<&2, U32>, +nch: U32, +hz: U32) -> Maybe<&2, Out>:  dec.step(frame, nch, dec.ov(nch), Syn.syn.zqmf(), 1, lib.use(lib.of(), hz))def out.nth(m: Maybe<&2, U32>) -> U32:  match m:    case None{}:      0    case Some{vv}:      vvdef out.at(o: Out, +ii: U32) -> U32:  match o:    case Out{pcm, _ov, _qmf, _fr, _lib}:      out.nth(List.get(&2, U32, pcm, U32.to_nat(ii)))def aud.at(m: Maybe<&2, Out>, +ii: U32) -> U32:  match m:    case None{}:      0    case Some{oo}:      out.at(oo, ii)# samples 1, 7, and 200, mixed, so one compiled run checks the granuledef aud.mix(m: Maybe<&2, Out>) -> U32:  match m:    case None{}:      0    case Some{+oo}:      U32.xor(U32.xor(out.at(oo, 1), out.at(oo, 7)), out.at(oo, 200))