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 ]
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]);