00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <math.h>
00044 #include "vorbis/codec.h"
00045 #include "mdct.h"
00046 #include "os.h"
00047 #include "misc.h"
00048
00049
00050
00051
00052 void mdct_init(mdct_lookup *lookup,int n){
00053 int *bitrev=(int*)_ogg_malloc(sizeof(*bitrev)*(n/4));
00054 DATA_TYPE *T=(float*)_ogg_malloc(sizeof(*T)*(n+n/4));
00055
00056 int i;
00057 int n2=n>>1;
00058 int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
00059 lookup->n=n;
00060 lookup->trig=T;
00061 lookup->bitrev=bitrev;
00062
00063
00064
00065 for(i=0;i<n/4;i++){
00066 T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
00067 T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
00068 T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
00069 T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
00070 }
00071 for(i=0;i<n/8;i++){
00072 T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
00073 T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
00074 }
00075
00076
00077
00078 {
00079 int mask=(1<<(log2n-1))-1,i,j;
00080 int msb=1<<(log2n-2);
00081 for(i=0;i<n/8;i++){
00082 int acc=0;
00083 for(j=0;msb>>j;j++)
00084 if((msb>>j)&i)acc|=1<<j;
00085 bitrev[i*2]=((~acc)&mask)-1;
00086 bitrev[i*2+1]=acc;
00087
00088 }
00089 }
00090 lookup->scale=FLOAT_CONV(4.f/n);
00091 }
00092
00093
00094 STIN void mdct_butterfly_8(DATA_TYPE *x){
00095 REG_TYPE r0 = x[6] + x[2];
00096 REG_TYPE r1 = x[6] - x[2];
00097 REG_TYPE r2 = x[4] + x[0];
00098 REG_TYPE r3 = x[4] - x[0];
00099
00100 x[6] = r0 + r2;
00101 x[4] = r0 - r2;
00102
00103 r0 = x[5] - x[1];
00104 r2 = x[7] - x[3];
00105 x[0] = r1 + r0;
00106 x[2] = r1 - r0;
00107
00108 r0 = x[5] + x[1];
00109 r1 = x[7] + x[3];
00110 x[3] = r2 + r3;
00111 x[1] = r2 - r3;
00112 x[7] = r1 + r0;
00113 x[5] = r1 - r0;
00114
00115 }
00116
00117
00118 STIN void mdct_butterfly_16(DATA_TYPE *x){
00119 REG_TYPE r0 = x[1] - x[9];
00120 REG_TYPE r1 = x[0] - x[8];
00121
00122 x[8] += x[0];
00123 x[9] += x[1];
00124 x[0] = MULT_NORM((r0 + r1) * cPI2_8);
00125 x[1] = MULT_NORM((r0 - r1) * cPI2_8);
00126
00127 r0 = x[3] - x[11];
00128 r1 = x[10] - x[2];
00129 x[10] += x[2];
00130 x[11] += x[3];
00131 x[2] = r0;
00132 x[3] = r1;
00133
00134 r0 = x[12] - x[4];
00135 r1 = x[13] - x[5];
00136 x[12] += x[4];
00137 x[13] += x[5];
00138 x[4] = MULT_NORM((r0 - r1) * cPI2_8);
00139 x[5] = MULT_NORM((r0 + r1) * cPI2_8);
00140
00141 r0 = x[14] - x[6];
00142 r1 = x[15] - x[7];
00143 x[14] += x[6];
00144 x[15] += x[7];
00145 x[6] = r0;
00146 x[7] = r1;
00147
00148 mdct_butterfly_8(x);
00149 mdct_butterfly_8(x+8);
00150 }
00151
00152
00153 STIN void mdct_butterfly_32(DATA_TYPE *x){
00154 REG_TYPE r0 = x[30] - x[14];
00155 REG_TYPE r1 = x[31] - x[15];
00156
00157 x[30] += x[14];
00158 x[31] += x[15];
00159 x[14] = r0;
00160 x[15] = r1;
00161
00162 r0 = x[28] - x[12];
00163 r1 = x[29] - x[13];
00164 x[28] += x[12];
00165 x[29] += x[13];
00166 x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 );
00167 x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 );
00168
00169 r0 = x[26] - x[10];
00170 r1 = x[27] - x[11];
00171 x[26] += x[10];
00172 x[27] += x[11];
00173 x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8);
00174 x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8);
00175
00176 r0 = x[24] - x[8];
00177 r1 = x[25] - x[9];
00178 x[24] += x[8];
00179 x[25] += x[9];
00180 x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 );
00181 x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
00182
00183 r0 = x[22] - x[6];
00184 r1 = x[7] - x[23];
00185 x[22] += x[6];
00186 x[23] += x[7];
00187 x[6] = r1;
00188 x[7] = r0;
00189
00190 r0 = x[4] - x[20];
00191 r1 = x[5] - x[21];
00192 x[20] += x[4];
00193 x[21] += x[5];
00194 x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 );
00195 x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 );
00196
00197 r0 = x[2] - x[18];
00198 r1 = x[3] - x[19];
00199 x[18] += x[2];
00200 x[19] += x[3];
00201 x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8);
00202 x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8);
00203
00204 r0 = x[0] - x[16];
00205 r1 = x[1] - x[17];
00206 x[16] += x[0];
00207 x[17] += x[1];
00208 x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
00209 x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 );
00210
00211 mdct_butterfly_16(x);
00212 mdct_butterfly_16(x+16);
00213
00214 }
00215
00216
00217 STIN void mdct_butterfly_first(DATA_TYPE *T,
00218 DATA_TYPE *x,
00219 int points){
00220
00221 DATA_TYPE *x1 = x + points - 8;
00222 DATA_TYPE *x2 = x + (points>>1) - 8;
00223 REG_TYPE r0;
00224 REG_TYPE r1;
00225
00226 do{
00227
00228 r0 = x1[6] - x2[6];
00229 r1 = x1[7] - x2[7];
00230 x1[6] += x2[6];
00231 x1[7] += x2[7];
00232 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
00233 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
00234
00235 r0 = x1[4] - x2[4];
00236 r1 = x1[5] - x2[5];
00237 x1[4] += x2[4];
00238 x1[5] += x2[5];
00239 x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]);
00240 x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]);
00241
00242 r0 = x1[2] - x2[2];
00243 r1 = x1[3] - x2[3];
00244 x1[2] += x2[2];
00245 x1[3] += x2[3];
00246 x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]);
00247 x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]);
00248
00249 r0 = x1[0] - x2[0];
00250 r1 = x1[1] - x2[1];
00251 x1[0] += x2[0];
00252 x1[1] += x2[1];
00253 x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]);
00254 x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]);
00255
00256 x1-=8;
00257 x2-=8;
00258 T+=16;
00259
00260 }while(x2>=x);
00261 }
00262
00263
00264 STIN void mdct_butterfly_generic(DATA_TYPE *T,
00265 DATA_TYPE *x,
00266 int points,
00267 int trigint){
00268
00269 DATA_TYPE *x1 = x + points - 8;
00270 DATA_TYPE *x2 = x + (points>>1) - 8;
00271 REG_TYPE r0;
00272 REG_TYPE r1;
00273
00274 do{
00275
00276 r0 = x1[6] - x2[6];
00277 r1 = x1[7] - x2[7];
00278 x1[6] += x2[6];
00279 x1[7] += x2[7];
00280 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
00281 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
00282
00283 T+=trigint;
00284
00285 r0 = x1[4] - x2[4];
00286 r1 = x1[5] - x2[5];
00287 x1[4] += x2[4];
00288 x1[5] += x2[5];
00289 x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]);
00290 x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]);
00291
00292 T+=trigint;
00293
00294 r0 = x1[2] - x2[2];
00295 r1 = x1[3] - x2[3];
00296 x1[2] += x2[2];
00297 x1[3] += x2[3];
00298 x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]);
00299 x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]);
00300
00301 T+=trigint;
00302
00303 r0 = x1[0] - x2[0];
00304 r1 = x1[1] - x2[1];
00305 x1[0] += x2[0];
00306 x1[1] += x2[1];
00307 x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]);
00308 x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
00309
00310 T+=trigint;
00311 x1-=8;
00312 x2-=8;
00313
00314 }while(x2>=x);
00315 }
00316
00317 STIN void mdct_butterflies(mdct_lookup *init,
00318 DATA_TYPE *x,
00319 int points){
00320
00321 DATA_TYPE *T=init->trig;
00322 int stages=init->log2n-5;
00323 int i,j;
00324
00325 if(--stages>0){
00326 mdct_butterfly_first(T,x,points);
00327 }
00328
00329 for(i=1;--stages>0;i++){
00330 for(j=0;j<(1<<i);j++)
00331 mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
00332 }
00333
00334 for(j=0;j<points;j+=32)
00335 mdct_butterfly_32(x+j);
00336
00337 }
00338
00339 void mdct_clear(mdct_lookup *l){
00340 if(l){
00341 if(l->trig)_ogg_free(l->trig);
00342 if(l->bitrev)_ogg_free(l->bitrev);
00343 memset(l,0,sizeof(*l));
00344 }
00345 }
00346
00347 STIN void mdct_bitreverse(mdct_lookup *init,
00348 DATA_TYPE *x){
00349 int n = init->n;
00350 int *bit = init->bitrev;
00351 DATA_TYPE *w0 = x;
00352 DATA_TYPE *w1 = x = w0+(n>>1);
00353 DATA_TYPE *T = init->trig+n;
00354
00355 do{
00356 DATA_TYPE *x0 = x+bit[0];
00357 DATA_TYPE *x1 = x+bit[1];
00358
00359 REG_TYPE r0 = x0[1] - x1[1];
00360 REG_TYPE r1 = x0[0] + x1[0];
00361 REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]);
00362 REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]);
00363
00364 w1 -= 4;
00365
00366 r0 = HALVE(x0[1] + x1[1]);
00367 r1 = HALVE(x0[0] - x1[0]);
00368
00369 w0[0] = r0 + r2;
00370 w1[2] = r0 - r2;
00371 w0[1] = r1 + r3;
00372 w1[3] = r3 - r1;
00373
00374 x0 = x+bit[2];
00375 x1 = x+bit[3];
00376
00377 r0 = x0[1] - x1[1];
00378 r1 = x0[0] + x1[0];
00379 r2 = MULT_NORM(r1 * T[2] + r0 * T[3]);
00380 r3 = MULT_NORM(r1 * T[3] - r0 * T[2]);
00381
00382 r0 = HALVE(x0[1] + x1[1]);
00383 r1 = HALVE(x0[0] - x1[0]);
00384
00385 w0[2] = r0 + r2;
00386 w1[0] = r0 - r2;
00387 w0[3] = r1 + r3;
00388 w1[1] = r3 - r1;
00389
00390 T += 4;
00391 bit += 4;
00392 w0 += 4;
00393
00394 }while(w0<w1);
00395 }
00396
00397 void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
00398 int n=init->n;
00399 int n2=n>>1;
00400 int n4=n>>2;
00401
00402
00403
00404 DATA_TYPE *iX = in+n2-7;
00405 DATA_TYPE *oX = out+n2+n4;
00406 DATA_TYPE *T = init->trig+n4;
00407
00408 do{
00409 oX -= 4;
00410 oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]);
00411 oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]);
00412 oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]);
00413 oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]);
00414 iX -= 8;
00415 T += 4;
00416 }while(iX>=in);
00417
00418 iX = in+n2-8;
00419 oX = out+n2+n4;
00420 T = init->trig+n4;
00421
00422 do{
00423 T -= 4;
00424 oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
00425 oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
00426 oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
00427 oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
00428 iX -= 8;
00429 oX += 4;
00430 }while(iX>=in);
00431
00432 mdct_butterflies(init,out+n2,n2);
00433 mdct_bitreverse(init,out);
00434
00435
00436
00437 {
00438 DATA_TYPE *oX1=out+n2+n4;
00439 DATA_TYPE *oX2=out+n2+n4;
00440 DATA_TYPE *iX =out;
00441 T =init->trig+n2;
00442
00443 do{
00444 oX1-=4;
00445
00446 oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
00447 oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
00448
00449 oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
00450 oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
00451
00452 oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
00453 oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
00454
00455 oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
00456 oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
00457
00458 oX2+=4;
00459 iX += 8;
00460 T += 8;
00461 }while(iX<oX1);
00462
00463 iX=out+n2+n4;
00464 oX1=out+n4;
00465 oX2=oX1;
00466
00467 do{
00468 oX1-=4;
00469 iX-=4;
00470
00471 oX2[0] = -(oX1[3] = iX[3]);
00472 oX2[1] = -(oX1[2] = iX[2]);
00473 oX2[2] = -(oX1[1] = iX[1]);
00474 oX2[3] = -(oX1[0] = iX[0]);
00475
00476 oX2+=4;
00477 }while(oX2<iX);
00478
00479 iX=out+n2+n4;
00480 oX1=out+n2+n4;
00481 oX2=out+n2;
00482 do{
00483 oX1-=4;
00484 oX1[0]= iX[3];
00485 oX1[1]= iX[2];
00486 oX1[2]= iX[1];
00487 oX1[3]= iX[0];
00488 iX+=4;
00489 }while(oX1>oX2);
00490 }
00491 }
00492
00493 void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
00494 int n=init->n;
00495 int n2=n>>1;
00496 int n4=n>>2;
00497 int n8=n>>3;
00498
00499 DATA_TYPE *w=(DATA_TYPE*)_ogg_malloc(n*sizeof(*w));
00500 DATA_TYPE *w_cpy = w;
00501 DATA_TYPE *w2=w+n2;
00502
00503
00504
00505
00506
00507 REG_TYPE r0;
00508 REG_TYPE r1;
00509 DATA_TYPE *x0=in+n2+n4;
00510 DATA_TYPE *x1=x0+1;
00511 DATA_TYPE *T=init->trig+n2;
00512
00513 int i=0;
00514
00515 for(i=0;i<n8;i+=2){
00516 x0 -=4;
00517 T-=2;
00518 r0= x0[2] + x1[0];
00519 r1= x0[0] + x1[2];
00520 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
00521 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
00522 x1 +=4;
00523 }
00524
00525 x1=in+1;
00526
00527 for(;i<n2-n8;i+=2){
00528 T-=2;
00529 x0 -=4;
00530 r0= x0[2] - x1[0];
00531 r1= x0[0] - x1[2];
00532 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
00533 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
00534 x1 +=4;
00535 }
00536
00537 x0=in+n;
00538
00539 for(;i<n2;i+=2){
00540 T-=2;
00541 x0 -=4;
00542 r0= -x0[2] - x1[0];
00543 r1= -x0[0] - x1[2];
00544 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
00545 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
00546 x1 +=4;
00547 }
00548
00549
00550 mdct_butterflies(init,w+n2,n2);
00551 mdct_bitreverse(init,w);
00552
00553
00554
00555 T=init->trig+n2;
00556 x0=out+n2;
00557
00558 for(i=0;i<n4;i++){
00559 x0--;
00560 out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
00561 x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
00562 w+=2;
00563 T+=2;
00564 }
00565 free(w_cpy);
00566 }
00567