xue@11
|
1 /*
|
xue@11
|
2 Harmonic sinusoidal modelling and tools
|
xue@11
|
3
|
xue@11
|
4 C++ code package for harmonic sinusoidal modelling and relevant signal processing.
|
xue@11
|
5 Centre for Digital Music, Queen Mary, University of London.
|
xue@11
|
6 This file copyright 2011 Wen Xue.
|
xue@11
|
7
|
xue@11
|
8 This program is free software; you can redistribute it and/or
|
xue@11
|
9 modify it under the terms of the GNU General Public License as
|
xue@11
|
10 published by the Free Software Foundation; either version 2 of the
|
xue@11
|
11 License, or (at your option) any later version.
|
xue@11
|
12 */
|
xue@1
|
13 //---------------------------------------------------------------------------
|
xue@1
|
14
|
xue@1
|
15 #include <math.h>
|
Chris@2
|
16 #include <string.h>
|
xue@1
|
17 #include "wavelet.h"
|
xue@1
|
18 #include "matrix.h"
|
xue@1
|
19
|
Chris@5
|
20 /** \file wavelet.h */
|
Chris@5
|
21
|
xue@1
|
22 //---------------------------------------------------------------------------
|
Chris@5
|
23 /**
|
xue@1
|
24 function csqrt: real implementation of complex square root z=sqrt(x)
|
xue@1
|
25
|
xue@1
|
26 In: xr and xi: real and imaginary parts of x
|
xue@1
|
27 Out: zr and zi: real and imaginary parts of z=sqrt(x)
|
xue@1
|
28
|
xue@1
|
29 No return value.
|
xue@1
|
30 */
|
xue@1
|
31 void csqrt(double& zr, double& zi, double xr, double xi)
|
xue@1
|
32 {
|
xue@1
|
33 if (xi==0)
|
xue@1
|
34 if (xr>=0) zr=sqrt(xr), zi=0;
|
xue@1
|
35 else zi=sqrt(-xr), zr=0;
|
xue@1
|
36 else
|
xue@1
|
37 {
|
xue@1
|
38 double xm=sqrt(xr*xr+xi*xi);
|
xue@1
|
39 double ri=sqrt((xm-xr)/2);
|
xue@1
|
40 zr=xi/2/ri;
|
xue@1
|
41 zi=ri;
|
xue@1
|
42 }
|
xue@1
|
43 }//csqrt
|
xue@1
|
44
|
Chris@5
|
45 /**
|
xue@1
|
46 function Daubechies: calculates the Daubechies filter of a given order p
|
xue@1
|
47
|
xue@1
|
48 In: filter order p
|
xue@1
|
49 Out: h[2p]: the 2p FIR coefficients
|
xue@1
|
50
|
xue@1
|
51 No reutrn value. The calculated filters are minimum phase, which means the energy concentrates at the
|
xue@1
|
52 beginning. This is usually used for reconstruction. On the contrary, for wavelet analysis the filter
|
xue@1
|
53 is mirrored.
|
xue@1
|
54 */
|
xue@1
|
55 void Daubechies(int p, double* h)
|
xue@1
|
56 {
|
xue@1
|
57 //initialize h(z)
|
xue@1
|
58 double r01=pow(2, -p-p+1.5);
|
xue@1
|
59
|
xue@1
|
60 h[0]=1;
|
xue@1
|
61 for (int i=1; i<=p; i++)
|
xue@1
|
62 {
|
xue@1
|
63 h[i]=h[i-1]*(p+1-i)/i;
|
xue@1
|
64 }
|
xue@1
|
65
|
xue@1
|
66 //construct polynomial p
|
xue@1
|
67 double *P=new double[p], *rp=new double[p], *ip=new double[p];
|
xue@1
|
68
|
xue@1
|
69 P[p-1]=1;
|
xue@1
|
70 double r02=1;
|
xue@1
|
71 for (int i=p-1; i>0; i--)
|
xue@1
|
72 {
|
xue@1
|
73 double rate=(i+1-1.0)/(p-2.0+i+1);
|
xue@1
|
74 P[i-1]=P[i]*rate;
|
xue@1
|
75 r02/=rate;
|
xue@1
|
76 }
|
xue@1
|
77 Roots(p-1, P, rp, ip);
|
xue@1
|
78 for (int i=0; i<p-1; i++)
|
xue@1
|
79 {
|
xue@1
|
80 //current length of h is p+1+i, h[0:p+i]
|
xue@1
|
81 if (i<p-2 && rp[i]==rp[i+1] && ip[i]==-ip[i+1])
|
xue@1
|
82 {
|
xue@1
|
83 double ar=rp[i], ai=ip[i];
|
xue@1
|
84 double bkr=-2*ar+1, bki=-2*ai, ckr=4*(ar*ar-ai*ai-ar), cki=4*(2*ar*ai-ai), dlr, dli;
|
xue@1
|
85 csqrt(dlr, dli, ckr, cki);
|
xue@1
|
86 double akr=bkr+dlr, aki=bki+dli;
|
xue@1
|
87 if (akr*akr+aki*aki>1) akr=bkr-dlr, aki=bki-dli;
|
xue@1
|
88 double ak1=-2*akr, ak2=akr*akr+aki*aki;
|
xue@1
|
89 h[p+2+i]=ak2*h[p+i];
|
xue@1
|
90 h[p+1+i]=ak2*h[p-1+i]+ak1*h[p+i];
|
xue@1
|
91 for (int j=p+i; j>1; j--) h[j]=h[j]+ak1*h[j-1]+ak2*h[j-2];
|
xue@1
|
92 h[1]=h[1]+ak1*h[0];
|
xue@1
|
93 r02/=ak2;
|
xue@1
|
94 i++;
|
xue@1
|
95 }
|
xue@1
|
96 else //real root of P
|
xue@1
|
97 {
|
xue@1
|
98 double ak, bk=-(2*rp[i]-1), delk=4*rp[i]*(rp[i]-1);
|
xue@1
|
99 if (bk>0) ak=bk-sqrt(delk);
|
xue@1
|
100 else ak=bk+sqrt(delk);
|
xue@1
|
101 r02/=ak;
|
xue@1
|
102 h[p+1+i]=-ak*h[p+i];
|
xue@1
|
103 for (int j=p+i; j>0; j--) h[j]=h[j]-ak*h[j-1];
|
xue@1
|
104 }
|
xue@1
|
105 }
|
xue@1
|
106 delete[] P; delete[] rp; delete[] ip;
|
xue@1
|
107 r01=r01*sqrt(r02);
|
xue@1
|
108 for (int i=0; i<p*2; i++) h[i]*=r01;
|
xue@1
|
109 }//Daubechies
|
xue@1
|
110
|
xue@1
|
111 /*
|
xue@1
|
112 Periodic wavelet decomposition and reconstruction routines
|
xue@1
|
113
|
xue@1
|
114 The wavelet transform of an N-point sequence is arranged in "interleaved" format
|
xue@1
|
115 as another N-point sequance. Level 1 details are found at N/2 points 1, 3, 5, ...,
|
xue@1
|
116 N-1; level 2 details are found at N/4 points 2, 6, ..., N-2; level 3 details are
|
xue@1
|
117 found at N/8 points 4, 12, ..., N-4; etc.
|
xue@1
|
118 */
|
xue@1
|
119
|
Chris@5
|
120 /**
|
xue@1
|
121 function dwtpqmf: in this implementation h and g are the same as reconstruction qmf filters. In fact
|
xue@1
|
122 the actual filters used are their mirrors and filter origin are aligned to the ends of the real
|
xue@1
|
123 filters, which turn out to be the starts of h and g.
|
xue@1
|
124
|
xue@1
|
125 The inverse transform is idwtp(), the same as inversing dwtp().
|
xue@1
|
126
|
xue@1
|
127 In: in[Count]: waveform data
|
xue@1
|
128 h[M], g[M]: quadratic mirror filter pair
|
xue@1
|
129 N: maximal time resolution
|
xue@1
|
130 Count=kN, N=2^lN being the reciprocal of the most detailed frequency scale, i.e.
|
xue@1
|
131 N=1 for no transforming at all, N=2 for dividing into approx. and detail,
|
xue@1
|
132 N=4 for dividing into approx+detail(approx+detial), etc.
|
xue@1
|
133 Count*2/N=2k gives the smallest length to be convolved with h and g.
|
xue@1
|
134 Out: out[N], the wavelet transform, arranged in interleaved format.
|
xue@1
|
135
|
xue@1
|
136 Returns maximal atom length (should equal N).
|
xue@1
|
137 */
|
xue@1
|
138 int dwtpqmf(double* in, int Count, int N, double* h, double* g, int M, double* out)
|
xue@1
|
139 {
|
xue@1
|
140 double* tmp=new double[Count];
|
xue@1
|
141 double *tmpa=tmp, *tmpla=in;
|
xue@1
|
142 int C=Count, L=0, n=1;
|
xue@1
|
143
|
xue@1
|
144 A:
|
xue@1
|
145 {
|
xue@1
|
146 //C: signal length at current layer
|
xue@1
|
147 //L: layer index, 0 being most detailed
|
xue@1
|
148 //n: atom length on current layer, equals 2^L.
|
xue@1
|
149 //C*n=(C<<L)=Count
|
xue@1
|
150 double* tmpd=&tmpa[C/2];
|
xue@1
|
151 for (int i=0; i<C; i+=2)
|
xue@1
|
152 {
|
xue@1
|
153 int i2=i/2;
|
xue@1
|
154 tmpa[i2]=tmpla[i]*h[0];
|
xue@1
|
155 tmpd[i2]=tmpla[i]*g[0];
|
xue@1
|
156 for (int j=1; j<M; j++)
|
xue@1
|
157 {
|
xue@1
|
158 if (i+j<C)
|
xue@1
|
159 {
|
xue@1
|
160 tmpa[i2]+=tmpla[i+j]*h[j];
|
xue@1
|
161 tmpd[i2]+=tmpla[i+j]*g[j];
|
xue@1
|
162 }
|
xue@1
|
163 else
|
xue@1
|
164 {
|
xue@1
|
165 tmpa[i2]+=tmpla[i+j-C]*h[j];
|
xue@1
|
166 tmpd[i2]+=tmpla[i+j-C]*g[j];
|
xue@1
|
167 }
|
xue@1
|
168 }
|
xue@1
|
169 }
|
xue@1
|
170 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
|
xue@1
|
171 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
|
xue@1
|
172 n*=2;
|
xue@1
|
173 if (n<N)
|
xue@1
|
174 {
|
xue@1
|
175 tmpla=tmpa;
|
xue@1
|
176 tmpa=tmpd;
|
xue@1
|
177 L++;
|
xue@1
|
178 C/=2;
|
xue@1
|
179 goto A;
|
xue@1
|
180 }
|
xue@1
|
181 }
|
xue@1
|
182 delete[] tmp;
|
xue@1
|
183 return n;
|
xue@1
|
184 }//dwtpqmf
|
xue@1
|
185
|
Chris@5
|
186 /**
|
xue@1
|
187 function dwtp: in this implementation h and g can be different from mirrored reconstruction filters,
|
xue@1
|
188 i.e. the biorthogonal transform. h[0] and g[0] are aligned at the ends of the filters, i.e. h[-M+1:0],
|
xue@1
|
189 g[-M+1:0].
|
xue@1
|
190
|
xue@1
|
191 In: in[Count]: waveform data
|
xue@1
|
192 h[-M+1:0], g[-M+1:0]: quadratic mirror filter pair
|
xue@1
|
193 N: maximal time resolution
|
xue@1
|
194 Out: out[N], the wavelet transform, arranged in interleaved format.
|
xue@1
|
195
|
xue@1
|
196 Returns maximal atom length (should equal N).
|
xue@1
|
197 */
|
xue@1
|
198 int dwtp(double* in, int Count, int N, double* h, double* g, int M, double* out)
|
xue@1
|
199 {
|
xue@1
|
200 double* tmp=new double[Count];
|
xue@1
|
201 double *tmpa=tmp, *tmpla=in;
|
xue@1
|
202 int C=Count, L=0, n=1;
|
xue@1
|
203
|
xue@1
|
204 A:
|
xue@1
|
205 {
|
xue@1
|
206 double* tmpd=&tmpa[C/2];
|
xue@1
|
207 for (int i=0; i<C; i+=2)
|
xue@1
|
208 {
|
xue@1
|
209 int i2=i/2;
|
xue@1
|
210 tmpa[i2]=tmpla[i]*h[0];
|
xue@1
|
211 tmpd[i2]=tmpla[i]*g[0];
|
xue@1
|
212 for (int j=-1; j>-M; j--)
|
xue@1
|
213 {
|
xue@1
|
214 if (i-j<C)
|
xue@1
|
215 {
|
xue@1
|
216 tmpa[i2]+=tmpla[i-j]*h[j];
|
xue@1
|
217 tmpd[i2]+=tmpla[i-j]*g[j];
|
xue@1
|
218 }
|
xue@1
|
219 else
|
xue@1
|
220 {
|
xue@1
|
221 tmpa[i2]+=tmpla[i-j-C]*h[j];
|
xue@1
|
222 tmpd[i2]+=tmpla[i-j-C]*g[j];
|
xue@1
|
223 }
|
xue@1
|
224 }
|
xue@1
|
225 }
|
xue@1
|
226 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
|
xue@1
|
227 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
|
xue@1
|
228 n*=2;
|
xue@1
|
229 if (n<N)
|
xue@1
|
230 {
|
xue@1
|
231 tmpla=tmpa;
|
xue@1
|
232 tmpa=tmpd;
|
xue@1
|
233 L++;
|
xue@1
|
234 C/=2;
|
xue@1
|
235 goto A;
|
xue@1
|
236 }
|
xue@1
|
237 }
|
xue@1
|
238 delete[] tmp;
|
xue@1
|
239 return n;
|
xue@1
|
240 }//dwtp
|
xue@1
|
241
|
Chris@5
|
242 /**
|
xue@1
|
243 function dwtp: in this implementation h and g can be different size. h[0] and g[0] are aligned at the
|
xue@1
|
244 ends of the filters, i.e. h[-Mh+1:0], g[-Mg+1:0].
|
xue@1
|
245
|
xue@1
|
246 In: in[Count]: waveform data
|
xue@1
|
247 h[-Mh+1:0], g[-Mg+1:0]: quadratic mirror filter pair
|
xue@1
|
248 N: maximal time resolution
|
xue@1
|
249 Out: out[N], the wavelet transform, arranged in interleaved format.
|
xue@1
|
250
|
xue@1
|
251 Returns maximal atom length (should equal N).
|
xue@1
|
252 */
|
xue@1
|
253 int dwtp(double* in, int Count, int N, double* h, int Mh, double* g, int Mg, double* out)
|
xue@1
|
254 {
|
xue@1
|
255 double* tmp=new double[Count];
|
xue@1
|
256 double *tmpa=tmp, *tmpla=in;
|
xue@1
|
257 int C=Count, L=0, n=1;
|
xue@1
|
258
|
xue@1
|
259 A:
|
xue@1
|
260 {
|
xue@1
|
261 double* tmpd=&tmpa[C/2];
|
xue@1
|
262 for (int i=0; i<C; i+=2)
|
xue@1
|
263 {
|
xue@1
|
264 int i2=i/2;
|
xue@1
|
265 tmpa[i2]=tmpla[i]*h[0];
|
xue@1
|
266 tmpd[i2]=tmpla[i]*g[0];
|
xue@1
|
267 for (int j=-1; j>-Mh; j--)
|
xue@1
|
268 {
|
xue@1
|
269 if (i-j<C)
|
xue@1
|
270 {
|
xue@1
|
271 tmpa[i2]+=tmpla[i-j]*h[j];
|
xue@1
|
272 }
|
xue@1
|
273 else
|
xue@1
|
274 {
|
xue@1
|
275 tmpa[i2]+=tmpla[i-j-C]*h[j];
|
xue@1
|
276 }
|
xue@1
|
277 }
|
xue@1
|
278 for (int j=-1; j>-Mg; j--)
|
xue@1
|
279 {
|
xue@1
|
280 if (i-j<C)
|
xue@1
|
281 {
|
xue@1
|
282 tmpd[i2]+=tmpla[i-j]*g[j];
|
xue@1
|
283 }
|
xue@1
|
284 else
|
xue@1
|
285 {
|
xue@1
|
286 tmpd[i2]+=tmpla[i-j-C]*g[j];
|
xue@1
|
287 }
|
xue@1
|
288 }
|
xue@1
|
289 }
|
xue@1
|
290 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
|
xue@1
|
291 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
|
xue@1
|
292 n*=2;
|
xue@1
|
293 if (n<N)
|
xue@1
|
294 {
|
xue@1
|
295 tmpla=tmpa;
|
xue@1
|
296 tmpa=tmpd;
|
xue@1
|
297 L++;
|
xue@1
|
298 C/=2;
|
xue@1
|
299 goto A;
|
xue@1
|
300 }
|
xue@1
|
301 }
|
xue@1
|
302 delete[] tmp;
|
xue@1
|
303 return n;
|
xue@1
|
304 }//dwtp
|
xue@1
|
305
|
Chris@5
|
306 /**
|
xue@1
|
307 function dwtp: in this implementation h and g can be arbitrarily located: h from $sh to $eh, g from
|
xue@1
|
308 $sg to $eg.
|
xue@1
|
309
|
xue@1
|
310 In: in[Count]: waveform data
|
xue@1
|
311 h[sh:eh-1], g[sg:eg-1]: quadratic mirror filter pair
|
xue@1
|
312 N: maximal time resolution
|
xue@1
|
313 Out: out[N], the wavelet transform, arranged in interleaved format.
|
xue@1
|
314
|
xue@1
|
315 Returns maximal atom length (should equal N).
|
xue@1
|
316 */
|
xue@1
|
317 int dwtp(double* in, int Count, int N, double* h, int sh, int eh, double* g, int sg, int eg, double* out)
|
xue@1
|
318 {
|
xue@1
|
319 double* tmp=new double[Count];
|
xue@1
|
320 double *tmpa=tmp, *tmpla=in;
|
xue@1
|
321 int C=Count, L=0, n=1;
|
xue@1
|
322
|
xue@1
|
323 A:
|
xue@1
|
324 {
|
xue@1
|
325 double* tmpd=&tmpa[C/2];
|
xue@1
|
326 for (int i=0; i<C; i+=2)
|
xue@1
|
327 {
|
xue@1
|
328 int i2=i/2;
|
xue@1
|
329 tmpa[i2]=0;//tmpla[i]*h[0];
|
xue@1
|
330 tmpd[i2]=0;//tmpla[i]*g[0];
|
xue@1
|
331 for (int j=sh; j<=eh; j++)
|
xue@1
|
332 {
|
xue@1
|
333 int ind=i-j;
|
xue@1
|
334 if (ind>=C) tmpa[i2]+=tmpla[ind-C]*h[j];
|
xue@1
|
335 else if (ind<0) tmpa[i2]+=tmpla[ind+C]*h[j];
|
xue@1
|
336 else tmpa[i2]+=tmpla[ind]*h[j];
|
xue@1
|
337 }
|
xue@1
|
338 for (int j=sg; j<=eg; j++)
|
xue@1
|
339 {
|
xue@1
|
340 int ind=i-j;
|
xue@1
|
341 if (ind>=C) tmpd[i2]+=tmpla[i-j-C]*g[j];
|
xue@1
|
342 else if (ind<0) tmpd[i2]+=tmpla[i-j+C]*g[j];
|
xue@1
|
343 else tmpd[i2]+=tmpla[i-j]*g[j];
|
xue@1
|
344 }
|
xue@1
|
345 }
|
xue@1
|
346 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
|
xue@1
|
347 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
|
xue@1
|
348 n*=2;
|
xue@1
|
349 if (n<N)
|
xue@1
|
350 {
|
xue@1
|
351 tmpla=tmpa;
|
xue@1
|
352 tmpa=tmpd;
|
xue@1
|
353 L++;
|
xue@1
|
354 C/=2;
|
xue@1
|
355 goto A;
|
xue@1
|
356 }
|
xue@1
|
357 }
|
xue@1
|
358 delete[] tmp;
|
xue@1
|
359 return n;
|
xue@1
|
360 }//dwtp
|
xue@1
|
361
|
Chris@5
|
362 /**
|
xue@1
|
363 function idwtp: periodic wavelet reconstruction by qmf
|
xue@1
|
364
|
xue@1
|
365 In: in[Count]: wavelet transform in interleaved format
|
xue@1
|
366 h[M], g[M]: quadratic mirror filter pair
|
xue@1
|
367 N: maximal time resolution
|
xue@1
|
368 Out: out[N], waveform data (detail level 0).
|
xue@1
|
369
|
xue@1
|
370 No return value.
|
xue@1
|
371 */
|
xue@1
|
372 void idwtp(double* in, int Count, int N, double* h, double* g, int M, double* out)
|
xue@1
|
373 {
|
xue@1
|
374 double* tmp=new double[Count];
|
xue@1
|
375 memcpy(out, in, sizeof(double)*Count);
|
xue@1
|
376 int n=N, C=Count/N, L=log2(N)-1;
|
xue@1
|
377 while (n>1)
|
xue@1
|
378 {
|
xue@1
|
379 memset(tmp, 0, sizeof(double)*C*2);
|
xue@1
|
380 //2k<<L being the approx, (2k+1)<<L being the detail
|
xue@1
|
381 for (int i=0; i<C; i++)
|
xue@1
|
382 {
|
xue@1
|
383 for (int j=0; j<M; j++)
|
xue@1
|
384 {
|
xue@1
|
385 if (i*2+j<C*2)
|
xue@1
|
386 {
|
xue@1
|
387 tmp[i*2+j]+=out[(2*i)<<L]*h[j]+out[(2*i+1)<<L]*g[j];
|
xue@1
|
388 }
|
xue@1
|
389 else
|
xue@1
|
390 {
|
xue@1
|
391 tmp[i*2+j-C*2]+=out[(2*i)<<L]*h[j]+out[(2*i+1)<<L]*g[j];
|
xue@1
|
392 }
|
xue@1
|
393 }
|
xue@1
|
394 }
|
xue@1
|
395 for (int i=0; i<C*2; i++) out[i<<L]=tmp[i];
|
xue@1
|
396 n/=2;
|
xue@1
|
397 C*=2;
|
xue@1
|
398 L--;
|
xue@1
|
399 }
|
xue@1
|
400 delete[] tmp;
|
xue@1
|
401 }//idwtp
|
xue@1
|
402
|
Chris@5
|
403 /**
|
xue@1
|
404 function idwtp: in which h and g can have different length.
|
xue@1
|
405
|
xue@1
|
406 In: in[Count]: wavelet transform in interleaved format
|
xue@1
|
407 h[Mh], g[Mg]: quadratic mirror filter pair
|
xue@1
|
408 N: maximal time resolution
|
xue@1
|
409 Out: out[N], waveform data (detail level 0).
|
xue@1
|
410
|
xue@1
|
411 No return value.
|
xue@1
|
412 */
|
xue@1
|
413 void idwtp(double* in, int Count, int N, double* h, int Mh, double* g, int Mg, double* out)
|
xue@1
|
414 {
|
xue@1
|
415 double* tmp=new double[Count];
|
xue@1
|
416 memcpy(out, in, sizeof(double)*Count);
|
xue@1
|
417 int n=N, C=Count/N, L=log2(N)-1;
|
xue@1
|
418 while (n>1)
|
xue@1
|
419 {
|
xue@1
|
420 memset(tmp, 0, sizeof(double)*C*2);
|
xue@1
|
421 //2k<<L being the approx, (2k+1)<<L being the detail
|
xue@1
|
422 for (int i=0; i<C; i++)
|
xue@1
|
423 {
|
xue@1
|
424 for (int j=0; j<Mh; j++)
|
xue@1
|
425 {
|
xue@1
|
426 int ind=i*2+j+(Mg-Mh)/2;
|
xue@1
|
427 if (ind>=C*2)
|
xue@1
|
428 {
|
xue@1
|
429 tmp[ind-C*2]+=out[(2*i)<<L]*h[j];
|
xue@1
|
430 }
|
xue@1
|
431 else if (ind<0)
|
xue@1
|
432 {
|
xue@1
|
433 tmp[ind+C*2]+=out[(2*i)<<L]*h[j];
|
xue@1
|
434 }
|
xue@1
|
435 else
|
xue@1
|
436 {
|
xue@1
|
437 tmp[ind]+=out[(2*i)<<L]*h[j];
|
xue@1
|
438 }
|
xue@1
|
439 }
|
xue@1
|
440 }
|
xue@1
|
441 for (int i=0; i<C; i++)
|
xue@1
|
442 {
|
xue@1
|
443 for (int j=0; j<Mg; j++)
|
xue@1
|
444 {
|
xue@1
|
445 int ind=i*2+j+(Mh-Mg)/2;
|
xue@1
|
446 if (ind>=C*2)
|
xue@1
|
447 {
|
xue@1
|
448 tmp[ind-C*2]+=out[(2*i+1)<<L]*g[j];
|
xue@1
|
449 }
|
xue@1
|
450 else if (ind<0)
|
xue@1
|
451 {
|
xue@1
|
452 tmp[ind+C*2]+=out[(2*i+1)<<L]*g[j];
|
xue@1
|
453 }
|
xue@1
|
454 else
|
xue@1
|
455 {
|
xue@1
|
456 tmp[ind]+=out[(2*i+1)<<L]*g[j];
|
xue@1
|
457 }
|
xue@1
|
458 }
|
xue@1
|
459 }
|
xue@1
|
460 for (int i=0; i<C*2; i++) out[i<<L]=tmp[i];
|
xue@1
|
461 n/=2;
|
xue@1
|
462 C*=2;
|
xue@1
|
463 L--;
|
xue@1
|
464 }
|
xue@1
|
465 delete[] tmp;
|
xue@1
|
466 }//idwtp
|
xue@1
|
467
|
Chris@5
|
468 /**
|
xue@1
|
469 function idwtp: in which h and g can be arbitrarily located: h from $sh to $eh, g from $sg to $eg
|
xue@1
|
470
|
xue@1
|
471 In: in[Count]: wavelet transform in interleaved format
|
xue@1
|
472 h[sh:eh-1], g[sg:eg-1]: quadratic mirror filter pair
|
xue@1
|
473 N: maximal time resolution
|
xue@1
|
474 Out: out[N], waveform data (detail level 0).
|
xue@1
|
475
|
xue@1
|
476 No return value.
|
xue@1
|
477 */
|
xue@1
|
478 void idwtp(double* in, int Count, int N, double* h, int sh, int eh, double* g, int sg, int eg, double* out)
|
xue@1
|
479 {
|
xue@1
|
480 double* tmp=new double[Count];
|
xue@1
|
481 memcpy(out, in, sizeof(double)*Count);
|
xue@1
|
482 int n=N, C=Count/N, L=log2(N)-1;
|
xue@1
|
483 while (n>1)
|
xue@1
|
484 {
|
xue@1
|
485 memset(tmp, 0, sizeof(double)*C*2);
|
xue@1
|
486 //2k<<L being the approx, (2k+1)<<L being the detail
|
xue@1
|
487 for (int i=0; i<C; i++)
|
xue@1
|
488 {
|
xue@1
|
489 for (int j=sh; j<=eh; j++)
|
xue@1
|
490 {
|
xue@1
|
491 int ind=i*2+j;
|
xue@1
|
492 if (ind>=C*2) tmp[ind-C*2]+=out[(2*i)<<L]*h[j];
|
xue@1
|
493 else if (ind<0) tmp[ind+C*2]+=out[(2*i)<<L]*h[j];
|
xue@1
|
494 else tmp[ind]+=out[(2*i)<<L]*h[j];
|
xue@1
|
495 }
|
xue@1
|
496 }
|
xue@1
|
497 for (int i=0; i<C; i++)
|
xue@1
|
498 {
|
xue@1
|
499 for (int j=sg; j<=eg; j++)
|
xue@1
|
500 {
|
xue@1
|
501 int ind=i*2+j;
|
xue@1
|
502 if (ind>=C*2) tmp[ind-C*2]+=out[(2*i+1)<<L]*g[j];
|
xue@1
|
503 else if (ind<0) tmp[ind+C*2]+=out[(2*i+1)<<L]*g[j];
|
xue@1
|
504 else tmp[ind]+=out[(2*i+1)<<L]*g[j];
|
xue@1
|
505 }
|
xue@1
|
506 }
|
xue@1
|
507 for (int i=0; i<C*2; i++) out[i<<L]=tmp[i];
|
xue@1
|
508 n/=2;
|
xue@1
|
509 C*=2;
|
xue@1
|
510 L--;
|
xue@1
|
511 }
|
xue@1
|
512 delete[] tmp;
|
xue@1
|
513 }//idwtp
|
xue@1
|
514
|
xue@1
|
515 //---------------------------------------------------------------------------
|
xue@1
|
516
|
xue@1
|
517 /*
|
xue@1
|
518 Spline biorthogonal wavelet routines.
|
xue@1
|
519
|
xue@1
|
520 Further reading: "Calculation of biorthogonal spline wavelets.pdf"
|
xue@1
|
521 */
|
xue@1
|
522
|
xue@1
|
523 //function Cmb: combination number C(n, k) (n>=k>=0)
|
xue@1
|
524 int Cmb(int n, int k)
|
xue@1
|
525 {
|
xue@1
|
526 if (k>n/2) k=n-k;
|
xue@1
|
527 int c=1;
|
xue@1
|
528 for (int i=1; i<=k; i++) c=c*(n+1-i)/i;
|
xue@1
|
529 return c;
|
xue@1
|
530 }
|
xue@1
|
531
|
Chris@5
|
532 /**
|
xue@1
|
533 function splinewl: computes spline biorthogonal wavelet filters. This version of splinewl calcualtes
|
xue@1
|
534 the positive-time half of h and hm coefficients only.
|
xue@1
|
535
|
xue@1
|
536 p1 and p2 must have the same parity. If p1 is even, p1 coefficients will be returned in h1; if p1 is
|
xue@1
|
537 odd, p1-1 coefficients will be returned in h1.
|
xue@1
|
538
|
xue@1
|
539 Actual length of h is p1+1, of hm is p1+2p2-1. only a half of each is kept.
|
xue@1
|
540 p even: h[0:p1/2] <- [p1/2:p1], hm[0:p1/2+p2-1] <- [p1/2+p2-1:p1+2p2-2]
|
xue@1
|
541 p odd: h[0:(p1-1)/2] <- [(p1+1)/2:p1], hm[0:(p1-3)/2+p2] <- [(p1-1)/2+p2:p1+2p2-2]
|
xue@1
|
542 i.e. h[0:hp1] <- [p1-hp1:p1], hm[0:hp1+p2-1] <- [p1-hp1-1+p2:p1+2p2-2]
|
xue@1
|
543
|
xue@1
|
544 In: p1, p2: specify vanishing moments of h and hm
|
xue@1
|
545 Out: h[] and hm[] as specified above.
|
xue@1
|
546
|
xue@1
|
547 No return value.
|
xue@1
|
548 */
|
xue@1
|
549 void splinewl(int p1, int p2, double* h, double* hm)
|
xue@1
|
550 {
|
xue@1
|
551 int hp1=p1/2, hp2=p2/2;
|
xue@1
|
552 int q=(p1+p2)/2;
|
xue@1
|
553 h[hp1]=sqrt(2.0)*pow(2, -p1);
|
xue@1
|
554 // h1[hp1]=1;
|
xue@1
|
555 for (int i=1, j=hp1-1; i<=hp1; i++, j--)
|
xue@1
|
556 {
|
xue@1
|
557 h[j]=h[j+1]*(p1+1-i)/i;
|
xue@1
|
558 }
|
xue@1
|
559
|
xue@1
|
560 double *_hh1=new double[p2+1], *_hh2=new double[2*q];
|
xue@1
|
561 double *hh1=&_hh1[p2-hp2], *hh2=&_hh2[q];
|
xue@1
|
562
|
xue@1
|
563 hh1[hp2]=sqrt(2.0)*pow(2, -p2);
|
xue@1
|
564 for (int i=1, j=hp2-1; i<=hp2; i++, j--)
|
xue@1
|
565 {
|
xue@1
|
566 hh1[j]=hh1[j+1]*(p2+1-i)/i;
|
xue@1
|
567 }
|
xue@1
|
568 if (p2%2) //p2 is odd
|
xue@1
|
569 {
|
xue@1
|
570 for (int i=0; i<=hp2; i++) hh1[-i-1]=hh1[i];
|
xue@1
|
571 }
|
xue@1
|
572 else //p2 even
|
xue@1
|
573 {
|
xue@1
|
574 for (int i=1; i<=hp2; i++) hh1[-i]=hh1[i];
|
xue@1
|
575 }
|
xue@1
|
576
|
xue@1
|
577 memset(_hh2, 0, sizeof(double)*2*q);
|
xue@1
|
578 for (int n=1-q; n<=q-1; n++)
|
xue@1
|
579 {
|
xue@1
|
580 int k=abs(n);
|
xue@1
|
581 int CC1=Cmb(q-1+k, k), CC2=Cmb(2*k, k-n); //CC=1.0*C(q-1+k, k)*C(2*k, k-n)
|
xue@1
|
582 for (; k<=q-1; k++)
|
xue@1
|
583 {
|
xue@1
|
584 hh2[n]=hh2[n]+1.0*CC1*CC2*pow(0.25, k);
|
xue@1
|
585 CC1=CC1*(q+k)/(k+1);
|
xue@1
|
586 CC2=CC2*(2*k+1)*(2*k+2)/((k+1-n)*(k+1+n));
|
xue@1
|
587 }
|
xue@1
|
588 hh2[n]*=pow(-1, n);
|
xue@1
|
589 }
|
xue@1
|
590
|
xue@1
|
591 //hh1[hp2-p2:hp2], hh2[1-q:q-1]
|
xue@1
|
592 //h2=conv(hh1, hh2), but the positive half only
|
xue@1
|
593 memset(hm, 0, sizeof(double)*(hp1+p2));
|
xue@1
|
594 for (int i=hp2-p2; i<=hp2; i++)
|
xue@1
|
595 for (int j=1-q; j<=q-1; j++)
|
xue@1
|
596 {
|
xue@1
|
597 if (i+j>=0 && i+j<hp1+p2)
|
xue@1
|
598 hm[i+j]+=hh1[i]*hh2[j];
|
xue@1
|
599 }
|
xue@1
|
600
|
xue@1
|
601 delete[] _hh1;
|
xue@1
|
602 delete[] _hh2;
|
xue@1
|
603 }//splinewl
|
xue@1
|
604
|
xue@1
|
605
|
Chris@5
|
606 /**
|
xue@1
|
607 function splinewl: calculates the analysis and reconstruction filter pairs of spline biorthogonal
|
xue@1
|
608 wavelet (h, g) and (hm, gm). h has the size p1+1, hm has the size p1+2p2-1.
|
xue@1
|
609
|
xue@1
|
610 If p1+1 is odd, then all four filters are symmetric; if not, then h and hm are symmetric, while g and
|
xue@1
|
611 gm are anti-symmetric.
|
xue@1
|
612
|
xue@1
|
613 The concatenation of filters h with hm (or g with gm) introduces a time shift of p1+p2-1, which is the
|
xue@1
|
614 return value multiplied by -1.
|
xue@1
|
615
|
xue@1
|
616 If normmode==1, the results are normalized so that ||h||^2=||g||^2=1;
|
xue@1
|
617 if normmode==2, the results are normalized so that ||hm||^2=||gm||^2=1,
|
xue@1
|
618 if normmode==3, the results are normalized so that ||h||^2==||g||^2=||hm||^2=||gm||^2.
|
xue@1
|
619
|
xue@1
|
620 If a *points* buffer is specified, the function returns the starting and ending
|
xue@1
|
621 positions (inclusive) of h, hm, g, and gm, in the order of (hs, he, hms, hme,
|
xue@1
|
622 gs, ge, gms, gme), as ps[0]~ps[7].
|
xue@1
|
623
|
xue@1
|
624 In: p1 and p2, specify vanishing moments of h and hm, respectively.
|
xue@1
|
625 normmode: mode for normalization
|
xue@1
|
626 Out: h[p1+1], g[p1+1], hm[p1+2p2-1], gm[p1+2p2-1], points[8] (optional)
|
xue@1
|
627
|
xue@1
|
628 Returns -p1-p2+1.
|
xue@1
|
629 */
|
xue@1
|
630 int splinewl(int p1, int p2, double* h, double* hm, double* g, double* gm, int normmode, int* points)
|
xue@1
|
631 {
|
xue@1
|
632 int lf=p1+1, lb=p1+2*p2-1;
|
xue@1
|
633 int hlf=lf/2, hlb=lb/2;
|
xue@1
|
634
|
xue@1
|
635 double *h1=&h[hlf], *h2=&hm[hlb];
|
xue@1
|
636 int hp1=p1/2, hp2=p2/2;
|
xue@1
|
637 int q=(p1+p2)/2;
|
xue@1
|
638 h1[hp1]=sqrt(2.0)*pow(2, -p1);
|
xue@1
|
639 // h1[hp1]=2*pow(2, -p1);
|
xue@1
|
640 for (int i=1, j=hp1-1; i<=hp1; i++, j--) h1[j]=h1[j+1]*(p1+1-i)/i;
|
xue@1
|
641
|
xue@1
|
642 double *_hh1=new double[p2+1+2*q];
|
xue@1
|
643 double *_hh2=&_hh1[p2+1];
|
xue@1
|
644 double *hh1=&_hh1[p2-hp2], *hh2=&_hh2[q];
|
xue@1
|
645 hh1[hp2]=sqrt(2.0)*pow(2, -p2);
|
xue@1
|
646 // hh1[hp2]=pow(2, -p2);
|
xue@1
|
647 for (int i=1, j=hp2-1; i<=hp2; i++, j--) hh1[j]=hh1[j+1]*(p2+1-i)/i;
|
xue@1
|
648 if (p2%2) for (int i=0; i<=hp2; i++) hh1[-i-1]=hh1[i];
|
xue@1
|
649 else for (int i=1; i<=hp2; i++) hh1[-i]=hh1[i];
|
xue@1
|
650 memset(_hh2, 0, sizeof(double)*2*q);
|
xue@1
|
651 for (int n=1-q; n<=q-1; n++)
|
xue@1
|
652 {
|
xue@1
|
653 int k=abs(n);
|
xue@1
|
654 int CC1=Cmb(q-1+k, k), CC2=Cmb(2*k, k-n); //CC=1.0*C(q-1+k, k)*C(2*k, k-n)
|
xue@1
|
655 for (int k=abs(n); k<=q-1; k++)
|
xue@1
|
656 {
|
xue@1
|
657 hh2[n]=hh2[n]+1.0*CC1*CC2*pow(0.25, k);
|
xue@1
|
658 CC1=CC1*(q+k)/(k+1);
|
xue@1
|
659 CC2=CC2*(2*k+1)*(2*k+2)/((k+1-n)*(k+1+n));
|
xue@1
|
660 }
|
xue@1
|
661 hh2[n]*=pow(-1, n);
|
xue@1
|
662 }
|
xue@1
|
663 //hh1[hp2-p2:hp2], hh2[1-q:q-1]
|
xue@1
|
664 //h2=conv(hh1, hh2), but the positive half only
|
xue@1
|
665 memset(h2, 0, sizeof(double)*(hp1+p2));
|
xue@1
|
666 for (int i=hp2-p2; i<=hp2; i++) for (int j=1-q; j<=q-1; j++)
|
xue@1
|
667 if (i+j>=0 && i+j<hp1+p2) h2[i+j]+=hh1[i]*hh2[j];
|
xue@1
|
668 delete[] _hh1;
|
xue@1
|
669
|
xue@1
|
670 int hs, he, hms, hme, gs, ge, gms, gme;
|
xue@1
|
671 if (lf%2)
|
xue@1
|
672 {
|
xue@1
|
673 hs=-hlf, he=hlf, hms=-hlb, hme=hlb;
|
xue@1
|
674 gs=-hlb+1, ge=hlb+1, gms=-hlf-1, gme=hlf-1;
|
xue@1
|
675 }
|
xue@1
|
676 else
|
xue@1
|
677 {
|
xue@1
|
678 hs=-hlf, he=hlf-1, hms=-hlb+1, hme=hlb;
|
xue@1
|
679 gs=-hlb, ge=hlb-1, gms=-hlf+1, gme=hlf;
|
xue@1
|
680 }
|
xue@1
|
681
|
xue@1
|
682 if (lf%2)
|
xue@1
|
683 {
|
xue@1
|
684 for (int i=1; i<=hlf; i++) h1[-i]=h1[i];
|
xue@1
|
685 for (int i=1; i<=hlb; i++) h2[-i]=h2[i];
|
xue@1
|
686 double* _g=&g[hlb-1], *_gm=&gm[hlf+1];
|
xue@1
|
687 for (int i=gs; i<=ge; i++) _g[i]=(i%2)?h2[1-i]:-h2[1-i];
|
xue@1
|
688 for (int i=gms; i<=gme; i++) _gm[i]=(i%2)?h1[-1-i]:-h1[-1-i];
|
xue@1
|
689 }
|
xue@1
|
690 else
|
xue@1
|
691 {
|
xue@1
|
692 for (int i=0; i<hlf; i++) h1[-i-1]=h1[i];
|
xue@1
|
693 for (int i=0; i<hlb; i++) h2[-i-1]=h2[i];
|
xue@1
|
694 h2=&h2[-1];
|
xue@1
|
695 double *_g=&g[hlb], *_gm=&gm[hlf-1];
|
xue@1
|
696 for (int i=gs; i<=ge; i++) _g[i]=(i%2)?-h2[-i]:h2[-i];
|
xue@1
|
697 for (int i=gms; i<=gme; i++) _gm[i]=(i%2)?-h1[-i]:h1[-i];
|
xue@1
|
698 }
|
xue@1
|
699
|
xue@1
|
700 if (normmode)
|
xue@1
|
701 {
|
xue@1
|
702 double sumh=0; for (int i=0; i<=he-hs; i++) sumh+=h[i]*h[i];
|
xue@1
|
703 double sumhm=0; for (int i=0; i<=hme-hms; i++) sumhm+=hm[i]*hm[i];
|
xue@1
|
704 if (normmode==1)
|
xue@1
|
705 {
|
xue@1
|
706 double rr=sqrt(sumh);
|
xue@1
|
707 for (int i=0; i<=hme-hms; i++) hm[i]*=rr;
|
xue@1
|
708 rr=1.0/rr;
|
xue@1
|
709 for (int i=0; i<=he-hs; i++) h[i]*=rr;
|
xue@1
|
710 rr=sqrt(sumhm);
|
xue@1
|
711 for (int i=0; i<=gme-gms; i++) gm[i]*=rr;
|
xue@1
|
712 rr=1.0/rr;
|
xue@1
|
713 for (int i=0; i<=ge-gs; i++) g[i]*=rr;
|
xue@1
|
714 }
|
xue@1
|
715 else if (normmode==2)
|
xue@1
|
716 {
|
xue@1
|
717 double rr=sqrt(sumh);
|
xue@1
|
718 for (int i=0; i<=ge-gs; i++) g[i]*=rr;
|
xue@1
|
719 rr=1.0/rr;
|
xue@1
|
720 for (int i=0; i<=gme-gms; i++) gm[i]*=rr;
|
xue@1
|
721 rr=sqrt(sumhm);
|
xue@1
|
722 for (int i=0; i<=he-hs; i++) h[i]*=rr;
|
xue@1
|
723 rr=1.0/rr;
|
xue@1
|
724 for (int i=0; i<=hme-hms; i++) hm[i]*=rr;
|
xue@1
|
725 }
|
xue@1
|
726 else if (normmode==3)
|
xue@1
|
727 {
|
xue@1
|
728 double rr=pow(sumh/sumhm, 0.25);
|
xue@1
|
729 for (int i=0; i<=hme-hms; i++) hm[i]*=rr;
|
xue@1
|
730 for (int i=0; i<=ge-gs; i++) g[i]*=rr;
|
xue@1
|
731 rr=1.0/rr;
|
xue@1
|
732 for (int i=0; i<=he-hs; i++) h[i]*=rr;
|
xue@1
|
733 for (int i=0; i<=gme-gms; i++) gm[i]*=rr;
|
xue@1
|
734 }
|
xue@1
|
735 }
|
xue@1
|
736
|
xue@1
|
737 if (points)
|
xue@1
|
738 {
|
xue@1
|
739 points[0]=hs, points[1]=he, points[2]=hms, points[3]=hme;
|
xue@1
|
740 points[4]=gs, points[5]=ge, points[6]=gms, points[7]=gme;
|
xue@1
|
741 }
|
xue@1
|
742 return -p1-p2+1;
|
xue@1
|
743 }//splinewl
|
xue@1
|
744
|
xue@1
|
745 //---------------------------------------------------------------------------
|
Chris@5
|
746 /**
|
xue@1
|
747 function wavpacqmf: calculate pseudo local cosine transforms using wavelet packet
|
xue@1
|
748
|
xue@1
|
749 In: data[Count], Count=fr*WID, waveform data
|
xue@1
|
750 WID: largest scale, equals 2^ORDER
|
xue@1
|
751 wid: smallest scale, euqals 2^order
|
xue@1
|
752 h[M], g[M]: quadratic mirror filter pair, fr>2*M
|
xue@1
|
753 Out: spec[0][fr][WID], spec[1][2*fr][WID/2], ..., spec[ORDER-order-1][FR][wid]
|
xue@1
|
754
|
xue@1
|
755 No return value.
|
xue@1
|
756 */
|
xue@1
|
757 void wavpacqmf(double*** spec, double* data, int Count, int WID, int wid, int M, double* h, double* g)
|
xue@1
|
758 {
|
xue@1
|
759 int fr=Count/WID, ORDER=log2(WID), order=log2(wid);
|
xue@1
|
760 double* _data1=new double[Count*2];
|
xue@1
|
761 double *data1=_data1, *data2=&_data1[Count];
|
xue@1
|
762 //the qmf always filters data1 and puts the results to data2
|
xue@1
|
763 memcpy(data1, data, sizeof(double)*Count);
|
xue@1
|
764 int l=0, C=fr*WID, FR=1;
|
xue@1
|
765 double *ldata, *ldataa, *ldatad;
|
xue@1
|
766 while (l<ORDER)
|
xue@1
|
767 {
|
xue@1
|
768 //qmf
|
xue@1
|
769 for (int f=0; f<FR; f++)
|
xue@1
|
770 {
|
xue@1
|
771 ldata=&data1[f*C];
|
xue@1
|
772 if (f%2==0)
|
xue@1
|
773 ldataa=&data2[f*C], ldatad=&data2[f*C+C/2];
|
xue@1
|
774 else
|
xue@1
|
775 ldatad=&data2[f*C], ldataa=&data2[f*C+C/2];
|
xue@1
|
776
|
xue@1
|
777 memset(&data2[f*C], 0, sizeof(double)*C);
|
xue@1
|
778 for (int i=0; i<C; i+=2)
|
xue@1
|
779 {
|
xue@1
|
780 int i2=i/2;
|
xue@1
|
781 ldataa[i2]=ldata[i]*h[0];
|
xue@1
|
782 ldatad[i2]=ldata[i]*g[0];
|
xue@1
|
783 for (int j=1; j<M; j++)
|
xue@1
|
784 {
|
xue@1
|
785 if (i+j<C)
|
xue@1
|
786 {
|
xue@1
|
787 ldataa[i2]+=ldata[i+j]*h[j];
|
xue@1
|
788 ldatad[i2]+=ldata[i+j]*g[j];
|
xue@1
|
789 }
|
xue@1
|
790 else
|
xue@1
|
791 {
|
xue@1
|
792 ldataa[i2]+=ldata[i+j-C]*h[j];
|
xue@1
|
793 ldatad[i2]+=ldata[i+j-C]*g[j];
|
xue@1
|
794 }
|
xue@1
|
795 }
|
xue@1
|
796 }
|
xue@1
|
797 }
|
xue@1
|
798 double *tmp=data2; data2=data1; data1=tmp;
|
xue@1
|
799 l++;
|
xue@1
|
800 C=(C>>1);
|
xue@1
|
801 FR=(FR<<1);
|
xue@1
|
802 if (l>=order)
|
xue@1
|
803 {
|
xue@1
|
804 for (int f=0; f<FR; f++)
|
xue@1
|
805 for(int i=0; i<C; i++)
|
xue@1
|
806 spec[ORDER-l][i][f]=data1[f*C+i];
|
xue@1
|
807 }
|
xue@1
|
808 }
|
xue@1
|
809
|
xue@1
|
810 delete[] _data1;
|
xue@1
|
811 }//wavpacqmf
|
xue@1
|
812
|
Chris@5
|
813 /**
|
xue@1
|
814 function iwavpacqmf: inverse transform of wavpacqmf
|
xue@1
|
815
|
xue@1
|
816 In: spec[Fr][Wid], Fr>M*2
|
xue@1
|
817 h[M], g[M], quadratic mirror filter pair
|
xue@1
|
818 Out: data[Fr*Wid]
|
xue@1
|
819
|
xue@1
|
820 No return value.
|
xue@1
|
821 */
|
xue@1
|
822 void iwavpacqmf(double* data, double** spec, int Fr, int Wid, int M, double* h, double* g)
|
xue@1
|
823 {
|
xue@1
|
824 int Count=Fr*Wid, Order=log2(Wid);
|
xue@1
|
825 double* _data1=new double[Count];
|
xue@1
|
826 double *data1, *data2, *ldata, *ldataa, *ldatad;
|
xue@1
|
827 if (Order%2) data1=_data1, data2=data;
|
xue@1
|
828 else data1=data, data2=_data1;
|
xue@1
|
829 //data pass to buffer
|
xue@1
|
830 for (int i=0, t=0; i<Wid; i++)
|
xue@1
|
831 for (int j=0; j<Fr; j++)
|
xue@1
|
832 data1[t++]=spec[j][i];
|
xue@1
|
833
|
xue@1
|
834 int l=Order;
|
xue@1
|
835 int C=Fr;
|
xue@1
|
836 int K=Wid/2;
|
xue@1
|
837 while (l>0)
|
xue@1
|
838 {
|
xue@1
|
839 memset(data2, 0, sizeof(double)*Count);
|
xue@1
|
840 for (int k=0; k<K; k++)
|
xue@1
|
841 {
|
xue@1
|
842 if (k%2==0) ldataa=&data1[2*k*C], ldatad=&data1[(2*k+1)*C];
|
xue@1
|
843 else ldatad=&data1[2*k*C], ldataa=&data1[(2*k+1)*C];
|
xue@1
|
844 ldata=&data2[2*k*C];
|
xue@1
|
845 //qmf
|
xue@1
|
846 for (int i=0; i<C; i++)
|
xue@1
|
847 {
|
xue@1
|
848 for (int j=0; j<M; j++)
|
xue@1
|
849 {
|
xue@1
|
850 if (i*2+j<C*2)
|
xue@1
|
851 {
|
xue@1
|
852 ldata[i*2+j]+=ldataa[i]*h[j]+ldatad[i]*g[j];
|
xue@1
|
853 }
|
xue@1
|
854 else
|
xue@1
|
855 {
|
xue@1
|
856 ldata[i*2+j-C*2]+=ldataa[i]*h[j]+ldatad[i]*g[j];
|
xue@1
|
857 }
|
xue@1
|
858 }
|
xue@1
|
859 }
|
xue@1
|
860 }
|
xue@1
|
861
|
xue@1
|
862 double *tmp=data2; data2=data1; data1=tmp;
|
xue@1
|
863 l--;
|
xue@1
|
864 C=(C<<1);
|
xue@1
|
865 K=(K>>1);
|
xue@1
|
866 }
|
xue@1
|
867 delete[] _data1;
|
xue@1
|
868 }//iwavpacqmf
|
xue@1
|
869
|
Chris@5
|
870 /**
|
xue@1
|
871 function wavpac: calculate pseudo local cosine transforms using wavelet packet,
|
xue@1
|
872
|
xue@1
|
873 In: data[Count], Count=fr*WID, waveform data
|
xue@1
|
874 WID: largest scale, equals 2^ORDER
|
xue@1
|
875 wid: smallest scale, euqals 2^order
|
xue@1
|
876 h[hs:he-1], g[gs:ge-1]: filter pair
|
xue@1
|
877 Out: spec[0][fr][WID], spec[1][2*fr][WID/2], ..., spec[ORDER-order-1][FR][wid]
|
xue@1
|
878
|
xue@1
|
879 No return value.
|
xue@1
|
880 */
|
xue@1
|
881 void wavpac(double*** spec, double* data, int Count, int WID, int wid, double* h, int hs, int he, double* g, int gs, int ge)
|
xue@1
|
882 {
|
xue@1
|
883 int fr=Count/WID, ORDER=log2(WID), order=log2(wid);
|
xue@1
|
884 double* _data1=new double[Count*2];
|
xue@1
|
885 double *data1=_data1, *data2=&_data1[Count];
|
xue@1
|
886 //the qmf always filters data1 and puts the results to data2
|
xue@1
|
887 memcpy(data1, data, sizeof(double)*Count);
|
xue@1
|
888 int l=0, C=fr*WID, FR=1;
|
xue@1
|
889 double *ldata, *ldataa, *ldatad;
|
xue@1
|
890 while (l<ORDER)
|
xue@1
|
891 {
|
xue@1
|
892 //qmf
|
xue@1
|
893 for (int f=0; f<FR; f++)
|
xue@1
|
894 {
|
xue@1
|
895 ldata=&data1[f*C];
|
xue@1
|
896 if (f%2==0)
|
xue@1
|
897 ldataa=&data2[f*C], ldatad=&data2[f*C+C/2];
|
xue@1
|
898 else
|
xue@1
|
899 ldatad=&data2[f*C], ldataa=&data2[f*C+C/2];
|
xue@1
|
900
|
xue@1
|
901 memset(&data2[f*C], 0, sizeof(double)*C);
|
xue@1
|
902 for (int i=0; i<C; i+=2)
|
xue@1
|
903 {
|
xue@1
|
904 int i2=i/2;
|
xue@1
|
905 ldataa[i2]=0;//ldata[i]*h[0];
|
xue@1
|
906 ldatad[i2]=0;//ldata[i]*g[0];
|
xue@1
|
907 for (int j=hs; j<=he; j++)
|
xue@1
|
908 {
|
xue@1
|
909 int ind=i-j;
|
xue@1
|
910 if (ind>=C)
|
xue@1
|
911 {
|
xue@1
|
912 ldataa[i2]+=ldata[ind-C]*h[j];
|
xue@1
|
913 }
|
xue@1
|
914 else if (ind<0)
|
xue@1
|
915 {
|
xue@1
|
916 ldataa[i2]+=ldata[ind+C]*h[j];
|
xue@1
|
917 }
|
xue@1
|
918 else
|
xue@1
|
919 {
|
xue@1
|
920 ldataa[i2]+=ldata[ind]*h[j];
|
xue@1
|
921 }
|
xue@1
|
922 }
|
xue@1
|
923 for (int j=gs; j<=ge; j++)
|
xue@1
|
924 {
|
xue@1
|
925 int ind=i-j;
|
xue@1
|
926 if (ind>=C)
|
xue@1
|
927 {
|
xue@1
|
928 ldatad[i2]+=ldata[ind-C]*g[j];
|
xue@1
|
929 }
|
xue@1
|
930 else if (ind<0)
|
xue@1
|
931 {
|
xue@1
|
932 ldatad[i2]+=ldata[ind+C]*g[j];
|
xue@1
|
933 }
|
xue@1
|
934 else
|
xue@1
|
935 {
|
xue@1
|
936 ldatad[i2]+=ldata[ind]*g[j];
|
xue@1
|
937 }
|
xue@1
|
938 }
|
xue@1
|
939 }
|
xue@1
|
940 }
|
xue@1
|
941 double *tmp=data2; data2=data1; data1=tmp;
|
xue@1
|
942 l++;
|
xue@1
|
943 C=(C>>1);
|
xue@1
|
944 FR=(FR<<1);
|
xue@1
|
945 if (l>=order)
|
xue@1
|
946 {
|
xue@1
|
947 for (int f=0; f<FR; f++)
|
xue@1
|
948 for(int i=0; i<C; i++)
|
xue@1
|
949 spec[ORDER-l][i][f]=data1[f*C+i];
|
xue@1
|
950 }
|
xue@1
|
951 }
|
xue@1
|
952
|
xue@1
|
953 delete[] _data1;
|
xue@1
|
954 }//wavpac
|
xue@1
|
955
|
Chris@5
|
956 /**
|
xue@1
|
957 function iwavpac: inverse transform of wavpac
|
xue@1
|
958
|
xue@1
|
959 In: spec[Fr][Wid]
|
xue@1
|
960 h[hs:he-1], g[gs:ge-1], reconstruction filter pair
|
xue@1
|
961 Out: data[Fr*Wid]
|
xue@1
|
962
|
xue@1
|
963 No return value.
|
xue@1
|
964 */
|
xue@1
|
965 void iwavpac(double* data, double** spec, int Fr, int Wid, double* h, int hs, int he, double* g, int gs, int ge)
|
xue@1
|
966 {
|
xue@1
|
967 int Count=Fr*Wid, Order=log2(Wid);
|
xue@1
|
968 double* _data1=new double[Count];
|
xue@1
|
969 double *data1, *data2, *ldata, *ldataa, *ldatad;
|
xue@1
|
970 if (Order%2) data1=_data1, data2=data;
|
xue@1
|
971 else data1=data, data2=_data1;
|
xue@1
|
972 //data pass to buffer
|
xue@1
|
973 for (int i=0, t=0; i<Wid; i++)
|
xue@1
|
974 for (int j=0; j<Fr; j++)
|
xue@1
|
975 data1[t++]=spec[j][i];
|
xue@1
|
976
|
xue@1
|
977 int l=Order;
|
xue@1
|
978 int C=Fr;
|
xue@1
|
979 int K=Wid/2;
|
xue@1
|
980 while (l>0)
|
xue@1
|
981 {
|
xue@1
|
982 memset(data2, 0, sizeof(double)*Count);
|
xue@1
|
983 for (int k=0; k<K; k++)
|
xue@1
|
984 {
|
xue@1
|
985 if (k%2==0) ldataa=&data1[2*k*C], ldatad=&data1[(2*k+1)*C];
|
xue@1
|
986 else ldatad=&data1[2*k*C], ldataa=&data1[(2*k+1)*C];
|
xue@1
|
987 ldata=&data2[2*k*C];
|
xue@1
|
988 //qmf
|
xue@1
|
989 for (int i=0; i<C; i++)
|
xue@1
|
990 {
|
xue@1
|
991 for (int j=hs; j<=he; j++)
|
xue@1
|
992 {
|
xue@1
|
993 int ind=i*2+j;
|
xue@1
|
994 if (ind>=C*2)
|
xue@1
|
995 {
|
xue@1
|
996 ldata[ind-C*2]+=ldataa[i]*h[j];
|
xue@1
|
997 }
|
xue@1
|
998 else if (ind<0)
|
xue@1
|
999 {
|
xue@1
|
1000 ldata[ind+C*2]+=ldataa[i]*h[j];
|
xue@1
|
1001 }
|
xue@1
|
1002 else
|
xue@1
|
1003 {
|
xue@1
|
1004 ldata[ind]+=ldataa[i]*h[j];
|
xue@1
|
1005 }
|
xue@1
|
1006 }
|
xue@1
|
1007 for (int j=gs; j<=ge; j++)
|
xue@1
|
1008 {
|
xue@1
|
1009 int ind=i*2+j;
|
xue@1
|
1010 if (ind>=C*2)
|
xue@1
|
1011 {
|
xue@1
|
1012 ldata[ind-C*2]+=ldatad[i]*g[j];
|
xue@1
|
1013 }
|
xue@1
|
1014 else if (ind<0)
|
xue@1
|
1015 {
|
xue@1
|
1016 ldata[ind+C*2]+=ldatad[i]*g[j];
|
xue@1
|
1017 }
|
xue@1
|
1018 else
|
xue@1
|
1019 {
|
xue@1
|
1020 ldata[ind]+=ldatad[i]*g[j];
|
xue@1
|
1021 }
|
xue@1
|
1022 }
|
xue@1
|
1023 }
|
xue@1
|
1024 }
|
xue@1
|
1025
|
xue@1
|
1026 double *tmp=data2; data2=data1; data1=tmp;
|
xue@1
|
1027 l--;
|
xue@1
|
1028 C=(C<<1);
|
xue@1
|
1029 K=(K>>1);
|
xue@1
|
1030 }
|
xue@1
|
1031 delete[] _data1;
|
xue@1
|
1032 }//iwavpac
|