plectrum

Plectrum: instrument tuner for Android
Log | Files | Refs | README | LICENSE

Daubechies4Wavelet.java (3564B)


      1 package be.tarsos.dsp.wavelet.lift;
      2 
      3 /**
      4 * 
      5 * @author Ian Kaplan
      6 */
      7 public class Daubechies4Wavelet extends LiftingSchemeBaseWavelet {
      8 	final static float sqrt3 = (float) Math.sqrt(3);
      9 	final static float sqrt2 = (float) Math.sqrt(2);
     10 
     11 	protected void normalize(float[] S, int N, int direction) {
     12 		int half = N >> 1;
     13 
     14 		for (int n = 0; n < half; n++) {
     15 			if (direction == forward) {
     16 				S[n] = ((sqrt3 - 1.0f) / sqrt2) * S[n];
     17 				S[n + half] = ((sqrt3 + 1.0f) / sqrt2) * S[n + half];
     18 			} else if (direction == inverse) {
     19 				S[n] = ((sqrt3 + 1.0f) / sqrt2) * S[n];
     20 				S[n + half] = ((sqrt3 - 1.0f) / sqrt2) * S[n + half];
     21 			} else {
     22 				System.out
     23 						.println("Daubechies4Wavelet::normalize: bad direction value");
     24 				break;
     25 			}
     26 		}
     27 	} // normalize
     28 
     29 	protected void predict(float[] S, int N, int direction) {
     30 		int half = N >> 1;
     31 
     32 		if (direction == forward) {
     33 			S[half] = S[half] - (sqrt3 / 4.0f) * S[0]
     34 					- (((sqrt3 - 2) / 4.0f) * S[half - 1]);
     35 		} else if (direction == inverse) {
     36 			S[half] = S[half] + (sqrt3 / 4.0f) * S[0]
     37 					+ (((sqrt3 - 2) / 4.0f) * S[half - 1]);
     38 		} else {
     39 			System.out
     40 					.println("Daubechies4Wavelet::predict: bad direction value");
     41 		}
     42 
     43 		// predict, forward
     44 
     45 		for (int n = 1; n < half; n++) {
     46 			if (direction == forward) {
     47 				S[half + n] = S[half + n] - (sqrt3 / 4.0f) * S[n]
     48 						- (((sqrt3 - 2) / 4.0f) * S[n - 1]);
     49 			} else if (direction == inverse) {
     50 				S[half + n] = S[half + n] + (sqrt3 / 4.0f) * S[n]
     51 						+ (((sqrt3 - 2) / 4.0f) * S[n - 1]);
     52 			} else {
     53 				break;
     54 			}
     55 		}
     56 
     57 	} // predict
     58 
     59 	protected void updateOne(float[] S, int N, int direction) {
     60 		int half = N >> 1;
     61 
     62 		for (int n = 0; n < half; n++) {
     63 			float updateVal = sqrt3 * S[half + n];
     64 
     65 			if (direction == forward) {
     66 				S[n] = S[n] + updateVal;
     67 			} else if (direction == inverse) {
     68 				S[n] = S[n] - updateVal;
     69 			} else {
     70 				System.out
     71 						.println("Daubechies4Wavelet::updateOne: bad direction value");
     72 				break;
     73 			}
     74 		}
     75 	} // updateOne
     76 
     77 	protected void update(float[] S, int N, int direction) {
     78 		int half = N >> 1;
     79 
     80 		for (int n = 0; n < half - 1; n++) {
     81 			if (direction == forward) {
     82 				S[n] = S[n] - S[half + n + 1];
     83 			} else if (direction == inverse) {
     84 				S[n] = S[n] + S[half + n + 1];
     85 			} else {
     86 				System.out
     87 						.println("Daubechies4Wavelet::update: bad direction value");
     88 				break;
     89 			}
     90 		}
     91 
     92 		if (direction == forward) {
     93 			S[half - 1] = S[half - 1] - S[half];
     94 		} else if (direction == inverse) {
     95 			S[half - 1] = S[half - 1] + S[half];
     96 		}
     97 	} // update
     98 
     99 	public void forwardTrans(float[] vec) {
    100 		final int N = vec.length;
    101 
    102 		for (int n = N; n > 1; n = n >> 1) {
    103 			split(vec, n);
    104 			updateOne(vec, n, forward); // update 1
    105 			predict(vec, n, forward);
    106 			update(vec, n, forward); // update 2
    107 			normalize(vec, n, forward);
    108 		}
    109 	} // forwardTrans
    110 
    111 	/**
    112 	 * <p>
    113 	 * Default two step Lifting Scheme inverse wavelet transform
    114 	 * </p>
    115 	 * 
    116 	 * <p>
    117 	 * inverseTrans is passed the result of an ordered wavelet transform,
    118 	 * consisting of an average and a set of wavelet coefficients. The inverse
    119 	 * transform is calculated in-place and the result is returned in the
    120 	 * argument array.
    121 	 * </p>
    122 	 */
    123 	public void inverseTrans(float[] vec) {
    124 		final int N = vec.length;
    125 
    126 		for (int n = 2; n <= N; n = n << 1) {
    127 			normalize(vec, n, inverse);
    128 			update(vec, n, inverse);
    129 			predict(vec, n, inverse);
    130 			updateOne(vec, n, inverse);
    131 			merge(vec, n);
    132 		}
    133 	} // inverseTrans
    134 }