1
/********************************************************************
3
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
5
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
9
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12
********************************************************************
14
function: normalized modified discrete cosine transform
15
power of two length transform only [64 <= n ]
16
last mod: $Id: mdct.c,v 1.1 2004/12/30 12:09:20 henry Exp $
18
Original algorithm adapted long ago from _The use of multirate filter
19
banks for coding of high quality digital audio_, by T. Sporer,
20
K. Brandenburg and B. Edler, collection of the European Signal
21
Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
24
The below code implements an algorithm that no longer looks much like
25
that presented in the paper, but the basic structure remains if you
26
dig deep enough to see it.
28
This module DOES NOT INCLUDE code to generate/apply the window
29
function. Everybody has their own weird favorite including me... I
30
happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
33
********************************************************************/
35
#include "ivorbiscodec.h"
39
#include "mdct_lookup.h"
42
/* 8 point butterfly (in place) */
43
STIN void mdct_butterfly_8(DATA_TYPE *x){
45
REG_TYPE r0 = x[4] + x[0];
46
REG_TYPE r1 = x[4] - x[0];
47
REG_TYPE r2 = x[5] + x[1];
48
REG_TYPE r3 = x[5] - x[1];
49
REG_TYPE r4 = x[6] + x[2];
50
REG_TYPE r5 = x[6] - x[2];
51
REG_TYPE r6 = x[7] + x[3];
52
REG_TYPE r7 = x[7] - x[3];
65
/* 16 point butterfly (in place, 4 register) */
66
STIN void mdct_butterfly_16(DATA_TYPE *x){
70
r0 = x[ 0] - x[ 8]; x[ 8] += x[ 0];
71
r1 = x[ 1] - x[ 9]; x[ 9] += x[ 1];
72
x[ 0] = MULT31((r0 + r1) , cPI2_8);
73
x[ 1] = MULT31((r1 - r0) , cPI2_8);
76
r0 = x[10] - x[ 2]; x[10] += x[ 2];
77
r1 = x[ 3] - x[11]; x[11] += x[ 3];
78
x[ 2] = r1; x[ 3] = r0;
81
r0 = x[12] - x[ 4]; x[12] += x[ 4];
82
r1 = x[13] - x[ 5]; x[13] += x[ 5];
83
x[ 4] = MULT31((r0 - r1) , cPI2_8);
84
x[ 5] = MULT31((r0 + r1) , cPI2_8);
87
r0 = x[14] - x[ 6]; x[14] += x[ 6];
88
r1 = x[15] - x[ 7]; x[15] += x[ 7];
89
x[ 6] = r0; x[ 7] = r1;
93
mdct_butterfly_8(x+8);
96
/* 32 point butterfly (in place, 4 register) */
97
STIN void mdct_butterfly_32(DATA_TYPE *x){
101
r0 = x[30] - x[14]; x[30] += x[14];
102
r1 = x[31] - x[15]; x[31] += x[15];
103
x[14] = r0; x[15] = r1;
106
r0 = x[28] - x[12]; x[28] += x[12];
107
r1 = x[29] - x[13]; x[29] += x[13];
108
XNPROD31( r0, r1, cPI1_8, cPI3_8, &x[12], &x[13] );
111
r0 = x[26] - x[10]; x[26] += x[10];
112
r1 = x[27] - x[11]; x[27] += x[11];
113
x[10] = MULT31((r0 - r1) , cPI2_8);
114
x[11] = MULT31((r0 + r1) , cPI2_8);
117
r0 = x[24] - x[ 8]; x[24] += x[ 8];
118
r1 = x[25] - x[ 9]; x[25] += x[ 9];
119
XNPROD31( r0, r1, cPI3_8, cPI1_8, &x[ 8], &x[ 9] );
122
r0 = x[22] - x[ 6]; x[22] += x[ 6];
123
r1 = x[ 7] - x[23]; x[23] += x[ 7];
124
x[ 6] = r1; x[ 7] = r0;
127
r0 = x[ 4] - x[20]; x[20] += x[ 4];
128
r1 = x[ 5] - x[21]; x[21] += x[ 5];
129
XPROD31 ( r0, r1, cPI3_8, cPI1_8, &x[ 4], &x[ 5] );
132
r0 = x[ 2] - x[18]; x[18] += x[ 2];
133
r1 = x[ 3] - x[19]; x[19] += x[ 3];
134
x[ 2] = MULT31((r1 + r0) , cPI2_8);
135
x[ 3] = MULT31((r1 - r0) , cPI2_8);
138
r0 = x[ 0] - x[16]; x[16] += x[ 0];
139
r1 = x[ 1] - x[17]; x[17] += x[ 1];
140
XPROD31 ( r0, r1, cPI1_8, cPI3_8, &x[ 0], &x[ 1] );
143
mdct_butterfly_16(x);
144
mdct_butterfly_16(x+16);
147
/* N/stage point generic N stage butterfly (in place, 2 register) */
148
STIN void mdct_butterfly_generic(DATA_TYPE *x,int points,int step){
150
LOOKUP_T *T = sincos_lookup0;
151
DATA_TYPE *x1 = x + points - 8;
152
DATA_TYPE *x2 = x + (points>>1) - 8;
157
r0 = x1[6] - x2[6]; x1[6] += x2[6];
158
r1 = x2[7] - x1[7]; x1[7] += x2[7];
159
XPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T+=step;
161
r0 = x1[4] - x2[4]; x1[4] += x2[4];
162
r1 = x2[5] - x1[5]; x1[5] += x2[5];
163
XPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T+=step;
165
r0 = x1[2] - x2[2]; x1[2] += x2[2];
166
r1 = x2[3] - x1[3]; x1[3] += x2[3];
167
XPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T+=step;
169
r0 = x1[0] - x2[0]; x1[0] += x2[0];
170
r1 = x2[1] - x1[1]; x1[1] += x2[1];
171
XPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T+=step;
174
}while(T<sincos_lookup0+1024);
176
r0 = x1[6] - x2[6]; x1[6] += x2[6];
177
r1 = x1[7] - x2[7]; x1[7] += x2[7];
178
XNPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T-=step;
180
r0 = x1[4] - x2[4]; x1[4] += x2[4];
181
r1 = x1[5] - x2[5]; x1[5] += x2[5];
182
XNPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T-=step;
184
r0 = x1[2] - x2[2]; x1[2] += x2[2];
185
r1 = x1[3] - x2[3]; x1[3] += x2[3];
186
XNPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T-=step;
188
r0 = x1[0] - x2[0]; x1[0] += x2[0];
189
r1 = x1[1] - x2[1]; x1[1] += x2[1];
190
XNPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T-=step;
193
}while(T>sincos_lookup0);
195
r0 = x2[6] - x1[6]; x1[6] += x2[6];
196
r1 = x2[7] - x1[7]; x1[7] += x2[7];
197
XPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T+=step;
199
r0 = x2[4] - x1[4]; x1[4] += x2[4];
200
r1 = x2[5] - x1[5]; x1[5] += x2[5];
201
XPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T+=step;
203
r0 = x2[2] - x1[2]; x1[2] += x2[2];
204
r1 = x2[3] - x1[3]; x1[3] += x2[3];
205
XPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T+=step;
207
r0 = x2[0] - x1[0]; x1[0] += x2[0];
208
r1 = x2[1] - x1[1]; x1[1] += x2[1];
209
XPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T+=step;
212
}while(T<sincos_lookup0+1024);
214
r0 = x1[6] - x2[6]; x1[6] += x2[6];
215
r1 = x2[7] - x1[7]; x1[7] += x2[7];
216
XNPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T-=step;
218
r0 = x1[4] - x2[4]; x1[4] += x2[4];
219
r1 = x2[5] - x1[5]; x1[5] += x2[5];
220
XNPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T-=step;
222
r0 = x1[2] - x2[2]; x1[2] += x2[2];
223
r1 = x2[3] - x1[3]; x1[3] += x2[3];
224
XNPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T-=step;
226
r0 = x1[0] - x2[0]; x1[0] += x2[0];
227
r1 = x2[1] - x1[1]; x1[1] += x2[1];
228
XNPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T-=step;
231
}while(T>sincos_lookup0);
234
STIN void mdct_butterflies(DATA_TYPE *x,int points,int shift){
239
for(i=0;--stages>0;i++){
240
for(j=0;j<(1<<i);j++)
241
mdct_butterfly_generic(x+(points>>i)*j,points>>i,4<<(i+shift));
244
for(j=0;j<points;j+=32)
245
mdct_butterfly_32(x+j);
249
static unsigned char bitrev[16]={0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
251
STIN int bitrev12(int x){
252
return bitrev[x>>8]|(bitrev[(x&0x0f0)>>4]<<4)|(((int)bitrev[x&0x00f])<<8);
255
STIN void mdct_bitreverse(DATA_TYPE *x,int n,int step,int shift){
259
DATA_TYPE *w1 = x = w0+(n>>1);
260
LOOKUP_T *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
261
LOOKUP_T *Ttop = T+1024;
265
DATA_TYPE r3 = bitrev12(bit++);
266
DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1;
267
DATA_TYPE *x1 = x + (r3>>shift);
269
REG_TYPE r0 = x0[0] + x1[0];
270
REG_TYPE r1 = x1[1] - x0[1];
272
XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step;
276
r0 = (x0[1] + x1[1])>>1;
277
r1 = (x0[0] - x1[0])>>1;
283
r3 = bitrev12(bit++);
284
x0 = x + ((r3 ^ 0xfff)>>shift) -1;
285
x1 = x + (r3>>shift);
290
XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step;
292
r0 = (x0[1] + x1[1])>>1;
293
r1 = (x0[0] - x1[0])>>1;
302
DATA_TYPE r3 = bitrev12(bit++);
303
DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1;
304
DATA_TYPE *x1 = x + (r3>>shift);
306
REG_TYPE r0 = x0[0] + x1[0];
307
REG_TYPE r1 = x1[1] - x0[1];
309
T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
313
r0 = (x0[1] + x1[1])>>1;
314
r1 = (x0[0] - x1[0])>>1;
320
r3 = bitrev12(bit++);
321
x0 = x + ((r3 ^ 0xfff)>>shift) -1;
322
x1 = x + (r3>>shift);
327
T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
329
r0 = (x0[1] + x1[1])>>1;
330
r1 = (x0[0] - x1[0])>>1;
340
void mdct_backward(int n, DATA_TYPE *in, DATA_TYPE *out){
350
for (shift=6;!(n&(1<<shift));shift++);
362
XPROD31( iX[4], iX[6], T[0], T[1], &oX[2], &oX[3] ); T+=step;
363
XPROD31( iX[0], iX[2], T[0], T[1], &oX[0], &oX[1] ); T+=step;
368
XPROD31( iX[4], iX[6], T[1], T[0], &oX[2], &oX[3] ); T-=step;
369
XPROD31( iX[0], iX[2], T[1], T[0], &oX[0], &oX[1] ); T-=step;
378
T+=step; XNPROD31( iX[6], iX[4], T[0], T[1], &oX[0], &oX[1] );
379
T+=step; XNPROD31( iX[2], iX[0], T[0], T[1], &oX[2], &oX[3] );
384
T-=step; XNPROD31( iX[6], iX[4], T[1], T[0], &oX[0], &oX[1] );
385
T-=step; XNPROD31( iX[2], iX[0], T[1], T[0], &oX[2], &oX[3] );
390
mdct_butterflies(out+n2,n2,shift);
391
mdct_bitreverse(out,n,step,shift);
393
/* rotate + window */
397
DATA_TYPE *oX1=out+n2+n4;
398
DATA_TYPE *oX2=out+n2+n4;
403
T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
406
XPROD31( iX[0], -iX[1], T[0], T[1], &oX1[3], &oX2[0] ); T+=step;
407
XPROD31( iX[2], -iX[3], T[0], T[1], &oX1[2], &oX2[1] ); T+=step;
408
XPROD31( iX[4], -iX[5], T[0], T[1], &oX1[1], &oX2[2] ); T+=step;
409
XPROD31( iX[6], -iX[7], T[0], T[1], &oX1[0], &oX2[3] ); T+=step;
417
/* linear interpolation between table values: offset=0.5, step=1 */
418
REG_TYPE t0,t1,v0,v1;
426
t0 += (v0 = (*V++)>>1);
427
t1 += (v1 = (*V++)>>1);
428
XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
429
v0 += (t0 = (*T++)>>1);
430
v1 += (t1 = (*T++)>>1);
431
XPROD31( iX[2], -iX[3], v0, v1, &oX1[2], &oX2[1] );
432
t0 += (v0 = (*V++)>>1);
433
t1 += (v1 = (*V++)>>1);
434
XPROD31( iX[4], -iX[5], t0, t1, &oX1[1], &oX2[2] );
435
v0 += (t0 = (*T++)>>1);
436
v1 += (t1 = (*T++)>>1);
437
XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
446
/* linear interpolation between table values: offset=0.25, step=0.5 */
447
REG_TYPE t0,t1,v0,v1,q0,q1;
457
t0 += (q0 = (v0-t0)>>2);
458
t1 += (q1 = (v1-t1)>>2);
459
XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
462
XPROD31( iX[2], -iX[3], t0, t1, &oX1[2], &oX2[1] );
466
v0 += (q0 = (t0-v0)>>2);
467
v1 += (q1 = (t1-v1)>>2);
468
XPROD31( iX[4], -iX[5], v0, v1, &oX1[1], &oX2[2] );
471
XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
488
oX2[0] = -(oX1[3] = iX[3]);
489
oX2[1] = -(oX1[2] = iX[2]);
490
oX2[2] = -(oX1[1] = iX[1]);
491
oX2[3] = -(oX1[0] = iX[0]);