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 /* build lookups for trig functions; also pre-figure scaling and
48 some window function algebra. */
50 void mdct_init(mdct_lookup *lookup,int n){
51 int *bitrev=malloc(sizeof(int)*(n/4));
52 double *trig=malloc(sizeof(double)*(n+n/4));
64 int log2n=lookup->log2n=rint(log(n)/log(2));
67 lookup->bitrev=bitrev;
72 AE[i]=cos((M_PI/n)*(4*i));
73 AO[i]=-sin((M_PI/n)*(4*i));
74 BE[i]=cos((M_PI/(2*n))*(2*i+1));
75 BO[i]=sin((M_PI/(2*n))*(2*i+1));
78 CE[i]=cos((M_PI/n)*(4*i+2));
79 CO[i]=-sin((M_PI/n)*(4*i+2));
82 /* bitreverse lookup... */
85 int mask=(1<<(log2n-1))-1,i,j;
90 if((msb>>j)&i)acc|=1<<j;
91 bitA[i]=((~acc)&mask)*2;
97 void mdct_clear(mdct_lookup *l){
99 if(l->trig)free(l->trig);
100 if(l->bitrev)free(l->bitrev);
101 memset(l,0,sizeof(mdct_lookup));
105 static inline void _mdct_kernel(double *x,
106 int n, int n2, int n4, int n8,
108 double *w=x+1; /* interleaved access improves cache locality */
116 double *AE=init->trig+n4;
120 double x0=xA[i]-xB[i];
121 double x1=xA[i+2]-xB[i+2];
124 w[i] =x0 * *AE + x1 * *AO;
127 w[i] =x1 * *AE - x0 * *AO;
137 for(i=0;i<init->log2n-3;i++){
141 double *AE=init->trig;
145 for(r=0;r<(n4>>i);r+=4){
147 int w2=wbase-(k0>>1);
150 for(s=0;s<(2<<i);s++){
151 x[w1+2]=w[w1+2]+w[w2+2];
153 x[w2+2]=(w[w1+2]-w[w2+2])* *AE-(w[w1]-w[w2])* *AO;
154 x[w2] =(w[w1]-w[w2])* *AE+(w[w1+2]-w[w2+2])* *AO;
169 /* step 4, 5, 6, 7 */
171 double *CE=init->trig+n;
173 int *bitA=init->bitrev;
183 double wA=w[t1]-w[t2];
184 double wB=w[t3]+w[t4];
185 double wC=w[t1]+w[t2];
186 double wD=w[t3]-w[t4];
189 double wBCO=wB* *(CO++);
191 double wBCE=wB* *(CE++);
193 *x1 =( wC+wACO+wBCE)*.5;
194 *(x2-2)=( wC-wACO-wBCE)*.5;
195 *(x1+2)=( wD+wBCO-wACE)*.5;
196 *x2 =(-wD+wBCO-wACE)*.5;
203 void mdct_forward(mdct_lookup *init, double *in, double *out, double *window){
205 double *x=alloca(n*sizeof(double));
211 /* window + rotate + step 1 */
216 double *AE=init->trig+n4;
222 tempA= in[in1+2]*window[in1+2] + in[in2]*window[in2];
223 tempB= in[in1]*window[in1] + in[in2+2]*window[in2+2];
226 x[i]= tempB* *AO + tempA* *AE;
227 x[i+2]= tempB* *AE - tempA* *AO;
233 tempA= in[in1+2]*window[in1+2] - in[in2]*window[in2];
234 tempB= in[in1]*window[in1] - in[in2+2]*window[in2+2];
237 x[i]= tempB* *AO + tempA* *AE;
238 x[i+2]= tempB* *AE - tempA* *AO;
244 tempA= -in[in1+2]*window[in1+2] - in[in2]*window[in2];
245 tempB= -in[in1]*window[in1] - in[in2+2]*window[in2+2];
248 x[i]= tempB* *AO + tempA* *AE;
249 x[i+2]= tempB* *AE - tempA* *AO;
253 _mdct_kernel(x,n,n2,n4,n8,init);
258 double *BE=init->trig+n2;
262 out[i] =x[0]* *BE+x[2]* *BO;
263 *(--out2)=x[0]* *BO-x[2]* *BE;
271 void mdct_backward(mdct_lookup *init, double *in, double *out, double *window){
273 double *x=alloca(n*sizeof(double));
279 /* window + rotate + step 1 */
283 double *AE=init->trig+n4;
288 *xO=-*(inO+2)* *AO - *inO * *AE;
290 *xO= *inO * *AO - *(inO+2)* *AE;
299 *xO=*inO * *AO + *(inO+2) * *AE;
301 *xO=*inO * *AE - *(inO+2) * *AO;
308 _mdct_kernel(x,n,n2,n4,n8,init);
313 double *BE=init->trig+n2;
316 int o3=n4+n2,o4=o3-1;
320 #ifdef VORBIS_SPECIFIC_MODIFICATIONS
321 double temp1= (*x * *BO - *(x+2) * *BE)/ scale;
322 double temp2= (*x * *BE + *(x+2) * *BO)/ -scale;
324 out[o1]=-temp1*window[o1];
325 out[o2]=temp1*window[o2];
326 out[o3]=out[o4]=temp2;
328 double temp1= (*x * *BO - *(x+2) * *BE)* scale;
329 double temp2= (*x * *BE + *(x+2) * *BO)* -scale;
331 out[o1]=-temp1*window[o1];
332 out[o2]=temp1*window[o2];
333 out[o3]=temp2*window[o3];
334 out[o4]=temp2*window[o4];