1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: modified discrete cosine transform
15 power of two length transform only [16 <= n ]
17 author: Monty <xiphmont@mit.edu>
18 modifications by: Monty
19 last modification date: Jul 29 1999
21 Algorithm adapted from _The use of multirate filter banks for coding
22 of high quality digital audio_, by T. Sporer, K. Brandenburg and
23 B. Edler, collection of the European Signal Processing Conference
24 (EUSIPCO), Amsterdam, June 1992, Vol.1, pp 211-214
26 Note that the below code won't make much sense without the paper;
27 The presented algorithm was already fairly polished, and the code
28 once followed it closely. The current code both corrects several
29 typos in the paper and goes beyond the presented optimizations
30 (steps 4 through 6 are, for example, entirely eliminated).
32 This module DOES NOT INCLUDE code to generate the window function.
33 Everybody has their own weird favorite including me... I happen to
34 like the properties of y=sin(2PI*sin^2(x)), but others may vehemently
37 ********************************************************************/
39 /* Undef the following if you want a normal MDCT */
40 #define VORBIS_SPECIFIC_MODIFICATIONS
47 static double oPI = 3.14159265358979323846;
49 /* build lookups for trig functions; also pre-figure scaling and
50 some window function algebra. */
52 MDCT_lookup *MDCT_init(int n){
53 MDCT_lookup *lookup=malloc(sizeof(MDCT_lookup));
54 int *bitrev=malloc(sizeof(int)*(n/4));
55 double *trig=malloc(sizeof(double)*(n+n/4));
67 int log2n=lookup->log2n=rint(log(n)/log(2));
70 lookup->bitrev=bitrev;
75 AE[i]=cos((oPI/n)*(4*i));
76 AO[i]=-sin((oPI/n)*(4*i));
77 BE[i]=cos((oPI/(2*n))*(2*i+1));
78 BO[i]=sin((oPI/(2*n))*(2*i+1));
81 CE[i]=cos((oPI/n)*(4*i+2));
82 CO[i]=-sin((oPI/n)*(4*i+2));
85 /* bitreverse lookup... */
88 int mask=(1<<(log2n-1))-1,i,j;
93 if((msb>>j)&i)acc|=1<<j;
94 bitA[i]=((~acc)&mask)*2;
102 void MDCT_free(MDCT_lookup *l){
104 if(l->trig)free(l->trig);
105 if(l->bitrev)free(l->bitrev);
110 static inline void _MDCT_kernel(double *x,
111 int n, int n2, int n4, int n8,
113 double *w=x+1; /* interleaved access improves cache locality */
121 double *AE=init->trig+n4;
125 double x0=xA[i]-xB[i];
126 double x1=xA[i+2]-xB[i+2];
129 w[i] =x0 * *AE + x1 * *AO;
132 w[i] =x1 * *AE - x0 * *AO;
142 for(i=0;i<init->log2n-3;i++){
146 double *AE=init->trig;
150 for(r=0;r<(n4>>i);r+=4){
152 int w2=wbase-(k0>>1);
155 for(s=0;s<(2<<i);s++){
156 x[w1+2]=w[w1+2]+w[w2+2];
158 x[w2+2]=(w[w1+2]-w[w2+2])* *AE-(w[w1]-w[w2])* *AO;
159 x[w2] =(w[w1]-w[w2])* *AE+(w[w1+2]-w[w2+2])* *AO;
174 /* step 4, 5, 6, 7 */
176 double *CE=init->trig+n;
178 int *bitA=init->bitrev;
188 double wA=w[t1]-w[t2];
189 double wB=w[t3]+w[t4];
190 double wC=w[t1]+w[t2];
191 double wD=w[t3]-w[t4];
194 double wBCO=wB* *(CO++);
196 double wBCE=wB* *(CE++);
198 *x1 =( wC+wACO+wBCE)*.5;
199 *(x2-2)=( wC-wACO-wBCE)*.5;
200 *(x1+2)=( wD+wBCO-wACE)*.5;
201 *x2 =(-wD+wBCO-wACE)*.5;
208 void MDCT(double *in, double *out, MDCT_lookup *init, double *window){
210 double *x=alloca(n*sizeof(double));
216 /* window + rotate + step 1 */
221 double *AE=init->trig+n4;
227 tempA= in[in1+2]*window[in1+2] + in[in2]*window[in2];
228 tempB= in[in1]*window[in1] + in[in2+2]*window[in2+2];
231 x[i]= tempB* *AO + tempA* *AE;
232 x[i+2]= tempB* *AE - tempA* *AO;
238 tempA= in[in1+2]*window[in1+2] - in[in2]*window[in2];
239 tempB= in[in1]*window[in1] - in[in2+2]*window[in2+2];
242 x[i]= tempB* *AO + tempA* *AE;
243 x[i+2]= tempB* *AE - tempA* *AO;
249 tempA= -in[in1+2]*window[in1+2] - in[in2]*window[in2];
250 tempB= -in[in1]*window[in1] - in[in2+2]*window[in2+2];
253 x[i]= tempB* *AO + tempA* *AE;
254 x[i+2]= tempB* *AE - tempA* *AO;
258 _MDCT_kernel(x,n,n2,n4,n8,init);
263 double *BE=init->trig+n2;
267 out[i] =x[0]* *BE+x[2]* *BO;
268 *(--out2)=x[0]* *BO-x[2]* *BE;
276 void iMDCT(double *in, double *out, MDCT_lookup *init, double *window){
278 double *x=alloca(n*sizeof(double));
284 /* window + rotate + step 1 */
288 double *AE=init->trig+n4;
293 *xO=-*(inO+2)* *AO - *inO * *AE;
295 *xO= *inO * *AO - *(inO+2)* *AE;
304 *xO=*inO * *AO + *(inO+2) * *AE;
306 *xO=*inO * *AE - *(inO+2) * *AO;
313 _MDCT_kernel(x,n,n2,n4,n8,init);
318 double *BE=init->trig+n2;
321 int o3=n4+n2,o4=o3-1;
325 #ifdef VORBIS_SPECIFIC_MODIFICATIONS
326 double temp1= (*x * *BO - *(x+2) * *BE)/ scale;
327 double temp2= (*x * *BE + *(x+2) * *BO)/ -scale;
329 out[o1]=-temp1*window[o1];
330 out[o2]=temp1*window[o2];
331 out[o3]=out[o4]=temp2;
333 double temp1= (*x * *BO - *(x+2) * *BE)* scale;
334 double temp2= (*x * *BE + *(x+2) * *BO)* -scale;
336 out[o1]=-temp1*window[o1];
337 out[o2]=temp1*window[o2];
338 out[o3]=temp2*window[o3];
339 out[o4]=temp2*window[o4];