1 /*Copyright (c) 2003-2004, Mark Borgerding 2 Lots of modifications by Jean-Marc Valin 3 Copyright (c) 2005-2007, Xiph.Org Foundation 4 Copyright (c) 2008, Xiph.Org Foundation, CSIRO 5 6 All rights reserved. 7 8 Redistribution and use in source and binary forms, with or without 9 modification, are permitted provided that the following conditions are met: 10 11 * Redistributions of source code must retain the above copyright notice, 12 this list of conditions and the following disclaimer. 13 * Redistributions in binary form must reproduce the above copyright notice, 14 this list of conditions and the following disclaimer in the 15 documentation and/or other materials provided with the distribution. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 POSSIBILITY OF SUCH DAMAGE.*/ 28 29 /* This code is originally from Mark Borgerding's KISS-FFT but has been 30 heavily modified to better suit Opus */ 31 32 #ifndef SKIP_CONFIG_H 33 # ifdef HAVE_CONFIG_H 34 # include "config.h" 35 # endif 36 #endif 37 38 #include "_kiss_fft_guts.h" 39 #include "arch.h" 40 #include "os_support.h" 41 #include "mathops.h" 42 #include "stack_alloc.h" 43 #include "os_support.h" 44 45 /* The guts header contains all the multiplication and addition macros that are defined for 46 complex numbers. It also delares the kf_ internal functions. 47 */ 48 49 static void kf_bfly2( 50 kiss_fft_cpx * Fout, 51 const size_t fstride, 52 const kiss_fft_state *st, 53 int m, 54 int N, 55 int mm 56 ) 57 { 58 kiss_fft_cpx * Fout2; 59 const kiss_twiddle_cpx * tw1; 60 int i,j; 61 kiss_fft_cpx * Fout_beg = Fout; 62 for (i=0;i<N;i++) 63 { 64 Fout = Fout_beg + i*mm; 65 Fout2 = Fout + m; 66 tw1 = st->twiddles; 67 for(j=0;j<m;j++) 68 { 69 kiss_fft_cpx t; 70 Fout->r = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1); 71 Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1); 72 C_MUL (t, *Fout2 , *tw1); 73 tw1 += fstride; 74 C_SUB( *Fout2 , *Fout , t ); 75 C_ADDTO( *Fout , t ); 76 ++Fout2; 77 ++Fout; 78 } 79 } 80 } 81 82 static void ki_bfly2( 83 kiss_fft_cpx * Fout, 84 const size_t fstride, 85 const kiss_fft_state *st, 86 int m, 87 int N, 88 int mm 89 ) 90 { 91 kiss_fft_cpx * Fout2; 92 const kiss_twiddle_cpx * tw1; 93 kiss_fft_cpx t; 94 int i,j; 95 kiss_fft_cpx * Fout_beg = Fout; 96 for (i=0;i<N;i++) 97 { 98 Fout = Fout_beg + i*mm; 99 Fout2 = Fout + m; 100 tw1 = st->twiddles; 101 for(j=0;j<m;j++) 102 { 103 C_MULC (t, *Fout2 , *tw1); 104 tw1 += fstride; 105 C_SUB( *Fout2 , *Fout , t ); 106 C_ADDTO( *Fout , t ); 107 ++Fout2; 108 ++Fout; 109 } 110 } 111 } 112 113 static void kf_bfly4( 114 kiss_fft_cpx * Fout, 115 const size_t fstride, 116 const kiss_fft_state *st, 117 int m, 118 int N, 119 int mm 120 ) 121 { 122 const kiss_twiddle_cpx *tw1,*tw2,*tw3; 123 kiss_fft_cpx scratch[6]; 124 const size_t m2=2*m; 125 const size_t m3=3*m; 126 int i, j; 127 128 kiss_fft_cpx * Fout_beg = Fout; 129 for (i=0;i<N;i++) 130 { 131 Fout = Fout_beg + i*mm; 132 tw3 = tw2 = tw1 = st->twiddles; 133 for (j=0;j<m;j++) 134 { 135 C_MUL4(scratch[0],Fout[m] , *tw1 ); 136 C_MUL4(scratch[1],Fout[m2] , *tw2 ); 137 C_MUL4(scratch[2],Fout[m3] , *tw3 ); 138 139 Fout->r = PSHR32(Fout->r, 2); 140 Fout->i = PSHR32(Fout->i, 2); 141 C_SUB( scratch[5] , *Fout, scratch[1] ); 142 C_ADDTO(*Fout, scratch[1]); 143 C_ADD( scratch[3] , scratch[0] , scratch[2] ); 144 C_SUB( scratch[4] , scratch[0] , scratch[2] ); 145 Fout[m2].r = PSHR32(Fout[m2].r, 2); 146 Fout[m2].i = PSHR32(Fout[m2].i, 2); 147 C_SUB( Fout[m2], *Fout, scratch[3] ); 148 tw1 += fstride; 149 tw2 += fstride*2; 150 tw3 += fstride*3; 151 C_ADDTO( *Fout , scratch[3] ); 152 153 Fout[m].r = scratch[5].r + scratch[4].i; 154 Fout[m].i = scratch[5].i - scratch[4].r; 155 Fout[m3].r = scratch[5].r - scratch[4].i; 156 Fout[m3].i = scratch[5].i + scratch[4].r; 157 ++Fout; 158 } 159 } 160 } 161 162 static void ki_bfly4( 163 kiss_fft_cpx * Fout, 164 const size_t fstride, 165 const kiss_fft_state *st, 166 int m, 167 int N, 168 int mm 169 ) 170 { 171 const kiss_twiddle_cpx *tw1,*tw2,*tw3; 172 kiss_fft_cpx scratch[6]; 173 const size_t m2=2*m; 174 const size_t m3=3*m; 175 int i, j; 176 177 kiss_fft_cpx * Fout_beg = Fout; 178 for (i=0;i<N;i++) 179 { 180 Fout = Fout_beg + i*mm; 181 tw3 = tw2 = tw1 = st->twiddles; 182 for (j=0;j<m;j++) 183 { 184 C_MULC(scratch[0],Fout[m] , *tw1 ); 185 C_MULC(scratch[1],Fout[m2] , *tw2 ); 186 C_MULC(scratch[2],Fout[m3] , *tw3 ); 187 188 C_SUB( scratch[5] , *Fout, scratch[1] ); 189 C_ADDTO(*Fout, scratch[1]); 190 C_ADD( scratch[3] , scratch[0] , scratch[2] ); 191 C_SUB( scratch[4] , scratch[0] , scratch[2] ); 192 C_SUB( Fout[m2], *Fout, scratch[3] ); 193 tw1 += fstride; 194 tw2 += fstride*2; 195 tw3 += fstride*3; 196 C_ADDTO( *Fout , scratch[3] ); 197 198 Fout[m].r = scratch[5].r - scratch[4].i; 199 Fout[m].i = scratch[5].i + scratch[4].r; 200 Fout[m3].r = scratch[5].r + scratch[4].i; 201 Fout[m3].i = scratch[5].i - scratch[4].r; 202 ++Fout; 203 } 204 } 205 } 206 207 #ifndef RADIX_TWO_ONLY 208 209 static void kf_bfly3( 210 kiss_fft_cpx * Fout, 211 const size_t fstride, 212 const kiss_fft_state *st, 213 int m, 214 int N, 215 int mm 216 ) 217 { 218 int i; 219 size_t k; 220 const size_t m2 = 2*m; 221 const kiss_twiddle_cpx *tw1,*tw2; 222 kiss_fft_cpx scratch[5]; 223 kiss_twiddle_cpx epi3; 224 225 kiss_fft_cpx * Fout_beg = Fout; 226 epi3 = st->twiddles[fstride*m]; 227 for (i=0;i<N;i++) 228 { 229 Fout = Fout_beg + i*mm; 230 tw1=tw2=st->twiddles; 231 k=m; 232 do { 233 C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); 234 235 C_MUL(scratch[1],Fout[m] , *tw1); 236 C_MUL(scratch[2],Fout[m2] , *tw2); 237 238 C_ADD(scratch[3],scratch[1],scratch[2]); 239 C_SUB(scratch[0],scratch[1],scratch[2]); 240 tw1 += fstride; 241 tw2 += fstride*2; 242 243 Fout[m].r = Fout->r - HALF_OF(scratch[3].r); 244 Fout[m].i = Fout->i - HALF_OF(scratch[3].i); 245 246 C_MULBYSCALAR( scratch[0] , epi3.i ); 247 248 C_ADDTO(*Fout,scratch[3]); 249 250 Fout[m2].r = Fout[m].r + scratch[0].i; 251 Fout[m2].i = Fout[m].i - scratch[0].r; 252 253 Fout[m].r -= scratch[0].i; 254 Fout[m].i += scratch[0].r; 255 256 ++Fout; 257 } while(--k); 258 } 259 } 260 261 static void ki_bfly3( 262 kiss_fft_cpx * Fout, 263 const size_t fstride, 264 const kiss_fft_state *st, 265 int m, 266 int N, 267 int mm 268 ) 269 { 270 int i, k; 271 const size_t m2 = 2*m; 272 const kiss_twiddle_cpx *tw1,*tw2; 273 kiss_fft_cpx scratch[5]; 274 kiss_twiddle_cpx epi3; 275 276 kiss_fft_cpx * Fout_beg = Fout; 277 epi3 = st->twiddles[fstride*m]; 278 for (i=0;i<N;i++) 279 { 280 Fout = Fout_beg + i*mm; 281 tw1=tw2=st->twiddles; 282 k=m; 283 do{ 284 285 C_MULC(scratch[1],Fout[m] , *tw1); 286 C_MULC(scratch[2],Fout[m2] , *tw2); 287 288 C_ADD(scratch[3],scratch[1],scratch[2]); 289 C_SUB(scratch[0],scratch[1],scratch[2]); 290 tw1 += fstride; 291 tw2 += fstride*2; 292 293 Fout[m].r = Fout->r - HALF_OF(scratch[3].r); 294 Fout[m].i = Fout->i - HALF_OF(scratch[3].i); 295 296 C_MULBYSCALAR( scratch[0] , -epi3.i ); 297 298 C_ADDTO(*Fout,scratch[3]); 299 300 Fout[m2].r = Fout[m].r + scratch[0].i; 301 Fout[m2].i = Fout[m].i - scratch[0].r; 302 303 Fout[m].r -= scratch[0].i; 304 Fout[m].i += scratch[0].r; 305 306 ++Fout; 307 }while(--k); 308 } 309 } 310 311 static void kf_bfly5( 312 kiss_fft_cpx * Fout, 313 const size_t fstride, 314 const kiss_fft_state *st, 315 int m, 316 int N, 317 int mm 318 ) 319 { 320 kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; 321 int i, u; 322 kiss_fft_cpx scratch[13]; 323 const kiss_twiddle_cpx * twiddles = st->twiddles; 324 const kiss_twiddle_cpx *tw; 325 kiss_twiddle_cpx ya,yb; 326 kiss_fft_cpx * Fout_beg = Fout; 327 328 ya = twiddles[fstride*m]; 329 yb = twiddles[fstride*2*m]; 330 tw=st->twiddles; 331 332 for (i=0;i<N;i++) 333 { 334 Fout = Fout_beg + i*mm; 335 Fout0=Fout; 336 Fout1=Fout0+m; 337 Fout2=Fout0+2*m; 338 Fout3=Fout0+3*m; 339 Fout4=Fout0+4*m; 340 341 for ( u=0; u<m; ++u ) { 342 C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5); 343 scratch[0] = *Fout0; 344 345 C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); 346 C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); 347 C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); 348 C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); 349 350 C_ADD( scratch[7],scratch[1],scratch[4]); 351 C_SUB( scratch[10],scratch[1],scratch[4]); 352 C_ADD( scratch[8],scratch[2],scratch[3]); 353 C_SUB( scratch[9],scratch[2],scratch[3]); 354 355 Fout0->r += scratch[7].r + scratch[8].r; 356 Fout0->i += scratch[7].i + scratch[8].i; 357 358 scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); 359 scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); 360 361 scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); 362 scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); 363 364 C_SUB(*Fout1,scratch[5],scratch[6]); 365 C_ADD(*Fout4,scratch[5],scratch[6]); 366 367 scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); 368 scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); 369 scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); 370 scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); 371 372 C_ADD(*Fout2,scratch[11],scratch[12]); 373 C_SUB(*Fout3,scratch[11],scratch[12]); 374 375 ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; 376 } 377 } 378 } 379 380 static void ki_bfly5( 381 kiss_fft_cpx * Fout, 382 const size_t fstride, 383 const kiss_fft_state *st, 384 int m, 385 int N, 386 int mm 387 ) 388 { 389 kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; 390 int i, u; 391 kiss_fft_cpx scratch[13]; 392 const kiss_twiddle_cpx * twiddles = st->twiddles; 393 const kiss_twiddle_cpx *tw; 394 kiss_twiddle_cpx ya,yb; 395 kiss_fft_cpx * Fout_beg = Fout; 396 397 ya = twiddles[fstride*m]; 398 yb = twiddles[fstride*2*m]; 399 tw=st->twiddles; 400 401 for (i=0;i<N;i++) 402 { 403 Fout = Fout_beg + i*mm; 404 Fout0=Fout; 405 Fout1=Fout0+m; 406 Fout2=Fout0+2*m; 407 Fout3=Fout0+3*m; 408 Fout4=Fout0+4*m; 409 410 for ( u=0; u<m; ++u ) { 411 scratch[0] = *Fout0; 412 413 C_MULC(scratch[1] ,*Fout1, tw[u*fstride]); 414 C_MULC(scratch[2] ,*Fout2, tw[2*u*fstride]); 415 C_MULC(scratch[3] ,*Fout3, tw[3*u*fstride]); 416 C_MULC(scratch[4] ,*Fout4, tw[4*u*fstride]); 417 418 C_ADD( scratch[7],scratch[1],scratch[4]); 419 C_SUB( scratch[10],scratch[1],scratch[4]); 420 C_ADD( scratch[8],scratch[2],scratch[3]); 421 C_SUB( scratch[9],scratch[2],scratch[3]); 422 423 Fout0->r += scratch[7].r + scratch[8].r; 424 Fout0->i += scratch[7].i + scratch[8].i; 425 426 scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); 427 scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); 428 429 scratch[6].r = -S_MUL(scratch[10].i,ya.i) - S_MUL(scratch[9].i,yb.i); 430 scratch[6].i = S_MUL(scratch[10].r,ya.i) + S_MUL(scratch[9].r,yb.i); 431 432 C_SUB(*Fout1,scratch[5],scratch[6]); 433 C_ADD(*Fout4,scratch[5],scratch[6]); 434 435 scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); 436 scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); 437 scratch[12].r = S_MUL(scratch[10].i,yb.i) - S_MUL(scratch[9].i,ya.i); 438 scratch[12].i = -S_MUL(scratch[10].r,yb.i) + S_MUL(scratch[9].r,ya.i); 439 440 C_ADD(*Fout2,scratch[11],scratch[12]); 441 C_SUB(*Fout3,scratch[11],scratch[12]); 442 443 ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; 444 } 445 } 446 } 447 448 #endif 449 450 451 #ifdef CUSTOM_MODES 452 453 static 454 void compute_bitrev_table( 455 int Fout, 456 opus_int16 *f, 457 const size_t fstride, 458 int in_stride, 459 opus_int16 * factors, 460 const kiss_fft_state *st 461 ) 462 { 463 const int p=*factors++; /* the radix */ 464 const int m=*factors++; /* stage's fft length/p */ 465 466 /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ 467 if (m==1) 468 { 469 int j; 470 for (j=0;j<p;j++) 471 { 472 *f = Fout+j; 473 f += fstride*in_stride; 474 } 475 } else { 476 int j; 477 for (j=0;j<p;j++) 478 { 479 compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st); 480 f += fstride*in_stride; 481 Fout += m; 482 } 483 } 484 } 485 486 /* facbuf is populated by p1,m1,p2,m2, ... 487 where 488 p[i] * m[i] = m[i-1] 489 m0 = n */ 490 static 491 int kf_factor(int n,opus_int16 * facbuf) 492 { 493 int p=4; 494 495 /*factor out powers of 4, powers of 2, then any remaining primes */ 496 do { 497 while (n % p) { 498 switch (p) { 499 case 4: p = 2; break; 500 case 2: p = 3; break; 501 default: p += 2; break; 502 } 503 if (p>32000 || (opus_int32)p*(opus_int32)p > n) 504 p = n; /* no more factors, skip to end */ 505 } 506 n /= p; 507 #ifdef RADIX_TWO_ONLY 508 if (p!=2 && p != 4) 509 #else 510 if (p>5) 511 #endif 512 { 513 return 0; 514 } 515 *facbuf++ = p; 516 *facbuf++ = n; 517 } while (n > 1); 518 return 1; 519 } 520 521 static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft) 522 { 523 int i; 524 #ifdef FIXED_POINT 525 for (i=0;i<nfft;++i) { 526 opus_val32 phase = -i; 527 kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft)); 528 } 529 #else 530 for (i=0;i<nfft;++i) { 531 const double pi=3.14159265358979323846264338327; 532 double phase = ( -2*pi /nfft ) * i; 533 kf_cexp(twiddles+i, phase ); 534 } 535 #endif 536 } 537 538 /* 539 * 540 * Allocates all necessary storage space for the fft and ifft. 541 * The return value is a contiguous block of memory. As such, 542 * It can be freed with free(). 543 * */ 544 kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base) 545 { 546 kiss_fft_state *st=NULL; 547 size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/ 548 549 if ( lenmem==NULL ) { 550 st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded ); 551 }else{ 552 if (mem != NULL && *lenmem >= memneeded) 553 st = (kiss_fft_state*)mem; 554 *lenmem = memneeded; 555 } 556 if (st) { 557 opus_int16 *bitrev; 558 kiss_twiddle_cpx *twiddles; 559 560 st->nfft=nfft; 561 #ifndef FIXED_POINT 562 st->scale = 1.f/nfft; 563 #endif 564 if (base != NULL) 565 { 566 st->twiddles = base->twiddles; 567 st->shift = 0; 568 while (nfft<<st->shift != base->nfft && st->shift < 32) 569 st->shift++; 570 if (st->shift>=32) 571 goto fail; 572 } else { 573 st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft); 574 compute_twiddles(twiddles, nfft); 575 st->shift = -1; 576 } 577 if (!kf_factor(nfft,st->factors)) 578 { 579 goto fail; 580 } 581 582 /* bitrev */ 583 st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft); 584 if (st->bitrev==NULL) 585 goto fail; 586 compute_bitrev_table(0, bitrev, 1,1, st->factors,st); 587 } 588 return st; 589 fail: 590 opus_fft_free(st); 591 return NULL; 592 } 593 594 kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem ) 595 { 596 return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL); 597 } 598 599 void opus_fft_free(const kiss_fft_state *cfg) 600 { 601 if (cfg) 602 { 603 opus_free((opus_int16*)cfg->bitrev); 604 if (cfg->shift < 0) 605 opus_free((kiss_twiddle_cpx*)cfg->twiddles); 606 opus_free((kiss_fft_state*)cfg); 607 } 608 } 609 610 #endif /* CUSTOM_MODES */ 611 612 void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) 613 { 614 int m2, m; 615 int p; 616 int L; 617 int fstride[MAXFACTORS]; 618 int i; 619 int shift; 620 621 /* st->shift can be -1 */ 622 shift = st->shift>0 ? st->shift : 0; 623 624 celt_assert2 (fin != fout, "In-place FFT not supported"); 625 /* Bit-reverse the input */ 626 for (i=0;i<st->nfft;i++) 627 { 628 fout[st->bitrev[i]] = fin[i]; 629 #ifndef FIXED_POINT 630 fout[st->bitrev[i]].r *= st->scale; 631 fout[st->bitrev[i]].i *= st->scale; 632 #endif 633 } 634 635 fstride[0] = 1; 636 L=0; 637 do { 638 p = st->factors[2*L]; 639 m = st->factors[2*L+1]; 640 fstride[L+1] = fstride[L]*p; 641 L++; 642 } while(m!=1); 643 m = st->factors[2*L-1]; 644 for (i=L-1;i>=0;i--) 645 { 646 if (i!=0) 647 m2 = st->factors[2*i-1]; 648 else 649 m2 = 1; 650 switch (st->factors[2*i]) 651 { 652 case 2: 653 kf_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2); 654 break; 655 case 4: 656 kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2); 657 break; 658 #ifndef RADIX_TWO_ONLY 659 case 3: 660 kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2); 661 break; 662 case 5: 663 kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2); 664 break; 665 #endif 666 } 667 m = m2; 668 } 669 } 670 671 void opus_ifft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) 672 { 673 int m2, m; 674 int p; 675 int L; 676 int fstride[MAXFACTORS]; 677 int i; 678 int shift; 679 680 /* st->shift can be -1 */ 681 shift = st->shift>0 ? st->shift : 0; 682 celt_assert2 (fin != fout, "In-place FFT not supported"); 683 /* Bit-reverse the input */ 684 for (i=0;i<st->nfft;i++) 685 fout[st->bitrev[i]] = fin[i]; 686 687 fstride[0] = 1; 688 L=0; 689 do { 690 p = st->factors[2*L]; 691 m = st->factors[2*L+1]; 692 fstride[L+1] = fstride[L]*p; 693 L++; 694 } while(m!=1); 695 m = st->factors[2*L-1]; 696 for (i=L-1;i>=0;i--) 697 { 698 if (i!=0) 699 m2 = st->factors[2*i-1]; 700 else 701 m2 = 1; 702 switch (st->factors[2*i]) 703 { 704 case 2: 705 ki_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2); 706 break; 707 case 4: 708 ki_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2); 709 break; 710 #ifndef RADIX_TWO_ONLY 711 case 3: 712 ki_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2); 713 break; 714 case 5: 715 ki_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2); 716 break; 717 #endif 718 } 719 m = m2; 720 } 721 } 722 723