diff --git a/app/Locabean/AndroidManifest.xml b/app/Locabean/AndroidManifest.xml index 84ea4e4..d135b9d 100644 --- a/app/Locabean/AndroidManifest.xml +++ b/app/Locabean/AndroidManifest.xml @@ -5,7 +5,7 @@ android:versionName="1.0" > diff --git a/app/Locabean/libs/musicg-1.4.2.0.jar b/app/Locabean/libs/musicg-1.4.2.0.jar new file mode 100644 index 0000000..c58c0af Binary files /dev/null and b/app/Locabean/libs/musicg-1.4.2.0.jar differ diff --git a/app/Locabean/src/com/locaudio/locabean/WaveWriter.java b/app/Locabean/src/com/locaudio/io/WaveWriter.java similarity index 89% rename from app/Locabean/src/com/locaudio/locabean/WaveWriter.java rename to app/Locabean/src/com/locaudio/io/WaveWriter.java index 03391cb..dadd8a3 100644 --- a/app/Locabean/src/com/locaudio/locabean/WaveWriter.java +++ b/app/Locabean/src/com/locaudio/io/WaveWriter.java @@ -1,4 +1,4 @@ -package com.locaudio.locabean; +package com.locaudio.io; import java.io.File; import java.io.FileInputStream; @@ -8,6 +8,7 @@ import android.media.AudioFormat; import android.media.AudioRecord; +import android.media.MediaRecorder; import android.os.Environment; public class WaveWriter { @@ -26,7 +27,7 @@ public class WaveWriter { protected static final int BUFFER_SIZE = AudioRecord.getMinBufferSize( RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); - protected static void writeWaveFileHeader(FileOutputStream out, + public static void writeWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate, int bitsPerSample) throws IOException { @@ -80,7 +81,7 @@ protected static void writeWaveFileHeader(FileOutputStream out, out.write(header, 0, 44); } - protected static void copyWaveFile(String inFilename, String outFilename) { + public static void copyWaveFile(String inFilename, String outFilename) { FileInputStream in = null; FileOutputStream out = null; long totalAudioLen = 0; @@ -115,7 +116,7 @@ protected static void copyWaveFile(String inFilename, String outFilename) { } } - protected static String getFilename() { + public static String getFilename() { String filepath = Environment.getExternalStorageDirectory().getPath(); File file = new File(filepath, AUDIO_RECORDER_FOLDER); @@ -126,7 +127,7 @@ protected static String getFilename() { return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_FILENAME + AUDIO_RECORDER_FILE_EXT_WAV); } - protected static String getTempFilename() { + public static String getTempFilename() { String filepath = Environment.getExternalStorageDirectory().getPath(); File file = new File(filepath, AUDIO_RECORDER_FOLDER); @@ -142,13 +143,13 @@ protected static String getTempFilename() { return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE); } - protected static void deleteTempFile() { + public static void deleteTempFile() { File file = new File(getTempFilename()); file.delete(); } - protected static void writeAudioDataToFile(AudioRecord recorder, + public static void writeAudioDataToFile(AudioRecord recorder, boolean isRecording) { byte data[] = new byte[WaveWriter.BUFFER_SIZE]; String filename = getTempFilename(); @@ -183,4 +184,10 @@ protected static void writeAudioDataToFile(AudioRecord recorder, } } } + + public static AudioRecord getAudioRecord() { + return new AudioRecord(MediaRecorder.AudioSource.MIC, + RECORDER_SAMPLERATE, RECORDER_CHANNELS, + RECORDER_AUDIO_ENCODING, BUFFER_SIZE); + } } diff --git a/app/Locabean/src/com/locaudio/locabean/NodeActivity.java b/app/Locabean/src/com/locaudio/locabean/NodeActivity.java index 2cb6c42..946e05c 100644 --- a/app/Locabean/src/com/locaudio/locabean/NodeActivity.java +++ b/app/Locabean/src/com/locaudio/locabean/NodeActivity.java @@ -4,7 +4,6 @@ import android.app.Activity; import android.media.AudioRecord; -import android.media.MediaRecorder; import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.view.View; @@ -13,6 +12,8 @@ import com.musicg.wave.Wave; +import com.locaudio.io.WaveWriter; + public class NodeActivity extends Activity { private AudioRecord recorder = null; @@ -46,9 +47,7 @@ private void enableButtons(boolean isRecording) { } private void startRecording() { - recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, - WaveWriter.RECORDER_SAMPLERATE, WaveWriter.RECORDER_CHANNELS, - WaveWriter.RECORDER_AUDIO_ENCODING, WaveWriter.BUFFER_SIZE); + recorder = WaveWriter.getAudioRecord(); int i = recorder.getState(); if (i == 1) diff --git a/app/Locabean/src/com/locaudio/net/Requests.java b/app/Locabean/src/com/locaudio/net/Requests.java new file mode 100644 index 0000000..91b3001 --- /dev/null +++ b/app/Locabean/src/com/locaudio/net/Requests.java @@ -0,0 +1,83 @@ +package com.locaudio.net; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.CharBuffer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.json.JSONException; +import org.json.JSONObject; + +public class Requests { + + private String ipAddress = null; + private int port = 80; + private String url = null; + private static final int CHAR_BUFFER_SIZE = 256; + + public Requests() { + this.ipAddress = "localhost"; + this.port = 8000; + this.url = this.ipAddress + ":" + this.port; + } + + public Requests(String ipAddress, int port) { + this.ipAddress = ipAddress; + this.port = port; + this.url = this.ipAddress + ":" + this.port; + } + + public JSONObject post(Map paramMap) + throws ClientProtocolException, IOException, JSONException { + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost(this.url); + + // Request parameters and other properties. + List params = new ArrayList(); + + Iterator> it = paramMap.entrySet().iterator(); + Entry pair = null; + + while (it.hasNext()) { + pair = (Entry) it.next(); + params.add(new BasicNameValuePair(pair.getKey(), pair.getValue())); + } + + httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); + + // Execute and get the response. + HttpResponse response = httpclient.execute(httppost); + HttpEntity entity = response.getEntity(); + + if (entity != null) { + InputStreamReader reader = new InputStreamReader( + entity.getContent()); + try { + CharBuffer target = CharBuffer.allocate(CHAR_BUFFER_SIZE); + reader.read(target); + return new JSONObject(target.toString()); + } finally { + reader.close(); + } + } else { + return new JSONObject(); + } + } + + public JSONObject get(String... params) { + return new JSONObject(); + } +} diff --git a/app/Locabean/src/com/musicg/api/ClapApi.java b/app/Locabean/src/com/musicg/api/ClapApi.java deleted file mode 100644 index 0937cda..0000000 --- a/app/Locabean/src/com/musicg/api/ClapApi.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.api; - -import com.musicg.wave.WaveHeader; - -/** - * Api for detecting clap - * - * @author Jacquet Wong - * - */ -public class ClapApi extends DetectionApi{ - - public ClapApi(WaveHeader waveHeader) { - super(waveHeader); - } - - protected void init(){ - // settings for detecting a clap - minFrequency = 1000.0f; - maxFrequency = Double.MAX_VALUE; - - // get the decay part of a clap - minIntensity = 10000.0f; - maxIntensity = 100000.0f; - - minStandardDeviation = 0.0f; - maxStandardDeviation = 0.05f; - - highPass = 100; - lowPass = 10000; - - minNumZeroCross = 100; - maxNumZeroCross = 500; - - numRobust = 4; - } - - public boolean isClap(byte[] audioBytes){ - return isSpecificSound(audioBytes); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/api/DetectionApi.java b/app/Locabean/src/com/musicg/api/DetectionApi.java deleted file mode 100644 index 723eb81..0000000 --- a/app/Locabean/src/com/musicg/api/DetectionApi.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.api; - -import com.musicg.math.rank.ArrayRankDouble; -import com.musicg.math.statistics.StandardDeviation; -import com.musicg.math.statistics.ZeroCrossingRate; -import com.musicg.wave.Wave; -import com.musicg.wave.WaveHeader; -import com.musicg.wave.extension.Spectrogram; - -/** - * Api for detecting different sounds - * - * @author Jacquet Wong - * - */ -public class DetectionApi { - - protected WaveHeader waveHeader; - protected int fftSampleSize; - protected int numFrequencyUnit; - protected double unitFrequency; - protected double minFrequency, maxFrequency; - protected double minIntensity, maxIntensity; - protected double minStandardDeviation, maxStandardDeviation; - protected int highPass, lowPass; - protected int minNumZeroCross, maxNumZeroCross; - protected int lowerBoundary, upperBoundary; - protected int numRobust; - - /** - * Constructor, support mono Wav only, 4096 sample byte size for 44100Hz - * 16bit mono wav - * - * @param sampleRate - * Sample rate of the input audio byte - * @param bitsPerSample - * Bit size of a sample of the input audio byte - */ - public DetectionApi(WaveHeader waveHeader) { - if (waveHeader.getChannels() == 1) { - this.waveHeader = waveHeader; - init(); - } else { - System.err.println("DetectionAPI supports mono Wav only"); - } - } - - /** - * Initiate the settings for specific sound detection - */ - protected void init(){ - // do nothing, needed to be overrided - } - - /** - * Determine the audio bytes contains a specific sound or not - * - * @param audioBytes - * input audio byte - * @return - */ - public boolean isSpecificSound(byte[] audioBytes) { - - int bytesPerSample = waveHeader.getBitsPerSample() / 8; - int numSamples = audioBytes.length / bytesPerSample; - - // numSamples required to be a power of 2 - if (numSamples > 0 && Integer.bitCount(numSamples) == 1) { - fftSampleSize = numSamples; - numFrequencyUnit = fftSampleSize / 2; - - // frequency could be caught within the half of nSamples according to Nyquist theory - unitFrequency = (double) waveHeader.getSampleRate() / 2 / numFrequencyUnit; - - // set boundary - lowerBoundary = (int) (highPass / unitFrequency); - upperBoundary = (int) (lowPass / unitFrequency); - // end set boundary - - Wave wave = new Wave(waveHeader, audioBytes); // audio bytes of this frame - short[] amplitudes = wave.getSampleAmplitudes(); - - // spectrum for the clip - Spectrogram spectrogram = wave.getSpectrogram(fftSampleSize, 0); - - double[][] spectrogramData = spectrogram.getAbsoluteSpectrogramData(); - - // since fftSampleSize==numSamples, there're only one spectrum which is thisFrameSpectrogramData[0] - double[] spectrum = spectrogramData[0]; - - int frequencyUnitRange = upperBoundary - lowerBoundary + 1; - double[] rangedSpectrum = new double[frequencyUnitRange]; - System.arraycopy(spectrum, lowerBoundary, rangedSpectrum, 0, rangedSpectrum.length); - - if (frequencyUnitRange <= spectrum.length) { - - if (isPassedIntensity(spectrum)){ - if (isPassedStandardDeviation(spectrogramData)){ - if (isPassedZeroCrossingRate(amplitudes)){ - if (isPassedFrequency(rangedSpectrum)){ - return true; - } - } - } - } - - /* - // run all checking for debug - boolean isPassedChecking = true; - // rule 1: check the intensity of this frame - isPassedChecking &= isPassedIntensity(spectrum); - // rule 2: check the frequency of this frame - isPassedChecking &= isPassedFrequency(rangedSpectrum); - // rule 3: check the zero crossing rate of this frame - isPassedChecking &= isPassedZeroCrossingRate(amplitudes); - // rule 4: check the standard deviation of this frame with reference of previous frames - isPassedChecking &= isPassedStandardDeviation(spectrogramData); - System.out.println("Result: " + isPassedChecking + "\n"); - return isPassedChecking; - // end run all checking for debug - */ - - } else { - System.err - .println("is error: the wave needed to be higher sample rate"); - } - - } else { - System.out.println("The sample size must be a power of 2"); - } - - return false; - } - - protected void normalizeSpectrogramData(double[][] spectrogramData) { - - // normalization of absoultSpectrogram - // set max and min amplitudes - double maxAmp = Double.MIN_VALUE; - double minAmp = Double.MAX_VALUE; - for (int i = 0; i < spectrogramData.length; i++) { - for (int j = 0; j < spectrogramData[i].length; j++){ - if (spectrogramData[i][j] > maxAmp) { - maxAmp = spectrogramData[i][j]; - } else if (spectrogramData[i][j] < minAmp) { - minAmp = spectrogramData[i][j]; - } - } - } - // end set max and min amplitudes - - // normalization - // avoiding divided by zero - double minValidAmp = 0.00000000001F; - if (minAmp == 0) { - minAmp = minValidAmp; - } - - double diff = Math.log10(maxAmp / minAmp); // perceptual difference - for (int i = 0; i < spectrogramData.length; i++) { - for (int j = 0; j < spectrogramData[i].length; j++) { - if (spectrogramData[i][j] < minValidAmp) { - spectrogramData[i][j] = 0; - } else { - spectrogramData[i][j] = (Math.log10(spectrogramData[i][j] / minAmp)) / diff; - } - } - } - // end normalization - } - - protected boolean isPassedStandardDeviation(double[][] spectrogramData){ - - // normalize the spectrogramData (with all frames in the spectrogram) - normalizeSpectrogramData(spectrogramData); - - // analyst data in this frame - // since fftSampleSize==numSamples, there're only one spectrum which is spectrogramData[last] - double[] spectrum = spectrogramData[spectrogramData.length - 1]; - // find top most robust frequencies in this frame - double[] robustFrequencies = new double[numRobust]; - ArrayRankDouble arrayRankDouble = new ArrayRankDouble(); - double nthValue = arrayRankDouble.getNthOrderedValue(spectrum, numRobust, false); - // end analyst data in this frame - - int count = 0; - for (int i = 0; i < spectrum.length; i++) { - if (spectrum[i] >= nthValue) { - robustFrequencies[count++] = spectrum[i]; - if (count >= numRobust) { - break; - } - } - } - // end find top most robust frequencies - - StandardDeviation standardDeviation = new StandardDeviation(); - standardDeviation.setValues(robustFrequencies); - double sd = standardDeviation.evaluate(); - - // range of standard deviation - boolean result = (sd >= minStandardDeviation && sd <= maxStandardDeviation); - //System.out.println("sd: " + sd + " " + result); - return result; - } - - protected boolean isPassedFrequency(double[] spectrum){ - // find the robust frequency - ArrayRankDouble arrayRankDouble = new ArrayRankDouble(); - double robustFrequency = arrayRankDouble.getMaxValueIndex(spectrum) * unitFrequency; - - // frequency of the sound should not be too low or too high - boolean result = (robustFrequency >= minFrequency && robustFrequency <= maxFrequency); - //System.out.println("freq: " + robustFrequency + " " + result); - return result; - } - - protected boolean isPassedIntensity(double[] spectrum){ - // get the average intensity of the signal - double intensity = 0; - for (int i = 0; i < spectrum.length; i++) { - intensity += spectrum[i]; - } - intensity /= spectrum.length; - // end get the average intensity of the signal - - // intensity of the whistle should not be too soft - boolean result = (intensity > minIntensity && intensity <= maxIntensity); - //System.out.println("intensity: " + intensity + " " + result); - - return result; - } - - protected boolean isPassedZeroCrossingRate(short[] amplitudes){ - ZeroCrossingRate zcr = new ZeroCrossingRate(amplitudes, 1); - int numZeroCrosses = (int) zcr.evaluate(); - - // different sound has different range of zero crossing value - // when lengthInSecond=1, zero crossing rate is the num - // of zero crosses - boolean result = (numZeroCrosses >= minNumZeroCross && numZeroCrosses <= maxNumZeroCross); - //System.out.println("zcr: " + numZeroCrosses + " " +result); - - return result; - } - -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/api/WhistleApi.java b/app/Locabean/src/com/musicg/api/WhistleApi.java deleted file mode 100644 index 3099f87..0000000 --- a/app/Locabean/src/com/musicg/api/WhistleApi.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.api; - -import com.musicg.wave.WaveHeader; - -/** - * Api for detecting whistle - * - * @author Jacquet Wong - * - */ -public class WhistleApi extends DetectionApi{ - - public WhistleApi(WaveHeader waveHeader) { - super(waveHeader); - } - - protected void init(){ - // settings for detecting a whistle - minFrequency = 600.0f; - maxFrequency = Double.MAX_VALUE; - - minIntensity = 100.0f; - maxIntensity = 100000.0f; - - minStandardDeviation = 0.1f; - maxStandardDeviation = 1.0f; - - highPass = 100; - lowPass = 10000; - - minNumZeroCross = 50; - maxNumZeroCross = 200; - - numRobust = 10; - } - - public boolean isWhistle(byte[] audioBytes){ - return isSpecificSound(audioBytes); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/dsp/FastFourierTransform.java b/app/Locabean/src/com/musicg/dsp/FastFourierTransform.java deleted file mode 100644 index f8e27d8..0000000 --- a/app/Locabean/src/com/musicg/dsp/FastFourierTransform.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.dsp; - -import com.sun.media.sound.FFT; - -/** - * FFT object, transform amplitudes to frequency intensities - * - * @author Jacquet Wong - * - */ -public class FastFourierTransform { - - /** - * Get the frequency intensities - * - * @param amplitudes - * amplitudes of the signal - * @return intensities of each frequency unit: mag[frequency_unit]=intensity - */ - public double[] getMagnitudes(double[] amplitudes) { - - int sampleSize = amplitudes.length; - - // call the fft and transform the complex numbers - FFT fft = new FFT(sampleSize / 2, -1); - fft.transform(amplitudes); - // end call the fft and transform the complex numbers - - double[] complexNumbers = amplitudes; - - // even indexes (0,2,4,6,...) are real parts - // odd indexes (1,3,5,7,...) are img parts - int indexSize = sampleSize / 2; - - // FFT produces a transformed pair of arrays where the first half of the - // values represent positive frequency components and the second half - // represents negative frequency components. - // we omit the negative ones - int positiveSize = indexSize / 2; - - double[] mag = new double[positiveSize]; - for (int i = 0; i < indexSize; i += 2) { - mag[i / 2] = Math.sqrt(complexNumbers[i] * complexNumbers[i] + complexNumbers[i + 1] * complexNumbers[i + 1]); - } - - return mag; - } - -} diff --git a/app/Locabean/src/com/musicg/dsp/LinearInterpolation.java b/app/Locabean/src/com/musicg/dsp/LinearInterpolation.java deleted file mode 100644 index a74b433..0000000 --- a/app/Locabean/src/com/musicg/dsp/LinearInterpolation.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.dsp; - -/** - * Construct new data points within the range of a discrete set of known data points by linear equation - * - * @author Jacquet Wong - */ -public class LinearInterpolation { - - public LinearInterpolation(){ - - } - - /** - * Do interpolation on the samples according to the original and destinated sample rates - * - * @param oldSampleRate sample rate of the original samples - * @param newSampleRate sample rate of the interpolated samples - * @param samples original samples - * @return interpolated samples - */ - public short[] interpolate(int oldSampleRate, int newSampleRate, short[] samples) { - - if (oldSampleRate==newSampleRate){ - return samples; - } - - int newLength=(int)Math.round(((float)samples.length/oldSampleRate*newSampleRate)); - float lengthMultiplier=(float)newLength/samples.length; - short[] interpolatedSamples = new short[newLength]; - - // interpolate the value by the linear equation y=mx+c - for (int i = 0; i < newLength; i++){ - - // get the nearest positions for the interpolated point - float currentPosition = i / lengthMultiplier; - int nearestLeftPosition = (int)currentPosition; - int nearestRightPosition = nearestLeftPosition + 1; - if (nearestRightPosition>=samples.length){ - nearestRightPosition=samples.length-1; - } - - float slope=samples[nearestRightPosition]-samples[nearestLeftPosition]; // delta x is 1 - float positionFromLeft = currentPosition - nearestLeftPosition; - - interpolatedSamples[i] = (short)(slope*positionFromLeft+samples[nearestLeftPosition]); // y=mx+c - } - - return interpolatedSamples; - } -} diff --git a/app/Locabean/src/com/musicg/dsp/Resampler.java b/app/Locabean/src/com/musicg/dsp/Resampler.java deleted file mode 100644 index 1f0f517..0000000 --- a/app/Locabean/src/com/musicg/dsp/Resampler.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.dsp; - -/** - * Resample signal data (base on bytes) - * - * @author jacquet - * - */ -public class Resampler { - - public Resampler() { - } - - /** - * Do resampling. Currently the amplitude is stored by short such that maximum bitsPerSample is 16 (bytePerSample is 2) - * - * @param sourceData The source data in bytes - * @param bitsPerSample How many bits represents one sample (currently supports max. bitsPerSample=16) - * @param sourceRate Sample rate of the source data - * @param targetRate Sample rate of the target data - * @return re-sampled data - */ - public byte[] reSample(byte[] sourceData, int bitsPerSample, int sourceRate, int targetRate) { - - // make the bytes to amplitudes first - int bytePerSample = bitsPerSample / 8; - int numSamples = sourceData.length / bytePerSample; - short[] amplitudes = new short[numSamples]; // 16 bit, use a short to store - - int pointer = 0; - for (int i = 0; i < numSamples; i++) { - short amplitude = 0; - for (int byteNumber = 0; byteNumber < bytePerSample; byteNumber++) { - // little endian - amplitude |= (short) ((sourceData[pointer++] & 0xFF) << (byteNumber * 8)); - } - amplitudes[i] = amplitude; - } - // end make the amplitudes - - // do interpolation - LinearInterpolation reSample=new LinearInterpolation(); - short[] targetSample = reSample.interpolate(sourceRate, targetRate, amplitudes); - int targetLength = targetSample.length; - // end do interpolation - - // TODO: Remove the high frequency signals with a digital filter, leaving a signal containing only half-sample-rated frequency information, but still sampled at a rate of target sample rate. Usually FIR is used - - // end resample the amplitudes - - // convert the amplitude to bytes - byte[] bytes; - if (bytePerSample==1){ - bytes= new byte[targetLength]; - for (int i=0; i> 8) & 0xff); - } - } - // end convert the amplitude to bytes - - return bytes; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/dsp/WindowFunction.java b/app/Locabean/src/com/musicg/dsp/WindowFunction.java deleted file mode 100644 index 3043565..0000000 --- a/app/Locabean/src/com/musicg/dsp/WindowFunction.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.dsp; - -/** - * Window functions generator - * - * @author Jacquet Wong - * - */ -public class WindowFunction { - - public static final int RECTANGULAR = 0; - public static final int BARTLETT = 1; - public static final int HANNING = 2; - public static final int HAMMING = 3; - public static final int BLACKMAN = 4; - - int windowType = 0; // defaults to rectangular window - - public WindowFunction() { - } - - public void setWindowType(int wt) { - windowType = wt; - } - - public void setWindowType(String w) { - if (w.toUpperCase().equals("RECTANGULAR")) - windowType = RECTANGULAR; - if (w.toUpperCase().equals("BARTLETT")) - windowType = BARTLETT; - if (w.toUpperCase().equals("HANNING")) - windowType = HANNING; - if (w.toUpperCase().equals("HAMMING")) - windowType = HAMMING; - if (w.toUpperCase().equals("BLACKMAN")) - windowType = BLACKMAN; - } - - public int getWindowType() { - return windowType; - } - - /** - * Generate a window - * - * @param nSamples size of the window - * @return window in array - */ - public double[] generate(int nSamples) { - // generate nSamples window function values - // for index values 0 .. nSamples - 1 - int m = nSamples / 2; - double r; - double pi = Math.PI; - double[] w = new double[nSamples]; - switch (windowType) { - case BARTLETT: // Bartlett (triangular) window - for (int n = 0; n < nSamples; n++) - w[n] = 1.0f - Math.abs(n - m) / m; - break; - case HANNING: // Hanning window - r = pi / (m + 1); - for (int n = -m; n < m; n++) - w[m + n] = 0.5f + 0.5f * Math.cos(n * r); - break; - case HAMMING: // Hamming window - r = pi / m; - for (int n = -m; n < m; n++) - w[m + n] = 0.54f + 0.46f * Math.cos(n * r); - break; - case BLACKMAN: // Blackman window - r = pi / m; - for (int n = -m; n < m; n++) - w[m + n] = 0.42f + 0.5f * Math.cos(n * r) + 0.08f - * Math.cos(2 * n * r); - break; - default: // Rectangular window function - for (int n = 0; n < nSamples; n++) - w[n] = 1.0f; - } - return w; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/experiment/math/cluster/Segment.java b/app/Locabean/src/com/musicg/experiment/math/cluster/Segment.java deleted file mode 100644 index f3013fa..0000000 --- a/app/Locabean/src/com/musicg/experiment/math/cluster/Segment.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.experiment.math.cluster; -public class Segment { - - private int startPosition; - private int size; - private double mean; - - public int getStartPosition() { - return startPosition; - } - - public void setStartPosition(int startPosition) { - this.startPosition = startPosition; - } - - public int getSize() { - return size; - } - - public void setSize(int size) { - this.size = size; - } - - public double getMean() { - return mean; - } - - public void setMean(double mean) { - this.mean = mean; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/experiment/math/cluster/SegmentCluster.java b/app/Locabean/src/com/musicg/experiment/math/cluster/SegmentCluster.java deleted file mode 100644 index 1dde27d..0000000 --- a/app/Locabean/src/com/musicg/experiment/math/cluster/SegmentCluster.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.experiment.math.cluster; -import java.util.LinkedList; -import java.util.List; - -import com.musicg.pitch.PitchHandler; - -public class SegmentCluster{ - - private double diffThreshold; - - public SegmentCluster(){ - this.diffThreshold=1; - } - - public SegmentCluster(double diffThreshold){ - this.diffThreshold=diffThreshold; - } - - public void setDiffThreshold(double diffThreshold){ - this.diffThreshold=diffThreshold; - } - - public List getSegments(double[] array){ - - PitchHandler pitchHandler=new PitchHandler(); - List segmentList=new LinkedList(); - - double segmentMean=0; - int segmentSize=0; - - if (array.length>0){ - segmentMean=array[1]; - segmentSize=1; - } - - for (int i=1; i[] pointsLists = getRobustPointList(spectorgramData); - int numFrames = pointsLists.length; - - // prepare fingerprint bytes - coordinates = new int[numFrames][numRobustPointsPerFrame]; - - for (int x = 0; x < numFrames; x++) { - if (pointsLists[x].size() == numRobustPointsPerFrame) { - Iterator pointsListsIterator = pointsLists[x] - .iterator(); - for (int y = 0; y < numRobustPointsPerFrame; y++) { - coordinates[x][y] = pointsListsIterator.next(); - } - } else { - // use -1 to fill the empty byte - for (int y = 0; y < numRobustPointsPerFrame; y++) { - coordinates[x][y] = -1; - } - } - } - // end make fingerprint - - // for each valid coordinate, append with its intensity - List byteList = new LinkedList(); - for (int i = 0; i < numFrames; i++) { - for (int j = 0; j < numRobustPointsPerFrame; j++) { - if (coordinates[i][j] != -1) { - // first 2 bytes is x - int x = i; - byteList.add((byte) (x >> 8)); - byteList.add((byte) x); - - // next 2 bytes is y - int y = coordinates[i][j]; - byteList.add((byte) (y >> 8)); - byteList.add((byte) y); - - // next 4 bytes is intensity - int intensity = (int) (spectorgramData[x][y] * Integer.MAX_VALUE); // spectorgramData - // is - // ranged - // from - // 0~1 - byteList.add((byte) (intensity >> 24)); - byteList.add((byte) (intensity >> 16)); - byteList.add((byte) (intensity >> 8)); - byteList.add((byte) intensity); - } - } - } - // end for each valid coordinate, append with its intensity - - fingerprint = new byte[byteList.size()]; - Iterator byteListIterator = byteList.iterator(); - int pointer = 0; - while (byteListIterator.hasNext()) { - fingerprint[pointer++] = byteListIterator.next(); - } - - return fingerprint; - } - - /** - * Get bytes from fingerprint file - * - * @param fingerprintFile - * fingerprint filename - * @return fingerprint in bytes - */ - public byte[] getFingerprintFromFile(String fingerprintFile) { - byte[] fingerprint = null; - try { - InputStream fis = new FileInputStream(fingerprintFile); - fingerprint = getFingerprintFromInputStream(fis); - fis.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return fingerprint; - } - - /** - * Get bytes from fingerprint inputstream - * - * @param fingerprintFile - * fingerprint inputstream - * @return fingerprint in bytes - */ - public byte[] getFingerprintFromInputStream(InputStream inputStream) { - byte[] fingerprint = null; - try { - fingerprint = new byte[inputStream.available()]; - inputStream.read(fingerprint); - } catch (IOException e) { - e.printStackTrace(); - } - return fingerprint; - } - - /** - * Save fingerprint to a file - * - * @param fingerprint - * fingerprint bytes - * @param filename - * fingerprint filename - * @see fingerprint file saved - */ - public void saveFingerprintAsFile(byte[] fingerprint, String filename) { - - FileOutputStream fileOutputStream; - try { - fileOutputStream = new FileOutputStream(filename); - fileOutputStream.write(fingerprint); - fileOutputStream.close(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - // robustLists[x]=y1,y2,y3,... - private List[] getRobustPointList(double[][] spectrogramData) { - - System.out.println(spectrogramData); - int numX = spectrogramData.length; - int numY = spectrogramData[0].length; - - double[][] allBanksIntensities = new double[numX][numY]; - int bandwidthPerBank = numY / numFilterBanks; - - for (int b = 0; b < numFilterBanks; b++) { - - double[][] bankIntensities = new double[numX][bandwidthPerBank]; - - for (int i = 0; i < numX; i++) { - for (int j = 0; j < bandwidthPerBank; j++) { - bankIntensities[i][j] = spectrogramData[i][j + b - * bandwidthPerBank]; - } - } - - // get the most robust point in each filter bank - TopManyPointsProcessorChain processorChain = new TopManyPointsProcessorChain( - bankIntensities, 1); - double[][] processedIntensities = processorChain.getIntensities(); - - for (int i = 0; i < numX; i++) { - for (int j = 0; j < bandwidthPerBank; j++) { - allBanksIntensities[i][j + b * bandwidthPerBank] = processedIntensities[i][j]; - } - } - } - - List robustPointList = new LinkedList(); - - // find robust points - for (int i = 0; i < allBanksIntensities.length; i++) { - for (int j = 0; j < allBanksIntensities[i].length; j++) { - if (allBanksIntensities[i][j] > 0) { - - int[] point = new int[] { i, j }; - // System.out.println(i+","+frequency); - robustPointList.add(point); - } - } - } - // end find robust points - - List[] robustLists = new LinkedList[spectrogramData.length]; - for (int i = 0; i < robustLists.length; i++) { - robustLists[i] = new LinkedList(); - } - - // robustLists[x]=y1,y2,y3,... - Iterator robustPointListIterator = robustPointList.iterator(); - while (robustPointListIterator.hasNext()) { - int[] coor = robustPointListIterator.next(); - robustLists[coor[0]].add(coor[1]); - } - - // return the list per frame - return robustLists; - } - - /** - * Number of frames in a fingerprint Each frame lengths 8 bytes Usually - * there is more than one point in each frame, so it cannot simply divide - * the bytes length by 8 Last 8 byte of thisFingerprint is the last frame of - * this wave First 2 byte of the last 8 byte is the x position of this wave, - * i.e. (number_of_frames-1) of this wave - * - * @param fingerprint - * fingerprint bytes - * @return number of frames of the fingerprint - */ - public static int getNumFrames(byte[] fingerprint) { - - if (fingerprint.length < 8) { - return 0; - } - - // get the last x-coordinate (length-8&length-7)bytes from fingerprint - int numFrames = ((int) (fingerprint[fingerprint.length - 8] & 0xff) << 8 | (int) (fingerprint[fingerprint.length - 7] & 0xff)) + 1; - return numFrames; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/fingerprint/FingerprintSimilarity.java b/app/Locabean/src/com/musicg/fingerprint/FingerprintSimilarity.java deleted file mode 100644 index 0330fdc..0000000 --- a/app/Locabean/src/com/musicg/fingerprint/FingerprintSimilarity.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2012 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.musicg.fingerprint; - -import com.musicg.properties.FingerprintProperties; - -/** - * A class for fingerprint's similarity - * - * @author jacquet - * - */ -public class FingerprintSimilarity { - - private FingerprintProperties fingerprintProperties=FingerprintProperties.getInstance(); - private int mostSimilarFramePosition; - private float score; - private float similarity; - - /** - * Constructor - */ - public FingerprintSimilarity() { - mostSimilarFramePosition = Integer.MIN_VALUE; - score=-1; - similarity = -1; - } - - /** - * Get the most similar position in terms of frame number - * - * @return most similar frame position - */ - public int getMostSimilarFramePosition() { - return mostSimilarFramePosition; - } - - /** - * Set the most similar position in terms of frame number - * - * @param mostSimilarFramePosition - */ - public void setMostSimilarFramePosition(int mostSimilarFramePosition) { - this.mostSimilarFramePosition = mostSimilarFramePosition; - } - - /** - * Get the similarity of the fingerprints - * similarity from 0~1, which 0 means no similar feature is found and 1 means in average there is at least one match in every frame - * - * @return fingerprints similarity - */ - public float getSimilarity() { - return similarity; - } - - /** - * Set the similarity of the fingerprints - * - * @param fingerprints similarity - */ - public void setSimilarity(float similarity) { - this.similarity = similarity; - } - - /** - * Get the similarity score of the fingerprints - * Number of features found in the fingerprints per frame - * - * @return fingerprints similarity score - */ - public float getScore() { - return score; - } - - /** - * Set the similarity score of the fingerprints - * - * @param score - */ - public void setScore(float score) { - this.score = score; - } - - /** - * Get the most similar position in terms of time in second - * - * @return most similar starting time - */ - public float getsetMostSimilarTimePosition(){ - return (float)mostSimilarFramePosition/fingerprintProperties.getNumRobustPointsPerFrame()/fingerprintProperties.getFps(); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/fingerprint/FingerprintSimilarityComputer.java b/app/Locabean/src/com/musicg/fingerprint/FingerprintSimilarityComputer.java deleted file mode 100644 index ee16148..0000000 --- a/app/Locabean/src/com/musicg/fingerprint/FingerprintSimilarityComputer.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2012 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.musicg.fingerprint; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -import com.musicg.math.rank.MapRank; -import com.musicg.math.rank.MapRankInteger; - -/** - * Compute the similarity of two fingerprints - * - * @author jacquet - * - */ -public class FingerprintSimilarityComputer{ - - private FingerprintSimilarity fingerprintSimilarity; - byte[] fingerprint1, fingerprint2; - - /** - * Constructor, ready to compute the similarity of two fingerprints - * - * @param fingerprint1 - * @param fingerprint2 - */ - public FingerprintSimilarityComputer(byte[] fingerprint1, byte[] fingerprint2){ - - this.fingerprint1=fingerprint1; - this.fingerprint2=fingerprint2; - - fingerprintSimilarity=new FingerprintSimilarity(); - } - - /** - * Get fingerprint similarity of inout fingerprints - * - * @return fingerprint similarity object - */ - public FingerprintSimilarity getFingerprintsSimilarity(){ - HashMap offset_Score_Table=new HashMap(); // offset_Score_Table - int numFrames=0; - float score=0; - int mostSimilarFramePosition=Integer.MIN_VALUE; - - // one frame may contain several points, use the shorter one be the denominator - if (fingerprint1.length>fingerprint2.length){ - numFrames=FingerprintManager.getNumFrames(fingerprint2); - } - else{ - numFrames=FingerprintManager.getNumFrames(fingerprint1); - } - - // get the pairs - PairManager pairManager=new PairManager(); - HashMap> this_Pair_PositionList_Table=pairManager.getPair_PositionList_Table(fingerprint1); - HashMap> compareWave_Pair_PositionList_Table=pairManager.getPair_PositionList_Table(fingerprint2); - - Iterator compareWaveHashNumberIterator=compareWave_Pair_PositionList_Table.keySet().iterator(); - while (compareWaveHashNumberIterator.hasNext()){ - int compareWaveHashNumber=compareWaveHashNumberIterator.next(); - - // if the compareWaveHashNumber doesn't exist in both tables, no need to compare - if (!this_Pair_PositionList_Table.containsKey(compareWaveHashNumber) - || !compareWave_Pair_PositionList_Table.containsKey(compareWaveHashNumber)){ - continue; - } - - // for each compare hash number, get the positions - List wavePositionList=this_Pair_PositionList_Table.get(compareWaveHashNumber); - List compareWavePositionList=compareWave_Pair_PositionList_Table.get(compareWaveHashNumber); - - Iterator wavePositionListIterator=wavePositionList.iterator(); - while (wavePositionListIterator.hasNext()){ - int thisPosition=wavePositionListIterator.next(); - Iterator compareWavePositionListIterator=compareWavePositionList.iterator(); - while (compareWavePositionListIterator.hasNext()){ - int compareWavePosition=compareWavePositionListIterator.next(); - int offset=thisPosition-compareWavePosition; - - if (offset_Score_Table.containsKey(offset)){ - offset_Score_Table.put(offset, offset_Score_Table.get(offset)+1); - } - else{ - offset_Score_Table.put(offset, 1); - } - } - } - } - - // map rank - MapRank mapRank=new MapRankInteger(offset_Score_Table,false); - - // get the most similar positions and scores - List orderedKeyList=mapRank.getOrderedKeyList(100, true); - if (orderedKeyList.size()>0){ - int key=orderedKeyList.get(0); - // get the highest score position - if (mostSimilarFramePosition==Integer.MIN_VALUE){ - mostSimilarFramePosition=key; - score=offset_Score_Table.get(key); - - // accumulate the scores from neighbours - if (offset_Score_Table.containsKey(key-1)){ - score+=offset_Score_Table.get(key-1)/2; - } - if (offset_Score_Table.containsKey(key+1)){ - score+=offset_Score_Table.get(key+1)/2; - } - } - } - - /* - Iterator orderedKeyListIterator=orderedKeyList.iterator(); - while (orderedKeyListIterator.hasNext()){ - int offset=orderedKeyListIterator.next(); - System.out.println(offset+": "+offset_Score_Table.get(offset)); - } - */ - - score/=numFrames; - float similarity=score; - // similarity >1 means in average there is at least one match in every frame - if (similarity>1){ - similarity=1; - } - - fingerprintSimilarity.setMostSimilarFramePosition(mostSimilarFramePosition); - fingerprintSimilarity.setScore(score); - fingerprintSimilarity.setSimilarity(similarity); - - return fingerprintSimilarity; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/fingerprint/PairManager.java b/app/Locabean/src/com/musicg/fingerprint/PairManager.java deleted file mode 100644 index 1e86d2f..0000000 --- a/app/Locabean/src/com/musicg/fingerprint/PairManager.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2012 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.fingerprint; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import com.musicg.math.quicksort.QuickSortIndexPreserved; -import com.musicg.properties.FingerprintProperties; - -/** - * Make pairs for the audio fingerprints, which a pair is used to group the same features together - * - * @author jacquet - * - */ -public class PairManager{ - - FingerprintProperties fingerprintProperties=FingerprintProperties.getInstance(); - private int numFilterBanks=fingerprintProperties.getNumFilterBanks(); - private int bandwidthPerBank=fingerprintProperties.getNumFrequencyUnits()/numFilterBanks; - private int anchorPointsIntervalLength=fingerprintProperties.getAnchorPointsIntervalLength(); - private int numAnchorPointsPerInterval=fingerprintProperties.getNumAnchorPointsPerInterval(); - private int maxTargetZoneDistance=fingerprintProperties.getMaxTargetZoneDistance(); - private int numFrequencyUnits=fingerprintProperties.getNumFrequencyUnits(); - - private int maxPairs; - private boolean isReferencePairing; - private HashMap stopPairTable=new HashMap(); - - /** - * Constructor - */ - public PairManager(){ - maxPairs=fingerprintProperties.getRefMaxActivePairs(); - isReferencePairing=true; - } - - /** - * Constructor, number of pairs of robust points depends on the parameter isReferencePairing - * no. of pairs of reference and sample can be different due to environmental influence of source - * @param isReferencePairing - */ - public PairManager(boolean isReferencePairing){ - if (isReferencePairing){ - maxPairs=fingerprintProperties.getRefMaxActivePairs(); - } - else{ - maxPairs=fingerprintProperties.getSampleMaxActivePairs(); - } - this.isReferencePairing=isReferencePairing; - } - - /** - * Get a pair-positionList table - * It's a hash map which the key is the hashed pair, and the value is list of positions - * That means the table stores the positions which have the same hashed pair - * - * @param fingerprint fingerprint bytes - * @return pair-positionList HashMap - */ - public HashMap> getPair_PositionList_Table(byte[] fingerprint){ - - List pairPositionList=getPairPositionList(fingerprint); - - // table to store pair:pos,pos,pos,...;pair2:pos,pos,pos,.... - HashMap> pair_positionList_table=new HashMap>(); - - // get all pair_positions from list, use a table to collect the data group by pair hashcode - Iterator pairPositionListIterator=pairPositionList.iterator(); - while (pairPositionListIterator.hasNext()){ - int[] pair_position=pairPositionListIterator.next(); - //System.out.println(pair_position[0]+","+pair_position[1]); - - // group by pair-hashcode, i.e.: > - if (pair_positionList_table.containsKey(pair_position[0])){ - pair_positionList_table.get(pair_position[0]).add(pair_position[1]); - } - else{ - List positionList=new LinkedList(); - positionList.add(pair_position[1]); - pair_positionList_table.put(pair_position[0], positionList); - } - // end group by pair-hashcode, i.e.: > - } - // end get all pair_positions from list, use a table to collect the data group by pair hashcode - - return pair_positionList_table; - } - - // this return list contains: int[0]=pair_hashcode, int[1]=position - private List getPairPositionList(byte[] fingerprint){ - - int numFrames=FingerprintManager.getNumFrames(fingerprint); - - // table for paired frames - byte[] pairedFrameTable=new byte[numFrames/anchorPointsIntervalLength+1]; // each second has numAnchorPointsPerSecond pairs only - // end table for paired frames - - List pairList=new LinkedList(); - List sortedCoordinateList=getSortedCoordinateList(fingerprint); - - Iterator anchorPointListIterator=sortedCoordinateList.iterator(); - while (anchorPointListIterator.hasNext()){ - int[] anchorPoint=anchorPointListIterator.next(); - int anchorX=anchorPoint[0]; - int anchorY=anchorPoint[1]; - int numPairs=0; - - Iterator targetPointListIterator=sortedCoordinateList.iterator(); - while (targetPointListIterator.hasNext()){ - - if (numPairs>=maxPairs){ - break; - } - - if (isReferencePairing && pairedFrameTable[anchorX/anchorPointsIntervalLength]>=numAnchorPointsPerInterval){ - break; - } - - int[] targetPoint=targetPointListIterator.next(); - int targetX=targetPoint[0]; - int targetY=targetPoint[1]; - - if (anchorX==targetX && anchorY==targetY){ - continue; - } - - // pair up the points - int x1,y1,x2,y2; // x2 always >= x1 - if (targetX>=anchorX){ - x2=targetX; - y2=targetY; - x1=anchorX; - y1=anchorY; - } - else{ - x2=anchorX; - y2=anchorY; - x1=targetX; - y1=targetY; - } - - // check target zone - if ((x2-x1)>maxTargetZoneDistance){ - continue; - } - // end check target zone - - // check filter bank zone - if (!(y1/bandwidthPerBank == y2/bandwidthPerBank)){ - continue; // same filter bank should have equal value - } - // end check filter bank zone - - int pairHashcode=(x2-x1)*numFrequencyUnits*numFrequencyUnits+y2*numFrequencyUnits+y1; - - // stop list applied on sample pairing only - if (!isReferencePairing && stopPairTable.containsKey(pairHashcode)){ - numPairs++; // no reservation - continue; // escape this point only - } - // end stop list applied on sample pairing only - - // pass all rules - pairList.add(new int[]{pairHashcode,anchorX}); - pairedFrameTable[anchorX/anchorPointsIntervalLength]++; - //System.out.println(anchorX+","+anchorY+"&"+targetX+","+targetY+":"+pairHashcode+" ("+pairedFrameTable[anchorX/anchorPointsIntervalLength]+")"); - numPairs++; - // end pair up the points - } - } - - return pairList; - } - - private List getSortedCoordinateList(byte[] fingerprint){ - // each point data is 8 bytes - // first 2 bytes is x - // next 2 bytes is y - // next 4 bytes is intensity - - // get all intensities - int numCoordinates=fingerprint.length/8; - int[] intensities=new int[numCoordinates]; - for (int i=0; i sortedCoordinateList=new LinkedList(); - for (int i=sortIndexes.length-1; i>=0; i--){ - int pointer=sortIndexes[i]*8; - int x=(int)(fingerprint[pointer]&0xff)<<8 | (int)(fingerprint[pointer+1]&0xff); - int y=(int)(fingerprint[pointer+2]&0xff)<<8 | (int)(fingerprint[pointer+3]&0xff); - sortedCoordinateList.add(new int[]{x,y}); - } - return sortedCoordinateList; - } - - /** - * Convert hashed pair to bytes - * - * @param pairHashcode hashed pair - * @return byte array - */ - public static byte[] pairHashcodeToBytes(int pairHashcode){ - return new byte[]{(byte)(pairHashcode>>8),(byte)pairHashcode}; - } - - /** - * Convert bytes to hased pair - * - * @param pairBytes - * @return hashed pair - */ - public static int pairBytesToHashcode(byte[] pairBytes){ - return (int)(pairBytes[0]&0xFF)<<8|(int)(pairBytes[1]&0xFF); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/main/demo/FingerprintDemo.java b/app/Locabean/src/com/musicg/main/demo/FingerprintDemo.java deleted file mode 100644 index 31a4074..0000000 --- a/app/Locabean/src/com/musicg/main/demo/FingerprintDemo.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2012 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.musicg.main.demo; - -import com.musicg.fingerprint.FingerprintManager; -import com.musicg.wave.Wave; -import java.util.Arrays; - -public class FingerprintDemo{ - - public static void main (String[] args){ - - String filename = "cock_a_1.wav"; - - // create a wave object - Wave wave = new Wave("audio_work/"+filename); - - // get the fingerprint - byte[] fingerprint=wave.getFingerprint(); - System.out.println(Arrays.toString(fingerprint)); - // dump the fingerprint - FingerprintManager fingerprintManager=new FingerprintManager(); - fingerprintManager.saveFingerprintAsFile(fingerprint, "out/"+filename+".fingerprint"); - - // load fingerprint from file - byte[] loadedFp=fingerprintManager.getFingerprintFromFile("out/"+filename+".fingerprint"); - - // fingerprint bytes checking -// for (int i=0; i0){ - System.out.println(i+": "+processedIntensities[i][j]); - } - } - } - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/main/demo/WaveDemo.java b/app/Locabean/src/com/musicg/main/demo/WaveDemo.java deleted file mode 100644 index 707045a..0000000 --- a/app/Locabean/src/com/musicg/main/demo/WaveDemo.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2012 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.musicg.main.demo; - -import com.musicg.wave.Wave; -import com.musicg.wave.WaveFileManager; - -public class WaveDemo { - - public static void main(String[] args) { - - String filename = "audio_work/cock_a_1.wav"; - String outFolder="out"; - - // create a wave object - Wave wave = new Wave(filename); - - // print the wave header and info - System.out.println(wave); - - // trim the wav - wave.leftTrim(1); - wave.rightTrim(0.5F); - - // save the trimmed wav - WaveFileManager waveFileManager=new WaveFileManager(wave); - waveFileManager.saveWaveAsFile(outFolder+"/out.wav"); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/main/demo/WhistleApiDemo.java b/app/Locabean/src/com/musicg/main/demo/WhistleApiDemo.java deleted file mode 100644 index e1eb4bd..0000000 --- a/app/Locabean/src/com/musicg/main/demo/WhistleApiDemo.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2012 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.musicg.main.demo; - -import com.musicg.wave.Wave; -import com.musicg.wave.WaveTypeDetector; - -public class WhistleApiDemo{ - public static void main(String[] args){ - String filename = "audio_work/whistle.wav"; - - // create a wave object - Wave wave = new Wave(filename); - - WaveTypeDetector waveTypeDetector=new WaveTypeDetector(wave); - System.out.println("Is whistle probability: "+waveTypeDetector.getWhistleProbability()); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/quicksort/QuickSort.java b/app/Locabean/src/com/musicg/math/quicksort/QuickSort.java deleted file mode 100644 index 5b3acb4..0000000 --- a/app/Locabean/src/com/musicg/math/quicksort/QuickSort.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.musicg.math.quicksort; - -public abstract class QuickSort{ - public abstract int[] getSortIndexes(); -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/quicksort/QuickSortDouble.java b/app/Locabean/src/com/musicg/math/quicksort/QuickSortDouble.java deleted file mode 100644 index fbc9e59..0000000 --- a/app/Locabean/src/com/musicg/math/quicksort/QuickSortDouble.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.musicg.math.quicksort; -public class QuickSortDouble extends QuickSort{ - - private int[] indexes; - private double[] array; - - public QuickSortDouble(double[] array){ - this.array=array; - indexes=new int[array.length]; - for (int i=0; i= j) break; // check if pointers cross - swap(a, indexes, i, j); // swap two elements into place - } - swap(a, indexes, i, right); // swap with partition element - return i; - } - - // exchange a[i] and a[j] - private void swap(double[] a, int[] indexes, int i, int j) { - int swap = indexes[i]; - indexes[i] = indexes[j]; - indexes[j] = swap; - } - -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/quicksort/QuickSortIndexPreserved.java b/app/Locabean/src/com/musicg/math/quicksort/QuickSortIndexPreserved.java deleted file mode 100644 index 5a333e4..0000000 --- a/app/Locabean/src/com/musicg/math/quicksort/QuickSortIndexPreserved.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.musicg.math.quicksort; -public class QuickSortIndexPreserved { - - private QuickSort quickSort; - - public QuickSortIndexPreserved(int[] array){ - quickSort=new QuickSortInteger(array); - } - - public QuickSortIndexPreserved(double[] array){ - quickSort=new QuickSortDouble(array); - } - - public QuickSortIndexPreserved(short[] array){ - quickSort=new QuickSortShort(array); - } - - public int[] getSortIndexes(){ - return quickSort.getSortIndexes(); - } - -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/quicksort/QuickSortInteger.java b/app/Locabean/src/com/musicg/math/quicksort/QuickSortInteger.java deleted file mode 100644 index a6684c2..0000000 --- a/app/Locabean/src/com/musicg/math/quicksort/QuickSortInteger.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.musicg.math.quicksort; -public class QuickSortInteger extends QuickSort{ - - private int[] indexes; - private int[] array; - - public QuickSortInteger(int[] array){ - this.array=array; - indexes=new int[array.length]; - for (int i=0; i= j) break; // check if pointers cross - swap(a, indexes, i, j); // swap two elements into place - } - swap(a, indexes, i, right); // swap with partition element - return i; - } - - // exchange a[i] and a[j] - private void swap(int[] a, int[] indexes, int i, int j) { - int swap = indexes[i]; - indexes[i] = indexes[j]; - indexes[j] = swap; - } - -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/quicksort/QuickSortShort.java b/app/Locabean/src/com/musicg/math/quicksort/QuickSortShort.java deleted file mode 100644 index 271407b..0000000 --- a/app/Locabean/src/com/musicg/math/quicksort/QuickSortShort.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.musicg.math.quicksort; -public class QuickSortShort extends QuickSort{ - - private int[] indexes; - private short[] array; - - public QuickSortShort(short[] array){ - this.array=array; - indexes=new int[array.length]; - for (int i=0; i= j) break; // check if pointers cross - swap(a, indexes, i, j); // swap two elements into place - } - swap(a, indexes, i, right); // swap with partition element - return i; - } - - // exchange a[i] and a[j] - private void swap(short[] a, int[] indexes, int i, int j) { - int swap = indexes[i]; - indexes[i] = indexes[j]; - indexes[j] = swap; - } - -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/rank/ArrayRankDouble.java b/app/Locabean/src/com/musicg/math/rank/ArrayRankDouble.java deleted file mode 100644 index 1881680..0000000 --- a/app/Locabean/src/com/musicg/math/rank/ArrayRankDouble.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.math.rank; - -public class ArrayRankDouble { - - /** - * Get the index position of maximum value the given array - * @param array - * @return index of the max value in array - */ - public int getMaxValueIndex(double[] array) { - - int index = 0; - double max = Integer.MIN_VALUE; - - for (int i = 0; i < array.length; i++) { - if (array[i] > max) { - max = array[i]; - index = i; - } - } - - return index; - } - - /** - * Get the index position of minimum value in the given array - * @param array - * @return index of the min value in array - */ - public int getMinValueIndex(double[] array) { - - int index = 0; - double min = Integer.MAX_VALUE; - - for (int i = 0; i < array.length; i++) { - if (array[i] < min) { - min = array[i]; - index = i; - } - } - - return index; - } - - /** - * Get the n-th value in the array after sorted - * @param array - * @param n - * @param ascending is ascending order or not - * @return - */ - public double getNthOrderedValue(double[] array, int n, boolean ascending) { - - if (n > array.length) { - n = array.length; - } - - int targetindex; - if (ascending) { - targetindex = n; - } else { - targetindex = array.length - n; - } - - // this value is the value of the numKey-th element - double passValue = getOrderedValue(array, targetindex); - - return passValue; - } - - private double getOrderedValue(double[] array, int index) { - locate(array, 0, array.length - 1, index); - return array[index]; - } - - // sort the partitions by quick sort, and locate the target index - private void locate(double[] array, int left, int right, int index) { - - int mid = (left + right) / 2; - // System.out.println(left+" to "+right+" ("+mid+")"); - - if (right == left) { - // System.out.println("* "+array[targetIndex]); - // result=array[targetIndex]; - return; - } - - if (left < right) { - double s = array[mid]; - int i = left - 1; - int j = right + 1; - - while (true) { - while (array[++i] < s) - ; - while (array[--j] > s) - ; - if (i >= j) - break; - swap(array, i, j); - } - - // System.out.println("2 parts: "+left+"-"+(i-1)+" and "+(j+1)+"-"+right); - - if (i > index) { - // the target index in the left partition - // System.out.println("left partition"); - locate(array, left, i - 1, index); - } else { - // the target index in the right partition - // System.out.println("right partition"); - locate(array, j + 1, right, index); - } - } - } - - private void swap(double[] array, int i, int j) { - double t = array[i]; - array[i] = array[j]; - array[j] = t; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/rank/MapRank.java b/app/Locabean/src/com/musicg/math/rank/MapRank.java deleted file mode 100644 index 24c4e49..0000000 --- a/app/Locabean/src/com/musicg/math/rank/MapRank.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.musicg.math.rank; - -import java.util.List; - -public interface MapRank{ - public List getOrderedKeyList(int numKeys, boolean sharpLimit); -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/rank/MapRankDouble.java b/app/Locabean/src/com/musicg/math/rank/MapRankDouble.java deleted file mode 100644 index 160a198..0000000 --- a/app/Locabean/src/com/musicg/math/rank/MapRankDouble.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.musicg.math.rank; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -public class MapRankDouble implements MapRank{ - - private Map map; - private boolean acsending=true; - - public MapRankDouble(Map map, boolean acsending){ - this.map=map; - this.acsending=acsending; - } - - public List getOrderedKeyList(int numKeys, boolean sharpLimit){ // if sharp limited, will return sharp numKeys, otherwise will return until the values not equals the exact key's value - - Set mapEntrySet=map.entrySet(); - List keyList=new LinkedList(); - - // if the numKeys is larger than map size, limit it - if (numKeys>map.size()){ - numKeys=map.size(); - } - // end if the numKeys is larger than map size, limit it - - if (map.size()>0){ - double[] array=new double[map.size()]; - int count=0; - - // get the pass values - Iterator mapIterator=mapEntrySet.iterator(); - while (mapIterator.hasNext()){ - Entry entry=mapIterator.next(); - array[count++]=(Double)entry.getValue(); - } - // end get the pass values - - int targetindex; - if (acsending){ - targetindex=numKeys; - } - else{ - targetindex=array.length-numKeys; - } - - double passValue=getOrderedValue(array,targetindex); // this value is the value of the numKey-th element - // get the passed keys and values - Map passedMap=new HashMap(); - List valueList=new LinkedList(); - mapIterator=mapEntrySet.iterator(); - - while (mapIterator.hasNext()){ - Entry entry=mapIterator.next(); - double value=(Double)entry.getValue(); - if ((acsending && value<=passValue) || (!acsending && value>=passValue)){ - passedMap.put(entry.getKey(), value); - valueList.add(value); - } - } - // end get the passed keys and values - - // sort the value list - Double[] listArr=new Double[valueList.size()]; - valueList.toArray(listArr); - Arrays.sort(listArr); - // end sort the value list - - // get the list of keys - int resultCount=0; - int index; - if (acsending){ - index=0; - } - else{ - index=listArr.length-1; - } - - if (!sharpLimit){ - numKeys=listArr.length; - } - - while (true){ - double targetValue=(Double)listArr[index]; - Iterator passedMapIterator=passedMap.entrySet().iterator(); - while(passedMapIterator.hasNext()){ - Entry entry=passedMapIterator.next(); - if ((Double)entry.getValue()==targetValue){ - keyList.add(entry.getKey()); - passedMapIterator.remove(); - resultCount++; - break; - } - } - - if (acsending){ - index++; - } - else{ - index--; - } - - if (resultCount>=numKeys){ - break; - } - } - // end get the list of keys - } - - return keyList; - } - - private double getOrderedValue(double[] array, int index){ - locate(array,0,array.length-1,index); - return array[index]; - } - - // sort the partitions by quick sort, and locate the target index - private void locate(double[] array, int left, int right, int index) { - - int mid=(left+right)/2; - //System.out.println(left+" to "+right+" ("+mid+")"); - - if (right==left){ - //System.out.println("* "+array[targetIndex]); - //result=array[targetIndex]; - return; - } - - if(left < right) { - double s = array[mid]; - int i = left - 1; - int j = right + 1; - - while(true) { - while(array[++i] < s) ; - while(array[--j] > s) ; - if(i >= j) - break; - swap(array, i, j); - } - - //System.out.println("2 parts: "+left+"-"+(i-1)+" and "+(j+1)+"-"+right); - - if (i>index){ - // the target index in the left partition - //System.out.println("left partition"); - locate(array, left, i-1,index); - } - else{ - // the target index in the right partition - //System.out.println("right partition"); - locate(array, j+1, right,index); - } - } - } - - private void swap(double[] array, int i, int j) { - double t = array[i]; - array[i] = array[j]; - array[j] = t; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/rank/MapRankInteger.java b/app/Locabean/src/com/musicg/math/rank/MapRankInteger.java deleted file mode 100644 index b7c528b..0000000 --- a/app/Locabean/src/com/musicg/math/rank/MapRankInteger.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.musicg.math.rank; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -public class MapRankInteger implements MapRank{ - - private Map map; - private boolean acsending=true; - - public MapRankInteger(Map map, boolean acsending){ - this.map=map; - this.acsending=acsending; - } - - public List getOrderedKeyList(int numKeys, boolean sharpLimit){ // if sharp limited, will return sharp numKeys, otherwise will return until the values not equals the exact key's value - - Set mapEntrySet=map.entrySet(); - List keyList=new LinkedList(); - - // if the numKeys is larger than map size, limit it - if (numKeys>map.size()){ - numKeys=map.size(); - } - // end if the numKeys is larger than map size, limit it - - if (map.size()>0){ - int[] array=new int[map.size()]; - int count=0; - - // get the pass values - Iterator mapIterator=mapEntrySet.iterator(); - while (mapIterator.hasNext()){ - Entry entry=mapIterator.next(); - array[count++]=(Integer)entry.getValue(); - } - // end get the pass values - - int targetindex; - if (acsending){ - targetindex=numKeys; - } - else{ - targetindex=array.length-numKeys; - } - - int passValue=getOrderedValue(array,targetindex); // this value is the value of the numKey-th element - // get the passed keys and values - Map passedMap=new HashMap(); - List valueList=new LinkedList(); - mapIterator=mapEntrySet.iterator(); - - while (mapIterator.hasNext()){ - Entry entry=mapIterator.next(); - int value=(Integer)entry.getValue(); - if ((acsending && value<=passValue) || (!acsending && value>=passValue)){ - passedMap.put(entry.getKey(), value); - valueList.add(value); - } - } - // end get the passed keys and values - - // sort the value list - Integer[] listArr=new Integer[valueList.size()]; - valueList.toArray(listArr); - Arrays.sort(listArr); - // end sort the value list - - // get the list of keys - int resultCount=0; - int index; - if (acsending){ - index=0; - } - else{ - index=listArr.length-1; - } - - if (!sharpLimit){ - numKeys=listArr.length; - } - - while (true){ - int targetValue=(Integer)listArr[index]; - Iterator passedMapIterator=passedMap.entrySet().iterator(); - while(passedMapIterator.hasNext()){ - Entry entry=passedMapIterator.next(); - if ((Integer)entry.getValue()==targetValue){ - keyList.add(entry.getKey()); - passedMapIterator.remove(); - resultCount++; - break; - } - } - - if (acsending){ - index++; - } - else{ - index--; - } - - if (resultCount>=numKeys){ - break; - } - } - // end get the list of keys - } - - return keyList; - } - - private int getOrderedValue(int[] array, int index){ - locate(array,0,array.length-1,index); - return array[index]; - } - - // sort the partitions by quick sort, and locate the target index - private void locate(int[] array, int left, int right, int index) { - - int mid=(left+right)/2; - //System.out.println(left+" to "+right+" ("+mid+")"); - - if (right==left){ - //System.out.println("* "+array[targetIndex]); - //result=array[targetIndex]; - return; - } - - if(left < right) { - int s = array[mid]; - int i = left - 1; - int j = right + 1; - - while(true) { - while(array[++i] < s) ; - while(array[--j] > s) ; - if(i >= j) - break; - swap(array, i, j); - } - - //System.out.println("2 parts: "+left+"-"+(i-1)+" and "+(j+1)+"-"+right); - - if (i>index){ - // the target index in the left partition - //System.out.println("left partition"); - locate(array, left, i-1,index); - } - else{ - // the target index in the right partition - //System.out.println("right partition"); - locate(array, j+1, right,index); - } - } - } - - private void swap(int[] array, int i, int j) { - int t = array[i]; - array[i] = array[j]; - array[j] = t; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/rank/MapRankShort.java b/app/Locabean/src/com/musicg/math/rank/MapRankShort.java deleted file mode 100644 index 89e6ca2..0000000 --- a/app/Locabean/src/com/musicg/math/rank/MapRankShort.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.musicg.math.rank; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -public class MapRankShort implements MapRank{ - - private Map map; - private boolean acsending=true; - - public MapRankShort(Map map, boolean acsending){ - this.map=map; - this.acsending=acsending; - } - - public List getOrderedKeyList(int numKeys, boolean sharpLimit){ // if sharp limited, will return sharp numKeys, otherwise will return until the values not equals the exact key's value - - Set mapEntrySet=map.entrySet(); - List keyList=new LinkedList(); - - // if the numKeys is larger than map size, limit it - if (numKeys>map.size()){ - numKeys=map.size(); - } - // end if the numKeys is larger than map size, limit it - - if (map.size()>0){ - - short[] array=new short[map.size()]; - int count=0; - - // get the pass values - Iterator mapIterator=mapEntrySet.iterator(); - while (mapIterator.hasNext()){ - Entry entry=mapIterator.next(); - array[count++]=(Short)entry.getValue(); - } - // end get the pass values - - int targetindex; - if (acsending){ - targetindex=numKeys; - } - else{ - targetindex=array.length-numKeys; - } - - short passValue=getOrderedValue(array,targetindex); // this value is the value of the numKey-th element - // get the passed keys and values - Map passedMap=new HashMap(); - List valueList=new LinkedList(); - mapIterator=mapEntrySet.iterator(); - - while (mapIterator.hasNext()){ - Entry entry=mapIterator.next(); - short value=(Short)entry.getValue(); - if ((acsending && value<=passValue) || (!acsending && value>=passValue)){ - passedMap.put(entry.getKey(), value); - valueList.add(value); - } - } - // end get the passed keys and values - - // sort the value list - Short[] listArr=new Short[valueList.size()]; - valueList.toArray(listArr); - Arrays.sort(listArr); - // end sort the value list - - // get the list of keys - int resultCount=0; - int index; - if (acsending){ - index=0; - } - else{ - index=listArr.length-1; - } - - if (!sharpLimit){ - numKeys=listArr.length; - } - - while (true){ - short targetValue=(Short)listArr[index]; - Iterator passedMapIterator=passedMap.entrySet().iterator(); - while(passedMapIterator.hasNext()){ - Entry entry=passedMapIterator.next(); - if ((Short)entry.getValue()==targetValue){ - keyList.add(entry.getKey()); - passedMapIterator.remove(); - resultCount++; - break; - } - } - - if (acsending){ - index++; - } - else{ - index--; - } - - if (resultCount>=numKeys){ - break; - } - } - // end get the list of keys - } - - return keyList; - } - - private short getOrderedValue(short[] array, int index){ - locate(array,0,array.length-1,index); - return array[index]; - } - - // sort the partitions by quick sort, and locate the target index - private void locate(short[] array, int left, int right, int index) { - - int mid=(left+right)/2; - //System.out.println(left+" to "+right+" ("+mid+")"); - - if (right==left){ - //System.out.println("* "+array[targetIndex]); - //result=array[targetIndex]; - return; - } - - if(left < right) { - short s = array[mid]; - int i = left - 1; - int j = right + 1; - - while(true) { - while(array[++i] < s) ; - while(array[--j] > s) ; - if(i >= j) - break; - swap(array, i, j); - } - - //System.out.println("2 parts: "+left+"-"+(i-1)+" and "+(j+1)+"-"+right); - - if (i>index){ - // the target index in the left partition - //System.out.println("left partition"); - locate(array, left, i-1,index); - } - else{ - // the target index in the right partition - //System.out.println("right partition"); - locate(array, j+1, right,index); - } - } - } - - private void swap(short[] array, int i, int j) { - short t = array[i]; - array[i] = array[j]; - array[j] = t; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/statistics/DataCentroid.java b/app/Locabean/src/com/musicg/math/statistics/DataCentroid.java deleted file mode 100644 index 7de62d5..0000000 --- a/app/Locabean/src/com/musicg/math/statistics/DataCentroid.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.math.statistics; - -/** - * Evaluate the centroid of an array - * - * @author Jacquet Wong - * - */ -public class DataCentroid extends MathStatistics{ - - public DataCentroid(){ - - } - - public DataCentroid(double[] values){ - setValues(values); - } - - public double evaluate(){ - double sumCentroid=0; - double sumIntensities=0; - int size=values.length; - - for (int i=0; i0){ - sumCentroid+=i*values[i]; - sumIntensities+=values[i]; - } - } - double avgCentroid=sumCentroid/sumIntensities; - - return avgCentroid; - } -} diff --git a/app/Locabean/src/com/musicg/math/statistics/MathStatistics.java b/app/Locabean/src/com/musicg/math/statistics/MathStatistics.java deleted file mode 100644 index ec07d7e..0000000 --- a/app/Locabean/src/com/musicg/math/statistics/MathStatistics.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.math.statistics; - -/** - * Abstract class for mathematics & statistics - * - * @author Jacquet Wong - * - */ -public abstract class MathStatistics{ - - protected double[] values; - - public void setValues(double[] values){ - this.values=values; - } - - public abstract double evaluate(); -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/statistics/Mean.java b/app/Locabean/src/com/musicg/math/statistics/Mean.java deleted file mode 100644 index ab988bf..0000000 --- a/app/Locabean/src/com/musicg/math/statistics/Mean.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.math.statistics; - -/** - * Evaluate the mean of an array - * @author Jacquet Wong - * - */ -public class Mean extends MathStatistics{ - - private Sum sum=new Sum(); - - public Mean(){ - } - - public Mean(double[] values){ - setValues(values); - } - - public double evaluate(){ - sum.setValues(values); - double mean=sum.evaluate()/sum.size(); - return mean; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/statistics/SpectralCentroid.java b/app/Locabean/src/com/musicg/math/statistics/SpectralCentroid.java deleted file mode 100644 index ec4a41c..0000000 --- a/app/Locabean/src/com/musicg/math/statistics/SpectralCentroid.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.math.statistics; - -/** - * Evaluate the spectral centroid of an array - * - * @author Jacquet Wong - * - */ -public class SpectralCentroid extends MathStatistics{ - - public SpectralCentroid(){ - - } - - public SpectralCentroid(double[] values){ - setValues(values); - } - - public double evaluate(){ - double sumCentroid=0; - double sumIntensities=0; - int size=values.length; - - for (int i=0; i0){ - sumCentroid+=i*values[i]; - sumIntensities+=values[i]; - } - } - double avgCentroid=sumCentroid/sumIntensities; - - return avgCentroid; - } -} diff --git a/app/Locabean/src/com/musicg/math/statistics/StandardDeviation.java b/app/Locabean/src/com/musicg/math/statistics/StandardDeviation.java deleted file mode 100644 index c2147c1..0000000 --- a/app/Locabean/src/com/musicg/math/statistics/StandardDeviation.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.math.statistics; - -/** - * Evaluate the standard deviation of an array - * - * @author Jacquet Wong - * - */ -public class StandardDeviation extends MathStatistics{ - - private Mean mean=new Mean(); - - public StandardDeviation(){ - - } - - public StandardDeviation(double[] values){ - setValues(values); - } - - public double evaluate(){ - - mean.setValues(values); - double meanValue=mean.evaluate(); - - int size=values.length; - double diffSquare=0; - double sd=Double.NaN; - - for (int i=0; i0){ - sd=Math.sqrt(diffSquare/size); - } - - return sd; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/math/statistics/Sum.java b/app/Locabean/src/com/musicg/math/statistics/Sum.java deleted file mode 100644 index 220d366..0000000 --- a/app/Locabean/src/com/musicg/math/statistics/Sum.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.math.statistics; - -/** - * Evaluate the sum of an array - * - * @author Jacquet Wong - * - */ -public class Sum extends MathStatistics{ - - public Sum(){ - } - - public Sum(double[] values){ - setValues(values); - } - - public double evaluate(){ - double sum=0; - int size=values.length; - for (int i=0 ;i=0 && signals[i+1]<0) || (signals[i]<0 && signals[i+1]>=0)){ - numZC++; - } - } - - return numZC/lengthInSecond; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/pitch/PitchHandler.java b/app/Locabean/src/com/musicg/pitch/PitchHandler.java deleted file mode 100644 index f384a9f..0000000 --- a/app/Locabean/src/com/musicg/pitch/PitchHandler.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.pitch; - -import java.util.Arrays; - -/** - * Methods for handling the pitches - * - * @author Jacquet Wong - * - */ -public class PitchHandler{ - - /** - * Get the tone changed by comparing two tones - * return 1.0 is a semi-tone, 2.0 is a tone, etc... - * - * @param f1 original tone - * @param f2 new tone - * @return tone changed - */ - public double getToneChanged(double f1, double f2){ - return Math.log(f1/f2)/Math.log(2)*12; - } - - /** - * Determine the harmonic probability of a list of frequencies - * - * @param list of frequencies - * @return probability of harmonic - */ - public double getHarmonicProbability(double[] frequencies){ - - int harmonicCount=0; - int count=0; - Arrays.sort(frequencies); - - for (int i=0; i=1){ - double minF0=100; - int minDivisor=(int)(f1/minF0); - - for (int i=1; i<=minDivisor; i++){ - double f0=f1/i; - int maxMultiplier=(int)(f2/f0+1); - for (int j=2; j<=maxMultiplier; j++){ - double f=f0*j; - double diff=Math.abs(getToneChanged(f,f2)%12); - if (diff>6) diff=12-diff; - if (diff<=1) return true; - } - } - } - - return false; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/processor/IntensityProcessor.java b/app/Locabean/src/com/musicg/processor/IntensityProcessor.java deleted file mode 100644 index b5874ee..0000000 --- a/app/Locabean/src/com/musicg/processor/IntensityProcessor.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.musicg.processor; - -public interface IntensityProcessor{ - public void execute(); - public double[][] getIntensities(); -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/processor/ProcessorChain.java b/app/Locabean/src/com/musicg/processor/ProcessorChain.java deleted file mode 100644 index bf44631..0000000 --- a/app/Locabean/src/com/musicg/processor/ProcessorChain.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.musicg.processor; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -public class ProcessorChain{ - - private double[][] intensities; - List processorList=new LinkedList(); - - public ProcessorChain(double[][] intensities){ - this.intensities=intensities; - RobustIntensityProcessor robustProcessor=new RobustIntensityProcessor(intensities,1); - processorList.add(robustProcessor); - process(); - } - - private void process(){ - Iterator iterator=processorList.iterator(); - while(iterator.hasNext()){ - IntensityProcessor processor=iterator.next(); - processor.execute(); - intensities=processor.getIntensities(); - } - } - - public double[][] getIntensities(){ - return intensities; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/processor/RobustIntensityProcessor.java b/app/Locabean/src/com/musicg/processor/RobustIntensityProcessor.java deleted file mode 100644 index d822890..0000000 --- a/app/Locabean/src/com/musicg/processor/RobustIntensityProcessor.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.musicg.processor; - -import com.musicg.math.rank.ArrayRankDouble; - -public class RobustIntensityProcessor implements IntensityProcessor{ - - private double[][] intensities; - private int numPointsPerFrame; - - public RobustIntensityProcessor(double[][] intensities, int numPointsPerFrame){ - this.intensities=intensities; - this.numPointsPerFrame=numPointsPerFrame; - } - - public void execute(){ - - int numX=intensities.length; - int numY=intensities[0].length; - double[][] processedIntensities=new double[numX][numY]; - - for (int i=0; i=passValue){ - processedIntensities[i][j]=intensities[i][j]; - } - } - } - intensities=processedIntensities; - } - - public double[][] getIntensities(){ - return intensities; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/processor/TopManyPointsProcessorChain.java b/app/Locabean/src/com/musicg/processor/TopManyPointsProcessorChain.java deleted file mode 100644 index 37663c3..0000000 --- a/app/Locabean/src/com/musicg/processor/TopManyPointsProcessorChain.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.musicg.processor; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - - -public class TopManyPointsProcessorChain{ - - private double[][] intensities; - List processorList=new LinkedList(); - - public TopManyPointsProcessorChain(double[][] intensities, int numPoints){ - this.intensities=intensities; - RobustIntensityProcessor robustProcessor=new RobustIntensityProcessor(intensities,numPoints); - processorList.add(robustProcessor); - process(); - } - - private void process(){ - Iterator iterator=processorList.iterator(); - while(iterator.hasNext()){ - IntensityProcessor processor=iterator.next(); - processor.execute(); - intensities=processor.getIntensities(); - } - } - - public double[][] getIntensities(){ - return intensities; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/properties/FingerprintProperties.java b/app/Locabean/src/com/musicg/properties/FingerprintProperties.java deleted file mode 100644 index 374cbcd..0000000 --- a/app/Locabean/src/com/musicg/properties/FingerprintProperties.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.properties; - -public class FingerprintProperties{ - - protected static FingerprintProperties instance=null; - - private int numRobustPointsPerFrame=4; // number of points in each frame, i.e. top 4 intensities in fingerprint - private int sampleSizePerFrame=2048; // number of audio samples in a frame, it is suggested to be the FFT Size - private int overlapFactor=4; // 8 means each move 1/8 nSample length. 1 means no overlap, better 1,2,4,8 ... 32 - private int numFilterBanks=4; - - private int upperBoundedFrequency=1500; // low pass - private int lowerBoundedFrequency=400; // high pass - private int fps=5; // in order to have 5fps with 2048 sampleSizePerFrame, wave's sample rate need to be 10240 (sampleSizePerFrame*fps) - private int sampleRate=sampleSizePerFrame*fps; // the audio's sample rate needed to resample to this in order to fit the sampleSizePerFrame and fps - private int numFramesInOneSecond=overlapFactor*fps; // since the overlap factor affects the actual number of fps, so this value is used to evaluate how many frames in one second eventually - - private int refMaxActivePairs=1; // max. active pairs per anchor point for reference songs - private int sampleMaxActivePairs=10; // max. active pairs per anchor point for sample clip - private int numAnchorPointsPerInterval=10; - private int anchorPointsIntervalLength=4; // in frames (5fps,4 overlap per second) - private int maxTargetZoneDistance=4; // in frame (5fps,4 overlap per second) - - private int numFrequencyUnits=(upperBoundedFrequency-lowerBoundedFrequency+1)/fps+1; // num frequency units - - public static FingerprintProperties getInstance(){ - if (instance == null){ - synchronized(FingerprintProperties.class){ - if(instance == null) { - instance = new FingerprintProperties(); - } - } - } - return instance; - } - - public int getNumRobustPointsPerFrame() { - return numRobustPointsPerFrame; - } - - public int getSampleSizePerFrame() { - return sampleSizePerFrame; - } - - public int getOverlapFactor() { - return overlapFactor; - } - - public int getNumFilterBanks() { - return numFilterBanks; - } - - public int getUpperBoundedFrequency() { - return upperBoundedFrequency; - } - - public int getLowerBoundedFrequency() { - return lowerBoundedFrequency; - } - - public int getFps() { - return fps; - } - - public int getRefMaxActivePairs() { - return refMaxActivePairs; - } - - public int getSampleMaxActivePairs() { - return sampleMaxActivePairs; - } - - public int getNumAnchorPointsPerInterval() { - return numAnchorPointsPerInterval; - } - - public int getAnchorPointsIntervalLength() { - return anchorPointsIntervalLength; - } - - public int getMaxTargetZoneDistance() { - return maxTargetZoneDistance; - } - - public int getNumFrequencyUnits() { - return numFrequencyUnits; - } - - public int getMaxPossiblePairHashcode(){ - return maxTargetZoneDistance*numFrequencyUnits*numFrequencyUnits+numFrequencyUnits*numFrequencyUnits+numFrequencyUnits; - } - - public int getSampleRate() { - return sampleRate; - } - - public int getNumFramesInOneSecond() { - return numFramesInOneSecond; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/serialization/ObjectSerializer.java b/app/Locabean/src/com/musicg/serialization/ObjectSerializer.java deleted file mode 100644 index 83964e6..0000000 --- a/app/Locabean/src/com/musicg/serialization/ObjectSerializer.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.musicg.serialization; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -public class ObjectSerializer{ - - public ObjectSerializer(){ - } - - public void dump(Object object, String dumpFile){ - // serialize the object - try { - FileOutputStream fout = new FileOutputStream(dumpFile); - ObjectOutputStream oos = new ObjectOutputStream(fout); - oos.writeObject(object); - oos.close(); - fout.close(); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - public Object load(String dumpFile){ - - Object object=null; - - // load the memory - try { - FileInputStream fin=new FileInputStream(dumpFile); - ObjectInputStream ois=new ObjectInputStream(fin); - object=ois.readObject(); - ois.close(); - fin.close(); - } - catch (Exception e) { - e.printStackTrace(); - } - - return object; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/version/Version.java b/app/Locabean/src/com/musicg/version/Version.java deleted file mode 100644 index 1a640ea..0000000 --- a/app/Locabean/src/com/musicg/version/Version.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.musicg.version; - -public class Version{ - public static final String VERSION="1.4.2.0"; -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/wave/Wave.java b/app/Locabean/src/com/musicg/wave/Wave.java deleted file mode 100644 index 4a01fcf..0000000 --- a/app/Locabean/src/com/musicg/wave/Wave.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.wave; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; - -import com.musicg.fingerprint.FingerprintManager; -import com.musicg.fingerprint.FingerprintSimilarity; -import com.musicg.fingerprint.FingerprintSimilarityComputer; -import com.musicg.wave.extension.NormalizedSampleAmplitudes; -import com.musicg.wave.extension.Spectrogram; - -/** - * Read WAVE headers and data from wave input stream - * - * @author Jacquet Wong - */ -public class Wave implements Serializable { - - private static final long serialVersionUID = 1L; - private WaveHeader waveHeader; - private byte[] data; // little endian - private byte[] fingerprint; - - /** - * Constructor - * - */ - public Wave() { - this.waveHeader = new WaveHeader(); - this.data = new byte[0]; - } - - /** - * Constructor - * - * @param filename - * Wave file - */ - public Wave(String filename) { - try { - InputStream inputStream = new FileInputStream(filename); - initWaveWithInputStream(inputStream); - inputStream.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Constructor - * - * @param inputStream - * Wave file input stream - */ - public Wave(InputStream inputStream) { - initWaveWithInputStream(inputStream); - } - - /** - * Constructor - * - * @param WaveHeader - * waveHeader - * @param byte[] data - */ - public Wave(WaveHeader waveHeader, byte[] data) { - this.waveHeader = waveHeader; - this.data = data; - } - - private void initWaveWithInputStream(InputStream inputStream) { - // reads the first 44 bytes for header - waveHeader = new WaveHeader(inputStream); - - if (waveHeader.isValid()) { - // load data - try { - data = new byte[inputStream.available()]; - inputStream.read(data); - } catch (IOException e) { - e.printStackTrace(); - } - // end load data - } else { - System.err.println("Invalid Wave Header"); - } - } - - /** - * Trim the wave data - * - * @param leftTrimNumberOfSample - * Number of sample trimmed from beginning - * @param rightTrimNumberOfSample - * Number of sample trimmed from ending - */ - public void trim(int leftTrimNumberOfSample, int rightTrimNumberOfSample) { - - long chunkSize = waveHeader.getChunkSize(); - long subChunk2Size = waveHeader.getSubChunk2Size(); - - long totalTrimmed = leftTrimNumberOfSample + rightTrimNumberOfSample; - - if (totalTrimmed > subChunk2Size) { - leftTrimNumberOfSample = (int) subChunk2Size; - } - - // update wav info - chunkSize -= totalTrimmed; - subChunk2Size -= totalTrimmed; - - if (chunkSize >= 0 && subChunk2Size >= 0) { - waveHeader.setChunkSize(chunkSize); - waveHeader.setSubChunk2Size(subChunk2Size); - - byte[] trimmedData = new byte[(int) subChunk2Size]; - System.arraycopy(data, (int) leftTrimNumberOfSample, trimmedData, - 0, (int) subChunk2Size); - data = trimmedData; - } else { - System.err.println("Trim error: Negative length"); - } - } - - /** - * Trim the wave data from beginning - * - * @param numberOfSample - * numberOfSample trimmed from beginning - */ - public void leftTrim(int numberOfSample) { - trim(numberOfSample, 0); - } - - /** - * Trim the wave data from ending - * - * @param numberOfSample - * numberOfSample trimmed from ending - */ - public void rightTrim(int numberOfSample) { - trim(0, numberOfSample); - } - - /** - * Trim the wave data - * - * @param leftTrimSecond - * Seconds trimmed from beginning - * @param rightTrimSecond - * Seconds trimmed from ending - */ - public void trim(double leftTrimSecond, double rightTrimSecond) { - - int sampleRate = waveHeader.getSampleRate(); - int bitsPerSample = waveHeader.getBitsPerSample(); - int channels = waveHeader.getChannels(); - - int leftTrimNumberOfSample = (int) (sampleRate * bitsPerSample / 8 - * channels * leftTrimSecond); - int rightTrimNumberOfSample = (int) (sampleRate * bitsPerSample / 8 - * channels * rightTrimSecond); - - trim(leftTrimNumberOfSample, rightTrimNumberOfSample); - } - - /** - * Trim the wave data from beginning - * - * @param second - * Seconds trimmed from beginning - */ - public void leftTrim(double second) { - trim(second, 0); - } - - /** - * Trim the wave data from ending - * - * @param second - * Seconds trimmed from ending - */ - public void rightTrim(double second) { - trim(0, second); - } - - /** - * Get the wave header - * - * @return waveHeader - */ - public WaveHeader getWaveHeader() { - return waveHeader; - } - - /** - * Get the wave spectrogram - * - * @return spectrogram - */ - public Spectrogram getSpectrogram() { - return new Spectrogram(this); - } - - /** - * Get the wave spectrogram - * - * @param fftSampleSize - * number of sample in fft, the value needed to be a number to - * power of 2 - * @param overlapFactor - * 1/overlapFactor overlapping, e.g. 1/4=25% overlapping, 0 for - * no overlapping - * - * @return spectrogram - */ - public Spectrogram getSpectrogram(int fftSampleSize, int overlapFactor) { - return new Spectrogram(this, fftSampleSize, overlapFactor); - } - - /** - * Get the wave data in bytes - * - * @return wave data - */ - public byte[] getBytes() { - return data; - } - - /** - * Data byte size of the wave excluding header size - * - * @return byte size of the wave - */ - public int size() { - return data.length; - } - - /** - * Length of the wave in second - * - * @return length in second - */ - public float length() { - float second = (float) waveHeader.getSubChunk2Size() - / waveHeader.getByteRate(); - return second; - } - - /** - * Timestamp of the wave length - * - * @return timestamp - */ - public String timestamp() { - float totalSeconds = this.length(); - float second = totalSeconds % 60; - int minute = (int) totalSeconds / 60 % 60; - int hour = (int) (totalSeconds / 3600); - - StringBuffer sb = new StringBuffer(); - if (hour > 0) { - sb.append(hour + ":"); - } - if (minute > 0) { - sb.append(minute + ":"); - } - sb.append(second); - - return sb.toString(); - } - - /** - * Get the amplitudes of the wave samples (depends on the header) - * - * @return amplitudes array (signed 16-bit) - */ - public short[] getSampleAmplitudes() { - int bytePerSample = waveHeader.getBitsPerSample() / 8; - int numSamples = data.length / bytePerSample; - short[] amplitudes = new short[numSamples]; - - int pointer = 0; - for (int i = 0; i < numSamples; i++) { - short amplitude = 0; - for (int byteNumber = 0; byteNumber < bytePerSample; byteNumber++) { - // little endian - amplitude |= (short) ((data[pointer++] & 0xFF) << (byteNumber * 8)); - } - amplitudes[i] = amplitude; - } - - return amplitudes; - } - - public String toString() { - StringBuffer sb = new StringBuffer(waveHeader.toString()); - sb.append("\n"); - sb.append("length: " + timestamp()); - return sb.toString(); - } - - public double[] getNormalizedAmplitudes() { - NormalizedSampleAmplitudes amplitudes = new NormalizedSampleAmplitudes( - this); - return amplitudes.getNormalizedAmplitudes(); - } - - public byte[] getFingerprint() { - if (fingerprint == null) { - FingerprintManager fingerprintManager = new FingerprintManager(); - fingerprint = fingerprintManager.extractFingerprint(this); - } - return fingerprint; - } - - public FingerprintSimilarity getFingerprintSimilarity(Wave wave) { - FingerprintSimilarityComputer fingerprintSimilarityComputer = new FingerprintSimilarityComputer( - this.getFingerprint(), wave.getFingerprint()); - return fingerprintSimilarityComputer.getFingerprintsSimilarity(); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/wave/WaveFileManager.java b/app/Locabean/src/com/musicg/wave/WaveFileManager.java deleted file mode 100644 index 5264c1c..0000000 --- a/app/Locabean/src/com/musicg/wave/WaveFileManager.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.wave; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - - -public class WaveFileManager{ - - private Wave wave; - - public WaveFileManager(){ - wave=new Wave(); - } - - public WaveFileManager(Wave wave){ - setWave(wave); - } - - /** - * Save the wave file - * - * @param filename - * filename to be saved - * - * @see wave file saved - */ - public void saveWaveAsFile(String filename){ - - WaveHeader waveHeader=wave.getWaveHeader(); - - int byteRate = waveHeader.getByteRate(); - int audioFormat = waveHeader.getAudioFormat(); - int sampleRate = waveHeader.getSampleRate(); - int bitsPerSample = waveHeader.getBitsPerSample(); - int channels = waveHeader.getChannels(); - long chunkSize = waveHeader.getChunkSize(); - long subChunk1Size = waveHeader.getSubChunk1Size(); - long subChunk2Size = waveHeader.getSubChunk2Size(); - int blockAlign = waveHeader.getBlockAlign(); - - try { - FileOutputStream fos = new FileOutputStream(filename); - fos.write(WaveHeader.RIFF_HEADER.getBytes()); - // little endian - fos.write(new byte[] { (byte) (chunkSize), (byte) (chunkSize >> 8), - (byte) (chunkSize >> 16), (byte) (chunkSize >> 24) }); - fos.write(WaveHeader.WAVE_HEADER.getBytes()); - fos.write(WaveHeader.FMT_HEADER.getBytes()); - fos.write(new byte[] { (byte) (subChunk1Size), - (byte) (subChunk1Size >> 8), (byte) (subChunk1Size >> 16), - (byte) (subChunk1Size >> 24) }); - fos.write(new byte[] { (byte) (audioFormat), - (byte) (audioFormat >> 8) }); - fos.write(new byte[] { (byte) (channels), (byte) (channels >> 8) }); - fos.write(new byte[] { (byte) (sampleRate), - (byte) (sampleRate >> 8), (byte) (sampleRate >> 16), - (byte) (sampleRate >> 24) }); - fos.write(new byte[] { (byte) (byteRate), (byte) (byteRate >> 8), - (byte) (byteRate >> 16), (byte) (byteRate >> 24) }); - fos.write(new byte[] { (byte) (blockAlign), - (byte) (blockAlign >> 8) }); - fos.write(new byte[] { (byte) (bitsPerSample), - (byte) (bitsPerSample >> 8) }); - fos.write(WaveHeader.DATA_HEADER.getBytes()); - fos.write(new byte[] { (byte) (subChunk2Size), - (byte) (subChunk2Size >> 8), (byte) (subChunk2Size >> 16), - (byte) (subChunk2Size >> 24) }); - fos.write(wave.getBytes()); - fos.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public Wave getWave() { - return wave; - } - - public void setWave(Wave wave) { - this.wave = wave; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/wave/WaveHeader.java b/app/Locabean/src/com/musicg/wave/WaveHeader.java deleted file mode 100644 index 982cd78..0000000 --- a/app/Locabean/src/com/musicg/wave/WaveHeader.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.wave; - -import java.io.IOException; -import java.io.InputStream; - -/** - * WAV File Specification - * https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - * - * @author Jacquet Wong - */ -public class WaveHeader { - - public static final String RIFF_HEADER = "RIFF"; - public static final String WAVE_HEADER = "WAVE"; - public static final String FMT_HEADER = "fmt "; - public static final String DATA_HEADER = "data"; - public static final int HEADER_BYTE_LENGTH = 44; // 44 bytes for header - - private boolean valid; - private String chunkId; // 4 bytes - private long chunkSize; // unsigned 4 bytes, little endian - private String format; // 4 bytes - private String subChunk1Id; // 4 bytes - private long subChunk1Size; // unsigned 4 bytes, little endian - private int audioFormat; // unsigned 2 bytes, little endian - private int channels; // unsigned 2 bytes, little endian - private long sampleRate; // unsigned 4 bytes, little endian - private long byteRate; // unsigned 4 bytes, little endian - private int blockAlign; // unsigned 2 bytes, little endian - private int bitsPerSample; // unsigned 2 bytes, little endian - private String subChunk2Id; // 4 bytes - private long subChunk2Size; // unsigned 4 bytes, little endian - - public WaveHeader(){ - // init a 8k 16bit mono wav - chunkSize=36; - subChunk1Size=16; - audioFormat=1; - channels=1; - sampleRate=8000; - byteRate=16000; - blockAlign=2; - bitsPerSample=16; - subChunk2Size=0; - valid=true; - } - - public WaveHeader(InputStream inputStream) { - valid = loadHeader(inputStream); - } - - private boolean loadHeader(InputStream inputStream) { - - byte[] headerBuffer = new byte[HEADER_BYTE_LENGTH]; - try { - inputStream.read(headerBuffer); - - // read header - int pointer = 0; - chunkId = new String(new byte[] { headerBuffer[pointer++], - headerBuffer[pointer++], headerBuffer[pointer++], - headerBuffer[pointer++] }); - // little endian - chunkSize = (long) (headerBuffer[pointer++] & 0xff) - | (long) (headerBuffer[pointer++] & 0xff) << 8 - | (long) (headerBuffer[pointer++] & 0xff) << 16 - | (long) (headerBuffer[pointer++] & 0xff << 24); - format = new String(new byte[] { headerBuffer[pointer++], - headerBuffer[pointer++], headerBuffer[pointer++], - headerBuffer[pointer++] }); - subChunk1Id = new String(new byte[] { headerBuffer[pointer++], - headerBuffer[pointer++], headerBuffer[pointer++], - headerBuffer[pointer++] }); - subChunk1Size = (long) (headerBuffer[pointer++] & 0xff) - | (long) (headerBuffer[pointer++] & 0xff) << 8 - | (long) (headerBuffer[pointer++] & 0xff) << 16 - | (long) (headerBuffer[pointer++] & 0xff) << 24; - audioFormat = (int) ((headerBuffer[pointer++] & 0xff) | (headerBuffer[pointer++] & 0xff) << 8); - channels = (int) ((headerBuffer[pointer++] & 0xff) | (headerBuffer[pointer++] & 0xff) << 8); - sampleRate = (long) (headerBuffer[pointer++] & 0xff) - | (long) (headerBuffer[pointer++] & 0xff) << 8 - | (long) (headerBuffer[pointer++] & 0xff) << 16 - | (long) (headerBuffer[pointer++] & 0xff) << 24; - byteRate = (long) (headerBuffer[pointer++] & 0xff) - | (long) (headerBuffer[pointer++] & 0xff) << 8 - | (long) (headerBuffer[pointer++] & 0xff) << 16 - | (long) (headerBuffer[pointer++] & 0xff) << 24; - blockAlign = (int) ((headerBuffer[pointer++] & 0xff) | (headerBuffer[pointer++] & 0xff) << 8); - bitsPerSample = (int) ((headerBuffer[pointer++] & 0xff) | (headerBuffer[pointer++] & 0xff) << 8); - subChunk2Id = new String(new byte[] { headerBuffer[pointer++], - headerBuffer[pointer++], headerBuffer[pointer++], - headerBuffer[pointer++] }); - subChunk2Size = (long) (headerBuffer[pointer++] & 0xff) - | (long) (headerBuffer[pointer++] & 0xff) << 8 - | (long) (headerBuffer[pointer++] & 0xff) << 16 - | (long) (headerBuffer[pointer++] & 0xff) << 24; - // end read header - - // the inputStream should be closed outside this method - - // dis.close(); - - } catch (IOException e) { - e.printStackTrace(); - return false; - } - - if (bitsPerSample!=8 && bitsPerSample!=16){ - System.err.println("WaveHeader: only supports bitsPerSample 8 or 16"); - return false; - } - - // check the format is support - if (chunkId.toUpperCase().equals(RIFF_HEADER) - && format.toUpperCase().equals(WAVE_HEADER) && audioFormat == 1) { - return true; - } - else{ - System.err.println("WaveHeader: Unsupported header format"); - } - - return false; - } - - public boolean isValid() { - return valid; - } - - public String getChunkId() { - return chunkId; - } - - public long getChunkSize() { - return chunkSize; - } - - public String getFormat() { - return format; - } - - public String getSubChunk1Id() { - return subChunk1Id; - } - - public long getSubChunk1Size() { - return subChunk1Size; - } - - public int getAudioFormat() { - return audioFormat; - } - - public int getChannels() { - return channels; - } - - public int getSampleRate() { - return (int) sampleRate; - } - - public int getByteRate() { - return (int) byteRate; - } - - public int getBlockAlign() { - return blockAlign; - } - - public int getBitsPerSample() { - return bitsPerSample; - } - - public String getSubChunk2Id() { - return subChunk2Id; - } - - public long getSubChunk2Size() { - return subChunk2Size; - } - - public void setSampleRate(int sampleRate){ - int newSubChunk2Size = (int)(this.subChunk2Size * sampleRate / this.sampleRate); - // if num bytes for each sample is even, the size of newSubChunk2Size also needed to be in even number - if ((bitsPerSample/8)%2==0){ - if (newSubChunk2Size%2!=0){ - newSubChunk2Size++; - } - } - - this.sampleRate = sampleRate; - this.byteRate = sampleRate*bitsPerSample/8; - this.chunkSize = newSubChunk2Size+36; - this.subChunk2Size = newSubChunk2Size; - } - - public void setChunkId(String chunkId) { - this.chunkId = chunkId; - } - - public void setChunkSize(long chunkSize) { - this.chunkSize = chunkSize; - } - - public void setFormat(String format) { - this.format = format; - } - - public void setSubChunk1Id(String subChunk1Id) { - this.subChunk1Id = subChunk1Id; - } - - public void setSubChunk1Size(long subChunk1Size) { - this.subChunk1Size = subChunk1Size; - } - - public void setAudioFormat(int audioFormat) { - this.audioFormat = audioFormat; - } - - public void setChannels(int channels) { - this.channels = channels; - } - - public void setByteRate(long byteRate) { - this.byteRate = byteRate; - } - - public void setBlockAlign(int blockAlign) { - this.blockAlign = blockAlign; - } - - public void setBitsPerSample(int bitsPerSample) { - this.bitsPerSample = bitsPerSample; - } - - public void setSubChunk2Id(String subChunk2Id) { - this.subChunk2Id = subChunk2Id; - } - - public void setSubChunk2Size(long subChunk2Size) { - this.subChunk2Size = subChunk2Size; - } - - public String toString() { - - StringBuffer sb = new StringBuffer(); - sb.append("chunkId: " + chunkId); - sb.append("\n"); - sb.append("chunkSize: " + chunkSize); - sb.append("\n"); - sb.append("format: " + format); - sb.append("\n"); - sb.append("subChunk1Id: " + subChunk1Id); - sb.append("\n"); - sb.append("subChunk1Size: " + subChunk1Size); - sb.append("\n"); - sb.append("audioFormat: " + audioFormat); - sb.append("\n"); - sb.append("channels: " + channels); - sb.append("\n"); - sb.append("sampleRate: " + sampleRate); - sb.append("\n"); - sb.append("byteRate: " + byteRate); - sb.append("\n"); - sb.append("blockAlign: " + blockAlign); - sb.append("\n"); - sb.append("bitsPerSample: " + bitsPerSample); - sb.append("\n"); - sb.append("subChunk2Id: " + subChunk2Id); - sb.append("\n"); - sb.append("subChunk2Size: " + subChunk2Size); - return sb.toString(); - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/wave/WaveTypeDetector.java b/app/Locabean/src/com/musicg/wave/WaveTypeDetector.java deleted file mode 100644 index d68612d..0000000 --- a/app/Locabean/src/com/musicg/wave/WaveTypeDetector.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.musicg.wave; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.ArrayList; - -import com.musicg.api.WhistleApi; - -public class WaveTypeDetector { - - private Wave wave; - - public WaveTypeDetector(Wave wave) { - this.wave = wave; - } - - public double getWhistleProbability() { - - double probability = 0; - - WaveHeader wavHeader = wave.getWaveHeader(); - - // fft size 1024, no overlap - int fftSampleSize = 1024; - int fftSignalByteLength = fftSampleSize * wavHeader.getBitsPerSample() / 8; - byte[] audioBytes = wave.getBytes(); - ByteArrayInputStream inputStream = new ByteArrayInputStream(audioBytes); - - WhistleApi whistleApi = new WhistleApi(wavHeader); - - // read the byte signals - try { - int numFrames = inputStream.available() / fftSignalByteLength; - byte[] bytes = new byte[fftSignalByteLength]; - int checkLength = 3; - int passScore = 3; - - ArrayList bufferList = new ArrayList(); - int numWhistles = 0; - int numPasses = 0; - - // first 10(checkLength) frames - for (int frameNumber = 0; frameNumber < checkLength; frameNumber++) { - inputStream.read(bytes); - boolean isWhistle = whistleApi.isWhistle(bytes); - bufferList.add(isWhistle); - if (isWhistle) { - numWhistles++; - } - if (numWhistles >= passScore) { - numPasses++; - } - // System.out.println(frameNumber+": "+numWhistles); - } - - // other frames - for (int frameNumber = checkLength; frameNumber < numFrames; frameNumber++) { - inputStream.read(bytes); - boolean isWhistle = whistleApi.isWhistle(bytes); - if (bufferList.get(0)) { - numWhistles--; - } - bufferList.remove(0); - bufferList.add(isWhistle); - - if (isWhistle) { - numWhistles++; - } - if (numWhistles >= passScore) { - numPasses++; - } - // System.out.println(frameNumber+": "+numWhistles); - } - probability = (double) numPasses / numFrames; - - } catch (IOException e) { - e.printStackTrace(); - } - - return probability; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/wave/extension/NormalizedSampleAmplitudes.java b/app/Locabean/src/com/musicg/wave/extension/NormalizedSampleAmplitudes.java deleted file mode 100644 index d4fabd7..0000000 --- a/app/Locabean/src/com/musicg/wave/extension/NormalizedSampleAmplitudes.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.wave.extension; - -import com.musicg.wave.Wave; - -/** - * Handles the wave data in amplitude-time domain. - * - * @author Jacquet Wong - */ -public class NormalizedSampleAmplitudes{ - - private Wave wave; - private double[] normalizedAmplitudes; // normalizedAmplitudes[sampleNumber]=normalizedAmplitudeInTheFrame - - public NormalizedSampleAmplitudes(Wave wave){ - this.wave=wave; - } - - /** - * - * Get normalized amplitude of each frame - * - * @return array of normalized amplitudes(signed 16 bit): normalizedAmplitudes[frame]=amplitude - */ - public double[] getNormalizedAmplitudes() { - - if (normalizedAmplitudes == null) { - - boolean signed=true; - - // usually 8bit is unsigned - if (wave.getWaveHeader().getBitsPerSample()==8){ - signed=false; - } - - short[] amplitudes=wave.getSampleAmplitudes(); - int numSamples = amplitudes.length; - int maxAmplitude = 1 << (wave.getWaveHeader().getBitsPerSample() - 1); - - if (!signed){ // one more bit for unsigned value - maxAmplitude<<=1; - } - - normalizedAmplitudes = new double[numSamples]; - for (int i = 0; i < numSamples; i++) { - normalizedAmplitudes[i] = (double) amplitudes[i] / maxAmplitude; - } - } - return normalizedAmplitudes; - } -} \ No newline at end of file diff --git a/app/Locabean/src/com/musicg/wave/extension/Spectrogram.java b/app/Locabean/src/com/musicg/wave/extension/Spectrogram.java deleted file mode 100644 index a4d1b5a..0000000 --- a/app/Locabean/src/com/musicg/wave/extension/Spectrogram.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2011 Jacquet Wong - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.musicg.wave.extension; - -import com.musicg.dsp.FastFourierTransform; -import com.musicg.dsp.WindowFunction; -import com.musicg.wave.Wave; - -/** - * Handles the wave data in frequency-time domain. - * - * @author Jacquet Wong - */ -public class Spectrogram{ - - public static final int SPECTROGRAM_DEFAULT_FFT_SAMPLE_SIZE = 1024; - public static final int SPECTROGRAM_DEFAULT_OVERLAP_FACTOR = 0; // 0 for no overlapping - - private Wave wave; - private double[][] spectrogram; // relative spectrogram - private double[][] absoluteSpectrogram; // absolute spectrogram - private int fftSampleSize; // number of sample in fft, the value needed to be a number to power of 2 - private int overlapFactor; // 1/overlapFactor overlapping, e.g. 1/4=25% overlapping - private int numFrames; // number of frames of the spectrogram - private int framesPerSecond; // frame per second of the spectrogram - private int numFrequencyUnit; // number of y-axis unit - private double unitFrequency; // frequency per y-axis unit - - /** - * Constructor - * - * @param wave - */ - public Spectrogram(Wave wave) { - this.wave=wave; - // default - this.fftSampleSize=SPECTROGRAM_DEFAULT_FFT_SAMPLE_SIZE; - this.overlapFactor=SPECTROGRAM_DEFAULT_OVERLAP_FACTOR; - buildSpectrogram(); - } - - /** - * Constructor - * - * @param wave - * @param fftSampleSize number of sample in fft, the value needed to be a number to power of 2 - * @param overlapFactor 1/overlapFactor overlapping, e.g. 1/4=25% overlapping, 0 for no overlapping - */ - public Spectrogram(Wave wave, int fftSampleSize, int overlapFactor) { - this.wave=wave; - - if (Integer.bitCount(fftSampleSize)==1){ - this.fftSampleSize=fftSampleSize; - } - else{ - System.err.print("The input number must be a power of 2"); - this.fftSampleSize=SPECTROGRAM_DEFAULT_FFT_SAMPLE_SIZE; - } - - this.overlapFactor=overlapFactor; - - buildSpectrogram(); - } - - /** - * Build spectrogram - */ - private void buildSpectrogram(){ - - short[] amplitudes=wave.getSampleAmplitudes(); - int numSamples = amplitudes.length; - - int pointer=0; - // overlapping - if (overlapFactor>1){ - int numOverlappedSamples=numSamples*overlapFactor; - int backSamples=fftSampleSize*(overlapFactor-1)/overlapFactor; - int fftSampleSize_1=fftSampleSize-1; - short[] overlapAmp= new short[numOverlappedSamples]; - pointer=0; - for (int i=0; i0){ - - numFrequencyUnit=absoluteSpectrogram[0].length; - unitFrequency=(double)wave.getWaveHeader().getSampleRate()/2/numFrequencyUnit; // frequency could be caught within the half of nSamples according to Nyquist theory - - // normalization of absoultSpectrogram - spectrogram=new double[numFrames][numFrequencyUnit]; - - // set max and min amplitudes - double maxAmp=Double.MIN_VALUE; - double minAmp=Double.MAX_VALUE; - for (int i=0; imaxAmp){ - maxAmp=absoluteSpectrogram[i][j]; - } - else if(absoluteSpectrogram[i][j]> 1); - double wfr = Math.cos(arg); - double wfi = sign * Math.sin(arg); - - for (int j = 0; j < jmax; j += 2) { - warray[w_index++] = wr; - warray[w_index++] = wi; - - double tempr = wr; - wr = tempr * wfr - wi * wfi; - wi = tempr * wfi + wi * wfr; - } - } - - // PRECOMPUTATION of wwr1, wwi1 for factor 4 Decomposition (3 * complex - // operators and 8 +/- complex operators) - { - w_index = 0; - int w_index2 = warray.length >> 1; - for (int i = 0, nstep = 2; i < (imax - 1); i++) { - int jmax = nstep; - nstep *= 2; - - int ii = w_index + jmax; - for (int j = 0; j < jmax; j += 2) { - double wr = warray[w_index++]; - double wi = warray[w_index++]; - double wr1 = warray[ii++]; - double wi1 = warray[ii++]; - warray[w_index2++] = wr * wr1 - wi * wi1; - warray[w_index2++] = wr * wi1 + wi * wr1; - } - } - - } - - return warray; - } - - private final static void calc(int fftFrameSize, double[] data, int sign, - double[] w) { - - final int fftFrameSize2 = fftFrameSize << 1; - - int nstep = 2; - - if (nstep >= fftFrameSize2) - return; - int i = nstep - 2; - if (sign == -1) - calcF4F(fftFrameSize, data, i, nstep, w); - else - calcF4I(fftFrameSize, data, i, nstep, w); - - } - - private final static void calcF2E(int fftFrameSize, double[] data, int i, - int nstep, double[] w) { - int jmax = nstep; - for (int n = 0; n < jmax; n += 2) { - double wr = w[i++]; - double wi = w[i++]; - int m = n + jmax; - double datam_r = data[m]; - double datam_i = data[m + 1]; - double datan_r = data[n]; - double datan_i = data[n + 1]; - double tempr = datam_r * wr - datam_i * wi; - double tempi = datam_r * wi + datam_i * wr; - data[m] = datan_r - tempr; - data[m + 1] = datan_i - tempi; - data[n] = datan_r + tempr; - data[n + 1] = datan_i + tempi; - } - return; - - } - - // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- - // complex operators - private final static void calcF4F(int fftFrameSize, double[] data, int i, - int nstep, double[] w) { - final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; - // Factor-4 Decomposition - - int w_len = w.length >> 1; - while (nstep < fftFrameSize2) { - - if (nstep << 2 == fftFrameSize2) { - // Goto Factor-4 Final Decomposition - // calcF4E(data, i, nstep, -1, w); - calcF4FE(fftFrameSize, data, i, nstep, w); - return; - } - int jmax = nstep; - int nnstep = nstep << 1; - if (nnstep == fftFrameSize2) { - // Factor-4 Decomposition not possible - calcF2E(fftFrameSize, data, i, nstep, w); - return; - } - nstep <<= 2; - int ii = i + jmax; - int iii = i + w_len; - - { - i += 2; - ii += 2; - iii += 2; - - for (int n = 0; n < fftFrameSize2; n += nstep) { - int m = n + jmax; - - double datam1_r = data[m]; - double datam1_i = data[m + 1]; - double datan1_r = data[n]; - double datan1_i = data[n + 1]; - - n += nnstep; - m += nnstep; - double datam2_r = data[m]; - double datam2_i = data[m + 1]; - double datan2_r = data[n]; - double datan2_i = data[n + 1]; - - double tempr = datam1_r; - double tempi = datam1_i; - - datam1_r = datan1_r - tempr; - datam1_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - double n2w1r = datan2_r; - double n2w1i = datan2_i; - double m2ww1r = datam2_r; - double m2ww1i = datam2_i; - - tempr = m2ww1r - n2w1r; - tempi = m2ww1i - n2w1i; - - datam2_r = datam1_r + tempi; - datam2_i = datam1_i - tempr; - datam1_r = datam1_r - tempi; - datam1_i = datam1_i + tempr; - - tempr = n2w1r + m2ww1r; - tempi = n2w1i + m2ww1i; - - datan2_r = datan1_r - tempr; - datan2_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - data[m] = datam2_r; - data[m + 1] = datam2_i; - data[n] = datan2_r; - data[n + 1] = datan2_i; - - n -= nnstep; - m -= nnstep; - data[m] = datam1_r; - data[m + 1] = datam1_i; - data[n] = datan1_r; - data[n + 1] = datan1_i; - - } - } - - for (int j = 2; j < jmax; j += 2) { - double wr = w[i++]; - double wi = w[i++]; - double wr1 = w[ii++]; - double wi1 = w[ii++]; - double wwr1 = w[iii++]; - double wwi1 = w[iii++]; - // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be - // precomputed!!! - // double wwi1 = wr * wi1 + wi * wr1; - - for (int n = j; n < fftFrameSize2; n += nstep) { - int m = n + jmax; - - double datam1_r = data[m]; - double datam1_i = data[m + 1]; - double datan1_r = data[n]; - double datan1_i = data[n + 1]; - - n += nnstep; - m += nnstep; - double datam2_r = data[m]; - double datam2_i = data[m + 1]; - double datan2_r = data[n]; - double datan2_i = data[n + 1]; - - double tempr = datam1_r * wr - datam1_i * wi; - double tempi = datam1_r * wi + datam1_i * wr; - - datam1_r = datan1_r - tempr; - datam1_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - double n2w1r = datan2_r * wr1 - datan2_i * wi1; - double n2w1i = datan2_r * wi1 + datan2_i * wr1; - double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; - double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; - - tempr = m2ww1r - n2w1r; - tempi = m2ww1i - n2w1i; - - datam2_r = datam1_r + tempi; - datam2_i = datam1_i - tempr; - datam1_r = datam1_r - tempi; - datam1_i = datam1_i + tempr; - - tempr = n2w1r + m2ww1r; - tempi = n2w1i + m2ww1i; - - datan2_r = datan1_r - tempr; - datan2_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - data[m] = datam2_r; - data[m + 1] = datam2_i; - data[n] = datan2_r; - data[n + 1] = datan2_i; - - n -= nnstep; - m -= nnstep; - data[m] = datam1_r; - data[m + 1] = datam1_i; - data[n] = datan1_r; - data[n + 1] = datan1_i; - } - } - - i += jmax << 1; - - } - - calcF2E(fftFrameSize, data, i, nstep, w); - - } - - // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- - // complex operators - private final static void calcF4I(int fftFrameSize, double[] data, int i, - int nstep, double[] w) { - final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; - // Factor-4 Decomposition - - int w_len = w.length >> 1; - while (nstep < fftFrameSize2) { - - if (nstep << 2 == fftFrameSize2) { - // Goto Factor-4 Final Decomposition - // calcF4E(data, i, nstep, 1, w); - calcF4IE(fftFrameSize, data, i, nstep, w); - return; - } - int jmax = nstep; - int nnstep = nstep << 1; - if (nnstep == fftFrameSize2) { - // Factor-4 Decomposition not possible - calcF2E(fftFrameSize, data, i, nstep, w); - return; - } - nstep <<= 2; - int ii = i + jmax; - int iii = i + w_len; - { - i += 2; - ii += 2; - iii += 2; - - for (int n = 0; n < fftFrameSize2; n += nstep) { - int m = n + jmax; - - double datam1_r = data[m]; - double datam1_i = data[m + 1]; - double datan1_r = data[n]; - double datan1_i = data[n + 1]; - - n += nnstep; - m += nnstep; - double datam2_r = data[m]; - double datam2_i = data[m + 1]; - double datan2_r = data[n]; - double datan2_i = data[n + 1]; - - double tempr = datam1_r; - double tempi = datam1_i; - - datam1_r = datan1_r - tempr; - datam1_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - double n2w1r = datan2_r; - double n2w1i = datan2_i; - double m2ww1r = datam2_r; - double m2ww1i = datam2_i; - - tempr = n2w1r - m2ww1r; - tempi = n2w1i - m2ww1i; - - datam2_r = datam1_r + tempi; - datam2_i = datam1_i - tempr; - datam1_r = datam1_r - tempi; - datam1_i = datam1_i + tempr; - - tempr = n2w1r + m2ww1r; - tempi = n2w1i + m2ww1i; - - datan2_r = datan1_r - tempr; - datan2_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - data[m] = datam2_r; - data[m + 1] = datam2_i; - data[n] = datan2_r; - data[n + 1] = datan2_i; - - n -= nnstep; - m -= nnstep; - data[m] = datam1_r; - data[m + 1] = datam1_i; - data[n] = datan1_r; - data[n + 1] = datan1_i; - - } - - } - for (int j = 2; j < jmax; j += 2) { - double wr = w[i++]; - double wi = w[i++]; - double wr1 = w[ii++]; - double wi1 = w[ii++]; - double wwr1 = w[iii++]; - double wwi1 = w[iii++]; - // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be - // precomputed!!! - // double wwi1 = wr * wi1 + wi * wr1; - - for (int n = j; n < fftFrameSize2; n += nstep) { - int m = n + jmax; - - double datam1_r = data[m]; - double datam1_i = data[m + 1]; - double datan1_r = data[n]; - double datan1_i = data[n + 1]; - - n += nnstep; - m += nnstep; - double datam2_r = data[m]; - double datam2_i = data[m + 1]; - double datan2_r = data[n]; - double datan2_i = data[n + 1]; - - double tempr = datam1_r * wr - datam1_i * wi; - double tempi = datam1_r * wi + datam1_i * wr; - - datam1_r = datan1_r - tempr; - datam1_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - double n2w1r = datan2_r * wr1 - datan2_i * wi1; - double n2w1i = datan2_r * wi1 + datan2_i * wr1; - double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; - double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; - - tempr = n2w1r - m2ww1r; - tempi = n2w1i - m2ww1i; - - datam2_r = datam1_r + tempi; - datam2_i = datam1_i - tempr; - datam1_r = datam1_r - tempi; - datam1_i = datam1_i + tempr; - - tempr = n2w1r + m2ww1r; - tempi = n2w1i + m2ww1i; - - datan2_r = datan1_r - tempr; - datan2_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - data[m] = datam2_r; - data[m + 1] = datam2_i; - data[n] = datan2_r; - data[n + 1] = datan2_i; - - n -= nnstep; - m -= nnstep; - data[m] = datam1_r; - data[m + 1] = datam1_i; - data[n] = datan1_r; - data[n + 1] = datan1_i; - - } - } - - i += jmax << 1; - - } - - calcF2E(fftFrameSize, data, i, nstep, w); - - } - - // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- - // complex operators - private final static void calcF4FE(int fftFrameSize, double[] data, int i, - int nstep, double[] w) { - final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; - // Factor-4 Decomposition - - int w_len = w.length >> 1; - while (nstep < fftFrameSize2) { - - int jmax = nstep; - int nnstep = nstep << 1; - if (nnstep == fftFrameSize2) { - // Factor-4 Decomposition not possible - calcF2E(fftFrameSize, data, i, nstep, w); - return; - } - nstep <<= 2; - int ii = i + jmax; - int iii = i + w_len; - for (int n = 0; n < jmax; n += 2) { - double wr = w[i++]; - double wi = w[i++]; - double wr1 = w[ii++]; - double wi1 = w[ii++]; - double wwr1 = w[iii++]; - double wwi1 = w[iii++]; - // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be - // precomputed!!! - // double wwi1 = wr * wi1 + wi * wr1; - - int m = n + jmax; - - double datam1_r = data[m]; - double datam1_i = data[m + 1]; - double datan1_r = data[n]; - double datan1_i = data[n + 1]; - - n += nnstep; - m += nnstep; - double datam2_r = data[m]; - double datam2_i = data[m + 1]; - double datan2_r = data[n]; - double datan2_i = data[n + 1]; - - double tempr = datam1_r * wr - datam1_i * wi; - double tempi = datam1_r * wi + datam1_i * wr; - - datam1_r = datan1_r - tempr; - datam1_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - double n2w1r = datan2_r * wr1 - datan2_i * wi1; - double n2w1i = datan2_r * wi1 + datan2_i * wr1; - double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; - double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; - - tempr = m2ww1r - n2w1r; - tempi = m2ww1i - n2w1i; - - datam2_r = datam1_r + tempi; - datam2_i = datam1_i - tempr; - datam1_r = datam1_r - tempi; - datam1_i = datam1_i + tempr; - - tempr = n2w1r + m2ww1r; - tempi = n2w1i + m2ww1i; - - datan2_r = datan1_r - tempr; - datan2_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - data[m] = datam2_r; - data[m + 1] = datam2_i; - data[n] = datan2_r; - data[n + 1] = datan2_i; - - n -= nnstep; - m -= nnstep; - data[m] = datam1_r; - data[m + 1] = datam1_i; - data[n] = datan1_r; - data[n + 1] = datan1_i; - - } - - i += jmax << 1; - - } - - } - - // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- - // complex operators - private final static void calcF4IE(int fftFrameSize, double[] data, int i, - int nstep, double[] w) { - final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; - // Factor-4 Decomposition - - int w_len = w.length >> 1; - while (nstep < fftFrameSize2) { - - int jmax = nstep; - int nnstep = nstep << 1; - if (nnstep == fftFrameSize2) { - // Factor-4 Decomposition not possible - calcF2E(fftFrameSize, data, i, nstep, w); - return; - } - nstep <<= 2; - int ii = i + jmax; - int iii = i + w_len; - for (int n = 0; n < jmax; n += 2) { - double wr = w[i++]; - double wi = w[i++]; - double wr1 = w[ii++]; - double wi1 = w[ii++]; - double wwr1 = w[iii++]; - double wwi1 = w[iii++]; - // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be - // precomputed!!! - // double wwi1 = wr * wi1 + wi * wr1; - - int m = n + jmax; - - double datam1_r = data[m]; - double datam1_i = data[m + 1]; - double datan1_r = data[n]; - double datan1_i = data[n + 1]; - - n += nnstep; - m += nnstep; - double datam2_r = data[m]; - double datam2_i = data[m + 1]; - double datan2_r = data[n]; - double datan2_i = data[n + 1]; - - double tempr = datam1_r * wr - datam1_i * wi; - double tempi = datam1_r * wi + datam1_i * wr; - - datam1_r = datan1_r - tempr; - datam1_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - double n2w1r = datan2_r * wr1 - datan2_i * wi1; - double n2w1i = datan2_r * wi1 + datan2_i * wr1; - double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1; - double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1; - - tempr = n2w1r - m2ww1r; - tempi = n2w1i - m2ww1i; - - datam2_r = datam1_r + tempi; - datam2_i = datam1_i - tempr; - datam1_r = datam1_r - tempi; - datam1_i = datam1_i + tempr; - - tempr = n2w1r + m2ww1r; - tempi = n2w1i + m2ww1i; - - datan2_r = datan1_r - tempr; - datan2_i = datan1_i - tempi; - datan1_r = datan1_r + tempr; - datan1_i = datan1_i + tempi; - - data[m] = datam2_r; - data[m + 1] = datam2_i; - data[n] = datan2_r; - data[n + 1] = datan2_i; - - n -= nnstep; - m -= nnstep; - data[m] = datam1_r; - data[m + 1] = datam1_i; - data[n] = datan1_r; - data[n + 1] = datan1_i; - - } - - i += jmax << 1; - - } - - } - - private final void bitreversal(double[] data) { - if (fftFrameSize < 4) - return; - - int inverse = fftFrameSize2 - 2; - for (int i = 0; i < fftFrameSize; i += 4) { - int j = bitm_array[i]; - - // Performing Bit-Reversal, even v.s. even, O(2N) - if (i < j) { - - int n = i; - int m = j; - - // COMPLEX: SWAP(data[n], data[m]) - // Real Part - double tempr = data[n]; - data[n] = data[m]; - data[m] = tempr; - // Imagery Part - n++; - m++; - double tempi = data[n]; - data[n] = data[m]; - data[m] = tempi; - - n = inverse - i; - m = inverse - j; - - // COMPLEX: SWAP(data[n], data[m]) - // Real Part - tempr = data[n]; - data[n] = data[m]; - data[m] = tempr; - // Imagery Part - n++; - m++; - tempi = data[n]; - data[n] = data[m]; - data[m] = tempi; - } - - // Performing Bit-Reversal, odd v.s. even, O(N) - - int m = j + fftFrameSize; // bitm_array[i+2]; - // COMPLEX: SWAP(data[n], data[m]) - // Real Part - int n = i + 2; - double tempr = data[n]; - data[n] = data[m]; - data[m] = tempr; - // Imagery Part - n++; - m++; - double tempi = data[n]; - data[n] = data[m]; - data[m] = tempi; - } - - } -} \ No newline at end of file