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-2009 *
9 * by the Xiph.Org Foundation 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 16227 2009-07-08 06:58:46Z xiphmont $
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(.5PI*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"
49 /* build lookups for trig functions; also pre-figure scaling and
50 some window function algebra. */
52 void mdct_init(mdct_lookup *lookup,int n){
53 int *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
54 DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
58 int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
61 lookup->bitrev=bitrev;
66 T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
67 T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
68 T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
69 T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
72 T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
73 T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
76 /* bitreverse lookup... */
79 int mask=(1<<(log2n-1))-1,i,j;
84 if((msb>>j)&i)acc|=1<<j;
85 bitrev[i*2]=((~acc)&mask)-1;
90 lookup->scale=FLOAT_CONV(4.f/n);
93 /* 8 point butterfly (in place, 4 register) */
94 STIN void mdct_butterfly_8(DATA_TYPE *x){
95 REG_TYPE r0 = x[6] + x[2];
96 REG_TYPE r1 = x[6] - x[2];
97 REG_TYPE r2 = x[4] + x[0];
98 REG_TYPE r3 = x[4] - x[0];
117 /* 16 point butterfly (in place, 4 register) */
118 STIN void mdct_butterfly_16(DATA_TYPE *x){
119 REG_TYPE r0 = x[1] - x[9];
120 REG_TYPE r1 = x[0] - x[8];
124 x[0] = MULT_NORM((r0 + r1) * cPI2_8);
125 x[1] = MULT_NORM((r0 - r1) * cPI2_8);
138 x[4] = MULT_NORM((r0 - r1) * cPI2_8);
139 x[5] = MULT_NORM((r0 + r1) * cPI2_8);
149 mdct_butterfly_8(x+8);
152 /* 32 point butterfly (in place, 4 register) */
153 STIN void mdct_butterfly_32(DATA_TYPE *x){
154 REG_TYPE r0 = x[30] - x[14];
155 REG_TYPE r1 = x[31] - x[15];
166 x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 );
167 x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 );
173 x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8);
174 x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8);
180 x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 );
181 x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
194 x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 );
195 x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 );
201 x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8);
202 x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8);
208 x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
209 x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 );
211 mdct_butterfly_16(x);
212 mdct_butterfly_16(x+16);
216 /* N point first stage butterfly (in place, 2 register) */
217 STIN void mdct_butterfly_first(DATA_TYPE *T,
221 DATA_TYPE *x1 = x + points - 8;
222 DATA_TYPE *x2 = x + (points>>1) - 8;
232 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
233 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
239 x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]);
240 x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]);
246 x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]);
247 x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]);
253 x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]);
254 x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]);
263 /* N/stage point generic N stage butterfly (in place, 2 register) */
264 STIN void mdct_butterfly_generic(DATA_TYPE *T,
269 DATA_TYPE *x1 = x + points - 8;
270 DATA_TYPE *x2 = x + (points>>1) - 8;
280 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
281 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
289 x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]);
290 x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]);
298 x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]);
299 x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]);
307 x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]);
308 x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
317 STIN void mdct_butterflies(mdct_lookup *init,
321 DATA_TYPE *T=init->trig;
322 int stages=init->log2n-5;
326 mdct_butterfly_first(T,x,points);
329 for(i=1;--stages>0;i++){
330 for(j=0;j<(1<<i);j++)
331 mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
334 for(j=0;j<points;j+=32)
335 mdct_butterfly_32(x+j);
339 void mdct_clear(mdct_lookup *l){
341 if(l->trig)_ogg_free(l->trig);
342 if(l->bitrev)_ogg_free(l->bitrev);
343 memset(l,0,sizeof(*l));
347 STIN void mdct_bitreverse(mdct_lookup *init,
350 int *bit = init->bitrev;
352 DATA_TYPE *w1 = x = w0+(n>>1);
353 DATA_TYPE *T = init->trig+n;
356 DATA_TYPE *x0 = x+bit[0];
357 DATA_TYPE *x1 = x+bit[1];
359 REG_TYPE r0 = x0[1] - x1[1];
360 REG_TYPE r1 = x0[0] + x1[0];
361 REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]);
362 REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]);
366 r0 = HALVE(x0[1] + x1[1]);
367 r1 = HALVE(x0[0] - x1[0]);
379 r2 = MULT_NORM(r1 * T[2] + r0 * T[3]);
380 r3 = MULT_NORM(r1 * T[3] - r0 * T[2]);
382 r0 = HALVE(x0[1] + x1[1]);
383 r1 = HALVE(x0[0] - x1[0]);
397 void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
404 DATA_TYPE *iX = in+n2-7;
405 DATA_TYPE *oX = out+n2+n4;
406 DATA_TYPE *T = init->trig+n4;
410 oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]);
411 oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]);
412 oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]);
413 oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]);
424 oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
425 oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
426 oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
427 oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
432 mdct_butterflies(init,out+n2,n2);
433 mdct_bitreverse(init,out);
435 /* roatate + window */
438 DATA_TYPE *oX1=out+n2+n4;
439 DATA_TYPE *oX2=out+n2+n4;
446 oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
447 oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
449 oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
450 oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
452 oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
453 oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
455 oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
456 oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
471 oX2[0] = -(oX1[3] = iX[3]);
472 oX2[1] = -(oX1[2] = iX[2]);
473 oX2[2] = -(oX1[1] = iX[1]);
474 oX2[3] = -(oX1[0] = iX[0]);
493 void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
498 DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
503 /* window + rotate + step 1 */
507 DATA_TYPE *x0=in+n2+n4;
509 DATA_TYPE *T=init->trig+n2;
518 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
519 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
530 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
531 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
542 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
543 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
548 mdct_butterflies(init,w+n2,n2);
549 mdct_bitreverse(init,w);
551 /* roatate + window */
558 out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
559 x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);