1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*Copyright (c) 2003-2004, Mark Borgerding 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Lots of modifications by Jean-Marc Valin 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Copyright (c) 2005-2007, Xiph.Org Foundation 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Copyright (c) 2008, Xiph.Org Foundation, CSIRO 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org All rights reserved. 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Redistribution and use in source and binary forms, with or without 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org modification, are permitted provided that the following conditions are met: 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * Redistributions of source code must retain the above copyright notice, 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org this list of conditions and the following disclaimer. 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * Redistributions in binary form must reproduce the above copyright notice, 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org this list of conditions and the following disclaimer in the 15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org documentation and/or other materials provided with the distribution. 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org POSSIBILITY OF SUCH DAMAGE.*/ 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* This code is originally from Mark Borgerding's KISS-FFT but has been 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org heavily modified to better suit Opus */ 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef SKIP_CONFIG_H 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# ifdef HAVE_CONFIG_H 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# include "config.h" 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# endif 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "_kiss_fft_guts.h" 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "arch.h" 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h" 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "mathops.h" 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "stack_alloc.h" 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* The guts header contains all the multiplication and addition macros that are defined for 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org complex numbers. It also delares the kf_ internal functions. 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly2( 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout2; 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx * tw1; 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i,j; 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout2 = Fout + m; 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 = st->twiddles; 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for(j=0;j<m;j++) 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx t; 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout->r = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1); 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1); 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL (t, *Fout2 , *tw1); 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 += fstride; 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( *Fout2 , *Fout , t ); 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO( *Fout , t ); 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout2; 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout; 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly2( 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout2; 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx * tw1; 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx t; 93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i,j; 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout2 = Fout + m; 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 = st->twiddles; 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for(j=0;j<m;j++) 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC (t, *Fout2 , *tw1); 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 += fstride; 104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( *Fout2 , *Fout , t ); 105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO( *Fout , t ); 106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout2; 107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout; 108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly4( 113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx *tw1,*tw2,*tw3; 122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx scratch[6]; 123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t m2=2*m; 124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t m3=3*m; 125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, j; 126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw3 = tw2 = tw1 = st->twiddles; 132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<m;j++) 133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL4(scratch[0],Fout[m] , *tw1 ); 135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL4(scratch[1],Fout[m2] , *tw2 ); 136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL4(scratch[2],Fout[m3] , *tw3 ); 137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout->r = PSHR32(Fout->r, 2); 139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout->i = PSHR32(Fout->i, 2); 140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[5] , *Fout, scratch[1] ); 141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO(*Fout, scratch[1]); 142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD( scratch[3] , scratch[0] , scratch[2] ); 143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[4] , scratch[0] , scratch[2] ); 144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( Fout[m2], *Fout, scratch[3] ); 145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 += fstride; 146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw2 += fstride*2; 147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw3 += fstride*3; 148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO( *Fout , scratch[3] ); 149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].r = scratch[5].r + scratch[4].i; 151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].i = scratch[5].i - scratch[4].r; 152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m3].r = scratch[5].r - scratch[4].i; 153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m3].i = scratch[5].i + scratch[4].r; 154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout; 155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly4( 160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx *tw1,*tw2,*tw3; 169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx scratch[6]; 170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t m2=2*m; 171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t m3=3*m; 172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, j; 173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw3 = tw2 = tw1 = st->twiddles; 179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<m;j++) 180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[0],Fout[m] , *tw1 ); 182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[1],Fout[m2] , *tw2 ); 183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[2],Fout[m3] , *tw3 ); 184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[5] , *Fout, scratch[1] ); 186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO(*Fout, scratch[1]); 187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD( scratch[3] , scratch[0] , scratch[2] ); 188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[4] , scratch[0] , scratch[2] ); 189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( Fout[m2], *Fout, scratch[3] ); 190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 += fstride; 191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw2 += fstride*2; 192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw3 += fstride*3; 193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO( *Fout , scratch[3] ); 194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].r = scratch[5].r - scratch[4].i; 196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].i = scratch[5].i + scratch[4].r; 197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m3].r = scratch[5].r + scratch[4].i; 198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m3].i = scratch[5].i - scratch[4].r; 199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout; 200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef RADIX_TWO_ONLY 205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly3( 207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 210885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 211885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org size_t k; 217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t m2 = 2*m; 218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx *tw1,*tw2; 219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx scratch[5]; 220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_twiddle_cpx epi3; 221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org epi3 = st->twiddles[fstride*m]; 224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 225885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 226885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1=tw2=st->twiddles; 228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org k=m; 229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); 231885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 232885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL(scratch[1],Fout[m] , *tw1); 233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL(scratch[2],Fout[m2] , *tw2); 234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD(scratch[3],scratch[1],scratch[2]); 236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB(scratch[0],scratch[1],scratch[2]); 237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 += fstride; 238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw2 += fstride*2; 239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].r = Fout->r - HALF_OF(scratch[3].r); 241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].i = Fout->i - HALF_OF(scratch[3].i); 242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULBYSCALAR( scratch[0] , epi3.i ); 244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO(*Fout,scratch[3]); 246885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m2].r = Fout[m].r + scratch[0].i; 248885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m2].i = Fout[m].i - scratch[0].r; 249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].r -= scratch[0].i; 251885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].i += scratch[0].r; 252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout; 254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while(--k); 255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly3( 259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, k; 268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t m2 = 2*m; 269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx *tw1,*tw2; 270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx scratch[5]; 271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_twiddle_cpx epi3; 272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org epi3 = st->twiddles[fstride*m]; 275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1=tw2=st->twiddles; 279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org k=m; 280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do{ 281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[1],Fout[m] , *tw1); 283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[2],Fout[m2] , *tw2); 284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD(scratch[3],scratch[1],scratch[2]); 286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB(scratch[0],scratch[1],scratch[2]); 287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw1 += fstride; 288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw2 += fstride*2; 289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].r = Fout->r - HALF_OF(scratch[3].r); 291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].i = Fout->i - HALF_OF(scratch[3].i); 292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULBYSCALAR( scratch[0] , -epi3.i ); 294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADDTO(*Fout,scratch[3]); 296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m2].r = Fout[m].r + scratch[0].i; 298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m2].i = Fout[m].i - scratch[0].r; 299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].r -= scratch[0].i; 301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout[m].i += scratch[0].r; 302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout; 304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }while(--k); 305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly5( 309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; 318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, u; 319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx scratch[13]; 320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx * twiddles = st->twiddles; 321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx *tw; 322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_twiddle_cpx ya,yb; 323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ya = twiddles[fstride*m]; 326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org yb = twiddles[fstride*2*m]; 327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw=st->twiddles; 328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout0=Fout; 333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout1=Fout0+m; 334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout2=Fout0+2*m; 335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout3=Fout0+3*m; 336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout4=Fout0+4*m; 337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for ( u=0; u<m; ++u ) { 339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5); 340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[0] = *Fout0; 341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); 343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); 344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); 345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); 346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD( scratch[7],scratch[1],scratch[4]); 348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[10],scratch[1],scratch[4]); 349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD( scratch[8],scratch[2],scratch[3]); 350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[9],scratch[2],scratch[3]); 351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout0->r += scratch[7].r + scratch[8].r; 353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout0->i += scratch[7].i + scratch[8].i; 354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); 356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); 357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); 359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); 360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB(*Fout1,scratch[5],scratch[6]); 362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD(*Fout4,scratch[5],scratch[6]); 363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); 365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); 366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); 367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); 368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD(*Fout2,scratch[11],scratch[12]); 370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB(*Fout3,scratch[11],scratch[12]); 371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; 373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly5( 378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout, 379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st, 381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m, 382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, 383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int mm 384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; 387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, u; 388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx scratch[13]; 389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx * twiddles = st->twiddles; 390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_twiddle_cpx *tw; 391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_twiddle_cpx ya,yb; 392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_cpx * Fout_beg = Fout; 393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ya = twiddles[fstride*m]; 395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org yb = twiddles[fstride*2*m]; 396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tw=st->twiddles; 397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout = Fout_beg + i*mm; 401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout0=Fout; 402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout1=Fout0+m; 403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout2=Fout0+2*m; 404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout3=Fout0+3*m; 405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout4=Fout0+4*m; 406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for ( u=0; u<m; ++u ) { 408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[0] = *Fout0; 409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[1] ,*Fout1, tw[u*fstride]); 411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[2] ,*Fout2, tw[2*u*fstride]); 412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[3] ,*Fout3, tw[3*u*fstride]); 413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_MULC(scratch[4] ,*Fout4, tw[4*u*fstride]); 414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD( scratch[7],scratch[1],scratch[4]); 416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[10],scratch[1],scratch[4]); 417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD( scratch[8],scratch[2],scratch[3]); 418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB( scratch[9],scratch[2],scratch[3]); 419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout0->r += scratch[7].r + scratch[8].r; 421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout0->i += scratch[7].i + scratch[8].i; 422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); 424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); 425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[6].r = -S_MUL(scratch[10].i,ya.i) - S_MUL(scratch[9].i,yb.i); 427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[6].i = S_MUL(scratch[10].r,ya.i) + S_MUL(scratch[9].r,yb.i); 428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB(*Fout1,scratch[5],scratch[6]); 430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD(*Fout4,scratch[5],scratch[6]); 431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); 433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); 434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[12].r = S_MUL(scratch[10].i,yb.i) - S_MUL(scratch[9].i,ya.i); 435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org scratch[12].i = -S_MUL(scratch[10].r,yb.i) + S_MUL(scratch[9].r,ya.i); 436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_ADD(*Fout2,scratch[11],scratch[12]); 438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org C_SUB(*Fout3,scratch[11],scratch[12]); 439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; 441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef CUSTOM_MODES 449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic 451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid compute_bitrev_table( 452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int Fout, 453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int16 *f, 454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const size_t fstride, 455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int in_stride, 456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int16 * factors, 457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const kiss_fft_state *st 458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const int p=*factors++; /* the radix */ 461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const int m=*factors++; /* stage's fft length/p */ 462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ 464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (m==1) 465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<p;j++) 468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *f = Fout+j; 470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org f += fstride*in_stride; 471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int j; 474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<p;j++) 475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st); 477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org f += fstride*in_stride; 478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Fout += m; 479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* facbuf is populated by p1,m1,p2,m2, ... 484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org where 485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org p[i] * m[i] = m[i-1] 486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m0 = n */ 487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic 488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint kf_factor(int n,opus_int16 * facbuf) 489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int p=4; 491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*factor out powers of 4, powers of 2, then any remaining primes */ 493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org while (n % p) { 495885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org switch (p) { 496885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 4: p = 2; break; 497885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 2: p = 3; break; 498885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org default: p += 2; break; 499885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 500885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (p>32000 || (opus_int32)p*(opus_int32)p > n) 501885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org p = n; /* no more factors, skip to end */ 502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org n /= p; 504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RADIX_TWO_ONLY 505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (p!=2 && p != 4) 506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (p>5) 508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return 0; 511885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *facbuf++ = p; 513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *facbuf++ = n; 514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while (n > 1); 515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return 1; 516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft) 519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<nfft;++i) { 523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 phase = -i; 524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft)); 525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 527885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<nfft;++i) { 528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const double pi=3.14159265358979323846264338327; 529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org double phase = ( -2*pi /nfft ) * i; 530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kf_cexp(twiddles+i, phase ); 531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 535885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* 536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * 537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * Allocates all necessary storage space for the fft and ifft. 538885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * The return value is a contiguous block of memory. As such, 539885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * It can be freed with free(). 540885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * */ 541885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgkiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base) 542885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 543885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_fft_state *st=NULL; 544885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/ 545885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 546885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if ( lenmem==NULL ) { 547885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded ); 548885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }else{ 549885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (mem != NULL && *lenmem >= memneeded) 550885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st = (kiss_fft_state*)mem; 551885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *lenmem = memneeded; 552885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 553885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (st) { 554885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_int16 *bitrev; 555885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kiss_twiddle_cpx *twiddles; 556885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 557885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->nfft=nfft; 558885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef FIXED_POINT 559885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->scale = 1.f/nfft; 560885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 561885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (base != NULL) 562885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 563885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->twiddles = base->twiddles; 564885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->shift = 0; 565885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org while (nfft<<st->shift != base->nfft && st->shift < 32) 566885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->shift++; 567885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (st->shift>=32) 568885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org goto fail; 569885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 570885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft); 571885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org compute_twiddles(twiddles, nfft); 572885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->shift = -1; 573885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 574885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (!kf_factor(nfft,st->factors)) 575885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 576885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org goto fail; 577885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 578885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 579885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* bitrev */ 580885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft); 581885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (st->bitrev==NULL) 582885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org goto fail; 583885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org compute_bitrev_table(0, bitrev, 1,1, st->factors,st); 584885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 585885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return st; 586885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgfail: 587885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_fft_free(st); 588885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return NULL; 589885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 590885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 591885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgkiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem ) 592885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 593885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL); 594885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 595885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 596885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid opus_fft_free(const kiss_fft_state *cfg) 597885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 598885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (cfg) 599885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 600885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_free((opus_int16*)cfg->bitrev); 601885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (cfg->shift < 0) 602885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_free((kiss_twiddle_cpx*)cfg->twiddles); 603885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_free((kiss_fft_state*)cfg); 604885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 605885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 606885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 607885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* CUSTOM_MODES */ 608885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 609885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) 610885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 611885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m2, m; 612885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int p; 613885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int L; 614885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int fstride[MAXFACTORS]; 615885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 616885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shift; 617885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 618885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* st->shift can be -1 */ 619885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift = st->shift>0 ? st->shift : 0; 620885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 621885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2 (fin != fout, "In-place FFT not supported"); 622885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Bit-reverse the input */ 623885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<st->nfft;i++) 624885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 625885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fout[st->bitrev[i]] = fin[i]; 626885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef FIXED_POINT 627885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fout[st->bitrev[i]].r *= st->scale; 628885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fout[st->bitrev[i]].i *= st->scale; 629885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 630885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 631885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 632885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fstride[0] = 1; 633885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org L=0; 634885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 635885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org p = st->factors[2*L]; 636885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = st->factors[2*L+1]; 637885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fstride[L+1] = fstride[L]*p; 638885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org L++; 639885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while(m!=1); 640885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = st->factors[2*L-1]; 641885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=L-1;i>=0;i--) 642885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 643885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (i!=0) 644885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m2 = st->factors[2*i-1]; 645885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 646885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m2 = 1; 647885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org switch (st->factors[2*i]) 648885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 649885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 2: 650885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kf_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2); 651885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 652885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 4: 653885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2); 654885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 655885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #ifndef RADIX_TWO_ONLY 656885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 3: 657885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2); 658885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 659885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 5: 660885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2); 661885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 662885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #endif 663885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 664885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = m2; 665885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 666885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 667885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 668885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid opus_ifft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) 669885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 670885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int m2, m; 671885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int p; 672885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int L; 673885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int fstride[MAXFACTORS]; 674885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 675885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shift; 676885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 677885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* st->shift can be -1 */ 678885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift = st->shift>0 ? st->shift : 0; 679885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert2 (fin != fout, "In-place FFT not supported"); 680885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Bit-reverse the input */ 681885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<st->nfft;i++) 682885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fout[st->bitrev[i]] = fin[i]; 683885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 684885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fstride[0] = 1; 685885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org L=0; 686885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org do { 687885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org p = st->factors[2*L]; 688885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = st->factors[2*L+1]; 689885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org fstride[L+1] = fstride[L]*p; 690885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org L++; 691885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } while(m!=1); 692885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = st->factors[2*L-1]; 693885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=L-1;i>=0;i--) 694885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 695885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (i!=0) 696885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m2 = st->factors[2*i-1]; 697885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 698885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m2 = 1; 699885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org switch (st->factors[2*i]) 700885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 701885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 2: 702885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ki_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2); 703885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 704885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 4: 705885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ki_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2); 706885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 707885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef RADIX_TWO_ONLY 708885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 3: 709885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ki_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2); 710885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 711885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org case 5: 712885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ki_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2); 713885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 714885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 715885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 716885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org m = m2; 717885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 718885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 719885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 720