xue@11: /* xue@11: Harmonic sinusoidal modelling and tools xue@11: xue@11: C++ code package for harmonic sinusoidal modelling and relevant signal processing. xue@11: Centre for Digital Music, Queen Mary, University of London. xue@11: This file copyright 2011 Wen Xue. xue@11: xue@11: This program is free software; you can redistribute it and/or xue@11: modify it under the terms of the GNU General Public License as xue@11: published by the Free Software Foundation; either version 2 of the xue@11: License, or (at your option) any later version. xue@11: */ xue@1: //--------------------------------------------------------------------------- xue@1: Chris@2: #include xue@1: #include xue@1: #include "fft.h" xue@1: Chris@5: /** \file fft.h */ Chris@5: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function Atan2: (0, 0)-safe atan2 xue@1: xue@1: Returns 0 is x=y=0, atan2(x,y) otherwise. xue@1: */ xue@1: double Atan2(double y, double x) xue@1: { xue@1: if (x==0 && y==0) return 0; xue@1: else return atan2(y, x); xue@1: }//Atan2 xue@1: Chris@5: /** xue@11: function Log2: Log2 xue@11: xue@11: Returns x for Log2(2^x) if x is integer. xue@11: */ xue@11: int Log2(int x) xue@11: { xue@11: return floor(log(x)/log(2)+0.5); xue@11: }//Log2 xue@11: xue@11: /** xue@1: function BitInv: inverse bit order of Value within an $Order-bit expression. xue@1: xue@1: In: integer Value smaller than 2^Order xue@1: xue@1: Returns an integer whose lowest Order bits are the lowest Order bits of Value in reverse order. xue@1: */ xue@1: int BitInv(int Value, int Order) xue@1: { xue@1: int Result; xue@1: Result=0; xue@1: for (int i=0;i>1; xue@1: } xue@1: return Result; xue@1: }//BitInv xue@1: Chris@5: /** xue@1: function SetTwiddleFactors: fill w[N/2] with twiddle factors used in N-point complex FFT. xue@1: xue@1: In: N xue@1: Out: array w[N/2] containing twiddle factors xue@1: xue@1: No return value. xue@1: */ xue@1: void SetTwiddleFactors(int N, cdouble* w) xue@1: { xue@1: double ep=-M_PI*2/N; xue@1: for (int i=0; i1) xue@1: { xue@1: //N=2^order, 4|N, 2|hN xue@1: //keep subsequence 0, 2C, 4C, ... 2(N-1)C xue@1: //process sequence C, 3C, ..., (2N-1)C only xue@1: //RDCT4 routine xue@1: int hN=N/2, N2=N*2; xue@1: for (int i=0; i>1); xue@1: C=(C<<1); xue@1: for (int i=1; i0) xue@1: { xue@1: //N=2^order, 4|N, 2|hN xue@1: //keep subsequence 0, 2C, 4C, ... 2(N-1)C xue@1: //process sequence C, 3C, ..., (2N-1)C only xue@1: //data pass from Input xue@1: for (int i=0; i>1); xue@1: C=(C<<1); xue@1: for (int i=1; iwid) memcpy(&spec[fr][hwid], &data[fr*Wid+hwid], sizeof(double)*(Wid-wid)); xue@1: for (int i=0, j=(fr+1)*Wid-hwid, k=(fr+1)*Wid+hwid-1, l=Wid-hwid; i>=1, M<<=1) xue@1: { xue@1: cdouble *Xn=X[n], *Xp=X[n-1]; xue@1: for (int l=0; l3 xue@1: { xue@1: cdouble *aX=&X[n][l*M+M/2]; xue@1: for (int an=1, aL=1, aM=M/2; an