1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Imdct.mli *)(* cos(pi / 2n (2i + 1 + n/2)(2k + 1)), for the two sizes *)letcosines(n:int):floatarrayarray=Array.initn(funi->Array.init(n/2)(funk->cos(Float.pi/.float_of_int(2*n)*.float_of_int(((2*i)+1+(n/2))*((2*k)+1)))))letcos36=cosines36letcos12=cosines12lettable(n:int)=ifn=36thencos36elseifn=12thencos12elsecosinesn(* output i, the formula: a for loop, not Array.iteri, since a float ref
* that a closure captures is boxed, an allocation per addition
* (notes_opti_ocaml.md) *)letoutput(c:floatarrayarray)(coefficients:floatarray)(i:int):float=letrow=c.(i)andsum=ref0.infork=0toArray.lengthcoefficients-1dosum:=!sum+.(coefficients.(k)*.row.(k))done;!sum(* claude: a quarter of the outputs computed, the others their mirrors,
* where it was every output from the formula:
*
* Array.init n (fun i -> output c coefficients i)
*
* With a = 2i + 1 + n/2, output n/2 - 1 - i has 2n - a instead, and
* cos((2k + 1) pi - x) = -cos x: x[n/2 - 1 - i] = -x[i]; output 3n/2 - 1
* - i has 4n - a, and cos(2 (2k + 1) pi - x) = cos x: x[3n/2 - 1 - i] =
* x[i] -- the aliases, the halves mirrored, that the overlap cancels.
* And coefficients all zero (the high subbands, mostly) give zeros,
* nothing computed. Half the multiplications, and far fewer in quiet
* bands (notes_opti_ocaml.md). *)letimdct(coefficients:floatarray):floatarray=letn=2*Array.lengthcoefficientsinletx=Array.maken0.inifArray.exists(funv->v<>0.)coefficientsthen(letc=tableninfori=0to(n/4)-1doletv=outputccoefficientsiinx.(i)<-v;x.((n/2)-1-i)<--.vdone;fori=n/2to(3*n/4)-1doletv=outputccoefficientsiinx.(i)<-v;x.((3*n/2)-1-i)<-vdone);xletmdct(samples:floatarray):floatarray=letn=Array.lengthsamplesinletc=tableninArray.init(n/2)(funk->letsum=ref0.infori=0ton-1dosum:=!sum+.(samples.(i)*.c.(i).(k))done;!sum)letsine(period:int)(i:int):float=sin(Float.pi/.float_of_intperiod*.(float_of_inti+.0.5))letwindows=[|Array.init36(sine36);Array.init36(funi->ifi<18thensine36ielseifi<24then1.elseifi<30thensine12(i-18)else0.);Array.init12(sine12);Array.init36(funi->ifi<6then0.elseifi<12thensine12(i-6)elseifi<18then1.elsesine36i)|]letwindow(block_type:int):floatarray=windows.(block_type)