~/bend-docscommunity

src/mp3_syn.bend checks

raw source on the hub · import 0xd2dab0fbc9db2e9ba3da65dae724eb41/src/mp3_syn.bend as Mp3_syn

MPEG-1 Layer III synthesis: antialias, IMDCT-36, sign flip, DCT-II, polyphase.

3 imports
import Base
import ./mp3_tab.bend as Tab
import ./mp3_enc.bend as Enc

Types

type D9 source · line 246 · raw

Data

even and odd 9-point DCT results, ready to interleave

type Wn source · line 284 · raw

Data

one windowed band: 18 time samples and 9 new overlap samples

type Ws source · line 288 · raw

Data

window product and the overlap it saves

type Dx source · line 328 · raw

Type

one F32 read from the IMDCT/DCT spectrum Array

type Il source · line 339 · raw

Type

spectrum Array beside the samples just read

type Im source · line 365 · raw

Type

576 lines in the spectrum Array, and 288 overlap samples

type Ia source · line 405 · raw

Type

spectrum Array beside the two aliasing samples

type Q4 source · line 491 · raw

Data

four DCT-II column results

type Dq source · line 519 · raw

Type

spectrum Array beside one finished column

type Dr source · line 555 · raw

Type

spectrum Array beside the 4 by 8 working rows

type E8 source · line 573 · raw

Data

eight floats carried through the DCT-II row butterfly

type Sv source · line 648 · raw

Type

seven samples of one scatter column, row-major

type Sc source · line 698 · raw

Type

spectrum Array beside the rows Array

type Sf source · line 733 · raw

Type

row 0, 1, 2 and 3 of column 7

type La source · line 808 · raw

Type

one F32 read from the polyphase delay Array

type Mac source · line 843 · raw

Data

four running polyphase sums, a and b

type Mk source · line 847 · raw

Type

MAC state plus the delay line handle mac.* only reads

type Sw source · line 931 · raw

Type

one window coefficient handed back beside the table Array.get just read

type Mw source · line 946 · raw

Type

MAC state plus the window table the next load still reads

type Ga source · line 1011 · raw

Type

one F32 read from the post-DCT granule Array

type Lg source · line 1022 · raw

Type

delay line handed back beside the granule Array a write just read

type Pp source · line 1378 · raw

Type

PCM and delay line while pairing synth samples

type Sb source · line 1404 · raw

Type

delay line and the PCM written so far

type Bg source · line 1417 · raw

Type

polyphase state, the granule Array the rows still read, and the window table

type Sr source · line 1435 · raw

Type

a finished row, with the window table the next row still reads

type Pc source · line 1526 · raw

Data

PCM, the overlap to carry, and the polyphase delay

Definitions

def f.add source · line 7 · raw

@+aa:F32 -> @+bb:F32 -> F32

add two binary32 values

def f.sub source · line 11 · raw

@+aa:F32 -> @+bb:F32 -> F32

subtract two binary32 values

def f.mul source · line 15 · raw

@+aa:F32 -> @+bb:F32 -> F32

multiply two binary32 values

def f.at source · line 19 · raw

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

sample at an index, or 0 past the end

def f.set source · line 23 · raw

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

replace one sample

def u.add source · line 27 · raw

@+aa:U32 -> @+bb:U32 -> U32

unsigned add

def u.sub source · line 31 · raw

@+aa:U32 -> @+bb:U32 -> U32

unsigned subtract

def u.mul source · line 35 · raw

@+aa:U32 -> @+bb:U32 -> U32

unsigned multiply

def u.and source · line 39 · raw

@+kk:U32 -> U32

low bit

def c.half source · line 43 · raw

F32

0.5

def c.c939 source · line 47 · raw

F32

0.93969262

def c.c766 source · line 51 · raw

F32

0.76604444

def c.c173 source · line 55 · raw

F32

0.17364818

def c.c866 source · line 59 · raw

F32

0.86602540

def c.c984 source · line 63 · raw

F32

0.98480775

def c.c342 source · line 67 · raw

F32

0.34202014

def c.c642 source · line 71 · raw

F32

0.64278761

def c.c707 source · line 75 · raw

F32

0.70710677

def c.c198 source · line 79 · raw

F32

0.198912367

def c.c382 source · line 83 · raw

F32

0.382683432

def c.c509 source · line 87 · raw

F32

0.50979561

def c.c541 source · line 91 · raw

F32

0.54119611

def c.c601 source · line 95 · raw

F32

0.60134488

def c.c899 source · line 99 · raw

F32

0.89997619

def c.c130 source · line 103 · raw

F32

1.30656302

def c.c256 source · line 107 · raw

F32

2.56291556

def c.inv source · line 111 · raw

F32

1/32768, the polyphase scale

def ls.drop source · line 115 · raw

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

drop a prefix

def ls.take source · line 125 · raw

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

take a prefix, reversed into acc

def ls.slice source · line 135 · raw

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

a slice of length hop starting at an index

def ls.poke source · line 139 · raw

@hop:Nat -> @dst:List<&2, F32> -> @src:List<&2, F32> -> @+at:U32 -> List<&2, F32>

write a short list over a destination starting at an index

def cs.pack source · line 149 · raw

@+v0:F32 -> @+v1:F32 -> @+v2:F32 -> @+v3:F32 -> @+v4:F32 -> @+v5:F32 -> @+v6:F32 -> @+v7:F32 -> @+v8:F32 -> List<&2, F32>

nine samples, index 0 first

def cs.co source · line 155 · raw

@+gg:List<&2, F32> -> List<&2, F32>

cosine half of one IMDCT-36 band

def cs.si source · line 163 · raw

@+gg:List<&2, F32> -> List<&2, F32>

sine half of one IMDCT-36 band

def d9.t0 source · line 170 · raw

@+y0:F32 -> @+y6:F32 -> F32

even-part sum used by the 9-point DCT

def d9.s0 source · line 174 · raw

@+y0:F32 -> @+y6:F32 -> F32

even-part difference

def d9.t4 source · line 178 · raw

@+y4:F32 -> @+y2:F32 -> F32

twiddle on bins 4 and 2

def d9.t2 source · line 182 · raw

@+y8:F32 -> @+y2:F32 -> F32

twiddle on bins 8 and 2

def d9.s6 source · line 186 · raw

@+y4:F32 -> @+y8:F32 -> F32

twiddle on bins 4 and 8

def d9.s4 source · line 190 · raw

@+y4:F32 -> @+y8:F32 -> @+y2:F32 -> F32

even residual

def d9.s2 source · line 194 · raw

@+s0:F32 -> @+s4:F32 -> F32

scaled residual

def d9.y4 source · line 198 · raw

@+s4:F32 -> @+s0:F32 -> F32

centre bin of the even DCT

def d9.s8c source · line 202 · raw

@+t0:F32 -> @+t2:F32 -> @+s6:F32 -> F32

high even output

def d9.s0c source · line 206 · raw

@+t0:F32 -> @+t4:F32 -> @+t2:F32 -> F32

low even output

def d9.s4c source · line 210 · raw

@+t0:F32 -> @+t4:F32 -> @+s6:F32 -> F32

mid even output

def d9.s3 source · line 214 · raw

@+y3:F32 -> F32

odd centre

def d9.tb0 source · line 218 · raw

@+y5:F32 -> @+y1:F32 -> F32

odd low twiddle

def d9.tb4 source · line 222 · raw

@+y5:F32 -> @+y7:F32 -> F32

odd high twiddle

def d9.tb2 source · line 226 · raw

@+y1:F32 -> @+y7:F32 -> F32

odd mid twiddle

def d9.s1 source · line 230 · raw

@+y1:F32 -> @+y5:F32 -> @+y7:F32 -> F32

odd residual

def d9.s5c source · line 234 · raw

@+t0:F32 -> @+s3:F32 -> @+t2:F32 -> F32

odd combination

def d9.s7c source · line 238 · raw

@+t4:F32 -> @+s3:F32 -> @+t0:F32 -> F32

odd combination

def d9.s3c source · line 242 · raw

@+t4:F32 -> @+s3:F32 -> @+t2:F32 -> F32

odd combination

def d9.from source · line 252 · raw

@+t0:F32 -> @+s0:F32 -> @+t4:F32 -> @+t2:F32 -> @+s6:F32 -> @+s4:F32 -> @+s3:F32 -> @+u0:F32 -> @+u4:F32 -> @+u2:F32 -> @+s1:F32 -> D9

assemble the nine DCT outputs from the even and odd parts

def d9.build source · line 260 · raw

@+y0:F32 -> @+y1:F32 -> @+y2:F32 -> @+y3:F32 -> @+y4:F32 -> @+y5:F32 -> @+y6:F32 -> @+y7:F32 -> @+y8:F32 -> D9

9-point DCT of one half

def d9.list source · line 267 · raw

@dd:D9 -> List<&2, F32>

nine DCT outputs in bin order

def d9.run source · line 274 · raw

@+ys:List<&2, F32> -> List<&2, F32>

9-point DCT

def d9.neg source · line 279 · raw

@+ys:List<&2, F32> -> List<&2, F32>

negate the odd bins of a sine DCT

def wn.pair source · line 292 · raw

@+co:List<&2, F32> -> @+si:List<&2, F32> -> @+tw:List<&2, F32> -> @+ii:U32 -> Ws

aliasing pair for one window index

def wn.put source · line 297 · raw

@st:Wn -> @+ov:List<&2, F32> -> @+win:List<&2, F32> -> @+ii:U32 -> @ws:Ws -> Wn

write one window index into the band

def wn.one source · line 305 · raw

@st:Wn -> @+co:List<&2, F32> -> @+si:List<&2, F32> -> @+ov:List<&2, F32> -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> @+ii:U32 -> Wn

one of the nine window steps

def wn.go source · line 312 · raw

@hop:Nat -> @st:Wn -> @+co:List<&2, F32> -> @+si:List<&2, F32> -> @+ov:List<&2, F32> -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> @+ii:U32 -> Wn

window all nine indices

def im.band source · line 323 · raw

@+gg:List<&2, F32> -> @+ov:List<&2, F32> -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> Wn

IMDCT-36 of one 18-point band

def dx.of source · line 331 · raw

@got:Pair(Array<F32>, F32) -> Dx

def dx.at source · line 335 · raw

@acc:Array<F32> -> @+ii:U32 -> Dx

def ix.pull source · line 343 · raw

@hop:Nat -> @got:Dx -> @+ii:U32 -> @ys:List<&2, F32> -> Il

pull one sample; hop is remaining after this read

def ix.take source · line 351 · raw

@acc:Array<F32> -> @+at:U32 -> @hop:Nat -> Il

hop+1 samples starting at at. The spectrum Array is handed back.

def ix.poke source · line 355 · raw

@hop:Nat -> @acc:Array<F32> -> @src:List<&2, F32> -> @+at:U32 -> Array<F32>

write a short list into the spectrum Array

def im.store source · line 369 · raw

@buf:Array<F32> -> @+ov:List<&2, F32> -> @ww:Wn -> @+jj:U32 -> @+base:U32 -> Im

write one band back into the spectrum Array and the overlap

def im.got source · line 375 · raw

@got:Il -> @+ov:List<&2, F32> -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> @+jj:U32 -> @+base:U32 -> Im

band samples in hand; window them and store

def im.one source · line 383 · raw

@st:Im -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> @+jj:U32 -> @+base:U32 -> Im

IMDCT-36 of band jj. Each of the 18 samples is an Array.get.

def im.go source · line 389 · raw

@hop:Nat -> @st:Im -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> @+jj:U32 -> @+base:U32 -> Im

IMDCT-36 over 32 bands. base is the channel offset in the spectrum Array.

def aa.ixh source · line 397 · raw

@+base:U32 -> @+bb:U32 -> @+ii:U32 -> U32

high index of one aliasing pair

def aa.ixl source · line 401 · raw

@+base:U32 -> @+bb:U32 -> @+ii:U32 -> U32

low index of one aliasing pair

def aa.lo source · line 409 · raw

@got:Dx -> @+up:F32 -> Ia

low sample, then both indices are in hand

def aa.rd1 source · line 415 · raw

@got:Dx -> @+lo:U32 -> Ia

high sample in hand; read the low sample next

def aa.rd source · line 421 · raw

@acc:Array<F32> -> @+hi:U32 -> @+lo:U32 -> Ia

read both samples of one aliasing pair. Each read is an Array.get.

def aa.wr source · line 425 · raw

@acc:Array<F32> -> @+up:F32 -> @+dp:F32 -> @+c0:F32 -> @+c1:F32 -> @+hi:U32 -> @+lo:U32 -> Array<F32>

butterfly of one aliasing pair. c0 and c1 are the two cosine rows.

def aa.use source · line 432 · raw

@got:Ia -> @+c0:F32 -> @+c1:F32 -> @+hi:U32 -> @+lo:U32 -> Array<F32>

write the pair once both samples have been read

def aa.one source · line 438 · raw

@acc:Array<F32> -> @+aa:List<&2, F32> -> @+bb:U32 -> @+ii:U32 -> @+base:U32 -> Array<F32>

one butterfly at index ii of band bb

def aa.i source · line 443 · raw

@hop:Nat -> @acc:Array<F32> -> @+aa:List<&2, F32> -> @+bb:U32 -> @+ii:U32 -> @+base:U32 -> Array<F32>

eight butterflies between band bb and the next

def aa.b source · line 451 · raw

@hop:Nat -> @acc:Array<F32> -> @+aa:List<&2, F32> -> @+bb:U32 -> @+base:U32 -> Array<F32>

antialias from low bands toward high bands

def aa.run source · line 459 · raw

@acc:Array<F32> -> @+aa:List<&2, F32> -> @+base:U32 -> Array<F32>

31 long-block aliasing pairs. base is the channel offset in the spectrum Array.

def sg.neg source · line 463 · raw

@got:Dx -> @+at:U32 -> Array<F32>

negate the sample just read

def sg.i source · line 469 · raw

@hop:Nat -> @acc:Array<F32> -> @+base:U32 -> @+ii:U32 -> Array<F32>

negate one odd sample of an odd band

def sg.b source · line 477 · raw

@hop:Nat -> @acc:Array<F32> -> @+base:U32 -> Array<F32>

odd samples of 16 odd bands, starting at sample 18

def im.sign source · line 485 · raw

@st:Im -> @+base:U32 -> Im

frequency inversion after the IMDCT. base is the channel offset.

def dc.x0 source · line 495 · raw

@acc:Array<F32> -> @+kk:U32 -> @+ii:U32 -> Dx

column sample i of the 32-band vector

def dc.x1 source · line 499 · raw

@acc:Array<F32> -> @+kk:U32 -> @+ii:U32 -> Dx

mirrored column

def dc.x2 source · line 503 · raw

@acc:Array<F32> -> @+kk:U32 -> @+ii:U32 -> Dx

upper column

def dc.x3 source · line 507 · raw

@acc:Array<F32> -> @+kk:U32 -> @+ii:U32 -> Dx

upper mirror

def dc.q2 source · line 511 · raw

@+t0:F32 -> @+t1:F32 -> @+t2:F32 -> @+t3:F32 -> @+s2:F32 -> Q4

finish the column butterfly

def dc.q source · line 515 · raw

@+x0:F32 -> @+x1:F32 -> @+x2:F32 -> @+x3:F32 -> @+s0:F32 -> @+s1:F32 -> @+s2:F32 -> Q4

one DCT-II column from four samples and three secants

def dc.rd3 source · line 523 · raw

@got:Dx -> @+x0:F32 -> @+x1:F32 -> @+x2:F32 -> @+s0:F32 -> @+s1:F32 -> @+s2:F32 -> Dq

fourth sample, then the column butterfly

def dc.rd2 source · line 529 · raw

@got:Dx -> @+sec:List<&2, F32> -> @+kk:U32 -> @+ii:U32 -> @+x0:F32 -> @+x1:F32 -> Dq

third sample and the three secants

def dc.rd1 source · line 536 · raw

@got:Dx -> @+sec:List<&2, F32> -> @+kk:U32 -> @+ii:U32 -> @+x0:F32 -> Dq

second sample

def dc.cell source · line 542 · raw

@got:Dx -> @+sec:List<&2, F32> -> @+kk:U32 -> @+ii:U32 -> Dq

read column ii. Each of the four samples is an Array.get.

def dc.store source · line 548 · raw

@xs:Array<F32> -> @qq:Q4 -> @+ii:U32 -> Array<F32>

store one column into the 4 by 8 working Array

def dc.stored source · line 559 · raw

@got:Dq -> @xs:Array<F32> -> @+ii:U32 -> Dr

write one gathered column and keep both Arrays

def dc.cols source · line 565 · raw

@hop:Nat -> @got:Dr -> @+sec:List<&2, F32> -> @+kk:U32 -> @+ii:U32 -> Dr

gather all eight columns before any write-back

def but.sum2 source · line 577 · raw

@+xt:F32 -> @+y0:F32 -> @+y7:F32 -> @+y1:F32 -> @+y6:F32 -> @+y2:F32 -> @+y5:F32 -> @+y3:F32 -> E8

finish the first stage

def but.sum source · line 583 · raw

@+x0:F32 -> @+x1:F32 -> @+x2:F32 -> @+x3:F32 -> @+x4:F32 -> @+x5:F32 -> @+x6:F32 -> @+x7:F32 -> E8

first add/sub stage of a DCT-II row

def but.mid source · line 588 · raw

@ee:E8 -> E8

second stage: the 45-degree rotations

def but.rot3 source · line 595 · raw

@+o0:F32 -> @+w3:F32 -> @+w6:F32 -> @+y4:F32 -> @+o4:F32 -> @+p5:F32 -> @+p7:F32 -> @+xt:F32 -> E8

last rotation update

def but.rot2 source · line 601 · raw

@+o0:F32 -> @+w3:F32 -> @+w6:F32 -> @+y4:F32 -> @+o4:F32 -> @+p5:F32 -> @+w7:F32 -> @+xt:F32 -> E8

complete the rotation

def but.rot source · line 607 · raw

@ee:E8 -> E8

third stage: the small-angle rotation, using the updated values

def but.end source · line 613 · raw

@ee:E8 -> List<&2, F32>

eight row outputs

def but.out source · line 621 · raw

@ee:E8 -> List<&2, F32>

cs.pack takes 9; the row is 8. Drop the padding below.

def but.sum8 source · line 625 · raw

@acc:Array<F32> -> @+ys:List<&2, F32> -> @+base:U32 -> Array<F32>

butterfly the eight samples and write the row back

def but.use source · line 630 · raw

@got:Il -> @+base:U32 -> Array<F32>

butterfly one row. The eight inputs are one slice of the working Array.

def but.row source · line 636 · raw

@xs:Array<F32> -> @+base:U32 -> Array<F32>

butterfly one row of eight and write it back

def dc.fly source · line 640 · raw

@hop:Nat -> @xs:Array<F32> -> @+base:U32 -> Array<F32>

butterfly all four rows

def sc.v6 source · line 652 · raw

@got:Dx -> @+r0:F32 -> @+r1:F32 -> @+r1n:F32 -> @+r2:F32 -> @+r2n:F32 -> @+r3:F32 -> Sv

row 3, column ii+1

def sc.v5 source · line 658 · raw

@got:Dx -> @+ii:U32 -> @+r0:F32 -> @+r1:F32 -> @+r1n:F32 -> @+r2:F32 -> @+r2n:F32 -> Sv

row 3, column ii

def sc.v4 source · line 664 · raw

@got:Dx -> @+ii:U32 -> @+r0:F32 -> @+r1:F32 -> @+r1n:F32 -> @+r2:F32 -> Sv

row 2, column ii+1

def sc.v3 source · line 670 · raw

@got:Dx -> @+ii:U32 -> @+r0:F32 -> @+r1:F32 -> @+r1n:F32 -> Sv

row 2, column ii

def sc.v2 source · line 676 · raw

@got:Dx -> @+ii:U32 -> @+r0:F32 -> @+r1:F32 -> Sv

row 1, column ii+1

def sc.v1 source · line 682 · raw

@got:Dx -> @+ii:U32 -> @+r0:F32 -> Sv

row 1, column ii

def sc.v0 source · line 688 · raw

@got:Dx -> @+ii:U32 -> Sv

row 0, column ii, then the six neighbour slots

def sc.vals source · line 694 · raw

@xs:Array<F32> -> @+ii:U32 -> Sv

the seven samples of column ii, each an Array.get

def sc.bands source · line 702 · raw

@+p0:F32 -> @+p1:F32 -> @+p2:F32 -> @+p3:F32 -> @+p4:F32 -> @+p5:F32 -> @+p6:F32 -> Q4

four band values from the seven column samples

def sc.put4 source · line 708 · raw

@xs:Array<F32> -> @acc:Array<F32> -> @qq:Q4 -> @+yy:U32 -> Sc

store the four bands and hand both Arrays back

def sc.put source · line 715 · raw

@got:Sv -> @acc:Array<F32> -> @+yy:U32 -> Sc

write one scatter group from the seven samples

def sc.one source · line 721 · raw

@acc:Array<F32> -> @xs:Array<F32> -> @+yy:U32 -> @+ii:U32 -> Sc

scatter one group of four bands into the spectrum Array

def sc.go source · line 725 · raw

@hop:Nat -> @got:Sc -> @+yy:U32 -> @+ii:U32 -> Sc

seven scatter steps; the eighth is the tail

def sc.e3 source · line 737 · raw

@got:Dx -> @+r0:F32 -> @+r1:F32 -> @+r2:F32 -> Sf

fourth tail sample, index 31

def sc.e2 source · line 743 · raw

@got:Dx -> @+r0:F32 -> @+r1:F32 -> Sf

third tail sample, index 23

def sc.e1 source · line 749 · raw

@got:Dx -> @+r0:F32 -> Sf

second tail sample, index 15

def sc.e0 source · line 755 · raw

@got:Dx -> Sf

first tail sample, index 7, then the other three rows

def sc.tset source · line 761 · raw

@acc:Array<F32> -> @+r0:F32 -> @+r1:F32 -> @+r2:F32 -> @+r3:F32 -> @+yy:U32 -> Array<F32>

four tail bands. r3 is both the high sum and the last band.

def sc.tend source · line 766 · raw

@got:Sf -> @acc:Array<F32> -> @+yy:U32 -> Array<F32>

drop the rows Array once the four tail samples have been read

def sc.tail source · line 774 · raw

@got:Sc -> @+yy:U32 -> Array<F32>

last scatter group, which has no i+1 neighbour. The rows Array ends here.

def sc.run source · line 780 · raw

@acc:Array<F32> -> @xs:Array<F32> -> @+kk:U32 -> Array<F32>

scatter every band of frequency bin kk

def dc.rows source · line 784 · raw

@got:Dr -> Dr

butterfly the gathered rows, then scatter them back into the spectrum

def dc.scat source · line 790 · raw

@got:Dr -> @+kk:U32 -> Array<F32>

scatter one frequency bin. The working rows are consumed here.

def dc.one source · line 796 · raw

@acc:Array<F32> -> @+sec:List<&2, F32> -> @+kk:U32 -> Array<F32>

one frequency bin of the 32-point DCT-II. The working rows stay an Array.

def dc.run source · line 800 · raw

@hop:Nat -> @acc:Array<F32> -> @+sec:List<&2, F32> -> @+kk:U32 -> Array<F32>

DCT-II of 18 frequency bins. kk is the first bin's index in the spectrum Array.

def la.of source · line 811 · raw

@got:Pair(Array<F32>, F32) -> La

def ln.at source · line 815 · raw

@lin:Array<F32> -> @+ii:U32 -> La

def ln.set source · line 818 · raw

@lin:Array<F32> -> @+ii:U32 -> @+vv:F32 -> Array<F32>

def ln.fill source · line 821 · raw

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

def ln.pull source · line 829 · raw

@hop:Nat -> @got:La -> @+ii:U32 -> @acc:List<&2, F32> -> List<&2, F32>

pull one sample into an accumulator; hop is remaining after this read

def ln.list source · line 839 · raw

@a:Array<F32> -> @hop:Nat -> List<&2, F32>

first hop+1 slots of an Array as a list

def mac.av source · line 851 · raw

@+mode:U32 -> @+zv:F32 -> @+yv:F32 -> @+w0:F32 -> @+w1:F32 -> F32

mode 0 replaces, mode 2 flips the a product, otherwise both add

def mac.wr source · line 859 · raw

@+aa:List<&2, F32> -> @+bb:List<&2, F32> -> @+mode:U32 -> @+jj:U32 -> @+bv:F32 -> @+av:F32 -> Mac

apply one lane of a window load

def mac.jy source · line 869 · raw

@st:Mac -> @got:La -> @+w0:F32 -> @+w1:F32 -> @+mode:U32 -> @+jj:U32 -> @+zv:F32 -> Mk

one of the four lanes, y slot

def mac.jz source · line 877 · raw

@st:Mac -> @got:La -> @+w0:F32 -> @+w1:F32 -> @+vy:U32 -> @+mode:U32 -> @+jj:U32 -> Mk

one of the four lanes, z slot

def mac.j source · line 885 · raw

@st:Mac -> @lin:Array<F32> -> @+w0:F32 -> @+w1:F32 -> @+vz:U32 -> @+vy:U32 -> @+mode:U32 -> @+jj:U32 -> Mk

one of the four lanes

def mac.js_next source · line 891 · raw

@mk:Mk -> @+w0:F32 -> @+w1:F32 -> @+vz:U32 -> @+vy:U32 -> @+mode:U32 -> @+jj:U32 -> Mk

four lanes of one load, advance one lane

def mac.js source · line 897 · raw

@hop:Nat -> @mk:Mk -> @+w0:F32 -> @+w1:F32 -> @+vz:U32 -> @+vy:U32 -> @+mode:U32 -> @+jj:U32 -> Mk

four lanes of one load

def mac.mode3 source · line 907 · raw

@odd:Bool -> U32

odd or even load

def mac.mode2 source · line 915 · raw

@zero:Bool -> @odd:Bool -> U32

pick the load mode

def mac.mode source · line 923 · raw

@+kk:U32 -> U32

k = 0 replaces, odd k uses mode 2, other even k uses mode 1

def mac.pos source · line 927 · raw

@+ii:U32 -> @+kk:U32 -> U32

window-coefficient index for block row ii and load kk

def sw.of source · line 934 · raw

@got:Pair(Array<F32>, F32) -> Sw

def sw.at source · line 938 · raw

@syn:Array<F32> -> @+ii:U32 -> Sw

def sw.tab source · line 942 · raw

Array<F32>

242 synthesis-window coefficients. 256 slots cover every mac.pos index.

def mac.step2 source · line 950 · raw

@mk:Mk -> @got:Sw -> @+w0:F32 -> @+zlin:U32 -> @+ii:U32 -> @+kk:U32 -> Mw

second coefficient, then the eight-lane load

def mac.step1 source · line 957 · raw

@mk:Mk -> @got:Sw -> @+pos:U32 -> @+zlin:U32 -> @+ii:U32 -> @+kk:U32 -> Mw

first coefficient, then its neighbour

def mac.step source · line 963 · raw

@mk:Mk -> @syn:Array<F32> -> @+zlin:U32 -> @+ii:U32 -> @+kk:U32 -> Mw

one of the eight loads. Each tap reads the window Array.

def mac.k source · line 967 · raw

@hop:Nat -> @got:Mw -> @+zlin:U32 -> @+ii:U32 -> @+kk:U32 -> Mw

eight loads

def mac.sc source · line 975 · raw

@+vv:F32 -> F32

scale a polyphase sum into a sample

def mac.p8 source · line 979 · raw

@pcm:Array<F32> -> @+aa:List<&2, F32> -> @+bb:List<&2, F32> -> @+nch:U32 -> @+pcmi:U32 -> @+ii:U32 -> Array<F32>

write the eight samples this row produces

def mac.put source · line 993 · raw

@pcm:Array<F32> -> @st:Mac -> @+nch:U32 -> @+pcmi:U32 -> @+ii:U32 -> Array<F32>

store the row

def mac.z source · line 999 · raw

Mac

fresh accumulators

def blk.off source · line 1003 · raw

@+nch:U32 -> @right:Bool -> U32

channel offset: the right channel starts at 576 when there are two

def ga.of source · line 1014 · raw

@got:Pair(Array<F32>, F32) -> Ga

def ga.at source · line 1018 · raw

@gr:Array<F32> -> @+ii:U32 -> Ga

def blk.ix source · line 1026 · raw

@+nch:U32 -> @+band:U32 -> @+tm:U32 -> @right:Bool -> U32

subband index. right selects the second channel, which starts at 576.

def blk.rd source · line 1029 · raw

@gr:Array<F32> -> @+nch:U32 -> @+band:U32 -> @+tm:U32 -> @right:Bool -> Ga

def blk.w4d source · line 1033 · raw

@g:Ga -> @lin:Array<F32> -> @+at:U32 -> @+v0:F32 -> @+v1:F32 -> @+v2:F32 -> Lg

fourth sample of a four-lane write

def blk.w4c source · line 1040 · raw

@g:Ga -> @lin:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+tm:U32 -> @+v0:F32 -> @+v1:F32 -> Lg

third sample: band 0, this channel's left slot

def blk.w4b source · line 1046 · raw

@g:Ga -> @lin:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+tm:U32 -> @+v0:F32 -> Lg

second sample: the right channel of this band

def blk.w4a source · line 1052 · raw

@g:Ga -> @lin:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> Lg

first sample: the left channel of this band

def blk.w4 source · line 1058 · raw

@lin:Array<F32> -> @gr:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> Lg

write the four samples at zlin + 4*slot

def blk.w2b source · line 1064 · raw

@g:Ga -> @lin:Array<F32> -> @+at:U32 -> @+v0:F32 -> Lg

right channel of a two-lane write

def blk.w2a source · line 1070 · raw

@g:Ga -> @lin:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> Lg

left channel of a two-lane write

def blk.w2 source · line 1076 · raw

@lin:Array<F32> -> @gr:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> Lg

the second write of a row uses band (1+ii), not band 0

def blk.pre2 source · line 1082 · raw

@got:Lg -> @+nch:U32 -> @+zlin:U32 -> @+tm:U32 -> Lg

second preamble write: band 16 at the next time

def blk.pre source · line 1088 · raw

@lin:Array<F32> -> @gr:Array<F32> -> @+nch:U32 -> @+zlin:U32 -> @+tm:U32 -> Lg

preamble: bands 16 and 0 at the current and next time

def blk.hist source · line 1094 · raw

@+zlin:U32 -> @+ii:U32 -> U32

index of the history write, which steps back 16 slots

def blk.wsd source · line 1098 · raw

@g:Ga -> @lin:Array<F32> -> @+at:U32 -> @+v0:F32 -> @+v1:F32 -> @+v2:F32 -> Lg

fourth lane: this band at the next time, right channel

def blk.wsc source · line 1105 · raw

@g:Ga -> @lin:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> @+v0:F32 -> @+v1:F32 -> Lg

third lane: this band at the next time, left channel

def blk.wsb source · line 1113 · raw

@g:Ga -> @lin:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> @+v0:F32 -> Lg

second lane: this band at this time, right channel

def blk.wsa source · line 1119 · raw

@g:Ga -> @lin:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> Lg

first lane: this band at this time, left channel

def blk.ws source · line 1125 · raw

@lin:Array<F32> -> @gr:Array<F32> -> @+nch:U32 -> @+at:U32 -> @+band:U32 -> @+tm:U32 -> Lg

same band at this time and the next, four lanes

def blk.i1 source · line 1131 · raw

@lin:Array<F32> -> @gr:Array<F32> -> @+nch:U32 -> @+zlin:U32 -> @+tm:U32 -> @+ii:U32 -> Lg

current-slot writes for row ii

def blk.i2b source · line 1137 · raw

@got:Lg -> @+nch:U32 -> @+zlin:U32 -> @+tm:U32 -> @+ii:U32 -> Lg

history write, after the next-slot write has returned the granule

def blk.i2 source · line 1143 · raw

@lin:Array<F32> -> @gr:Array<F32> -> @+nch:U32 -> @+zlin:U32 -> @+tm:U32 -> @+ii:U32 -> Lg

next-slot and history writes for row ii

def blk.ib source · line 1150 · raw

@got:Lg -> @+nch:U32 -> @+zlin:U32 -> @+tm:U32 -> @+ii:U32 -> Lg

history writes, after the current-slot write has returned the granule

def blk.i source · line 1156 · raw

@lin:Array<F32> -> @gr:Array<F32> -> @+nch:U32 -> @+zlin:U32 -> @+tm:U32 -> @+ii:U32 -> Lg

both writes for row ii

def sp.a1a3 source · line 1162 · raw

@g1:La -> @+v896:F32 -> La

(z+896) - z, times 29

def sp.a1a2 source · line 1167 · raw

@g0:La -> @+zz:U32 -> La

def sp.a1a source · line 1172 · raw

@lin:Array<F32> -> @+zz:U32 -> La

def sp.a1b2 source · line 1176 · raw

@g1:La -> @+acc:F32 -> @+v64:F32 -> La

slots 1 and 13, times 213

def sp.a1b1 source · line 1181 · raw

@g0:La -> @+acc:F32 -> @+zz:U32 -> La

def sp.a1b source · line 1186 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a1c2 source · line 1190 · raw

@g1:La -> @+acc:F32 -> @+v768:F32 -> La

slots 12 and 2, times 459

def sp.a1c1 source · line 1195 · raw

@g0:La -> @+acc:F32 -> @+zz:U32 -> La

def sp.a1c source · line 1200 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a1d2 source · line 1204 · raw

@g1:La -> @+acc:F32 -> @+v192:F32 -> La

slots 3 and 11, times 2037

def sp.a1d1 source · line 1209 · raw

@g0:La -> @+acc:F32 -> @+zz:U32 -> La

def sp.a1d source · line 1214 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a1e2 source · line 1218 · raw

@g1:La -> @+acc:F32 -> @+v640:F32 -> La

slots 10 and 4, times 5153

def sp.a1e1 source · line 1223 · raw

@g0:La -> @+acc:F32 -> @+zz:U32 -> La

def sp.a1e source · line 1228 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a1f2 source · line 1232 · raw

@g1:La -> @+acc:F32 -> @+v320:F32 -> La

slots 5 and 9, times 6574

def sp.a1f1 source · line 1237 · raw

@g0:La -> @+acc:F32 -> @+zz:U32 -> La

def sp.a1f source · line 1242 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a1g4 source · line 1246 · raw

@g2:La -> @+acc:F32 -> @+v512:F32 -> @+v384:F32 -> La

slots 8 and 6, times 37489, then slot 7 times 75038

def sp.a1g3 source · line 1253 · raw

@g1:La -> @+acc:F32 -> @+v512:F32 -> @+zz:U32 -> La

def sp.a1g2 source · line 1258 · raw

@g0:La -> @+acc:F32 -> @+zz:U32 -> La

def sp.a1g source · line 1263 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a1go6 source · line 1266 · raw

@g:La -> @+zz:U32 -> La

def sp.a1go5 source · line 1271 · raw

@g:La -> @+zz:U32 -> La

def sp.a1go4 source · line 1276 · raw

@g:La -> @+zz:U32 -> La

def sp.a1go3 source · line 1281 · raw

@g:La -> @+zz:U32 -> La

def sp.a1go2 source · line 1286 · raw

@g:La -> @+zz:U32 -> La

def sp.a1go1 source · line 1291 · raw

@g:La -> @+zz:U32 -> La

def sp.a1 source · line 1297 · raw

@lin:Array<F32> -> @+zz:U32 -> La

first grouped window sum

def sp.a2a4 source · line 1301 · raw

@g3:La -> @+v898:F32 -> @+v770:F32 -> @+v642:F32 -> La

taps 898, 770, 642, 514

def sp.a2a3 source · line 1308 · raw

@g2:La -> @+v898:F32 -> @+v770:F32 -> @+zz:U32 -> La

def sp.a2a2 source · line 1313 · raw

@g1:La -> @+v898:F32 -> @+zz:U32 -> La

def sp.a2a1 source · line 1318 · raw

@g0:La -> @+zz:U32 -> La

def sp.a2a source · line 1323 · raw

@lin:Array<F32> -> @+zz:U32 -> La

def sp.a2b2 source · line 1327 · raw

@g1:La -> @+acc:F32 -> @+v386:F32 -> La

taps 386 and 258

def sp.a2b1 source · line 1332 · raw

@g0:La -> @+acc:F32 -> @+zz:U32 -> La

def sp.a2b source · line 1337 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a2c1 source · line 1341 · raw

@g:La -> @+acc:F32 -> La

tap 130

def sp.a2c source · line 1346 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a2d1 source · line 1350 · raw

@g:La -> @+acc:F32 -> La

tap 2

def sp.a2d source · line 1355 · raw

@+acc:F32 -> @lin:Array<F32> -> @+zz:U32 -> La

def sp.a2go3 source · line 1358 · raw

@g:La -> @+zz:U32 -> La

def sp.a2go2 source · line 1363 · raw

@g:La -> @+zz:U32 -> La

def sp.a2go1 source · line 1368 · raw

@g:La -> @+zz:U32 -> La

def sp.a2 source · line 1374 · raw

@lin:Array<F32> -> @+zz:U32 -> La

second window sum, eight weighted taps

def sp.pair2 source · line 1382 · raw

@g2:La -> @pcm:Array<F32> -> @+pcmi:U32 -> @+nch:U32 -> Pp

one synth pair: two scaled samples

def sp.pair1 source · line 1387 · raw

@g1:La -> @pcm:Array<F32> -> @+pcmi:U32 -> @+nch:U32 -> @+zz:U32 -> Pp

def sp.pair source · line 1392 · raw

@st:Pp -> @+pcmi:U32 -> @+nch:U32 -> @+zz:U32 -> Pp

def blk.pairs source · line 1398 · raw

@st:Pp -> @+nch:U32 -> @+pcmi:U32 -> @+z0:U32 -> Pp

four synth pairs that open a block

def blk.armed1 source · line 1407 · raw

@got:Pp -> Sb

def blk.armed source · line 1413 · raw

@lin:Array<F32> -> @pcm:Array<F32> -> @+nch:U32 -> @+tm:U32 -> Sb

pairs read the delay line the preamble just wrote

def blk.arm2 source · line 1421 · raw

@got:Lg -> @pcm:Array<F32> -> @syn:Array<F32> -> @+nch:U32 -> @+tm:U32 -> Bg

preamble done: the pairs read the delay line, the granule and window stay put

def blk.arm source · line 1427 · raw

@got:Bg -> @+nch:U32 -> @+tm:U32 -> Bg

open a block: preamble, then the four pairs

def blk.row1 source · line 1438 · raw

@got:Mw -> @pcm:Array<F32> -> @+nch:U32 -> @+tm:U32 -> @+ii:U32 -> Sr

def blk.row3 source · line 1445 · raw

@got:Sr -> @gr:Array<F32> -> Bg

def blk.row source · line 1451 · raw

@lin:Array<F32> -> @pcm:Array<F32> -> @syn:Array<F32> -> @+nch:U32 -> @+tm:U32 -> @+ii:U32 -> Sr

window the row just written

def blk.step2 source · line 1457 · raw

@got:Lg -> @pcm:Array<F32> -> @syn:Array<F32> -> @+nch:U32 -> @+tm:U32 -> @+ii:U32 -> Bg

window the row, keeping the granule for the rows still to come

def blk.step source · line 1465 · raw

@got:Bg -> @+nch:U32 -> @+tm:U32 -> @+ii:U32 -> Bg

one row of the block, from i = 14 down to 0

def blk.i.go source · line 1473 · raw

@hop:Nat -> @got:Bg -> @+nch:U32 -> @+tm:U32 -> @+ii:U32 -> Bg

fifteen rows

def blk.one source · line 1481 · raw

@got:Bg -> @+nch:U32 -> @+tm:U32 -> Bg

one time block

def blk.go source · line 1485 · raw

@hop:Nat -> @got:Bg -> @+nch:U32 -> @+tm:U32 -> Bg

nine time blocks, time = 0, 2, ..., 16

def qmf.ev source · line 1494 · raw

@hop:Nat -> @old:List<&2, F32> -> @got:La -> @+ii:U32 -> @acc:List<&2, F32> -> List<&2, F32>

one even delay sample and the odd slot kept from the carried tail. hop is the pairs still to come after this one. The sample was read at ii.

def qmf.st source · line 1508 · raw

@+old:List<&2, F32> -> @lin:Array<F32> -> List<&2, F32>

stereo tail: 960 delay-Array samples in one pull. The old list is dropped.

def qmf.pick source · line 1514 · raw

@mono:Bool -> @+qmf:List<&2, F32> -> @lin:Array<F32> -> List<&2, F32>

mono keeps odd slots; stereo replaces the whole tail from the delay Array

def qmf.save source · line 1522 · raw

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

save the 15-block tail off the delay Array, one pass, no List.set

def syn.zov source · line 1530 · raw

List<&2, F32>

zero overlap, 288 samples, one channel

def syn.zqmf source · line 1534 · raw

List<&2, F32>

zero polyphase delay

def ch.prep source · line 1538 · raw

@acc:Array<F32> -> @+ov:List<&2, F32> -> @+aa:List<&2, F32> -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> @+base:U32 -> Im

antialias, IMDCT, and the sign flip for one channel

def syn.st2 source · line 1545 · raw

@+ova:List<&2, F32> -> @bb:Im -> Im

append the second channel's overlap. The spectrum Array already holds both.

def syn.st source · line 1551 · raw

@aa:Im -> @+ovb:List<&2, F32> -> @+cs:List<&2, F32> -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> Im

join two channel states. The right channel starts at bin 576.

def syn.ch source · line 1559 · raw

@mono:Bool -> @acc:Array<F32> -> @+ov:List<&2, F32> -> @+aa:List<&2, F32> -> @+tw:List<&2, F32> -> @+win:List<&2, F32> -> Im

prepare one or two channels

def syn.ready source · line 1570 · raw

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

tables shared by a granule. 2048 slots cover mono 576 and stereo 1152.

def sy.dct2 source · line 1575 · raw

@mono:Bool -> @acc:Array<F32> -> @+sec:List<&2, F32> -> Array<F32>

second channel starts at bin 576

def sy.dct source · line 1583 · raw

@mono:Bool -> @acc:Array<F32> -> @+sec:List<&2, F32> -> Array<F32>

DCT-II of each channel. The spectrum Array is the one IMDCT just wrote.

def sy.lin source · line 1587 · raw

@+qmf:List<&2, F32> -> Array<F32>

delay line: the carried tail, then zeros (4096-slot Array starts at 0.0)

def sy.pcm source · line 1591 · raw

Array<F32>

empty PCM for one granule (2048-slot Array covers mono 576 and stereo 1152)

def sy.pcm.list source · line 1595 · raw

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

PCM Array back to a list of length 576*nch

def syn.drop source · line 1599 · raw

@gr:Array<F32> -> @st:Sb -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+nch:U32 -> Pc

the granule Array is finished once the nine blocks have read it

def syn.out source · line 1607 · raw

@got:Bg -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+nch:U32 -> Pc

run the polyphase and keep the overlap from the IMDCT

def syn.pcm source · line 1615 · raw

@buf:Array<F32> -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+nch:U32 -> Pc

DCT-II then nine polyphase blocks. The spectrum Array is what the polyphase reads.

def syn.finish source · line 1620 · raw

@st:Im -> @+qmf:List<&2, F32> -> @+nch:U32 -> Pc

synthesis of a prepared granule

def syn.gran source · line 1626 · raw

@+spec:List<&2, F32> -> @+ov:List<&2, F32> -> @+qmf:List<&2, F32> -> @+nch:U32 -> Pc

one granule to PCM. spec is 576 samples per channel. ov is 288 per channel.

def syn.im source · line 1630 · raw

@+buf:List<&2, F32> -> @+ov:List<&2, F32> -> Im

IMDCT only, 32 bands, no antialias. Used to check the unit impulse.

def syn.nth source · line 1635 · raw

@st:Pc -> @+ii:U32 -> U32

one PCM sample of a granule, as a binary32 word

def syn.word1 source · line 1641 · raw

@got:Dx -> U32

drop the spectrum Array once sample 0 has been read

def syn.word source · line 1649 · raw

@st:Im -> U32

first sample of an IMDCT buffer, as a binary32 word

def syn.probe source · line 1655 · raw

@+ii:U32 -> U32

PCM word ii of one granule whose spectrum is a unit impulse at bin 0.

def syn.impulse source · line 1660 · raw

U32

unit impulse at bin 0. The first sample is the float32 word 1022453915.