Mercurial > hg > x
comparison sinest.h @ 2:fc19d45615d1
* Make all file names lower-case to avoid case ambiguity
(some includes differed in case from the filenames they were
trying to include). Also replace MinGW-specific mem.h with
string.h
author | Chris Cannam |
---|---|
date | Tue, 05 Oct 2010 11:04:40 +0100 |
parents | SinEst.h@6422640a802f |
children | 5f3c32dc6e17 |
comparison
equal
deleted
inserted
replaced
1:6422640a802f | 2:fc19d45615d1 |
---|---|
1 #ifndef SinEstH | |
2 #define SinEstH | |
3 | |
4 /* | |
5 SinEst.cpp - sinusoid estimation algorithms | |
6 */ | |
7 | |
8 | |
9 #include <string.h> | |
10 #include "xcomplex.h" | |
11 #include "arrayalloc.h" | |
12 #include "matrix.h" | |
13 #ifdef I | |
14 #undef I | |
15 #endif | |
16 | |
17 //--since function derivative------------------------------------------------ | |
18 double ddsincd_unn(double x, int N); | |
19 double dsincd_unn(double x, int N); | |
20 | |
21 //--window spectrum and derivatives------------------------------------------ | |
22 cdouble* Window(cdouble* x, double f, int N, int M, double* c, int K1, int K2); | |
23 void dWindow(cdouble* dx, cdouble* x, double f, int N, int M, double* c, int K1, int K2); | |
24 void ddWindow(cdouble* ddx, cdouble* dx, cdouble* x, double f, int N, int M, double* c, int K1, int K2); | |
25 | |
26 //--spectral projection routines--------------------------------------------- | |
27 cdouble IPWindowC(double f, cdouble* x, int N, int M, double* c, double iH2, int K1, int K2); | |
28 | |
29 double IPWindow(double f, cdouble* x, int N, int M, double* c, double iH2, int K1, int K2, bool returnamplitude); | |
30 double IPWindow(double f, void* params); | |
31 double ddIPWindow(double f, void* params); | |
32 double ddIPWindow(double f, cdouble* x, int N, int M, double* c, double iH2, int K1, int K2, double& dipwindow, double& ipwindow); | |
33 | |
34 double sIPWindow(double f, int L, cdouble** x, int N, int M, double* c, double iH2, int K1, int K2, cdouble* ej2ph=0); | |
35 double sIPWindow(double f, void* params); | |
36 double dsIPWindow(double f, int L, cdouble** x, int N, int M, double* c, double iH2, int K1, int K2, double& sip); | |
37 double dsIPWindow(double f, void* params); | |
38 double ddsIPWindow(double f, int L, cdouble** x, int N, int M, double* c, double iH2, int K1, int K2, double& dsip, double& sip); | |
39 double ddsIPWindow(double f, void* params); | |
40 double ddsIPWindow_unn(double f, cdouble* x, int N, int M, double* c, int K1, int K2, double& dsipwindow, double& sipwindow, cdouble* w_unn=0); | |
41 | |
42 double sIPWindowC(double f, int L, double offst_rel, cdouble** x, int N, int M, double* c, double iH2, int K1, int K2, cdouble* ej2ph=0); | |
43 double sIPWindowC(double f, void* params); | |
44 double dsIPWindowC(double f, int L, double offst_rel, cdouble** x, int N, int M, double* c, double iH2, int K1, int K2, double& sip); | |
45 double dsIPWindowC(double f, void* params); | |
46 double ddsIPWindowC(double f, int L, double offst_rel, cdouble** x, int N, int M, double* c, double iH2, int K1, int K2, double& dsip, double& sip); | |
47 double ddsIPWindowC(double f, void* params); | |
48 | |
49 //--least-square sinusoid estimation routines-------------------------------- | |
50 double LSESinusoid(cdouble* x, int N, double B, int M, double* c, double iH2, double& a, double& pp, double epf=1e-6); | |
51 void LSESinusoid(double& f, cdouble* x, int N, double B, int M, double* c, double iH2, double& a, double& pp, double epf=1e-6); | |
52 double LSESinusoid(int f1, int f2, cdouble* x, int N, double B, int M, double* c, double iH2, double& a, double& pp, double epf); | |
53 int LSESinusoid(double& f, double f1, double f2, cdouble* x, int N, double B, int M, double* c, double iH2, double& a, double& pp, double epf); | |
54 double LSESinusoidMP(double& f, double f1, double f2, cdouble** x, int Fr, int N, double B, int M, double* c, double iH2, double* a, double* ph, double epf); | |
55 | |
56 //--multi-sinusoid spectral projection routines------------------------------ | |
57 void IPMulti(int I, double* f, cdouble* lmd, cdouble* x, int Wid, int K1, int K2, int M, double* c, double eps=0); | |
58 void IPMulti(int I, double* f, cdouble* lmd, cfloat* x, int Wid, int K1, int K2, int M, double* c, double eps=0, double* sens=0, double* r1=0); | |
59 void IPMultiSens(int I, double* f, int Wid, int K1, int K2, int M, double* c, double* sens, double eps=0); | |
60 double IPMulti(int I, double* f, cdouble* lmd, cdouble* x, int Wid, int M, double* c, double iH2, int B); | |
61 double IPMulti_Direct(int I, double* f, double* ph, double* a, cdouble* x, int Wid, int M, double* c, double iH2, int B); | |
62 double IPMulti_GS(int I, double* f, double* ph, double* a, cdouble* x, int Wid, int M, double* c, double iH2, int B, double** L=0, double** Q=0); | |
63 cdouble* IPMulti(int I, int J, double* f, double* ph, double* a, cdouble* x, int Wid, int M, double* c, cdouble** wt=0, cdouble** Q=0, double** L=0, MList* RetList=0); | |
64 | |
65 //--dual-sinusoid spectral projection routines------------------------------- | |
66 double WindowDuo(double df, int N, double* d, int M, cdouble* w); | |
67 double ddWindowDuo(double df, int N, double* d, int M, double& dwindow, double& window, cdouble* w); | |
68 double sIPWindowDuo(double f1, double f2, cdouble* x, int N, double* c, double* d, int M, double iH2, int K1, int K2, cdouble& lmd1, cdouble& lmd2); | |
69 double sIPWindowDuo(double f2, void* params); | |
70 void ddsIPWindowDuo(double* ddsip2, double f1, double f2, cdouble* x, int N, double* c, double* d, int M, double iH2, int K1, int K2, cdouble& lmd1, cdouble& lmd2); | |
71 double ddsIPWindowDuo(double f2, void* params); | |
72 int LSEDuo(double& f2, double fmin, double fmax, double f1, cdouble* x, int N, double B, double* c, double* d, int M, double iH2, cdouble& r1, cdouble &r2, double epf); | |
73 | |
74 //--time-frequency reassignment---------------------------------------------- | |
75 void TFReas(double& f, double& t, double& fslope, int Wid, cdouble* data, double* win, double* dwin, double* ddwin, double* plogaslope=0); | |
76 void TFReas(double& f, double t, double& a, double& ph, double& fslope, int Wid, cdouble* data, double* w, double* dw, double* ddw, double* win=0); | |
77 | |
78 //--additive and multiplicative reestimation routines------------------------ | |
79 typedef double (*TBasicAnalyzer)(double* fs, double* as, double* phs, double* das, cdouble* x, int Count, int Wid, int Offst, __int16* ref, int reserved, bool LogA); | |
80 void AdditiveUpdate(double* fs, double* as, double* phs, double* das, cdouble* x, int Count, int Wid, int Offst, TBasicAnalyzer BasicAnalyzer, int reserved, bool LogA=false); | |
81 void AdditiveAnalyzer(double* fs, double* as, double* phs, double* das, cdouble* x, int Count, int Wid, int Offst, __int16* ref, TBasicAnalyzer BasicAnalyzer, int reserved, bool LogA=false); | |
82 void MultiplicativeUpdate(double* fs, double* as, double* phs, double* das, cdouble* x, int Count, int Wid, int Offst, TBasicAnalyzer BasicAnalyzer, int reserved, bool LogA=false); | |
83 void MultiplicativeAnalyzer(double* fs, double* as, double* phs, double* das, cdouble* x, int Count, int Wid, int Offst, __int16* ref, TBasicAnalyzer BasicAnalyzer, int reserved, bool LogA=false); | |
84 void MultiplicativeUpdateF(double* fs, double* as, double* phs, __int16* x, int Fr, int frst, int fren, int Wid, int Offst); | |
85 | |
86 void ReEstFreq(int FrCount, int Wid, int Offst, double* x, double* fbuf, double* abuf, double* pbuf, double* win, int M, double* c, double iH2, cdouble* w, cdouble* xc, cdouble* xs, double* ps, double* fa, double* fb, double* fc, double* fd, double* ns, int* Wids=0); | |
87 void ReEstFreq_2(int FrCount, int Wid, int Offst, double* x, double* fbuf, double* abuf, double* pbuf, double* win, int M, double* c, double iH2, cdouble* w, cdouble* xc, cdouble* xs, double* f3, double* f2, double* f1, double* f0, double* ns); | |
88 void ReEstFreqAmp(int FrCount, int Wid, int Offst, double* x, double* fbuf, double* abuf, double* pbuf, double* win, int M, double* c, double iH2, cdouble* w, cdouble* xc, cdouble* xs, double* ps, double* as, double* fa, double* fb, double* fc, double* fd, double* aa, double* ab, double* ac, double* ad, double* ns, int* Wids=0); | |
89 int Reestimate2(int FrCount, int Wid, int Offst, double* win, int M, double* c, double iH2, double* x, double* ae, double* fe, double* pe, double* aret, double* fret, double *pret, int maxiter, int* Wids=0); | |
90 | |
91 //--local derivative algorithms - DAFx09------------------------------------- | |
92 void Derivative(int M, double (**h)(double t, void*), double (**dh)(double t, void*), cdouble* r, int p0s, int* p0, int q0s, int* q0, int Wid, double* s, double** win, double omg, void* harg); | |
93 void DerivativeLS(int K, int M, double (**h)(double t, void* harg), double (**dh)(double t, void* harg), cdouble* r, int p0s, int* p0, int q0s, int* q0, int Wid, double* s, double** win, double omg, void* harg, bool r0=false); | |
94 void DerivativeLS(int Fr, int K, int M, double (**h)(double t, void* harg), double (**dh)(double t, void* harg), cdouble* r, int p0s, int* p0, int q0s, int* q0, int Wid, double* s, double** win, double omg, void* harg, bool r0=false); | |
95 | |
96 //--the Abe-Smith estimator-------------------------------------------------- | |
97 void TFAS05(double& f, double& t, double& a, double& ph, double& aesp, double& fslope, int Wid, double* data, double* w, double res=1); | |
98 void TFAS05_enh(double& f, double& t, double& a, double& ph, double& aesp, double& fslope, int Wid, double* data, double* w, double res=1); | |
99 void TFAS05_enh(double& f, double& t, double& a, double& ph, int Wid, double* data, double* w, double res=1); | |
100 | |
101 //--piecewise derivative algorithms and tools-------------------------------- | |
102 void DerivativePiecewise(int N, cdouble* aita, int L, double* f, int T, cdouble* s, double*** A, int M, double** h, int I, cdouble** u, cdouble** du, int endmode=0, cdouble* ds=0); | |
103 void DerivativePiecewise2(int Np, double* p, int Nq, double* q, int L, double* f, int T, cdouble* s, double*** A, double*** B, int M, double** h, int I, cdouble** u, cdouble** du, int endmode=0, cdouble* ds=0); | |
104 void DerivativePiecewise3(int Np, double* p, int Nq, double* q, int L, double* f, int T, cdouble* s, double*** DA, double*** B, int M, double** h, int I, cdouble** u, cdouble** du, int endmode=0, cdouble* ds=0, double** dh=0); | |
105 void seth(int M, int T, double**& h, MList* mlist); | |
106 void setdh(int M, int T, double**& dh, MList* mlist); | |
107 void setdih(int M, int T, double**& dih, MList* mlist); | |
108 void setu(int I, int Wid, cdouble**& u, cdouble**& du, int WinOrder=2, MList* mlist=0); | |
109 void ssALinearSpline(int L, int T, int M, int& N, double*** &A, MList* mlist, int mode=0); | |
110 void ssACubicHermite(int L, int T, int M, int& N, double*** &A, MList* mlist, int mode=0); | |
111 void ssACubicSpline(int L, int T, int M, int& N, double*** &A, MList* mlist, int mode=0); | |
112 void ssLinearSpline(int L, int T, int M, int &N, double** &h, double*** &A, MList* mlist, int mode=0); | |
113 void ssCubicHermite(int L, int T, int M, int& N, double** &h, double*** &A, MList* mlist, int mode=0); | |
114 void ssCubicSpline(int L, int T, int M, int& N, double** &h, double*** &A, MList* mlist, int mode=0); | |
115 void DerivativePiecewiseI(cdouble* aita, int L, double* f, int T, cdouble* s, int M, void (*SpecifyA)(int L, int T, int M, int &N, double*** &A, MList* mlist, int mode), int ssmode=0, int WinOrder=2, int I=2, int endmode=0, cdouble* ds=0); | |
116 void DerivativePiecewiseII(double* p, double* q, int L, double* f, int T, cdouble* s, int M, void (*SpecifyA)(int L, int T, int M, int &N, double*** &A, MList* mlist, int mode), int ssAmode, void (*SpecifyB)(int L, int T, int M, int &N, double*** &B, MList* mlist, int mode), int ssBmode, int WinOrder=2, int I=2, int endmode=0, cdouble* ds=0); | |
117 void DerivativePiecewiseIII(double* p, double* q, int L, double* f, int T, cdouble* s, int M, void (*SpecifyA)(int L, int T, int M, int &N, double*** &A, MList* mlist, int mode), int ssAmode, void (*SpecifyB)(int L, int T, int M, int &N, double*** &B, MList* mlist, int mode), int ssBmode, int WinOrder=2, int I=2, int endmode=0, cdouble* ds=0); | |
118 double AmpPhCorrectionExpA(cdouble* s2, int N, cdouble* aita, int L, int T, cdouble* sre, int M, double** h, double** dih, double*** A, void (*SpecifyA)(int L, int T, int M, int &N, double*** &A, MList* mlist, int mode), int WinOrder); | |
119 | |
120 //--local derivative algorithms - general------------------------------------ | |
121 /* | |
122 template DerivativeLSv: local derivative algorithm for estimating time-varying sinusoids, "v" version, | |
123 i.e. using tuned test functions. | |
124 | |
125 In: s[Wid]: waveform data | |
126 v[I][Wid], dv[I][Wid]: test functions and their derivatives | |
127 h[M+1][Wid]: basis functions | |
128 p0[p0s], q0[q0s]: zero-constraints, i.e. Re(lmd[p0[*]]) and Im(lmd[q0[*]]) are constrained zero. | |
129 Out: lmd[1:M]: coefficients of h[1:M]. | |
130 | |
131 Returns inner product of s and v[0]. | |
132 */ | |
133 template<class Ts>cdouble DerivativeLSv(int Wid, Ts* s, int I, cdouble** v, cdouble** dv, int M, double **h, cdouble* lmd, int p0s, int* p0, int q0s, int* q0) | |
134 { | |
135 int Kr=M*2-p0s-q0s; //number of real unknowns apart from p0 and q0 | |
136 if (I<ceil(Kr/2.0)) throw("insufficient test functions"); //Kr/2 complex equations are needed to solve the unknowns | |
137 | |
138 //ind maps the real unknowns to their positions in physical buffer | |
139 //uind maps them back | |
140 int *uind=new int[Kr], *ind=new int[2*M]; | |
141 memset(ind, 0, sizeof(int)*2*M); | |
142 for (int p=0; p<p0s; p++) ind[2*(p0[p]-1)]=-1; | |
143 for (int q=0; q<q0s; q++) ind[2*(q0[q]-1)+1]=-1; | |
144 | |
145 { | |
146 int p=0, up=0; while (p<2*M){if (ind[p]>=0){uind[up]=p; ind[p]=up; up++;} p++;} | |
147 if (up!=Kr) throw(""); | |
148 } | |
149 | |
150 cdouble* sv1=new cdouble[I]; | |
151 for (int i=0; i<I; i++) sv1[i]=-Inner(Wid, s, dv[i]); | |
152 | |
153 double** Allocate2(double, 2*I, Kr, A); | |
154 for (int m=1; m<=M; m++) | |
155 for (int i=0; i<I; i++) | |
156 { | |
157 int lind; | |
158 cdouble shv=Inner(Wid, s, h[m], v[i]); | |
159 if ((lind=ind[2*(m-1)])>=0) | |
160 { | |
161 A[2*i][lind]=shv.x; | |
162 A[2*i+1][lind]=shv.y; | |
163 } | |
164 if ((lind=ind[2*m-1])>=0) | |
165 { | |
166 A[2*i][lind]=-shv.y; | |
167 A[2*i+1][lind]=shv.x; | |
168 } | |
169 } | |
170 | |
171 double* pq=new double[Kr]; | |
172 if (2*I==Kr) GECP(Kr, pq, A, (double*)sv1); | |
173 else LSLinear(2*I, Kr, pq, A, (double*)sv1); | |
174 | |
175 memset(lmd, 0, sizeof(double)*(M+1)*2); | |
176 for (int k=0; k<Kr; k++) ((double*)(&lmd[1]))[uind[k]]=pq[k]; | |
177 | |
178 cdouble result=Inner(Wid, s, v[0]); | |
179 delete[] pq; | |
180 delete[] sv1; | |
181 delete[] uind; | |
182 delete[] ind; | |
183 DeAlloc2(A); | |
184 return result; | |
185 }//DerivativeLSv | |
186 | |
187 /* | |
188 template DerivativeLS: local derivative algorithm for estimating time-varying sinusoids, "u" version, | |
189 i.e. using base-band test functions. | |
190 | |
191 In: s[Wid]: waveform data | |
192 u[I][Wid], du[I][Wid]: base-band test functions and their derivatives | |
193 omg: angular frequency onto which u[I] and du[I] are modulated to give the test functions | |
194 h[M+1][Wid]: basis functions | |
195 p0[p0s], q0[q0s]: zero-constraints, i.e. Re(lmd[p0[*]]) and Im(lmd[q0[*]]) are constrained zero. | |
196 Out: lmd[1:M]: coefficients of h[1:M]. | |
197 | |
198 Returns inner product of s and v[0]. | |
199 */ | |
200 template<class Ts, class Tu>cdouble DerivativeLS(int Wid, Ts* s, int I, double omg, Tu** u, Tu** du, int M, double **h, cdouble* lmd, int p0s, int* p0, int q0s, int* q0) | |
201 { | |
202 cdouble** Allocate2(cdouble, I, Wid, v); | |
203 cdouble** Allocate2(cdouble, I, Wid, dv); | |
204 cdouble jomg=cdouble(0, omg); int hWid=Wid/2; | |
205 for (int c=0; c<Wid; c++) | |
206 { | |
207 double t=c-hWid; | |
208 cdouble rot=cdouble(1).rotate(omg*t); | |
209 for (int i=0; i<I; i++) v[i][c]=u[i][c]*rot; | |
210 for (int i=0; i<I; i++) dv[i][c]=du[i][c]*rot+jomg*v[i][c]; | |
211 } | |
212 cdouble result=DerivativeLSv(Wid, s, I, v, dv, M, h, lmd, p0s, p0, q0s, q0); | |
213 DeAlloc2(v); DeAlloc2(dv); | |
214 return result; | |
215 }//DerivativeLS | |
216 | |
217 /* | |
218 template DerivativeLS_AmpPh: amplitude and phase estimation in the local derivative algorithm, "u" | |
219 version | |
220 | |
221 In: sv0: inner product of signal s[Wid] and test function v0 | |
222 u0[Wid], omg: base-band test function and carrier frequency used for computing v0[] | |
223 integr_h[M+1][Wid]: integrals of basis functions | |
224 | |
225 Returns coefficient to integr_h[0]=1. | |
226 */ | |
227 template<class Tu>cdouble DerivativeLS_AmpPh(int Wid, int M, double** integr_h, cdouble* lmd, double omg, Tu* u0, cdouble sv0) | |
228 { | |
229 cdouble e0=0; double hWid=Wid/2.0; | |
230 for (int n=0; n<Wid; n++) | |
231 { | |
232 cdouble expo=0; | |
233 for (int m=1; m<=M; m++) expo+=lmd[m]*integr_h[m][n]; | |
234 if (expo.x>300) expo.x=300; | |
235 else if (expo.x<-300) expo.x=-300; | |
236 e0+=exp(expo)**(cdouble(u0[n]).rotate(omg*(n-hWid))); | |
237 } | |
238 return log(sv0/e0); | |
239 }//DerivativeLS_AmpPh | |
240 | |
241 /* | |
242 template DerivativeLS_AmpPh: amplitude and phase estimation in the local derivative algorithm, "u" | |
243 version. | |
244 | |
245 In: s[Wid]: waveform data | |
246 u0[Wid], omg: base-band test function and carrier frequency used for computing v0[] | |
247 integr_h[M+1][Wid]: integrals of basis functions | |
248 | |
249 Returns coefficient to integr_h[0]=1. | |
250 */ | |
251 template<class Tu, class Ts>cdouble DerivativeLS_AmpPh(int Wid, int M, double** integr_h, cdouble* lmd, double omg, Tu* u0, Ts* s) | |
252 { | |
253 cdouble ss0=0, e0=0; double hWid=Wid/2.0; | |
254 for (int n=0; n<Wid; n++) | |
255 { | |
256 cdouble expo=0; | |
257 for (int m=1; m<=M; m++) expo+=lmd[m]*integr_h[m][n]; | |
258 if (expo.x>300) expo.x=300; | |
259 else if (expo.x<-300) expo.x=-300; | |
260 e0+=~exp(expo)*abs(u0[n]); | |
261 ss0+=s[n]**exp(expo)*abs(u0[n]); | |
262 } | |
263 return log(ss0/e0); | |
264 }//DerivativeLS_AmpPh | |
265 | |
266 cdouble DerivativeLSv_AmpPh(int, int, double**, cdouble*, cdouble*, cdouble); //the "v" version is implemented as a normal function in SinEst.cpp. | |
267 | |
268 /* | |
269 template DerivativeLSv: local derivative algorithm for estimating time-varying sinusoids, "v" version. | |
270 | |
271 In: s[Wid]: waveform data | |
272 v[I][Wid], dv[I][Wid]: test functions and their derivatives | |
273 h[M+1][Wid], integr_h[M+1][Wid]: basis functions and their integrals | |
274 p0[p0s], q0[q0s]: zero-constraints, i.e. Re(lmd[p0[*]]) and Im(lmd[q0[*]]) are constrained zero. | |
275 Out: lmd[M+1]: coefficients of h[M+1], including lmd[0]. | |
276 | |
277 No return value. | |
278 */ | |
279 template<class Ts> void DerivativeLSv(int Wid, Ts* s, int I, cdouble** v, cdouble** dv, int M, double **h, double **integr_h, cdouble* lmd, int p0s, int* p0, int q0s, int* q0) | |
280 { | |
281 cdouble sv0=DerivativeLSv(Wid, s, I, v, dv, M, h, lmd, p0s, p0, q0s, q0); | |
282 lmd[0]=DerivativeLSv_AmpPh(Wid, M, integr_h, lmd, v[0], sv0); | |
283 }//DerivativeLSv_AmpPh | |
284 | |
285 /*template DerivativeLSv: local derivative algorithm for estimating time-varying sinusoids, "u" version. | |
286 | |
287 In: s[Wid]: waveform data | |
288 u[I][Wid], du[I][Wid]: base-band test functions and their derivatives | |
289 omg: angular frequency onto which u[I] and du[I] are modulated to give the test functions | |
290 h[M+1][Wid], integr_h[M+1][Wid]: basis functions and their integrals | |
291 p0[p0s], q0[q0s]: zero-constraints, i.e. Re(lmd[p0[*]]) and Im(lmd[q0[*]]) are constrained zero. | |
292 Out: lmd[M+1]: coefficients of h[M+1], including lmd[0]. | |
293 | |
294 No return value. | |
295 */ | |
296 template<class Ts, class Tu>void DerivativeLS(int Wid, Ts* s, int I, double omg, Tu** u, Tu** du, int M, double **h, double **integr_h, cdouble* lmd, int p0s, int* p0, int q0s, int* q0) | |
297 { | |
298 cdouble sv0=DerivativeLS(Wid, s, I, omg, u, du, M, h, lmd, p0s, p0, q0s, q0); | |
299 lmd[0]=DerivativeLS_AmpPh(Wid, M, integr_h, lmd, omg, u[0], s); //sv0); | |
300 }//DerivativeLSv | |
301 | |
302 /* | |
303 template CosineWindows: generates the Hann^(K/2) window and its L-1 derivatives as Result[L][Wid+1] | |
304 | |
305 In: K, L, Wid | |
306 Out: w[L][Wid+1]: Hann^(K/2) window function and its derivatives up to order L-1 | |
307 | |
308 Returns pointer to w. w is created anew if w=0 is specified on start. | |
309 */ | |
310 template<class T>T** CosineWindows(int K, int Wid, T **w, int L=0) | |
311 { | |
312 if (L<=0) L=K; | |
313 if (!w) {Allocate2(T, L, Wid+1, w);} | |
314 memset(w[0], 0, sizeof(T)*L*(Wid+1)); | |
315 int hWid=Wid/2, dWid=Wid*2; | |
316 double *s=new double[dWid+hWid], *c=&s[hWid]; //s[n]=sin(pi*n/N), n=0, ..., 2N-1 | |
317 double *C=new double[K+2], *lK=&C[K/2+1], piC=M_PI/Wid; | |
318 //C[i]=C(K, i)(-1)^i*2^(-K+1), the combination number, i=0, ..., K/2 | |
319 //ik[i]=(K-2i)^k*(M_PI/Wid)^k, i=0, ..., K/2 | |
320 //calculate C(K,i)(-1)^i*2^(-K+1) | |
321 C[0]=1.0/(1<<(K-1)); double lC=C[0]; for (int i=1; i+i<=K; i++){lC=lC*(K-i+1)/i; C[i]=(i%2)?(-lC):lC;} | |
322 //calculate sin/cos functions | |
323 for (int n=0; n<dWid; n++) s[n]=sin(n*piC); memcpy(&s[dWid], s, sizeof(double)*hWid); | |
324 for (int k=0; k<L; k++) | |
325 { | |
326 if (k==0) for (int i=0; i+i<K; i++) lK[i]=C[i]; | |
327 else for (int i=0; i+i<K; i++) lK[i]*=(K-2*i)*piC; | |
328 | |
329 if ((K-k)%2) //K-k is odd | |
330 { | |
331 for (int i=0; i+i<K; i++) for (int n=0; n<=Wid; n++) w[k][n]+=lK[i]*s[(K-2*i)*n%dWid]; | |
332 if ((K-k-1)/2%2) for (int n=0; n<=Wid; n++) w[k][n]=-w[k][n]; | |
333 } | |
334 else | |
335 { | |
336 for (int i=0; i+i<K; i++) for (int n=0; n<=Wid; n++) w[k][n]+=lK[i]*c[(K-2*i)*n%dWid]; | |
337 if ((K-k)/2%2) for (int n=0; n<=Wid; n++) w[k][n]=-w[k][n]; | |
338 } | |
339 } | |
340 if (K%2==0){double tmp=C[K/2]*0.5; if (K/2%2) tmp=-tmp; for (int n=0; n<=Wid; n++) w[0][n]+=tmp;} | |
341 delete[] s; delete[] C; | |
342 return w; | |
343 }//CosineWindows | |
344 | |
345 | |
346 #endif |