~/bend-docscommunity

mp3_dec.bend checks

raw source on the hub · import 0x9137a47f23b329cb0d636ed271d4bfb2/mp3_dec.bend as Mp3_dec

MPEG-1 Layer III decoder. Long blocks, no bit reservoir. Layer I and II never reach here.

4 imports
import Base
import ./mp3_tab.bend as Tab
import ./mp3_enc.bend as Enc
import ./mp3_syn.bend as Syn

Types

type Tk source · line 34 · raw

Data

value plus the bits not consumed

type Bt source · line 78 · raw

Data

taken bits, in order, and the tail

type Gd source · line 94 · raw

Data

one granule channel, long blocks only. block 0 is long.

type Lib source · line 106 · raw

Data

tables shared by a frame

type Nd source · line 205 · raw

Data

Huffman node: leaf still packed, bits not yet flushed. done is 1 once the leaf is terminal.

type Sm source · line 290 · raw

Data

one decoded sample and the bits after it. leaf is the remaining nibble.

type Pr source · line 332 · raw

Data

two samples from one Huffman code

type Hs source · line 395 · raw

Data

spectrum walker: pairs left in this band, region, bands still to come in the region

type Op source · line 613 · raw

Data

main_data_begin and the bits after the side-info preamble

type Sd source · line 634 · raw

Data

channels read so far

type Gs source · line 655 · raw

Data

granule channels, in order, and the main-data bits

type Chs source · line 680 · raw

Data

one granule's channels flattened, and what remains

type Gr source · line 702 · raw

Data

PCM words, overlap, delay, and the unread side of the frame

type Out source · line 728 · raw

Data

one frame of PCM and the state to carry, including the shared tables

Definitions

def u.nth source · line 7 · raw

@xs:List<&2, U32> -> @+ii:U32 -> U32

def f.word source · line 10 · raw

@x:F32 -> U32

def se.or source · line 13 · raw

@neg:Bool -> @+w:U32 -> U32

def se.u16 source · line 20 · raw

@+w:U32 -> U32

def asr.fill source · line 23 · raw

@neg:Bool -> @+v:U32 -> U32

def asr.u3 source · line 30 · raw

@+w:U32 -> U32

def tk.go source · line 37 · raw

@hop:Nat -> @xs:List<&2, U32> -> @+acc:U32 -> Tk

def tk.drop source · line 46 · raw

@hop:Nat -> @xs:List<&2, U32> -> List<&2, U32>

def tk.v source · line 55 · raw

@t:Tk -> U32

def peek.at source · line 60 · raw

@+bits:List<&2, U32> -> @+n:U32 -> U32

def bits.pref source · line 63 · raw

@hop:Nat -> @+w:U32 -> @rest:List<&2, U32> -> List<&2, U32>

def bits.of source · line 70 · raw

@xs:List<&2, U32> -> List<&2, U32>

def bt.go source · line 81 · raw

@hop:Nat -> @xs:List<&2, U32> -> @acc:List<&2, U32> -> Bt

def bt.skip source · line 90 · raw

@hop:Nat -> @xs:List<&2, U32> -> List<&2, U32>

def gd.long source · line 100 · raw

@g:Gd -> Bool

def lib.of source · line 109 · raw

Lib

def lib.huff source · line 112 · raw

@l:Lib -> List<&2, U32>

def lib.ix source · line 117 · raw

@l:Lib -> List<&2, U32>

def lib.lin source · line 122 · raw

@l:Lib -> List<&2, U32>

def lib.pow source · line 127 · raw

@l:Lib -> List<&2, U32>

def rd.u source · line 132 · raw

@t:Tk -> U32

def rd.xs source · line 135 · raw

@t:Tk -> List<&2, U32>

def rd.n source · line 140 · raw

@bits:List<&2, U32> -> @+n:U32 -> Tk

def side.skip source · line 143 · raw

@bits:List<&2, U32> -> @+n:U32 -> List<&2, U32>

def side.tail source · line 146 · raw

@+part:U32 -> @+big:U32 -> @+gain:U32 -> @+comp:U32 -> @+t0:U32 -> @+t1:U32 -> @+t2:U32 -> @+r0:U32 -> @+r1:U32 -> @tail:Tk -> Pair(Gd, List<&2, U32>)

def side.r1 source · line 155 · raw

@+part:U32 -> @+big:U32 -> @+gain:U32 -> @+comp:U32 -> @+tabs:U32 -> @+r0:U32 -> @+r1:Tk -> Pair(Gd, List<&2, U32>)

def side.r0 source · line 161 · raw

@+part:U32 -> @+big:U32 -> @+gain:U32 -> @+comp:U32 -> @+tabs:U32 -> @+r0:Tk -> Pair(Gd, List<&2, U32>)

def side.long source · line 166 · raw

@+part:U32 -> @+big:U32 -> @+gain:U32 -> @+comp:U32 -> @+tabs:Tk -> Pair(Gd, List<&2, U32>)

def side.sw source · line 169 · raw

@longb:Bool -> @+part:U32 -> @+big:U32 -> @+gain:U32 -> @+comp:U32 -> @bits:List<&2, U32> -> Pair(Gd, List<&2, U32>)

def side.bit source · line 178 · raw

@+part:U32 -> @+big:U32 -> @+gain:U32 -> @+comp:U32 -> @+win:Tk -> Pair(Gd, List<&2, U32>)

def side.comp source · line 181 · raw

@+part:U32 -> @+big:U32 -> @+gain:U32 -> @+comp:Tk -> Pair(Gd, List<&2, U32>)

def side.gain source · line 184 · raw

@+part:U32 -> @+big:U32 -> @+gain:Tk -> Pair(Gd, List<&2, U32>)

def side.win source · line 187 · raw

@part:Tk -> @+big:Tk -> Pair(Gd, List<&2, U32>)

def side.ch source · line 191 · raw

@+bits:List<&2, U32> -> Pair(Gd, List<&2, U32>)

side info for one granule channel. Short blocks set block to 2.

def side.pair source · line 194 · raw

@got:Pair(Gd, List<&2, U32>) -> List<&2, U32>

def side.gd source · line 199 · raw

@got:Pair(Gd, List<&2, U32>) -> Gd

def hf.idx source · line 208 · raw

@+book:U32 -> @+pk:U32 -> @+leaf:U32 -> U32

def hf.hold source · line 211 · raw

@+leaf:U32 -> @bits:List<&2, U32> -> @+w:U32 -> Nd

def hf.dive source · line 214 · raw

@+leaf:U32 -> @+bits:List<&2, U32> -> @+w:U32 -> @+book:U32 -> @+huff:List<&2, U32> -> Nd

def hf.next source · line 218 · raw

@stop:Bool -> @+leaf:U32 -> @+bits:List<&2, U32> -> @+w:U32 -> @+book:U32 -> @+huff:List<&2, U32> -> Nd

def hf.step source · line 225 · raw

@st:Nd -> @+book:U32 -> @+huff:List<&2, U32> -> Nd

def hf.node source · line 230 · raw

@hop:Nat -> @st:Nd -> @+book:U32 -> @+huff:List<&2, U32> -> Nd

def hf.open source · line 237 · raw

@+bits:List<&2, U32> -> @+book:U32 -> @+huff:List<&2, U32> -> Nd

def pw.f source · line 240 · raw

@+low:U32 -> @+sign:U32 -> @+x:U32 -> F32

def pw.poly source · line 244 · raw

@+low:U32 -> @+sign:U32 -> @+x:U32 -> F32

def pw.out source · line 247 · raw

@+x:U32 -> @+low:U32 -> @+idx:U32 -> @+sign:U32 -> @+pows:List<&2, U32> -> @+mult:F32 -> F32

def pw.apply source · line 252 · raw

@+x:U32 -> @+pows:List<&2, U32> -> @+mult:F32 -> F32

def pw.shift source · line 256 · raw

@mid:Bool -> @+x:U32 -> U32

def pw.mult source · line 263 · raw

@mid:Bool -> F32

def pw.mul source · line 270 · raw

@+mid:Bool -> @+x:U32 -> @+pows:List<&2, U32> -> F32

def pw.wide source · line 273 · raw

@mid:Bool -> @+x:U32 -> @+pows:List<&2, U32> -> F32

def pw.pick source · line 276 · raw

@small:Bool -> @+x:U32 -> @+pows:List<&2, U32> -> F32

def pw.of source · line 283 · raw

@+x:U32 -> @+pows:List<&2, U32> -> F32

def pw.tab source · line 286 · raw

@+lsb:U32 -> @+sgn:U32 -> @+pows:List<&2, U32> -> F32

def sm.sgn source · line 293 · raw

@+t:Tk -> @+lsb:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Sm

def sm.plain source · line 296 · raw

@zero:Bool -> @bits:List<&2, U32> -> @+lsb:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Sm

def sm.neg2 source · line 305 · raw

@neg:Bool -> @+mag:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> @bits:List<&2, U32> -> Sm

def sm.neg source · line 312 · raw

@+t:Tk -> @+mag:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Sm

def sm.extra source · line 315 · raw

@+t:Tk -> @+lsb:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Sm

def sm.lin source · line 318 · raw

@use:Bool -> @bits:List<&2, U32> -> @+lin:U32 -> @+lsb:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Sm

def hf.sym source · line 325 · raw

@bits:List<&2, U32> -> @+leaf:U32 -> @+lin:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Sm

def hf.shift source · line 328 · raw

@+leaf:U32 -> U32

def hf.both source · line 335 · raw

@+a:F32 -> @s:Sm -> Pr

def hf.second source · line 340 · raw

@+leaf:U32 -> @s:Sm -> @+lin:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Pr

def hf.rest source · line 345 · raw

@+leaf:U32 -> @t:Tk -> @+lin:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Pr

def hf.code source · line 348 · raw

@nd:Nd -> @+lin:U32 -> @+gain:F32 -> @+pows:List<&2, U32> -> Pr

def hf.pair source · line 353 · raw

@bits:List<&2, U32> -> @+tab:U32 -> @+lin:U32 -> @+gain:F32 -> @+huff:List<&2, U32> -> @+ixs:List<&2, U32> -> @+pows:List<&2, U32> -> Pr

def dec.s0 source · line 359 · raw

@p:Pr -> F32

def hf.from source · line 364 · raw

@lib:Lib -> @bits:List<&2, U32> -> @+t0:U32 -> @+gain:F32 -> Pr

def dec.when source · line 369 · raw

@ok:Bool -> @+t0:U32 -> @+gain:U32 -> @bits:List<&2, U32> -> @lib:Lib -> F32

def dec.use source · line 376 · raw

@g:Gd -> @bits:List<&2, U32> -> @lib:Lib -> F32

def dec.gd source · line 382 · raw

@got:Pair(Gd, List<&2, U32>) -> @lib:Lib -> F32

def dec.top source · line 387 · raw

@bits:List<&2, U32> -> @lib:Lib -> F32

def dec.lead source · line 391 · raw

@xs:List<&2, U32> -> U32

first spectral sample of granule 0, for a single mono frame. 0 when the frame is not long-block.

def hs.w source · line 400 · raw

@+band:U32 -> @+scf:List<&2, U32> -> U32

def g.t0 source · line 403 · raw

@g:Gd -> U32

def g.t1 source · line 408 · raw

@g:Gd -> U32

def g.t2 source · line 413 · raw

@g:Gd -> U32

def g.r0 source · line 418 · raw

@g:Gd -> U32

def g.r1 source · line 423 · raw

@g:Gd -> U32

def hs.tab source · line 428 · raw

@+reg:U32 -> @+g:Gd -> U32

def hs.put source · line 437 · raw

@spec:List<&2, F32> -> @+at:U32 -> @+a:F32 -> @+b:F32 -> List<&2, F32>

def hs.open source · line 440 · raw

@reg:U32 -> @bits:List<&2, U32> -> @spec:List<&2, F32> -> @+at:U32 -> @+band:U32 -> @+cnt:U32 -> @+scf:List<&2, U32> -> Hs

def hs.flip source · line 451 · raw

@+reg:U32 -> @bits:List<&2, U32> -> @spec:List<&2, F32> -> @+at:U32 -> @+band:U32 -> @+g:Gd -> @+scf:List<&2, U32> -> Hs

def hs.region source · line 461 · raw

@endr:Bool -> @bits:List<&2, U32> -> @spec:List<&2, F32> -> @+at:U32 -> @+band:U32 -> @+reg:U32 -> @+cnt:U32 -> @+g:Gd -> @+scf:List<&2, U32> -> Hs

def hs.next source · line 471 · raw

@endb:Bool -> @bits:List<&2, U32> -> @spec:List<&2, F32> -> @+at:U32 -> @+band:U32 -> @+left:U32 -> @+reg:U32 -> @+cnt:U32 -> @+g:Gd -> @+scf:List<&2, U32> -> Hs

def lib.scf source · line 481 · raw

@l:Lib -> List<&2, U32>

def hs.place source · line 486 · raw

@p:Pr -> @spec:List<&2, F32> -> @+at:U32 -> @+band:U32 -> @+left:U32 -> @+reg:U32 -> @+cnt:U32 -> @+g:Gd -> @+lib:Lib -> Hs

def hs.step source · line 494 · raw

@st:Hs -> @+g:Gd -> @+gain:F32 -> @+lib:Lib -> Hs

def hs.go source · line 499 · raw

@hop:Nat -> @+g:Gd -> @+gain:F32 -> @+lib:Lib -> @st:Hs -> Hs

def hs.spec source · line 506 · raw

@st:Hs -> List<&2, F32>

def dec.full source · line 511 · raw

@+g:Gd -> @bits:List<&2, U32> -> @+lib:Lib -> List<&2, F32>

def dec.fold source · line 517 · raw

@xs:List<&2, F32> -> @+acc:U32 -> U32

def dec.frame source · line 524 · raw

@got:Pair(Gd, List<&2, U32>) -> @lib:Lib -> List<&2, F32>

def dec.sum source · line 529 · raw

@xs:List<&2, U32> -> U32

def g.part source · line 533 · raw

@g:Gd -> U32

part2_3_length of one granule channel

def gd.both source · line 539 · raw

@aa:Bool -> @bb:Bool -> Bool

long block, no scale-factor bits, big_values inside the 576 lines

def gd.u4 source · line 546 · raw

@ok:Bool -> @+big:U32 -> Bool

def gd.use source · line 553 · raw

@g:Gd -> Bool

def gs.ok source · line 560 · raw

@hop:Nat -> @gs:List<&2, Gd> -> @+ok:Bool -> Bool

every channel side-info block is a long block we can decode

def dec.spec source · line 570 · raw

@+g:Gd -> @bits:List<&2, U32> -> @+lib:Lib -> List<&2, F32>

Huffman of one channel. bits already sit on the channel's main data.

def bd.drop source · line 577 · raw

@hop:Nat -> @xs:List<&2, U32> -> List<&2, U32>

drop a prefix of a byte list

def bd.take source · line 587 · raw

@hop:Nat -> @xs:List<&2, U32> -> @acc:List<&2, U32> -> List<&2, U32>

take a prefix of a byte list

def scf.off source · line 597 · raw

@+hz:U32 -> U32

scale-factor band row. 44100 is 0, 48000 is 22, 32000 is 44.

def lib.use source · line 607 · raw

@l:Lib -> @+hz:U32 -> Lib

one sample-rate row of the scale-factor widths

def side.priv source · line 617 · raw

@+nch:U32 -> U32

private bits plus scfsi. mono is 5+4, stereo is 3+8.

def side.op source · line 624 · raw

@t:Tk -> @+nch:U32 -> Op

def side.open source · line 630 · raw

@bits:List<&2, U32> -> @+nch:U32 -> Op

9-bit main_data_begin, then the private bits and scfsi

def side.step2 source · line 637 · raw

@got:Pair(Gd, List<&2, U32>) -> @acc:List<&2, Gd> -> Sd

def side.step source · line 642 · raw

@st:Sd -> Sd

def side.nch source · line 647 · raw

@hop:Nat -> @st:Sd -> Sd

def gs.of source · line 658 · raw

@st:Sd -> Gs

def fr.n source · line 664 · raw

@+nch:U32 -> Nat

how many granule-channels a frame carries

def gr.n source · line 672 · raw

@+nch:U32 -> Nat

how many channels one granule carries

def chs.push source · line 683 · raw

@xs:List<&2, F32> -> @acc:List<&2, F32> -> List<&2, F32>

def chs.go source · line 690 · raw

@hop:Nat -> @gs:List<&2, Gd> -> @+bits:List<&2, U32> -> @+lib:Lib -> @spec:List<&2, F32> -> Chs

def pcm.bits source · line 705 · raw

@xs:List<&2, F32> -> @acc:List<&2, U32> -> List<&2, U32>

def gr.pack source · line 712 · raw

@pc:0x9137a47f23b329cb0d636ed271d4bfb2/mp3_syn.Pc -> @bits:List<&2, U32> -> @gs:List<&2, Gd> -> Gr

def gr.syn source · line 717 · raw

@cc:Chs -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+nch:U32 -> Gr

def gr.one source · line 722 · raw

@+gs:List<&2, Gd> -> @bits:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Gr

def dec.g3 source · line 731 · raw

@+pcm0:List<&2, U32> -> @g:Gr -> @+lib:Lib -> Maybe<&2, Out>

def dec.g2 source · line 736 · raw

@g:Gr -> @+nch:U32 -> @+lib:Lib -> Maybe<&2, Out>

def dec.grs source · line 741 · raw

@+gs:List<&2, Gd> -> @bits:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def dec.try source · line 746 · raw

@ok:Bool -> @+gs:List<&2, Gd> -> @bits:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def dec.got source · line 756 · raw

@gg:Gs -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def dec.beg source · line 761 · raw

@ok:Bool -> @bits:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def dec.open source · line 770 · raw

@op:Op -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def dec.live source · line 776 · raw

@+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

real synthesis, including a silent frame that still has to ring the delay line out

def pay.z source · line 782 · raw

@xs:List<&2, U32> -> Bool

payload after the 4-byte header is entirely zero

def dec.q2 source · line 791 · raw

@fresh:Bool -> @zero:Bool -> Bool

def dec.quiet source · line 798 · raw

@xs:List<&2, U32> -> @+fresh:U32 -> Bool

def dec.zpcm source · line 802 · raw

@+nch:U32 -> List<&2, U32>

1152 samples per channel, as zero words

def yn.both source · line 805 · raw

@aa:Bool -> @bb:Bool -> Bool

def g0.yes source · line 813 · raw

@g:Gd -> Bool

granule 0 of the integer pair: one big_value, gain 0, long block

def g1.yes source · line 819 · raw

@g:Gd -> Bool

def gs.two source · line 824 · raw

@gs:List<&2, Gd> -> Bool

def gs.mono source · line 831 · raw

@mono:Bool -> @gs:List<&2, Gd> -> Bool

def gs.hd source · line 838 · raw

@gs:List<&2, Gd> -> Gd

def nd.tab source · line 845 · raw

@g:Gd -> @bits:List<&2, U32> -> @+huff:List<&2, U32> -> @+ix:List<&2, U32> -> Nd

def nd.open source · line 852 · raw

@g:Gd -> @bits:List<&2, U32> -> @lib:Lib -> Nd

def pair.word source · line 858 · raw

@+leaf:U32 -> List<&2, U32>

the two Huffman magnitudes, then the rest of the 1152 mono words

def pair.try source · line 862 · raw

@nd:Nd -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def seek.arm source · line 869 · raw

@yes:Bool -> @gs:List<&2, Gd> -> @bits:List<&2, U32> -> @+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def seek.gs source · line 885 · raw

@gg:Gs -> @+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def seek.beg source · line 897 · raw

@ok:Bool -> @bits:List<&2, U32> -> @+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def seek.op source · line 912 · raw

@op:Op -> @+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def dec.seek source · line 925 · raw

@+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

gain 0 and one big_value: read the Huffman pair, skip the filterbank

def dec.alt source · line 930 · raw

@silent:Bool -> @+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+lib:Lib -> Maybe<&2, Out>

def dec.step source · line 942 · raw

@+frame:List<&2, U32> -> @+nch:U32 -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+fresh:U32 -> @+lib:Lib -> Maybe<&2, Out>

one MPEG-1 Layer III frame. fresh 1 and an all-zero payload skip the filterbank. A mono granule with big_values 1 and global_gain 0 returns that Huffman pair. lib is already the scale-factor row for this sampling frequency.

def dec.qmf source · line 948 · raw

List<&2, F32>

zero polyphase delay

def dec.ov source · line 952 · raw

@+nch:U32 -> List<&2, F32>

zero overlap for one or two channels

def dec.aud source · line 960 · raw

@+frame:List<&2, U32> -> @+nch:U32 -> @+hz:U32 -> Maybe<&2, Out>

one frame from a cold decoder, for a compiled check

def out.nth source · line 963 · raw

@m:Maybe<&2, U32> -> U32

def out.at source · line 970 · raw

@o:Out -> @+ii:U32 -> U32

def aud.at source · line 975 · raw

@m:Maybe<&2, Out> -> @+ii:U32 -> U32

def aud.mix source · line 983 · raw

@m:Maybe<&2, Out> -> U32

samples 1, 7, and 200, mixed, so one compiled run checks the granule