added SampleBuffer, added Spectrum to AudioProcessing

This commit is contained in:
Raybz@Raybz 2013-06-13 07:59:57 +02:00
parent d155041e52
commit 02afe42cd9
3 changed files with 83 additions and 19 deletions

View File

@ -26,24 +26,26 @@ import java.util.List;
import org.wyrez.audio.analysis.FFT; import org.wyrez.audio.analysis.FFT;
import org.wyrez.audio.decoder.Decoder; import org.wyrez.audio.decoder.Decoder;
import org.wyrez.audio.util.Band; import org.wyrez.audio.util.Band;
import org.wyrez.audio.util.SampleBuffer;
import org.wyrez.audio.util.SampleHelper; import org.wyrez.audio.util.SampleHelper;
/** /**
* Processor to create analysis-data of audio samples *Processor to create analysis-data of audio samples
* *
* @author Darth Affe * @author Darth Affe
*/ */
public class AudioProcessor { public class AudioProcessor {
private Band band; private Band band;
private int bufferSize; private int bufferSize;
private final float[] samples; private SampleBuffer sampleBuffer;
private float[] spectrum;
private float[] spectralFlux; private float[] spectralFlux;
private float[] threshold; private float[] threshold;
private float[] prunedSpectralFlux; private float[] prunedSpectralFlux;
private float[] peaks; private float[] peaks;
private float peakAverage; private float peakAverage;
private final float samplingRate; private float samplingRate;
private float bpm; private float bpm;
/** /**
@ -52,8 +54,7 @@ public class AudioProcessor {
* @param decoder The decoder to process * @param decoder The decoder to process
*/ */
public AudioProcessor(Decoder decoder) { public AudioProcessor(Decoder decoder) {
this.samples = SampleHelper.readAllSamples(decoder); this(SampleHelper.createSampleBuffer(decoder));
this.samplingRate = decoder.getSamplingRate();
} }
/** /**
@ -64,8 +65,16 @@ public class AudioProcessor {
* @param band The band to process * @param band The band to process
*/ */
public AudioProcessor(Decoder decoder, Band band) { public AudioProcessor(Decoder decoder, Band band) {
this.samples = SampleHelper.readAllSamples(decoder); this(SampleHelper.createSampleBuffer(decoder), band);
this.samplingRate = decoder.getSamplingRate(); }
public AudioProcessor(SampleBuffer sampleBuffer) {
this(sampleBuffer, null);
}
public AudioProcessor(SampleBuffer sampleBuffer, Band band) {
this.sampleBuffer = sampleBuffer;
this.samplingRate = sampleBuffer.samplingRate;
this.band = band; this.band = band;
} }
@ -73,6 +82,7 @@ public class AudioProcessor {
* Removes cached objects to save some memory. * Removes cached objects to save some memory.
*/ */
public void clean() { public void clean() {
spectrum = null;
spectralFlux = null; spectralFlux = null;
threshold = null; threshold = null;
prunedSpectralFlux = null; prunedSpectralFlux = null;
@ -170,24 +180,27 @@ public class AudioProcessor {
FFT fft = new FFT(bufferSize, samplingRate); FFT fft = new FFT(bufferSize, samplingRate);
fft.window(FFT.HAMMING); fft.window(FFT.HAMMING);
float[] buffer; float[] buffer;
float[] spectrum = new float[fft.getBandSize(band)]; float[] spectrumBuffer = new float[fft.getBandSize(band)];
float[] lastSpectrum = new float[spectrum.length]; float[] lastSpectrumBuffer = new float[spectrumBuffer.length];
List<Float> spectrum = new ArrayList<Float>();
List<Float> spectralFlux = new ArrayList<Float>(); List<Float> spectralFlux = new ArrayList<Float>();
for (int i = 0; i < samples.length; i += bufferSize) { for (int i = 0; i < sampleBuffer.samples.length; i += bufferSize) {
buffer = SampleHelper.splitSampleArray(samples, i, bufferSize); buffer = SampleHelper.splitSampleArray(sampleBuffer.samples, i, bufferSize);
fft.forward(buffer); fft.forward(buffer);
System.arraycopy(spectrum, 0, lastSpectrum, 0, spectrum.length); System.arraycopy(spectrumBuffer, 0, lastSpectrumBuffer, 0, spectrumBuffer.length);
System.arraycopy(fft.getSpectrum(band), 0, spectrum, 0, spectrum.length); System.arraycopy(fft.getSpectrum(band), 0, spectrumBuffer, 0, spectrumBuffer.length);
float flux = 0; float flux = 0;
for (int j = 0; j < spectrum.length; j++) { for (int j = 0; j < spectrumBuffer.length; j++) {
float value = (spectrum[j] - lastSpectrum[j]); spectrum.add(spectrumBuffer[j]);
float value = (spectrumBuffer[j] - lastSpectrumBuffer[j]);
flux += value < 0 ? 0 : value; flux += value < 0 ? 0 : value;
} }
spectralFlux.add(flux); spectralFlux.add(flux);
} }
this.spectralFlux = SampleHelper.convertToFloatArray(spectralFlux); this.spectralFlux = SampleHelper.convertToFloatArray(spectralFlux);
this.spectrum = SampleHelper.convertToFloatArray(spectrum);
} }
private void calculateThreshold(int thresholdWindowSize, float multiplier) { private void calculateThreshold(int thresholdWindowSize, float multiplier) {
@ -320,10 +333,19 @@ public class AudioProcessor {
/** /**
* Returns the samples which are analysed. * Returns the samples which are analysed.
* *
* @returns A float array containing the samples * @returns A SampleBuffer containing the samples
*/ */
public float[] getSamples() { public SampleBuffer getSampleBuffer() {
return samples; return sampleBuffer;
}
/**
* Returns the last calculated fft-spectrum.
*
* @returns A float array containing the spectrum data
*/
public float[] getSpectrum() {
return spectrum;
} }
/** /**

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2013 Darth Affe <http://wyrez.org> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.wyrez.audio.util;
/**
*
* @author Darth Affe
*/
public class SampleBuffer {
public final float[] samples;
public final float samplingRate;
public SampleBuffer(float[] samples, float samplingRate) {
this.samples = samples;
this.samplingRate = samplingRate;
}
}

View File

@ -97,4 +97,14 @@ public class SampleHelper {
} }
return convertToFloatArray(samples); return convertToFloatArray(samples);
} }
/**
* Creates a SampleBuffer from the data provided by the given decoder.
*
* @param deocder The decoder to read from
* @returns The new SampleBuffer
*/
public static SampleBuffer createSampleBuffer(Decoder decoder) {
return new SampleBuffer(readAllSamples(decoder), decoder.getSamplingRate());
}
} }