annotate wavelet.cpp @ 13:de3961f74f30 tip

Add Linux/gcc Makefile; build fix
author Chris Cannam
date Mon, 05 Sep 2011 15:22:35 +0100
parents 977f541d6683
children
rev   line source
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