src/mp3_enc.bend

emerging-ezaudio@0.4.0.0 · 1,531 lines · 0 definitions

1# MPEG-1 Layer III encoder: analysis filterbank, MDCT, quantiser, Huffman.
2import Base
3import emerging-ezaudio@0.4.0.0/src/mp3_tab.bend as Tab
4
5def f32.bits(+w: U32) -> F32:
6  match w:
7    case U32{+bb}:
8      F32{bb}
9
10def f32.word(x: F32) -> U32:
11  match x:
12    case F32{+bb}:
13      U32{bb}
14
15def u.nth.m(m: Maybe<&2, U32>) -> U32:
16  match m:
17    case None{}:
18      0
19    case Some{vv}:
20      vv
21
22def u.nth(xs: List<&2, U32>, +ii: U32) -> U32:
23  u.nth.m(List.get(&2, U32, xs, U32.to_nat(ii)))
24
25def f.nth.m(m: Maybe<&2, F32>) -> F32:
26  match m:
27    case None{}:
28      0.0
29    case Some{vv}:
30      vv
31
32def f.nth(xs: List<&2, F32>, +ii: U32) -> F32:
33  f.nth.m(List.get(&2, F32, xs, U32.to_nat(ii)))
34
35def f.put(xs: List<&2, F32>, +ii: U32, +vv: F32) -> List<&2, F32>:
36  List.set(&2, F32, xs, U32.to_nat(ii), vv)
37
38def f.of(xs: List<&2, U32>) -> List<&2, F32>:
39  match xs:
40    case Nil{}:
41      []
42    case +hd <> tl:
43      f32.bits(hd) <> f.of(tl)
44
45def f.rev(xs: List<&2, F32>) -> List<&2, F32>:
46  List.reverse(&2, F32, xs)
47
48def y.wrap(last: Bool, +ii: U32) -> U32:
49  match last:
50    case True{}:
51      0
52    case False{}:
53      (ii + 1 : U32)
54
55# 64 partials. Each windowed sample indexes one bin; a list walks from the head.
56type Ya is Type:
57  Ya{acc: Array<F32>, cur: F32}
58
59def ya.of(got: Array<F32> & F32) -> Ya:
60  (acc, cur) = got
61  Ya{acc, cur}
62
63def y.store(got: Ya, +ii: U32, +vv: F32) -> Array<F32>:
64  match got:
65    case Ya{acc, +cur}:
66      Array.set(F32, acc, ii, (cur + vv : F32))
67
68def y.add(acc: Array<F32>, +ii: U32, +vv: F32) -> Array<F32>:
69  y.store(ya.of(Array.get(F32, acc, ii)), ii, vv)
70
71def y.pull(hop: Nat, got: Ya, +ii: U32, acc: List<&2, F32>) -> List<&2, F32>:
72  match hop got:
73    case 0n Ya{_acc, +cur}:
74      f.rev(cur <> acc)
75    case 1n+p Ya{tab, +cur}:
76      y.pull(p, ya.of(Array.get(F32, tab, (ii + 1 : U32))), (ii + 1 : U32), (cur <> acc))
77
78def y.list(acc: Array<F32>) -> List<&2, F32>:
79  y.pull(63n, ya.of(Array.get(F32, acc, 0)), 0, [])
80
81# delay sample handed back beside the ring Array.get just read
82type Xs is Type:
83  Xs{x: Array<F32>, samp: F32}
84
85def xs.of(got: Array<F32> & F32) -> Xs:
86  (x, samp) = got
87  Xs{x, samp}
88
89# ring delay beside the 64 partial bins while windowing
90type Yr is Type:
91  Yr{x: Array<F32>, bins: Array<F32>}
92
93def y.step(got: Xs, bins: Array<F32>, +w: F32, +ii: U32) -> Yr:
94  match got:
95    case Xs{x2, +samp}:
96      Yr{x2, y.add(bins, ii, (samp * w : F32))}
97
98# window the 512-slot ring in place: multiply by win and fold into 64 bins
99def y.ring(
100  win: List<&2, F32>, got: Yr, +head: U32, +k: U32, +ii: U32
101) -> Yr:
102  match win got:
103    case Nil{} yr:
104      yr
105    case +w <> tl Yr{x, bins}:
106      y.ring(tl, y.step(xs.of(Array.get(F32, x, ((head + k : U32) .&. 511 : U32))), bins, w, ii),
107        head, (k + 1 : U32), y.wrap(U32.is_eq(ii, 63), ii))
108
109# a cosine table handed back beside the coefficient Array.get just read
110type Cf is Type:
111  Cf{tab: Array<F32>, co: F32}
112
113def cf.of(got: Array<F32> & F32) -> Cf:
114  (tab, co) = got
115  Cf{tab, co}
116
117def dot.go(tl: List<&2, F32>, got: Cf, +base: U32, +hd: F32, acc: F32) -> Array<F32> & F32:
118  match tl got:
119    case Nil{} Cf{tab, co}:
120      (tab, (acc + (co * hd : F32) : F32))
121    case +hd2 <> rest Cf{tab, co}:
122      dot.go(rest, cf.of(Array.get(F32, tab, (base + 1 : U32))), (base + 1 : U32), hd2,
123        (acc + (co * hd : F32) : F32))
124
125# tab.cos is 2048 F32s. Each tap reads that table with Array.get.
126def dot.row(ys: List<&2, F32>, tab: Array<F32>, +base: U32, acc: F32) -> Array<F32> & F32:
127  match ys:
128    case Nil{}:
129      (tab, acc)
130    case +hd <> tl:
131      dot.go(tl, cf.of(Array.get(F32, tab, base)), base, hd, acc)
132
133def sb.go(
134  hop: Nat, got: Cf, +ys: List<&2, F32>, +row: U32, acc: List<&2, F32>
135) -> Array<F32> & List<&2, F32>:
136  match hop got:
137    case 0n Cf{tab, dd}:
138      (tab, f.rev(((dd / 2.0 : F32) <> acc)))
139    case 1n+p Cf{tab, dd}:
140      sb.go(p, cf.of(dot.row(ys, tab, ((row + 1 : U32) * 64 : U32), 0.0)), ys, (row + 1 : U32),
141        ((dd / 2.0 : F32) <> acc))
142
143def sb.rows(
144  hop: Nat, tab: Array<F32>, +ys: List<&2, F32>, +row: U32, acc: List<&2, F32>
145) -> Array<F32> & List<&2, F32>:
146  match hop:
147    case 0n:
148      (tab, f.rev(acc))
149    case 1n+p:
150      sb.go(p, cf.of(dot.row(ys, tab, (row * 64 : U32), 0.0)), ys, row, acc)
151
152# subband result: ring delay returned beside the cosine table and 32 bands
153type As is Type:
154  As{x: Array<F32>, cos: Array<F32>, sb: List<&2, F32>}
155
156def as.of(x: Array<F32>, got: Array<F32> & List<&2, F32>) -> As:
157  (cos, sb) = got
158  As{x, cos, sb}
159
160def an.sb1(got: Yr, cos: Array<F32>) -> As:
161  match got:
162    case Yr{x2, bins}:
163      as.of(x2, sb.rows(32n, cos, y.list(bins), 0, []))
164
165# subband samples of one ring state. head indexes the oldest of 512 samples.
166def an.sb(
167  x: Array<F32>, +head: U32, +win: List<&2, F32>, cos: Array<F32>
168) -> As:
169  an.sb1(y.ring(win, Yr{x, Array.new(F32, 6n, 0.0)}, head, 0, 0), cos)
170
171# analysis delay ring (2^9 slots) and finished subband blocks, newest block first
172type An is Type:
173  An{x: Array<F32>, head: U32, out: List<&2, List<&2, F32>>}
174
175def an.done(+head: U32, out: List<&2, List<&2, F32>>, got: As) -> An & Array<F32>:
176  match got:
177    case As{x, cos, sb}:
178      (An{x, head, sb <> out}, cos)
179
180# overwrite the oldest 32 ring slots, then advance head
181def an.write(hop: Nat, x: Array<F32>, +at: U32, blk: List<&2, F32>) -> Array<F32>:
182  match hop blk:
183    case 0n _:
184      x
185    case _ Nil{}:
186      x
187    case 1n+p +hd <> tl:
188      an.write(p, Array.set(F32, x, at, hd), ((at + 1 : U32) .&. 511 : U32), tl)
189
190def an.push(st: An, blk: List<&2, F32>, +win: List<&2, F32>, cos: Array<F32>) -> An & Array<F32>:
191  match st:
192    case An{x, +head, out}:
193      an.done(((head + 32 : U32) .&. 511 : U32), out,
194        an.sb(an.write(32n, x, head, blk), ((head + 32 : U32) .&. 511 : U32), win, cos))
195
196def an.blk(
197  +s00: F32, +s01: F32, +s02: F32, +s03: F32, +s04: F32, +s05: F32, +s06: F32, +s07: F32,
198  +s08: F32, +s09: F32, +s10: F32, +s11: F32, +s12: F32, +s13: F32, +s14: F32, +s15: F32,
199  +s16: F32, +s17: F32, +s18: F32, +s19: F32, +s20: F32, +s21: F32, +s22: F32, +s23: F32,
200  +s24: F32, +s25: F32, +s26: F32, +s27: F32, +s28: F32, +s29: F32, +s30: F32, +s31: F32
201) -> List<&2, F32>:
202  [s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15,
203   s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31]
204
205# the delay line paired with the cosine table, which has one owner
206type Aw is Type:
207  Aw{st: An, cos: Array<F32>}
208
209def aw.of(got: An & Array<F32>) -> Aw:
210  (st, cos) = got
211  Aw{st, cos}
212
213def an.go(xs: List<&2, F32>, got: Aw, +win: List<&2, F32>) -> An & Array<F32>:
214  match xs got:
215    case +s00 <> +s01 <> +s02 <> +s03 <> +s04 <> +s05 <> +s06 <> +s07 <> +s08 <> +s09 <> +s10
216      <> +s11 <> +s12 <> +s13 <> +s14 <> +s15 <> +s16 <> +s17 <> +s18 <> +s19 <> +s20 <> +s21
217      <> +s22 <> +s23 <> +s24 <> +s25 <> +s26 <> +s27 <> +s28 <> +s29 <> +s30 <> +s31 <> rest Aw{st, cos}:
218      an.go(rest, aw.of(an.push(st, an.blk(s00, s01, s02, s03, s04, s05, s06, s07, s08, s09,
219        s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26,
220        s27, s28, s29, s30, s31), win, cos)), win)
221    case _ Aw{st, cos}:
222      (st, cos)
223
224def an.walk(xs: List<&2, F32>, st: An, +win: List<&2, F32>, cos: Array<F32>) -> An & Array<F32>:
225  an.go(xs, Aw{st, cos}, win)
226
227# 2^9 slots: 512-sample analysis delay, zero-filled, head at the oldest sample.
228def an.zero() -> An:
229  An{Array.new(F32, 9n, 0.0), 0, []}
230
231# subband frames, newest block first. each block is 32 bands.
232def f.revs(xs: List<&2, List<&2, F32>>) -> List<&2, List<&2, F32>>:
233  List.reverse(&2, List<&2, F32>, xs)
234
235def an.out(st: An) -> List<&2, List<&2, F32>>:
236  match st:
237    case An{_x, _head, out}:
238      f.revs(out)
239
240def cos.put(xs: List<&2, F32>, a: Array<F32>, +ii: U32) -> Array<F32>:
241  match xs:
242    case Nil{}:
243      a
244    case +hd <> tl:
245      cos.put(tl, Array.set(F32, a, ii, hd), (ii + 1 : U32))
246
247# 2^11 slots: tab.cos is 2048 coefficients, filled in list order.
248def cos.of() -> Array<F32>:
249  cos.put(f.of(Tab.tab.cos()), Array.new(F32, 11n, 0.0), 0)
250
251def an.fin(got: An & Array<F32>) -> List<&2, List<&2, F32>>:
252  (st, _cos) = got
253  an.out(st)
254
255def an.run(xs: List<&2, F32>) -> List<&2, List<&2, F32>>:
256  an.fin(an.walk(xs, an.zero(), f.of(Tab.tab.win()), cos.of()))
257
258# ldexp_q2 residual: mantissa and the exponent still to apply
259type Ld is Data:
260  Ld{yy: F32, ee: U32}
261
262def ex.of(+ee: U32) -> F32:
263  match ee:
264    case 0:
265      f32.bits(813694976)
266    case 1:
267      f32.bits(811025661)
268    case 2:
269      f32.bits(808781043)
270    case _:
271      f32.bits(806893552)
272
273def ld.scale(+ee: U32) -> F32:
274  U32.to_f32(((1073741824 >> U32.to_nat((ee >> 2n : U32)) : U32)))
275
276def ld.once(+yy: F32, +ee: U32) -> F32:
277  ((yy * ex.of((ee .&. 3 : U32)) : F32) * ld.scale(ee) : F32)
278
279def ld.minp(small: Bool, +ee: U32) -> U32:
280  match small:
281    case True{}:
282      ee
283    case False{}:
284      120
285
286def ld.cut(+yy: F32, +ee: U32, +cut: U32) -> Ld:
287  Ld{ld.once(yy, cut), (ee - cut : U32)}
288
289def ld.step(st: Ld) -> Ld:
290  match st:
291    case Ld{yy, 0}:
292      Ld{yy, 0}
293    case Ld{yy, +ee}:
294      ld.cut(yy, ee, ld.minp(U32.is_le(ee, 120), ee))
295
296def ld.go(hop: Nat, st: Ld) -> Ld:
297  match hop:
298    case 0n:
299      st
300    case 1n+p:
301      ld.go(p, ld.step(st))
302
303def ld.y(st: Ld) -> F32:
304  match st:
305    case Ld{yy, _ee}:
306      yy
307
308# minimp3 dequant gain for a global_gain. ix = round((|xr| / gain) ^ 0.75).
309def gain.of(+gg: U32) -> F32:
310  ld.y(ld.go(8n, Ld{2048.0, (258 - gg : U32)}))
311
312def q.cp(ok: Bool, +nn: U32) -> U32:
313  match ok:
314    case True{}:
315      nn
316    case False{}:
317      8206
318
319def q.clip(+nn: U32) -> U32:
320  q.cp(U32.is_le(nn, 8206), nn)
321
322def q.mag(+xr: F32, +gain: F32) -> U32:
323  q.clip(F32.to_u32(F32.round(F32.pow((F32.abs(xr) / gain : F32), 0.75))))
324
325def q.sign(neg: Bool, +mag: U32) -> U32:
326  match neg:
327    case False{}:
328      mag
329    case True{}:
330      (0 - mag : U32)
331
332def q.one(+xr: F32, +gain: F32) -> U32:
333  q.sign(F32.is_lt(xr, 0.0), q.mag(xr, gain))
334
335def q.all(xs: List<&2, F32>, +gain: F32) -> List<&2, U32>:
336  match xs:
337    case Nil{}:
338      []
339    case +hd <> tl:
340      q.one(hd, gain) <> q.all(tl, gain)
341
342def i.neg(+vv: U32) -> Bool:
343  U32.is_ne((vv .&. 2147483648 : U32), 0)
344
345def i.ab(neg: Bool, +vv: U32) -> U32:
346  match neg:
347    case False{}:
348      vv
349    case True{}:
350      (0 - vv : U32)
351
352def i.abs(+vv: U32) -> U32:
353  i.ab(i.neg(vv), vv)
354
355def scf.row(+hz: U32) -> U32:
356  match hz:
357    case 48000:
358      1
359    case 32000:
360      2
361    case _:
362      0
363
364def scf.at(+hz: U32, +band: U32) -> U32:
365  u.nth(Tab.tab.scf(), ((scf.row(hz) * 22 : U32) + band : U32))
366
367def nz.n(hop: Nat, xs: List<&2, U32>) -> Bool:
368  match hop xs:
369    case 0n _:
370      False{}
371    case _ Nil{}:
372      False{}
373    case 1n+p 0 <> t:
374      nz.n(p, t)
375    case _ _:
376      True{}
377
378def drop.u(hop: Nat, xs: List<&2, U32>) -> List<&2, U32>:
379  match hop xs:
380    case 0n ys:
381      ys
382    case _ Nil{}:
383      []
384    case 1n+p _hd <> tl:
385      drop.u(p, tl)
386
387def take.u(hop: Nat, xs: List<&2, U32>, acc: List<&2, U32>) -> List<&2, U32>:
388  match hop xs:
389    case 0n _:
390      List.reverse(&2, U32, acc)
391    case _ Nil{}:
392      List.reverse(&2, U32, acc)
393    case 1n+p +hd <> tl:
394      take.u(p, tl, hd <> acc)
395
396# big_values scan across the 22 long scalefactor bands
397type Bv is Data:
398  Bv{ix: List<&2, U32>, last: U32, acc: U32}
399
400def bv.put(ix: List<&2, U32>, +last: U32, +acc: U32, hit: Bool) -> Bv:
401  match hit:
402    case True{}:
403      Bv{ix, acc, acc}
404    case False{}:
405      Bv{ix, last, acc}
406
407def bv.got(ix: List<&2, U32>, +last: U32, +acc: U32, +width: U32, hit: Bool) -> Bv:
408  bv.put(drop.u(U32.to_nat(width), ix), last, (acc + U32.div(width, 2) : U32), hit)
409
410def bv.band(+ix: List<&2, U32>, +last: U32, +acc: U32, +width: U32) -> Bv:
411  bv.got(ix, last, acc, width, nz.n(U32.to_nat(width), ix))
412
413def bv.at(st: Bv, +hz: U32, +band: U32) -> Bv:
414  match st:
415    case Bv{+ix, last, +acc}:
416      bv.band(ix, last, acc, scf.at(hz, band))
417
418def bv.go(hop: Nat, st: Bv, +hz: U32, +band: U32) -> Bv:
419  match hop:
420    case 0n:
421      st
422    case 1n+p:
423      bv.go(p, bv.at(st, hz, band), hz, (band + 1 : U32))
424
425def bv.last(st: Bv) -> U32:
426  match st:
427    case Bv{_ix, last, _acc}:
428      last
429
430def bv.of(ix: List<&2, U32>, +hz: U32) -> U32:
431  bv.last(bv.go(22n, Bv{ix, 0, 0}, hz, 0))
432
433# Huffman bits for one granule, newest bit first, running length, and whether the table fit
434type Hp is Data:
435  Hp{bits: List<&2, U32>, n: U32, ok: U32}
436
437def hp.bit(hp: Hp, +bit: U32) -> Hp:
438  match hp:
439    case Hp{_bs, _n, 0}:
440      Hp{[], 0, 0}
441    case Hp{bs, +n, _ok}:
442      Hp{bit <> bs, (n + 1 : U32), 1}
443
444def hp.field(hop: Nat, hp: Hp, +code: U32, +left: U32) -> Hp:
445  match hop:
446    case 0n:
447      hp
448    case 1n+p:
449      hp.field(p, hp.bit(hp, ((code >> U32.to_nat((left - 1 : U32)) : U32) .&. 1 : U32)), code,
450        (left - 1 : U32))
451
452def lim.p(z: Bool, +lin: U32) -> U32:
453  match z:
454    case True{}:
455      15
456    case False{}:
457      (15 + ((1 << U32.to_nat(lin) : U32)) : U32)
458
459def lim.of(+lin: U32) -> U32:
460  lim.p(U32.is_eq(lin, 0), lin)
461
462def ca.p(big: Bool, +aa: U32) -> U32:
463  match big:
464    case True{}:
465      15
466    case False{}:
467      aa
468
469def ca.of(+lin: U32, +aa: U32) -> U32:
470  ca.p(U32.is_ne(lin, 0) && U32.is_ge(aa, 15), aa)
471
472def hp.sgn(neg: Bool) -> U32:
473  match neg:
474    case True{}:
475      1
476    case False{}:
477      0
478
479def hp.sp(z: Bool, hp: Hp, +vv: U32) -> Hp:
480  match z:
481    case True{}:
482      hp
483    case False{}:
484      hp.bit(hp, hp.sgn(i.neg(vv)))
485
486def hp.sign(hp: Hp, +vv: U32, +aa: U32) -> Hp:
487  hp.sp(U32.is_eq(aa, 0), hp, vv)
488
489def hp.lp(z: Bool, hp: Hp, +lin: U32, +extra: U32) -> Hp:
490  match z:
491    case True{}:
492      hp.field(U32.to_nat(lin), hp, extra, lin)
493    case False{}:
494      hp
495
496def hp.lin(hp: Hp, +lin: U32, +aa: U32) -> Hp:
497  hp.lp(U32.is_ne(lin, 0) && U32.is_ge(aa, 15), hp, lin, (aa - 15 : U32))
498
499def hp.over(aa: U32, bb: U32, +lin: U32) -> Bool:
500  U32.is_ge(aa, lim.of(lin)) || U32.is_ge(bb, lim.of(lin))
501
502def hp.bad(z: Bool, hp: Hp) -> Hp:
503  match z:
504    case True{}:
505      Hp{[], 0, 0}
506    case False{}:
507      hp
508
509# a Huffman word handed back beside the Array.get just read
510type Wd is Type:
511  Wd{tab: Array<U32>, w: U32}
512
513def wd.of(got: Array<U32> & U32) -> Wd:
514  (tab, w) = got
515  Wd{tab, w}
516
517# tab.code is 8192 words. Each pair reads that table with Array.get.
518def word.of(codes: Array<U32>, +tab: U32, +ca: U32, +cb: U32) -> Array<U32> & U32:
519  Array.get(U32, codes, (((tab * 256 : U32) + (ca * 16 : U32) : U32) + cb : U32))
520
521def hp.use(z: Bool, hp: Hp, +w: U32, +av: U32, +bv: U32, +aa: U32, +bb: U32, +lin: U32) -> Hp:
522  match z:
523    case True{}:
524      Hp{[], 0, 0}
525    case False{}:
526      hp.sign(hp.lin(hp.sign(hp.lin(hp.field(U32.to_nat((w >> 16n : U32)), hp, (w .&. 65535 : U32),
527        (w >> 16n : U32)), lin, aa), av, aa), lin, bb), bv, bb)
528
529def hp.word(hp: Hp, +av: U32, +bv: U32, +aa: U32, +bb: U32, +lin: U32, +w: U32) -> Hp:
530  hp.bad(hp.over(aa, bb, lin), hp.use(U32.is_eq((w >> 16n : U32), 0), hp, w, av, bv, aa, bb, lin))
531
532def hp.from(
533  got: Wd, hp: Hp, +av: U32, +bv: U32, +aa: U32, +bb: U32, +lin: U32
534) -> Array<U32> & Hp:
535  match got:
536    case Wd{tab, +w}:
537      (tab, hp.word(hp, av, bv, aa, bb, lin, w))
538
539def hp.ready(
540  hp: Hp, +tab: U32, +av: U32, +bv: U32, +aa: U32, +bb: U32, +lin: U32, codes: Array<U32>
541) -> Array<U32> & Hp:
542  hp.from(wd.of(word.of(codes, tab, ca.of(lin, aa), ca.of(lin, bb))), hp, av, bv, aa, bb, lin)
543
544def hp.pair(
545  hp: Hp, +tab: U32, +av: U32, +bv: U32, codes: Array<U32>, +lins: List<&2, U32>
546) -> Array<U32> & Hp:
547  hp.ready(hp, tab, av, bv, i.abs(av), i.abs(bv), u.nth(lins, tab), codes)
548
549# the code table beside the bits just produced for one pair
550type Hs is Type:
551  Hs{tab: Array<U32>, hp: Hp}
552
553def hs.of(got: Array<U32> & Hp) -> Hs:
554  (tab, hp) = got
555  Hs{tab, hp}
556
557def hp.pairs(
558  xs: List<&2, U32>, got: Hs, +tab: U32, +lins: List<&2, U32>
559) -> Array<U32> & Hp:
560  match xs got:
561    case Nil{} Hs{codes, hp}:
562      (codes, hp)
563    case +aa <> +bb <> tl Hs{codes, hp}:
564      hp.pairs(tl, hs.of(hp.pair(hp, tab, aa, bb, codes, lins)), tab, lins)
565    case _ Hs{codes, _hp}:
566      (codes, Hp{[], 0, 0})
567
568def hp.cands() -> List<&2, U32>:
569  [15, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
570
571# shortest Huffman table that encoded the granule
572type Best is Data:
573  Best{tab: U32, nn: U32, bits: List<&2, U32>, ok: U32}
574
575def best.or(a: Bool, b: Bool) -> Bool:
576  match a:
577    case True{}:
578      True{}
579    case False{}:
580      b
581
582def best.and(a: Bool, b: Bool) -> Bool:
583  match a:
584    case False{}:
585      False{}
586    case True{}:
587      b
588
589def best.better(+bok: U32, +bn: U32, +ok: U32, +nn: U32) -> Bool:
590  best.and(U32.is_eq(ok, 1), best.or(U32.is_eq(bok, 0), U32.is_lt(nn, bn)))
591
592def best.keep(
593  take: Bool, +tab: U32, +nn: U32, bits: List<&2, U32>, +bt: U32, +bn: U32,
594  bb: List<&2, U32>, +bok: U32
595) -> Best:
596  match take:
597    case True{}:
598      Best{tab, nn, bits, 1}
599    case False{}:
600      Best{bt, bn, bb, bok}
601
602def best.from(b: Best, +tab: U32, +ok: U32, +nn: U32, bits: List<&2, U32>) -> Best:
603  match b:
604    case Best{+bt, +bn, bb, +bok}:
605      best.keep(best.better(bok, bn, ok, nn), tab, nn, bits, bt, bn, bb, bok)
606
607def best.got(b: Best, +tab: U32, hp: Hp) -> Best:
608  match hp:
609    case Hp{+bits, +n, ok}:
610      best.from(b, tab, ok, n, bits)
611
612def best.pull(b: Best, +tab: U32, got: Hs) -> Array<U32> & Best:
613  match got:
614    case Hs{codes, hp}:
615      (codes, best.got(b, tab, hp))
616
617def best.one(
618  b: Best, +tab: U32, ix: List<&2, U32>, codes: Array<U32>, +lins: List<&2, U32>
619) -> Array<U32> & Best:
620  best.pull(b, tab, hs.of(hp.pairs(ix, Hs{codes, Hp{[], 0, 1}}, tab, lins)))
621
622def best.step(
623  b: Best, +tab: U32, +ix: List<&2, U32>, codes: Array<U32>, +lins: List<&2, U32>
624) -> Array<U32> & Best:
625  best.one(b, tab, ix, codes, lins)
626
627# the code table beside the shortest table so far
628type Bs is Type:
629  Bs{tab: Array<U32>, best: Best}
630
631def bs.of(got: Array<U32> & Best) -> Bs:
632  (tab, best) = got
633  Bs{tab, best}
634
635def best.go(
636  cs: List<&2, U32>, +ix: List<&2, U32>, got: Bs, +lins: List<&2, U32>
637) -> Array<U32> & Best:
638  match cs got:
639    case Nil{} Bs{codes, won}:
640      (codes, won)
641    case +hd <> tl Bs{codes, won}:
642      best.go(tl, ix, bs.of(best.step(won, hd, ix, codes, lins)), lins)
643
644def code.put(xs: List<&2, U32>, a: Array<U32>, +ii: U32) -> Array<U32>:
645  match xs:
646    case Nil{}:
647      a
648    case +hd <> tl:
649      code.put(tl, Array.set(U32, a, ii, hd), (ii + 1 : U32))
650
651# 2^13 slots: tab.code is 8192 words, filled in list order.
652def code.of() -> Array<U32>:
653  code.put(Tab.tab.code(), Array.new(U32, 13n, 0), 0)
654
655def best.fin(got: Bs) -> Best:
656  match got:
657    case Bs{_tab, best}:
658      best
659
660def best.of(ix: List<&2, U32>) -> Best:
661  best.fin(bs.of(best.go(hp.cands(), ix, Bs{code.of(), Best{0, 0, [], 0}}, Tab.tab.lin())))
662
663def ix.p(z: Bool, +mm: U32, +aa: U32) -> U32:
664  match z:
665    case True{}:
666      aa
667    case False{}:
668      mm
669
670def ix.up(+mm: U32, +aa: U32) -> U32:
671  ix.p(U32.is_lt(mm, aa), mm, aa)
672
673def ix.max(xs: List<&2, U32>, +mm: U32) -> U32:
674  match xs:
675    case Nil{}:
676      mm
677    case +hd <> tl:
678      ix.max(tl, ix.up(mm, i.abs(hd)))
679
680# binary search for the finest global_gain that fits the bit budget
681type Sr is Data:
682  Sr{lo: U32, hi: U32, gg: U32, tab: U32, bits: List<&2, U32>, ok: U32}
683
684def sr.g1(z: Bool, +mx: U32) -> Bool:
685  match z:
686    case False{}:
687      False{}
688    case True{}:
689      U32.is_lt(mx, 8000)
690
691def sr.good(+bk: U32, +nn: U32, +bud: U32, +mx: U32) -> Bool:
692  sr.g1(U32.is_eq(bk, 1) && U32.is_le(nn, bud), mx)
693
694def sr.fit(
695  okb: Bool, +lo: U32, +hi: U32, +mid: U32, +tt: U32, bits: List<&2, U32>, +ogg: U32, +ot: U32,
696  obits: List<&2, U32>, +ook: U32
697) -> Sr:
698  match okb:
699    case True{}:
700      Sr{lo, (mid - 1 : U32), mid, tt, bits, 1}
701    case False{}:
702      Sr{(mid + 1 : U32), hi, ogg, ot, obits, ook}
703
704def sr.best(
705  b: Best, +mx: U32, +bud: U32, +lo: U32, +hi: U32, +mid: U32, +ogg: U32, +ot: U32,
706  obits: List<&2, U32>, +ook: U32
707) -> Sr:
708  match b:
709    case Best{tt, nn, bb, bk}:
710      sr.fit(sr.good(bk, nn, bud, mx), lo, hi, mid, tt, bb, ogg, ot, obits, ook)
711
712def sr.zero(
713  z: Bool, +ix: List<&2, U32>, +mx: U32, +big: U32, +bud: U32, +lo: U32, +hi: U32, +mid: U32,
714  +ogg: U32, +ot: U32, obits: List<&2, U32>, +ook: U32
715) -> Sr:
716  match z:
717    case True{}:
718      sr.fit(True{}, lo, hi, mid, 0, [], ogg, ot, obits, ook)
719    case False{}:
720      sr.best(best.of(take.u(U32.to_nat((big * 2 : U32)), ix, [])), mx, bud, lo, hi, mid, ogg, ot,
721        obits, ook)
722
723def sr.ix(
724  +ix: List<&2, U32>, +hz: U32, +bud: U32, +lo: U32, +hi: U32, +mid: U32, +ogg: U32, +ot: U32,
725  obits: List<&2, U32>, +ook: U32
726) -> Sr:
727  sr.zero(U32.is_eq(bv.of(ix, hz), 0), ix, ix.max(ix, 0), bv.of(ix, hz), bud, lo, hi, mid, ogg, ot,
728    obits, ook)
729
730def sr.try(
731  +spec: List<&2, F32>, +hz: U32, +bud: U32, +lo: U32, +hi: U32, +mid: U32, +ogg: U32, +ot: U32,
732  obits: List<&2, U32>, +ook: U32
733) -> Sr:
734  sr.ix(q.all(spec, gain.of(mid)), hz, bud, lo, hi, mid, ogg, ot, obits, ook)
735
736def sr.live(
737  go: Bool, +spec: List<&2, F32>, +hz: U32, +bud: U32, +lo: U32, +hi: U32, +gg: U32, +tab: U32,
738  bits: List<&2, U32>, +ok: U32
739) -> Sr:
740  match go:
741    case False{}:
742      Sr{lo, hi, gg, tab, bits, ok}
743    case True{}:
744      sr.try(spec, hz, bud, lo, hi, U32.div((lo + hi : U32), 2), gg, tab, bits, ok)
745
746def sr.step(spec: List<&2, F32>, +hz: U32, +bud: U32, st: Sr) -> Sr:
747  match st:
748    case Sr{+lo, +hi, +gg, +tab, bits, +ok}:
749      sr.live(U32.is_le(lo, hi), spec, hz, bud, lo, hi, gg, tab, bits, ok)
750
751def sr.go(hop: Nat, +spec: List<&2, F32>, +hz: U32, +bud: U32, st: Sr) -> Sr:
752  match hop:
753    case 0n:
754      st
755    case 1n+p:
756      sr.go(p, spec, hz, bud, sr.step(spec, hz, bud, st))
757
758def sr.run(spec: List<&2, F32>, +hz: U32, +bud: U32) -> Sr:
759  sr.go(8n, spec, hz, bud, Sr{0, 255, 0, 0, [], 0})
760
761def pk.p(z: Bool, +mm: F32, +aa: F32) -> F32:
762  match z:
763    case True{}:
764      aa
765    case False{}:
766      mm
767
768def pk.up(+mm: F32, +aa: F32) -> F32:
769  pk.p(F32.is_lt(mm, aa), mm, aa)
770
771def pk.go(xs: List<&2, F32>, +mm: F32) -> F32:
772  match xs:
773    case Nil{}:
774      mm
775    case +hd <> tl:
776      pk.go(tl, pk.up(mm, F32.abs(hd)))
777
778def dz.one(z: Bool, +vv: F32) -> F32:
779  match z:
780    case True{}:
781      0.0
782    case False{}:
783      vv
784
785def dz.apply(xs: List<&2, F32>, +thr: F32) -> List<&2, F32>:
786  match xs:
787    case Nil{}:
788      []
789    case +hd <> tl:
790      dz.one(F32.is_lt(F32.abs(hd), thr), hd) <> dz.apply(tl, thr)
791
792def dz.on(
793  done: Bool, st: Sr, +spec: List<&2, F32>, +pk: F32, +thr: U32, +hz: U32, +bud: U32
794) -> Sr:
795  match done:
796    case True{}:
797      st
798    case False{}:
799      sr.run(dz.apply(spec, (pk * f32.bits(thr) : F32)), hz, bud)
800
801def dz.try(st: Sr, +spec: List<&2, F32>, +pk: F32, +thr: U32, +hz: U32, +bud: U32) -> Sr:
802  match st:
803    case Sr{+lo, +hi, +gg, +tab, bits, +ok}:
804      dz.on(U32.is_eq(ok, 1), Sr{lo, hi, gg, tab, bits, ok}, spec, pk, thr, hz, bud)
805
806def dz.go(
807  thrs: List<&2, U32>, +spec: List<&2, F32>, +pk: F32, +hz: U32, +bud: U32, st: Sr
808) -> Sr:
809  match thrs:
810    case Nil{}:
811      st
812    case +hd <> tl:
813      dz.go(tl, spec, pk, hz, bud, dz.try(st, spec, pk, hd, hz, bud))
814
815def dz.thrs() -> List<&2, U32>:
816  [953267991, 981668463, 994352038, 1008981770, 1022739087, 1036831949, 1045220557, 1053609165]
817
818def dz.maybe(tiny: Bool, +spec: List<&2, F32>, +pk: F32, +hz: U32, +bud: U32) -> Sr:
819  match tiny:
820    case True{}:
821      Sr{0, 0, 0, 0, [], 1}
822    case False{}:
823      dz.go(dz.thrs(), spec, pk, hz, bud, Sr{0, 255, 0, 0, [], 0})
824
825def dz.run(+spec: List<&2, F32>, +hz: U32, +bud: U32) -> Sr:
826  dz.maybe(F32.is_lt(pk.go(spec, 0.0), f32.bits(730643660)), spec, pk.go(spec, 0.0), hz, bud)
827
828# one quantized granule: part2_3_length, big_values, global_gain, table, bits
829type Gr is Data:
830  Gr{part: U32, big: U32, gain: U32, tab: U32, bits: List<&2, U32>}
831
832# reversed bit list and its length
833type Rv is Data:
834  Rv{xs: List<&2, U32>, n: U32}
835
836def rv.go(xs: List<&2, U32>, acc: List<&2, U32>, +n: U32) -> Rv:
837  match xs:
838    case Nil{}:
839      Rv{acc, n}
840    case +hd <> tl:
841      rv.go(tl, hd <> acc, (n + 1 : U32))
842
843def gr.from(r: Rv, +gg: U32, +tab: U32, +big: U32) -> Gr:
844  match r:
845    case Rv{xs, +n}:
846      Gr{n, big, gg, tab, xs}
847
848def gr.u(z: Bool, +gg: U32, +tab: U32, bits: List<&2, U32>, +big: U32) -> Gr:
849  match z:
850    case False{}:
851      Gr{0, 0, 0, 0, []}
852    case True{}:
853      gr.from(rv.go(bits, [], 0), gg, tab, big)
854
855def gr.use(z: Bool, +gg: U32, +tab: U32, bits: List<&2, U32>, ix: List<&2, U32>, +hz: U32) -> Gr:
856  match z:
857    case False{}:
858      Gr{0, 0, 0, 0, []}
859    case True{}:
860      gr.u(True{}, gg, tab, bits, bv.of(ix, hz))
861
862def gr.pack(st: Sr, +spec: List<&2, F32>, +hz: U32) -> Gr:
863  match st:
864    case Sr{_lo, _hi, +gg, +tab, bits, ok}:
865      gr.use(U32.is_eq(ok, 1), gg, tab, bits, q.all(spec, gain.of(gg)), hz)
866
867def gr.of(+spec: List<&2, F32>, +hz: U32, +bud: U32) -> Gr:
868  gr.pack(dz.run(spec, hz, bud), spec, hz)
869
870# a matrix coefficient handed back beside the Array.get just read
871type Bf is Type:
872  Bf{tab: Array<F32>, co: F32}
873
874def bf.of(got: Array<F32> & F32) -> Bf:
875  (tab, co) = got
876  Bf{tab, co}
877
878def bt.go(tl: List<&2, F32>, got: Bf, +base: U32, +hd: F32, acc: F32) -> Array<F32> & F32:
879  match tl got:
880    case Nil{} Bf{tab, co}:
881      (tab, (acc + (co * hd : F32) : F32))
882    case +hd2 <> rest Bf{tab, co}:
883      bt.go(rest, bf.of(Array.get(F32, tab, (base + 1 : U32))), (base + 1 : U32), hd2,
884        (acc + (co * hd : F32) : F32))
885
886# tab.bt is 648 F32s. Each tap reads that table with Array.get.
887def bt.dot(vec: List<&2, F32>, tab: Array<F32>, +base: U32, acc: F32) -> Array<F32> & F32:
888  match vec:
889    case Nil{}:
890      (tab, acc)
891    case +hd <> tl:
892      bt.go(tl, bf.of(Array.get(F32, tab, base)), base, hd, acc)
893
894def col.b(
895  hop: Nat, xs: List<&2, List<&2, F32>>, +band: U32, acc: List<&2, F32>
896) -> List<&2, F32>:
897  match hop xs:
898    case 0n _:
899      f.rev(acc)
900    case _ Nil{}:
901      f.rev(acc)
902    case 1n+p +blk <> tl:
903      col.b(p, tl, band, f.nth(blk, band) <> acc)
904
905def band.step(
906  hop: Nat, +vec: List<&2, F32>, got: Bf, +kk: U32, acc: List<&2, F32>
907) -> Array<F32> & List<&2, F32>:
908  match hop got:
909    case 0n Bf{tab, co}:
910      (tab, f.rev((co <> acc)))
911    case 1n+p Bf{tab, co}:
912      band.step(p, vec, bf.of(bt.dot(vec, tab, ((kk + 1 : U32) * 36 : U32), 0.0)), (kk + 1 : U32),
913        (co <> acc))
914
915def band.k(
916  hop: Nat, +vec: List<&2, F32>, tab: Array<F32>, +kk: U32, acc: List<&2, F32>
917) -> Array<F32> & List<&2, F32>:
918  match hop:
919    case 0n:
920      (tab, f.rev(acc))
921    case 1n+p:
922      band.step(p, vec, bf.of(bt.dot(vec, tab, (kk * 36 : U32), 0.0)), kk, acc)
923
924def band.row(
925  +aa: List<&2, List<&2, F32>>, +cc: List<&2, List<&2, F32>>, tab: Array<F32>, +band: U32
926) -> Array<F32> & List<&2, F32>:
927  band.k(18n, List.append(&2, F32, col.b(18n, aa, band, []), col.b(18n, cc, band, [])), tab, 0, [])
928
929def flat.bands(xs: List<&2, List<&2, F32>>) -> List<&2, F32>:
930  match xs:
931    case Nil{}:
932      []
933    case +hd <> tl:
934      List.append(&2, F32, hd, flat.bands(tl))
935
936# one MDCT row handed back beside the matrix
937type Br is Type:
938  Br{tab: Array<F32>, row: List<&2, F32>}
939
940def br.of(got: Array<F32> & List<&2, F32>) -> Br:
941  (tab, row) = got
942  Br{tab, row}
943
944def spec.step(
945  hop: Nat, +aa: List<&2, List<&2, F32>>, +cc: List<&2, List<&2, F32>>, got: Br, +band: U32,
946  acc: List<&2, List<&2, F32>>
947) -> Array<F32> & List<&2, F32>:
948  match hop got:
949    case 0n Br{tab, row}:
950      (tab, flat.bands(f.revs(row <> acc)))
951    case 1n+p Br{tab, row}:
952      spec.step(p, aa, cc, br.of(band.row(aa, cc, tab, (band + 1 : U32))), (band + 1 : U32),
953        (row <> acc))
954
955def spec.bands(
956  hop: Nat, +aa: List<&2, List<&2, F32>>, +cc: List<&2, List<&2, F32>>, tab: Array<F32>,
957  +band: U32, acc: List<&2, List<&2, F32>>
958) -> Array<F32> & List<&2, F32>:
959  match hop:
960    case 0n:
961      (tab, flat.bands(f.revs(acc)))
962    case 1n+p:
963      spec.step(p, aa, cc, br.of(band.row(aa, cc, tab, band)), band, acc)
964
965def drop.b(hop: Nat, xs: List<&2, List<&2, F32>>) -> List<&2, List<&2, F32>>:
966  match hop xs:
967    case 0n ys:
968      ys
969    case _ Nil{}:
970      []
971    case 1n+p _hd <> tl:
972      drop.b(p, tl)
973
974def take.b(
975  hop: Nat, xs: List<&2, List<&2, F32>>, acc: List<&2, List<&2, F32>>
976) -> List<&2, List<&2, F32>>:
977  match hop xs:
978    case 0n _:
979      f.revs(acc)
980    case _ Nil{}:
981      f.revs(acc)
982    case 1n+p +hd <> tl:
983      take.b(p, tl, hd <> acc)
984
985def spec.one(+blocks: List<&2, List<&2, F32>>, tab: Array<F32>) -> Array<F32> & List<&2, F32>:
986  spec.bands(32n, take.b(18n, blocks, []), take.b(18n, drop.b(18n, blocks), []), tab, 0, [])
987
988# 576 MDCT bins. Each butterfly reads and writes two of them; a list walks from the head.
989type Sa is Type:
990  Sa{acc: Array<F32>, cur: F32}
991
992def sa.of(got: Array<F32> & F32) -> Sa:
993  (acc, cur) = got
994  Sa{acc, cur}
995
996def al.fill(xs: List<&2, F32>, a: Array<F32>, +ii: U32) -> Array<F32>:
997  match xs:
998    case Nil{}:
999      a
1000    case +hd <> tl:
1001      al.fill(tl, Array.set(F32, a, ii, hd), (ii + 1 : U32))
1002
1003# 2^10 slots: one granule is 576 coefficients, filled in list order.
1004def al.arr(xs: List<&2, F32>) -> Array<F32>:
1005  al.fill(xs, Array.new(F32, 10n, 0.0), 0)
1006
1007def al.pull(hop: Nat, got: Sa, +ii: U32, acc: List<&2, F32>) -> List<&2, F32>:
1008  match hop got:
1009    case 0n Sa{_acc, +cur}:
1010      f.rev(cur <> acc)
1011    case 1n+p Sa{tab, +cur}:
1012      al.pull(p, sa.of(Array.get(F32, tab, (ii + 1 : U32))), (ii + 1 : U32), (cur <> acc))
1013
1014def al.list(acc: Array<F32>) -> List<&2, F32>:
1015  al.pull(575n, sa.of(Array.get(F32, acc, 0)), 0, [])
1016
1017def al.write(
1018  acc: Array<F32>, +up: F32, +dp: F32, +c0: F32, +c1: F32, +hi: U32, +lo: U32
1019) -> Array<F32>:
1020  Array.set(F32, Array.set(F32, acc, hi, ((c0 * up : F32) + (c1 * dp : F32) : F32)), lo,
1021    ((F32.neg(c1) * up : F32) + (c0 * dp : F32) : F32))
1022
1023def al.use(got: Sa, +dp: F32, +c0: F32, +c1: F32, +hi: U32, +lo: U32) -> Array<F32>:
1024  match got:
1025    case Sa{acc, +up}:
1026      al.write(acc, up, dp, c0, c1, hi, lo)
1027
1028def al.both(got: Sa, +c0: F32, +c1: F32, +hi: U32, +lo: U32) -> Array<F32>:
1029  match got:
1030    case Sa{acc, +dp}:
1031      al.use(sa.of(Array.get(F32, acc, hi)), dp, c0, c1, hi, lo)
1032
1033def al.one(acc: Array<F32>, +aa: List<&2, F32>, +bb: U32, +ii: U32) -> Array<F32>:
1034  al.both(sa.of(Array.get(F32, acc, ((bb * 18 : U32) + (17 - ii : U32) : U32))), f.nth(aa, ii),
1035    f.nth(aa, (ii + 8 : U32)), (((bb + 1 : U32) * 18 : U32) + ii : U32),
1036    ((bb * 18 : U32) + (17 - ii : U32) : U32))
1037
1038def al.i(hop: Nat, acc: Array<F32>, +aa: List<&2, F32>, +bb: U32, +ii: U32) -> Array<F32>:
1039  match hop:
1040    case 0n:
1041      acc
1042    case 1n+p:
1043      al.i(p, al.one(acc, aa, bb, ii), aa, bb, (ii + 1 : U32))
1044
1045def al.band(acc: Array<F32>, +aa: List<&2, F32>, +bb: U32) -> Array<F32>:
1046  al.i(8n, acc, aa, bb, 0)
1047
1048def al.go(hop: Nat, acc: Array<F32>, +aa: List<&2, F32>, +bb: U32) -> Array<F32>:
1049  match hop:
1050    case 0n:
1051      acc
1052    case 1n+p:
1053      al.go(p, al.band(acc, aa, bb), aa, (bb - 1 : U32))
1054
1055def al.fin(acc: Array<F32>) -> List<&2, F32>:
1056  al.list(al.go(31n, acc, f.of(Tab.tab.aa()), 30))
1057
1058def al.run(xs: List<&2, F32>) -> List<&2, F32>:
1059  al.fin(al.arr(xs))
1060
1061def spec.read(got: Br) -> Array<F32> & List<&2, F32>:
1062  match got:
1063    case Br{tab, row}:
1064      (tab, al.run(row))
1065
1066def spec.gran(+blocks: List<&2, List<&2, F32>>, tab: Array<F32>) -> Array<F32> & List<&2, F32>:
1067  spec.read(br.of(spec.one(blocks, tab)))
1068
1069def grans.step(
1070  hop: Nat, +blocks: List<&2, List<&2, F32>>, got: Br, acc: List<&2, List<&2, F32>>
1071) -> Array<F32> & List<&2, List<&2, F32>>:
1072  match hop got:
1073    case 0n Br{tab, row}:
1074      (tab, f.revs(row <> acc))
1075    case 1n+p Br{tab, row}:
1076      grans.step(p, drop.b(18n, blocks), br.of(spec.gran(blocks, tab)), (row <> acc))
1077
1078def grans.go(
1079  hop: Nat, +blocks: List<&2, List<&2, F32>>, tab: Array<F32>, acc: List<&2, List<&2, F32>>
1080) -> Array<F32> & List<&2, List<&2, F32>>:
1081  match hop:
1082    case 0n:
1083      (tab, f.revs(acc))
1084    case 1n+p:
1085      grans.step(p, drop.b(18n, blocks), br.of(spec.gran(blocks, tab)), acc)
1086
1087def grans.np(z: Bool, +nb: U32) -> U32:
1088  match z:
1089    case True{}:
1090      0
1091    case False{}:
1092      (U32.div(nb, 18) - 1 : U32)
1093
1094def grans.n(+nb: U32) -> U32:
1095  grans.np(U32.is_le(nb, 18), nb)
1096
1097def bt.put(xs: List<&2, F32>, a: Array<F32>, +ii: U32) -> Array<F32>:
1098  match xs:
1099    case Nil{}:
1100      a
1101    case +hd <> tl:
1102      bt.put(tl, Array.set(F32, a, ii, hd), (ii + 1 : U32))
1103
1104# 2^10 slots: tab.bt is 648 coefficients, filled in list order.
1105def bt.of() -> Array<F32>:
1106  bt.put(f.of(Tab.tab.bt()), Array.new(F32, 10n, 0.0), 0)
1107
1108def gran.fin(got: Array<F32> & List<&2, List<&2, F32>>) -> List<&2, List<&2, F32>>:
1109  (_tab, xs) = got
1110  xs
1111
1112def gran.all(+blocks: List<&2, List<&2, F32>>) -> List<&2, List<&2, F32>>:
1113  gran.fin(grans.go(U32.to_nat(grans.n(U32.from_nat(List.length(&2, List<&2, F32>, blocks)))), blocks,
1114    bt.of(), []))
1115
1116def flip.samp(z: Bool, +vv: F32) -> F32:
1117  match z:
1118    case True{}:
1119      F32.neg(vv)
1120    case False{}:
1121      vv
1122
1123def flip.go(xs: List<&2, F32>, +ii: U32, acc: List<&2, F32>, +odd: Bool) -> List<&2, F32>:
1124  match xs:
1125    case Nil{}:
1126      f.rev(acc)
1127    case +hd <> tl:
1128      flip.go(tl, (ii + 1 : U32), flip.samp(odd && U32.is_ne((ii .&. 1 : U32), 0), hd) <> acc, odd)
1129
1130def flip.one(blk: List<&2, F32>, odd: Bool) -> List<&2, F32>:
1131  flip.go(blk, 0, [], odd)
1132
1133def flip.all(xs: List<&2, List<&2, F32>>, +ii: U32, acc: List<&2, List<&2, F32>>) -> List<&2, List<&2, F32>>:
1134  match xs:
1135    case Nil{}:
1136      f.revs(acc)
1137    case +hd <> tl:
1138      flip.all(tl, (ii + 1 : U32), flip.one(hd, U32.is_ne((ii .&. 1 : U32), 0)) <> acc)
1139
1140def ch.specs(xs: List<&2, F32>) -> List<&2, List<&2, F32>>:
1141  gran.all(flip.all(an.run(xs), 0, []))
1142
1143# bit packer. completed bytes are newest-first until bw.bytes reverses them.
1144type Bw is Data:
1145  Bw{acc: U32, n: U32, out: List<&2, U32>}
1146
1147def bw.empty() -> Bw:
1148  Bw{0, 0, []}
1149
1150def bw.put(full: Bool, +acc: U32, +n: U32, out: List<&2, U32>) -> Bw:
1151  match full:
1152    case True{}:
1153      Bw{0, 0, (acc .&. 255 : U32) <> out}
1154    case False{}:
1155      Bw{acc, n, out}
1156
1157def bw.bit(st: Bw, +bit: U32) -> Bw:
1158  match st:
1159    case Bw{+acc, +n, out}:
1160      bw.put(U32.is_eq(n, 7), ((acc << 1n : U32) .|. (bit .&. 1 : U32) : U32), (n + 1 : U32), out)
1161
1162def bw.field(hop: Nat, st: Bw, +val: U32) -> Bw:
1163  match hop:
1164    case 0n:
1165      st
1166    case 1n++p:
1167      bw.field(p, bw.bit(st, ((val >> p : U32) .&. 1 : U32)), val)
1168
1169def bw.tail(empty: Bool, +acc: U32, +n: U32, out: List<&2, U32>) -> List<&2, U32>:
1170  match empty:
1171    case True{}:
1172      List.reverse(&2, U32, out)
1173    case False{}:
1174      List.reverse(&2, U32, (((acc << U32.to_nat((8 - n : U32)) : U32) .&. 255 : U32) <> out))
1175
1176def bw.bytes(st: Bw) -> List<&2, U32>:
1177  match st:
1178    case Bw{+acc, +n, out}:
1179      bw.tail(U32.is_eq(n, 0), acc, n, out)
1180
1181def pk.sr(+hz: U32) -> U32:
1182  match hz:
1183    case 48000:
1184      4
1185    case 32000:
1186      8
1187    case _:
1188      0
1189
1190def pk.mode(+ch: U32) -> U32:
1191  match ch:
1192    case 1:
1193      196
1194    case _:
1195      4
1196
1197def pk.hdr(+hz: U32, +ch: U32) -> List<&2, U32>:
1198  [255, 251, (224 .|. pk.sr(hz) : U32), pk.mode(ch)]
1199
1200def pk.fsz(+hz: U32) -> U32:
1201  U32.div(((1152 * 320 : U32) * 125 : U32), hz)
1202
1203def pk.sidebits(+ch: U32) -> U32:
1204  match ch:
1205    case 1:
1206      136
1207    case _:
1208      256
1209
1210def pk.bud(+hz: U32, +ch: U32) -> U32:
1211  (U32.div((((pk.fsz(hz) * 8 : U32) - 32 : U32) - pk.sidebits(ch) : U32), (ch * 2 : U32)) - 8 : U32)
1212
1213def blk.up(+n: U32) -> U32:
1214  U32.div((n + 31 : U32), 32)
1215
1216def blk.q(+b: U32) -> U32:
1217  U32.div((b + 17 : U32), 18)
1218
1219def blk.fix(even: Bool, +q: U32) -> U32:
1220  match even:
1221    case True{}:
1222      ((q + 1 : U32) * 18 : U32)
1223    case False{}:
1224      (q * 18 : U32)
1225
1226def blk.odd(+q: U32) -> U32:
1227  blk.fix(U32.is_eq((q .&. 1 : U32), 0), q)
1228
1229def blk.at(small: Bool, +b: U32) -> U32:
1230  match small:
1231    case True{}:
1232      54
1233    case False{}:
1234      blk.odd(blk.q(b))
1235
1236def blk.n(+n: U32) -> U32:
1237  blk.at(U32.is_lt(blk.up(n), 54), blk.up(n))
1238
1239def enc.need(+n: U32) -> U32:
1240  (blk.n(n) * 32 : U32)
1241
1242def enc.zero(short: Bool, +have: U32, +need: U32) -> U32:
1243  match short:
1244    case True{}:
1245      (need - have : U32)
1246    case False{}:
1247      0
1248
1249def enc.extra(+have: U32, +need: U32) -> U32:
1250  enc.zero(U32.is_le(have, need), have, need)
1251
1252def side.priv(+ch: U32) -> U32:
1253  match ch:
1254    case 1:
1255      5
1256    case _:
1257      3
1258
1259def side.head(st: Bw, +ch: U32) -> Bw:
1260  bw.field(U32.to_nat((ch * 4 : U32)), bw.field(U32.to_nat(side.priv(ch)), bw.field(9n, st, 0), 0), 0)
1261
1262def side.mid(st: Bw, +part: U32, +big: U32, +gain: U32) -> Bw:
1263  bw.field(1n, bw.field(4n, bw.field(8n, bw.field(9n, bw.field(12n, st, part), big), gain), 0), 0)
1264
1265def side.tabs(st: Bw, +tab: U32) -> Bw:
1266  bw.field(3n, bw.field(4n, bw.field(5n, bw.field(5n, bw.field(5n, st, tab), tab), tab), 15), 5)
1267
1268def side.end(st: Bw) -> Bw:
1269  bw.field(1n, bw.field(1n, bw.field(1n, st, 0), 0), 0)
1270
1271def side.gr(st: Bw, g: Gr) -> Bw:
1272  match g:
1273    case Gr{+part, +big, +gain, +tab, _bits}:
1274      side.end(side.tabs(side.mid(st, part, big, gain), tab))
1275
1276def side.grs(gs: List<&2, Gr>, st: Bw) -> Bw:
1277  match gs:
1278    case Nil{}:
1279      st
1280    case +hd <> tl:
1281      side.grs(tl, side.gr(st, hd))
1282
1283def side.bytes(gs: List<&2, Gr>, +ch: U32) -> List<&2, U32>:
1284  bw.bytes(side.grs(gs, side.head(bw.empty(), ch)))
1285
1286def body.bits(xs: List<&2, U32>, st: Bw) -> Bw:
1287  match xs:
1288    case Nil{}:
1289      st
1290    case +hd <> tl:
1291      body.bits(tl, bw.bit(st, hd))
1292
1293def body.one(g: Gr, st: Bw) -> Bw:
1294  match g:
1295    case Gr{_part, _big, _gain, _tab, bits}:
1296      body.bits(bits, st)
1297
1298def body.grs(gs: List<&2, Gr>, st: Bw) -> Bw:
1299  match gs:
1300    case Nil{}:
1301      st
1302    case +hd <> tl:
1303      body.grs(tl, body.one(hd, st))
1304
1305def pk.pad(+xs: List<&2, U32>, +fsz: U32) -> List<&2, U32>:
1306  List.append(&2, U32, xs, List.replicate(U32,
1307    U32.to_nat(enc.extra(U32.from_nat(List.length(&2, U32, xs)), fsz)), 0))
1308
1309def pk.fit(head: List<&2, U32>, body: List<&2, U32>, +fsz: U32) -> List<&2, U32>:
1310  pk.pad(List.append(&2, U32, head, body), fsz)
1311
1312def pk.one(+gs: List<&2, Gr>, +hz: U32, +ch: U32) -> List<&2, U32>:
1313  pk.fit(List.append(&2, U32, pk.hdr(hz, ch), side.bytes(gs, ch)), bw.bytes(body.grs(gs, bw.empty())),
1314    pk.fsz(hz))
1315
1316# one Huffman pair (mag, 0) in the first granule. global_gain stays 0.
1317def pulse.gr(b: Best) -> Gr:
1318  match b:
1319    case Best{+tab, _nn, bits, +ok}:
1320      gr.u(U32.is_eq(ok, 1), 0, tab, bits, 1)
1321
1322def pulse.clamp(small: Bool, +w: U32) -> U32:
1323  match small:
1324    case True{}:
1325      w
1326    case False{}:
1327      15
1328
1329def pulse.mag0(z: Bool, +w: U32) -> U32:
1330  match z:
1331    case True{}:
1332      1
1333    case False{}:
1334      pulse.clamp(U32.is_lt(w, 16), w)
1335
1336def pulse.mag(+w: U32) -> U32:
1337  pulse.mag0(U32.is_eq(w, 0), w)
1338
1339def pulse.frame(+hz: U32, +mag: U32) -> List<&2, U32>:
1340  pk.one([pulse.gr(best.of([mag, 0])), Gr{0, 0, 0, 0, []}], hz, 1)
1341
1342def pk.chan(
1343  specs: List<&2, List<&2, F32>>, +hz: U32, +bud: U32, acc: List<&2, Gr>
1344) -> List<&2, Gr>:
1345  match specs:
1346    case Nil{}:
1347      List.reverse(&2, Gr, acc)
1348    case +hd <> tl:
1349      pk.chan(tl, hz, bud, gr.of(hd, hz, bud) <> acc)
1350
1351def pk.buf(done: Bool, buf: List<&2, Gr>, +g: Gr) -> List<&2, Gr>:
1352  match done:
1353    case True{}:
1354      []
1355    case False{}:
1356      g <> buf
1357
1358def pk.have(done: Bool, +have: U32) -> U32:
1359  match done:
1360    case True{}:
1361      0
1362    case False{}:
1363      (have + 1 : U32)
1364
1365def pk.acc(
1366  done: Bool, buf: List<&2, Gr>, +g: Gr, +hz: U32, +ch: U32, acc: List<&2, List<&2, U32>>
1367) -> List<&2, List<&2, U32>>:
1368  match done:
1369    case True{}:
1370      pk.one(List.reverse(&2, Gr, g <> buf), hz, ch) <> acc
1371    case False{}:
1372      acc
1373
1374def pk.step(
1375  gs: List<&2, Gr>, +buf: List<&2, Gr>, +have: U32, +per: U32, +hz: U32, +ch: U32,
1376  acc: List<&2, List<&2, U32>>
1377) -> List<&2, List<&2, U32>>:
1378  match gs:
1379    case Nil{}:
1380      List.reverse(&2, List<&2, U32>, acc)
1381    case +hd <> tl:
1382      pk.step(tl, pk.buf(U32.is_eq((have + 1 : U32), per), buf, hd),
1383        pk.have(U32.is_eq((have + 1 : U32), per), have), per, hz, ch,
1384        pk.acc(U32.is_eq((have + 1 : U32), per), buf, hd, hz, ch, acc))
1385
1386def pk.zip(ls: List<&2, Gr>, rs: List<&2, Gr>, acc: List<&2, Gr>) -> List<&2, Gr>:
1387  match ls rs:
1388    case +l <> lt +r <> rt:
1389      pk.zip(lt, rt, r <> l <> acc)
1390    case _ _:
1391      List.reverse(&2, Gr, acc)
1392
1393def enc.grow(+xs: List<&2, F32>) -> List<&2, F32>:
1394  List.append(&2, F32, xs, List.replicate(F32, U32.to_nat(enc.extra(
1395    U32.from_nat(List.length(&2, F32, xs)), enc.need(U32.from_nat(List.length(&2, F32, xs))))), 0.0))
1396
1397def enc.chgr(xs: List<&2, F32>, +hz: U32, +bud: U32) -> List<&2, Gr>:
1398  pk.chan(ch.specs(enc.grow(xs)), hz, bud, [])
1399
1400def s16.f(neg: Bool, +w: U32) -> F32:
1401  match neg:
1402    case False{}:
1403      (U32.to_f32((w .&. 65535 : U32)) / 32768.0 : F32)
1404    case True{}:
1405      F32.neg((U32.to_f32((65536 - (w .&. 65535 : U32) : U32)) / 32768.0 : F32))
1406
1407def samp.of(+kind: U32, +w: U32) -> F32:
1408  match kind:
1409    case 1:
1410      s16.f(U32.is_ne((w .&. 32768 : U32), 0), w)
1411    case _:
1412      f32.bits(w)
1413
1414def pcm.go(+kind: U32, xs: List<&2, U32>, acc: List<&2, F32>) -> List<&2, F32>:
1415  match xs:
1416    case Nil{}:
1417      f.rev(acc)
1418    case +hd <> tl:
1419      pcm.go(kind, tl, samp.of(kind, hd) <> acc)
1420
1421# deinterleaved channels, newest sample first until split.go reverses them
1422type Chs is Data:
1423  Chs{l: List<&2, F32>, r: List<&2, F32>}
1424
1425def split.rev(c: Chs) -> Chs:
1426  match c:
1427    case Chs{l, r}:
1428      Chs{f.rev(l), f.rev(r)}
1429
1430def split.on(leftb: Bool, +v: F32, l: List<&2, F32>, r: List<&2, F32>) -> Chs:
1431  match leftb:
1432    case True{}:
1433      Chs{v <> l, r}
1434    case False{}:
1435      Chs{l, v <> r}
1436
1437def split.put(c: Chs, +v: F32, +phase: U32) -> Chs:
1438  match c:
1439    case Chs{l, r}:
1440      split.on(U32.is_eq(phase, 0), v, l, r)
1441
1442def split.flip(z: Bool) -> U32:
1443  match z:
1444    case True{}:
1445      1
1446    case False{}:
1447      0
1448
1449def split.ph(mono: Bool, +phase: U32) -> U32:
1450  match mono:
1451    case True{}:
1452      0
1453    case False{}:
1454      split.flip(U32.is_eq(phase, 0))
1455
1456def split.next(+ch: U32, +phase: U32) -> U32:
1457  split.ph(U32.is_eq(ch, 1), phase)
1458
1459def split.go(xs: List<&2, F32>, +ch: U32, c: Chs, +phase: U32) -> Chs:
1460  match xs:
1461    case Nil{}:
1462      split.rev(c)
1463    case +hd <> tl:
1464      split.go(tl, ch, split.put(c, hd, phase), split.next(ch, phase))
1465
1466def enc.flat(xs: List<&2, List<&2, U32>>) -> List<&2, U32>:
1467  match xs:
1468    case Nil{}:
1469      []
1470    case +hd <> tl:
1471      List.append(&2, U32, hd, enc.flat(tl))
1472
1473def enc.mono(+hz: U32, left: List<&2, F32>) -> List<&2, List<&2, U32>>:
1474  pk.step(enc.chgr(left, hz, pk.bud(hz, 1)), [], 0, 2, hz, 1, [])
1475
1476def enc.stereo(+hz: U32, left: List<&2, F32>, right: List<&2, F32>) -> List<&2, List<&2, U32>>:
1477  pk.step(pk.zip(enc.chgr(left, hz, pk.bud(hz, 2)), enc.chgr(right, hz, pk.bud(hz, 2)), []), [], 0,
1478    4, hz, 2, [])
1479
1480def enc.chs(
1481  mono: Bool, +hz: U32, left: List<&2, F32>, right: List<&2, F32>
1482) -> List<&2, List<&2, U32>>:
1483  match mono:
1484    case True{}:
1485      enc.mono(hz, left)
1486    case False{}:
1487      enc.stereo(hz, left, right)
1488
1489def enc.some(empty: Bool, +xs: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
1490  match empty:
1491    case True{}:
1492      None{}
1493    case False{}:
1494      Some{xs}
1495
1496def enc.packed(+xs: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
1497  enc.some(U32.is_eq(U32.from_nat(List.length(&2, U32, xs)), 0), xs)
1498
1499def enc.out(mono: Bool, +hz: U32, l: List<&2, F32>, r: List<&2, F32>) -> Maybe<&2, List<&2, U32>>:
1500  enc.packed(enc.flat(enc.chs(mono, hz, l, r)))
1501
1502def enc.from(c: Chs, +hz: U32, +ch: U32) -> Maybe<&2, List<&2, U32>>:
1503  match c:
1504    case Chs{l, r}:
1505      enc.out(U32.is_eq(ch, 1), hz, l, r)
1506
1507def enc.kind(+k: U32) -> Bool:
1508  match k:
1509    case 1:
1510      True{}
1511    case 3:
1512      True{}
1513    case _:
1514      False{}
1515
1516def enc.go(+hz: U32, +ch: U32, +kind: U32, frames: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
1517  enc.from(split.go(pcm.go(kind, frames, []), ch, Chs{[], []}, 0), hz, ch)
1518
1519def enc.finish(
1520  ok: Bool, +hz: U32, +ch: U32, +kind: U32, frames: List<&2, U32>
1521) -> Maybe<&2, List<&2, U32>>:
1522  match ok:
1523    case False{}:
1524      None{}
1525    case True{}:
1526      enc.go(hz, ch, kind, frames)
1527
1528def enc.run(
1529  +hz: U32, +ch: U32, +kind: U32, frames: List<&2, U32>
1530) -> Maybe<&2, List<&2, U32>>:
1531  enc.finish(enc.kind(kind), hz, ch, kind, frames)