OSDN Git Service

ff152d041d4ed079ec677004cf5bc494338af316
[mikumikustudio/MikuMikuStudio.git] / src / com / jmex / audio / filter / BandpassFilter.java
1 /*
2  * Copyright (c) 2003-2009 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 
17  *   may be used to endorse or promote products derived from this software 
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 package com.jmex.audio.filter;
34
35 import java.nio.ByteBuffer;
36 import java.nio.ByteOrder;
37 import java.nio.ShortBuffer;
38
39 /**
40  * @author Arman Ozcelik
41  * @version $Id: BandpassFilter.java,v 1.1 2007/03/06 15:29:12 nca Exp $
42  */
43 public class BandpassFilter extends Filter {
44
45     private float qParam = 1.6f;
46
47     private double alpha[];
48     private double beta[];
49     private double gamma[];
50
51     public BandpassFilter(int[] frequencies) {
52         super(frequencies);
53     }
54
55     public void init(int rate) {
56         super.initalize(rate);
57         alpha = new double[frequencies.length];
58         beta = new double[frequencies.length];
59         gamma = new double[frequencies.length];
60         resetABC(qParam);
61     }
62
63     public void resetABC(double q) {
64         for (int a = 0; a < theta.length; a++) {
65             double tan = Math.tan(theta[a] / (2.0 * q));
66             beta[a] = 0.5 * ((1.0 - tan) / (1.0 + tan));
67             alpha[a] = (0.5 - beta[a]) / 2.0;
68             gamma[a] = (0.5 + beta[a]) * Math.cos(theta[a]);
69         }
70     }
71
72     public byte[] filter(byte[] input) {
73
74         ByteOrder order = ByteOrder.nativeOrder();
75         ShortBuffer sbuf = ByteBuffer.wrap(input).order(order).asShortBuffer();
76         short[] sinput = new short[input.length / 2];
77         for (int i = 0; i < sinput.length; i++) {
78             sinput[i] = (sbuf.get(i));
79         }
80         if (output == null) {
81             output = new double[sinput.length];
82         }
83         for (int a = 0; a < output.length; a++) {
84             output[a] = sinput[a] * gainFactor;
85         }
86
87         for (int a = 0; a < frequencies.length; a++) {
88             passBand(a, sinput);
89         }
90         for (int a = 0; a < output.length; a++) {
91             sinput[a] = (short) Math.min(Short.MAX_VALUE, Math.max(output[a],
92                     Short.MIN_VALUE));
93         }
94         return toByte(sinput, true);
95
96     }
97
98     /**
99      * @param a
100      * @param buffer
101      */
102     private void passBand(int passNumber, short[] sinput) {
103         double[] inputArray = new double[3];
104         double[] outputArray = new double[3];
105         int i = 0, j = 0, k = 0;
106         for (int a = 0; a < sinput.length; a++) {
107             inputArray[i] = sinput[a];
108             j = i - 2;
109             if (j < 0)
110                 j += 3;
111             k = i - 1;
112             if (k < 0)
113                 k += 3;
114             outputArray[i] = 2 * (alpha[passNumber]
115                     * (inputArray[i] - inputArray[j]) + gamma[passNumber]
116                     * outputArray[k] - beta[passNumber] * outputArray[j]);
117
118             output[a] += adjust[passNumber] * outputArray[i];
119             i = (i + 1) % 3;
120         }
121
122     }
123
124     public byte[] toByte(short[] array, boolean flag) {
125         byte[] outBuf = new byte[array.length * 2];
126         for (int a = 0, b = 0; a < array.length; a++, b += 2) {
127             byte[] ret = toByte(array[a], flag);
128             outBuf[b] = ret[0];
129             outBuf[b + 1] = ret[1];
130         }
131         return outBuf;
132     }
133
134     public static final byte[] toByte(short value, boolean flag) {
135         byte temp[] = new byte[2];
136         for (byte b = 0; b <= 1; b++)
137             temp[b] = (byte) (value >>> (1 - b) * 8);
138
139         if (flag)
140             temp = reverse_order(temp, 2);
141
142         return temp;
143
144     }
145
146     public static final byte[] toByte(short s) {
147         return toByte(s, false);
148     }
149
150     private static final byte[] reverse_order(byte array[], int i) {
151         byte temp[] = new byte[i];
152         for (byte b = 0; b <= i - 1; b++)
153             temp[b] = array[i - 1 - b];
154
155         return temp;
156     }
157
158 }