annotate src/libvorbis-1.3.3/lib/mdct.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 05aa0afa9217
children
rev   line source
Chris@1 1 /********************************************************************
Chris@1 2 * *
Chris@1 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
Chris@1 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
Chris@1 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Chris@1 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
Chris@1 7 * *
Chris@1 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
Chris@1 9 * by the Xiph.Org Foundation http://www.xiph.org/ *
Chris@1 10 * *
Chris@1 11 ********************************************************************
Chris@1 12
Chris@1 13 function: normalized modified discrete cosine transform
Chris@1 14 power of two length transform only [64 <= n ]
Chris@1 15 last mod: $Id: mdct.c 16227 2009-07-08 06:58:46Z xiphmont $
Chris@1 16
Chris@1 17 Original algorithm adapted long ago from _The use of multirate filter
Chris@1 18 banks for coding of high quality digital audio_, by T. Sporer,
Chris@1 19 K. Brandenburg and B. Edler, collection of the European Signal
Chris@1 20 Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
Chris@1 21 211-214
Chris@1 22
Chris@1 23 The below code implements an algorithm that no longer looks much like
Chris@1 24 that presented in the paper, but the basic structure remains if you
Chris@1 25 dig deep enough to see it.
Chris@1 26
Chris@1 27 This module DOES NOT INCLUDE code to generate/apply the window
Chris@1 28 function. Everybody has their own weird favorite including me... I
Chris@1 29 happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
Chris@1 30 vehemently disagree.
Chris@1 31
Chris@1 32 ********************************************************************/
Chris@1 33
Chris@1 34 /* this can also be run as an integer transform by uncommenting a
Chris@1 35 define in mdct.h; the integerization is a first pass and although
Chris@1 36 it's likely stable for Vorbis, the dynamic range is constrained and
Chris@1 37 roundoff isn't done (so it's noisy). Consider it functional, but
Chris@1 38 only a starting point. There's no point on a machine with an FPU */
Chris@1 39
Chris@1 40 #include <stdio.h>
Chris@1 41 #include <stdlib.h>
Chris@1 42 #include <string.h>
Chris@1 43 #include <math.h>
Chris@1 44 #include "vorbis/codec.h"
Chris@1 45 #include "mdct.h"
Chris@1 46 #include "os.h"
Chris@1 47 #include "misc.h"
Chris@1 48
Chris@1 49 /* build lookups for trig functions; also pre-figure scaling and
Chris@1 50 some window function algebra. */
Chris@1 51
Chris@1 52 void mdct_init(mdct_lookup *lookup,int n){
Chris@1 53 int *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
Chris@1 54 DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
Chris@1 55
Chris@1 56 int i;
Chris@1 57 int n2=n>>1;
Chris@1 58 int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
Chris@1 59 lookup->n=n;
Chris@1 60 lookup->trig=T;
Chris@1 61 lookup->bitrev=bitrev;
Chris@1 62
Chris@1 63 /* trig lookups... */
Chris@1 64
Chris@1 65 for(i=0;i<n/4;i++){
Chris@1 66 T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
Chris@1 67 T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
Chris@1 68 T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
Chris@1 69 T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
Chris@1 70 }
Chris@1 71 for(i=0;i<n/8;i++){
Chris@1 72 T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
Chris@1 73 T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
Chris@1 74 }
Chris@1 75
Chris@1 76 /* bitreverse lookup... */
Chris@1 77
Chris@1 78 {
Chris@1 79 int mask=(1<<(log2n-1))-1,i,j;
Chris@1 80 int msb=1<<(log2n-2);
Chris@1 81 for(i=0;i<n/8;i++){
Chris@1 82 int acc=0;
Chris@1 83 for(j=0;msb>>j;j++)
Chris@1 84 if((msb>>j)&i)acc|=1<<j;
Chris@1 85 bitrev[i*2]=((~acc)&mask)-1;
Chris@1 86 bitrev[i*2+1]=acc;
Chris@1 87
Chris@1 88 }
Chris@1 89 }
Chris@1 90 lookup->scale=FLOAT_CONV(4.f/n);
Chris@1 91 }
Chris@1 92
Chris@1 93 /* 8 point butterfly (in place, 4 register) */
Chris@1 94 STIN void mdct_butterfly_8(DATA_TYPE *x){
Chris@1 95 REG_TYPE r0 = x[6] + x[2];
Chris@1 96 REG_TYPE r1 = x[6] - x[2];
Chris@1 97 REG_TYPE r2 = x[4] + x[0];
Chris@1 98 REG_TYPE r3 = x[4] - x[0];
Chris@1 99
Chris@1 100 x[6] = r0 + r2;
Chris@1 101 x[4] = r0 - r2;
Chris@1 102
Chris@1 103 r0 = x[5] - x[1];
Chris@1 104 r2 = x[7] - x[3];
Chris@1 105 x[0] = r1 + r0;
Chris@1 106 x[2] = r1 - r0;
Chris@1 107
Chris@1 108 r0 = x[5] + x[1];
Chris@1 109 r1 = x[7] + x[3];
Chris@1 110 x[3] = r2 + r3;
Chris@1 111 x[1] = r2 - r3;
Chris@1 112 x[7] = r1 + r0;
Chris@1 113 x[5] = r1 - r0;
Chris@1 114
Chris@1 115 }
Chris@1 116
Chris@1 117 /* 16 point butterfly (in place, 4 register) */
Chris@1 118 STIN void mdct_butterfly_16(DATA_TYPE *x){
Chris@1 119 REG_TYPE r0 = x[1] - x[9];
Chris@1 120 REG_TYPE r1 = x[0] - x[8];
Chris@1 121
Chris@1 122 x[8] += x[0];
Chris@1 123 x[9] += x[1];
Chris@1 124 x[0] = MULT_NORM((r0 + r1) * cPI2_8);
Chris@1 125 x[1] = MULT_NORM((r0 - r1) * cPI2_8);
Chris@1 126
Chris@1 127 r0 = x[3] - x[11];
Chris@1 128 r1 = x[10] - x[2];
Chris@1 129 x[10] += x[2];
Chris@1 130 x[11] += x[3];
Chris@1 131 x[2] = r0;
Chris@1 132 x[3] = r1;
Chris@1 133
Chris@1 134 r0 = x[12] - x[4];
Chris@1 135 r1 = x[13] - x[5];
Chris@1 136 x[12] += x[4];
Chris@1 137 x[13] += x[5];
Chris@1 138 x[4] = MULT_NORM((r0 - r1) * cPI2_8);
Chris@1 139 x[5] = MULT_NORM((r0 + r1) * cPI2_8);
Chris@1 140
Chris@1 141 r0 = x[14] - x[6];
Chris@1 142 r1 = x[15] - x[7];
Chris@1 143 x[14] += x[6];
Chris@1 144 x[15] += x[7];
Chris@1 145 x[6] = r0;
Chris@1 146 x[7] = r1;
Chris@1 147
Chris@1 148 mdct_butterfly_8(x);
Chris@1 149 mdct_butterfly_8(x+8);
Chris@1 150 }
Chris@1 151
Chris@1 152 /* 32 point butterfly (in place, 4 register) */
Chris@1 153 STIN void mdct_butterfly_32(DATA_TYPE *x){
Chris@1 154 REG_TYPE r0 = x[30] - x[14];
Chris@1 155 REG_TYPE r1 = x[31] - x[15];
Chris@1 156
Chris@1 157 x[30] += x[14];
Chris@1 158 x[31] += x[15];
Chris@1 159 x[14] = r0;
Chris@1 160 x[15] = r1;
Chris@1 161
Chris@1 162 r0 = x[28] - x[12];
Chris@1 163 r1 = x[29] - x[13];
Chris@1 164 x[28] += x[12];
Chris@1 165 x[29] += x[13];
Chris@1 166 x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 );
Chris@1 167 x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 );
Chris@1 168
Chris@1 169 r0 = x[26] - x[10];
Chris@1 170 r1 = x[27] - x[11];
Chris@1 171 x[26] += x[10];
Chris@1 172 x[27] += x[11];
Chris@1 173 x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8);
Chris@1 174 x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8);
Chris@1 175
Chris@1 176 r0 = x[24] - x[8];
Chris@1 177 r1 = x[25] - x[9];
Chris@1 178 x[24] += x[8];
Chris@1 179 x[25] += x[9];
Chris@1 180 x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 );
Chris@1 181 x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
Chris@1 182
Chris@1 183 r0 = x[22] - x[6];
Chris@1 184 r1 = x[7] - x[23];
Chris@1 185 x[22] += x[6];
Chris@1 186 x[23] += x[7];
Chris@1 187 x[6] = r1;
Chris@1 188 x[7] = r0;
Chris@1 189
Chris@1 190 r0 = x[4] - x[20];
Chris@1 191 r1 = x[5] - x[21];
Chris@1 192 x[20] += x[4];
Chris@1 193 x[21] += x[5];
Chris@1 194 x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 );
Chris@1 195 x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 );
Chris@1 196
Chris@1 197 r0 = x[2] - x[18];
Chris@1 198 r1 = x[3] - x[19];
Chris@1 199 x[18] += x[2];
Chris@1 200 x[19] += x[3];
Chris@1 201 x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8);
Chris@1 202 x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8);
Chris@1 203
Chris@1 204 r0 = x[0] - x[16];
Chris@1 205 r1 = x[1] - x[17];
Chris@1 206 x[16] += x[0];
Chris@1 207 x[17] += x[1];
Chris@1 208 x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 );
Chris@1 209 x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 );
Chris@1 210
Chris@1 211 mdct_butterfly_16(x);
Chris@1 212 mdct_butterfly_16(x+16);
Chris@1 213
Chris@1 214 }
Chris@1 215
Chris@1 216 /* N point first stage butterfly (in place, 2 register) */
Chris@1 217 STIN void mdct_butterfly_first(DATA_TYPE *T,
Chris@1 218 DATA_TYPE *x,
Chris@1 219 int points){
Chris@1 220
Chris@1 221 DATA_TYPE *x1 = x + points - 8;
Chris@1 222 DATA_TYPE *x2 = x + (points>>1) - 8;
Chris@1 223 REG_TYPE r0;
Chris@1 224 REG_TYPE r1;
Chris@1 225
Chris@1 226 do{
Chris@1 227
Chris@1 228 r0 = x1[6] - x2[6];
Chris@1 229 r1 = x1[7] - x2[7];
Chris@1 230 x1[6] += x2[6];
Chris@1 231 x1[7] += x2[7];
Chris@1 232 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
Chris@1 233 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
Chris@1 234
Chris@1 235 r0 = x1[4] - x2[4];
Chris@1 236 r1 = x1[5] - x2[5];
Chris@1 237 x1[4] += x2[4];
Chris@1 238 x1[5] += x2[5];
Chris@1 239 x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]);
Chris@1 240 x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]);
Chris@1 241
Chris@1 242 r0 = x1[2] - x2[2];
Chris@1 243 r1 = x1[3] - x2[3];
Chris@1 244 x1[2] += x2[2];
Chris@1 245 x1[3] += x2[3];
Chris@1 246 x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]);
Chris@1 247 x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]);
Chris@1 248
Chris@1 249 r0 = x1[0] - x2[0];
Chris@1 250 r1 = x1[1] - x2[1];
Chris@1 251 x1[0] += x2[0];
Chris@1 252 x1[1] += x2[1];
Chris@1 253 x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]);
Chris@1 254 x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]);
Chris@1 255
Chris@1 256 x1-=8;
Chris@1 257 x2-=8;
Chris@1 258 T+=16;
Chris@1 259
Chris@1 260 }while(x2>=x);
Chris@1 261 }
Chris@1 262
Chris@1 263 /* N/stage point generic N stage butterfly (in place, 2 register) */
Chris@1 264 STIN void mdct_butterfly_generic(DATA_TYPE *T,
Chris@1 265 DATA_TYPE *x,
Chris@1 266 int points,
Chris@1 267 int trigint){
Chris@1 268
Chris@1 269 DATA_TYPE *x1 = x + points - 8;
Chris@1 270 DATA_TYPE *x2 = x + (points>>1) - 8;
Chris@1 271 REG_TYPE r0;
Chris@1 272 REG_TYPE r1;
Chris@1 273
Chris@1 274 do{
Chris@1 275
Chris@1 276 r0 = x1[6] - x2[6];
Chris@1 277 r1 = x1[7] - x2[7];
Chris@1 278 x1[6] += x2[6];
Chris@1 279 x1[7] += x2[7];
Chris@1 280 x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]);
Chris@1 281 x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]);
Chris@1 282
Chris@1 283 T+=trigint;
Chris@1 284
Chris@1 285 r0 = x1[4] - x2[4];
Chris@1 286 r1 = x1[5] - x2[5];
Chris@1 287 x1[4] += x2[4];
Chris@1 288 x1[5] += x2[5];
Chris@1 289 x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]);
Chris@1 290 x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]);
Chris@1 291
Chris@1 292 T+=trigint;
Chris@1 293
Chris@1 294 r0 = x1[2] - x2[2];
Chris@1 295 r1 = x1[3] - x2[3];
Chris@1 296 x1[2] += x2[2];
Chris@1 297 x1[3] += x2[3];
Chris@1 298 x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]);
Chris@1 299 x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]);
Chris@1 300
Chris@1 301 T+=trigint;
Chris@1 302
Chris@1 303 r0 = x1[0] - x2[0];
Chris@1 304 r1 = x1[1] - x2[1];
Chris@1 305 x1[0] += x2[0];
Chris@1 306 x1[1] += x2[1];
Chris@1 307 x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]);
Chris@1 308 x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]);
Chris@1 309
Chris@1 310 T+=trigint;
Chris@1 311 x1-=8;
Chris@1 312 x2-=8;
Chris@1 313
Chris@1 314 }while(x2>=x);
Chris@1 315 }
Chris@1 316
Chris@1 317 STIN void mdct_butterflies(mdct_lookup *init,
Chris@1 318 DATA_TYPE *x,
Chris@1 319 int points){
Chris@1 320
Chris@1 321 DATA_TYPE *T=init->trig;
Chris@1 322 int stages=init->log2n-5;
Chris@1 323 int i,j;
Chris@1 324
Chris@1 325 if(--stages>0){
Chris@1 326 mdct_butterfly_first(T,x,points);
Chris@1 327 }
Chris@1 328
Chris@1 329 for(i=1;--stages>0;i++){
Chris@1 330 for(j=0;j<(1<<i);j++)
Chris@1 331 mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
Chris@1 332 }
Chris@1 333
Chris@1 334 for(j=0;j<points;j+=32)
Chris@1 335 mdct_butterfly_32(x+j);
Chris@1 336
Chris@1 337 }
Chris@1 338
Chris@1 339 void mdct_clear(mdct_lookup *l){
Chris@1 340 if(l){
Chris@1 341 if(l->trig)_ogg_free(l->trig);
Chris@1 342 if(l->bitrev)_ogg_free(l->bitrev);
Chris@1 343 memset(l,0,sizeof(*l));
Chris@1 344 }
Chris@1 345 }
Chris@1 346
Chris@1 347 STIN void mdct_bitreverse(mdct_lookup *init,
Chris@1 348 DATA_TYPE *x){
Chris@1 349 int n = init->n;
Chris@1 350 int *bit = init->bitrev;
Chris@1 351 DATA_TYPE *w0 = x;
Chris@1 352 DATA_TYPE *w1 = x = w0+(n>>1);
Chris@1 353 DATA_TYPE *T = init->trig+n;
Chris@1 354
Chris@1 355 do{
Chris@1 356 DATA_TYPE *x0 = x+bit[0];
Chris@1 357 DATA_TYPE *x1 = x+bit[1];
Chris@1 358
Chris@1 359 REG_TYPE r0 = x0[1] - x1[1];
Chris@1 360 REG_TYPE r1 = x0[0] + x1[0];
Chris@1 361 REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]);
Chris@1 362 REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]);
Chris@1 363
Chris@1 364 w1 -= 4;
Chris@1 365
Chris@1 366 r0 = HALVE(x0[1] + x1[1]);
Chris@1 367 r1 = HALVE(x0[0] - x1[0]);
Chris@1 368
Chris@1 369 w0[0] = r0 + r2;
Chris@1 370 w1[2] = r0 - r2;
Chris@1 371 w0[1] = r1 + r3;
Chris@1 372 w1[3] = r3 - r1;
Chris@1 373
Chris@1 374 x0 = x+bit[2];
Chris@1 375 x1 = x+bit[3];
Chris@1 376
Chris@1 377 r0 = x0[1] - x1[1];
Chris@1 378 r1 = x0[0] + x1[0];
Chris@1 379 r2 = MULT_NORM(r1 * T[2] + r0 * T[3]);
Chris@1 380 r3 = MULT_NORM(r1 * T[3] - r0 * T[2]);
Chris@1 381
Chris@1 382 r0 = HALVE(x0[1] + x1[1]);
Chris@1 383 r1 = HALVE(x0[0] - x1[0]);
Chris@1 384
Chris@1 385 w0[2] = r0 + r2;
Chris@1 386 w1[0] = r0 - r2;
Chris@1 387 w0[3] = r1 + r3;
Chris@1 388 w1[1] = r3 - r1;
Chris@1 389
Chris@1 390 T += 4;
Chris@1 391 bit += 4;
Chris@1 392 w0 += 4;
Chris@1 393
Chris@1 394 }while(w0<w1);
Chris@1 395 }
Chris@1 396
Chris@1 397 void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
Chris@1 398 int n=init->n;
Chris@1 399 int n2=n>>1;
Chris@1 400 int n4=n>>2;
Chris@1 401
Chris@1 402 /* rotate */
Chris@1 403
Chris@1 404 DATA_TYPE *iX = in+n2-7;
Chris@1 405 DATA_TYPE *oX = out+n2+n4;
Chris@1 406 DATA_TYPE *T = init->trig+n4;
Chris@1 407
Chris@1 408 do{
Chris@1 409 oX -= 4;
Chris@1 410 oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]);
Chris@1 411 oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]);
Chris@1 412 oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]);
Chris@1 413 oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]);
Chris@1 414 iX -= 8;
Chris@1 415 T += 4;
Chris@1 416 }while(iX>=in);
Chris@1 417
Chris@1 418 iX = in+n2-8;
Chris@1 419 oX = out+n2+n4;
Chris@1 420 T = init->trig+n4;
Chris@1 421
Chris@1 422 do{
Chris@1 423 T -= 4;
Chris@1 424 oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
Chris@1 425 oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
Chris@1 426 oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
Chris@1 427 oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
Chris@1 428 iX -= 8;
Chris@1 429 oX += 4;
Chris@1 430 }while(iX>=in);
Chris@1 431
Chris@1 432 mdct_butterflies(init,out+n2,n2);
Chris@1 433 mdct_bitreverse(init,out);
Chris@1 434
Chris@1 435 /* roatate + window */
Chris@1 436
Chris@1 437 {
Chris@1 438 DATA_TYPE *oX1=out+n2+n4;
Chris@1 439 DATA_TYPE *oX2=out+n2+n4;
Chris@1 440 DATA_TYPE *iX =out;
Chris@1 441 T =init->trig+n2;
Chris@1 442
Chris@1 443 do{
Chris@1 444 oX1-=4;
Chris@1 445
Chris@1 446 oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
Chris@1 447 oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
Chris@1 448
Chris@1 449 oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
Chris@1 450 oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
Chris@1 451
Chris@1 452 oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
Chris@1 453 oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
Chris@1 454
Chris@1 455 oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
Chris@1 456 oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
Chris@1 457
Chris@1 458 oX2+=4;
Chris@1 459 iX += 8;
Chris@1 460 T += 8;
Chris@1 461 }while(iX<oX1);
Chris@1 462
Chris@1 463 iX=out+n2+n4;
Chris@1 464 oX1=out+n4;
Chris@1 465 oX2=oX1;
Chris@1 466
Chris@1 467 do{
Chris@1 468 oX1-=4;
Chris@1 469 iX-=4;
Chris@1 470
Chris@1 471 oX2[0] = -(oX1[3] = iX[3]);
Chris@1 472 oX2[1] = -(oX1[2] = iX[2]);
Chris@1 473 oX2[2] = -(oX1[1] = iX[1]);
Chris@1 474 oX2[3] = -(oX1[0] = iX[0]);
Chris@1 475
Chris@1 476 oX2+=4;
Chris@1 477 }while(oX2<iX);
Chris@1 478
Chris@1 479 iX=out+n2+n4;
Chris@1 480 oX1=out+n2+n4;
Chris@1 481 oX2=out+n2;
Chris@1 482 do{
Chris@1 483 oX1-=4;
Chris@1 484 oX1[0]= iX[3];
Chris@1 485 oX1[1]= iX[2];
Chris@1 486 oX1[2]= iX[1];
Chris@1 487 oX1[3]= iX[0];
Chris@1 488 iX+=4;
Chris@1 489 }while(oX1>oX2);
Chris@1 490 }
Chris@1 491 }
Chris@1 492
Chris@1 493 void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
Chris@1 494 int n=init->n;
Chris@1 495 int n2=n>>1;
Chris@1 496 int n4=n>>2;
Chris@1 497 int n8=n>>3;
Chris@1 498 DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
Chris@1 499 DATA_TYPE *w2=w+n2;
Chris@1 500
Chris@1 501 /* rotate */
Chris@1 502
Chris@1 503 /* window + rotate + step 1 */
Chris@1 504
Chris@1 505 REG_TYPE r0;
Chris@1 506 REG_TYPE r1;
Chris@1 507 DATA_TYPE *x0=in+n2+n4;
Chris@1 508 DATA_TYPE *x1=x0+1;
Chris@1 509 DATA_TYPE *T=init->trig+n2;
Chris@1 510
Chris@1 511 int i=0;
Chris@1 512
Chris@1 513 for(i=0;i<n8;i+=2){
Chris@1 514 x0 -=4;
Chris@1 515 T-=2;
Chris@1 516 r0= x0[2] + x1[0];
Chris@1 517 r1= x0[0] + x1[2];
Chris@1 518 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
Chris@1 519 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
Chris@1 520 x1 +=4;
Chris@1 521 }
Chris@1 522
Chris@1 523 x1=in+1;
Chris@1 524
Chris@1 525 for(;i<n2-n8;i+=2){
Chris@1 526 T-=2;
Chris@1 527 x0 -=4;
Chris@1 528 r0= x0[2] - x1[0];
Chris@1 529 r1= x0[0] - x1[2];
Chris@1 530 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
Chris@1 531 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
Chris@1 532 x1 +=4;
Chris@1 533 }
Chris@1 534
Chris@1 535 x0=in+n;
Chris@1 536
Chris@1 537 for(;i<n2;i+=2){
Chris@1 538 T-=2;
Chris@1 539 x0 -=4;
Chris@1 540 r0= -x0[2] - x1[0];
Chris@1 541 r1= -x0[0] - x1[2];
Chris@1 542 w2[i]= MULT_NORM(r1*T[1] + r0*T[0]);
Chris@1 543 w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
Chris@1 544 x1 +=4;
Chris@1 545 }
Chris@1 546
Chris@1 547
Chris@1 548 mdct_butterflies(init,w+n2,n2);
Chris@1 549 mdct_bitreverse(init,w);
Chris@1 550
Chris@1 551 /* roatate + window */
Chris@1 552
Chris@1 553 T=init->trig+n2;
Chris@1 554 x0=out+n2;
Chris@1 555
Chris@1 556 for(i=0;i<n4;i++){
Chris@1 557 x0--;
Chris@1 558 out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
Chris@1 559 x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
Chris@1 560 w+=2;
Chris@1 561 T+=2;
Chris@1 562 }
Chris@1 563 }