1 # MPEG-1 Layer III encoder: analysis filterbank, MDCT, quantiser, Huffman. 2 import Base 3 import ./mp3_tab.bend as Tab 4 5 def f32.bits(+w: U32) -> F32: 6 match w: 7 case U32{+bb}: 8 F32{bb} 9 10 def f32.word(x: F32) -> U32: 11 match x: 12 case F32{+bb}: 13 U32{bb} 14 15 def u.nth.m(m: Maybe<&2, U32>) -> U32: 16 match m: 17 case None{}: 18 0 19 case Some{vv}: 20 vv 21 22 def u.nth(xs: List<&2, U32>, +ii: U32) -> U32: 23 u.nth.m(List.get(&2, U32, xs, U32.to_nat(ii))) 24 25 def f.nth.m(m: Maybe<&2, F32>) -> F32: 26 match m: 27 case None{}: 28 0.0 29 case Some{vv}: 30 vv 31 32 def f.nth(xs: List<&2, F32>, +ii: U32) -> F32: 33 f.nth.m(List.get(&2, F32, xs, U32.to_nat(ii))) 34 35 def 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 38 def 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 45 def f.rev(xs: List<&2, F32>) -> List<&2, F32>: 46 List.reverse(&2, F32, xs) 47 48 def 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. 56 type Ya is Type: 57 Ya{acc: Array, cur: F32} 58 59 def ya.of(got: Array & F32) -> Ya: 60 (acc, cur) = got 61 Ya{acc, cur} 62 63 def y.store(got: Ya, +ii: U32, +vv: F32) -> Array: 64 match got: 65 case Ya{acc, +cur}: 66 Array.set(F32, acc, ii, (cur + vv : F32)) 67 68 def y.add(acc: Array, +ii: U32, +vv: F32) -> Array: 69 y.store(ya.of(Array.get(F32, acc, ii)), ii, vv) 70 71 def 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 78 def y.list(acc: Array) -> 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 82 type Xs is Type: 83 Xs{x: Array, samp: F32} 84 85 def xs.of(got: Array & F32) -> Xs: 86 (x, samp) = got 87 Xs{x, samp} 88 89 # ring delay beside the 64 partial bins while windowing 90 type Yr is Type: 91 Yr{x: Array, bins: Array} 92 93 def y.step(got: Xs, bins: Array, +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 99 def 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 110 type Cf is Type: 111 Cf{tab: Array, co: F32} 112 113 def cf.of(got: Array & F32) -> Cf: 114 (tab, co) = got 115 Cf{tab, co} 116 117 def dot.go(tl: List<&2, F32>, got: Cf, +base: U32, +hd: F32, acc: F32) -> Array & 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. 126 def dot.row(ys: List<&2, F32>, tab: Array, +base: U32, acc: F32) -> Array & 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 133 def sb.go( 134 hop: Nat, got: Cf, +ys: List<&2, F32>, +row: U32, acc: List<&2, F32> 135 ) -> Array & 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 143 def sb.rows( 144 hop: Nat, tab: Array, +ys: List<&2, F32>, +row: U32, acc: List<&2, F32> 145 ) -> Array & 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 153 type As is Type: 154 As{x: Array, cos: Array, sb: List<&2, F32>} 155 156 def as.of(x: Array, got: Array & List<&2, F32>) -> As: 157 (cos, sb) = got 158 As{x, cos, sb} 159 160 def an.sb1(got: Yr, cos: Array) -> 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. 166 def an.sb( 167 x: Array, +head: U32, +win: List<&2, F32>, cos: Array 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 172 type An is Type: 173 An{x: Array, head: U32, out: List<&2, List<&2, F32>>} 174 175 def an.done(+head: U32, out: List<&2, List<&2, F32>>, got: As) -> An & Array: 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 181 def an.write(hop: Nat, x: Array, +at: U32, blk: List<&2, F32>) -> Array: 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 190 def an.push(st: An, blk: List<&2, F32>, +win: List<&2, F32>, cos: Array) -> An & Array: 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 196 def 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 206 type Aw is Type: 207 Aw{st: An, cos: Array} 208 209 def aw.of(got: An & Array) -> Aw: 210 (st, cos) = got 211 Aw{st, cos} 212 213 def an.go(xs: List<&2, F32>, got: Aw, +win: List<&2, F32>) -> An & Array: 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 224 def an.walk(xs: List<&2, F32>, st: An, +win: List<&2, F32>, cos: Array) -> An & Array: 225 an.go(xs, Aw{st, cos}, win) 226 227 # 2^9 slots: 512-sample analysis delay, zero-filled, head at the oldest sample. 228 def an.zero() -> An: 229 An{Array.new(F32, 9n, 0.0), 0, []} 230 231 # subband frames, newest block first. each block is 32 bands. 232 def f.revs(xs: List<&2, List<&2, F32>>) -> List<&2, List<&2, F32>>: 233 List.reverse(&2, List<&2, F32>, xs) 234 235 def an.out(st: An) -> List<&2, List<&2, F32>>: 236 match st: 237 case An{_x, _head, out}: 238 f.revs(out) 239 240 def cos.put(xs: List<&2, F32>, a: Array, +ii: U32) -> Array: 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. 248 def cos.of() -> Array: 249 cos.put(f.of(Tab.tab.cos()), Array.new(F32, 11n, 0.0), 0) 250 251 def an.fin(got: An & Array) -> List<&2, List<&2, F32>>: 252 (st, _cos) = got 253 an.out(st) 254 255 def 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 259 type Ld is Data: 260 Ld{yy: F32, ee: U32} 261 262 def 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 273 def ld.scale(+ee: U32) -> F32: 274 U32.to_f32(((1073741824 >> U32.to_nat((ee >> 2n : U32)) : U32))) 275 276 def ld.once(+yy: F32, +ee: U32) -> F32: 277 ((yy * ex.of((ee .&. 3 : U32)) : F32) * ld.scale(ee) : F32) 278 279 def ld.minp(small: Bool, +ee: U32) -> U32: 280 match small: 281 case True{}: 282 ee 283 case False{}: 284 120 285 286 def ld.cut(+yy: F32, +ee: U32, +cut: U32) -> Ld: 287 Ld{ld.once(yy, cut), (ee - cut : U32)} 288 289 def 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 296 def 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 303 def 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). 309 def gain.of(+gg: U32) -> F32: 310 ld.y(ld.go(8n, Ld{2048.0, (258 - gg : U32)})) 311 312 def q.cp(ok: Bool, +nn: U32) -> U32: 313 match ok: 314 case True{}: 315 nn 316 case False{}: 317 8206 318 319 def q.clip(+nn: U32) -> U32: 320 q.cp(U32.is_le(nn, 8206), nn) 321 322 def 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 325 def q.sign(neg: Bool, +mag: U32) -> U32: 326 match neg: 327 case False{}: 328 mag 329 case True{}: 330 (0 - mag : U32) 331 332 def q.one(+xr: F32, +gain: F32) -> U32: 333 q.sign(F32.is_lt(xr, 0.0), q.mag(xr, gain)) 334 335 def 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 342 def i.neg(+vv: U32) -> Bool: 343 U32.is_ne((vv .&. 2147483648 : U32), 0) 344 345 def i.ab(neg: Bool, +vv: U32) -> U32: 346 match neg: 347 case False{}: 348 vv 349 case True{}: 350 (0 - vv : U32) 351 352 def i.abs(+vv: U32) -> U32: 353 i.ab(i.neg(vv), vv) 354 355 def scf.row(+hz: U32) -> U32: 356 match hz: 357 case 48000: 358 1 359 case 32000: 360 2 361 case _: 362 0 363 364 def scf.at(+hz: U32, +band: U32) -> U32: 365 u.nth(Tab.tab.scf(), ((scf.row(hz) * 22 : U32) + band : U32)) 366 367 def 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 378 def 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 387 def 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 397 type Bv is Data: 398 Bv{ix: List<&2, U32>, last: U32, acc: U32} 399 400 def 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 407 def 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 410 def 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 413 def 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 418 def 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 425 def bv.last(st: Bv) -> U32: 426 match st: 427 case Bv{_ix, last, _acc}: 428 last 429 430 def 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 434 type Hp is Data: 435 Hp{bits: List<&2, U32>, n: U32, ok: U32} 436 437 def 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 444 def 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 452 def 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 459 def lim.of(+lin: U32) -> U32: 460 lim.p(U32.is_eq(lin, 0), lin) 461 462 def ca.p(big: Bool, +aa: U32) -> U32: 463 match big: 464 case True{}: 465 15 466 case False{}: 467 aa 468 469 def ca.of(+lin: U32, +aa: U32) -> U32: 470 ca.p(U32.is_ne(lin, 0) && U32.is_ge(aa, 15), aa) 471 472 def hp.sgn(neg: Bool) -> U32: 473 match neg: 474 case True{}: 475 1 476 case False{}: 477 0 478 479 def 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 486 def hp.sign(hp: Hp, +vv: U32, +aa: U32) -> Hp: 487 hp.sp(U32.is_eq(aa, 0), hp, vv) 488 489 def 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 496 def 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 499 def 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 502 def 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 510 type Wd is Type: 511 Wd{tab: Array, w: U32} 512 513 def wd.of(got: Array & 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. 518 def word.of(codes: Array, +tab: U32, +ca: U32, +cb: U32) -> Array & U32: 519 Array.get(U32, codes, (((tab * 256 : U32) + (ca * 16 : U32) : U32) + cb : U32)) 520 521 def 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 529 def 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 532 def hp.from( 533 got: Wd, hp: Hp, +av: U32, +bv: U32, +aa: U32, +bb: U32, +lin: U32 534 ) -> Array & Hp: 535 match got: 536 case Wd{tab, +w}: 537 (tab, hp.word(hp, av, bv, aa, bb, lin, w)) 538 539 def hp.ready( 540 hp: Hp, +tab: U32, +av: U32, +bv: U32, +aa: U32, +bb: U32, +lin: U32, codes: Array 541 ) -> Array & 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 544 def hp.pair( 545 hp: Hp, +tab: U32, +av: U32, +bv: U32, codes: Array, +lins: List<&2, U32> 546 ) -> Array & 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 550 type Hs is Type: 551 Hs{tab: Array, hp: Hp} 552 553 def hs.of(got: Array & Hp) -> Hs: 554 (tab, hp) = got 555 Hs{tab, hp} 556 557 def hp.pairs( 558 xs: List<&2, U32>, got: Hs, +tab: U32, +lins: List<&2, U32> 559 ) -> Array & 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 568 def 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 572 type Best is Data: 573 Best{tab: U32, nn: U32, bits: List<&2, U32>, ok: U32} 574 575 def best.or(a: Bool, b: Bool) -> Bool: 576 match a: 577 case True{}: 578 True{} 579 case False{}: 580 b 581 582 def best.and(a: Bool, b: Bool) -> Bool: 583 match a: 584 case False{}: 585 False{} 586 case True{}: 587 b 588 589 def 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 592 def 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 602 def 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 607 def 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 612 def best.pull(b: Best, +tab: U32, got: Hs) -> Array & Best: 613 match got: 614 case Hs{codes, hp}: 615 (codes, best.got(b, tab, hp)) 616 617 def best.one( 618 b: Best, +tab: U32, ix: List<&2, U32>, codes: Array, +lins: List<&2, U32> 619 ) -> Array & Best: 620 best.pull(b, tab, hs.of(hp.pairs(ix, Hs{codes, Hp{[], 0, 1}}, tab, lins))) 621 622 def best.step( 623 b: Best, +tab: U32, +ix: List<&2, U32>, codes: Array, +lins: List<&2, U32> 624 ) -> Array & Best: 625 best.one(b, tab, ix, codes, lins) 626 627 # the code table beside the shortest table so far 628 type Bs is Type: 629 Bs{tab: Array, best: Best} 630 631 def bs.of(got: Array & Best) -> Bs: 632 (tab, best) = got 633 Bs{tab, best} 634 635 def best.go( 636 cs: List<&2, U32>, +ix: List<&2, U32>, got: Bs, +lins: List<&2, U32> 637 ) -> Array & 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 644 def code.put(xs: List<&2, U32>, a: Array, +ii: U32) -> Array: 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. 652 def code.of() -> Array: 653 code.put(Tab.tab.code(), Array.new(U32, 13n, 0), 0) 654 655 def best.fin(got: Bs) -> Best: 656 match got: 657 case Bs{_tab, best}: 658 best 659 660 def 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 663 def ix.p(z: Bool, +mm: U32, +aa: U32) -> U32: 664 match z: 665 case True{}: 666 aa 667 case False{}: 668 mm 669 670 def ix.up(+mm: U32, +aa: U32) -> U32: 671 ix.p(U32.is_lt(mm, aa), mm, aa) 672 673 def 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 681 type Sr is Data: 682 Sr{lo: U32, hi: U32, gg: U32, tab: U32, bits: List<&2, U32>, ok: U32} 683 684 def 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 691 def 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 694 def 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 704 def 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 712 def 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 723 def 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 730 def 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 736 def 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 746 def 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 751 def 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 758 def 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 761 def pk.p(z: Bool, +mm: F32, +aa: F32) -> F32: 762 match z: 763 case True{}: 764 aa 765 case False{}: 766 mm 767 768 def pk.up(+mm: F32, +aa: F32) -> F32: 769 pk.p(F32.is_lt(mm, aa), mm, aa) 770 771 def 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 778 def dz.one(z: Bool, +vv: F32) -> F32: 779 match z: 780 case True{}: 781 0.0 782 case False{}: 783 vv 784 785 def 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 792 def 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 801 def 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 806 def 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 815 def dz.thrs() -> List<&2, U32>: 816 [953267991, 981668463, 994352038, 1008981770, 1022739087, 1036831949, 1045220557, 1053609165] 817 818 def 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 825 def 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 829 type 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 833 type Rv is Data: 834 Rv{xs: List<&2, U32>, n: U32} 835 836 def 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 843 def 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 848 def 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 855 def 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 862 def 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 867 def 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 871 type Bf is Type: 872 Bf{tab: Array, co: F32} 873 874 def bf.of(got: Array & F32) -> Bf: 875 (tab, co) = got 876 Bf{tab, co} 877 878 def bt.go(tl: List<&2, F32>, got: Bf, +base: U32, +hd: F32, acc: F32) -> Array & 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. 887 def bt.dot(vec: List<&2, F32>, tab: Array, +base: U32, acc: F32) -> Array & 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 894 def 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 905 def band.step( 906 hop: Nat, +vec: List<&2, F32>, got: Bf, +kk: U32, acc: List<&2, F32> 907 ) -> Array & 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 915 def band.k( 916 hop: Nat, +vec: List<&2, F32>, tab: Array, +kk: U32, acc: List<&2, F32> 917 ) -> Array & 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 924 def band.row( 925 +aa: List<&2, List<&2, F32>>, +cc: List<&2, List<&2, F32>>, tab: Array, +band: U32 926 ) -> Array & List<&2, F32>: 927 band.k(18n, List.append(&2, F32, col.b(18n, aa, band, []), col.b(18n, cc, band, [])), tab, 0, []) 928 929 def 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 937 type Br is Type: 938 Br{tab: Array, row: List<&2, F32>} 939 940 def br.of(got: Array & List<&2, F32>) -> Br: 941 (tab, row) = got 942 Br{tab, row} 943 944 def 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 & 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 955 def spec.bands( 956 hop: Nat, +aa: List<&2, List<&2, F32>>, +cc: List<&2, List<&2, F32>>, tab: Array, 957 +band: U32, acc: List<&2, List<&2, F32>> 958 ) -> Array & 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 965 def 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 974 def 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 985 def spec.one(+blocks: List<&2, List<&2, F32>>, tab: Array) -> Array & 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. 989 type Sa is Type: 990 Sa{acc: Array, cur: F32} 991 992 def sa.of(got: Array & F32) -> Sa: 993 (acc, cur) = got 994 Sa{acc, cur} 995 996 def al.fill(xs: List<&2, F32>, a: Array, +ii: U32) -> Array: 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. 1004 def al.arr(xs: List<&2, F32>) -> Array: 1005 al.fill(xs, Array.new(F32, 10n, 0.0), 0) 1006 1007 def 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 1014 def al.list(acc: Array) -> List<&2, F32>: 1015 al.pull(575n, sa.of(Array.get(F32, acc, 0)), 0, []) 1016 1017 def al.write( 1018 acc: Array, +up: F32, +dp: F32, +c0: F32, +c1: F32, +hi: U32, +lo: U32 1019 ) -> Array: 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 1023 def al.use(got: Sa, +dp: F32, +c0: F32, +c1: F32, +hi: U32, +lo: U32) -> Array: 1024 match got: 1025 case Sa{acc, +up}: 1026 al.write(acc, up, dp, c0, c1, hi, lo) 1027 1028 def al.both(got: Sa, +c0: F32, +c1: F32, +hi: U32, +lo: U32) -> Array: 1029 match got: 1030 case Sa{acc, +dp}: 1031 al.use(sa.of(Array.get(F32, acc, hi)), dp, c0, c1, hi, lo) 1032 1033 def al.one(acc: Array, +aa: List<&2, F32>, +bb: U32, +ii: U32) -> Array: 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 1038 def al.i(hop: Nat, acc: Array, +aa: List<&2, F32>, +bb: U32, +ii: U32) -> Array: 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 1045 def al.band(acc: Array, +aa: List<&2, F32>, +bb: U32) -> Array: 1046 al.i(8n, acc, aa, bb, 0) 1047 1048 def al.go(hop: Nat, acc: Array, +aa: List<&2, F32>, +bb: U32) -> Array: 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 1055 def al.fin(acc: Array) -> List<&2, F32>: 1056 al.list(al.go(31n, acc, f.of(Tab.tab.aa()), 30)) 1057 1058 def al.run(xs: List<&2, F32>) -> List<&2, F32>: 1059 al.fin(al.arr(xs)) 1060 1061 def spec.read(got: Br) -> Array & List<&2, F32>: 1062 match got: 1063 case Br{tab, row}: 1064 (tab, al.run(row)) 1065 1066 def spec.gran(+blocks: List<&2, List<&2, F32>>, tab: Array) -> Array & List<&2, F32>: 1067 spec.read(br.of(spec.one(blocks, tab))) 1068 1069 def grans.step( 1070 hop: Nat, +blocks: List<&2, List<&2, F32>>, got: Br, acc: List<&2, List<&2, F32>> 1071 ) -> Array & 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 1078 def grans.go( 1079 hop: Nat, +blocks: List<&2, List<&2, F32>>, tab: Array, acc: List<&2, List<&2, F32>> 1080 ) -> Array & 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 1087 def 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 1094 def grans.n(+nb: U32) -> U32: 1095 grans.np(U32.is_le(nb, 18), nb) 1096 1097 def bt.put(xs: List<&2, F32>, a: Array, +ii: U32) -> Array: 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. 1105 def bt.of() -> Array: 1106 bt.put(f.of(Tab.tab.bt()), Array.new(F32, 10n, 0.0), 0) 1107 1108 def gran.fin(got: Array & List<&2, List<&2, F32>>) -> List<&2, List<&2, F32>>: 1109 (_tab, xs) = got 1110 xs 1111 1112 def 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 1116 def flip.samp(z: Bool, +vv: F32) -> F32: 1117 match z: 1118 case True{}: 1119 F32.neg(vv) 1120 case False{}: 1121 vv 1122 1123 def 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 1130 def flip.one(blk: List<&2, F32>, odd: Bool) -> List<&2, F32>: 1131 flip.go(blk, 0, [], odd) 1132 1133 def 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 1140 def 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. 1144 type Bw is Data: 1145 Bw{acc: U32, n: U32, out: List<&2, U32>} 1146 1147 def bw.empty() -> Bw: 1148 Bw{0, 0, []} 1149 1150 def 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 1157 def 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 1162 def 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 1169 def 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 1176 def 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 1181 def pk.sr(+hz: U32) -> U32: 1182 match hz: 1183 case 48000: 1184 4 1185 case 32000: 1186 8 1187 case _: 1188 0 1189 1190 def pk.mode(+ch: U32) -> U32: 1191 match ch: 1192 case 1: 1193 196 1194 case _: 1195 4 1196 1197 def pk.hdr(+hz: U32, +ch: U32) -> List<&2, U32>: 1198 [255, 251, (224 .|. pk.sr(hz) : U32), pk.mode(ch)] 1199 1200 def pk.fsz(+hz: U32) -> U32: 1201 U32.div(((1152 * 320 : U32) * 125 : U32), hz) 1202 1203 def pk.sidebits(+ch: U32) -> U32: 1204 match ch: 1205 case 1: 1206 136 1207 case _: 1208 256 1209 1210 def 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 1213 def blk.up(+n: U32) -> U32: 1214 U32.div((n + 31 : U32), 32) 1215 1216 def blk.q(+b: U32) -> U32: 1217 U32.div((b + 17 : U32), 18) 1218 1219 def 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 1226 def blk.odd(+q: U32) -> U32: 1227 blk.fix(U32.is_eq((q .&. 1 : U32), 0), q) 1228 1229 def 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 1236 def blk.n(+n: U32) -> U32: 1237 blk.at(U32.is_lt(blk.up(n), 54), blk.up(n)) 1238 1239 def enc.need(+n: U32) -> U32: 1240 (blk.n(n) * 32 : U32) 1241 1242 def 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 1249 def enc.extra(+have: U32, +need: U32) -> U32: 1250 enc.zero(U32.is_le(have, need), have, need) 1251 1252 def side.priv(+ch: U32) -> U32: 1253 match ch: 1254 case 1: 1255 5 1256 case _: 1257 3 1258 1259 def 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 1262 def 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 1265 def 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 1268 def side.end(st: Bw) -> Bw: 1269 bw.field(1n, bw.field(1n, bw.field(1n, st, 0), 0), 0) 1270 1271 def 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 1276 def 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 1283 def side.bytes(gs: List<&2, Gr>, +ch: U32) -> List<&2, U32>: 1284 bw.bytes(side.grs(gs, side.head(bw.empty(), ch))) 1285 1286 def 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 1293 def body.one(g: Gr, st: Bw) -> Bw: 1294 match g: 1295 case Gr{_part, _big, _gain, _tab, bits}: 1296 body.bits(bits, st) 1297 1298 def 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 1305 def 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 1309 def 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 1312 def 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. 1317 def 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 1322 def pulse.clamp(small: Bool, +w: U32) -> U32: 1323 match small: 1324 case True{}: 1325 w 1326 case False{}: 1327 15 1328 1329 def 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 1336 def pulse.mag(+w: U32) -> U32: 1337 pulse.mag0(U32.is_eq(w, 0), w) 1338 1339 def 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 1342 def 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 1351 def 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 1358 def pk.have(done: Bool, +have: U32) -> U32: 1359 match done: 1360 case True{}: 1361 0 1362 case False{}: 1363 (have + 1 : U32) 1364 1365 def 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 1374 def 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 1386 def 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 1393 def 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 1397 def enc.chgr(xs: List<&2, F32>, +hz: U32, +bud: U32) -> List<&2, Gr>: 1398 pk.chan(ch.specs(enc.grow(xs)), hz, bud, []) 1399 1400 def 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 1407 def 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 1414 def 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 1422 type Chs is Data: 1423 Chs{l: List<&2, F32>, r: List<&2, F32>} 1424 1425 def split.rev(c: Chs) -> Chs: 1426 match c: 1427 case Chs{l, r}: 1428 Chs{f.rev(l), f.rev(r)} 1429 1430 def 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 1437 def 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 1442 def split.flip(z: Bool) -> U32: 1443 match z: 1444 case True{}: 1445 1 1446 case False{}: 1447 0 1448 1449 def 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 1456 def split.next(+ch: U32, +phase: U32) -> U32: 1457 split.ph(U32.is_eq(ch, 1), phase) 1458 1459 def 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 1466 def 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 1473 def 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 1476 def 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 1480 def 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 1489 def 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 1496 def 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 1499 def 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 1502 def 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 1507 def enc.kind(+k: U32) -> Bool: 1508 match k: 1509 case 1: 1510 True{} 1511 case 3: 1512 True{} 1513 case _: 1514 False{} 1515 1516 def 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 1519 def 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 1528 def 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)