src/mp3_dec.bend
emerging-ezaudio@0.4.0.0 · 988 lines · 0 definitions
1# MPEG-1 Layer III decoder. Long blocks, no bit reservoir. Layer I and II never reach here.
2import Base
3import emerging-ezaudio@0.4.0.0/src/mp3_tab.bend as Tab
4import emerging-ezaudio@0.4.0.0/src/mp3_enc.bend as Enc
5import emerging-ezaudio@0.4.0.0/src/mp3_syn.bend as Syn
6
7def u.nth(xs: List<&2, U32>, +ii: U32) -> U32:
8 Enc.u.nth(xs, ii)
9
10def f.word(x: F32) -> U32:
11 Enc.f32.word(x)
12
13def se.or(neg: Bool, +w: U32) -> U32:
14 match neg:
15 case True{}:
16 (w .|. 4294901760 : U32)
17 case False{}:
18 w
19
20def se.u16(+w: U32) -> U32:
21 se.or(U32.is_ne((w .&. 32768 : U32), 0), (w .&. 65535 : U32))
22
23def asr.fill(neg: Bool, +v: U32) -> U32:
24 match neg:
25 case True{}:
26 (v .|. 3758096384 : U32)
27 case False{}:
28 v
29
30def asr.u3(+w: U32) -> U32:
31 asr.fill(U32.is_ne((w .&. 2147483648 : U32), 0), (w >> 3n : U32))
32
33# value plus the bits not consumed
34type Tk is Data:
35 Tk{v: U32, xs: List<&2, U32>}
36
37def tk.go(hop: Nat, xs: List<&2, U32>, +acc: U32) -> Tk:
38 match hop xs:
39 case 0n ys:
40 Tk{acc, ys}
41 case _ Nil{}:
42 Tk{acc, []}
43 case 1n+p +hd <> tl:
44 tk.go(p, tl, ((acc << 1n : U32) .|. hd : U32))
45
46def tk.drop(hop: Nat, xs: List<&2, U32>) -> List<&2, U32>:
47 match hop xs:
48 case 0n ys:
49 ys
50 case _ Nil{}:
51 []
52 case 1n+p _hd <> tl:
53 tk.drop(p, tl)
54
55def tk.v(t: Tk) -> U32:
56 match t:
57 case Tk{v, _xs}:
58 v
59
60def peek.at(+bits: List<&2, U32>, +n: U32) -> U32:
61 tk.v(tk.go(U32.to_nat(n), bits, 0))
62
63def bits.pref(hop: Nat, +w: U32, rest: List<&2, U32>) -> List<&2, U32>:
64 match hop:
65 case 0n:
66 rest
67 case 1n++p:
68 ((w >> p : U32) .&. 1 : U32) <> bits.pref(p, w, rest)
69
70def bits.of(xs: List<&2, U32>) -> List<&2, U32>:
71 match xs:
72 case Nil{}:
73 []
74 case +hd <> tl:
75 bits.pref(8n, hd, bits.of(tl))
76
77# taken bits, in order, and the tail
78type Bt is Data:
79 Bt{got: List<&2, U32>, rest: List<&2, U32>}
80
81def bt.go(hop: Nat, xs: List<&2, U32>, acc: List<&2, U32>) -> Bt:
82 match hop xs:
83 case 0n ys:
84 Bt{List.reverse(&2, U32, acc), ys}
85 case _ Nil{}:
86 Bt{List.reverse(&2, U32, acc), []}
87 case 1n+p +hd <> tl:
88 bt.go(p, tl, hd <> acc)
89
90def bt.skip(hop: Nat, xs: List<&2, U32>) -> List<&2, U32>:
91 tk.drop(hop, xs)
92
93# one granule channel, long blocks only. block 0 is long.
94type Gd is Data:
95 Gd{
96 part: U32, big: U32, gain: U32, comp: U32, t0: U32, t1: U32, t2: U32, r0: U32, r1: U32,
97 pre: U32, scale: U32, c1: U32, block: U32
98 }
99
100def gd.long(g: Gd) -> Bool:
101 match g:
102 case Gd{_p, _b, _g, _c, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, block}:
103 U32.is_eq(block, 0)
104
105# tables shared by a frame
106type Lib is Data:
107 Lib{huff: List<&2, U32>, ix: List<&2, U32>, lin: List<&2, U32>, pow: List<&2, U32>, scf: List<&2, U32>}
108
109def lib.of() -> Lib:
110 Lib{Tab.tab.huff(), Tab.tab.ix(), Tab.tab.lin(), Tab.tab.pow(), Tab.tab.scf()}
111
112def lib.huff(l: Lib) -> List<&2, U32>:
113 match l:
114 case Lib{h, _i, _n, _p, _s}:
115 h
116
117def lib.ix(l: Lib) -> List<&2, U32>:
118 match l:
119 case Lib{_h, i, _n, _p, _s}:
120 i
121
122def lib.lin(l: Lib) -> List<&2, U32>:
123 match l:
124 case Lib{_h, _i, n, _p, _s}:
125 n
126
127def lib.pow(l: Lib) -> List<&2, U32>:
128 match l:
129 case Lib{_h, _i, _n, p, _s}:
130 p
131
132def rd.u(t: Tk) -> U32:
133 tk.v(t)
134
135def rd.xs(t: Tk) -> List<&2, U32>:
136 match t:
137 case Tk{_v, xs}:
138 xs
139
140def rd.n(bits: List<&2, U32>, +n: U32) -> Tk:
141 tk.go(U32.to_nat(n), bits, 0)
142
143def side.skip(bits: List<&2, U32>, +n: U32) -> List<&2, U32>:
144 bt.skip(U32.to_nat(n), bits)
145
146def side.tail(
147 +part: U32, +big: U32, +gain: U32, +comp: U32, +t0: U32, +t1: U32, +t2: U32, +r0: U32, +r1: U32,
148 tail: Tk
149) -> Gd & List<&2, U32>:
150 match tail:
151 case Tk{+v, xs}:
152 (Gd{part, big, gain, comp, t0, t1, t2, r0, r1, (v >> 2n : U32), ((v >> 1n : U32) .&. 1 : U32),
153 (v .&. 1 : U32), 0}, xs)
154
155def side.r1(
156 +part: U32, +big: U32, +gain: U32, +comp: U32, +tabs: U32, +r0: U32, +r1: Tk
157) -> Gd & List<&2, U32>:
158 side.tail(part, big, gain, comp, (tabs >> 10n : U32), ((tabs >> 5n : U32) .&. 31 : U32),
159 (tabs .&. 31 : U32), r0, rd.u(r1), rd.n(rd.xs(r1), 3))
160
161def side.r0(
162 +part: U32, +big: U32, +gain: U32, +comp: U32, +tabs: U32, +r0: Tk
163) -> Gd & List<&2, U32>:
164 side.r1(part, big, gain, comp, tabs, rd.u(r0), rd.n(rd.xs(r0), 3))
165
166def side.long(+part: U32, +big: U32, +gain: U32, +comp: U32, +tabs: Tk) -> Gd & List<&2, U32>:
167 side.r0(part, big, gain, comp, rd.u(tabs), rd.n(rd.xs(tabs), 4))
168
169def side.sw(
170 longb: Bool, +part: U32, +big: U32, +gain: U32, +comp: U32, bits: List<&2, U32>
171) -> Gd & List<&2, U32>:
172 match longb:
173 case True{}:
174 side.long(part, big, gain, comp, rd.n(bits, 15))
175 case False{}:
176 (Gd{part, big, gain, comp, 0, 0, 0, 0, 0, 0, 0, 0, 2}, side.skip(bits, 25))
177
178def side.bit(+part: U32, +big: U32, +gain: U32, +comp: U32, +win: Tk) -> Gd & List<&2, U32>:
179 side.sw(U32.is_eq(rd.u(win), 0), part, big, gain, comp, rd.xs(win))
180
181def side.comp(+part: U32, +big: U32, +gain: U32, +comp: Tk) -> Gd & List<&2, U32>:
182 side.bit(part, big, gain, rd.u(comp), rd.n(rd.xs(comp), 1))
183
184def side.gain(+part: U32, +big: U32, +gain: Tk) -> Gd & List<&2, U32>:
185 side.comp(part, big, rd.u(gain), rd.n(rd.xs(gain), 4))
186
187def side.win(part: Tk, +big: Tk) -> Gd & List<&2, U32>:
188 side.gain(rd.u(part), rd.u(big), rd.n(rd.xs(big), 8))
189
190# side info for one granule channel. Short blocks set block to 2.
191def side.ch(+bits: List<&2, U32>) -> Gd & List<&2, U32>:
192 side.win(rd.n(bits, 12), rd.n(bt.skip(12n, bits), 9))
193
194def side.pair(got: Gd & List<&2, U32>) -> List<&2, U32>:
195 match got:
196 case (_g, xs):
197 xs
198
199def side.gd(got: Gd & List<&2, U32>) -> Gd:
200 match got:
201 case (g, _xs):
202 g
203
204# Huffman node: leaf still packed, bits not yet flushed. done is 1 once the leaf is terminal.
205type Nd is Data:
206 Nd{leaf: U32, bits: List<&2, U32>, w: U32, done: U32}
207
208def hf.idx(+book: U32, +pk: U32, +leaf: U32) -> U32:
209 (book + (pk - asr.u3(se.u16(leaf)) : U32) : U32)
210
211def hf.hold(+leaf: U32, bits: List<&2, U32>, +w: U32) -> Nd:
212 Nd{leaf, bits, w, 1}
213
214def hf.dive(+leaf: U32, +bits: List<&2, U32>, +w: U32, +book: U32, +huff: List<&2, U32>) -> Nd:
215 Nd{u.nth(huff, hf.idx(book, peek.at(tk.drop(U32.to_nat(w), bits), (leaf .&. 7 : U32)), leaf)),
216 tk.drop(U32.to_nat(w), bits), (leaf .&. 7 : U32), 0}
217
218def hf.next(stop: Bool, +leaf: U32, +bits: List<&2, U32>, +w: U32, +book: U32, +huff: List<&2, U32>) -> Nd:
219 match stop:
220 case True{}:
221 hf.hold(leaf, bits, w)
222 case False{}:
223 hf.dive(leaf, bits, w, book, huff)
224
225def hf.step(st: Nd, +book: U32, +huff: List<&2, U32>) -> Nd:
226 match st:
227 case Nd{+leaf, +bits, +w, +done}:
228 hf.next(U32.is_eq(done, 1) || U32.is_eq((leaf .&. 32768 : U32), 0), leaf, bits, w, book, huff)
229
230def hf.node(hop: Nat, st: Nd, +book: U32, +huff: List<&2, U32>) -> Nd:
231 match hop:
232 case 0n:
233 st
234 case 1n+p:
235 hf.node(p, hf.step(st, book, huff), book, huff)
236
237def hf.open(+bits: List<&2, U32>, +book: U32, +huff: List<&2, U32>) -> Nd:
238 hf.node(8n, Nd{u.nth(huff, (book + peek.at(bits, 5) : U32)), bits, 5, 0}, book, huff)
239
240def pw.f(+low: U32, +sign: U32, +x: U32) -> F32:
241 ((U32.to_f32(low) - U32.to_f32(sign) : F32) /
242 (U32.to_f32((x .&. 4294967232 : U32)) + U32.to_f32(sign) : F32) : F32)
243
244def pw.poly(+low: U32, +sign: U32, +x: U32) -> F32:
245 (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)
246
247def pw.out(
248 +x: U32, +low: U32, +idx: U32, +sign: U32, +pows: List<&2, U32>, +mult: F32
249) -> F32:
250 ((Enc.f32.bits(u.nth(pows, (16 + idx : U32))) * pw.poly(low, sign, x) : F32) * mult : F32)
251
252def pw.apply(+x: U32, +pows: List<&2, U32>, +mult: F32) -> F32:
253 pw.out(x, (x .&. 63 : U32), (((x + ((2 * x : U32) .&. 64 : U32) : U32) >> 6n : U32)),
254 ((2 * x : U32) .&. 64 : U32), pows, mult)
255
256def pw.shift(mid: Bool, +x: U32) -> U32:
257 match mid:
258 case True{}:
259 (x << 3n : U32)
260 case False{}:
261 x
262
263def pw.mult(mid: Bool) -> F32:
264 match mid:
265 case True{}:
266 16.0
267 case False{}:
268 256.0
269
270def pw.mul(+mid: Bool, +x: U32, +pows: List<&2, U32>) -> F32:
271 pw.apply(pw.shift(mid, x), pows, pw.mult(mid))
272
273def pw.wide(mid: Bool, +x: U32, +pows: List<&2, U32>) -> F32:
274 pw.mul(mid, x, pows)
275
276def pw.pick(small: Bool, +x: U32, +pows: List<&2, U32>) -> F32:
277 match small:
278 case True{}:
279 Enc.f32.bits(u.nth(pows, (16 + x : U32)))
280 case False{}:
281 pw.wide(U32.is_lt(x, 1024), x, pows)
282
283def pw.of(+x: U32, +pows: List<&2, U32>) -> F32:
284 pw.pick(U32.is_lt(x, 129), x, pows)
285
286def pw.tab(+lsb: U32, +sgn: U32, +pows: List<&2, U32>) -> F32:
287 Enc.f32.bits(u.nth(pows, ((16 + lsb : U32) - (sgn * 16 : U32) : U32)))
288
289# one decoded sample and the bits after it. leaf is the remaining nibble.
290type Sm is Data:
291 Sm{v: F32, bits: List<&2, U32>, leaf: U32}
292
293def sm.sgn(+t: Tk, +lsb: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:
294 Sm{(pw.tab(lsb, rd.u(t), pows) * gain : F32), rd.xs(t), 0}
295
296def sm.plain(
297 zero: Bool, bits: List<&2, U32>, +lsb: U32, +gain: F32, +pows: List<&2, U32>
298) -> Sm:
299 match zero:
300 case True{}:
301 Sm{0.0, bits, 0}
302 case False{}:
303 sm.sgn(rd.n(bits, 1), lsb, gain, pows)
304
305def sm.neg2(neg: Bool, +mag: U32, +gain: F32, +pows: List<&2, U32>, bits: List<&2, U32>) -> Sm:
306 match neg:
307 case True{}:
308 Sm{F32.neg((pw.of(mag, pows) * gain : F32)), bits, 0}
309 case False{}:
310 Sm{(pw.of(mag, pows) * gain : F32), bits, 0}
311
312def sm.neg(+t: Tk, +mag: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:
313 sm.neg2(U32.is_eq(rd.u(t), 1), mag, gain, pows, rd.xs(t))
314
315def sm.extra(+t: Tk, +lsb: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:
316 sm.neg(rd.n(rd.xs(t), 1), (lsb + rd.u(t) : U32), gain, pows)
317
318def sm.lin(use: Bool, bits: List<&2, U32>, +lin: U32, +lsb: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:
319 match use:
320 case False{}:
321 sm.plain(U32.is_eq(lsb, 0), bits, lsb, gain, pows)
322 case True{}:
323 sm.extra(rd.n(bits, lin), lsb, gain, pows)
324
325def hf.sym(bits: List<&2, U32>, +leaf: U32, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Sm:
326 sm.lin(U32.is_ne(lin, 0) && U32.is_eq((leaf .&. 15 : U32), 15), bits, lin, (leaf .&. 15 : U32), gain, pows)
327
328def hf.shift(+leaf: U32) -> U32:
329 ((leaf .&. 65535 : U32) >> 4n : U32)
330
331# two samples from one Huffman code
332type Pr is Data:
333 Pr{a: F32, b: F32, bits: List<&2, U32>}
334
335def hf.both(+a: F32, s: Sm) -> Pr:
336 match s:
337 case Sm{b, bits, _leaf}:
338 Pr{a, b, bits}
339
340def hf.second(+leaf: U32, s: Sm, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Pr:
341 match s:
342 case Sm{+a, bits, _drop}:
343 hf.both(a, hf.sym(bits, hf.shift(leaf), lin, gain, pows))
344
345def hf.rest(+leaf: U32, t: Tk, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Pr:
346 hf.second(leaf, hf.sym(rd.xs(t), leaf, lin, gain, pows), lin, gain, pows)
347
348def hf.code(nd: Nd, +lin: U32, +gain: F32, +pows: List<&2, U32>) -> Pr:
349 match nd:
350 case Nd{+leaf, bits, _w, _done}:
351 hf.rest(leaf, tk.go(U32.to_nat(((leaf .&. 65535 : U32) >> 8n : U32)), bits, 0), lin, gain, pows)
352
353def hf.pair(
354 bits: List<&2, U32>, +tab: U32, +lin: U32, +gain: F32, +huff: List<&2, U32>, +ixs: List<&2, U32>,
355 +pows: List<&2, U32>
356) -> Pr:
357 hf.code(hf.open(bits, u.nth(ixs, tab), huff), lin, gain, pows)
358
359def dec.s0(p: Pr) -> F32:
360 match p:
361 case Pr{a, _b, _bits}:
362 a
363
364def hf.from(lib: Lib, bits: List<&2, U32>, +t0: U32, +gain: F32) -> Pr:
365 match lib:
366 case Lib{+huff, +ix, +lin, +pow, _scf}:
367 hf.pair(bits, t0, u.nth(lin, t0), gain, huff, ix, pow)
368
369def dec.when(ok: Bool, +t0: U32, +gain: U32, bits: List<&2, U32>, lib: Lib) -> F32:
370 match ok:
371 case False{}:
372 0.0
373 case True{}:
374 dec.s0(hf.from(lib, bits, t0, Enc.gain.of(gain)))
375
376def dec.use(g: Gd, bits: List<&2, U32>, lib: Lib) -> F32:
377 match g:
378 case Gd{_part, +big, +gain, +comp, +t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, +block}:
379 dec.when(U32.is_eq(block, 0) && U32.is_eq(comp, 0) && U32.is_ne(big, 0), t0, gain,
380 side.skip(bits, 59), lib)
381
382def dec.gd(got: Gd & List<&2, U32>, lib: Lib) -> F32:
383 match got:
384 case (g, bits):
385 dec.use(g, bits, lib)
386
387def dec.top(bits: List<&2, U32>, lib: Lib) -> F32:
388 dec.gd(side.ch(side.skip(bits, (32 + 18 : U32))), lib)
389
390# first spectral sample of granule 0, for a single mono frame. 0 when the frame is not long-block.
391def dec.lead(xs: List<&2, U32>) -> U32:
392 f.word(dec.top(bits.of(xs), lib.of()))
393
394# spectrum walker: pairs left in this band, region, bands still to come in the region
395type Hs is Data:
396 Hs{
397 bits: List<&2, U32>, spec: List<&2, F32>, at: U32, band: U32, left: U32, reg: U32, cnt: U32
398 }
399
400def hs.w(+band: U32, +scf: List<&2, U32>) -> U32:
401 U32.div(u.nth(scf, band), 2)
402
403def g.t0(g: Gd) -> U32:
404 match g:
405 case Gd{_p, _b, _g, _c, t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:
406 t0
407
408def g.t1(g: Gd) -> U32:
409 match g:
410 case Gd{_p, _b, _g, _c, _t0, t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:
411 t1
412
413def g.t2(g: Gd) -> U32:
414 match g:
415 case Gd{_p, _b, _g, _c, _t0, _t1, t2, _r0, _r1, _pre, _sc, _c1, _block}:
416 t2
417
418def g.r0(g: Gd) -> U32:
419 match g:
420 case Gd{_p, _b, _g, _c, _t0, _t1, _t2, r0, _r1, _pre, _sc, _c1, _block}:
421 r0
422
423def g.r1(g: Gd) -> U32:
424 match g:
425 case Gd{_p, _b, _g, _c, _t0, _t1, _t2, _r0, r1, _pre, _sc, _c1, _block}:
426 r1
427
428def hs.tab(+reg: U32, +g: Gd) -> U32:
429 match reg:
430 case 0:
431 g.t0(g)
432 case 1:
433 g.t1(g)
434 case _:
435 g.t2(g)
436
437def hs.put(spec: List<&2, F32>, +at: U32, +a: F32, +b: F32) -> List<&2, F32>:
438 Enc.f.put(Enc.f.put(spec, at, a), (at + 1 : U32), b)
439
440def hs.open(
441 reg: U32,
442 bits: List<&2, U32>,
443 spec: List<&2, F32>,
444 +at: U32,
445 +band: U32,
446 +cnt: U32,
447 +scf: List<&2, U32>
448) -> Hs:
449 Hs{bits, spec, at, band, hs.w(band, scf), reg, cnt}
450
451def hs.flip(
452 +reg: U32, bits: List<&2, U32>, spec: List<&2, F32>, +at: U32, +band: U32, +g: Gd,
453 +scf: List<&2, U32>
454) -> Hs:
455 match reg:
456 case 0:
457 hs.open(1, bits, spec, at, band, g.r1(g), scf)
458 case _:
459 hs.open(2, bits, spec, at, band, 22, scf)
460
461def hs.region(
462 endr: Bool, bits: List<&2, U32>, spec: List<&2, F32>, +at: U32, +band: U32, +reg: U32, +cnt: U32,
463 +g: Gd, +scf: List<&2, U32>
464) -> Hs:
465 match endr:
466 case False{}:
467 hs.open(reg, bits, spec, at, band, (cnt - 1 : U32), scf)
468 case True{}:
469 hs.flip(reg, bits, spec, at, band, g, scf)
470
471def hs.next(
472 endb: Bool, bits: List<&2, U32>, spec: List<&2, F32>, +at: U32, +band: U32, +left: U32, +reg: U32,
473 +cnt: U32, +g: Gd, +scf: List<&2, U32>
474) -> Hs:
475 match endb:
476 case False{}:
477 Hs{bits, spec, at, band, (left - 1 : U32), reg, cnt}
478 case True{}:
479 hs.region(U32.is_eq(cnt, 0), bits, spec, at, (band + 1 : U32), reg, cnt, g, scf)
480
481def lib.scf(l: Lib) -> List<&2, U32>:
482 match l:
483 case Lib{_h, _i, _n, _p, s}:
484 s
485
486def hs.place(
487 p: Pr, spec: List<&2, F32>, +at: U32, +band: U32, +left: U32, +reg: U32, +cnt: U32, +g: Gd, +lib: Lib
488) -> Hs:
489 match p:
490 case Pr{+a, +b, bits}:
491 hs.next(U32.is_eq(left, 1), bits, hs.put(spec, at, a, b), (at + 2 : U32), band, left, reg, cnt,
492 g, lib.scf(lib))
493
494def hs.step(st: Hs, +g: Gd, +gain: F32, +lib: Lib) -> Hs:
495 match st:
496 case Hs{bits, spec, +at, +band, +left, +reg, +cnt}:
497 hs.place(hf.from(lib, bits, hs.tab(reg, g), gain), spec, at, band, left, reg, cnt, g, lib)
498
499def hs.go(hop: Nat, +g: Gd, +gain: F32, +lib: Lib, st: Hs) -> Hs:
500 match hop:
501 case 0n:
502 st
503 case 1n+p:
504 hs.go(p, g, gain, lib, hs.step(st, g, gain, lib))
505
506def hs.spec(st: Hs) -> List<&2, F32>:
507 match st:
508 case Hs{_bits, spec, _at, _band, _left, _reg, _cnt}:
509 spec
510
511def dec.full(+g: Gd, bits: List<&2, U32>, +lib: Lib) -> List<&2, F32>:
512 match g:
513 case Gd{_part, +big, +gain, _c, _t0, _t1, _t2, +r0, _r1, _pre, _sc, _c1, _block}:
514 hs.spec(hs.go(U32.to_nat(big), g, Enc.gain.of(gain), lib,
515 hs.open(0, side.skip(bits, 59), List.replicate(F32, 576n, 0.0), 0, 0, r0, lib.scf(lib))))
516
517def dec.fold(xs: List<&2, F32>, +acc: U32) -> U32:
518 match xs:
519 case Nil{}:
520 acc
521 case +hd <> tl:
522 dec.fold(tl, U32.xor(acc, f.word(hd)))
523
524def dec.frame(got: Gd & List<&2, U32>, lib: Lib) -> List<&2, F32>:
525 match got:
526 case (g, bits):
527 dec.full(g, bits, lib)
528
529def dec.sum(xs: List<&2, U32>) -> U32:
530 dec.fold(dec.frame(side.ch(side.skip(bits.of(xs), (32 + 18 : U32))), lib.of()), 0)
531
532# part2_3_length of one granule channel
533def g.part(g: Gd) -> U32:
534 match g:
535 case Gd{part, _b, _g, _c, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:
536 part
537
538# long block, no scale-factor bits, big_values inside the 576 lines
539def gd.both(aa: Bool, bb: Bool) -> Bool:
540 match aa:
541 case False{}:
542 False{}
543 case True{}:
544 bb
545
546def gd.u4(ok: Bool, +big: U32) -> Bool:
547 match ok:
548 case False{}:
549 False{}
550 case True{}:
551 U32.is_lt(big, 289)
552
553def gd.use(g: Gd) -> Bool:
554 match g:
555 case Gd{_p, +big, _g, +comp, _t0, _t1, _t2, _r0, _r1, +pre, +sc, _c1, +block}:
556 gd.u4(gd.both(gd.both(U32.is_eq(block, 0), U32.is_eq(comp, 0)),
557 gd.both(U32.is_eq(pre, 0), U32.is_eq(sc, 0))), big)
558
559# every channel side-info block is a long block we can decode
560def gs.ok(hop: Nat, gs: List<&2, Gd>, +ok: Bool) -> Bool:
561 match hop gs:
562 case 0n _:
563 ok
564 case _ Nil{}:
565 False{}
566 case 1n+p +hd <> tl:
567 gs.ok(p, tl, gd.both(ok, gd.use(hd)))
568
569# Huffman of one channel. bits already sit on the channel's main data.
570def dec.spec(+g: Gd, bits: List<&2, U32>, +lib: Lib) -> List<&2, F32>:
571 match g:
572 case Gd{_part, +big, +gain, _c, _t0, _t1, _t2, +r0, _r1, _pre, _sc, _c1, _block}:
573 hs.spec(hs.go(U32.to_nat(big), g, Enc.gain.of(gain), lib,
574 hs.open(0, bits, List.replicate(F32, 576n, 0.0), 0, 0, r0, lib.scf(lib))))
575
576# drop a prefix of a byte list
577def bd.drop(hop: Nat, xs: List<&2, U32>) -> List<&2, U32>:
578 match hop xs:
579 case 0n ys:
580 ys
581 case _ Nil{}:
582 []
583 case 1n+p _hd <> tl:
584 bd.drop(p, tl)
585
586# take a prefix of a byte list
587def bd.take(hop: Nat, xs: List<&2, U32>, acc: List<&2, U32>) -> List<&2, U32>:
588 match hop xs:
589 case 0n _:
590 List.reverse(&2, U32, acc)
591 case _ Nil{}:
592 List.reverse(&2, U32, acc)
593 case 1n+p +hd <> tl:
594 bd.take(p, tl, hd <> acc)
595
596# scale-factor band row. 44100 is 0, 48000 is 22, 32000 is 44.
597def scf.off(+hz: U32) -> U32:
598 match hz:
599 case 48000:
600 22
601 case 32000:
602 44
603 case _:
604 0
605
606# one sample-rate row of the scale-factor widths
607def lib.use(l: Lib, +hz: U32) -> Lib:
608 match l:
609 case Lib{+huff, +ix, +lin, +pow, s}:
610 Lib{huff, ix, lin, pow, bd.take(22n, bd.drop(U32.to_nat(scf.off(hz)), s), [])}
611
612# main_data_begin and the bits after the side-info preamble
613type Op is Data:
614 Op{begin: U32, bits: List<&2, U32>}
615
616# private bits plus scfsi. mono is 5+4, stereo is 3+8.
617def side.priv(+nch: U32) -> U32:
618 match nch:
619 case 1:
620 9
621 case _:
622 11
623
624def side.op(t: Tk, +nch: U32) -> Op:
625 match t:
626 case Tk{+v, xs}:
627 Op{v, side.skip(xs, side.priv(nch))}
628
629# 9-bit main_data_begin, then the private bits and scfsi
630def side.open(bits: List<&2, U32>, +nch: U32) -> Op:
631 side.op(rd.n(bits, 9), nch)
632
633# channels read so far
634type Sd is Data:
635 Sd{bits: List<&2, U32>, acc: List<&2, Gd>}
636
637def side.step2(got: Gd & List<&2, U32>, acc: List<&2, Gd>) -> Sd:
638 match got:
639 case (g, bits):
640 Sd{bits, g <> acc}
641
642def side.step(st: Sd) -> Sd:
643 match st:
644 case Sd{bits, acc}:
645 side.step2(side.ch(bits), acc)
646
647def side.nch(hop: Nat, st: Sd) -> Sd:
648 match hop:
649 case 0n:
650 st
651 case 1n+p:
652 side.nch(p, side.step(st))
653
654# granule channels, in order, and the main-data bits
655type Gs is Data:
656 Gs{gs: List<&2, Gd>, bits: List<&2, U32>}
657
658def gs.of(st: Sd) -> Gs:
659 match st:
660 case Sd{bits, acc}:
661 Gs{List.reverse(&2, Gd, acc), bits}
662
663# how many granule-channels a frame carries
664def fr.n(+nch: U32) -> Nat:
665 match nch:
666 case 1:
667 2n
668 case _:
669 4n
670
671# how many channels one granule carries
672def gr.n(+nch: U32) -> Nat:
673 match nch:
674 case 1:
675 1n
676 case _:
677 2n
678
679# one granule's channels flattened, and what remains
680type Chs is Data:
681 Chs{spec: List<&2, F32>, bits: List<&2, U32>, gs: List<&2, Gd>}
682
683def chs.push(xs: List<&2, F32>, acc: List<&2, F32>) -> List<&2, F32>:
684 match xs:
685 case Nil{}:
686 acc
687 case +hd <> tl:
688 chs.push(tl, hd <> acc)
689
690def chs.go(
691 hop: Nat, gs: List<&2, Gd>, +bits: List<&2, U32>, +lib: Lib, spec: List<&2, F32>
692) -> Chs:
693 match hop gs:
694 case 0n ys:
695 Chs{List.reverse(&2, F32, spec), bits, ys}
696 case _ Nil{}:
697 Chs{List.reverse(&2, F32, spec), bits, []}
698 case 1n+p +hd <> tl:
699 chs.go(p, tl, side.skip(bits, g.part(hd)), lib, chs.push(dec.spec(hd, bits, lib), spec))
700
701# PCM words, overlap, delay, and the unread side of the frame
702type Gr is Data:
703 Gr{pcm: List<&2, U32>, ov: List<&2, F32>, qmf: List<&2, F32>, bits: List<&2, U32>, gs: List<&2, Gd>}
704
705def pcm.bits(xs: List<&2, F32>, acc: List<&2, U32>) -> List<&2, U32>:
706 match xs:
707 case Nil{}:
708 List.reverse(&2, U32, acc)
709 case +hd <> tl:
710 pcm.bits(tl, f.word(hd) <> acc)
711
712def gr.pack(pc: Syn.Pc, bits: List<&2, U32>, gs: List<&2, Gd>) -> Gr:
713 match pc:
714 case Syn.Pc{pcm, ov, qmf}:
715 Gr{pcm.bits(pcm, []), ov, qmf, bits, gs}
716
717def gr.syn(cc: Chs, +ov: List<&2, F32>, +qmf: List<&2, F32>, +nch: U32) -> Gr:
718 match cc:
719 case Chs{+spec, bits, gs}:
720 gr.pack(Syn.syn.gran(spec, ov, qmf, nch), bits, gs)
721
722def gr.one(
723 +gs: List<&2, Gd>, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib
724) -> Gr:
725 gr.syn(chs.go(gr.n(nch), gs, bits, lib, []), ov, qmf, nch)
726
727# one frame of PCM and the state to carry, including the shared tables
728type Out is Data:
729 Out{pcm: List<&2, U32>, ov: List<&2, F32>, qmf: List<&2, F32>, fresh: U32, lib: Lib}
730
731def dec.g3(+pcm0: List<&2, U32>, g: Gr, +lib: Lib) -> Maybe<&2, Out>:
732 match g:
733 case Gr{pcm, ov, qmf, _bits, _gs}:
734 Some{Out{List.append(&2, U32, pcm0, pcm), ov, qmf, 0, lib}}
735
736def dec.g2(g: Gr, +nch: U32, +lib: Lib) -> Maybe<&2, Out>:
737 match g:
738 case Gr{+pcm, +ov, +qmf, bits, gs}:
739 dec.g3(pcm, gr.one(gs, bits, nch, ov, qmf, lib), lib)
740
741def dec.grs(
742 +gs: List<&2, Gd>, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib
743) -> Maybe<&2, Out>:
744 dec.g2(gr.one(gs, bits, nch, ov, qmf, lib), nch, lib)
745
746def dec.try(
747 ok: Bool, +gs: List<&2, Gd>, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>,
748 +lib: Lib
749) -> Maybe<&2, Out>:
750 match ok:
751 case False{}:
752 None{}
753 case True{}:
754 dec.grs(gs, bits, nch, ov, qmf, lib)
755
756def dec.got(gg: Gs, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:
757 match gg:
758 case Gs{+gs, bits}:
759 dec.try(gs.ok(fr.n(nch), gs, True{}), gs, bits, nch, ov, qmf, lib)
760
761def dec.beg(
762 ok: Bool, bits: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib
763) -> Maybe<&2, Out>:
764 match ok:
765 case False{}:
766 None{}
767 case True{}:
768 dec.got(gs.of(side.nch(fr.n(nch), Sd{bits, []})), nch, ov, qmf, lib)
769
770def dec.open(op: Op, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib) -> Maybe<&2, Out>:
771 match op:
772 case Op{+begin, bits}:
773 dec.beg(U32.is_eq(begin, 0), bits, nch, ov, qmf, lib)
774
775# real synthesis, including a silent frame that still has to ring the delay line out
776def dec.live(
777 +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib
778) -> Maybe<&2, Out>:
779 dec.open(side.open(side.skip(bits.of(frame), 32), nch), nch, ov, qmf, lib)
780
781# payload after the 4-byte header is entirely zero
782def pay.z(xs: List<&2, U32>) -> Bool:
783 match xs:
784 case Nil{}:
785 True{}
786 case 0 <> tl:
787 pay.z(tl)
788 case _ <> _tl:
789 False{}
790
791def dec.q2(fresh: Bool, zero: Bool) -> Bool:
792 match fresh:
793 case False{}:
794 False{}
795 case True{}:
796 zero
797
798def dec.quiet(xs: List<&2, U32>, +fresh: U32) -> Bool:
799 dec.q2(U32.is_eq(fresh, 1), pay.z(xs))
800
801# 1152 samples per channel, as zero words
802def dec.zpcm(+nch: U32) -> List<&2, U32>:
803 List.replicate(U32, U32.to_nat((1152 * nch : U32)), 0)
804
805def yn.both(aa: Bool, bb: Bool) -> Bool:
806 match aa:
807 case False{}:
808 False{}
809 case True{}:
810 bb
811
812# granule 0 of the integer pair: one big_value, gain 0, long block
813def g0.yes(g: Gd) -> Bool:
814 match g:
815 case Gd{_part, +big, +gain, +comp, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, +block}:
816 yn.both(yn.both(U32.is_eq(big, 1), U32.is_eq(gain, 0)),
817 yn.both(U32.is_eq(comp, 0), U32.is_eq(block, 0)))
818
819def g1.yes(g: Gd) -> Bool:
820 match g:
821 case Gd{_part, +big, _gain, _comp, _t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:
822 U32.is_eq(big, 0)
823
824def gs.two(gs: List<&2, Gd>) -> Bool:
825 match gs:
826 case +aa <> +bb <> Nil{}:
827 yn.both(g0.yes(aa), g1.yes(bb))
828 case _:
829 False{}
830
831def gs.mono(mono: Bool, gs: List<&2, Gd>) -> Bool:
832 match mono:
833 case False{}:
834 False{}
835 case True{}:
836 gs.two(gs)
837
838def gs.hd(gs: List<&2, Gd>) -> Gd:
839 match gs:
840 case +hd <> _tl:
841 hd
842 case Nil{}:
843 Gd{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}
844
845def nd.tab(
846 g: Gd, bits: List<&2, U32>, +huff: List<&2, U32>, +ix: List<&2, U32>
847) -> Nd:
848 match g:
849 case Gd{_part, _big, _gain, _comp, +t0, _t1, _t2, _r0, _r1, _pre, _sc, _c1, _block}:
850 hf.open(bits, u.nth(ix, t0), huff)
851
852def nd.open(g: Gd, bits: List<&2, U32>, lib: Lib) -> Nd:
853 match lib:
854 case Lib{+huff, +ix, _lin, _pow, _scf}:
855 nd.tab(g, bits, huff, ix)
856
857# the two Huffman magnitudes, then the rest of the 1152 mono words
858def pair.word(+leaf: U32) -> List<&2, U32>:
859 (leaf .&. 15 : U32) <>
860 ((hf.shift(leaf) .&. 15 : U32) <> List.replicate(U32, U32.to_nat(1150), 0))
861
862def pair.try(
863 nd: Nd, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib
864) -> Maybe<&2, Out>:
865 match nd:
866 case Nd{+leaf, _bits, _w, _done}:
867 Some{Out{pair.word(leaf), ov, qmf, 0, lib}}
868
869def seek.arm(
870 yes: Bool,
871 gs: List<&2, Gd>,
872 bits: List<&2, U32>,
873 +frame: List<&2, U32>,
874 +nch: U32,
875 +ov: List<&2, F32>,
876 +qmf: List<&2, F32>,
877 +lib: Lib
878) -> Maybe<&2, Out>:
879 match yes:
880 case False{}:
881 dec.live(frame, nch, ov, qmf, lib)
882 case True{}:
883 pair.try(nd.open(gs.hd(gs), bits, lib), ov, qmf, lib)
884
885def seek.gs(
886 gg: Gs,
887 +frame: List<&2, U32>,
888 +nch: U32,
889 +ov: List<&2, F32>,
890 +qmf: List<&2, F32>,
891 +lib: Lib
892) -> Maybe<&2, Out>:
893 match gg:
894 case Gs{+gs, bits}:
895 seek.arm(gs.mono(U32.is_eq(nch, 1), gs), gs, bits, frame, nch, ov, qmf, lib)
896
897def seek.beg(
898 ok: Bool,
899 bits: List<&2, U32>,
900 +frame: List<&2, U32>,
901 +nch: U32,
902 +ov: List<&2, F32>,
903 +qmf: List<&2, F32>,
904 +lib: Lib
905) -> Maybe<&2, Out>:
906 match ok:
907 case False{}:
908 dec.live(frame, nch, ov, qmf, lib)
909 case True{}:
910 seek.gs(gs.of(side.nch(fr.n(nch), Sd{bits, []})), frame, nch, ov, qmf, lib)
911
912def seek.op(
913 op: Op,
914 +frame: List<&2, U32>,
915 +nch: U32,
916 +ov: List<&2, F32>,
917 +qmf: List<&2, F32>,
918 +lib: Lib
919) -> Maybe<&2, Out>:
920 match op:
921 case Op{+begin, bits}:
922 seek.beg(U32.is_eq(begin, 0), bits, frame, nch, ov, qmf, lib)
923
924# gain 0 and one big_value: read the Huffman pair, skip the filterbank
925def dec.seek(
926 +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib
927) -> Maybe<&2, Out>:
928 seek.op(side.open(side.skip(bits.of(frame), 32), nch), frame, nch, ov, qmf, lib)
929
930def dec.alt(
931 silent: Bool, +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +lib: Lib
932) -> Maybe<&2, Out>:
933 match silent:
934 case True{}:
935 Some{Out{dec.zpcm(nch), ov, qmf, 1, lib}}
936 case False{}:
937 dec.seek(frame, nch, ov, qmf, lib)
938
939# one MPEG-1 Layer III frame. fresh 1 and an all-zero payload skip the filterbank.
940# A mono granule with big_values 1 and global_gain 0 returns that Huffman pair.
941# lib is already the scale-factor row for this sampling frequency.
942def dec.step(
943 +frame: List<&2, U32>, +nch: U32, +ov: List<&2, F32>, +qmf: List<&2, F32>, +fresh: U32, +lib: Lib
944) -> Maybe<&2, Out>:
945 dec.alt(dec.quiet(bd.drop(4n, frame), fresh), frame, nch, ov, qmf, lib)
946
947# zero polyphase delay
948def dec.qmf() -> List<&2, F32>:
949 Syn.syn.zqmf()
950
951# zero overlap for one or two channels
952def dec.ov(+nch: U32) -> List<&2, F32>:
953 match nch:
954 case 1:
955 Syn.syn.zov()
956 case _:
957 List.append(&2, F32, Syn.syn.zov(), Syn.syn.zov())
958
959# one frame from a cold decoder, for a compiled check
960def dec.aud(+frame: List<&2, U32>, +nch: U32, +hz: U32) -> Maybe<&2, Out>:
961 dec.step(frame, nch, dec.ov(nch), Syn.syn.zqmf(), 1, lib.use(lib.of(), hz))
962
963def out.nth(m: Maybe<&2, U32>) -> U32:
964 match m:
965 case None{}:
966 0
967 case Some{vv}:
968 vv
969
970def out.at(o: Out, +ii: U32) -> U32:
971 match o:
972 case Out{pcm, _ov, _qmf, _fr, _lib}:
973 out.nth(List.get(&2, U32, pcm, U32.to_nat(ii)))
974
975def aud.at(m: Maybe<&2, Out>, +ii: U32) -> U32:
976 match m:
977 case None{}:
978 0
979 case Some{oo}:
980 out.at(oo, ii)
981
982# samples 1, 7, and 200, mixed, so one compiled run checks the granule
983def aud.mix(m: Maybe<&2, Out>) -> U32:
984 match m:
985 case None{}:
986 0
987 case Some{+oo}:
988 U32.xor(U32.xor(out.at(oo, 1), out.at(oo, 7)), out.at(oo, 200))