1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 function: normalized modified discrete cosine transform
14 power of two length transform only [64 <= n ]
15 last mod: $Id: mdct.c,v 1.26 2001/10/02 00:14:31 segher Exp $
17 Original algorithm adapted long ago from _The use of multirate filter
18 banks for coding of high quality digital audio_, by T. Sporer,
19 K. Brandenburg and B. Edler, collection of the European Signal
20 Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
23 The below code implements an algorithm that no longer looks much like
24 that presented in the paper, but the basic structure remains if you
25 dig deep enough to see it.
27 This module DOES NOT INCLUDE code to generate/apply the window
28 function. Everybody has their own weird favorite including me... I
29 happen to like the properties of y=sin(2PI*sin^2(x)), but others may
32 ********************************************************************/
34 /* this can also be run as an integer transform by uncommenting a
35 define in mdct.h; the integerization is a first pass and although
36 it's likely stable for Vorbis, the dynamic range is constrained and
37 roundoff isn't done (so it's noisy). Consider it functional, but
38 only a starting point. There's no point on a machine with an FPU */
44 #include "vorbis/codec.h"
48 /* build lookups for trig functions; also pre-figure scaling and
49 some window function algebra. */
51 void mdct_init(mdct_lookup *lookup,int n){
52 int *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
53 DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
57 int log2n=lookup->log2n=rint(log(n)/log(2));
60 lookup->bitrev=bitrev;
65 T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
66 T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
67 T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
68 T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
71 T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
72 T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
75 /* bitreverse lookup... */
78 int mask=(1<<(log2n-1))-1,i,j;
83 if((msb>>j)&i)acc|=1<<j;
84 bitrev[i*2]=((~acc)&mask)-1;
89 lookup->scale=FLOAT_CONV(4.f/n);
92 /* 8 point butterfly (in place, 4 register) */
93 STIN void mdct_butterfly_8(DATA_TYPE *x){
94 REG_TYPE r0 = x[6] + x[2];
95 REG_TYPE r1 = x[6] - x[2];
96 REG_TYPE r2 = x[4] + x[0];
97 REG_TYPE r3 = x[4] - x[0];
121 /* 16 point butterfly (in place, 4 register) */
122 STIN void mdct_butterfly_16(DATA_TYPE *x){
123 REG_TYPE r0 = x[1] - x[9];
124 REG_TYPE r1 = x[0] - x[8];
128 x[0] = MULT_NORM((r0 + r1) * cPI2_8);
129 x[1] = MULT_NORM((r0 - r1) * cPI2_8);
142 x[4] = MULT_NORM((r0 - r1) * cPI2_8);
143 x[5] = MULT_NORM((r0 + r1) * cPI2_8);
153 mdct_butterfly_8(x+8);
156 /* 32 point butterfly (in place, 4 register) */
157 STIN void mdct_butterfly_32(DATA_TYPE *x){
158 REG_TYPE r0 = x[30] - x[14];
159 REG_TYPE r1 = x[31] - x[15];
170 x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 );
171 x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 );
177 x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8);
178 x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8);
184 x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 );
185 x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
198 x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 );
199 x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 );
205 x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8);
206 x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8);
212 x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
213 x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 );
215 mdct_butterfly_16(x);
216 mdct_butterfly_16(x+16);
220 /* N point first stage butterfly (in place, 2 register) */
221 STIN void mdct_butterfly_first(DATA_TYPE *T,
225 DATA_TYPE *x1 = x + points - 8;
226 DATA_TYPE *x2 = x + (points>>1) - 8;
236 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
237 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
243 x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]);
244 x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]);
250 x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]);
251 x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]);
257 x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]);
258 x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]);
267 /* N/stage point generic N stage butterfly (in place, 2 register) */
268 STIN void mdct_butterfly_generic(DATA_TYPE *T,
273 DATA_TYPE *x1 = x + points - 8;
274 DATA_TYPE *x2 = x + (points>>1) - 8;
284 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
285 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
293 x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]);
294 x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]);
302 x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]);
303 x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]);
311 x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]);
312 x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
321 STIN void mdct_butterflies(mdct_lookup *init,
325 DATA_TYPE *T=init->trig;
326 int stages=init->log2n-5;
330 mdct_butterfly_first(T,x,points);
333 for(i=1;--stages>0;i++){
334 for(j=0;j<(1<<i);j++)
335 mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
338 for(j=0;j<points;j+=32)
339 mdct_butterfly_32(x+j);
343 void mdct_clear(mdct_lookup *l){
345 if(l->trig)_ogg_free(l->trig);
346 if(l->bitrev)_ogg_free(l->bitrev);
347 memset(l,0,sizeof(*l));
351 STIN void mdct_bitreverse(mdct_lookup *init,
354 int *bit = init->bitrev;
356 DATA_TYPE *w1 = x = w0+(n>>1);
357 DATA_TYPE *T = init->trig+n;
360 DATA_TYPE *x0 = x+bit[0];
361 DATA_TYPE *x1 = x+bit[1];
363 REG_TYPE r0 = x0[1] - x1[1];
364 REG_TYPE r1 = x0[0] + x1[0];
365 REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]);
366 REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]);
370 r0 = HALVE(x0[1] + x1[1]);
371 r1 = HALVE(x0[0] - x1[0]);
383 r2 = MULT_NORM(r1 * T[2] + r0 * T[3]);
384 r3 = MULT_NORM(r1 * T[3] - r0 * T[2]);
386 r0 = HALVE(x0[1] + x1[1]);
387 r1 = HALVE(x0[0] - x1[0]);
401 void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
408 DATA_TYPE *iX = in+n2-7;
409 DATA_TYPE *oX = out+n2+n4;
410 DATA_TYPE *T = init->trig+n4;
414 oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]);
415 oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]);
416 oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]);
417 oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]);
428 oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
429 oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
430 oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
431 oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
436 mdct_butterflies(init,out+n2,n2);
437 mdct_bitreverse(init,out);
439 /* roatate + window */
442 DATA_TYPE *oX1=out+n2+n4;
443 DATA_TYPE *oX2=out+n2+n4;
450 oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
451 oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
453 oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
454 oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
456 oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
457 oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
459 oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
460 oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
475 oX2[0] = -(oX1[3] = iX[3]);
476 oX2[1] = -(oX1[2] = iX[2]);
477 oX2[2] = -(oX1[1] = iX[1]);
478 oX2[3] = -(oX1[0] = iX[0]);
497 void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
502 DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
507 /* window + rotate + step 1 */
511 DATA_TYPE *x0=in+n2+n4;
513 DATA_TYPE *T=init->trig+n2;
522 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
523 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
534 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
535 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
546 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
547 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
552 mdct_butterflies(init,w+n2,n2);
553 mdct_bitreverse(init,w);
555 /* roatate + window */
562 out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
563 x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);