wav decoding optimization works
This commit is contained in:
parent
a47cd1993b
commit
107b0e2553
@ -71,7 +71,7 @@ public class AudioAnalyzer {
|
|||||||
public void run() {
|
public void run() {
|
||||||
progress = 0;
|
progress = 0;
|
||||||
int tasksDone = 0;
|
int tasksDone = 0;
|
||||||
int totalTasks = audioData.getSampleCount()/audioData.getReadWindowSize();
|
long totalTasks = audioData.getFrameCount()/audioData.getReadWindowSize();
|
||||||
|
|
||||||
bassThresholdMultiplier = 1.5f;
|
bassThresholdMultiplier = 1.5f;
|
||||||
mThresholdMultiplier = 1.4f;
|
mThresholdMultiplier = 1.4f;
|
||||||
@ -93,6 +93,7 @@ public class AudioAnalyzer {
|
|||||||
Gdx.app.debug("Read freq", String.valueOf(audioData.getSampleRate()));
|
Gdx.app.debug("Read freq", String.valueOf(audioData.getSampleRate()));
|
||||||
Gdx.app.debug("Using following bin ranges", "\nBass freq begin: " + bassBinBegin + "\nBass freq end: " + bassBinEnd + "\nMain freq begin: " + umBinBegin + "\nMain freq end: " + umBinEnd);
|
Gdx.app.debug("Using following bin ranges", "\nBass freq begin: " + bassBinBegin + "\nBass freq end: " + bassBinEnd + "\nMain freq begin: " + umBinBegin + "\nMain freq end: " + umBinEnd);
|
||||||
|
|
||||||
|
Gdx.app.debug("Total tasks", String.valueOf(totalTasks));
|
||||||
|
|
||||||
Gdx.app.debug("Threshold Calc Range UM", String.valueOf(umThresholdCalcRange));
|
Gdx.app.debug("Threshold Calc Range UM", String.valueOf(umThresholdCalcRange));
|
||||||
Gdx.app.debug("Threshold Calc Range M", String.valueOf(umThresholdCalcRange));
|
Gdx.app.debug("Threshold Calc Range M", String.valueOf(umThresholdCalcRange));
|
||||||
@ -100,6 +101,7 @@ public class AudioAnalyzer {
|
|||||||
|
|
||||||
fft = new FloatFFT_1D(audioData.getReadWindowSize());
|
fft = new FloatFFT_1D(audioData.getReadWindowSize());
|
||||||
int seedDigit = 0;
|
int seedDigit = 0;
|
||||||
|
|
||||||
while (audioData.readSamples(audioPCM) > 0 && work) {
|
while (audioData.readSamples(audioPCM) > 0 && work) {
|
||||||
|
|
||||||
fft.realForward(audioPCM);
|
fft.realForward(audioPCM);
|
||||||
|
@ -44,7 +44,7 @@ public interface AudioData extends Disposable {
|
|||||||
* returns sample count
|
* returns sample count
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int getSampleCount();
|
public long getFrameCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns duration of song in seconds
|
* returns duration of song in seconds
|
||||||
|
@ -10,10 +10,12 @@ import org.jaudiotagger.tag.TagException;
|
|||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.audio.Music;
|
import com.badlogic.gdx.audio.Music;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
|
|
||||||
import javazoom.jl.decoder.Bitstream;
|
import javazoom.jl.decoder.Bitstream;
|
||||||
import javazoom.jl.decoder.BitstreamException;
|
import javazoom.jl.decoder.BitstreamException;
|
||||||
import javazoom.jl.decoder.DecoderException;
|
import javazoom.jl.decoder.DecoderException;
|
||||||
|
import javazoom.jl.decoder.Header;
|
||||||
import javazoom.jl.decoder.MP3Decoder;
|
import javazoom.jl.decoder.MP3Decoder;
|
||||||
import javazoom.jl.decoder.OutputBuffer;
|
import javazoom.jl.decoder.OutputBuffer;
|
||||||
|
|
||||||
@ -24,27 +26,39 @@ public class Mp3AudioData implements AudioData {
|
|||||||
private int readIndex;
|
private int readIndex;
|
||||||
|
|
||||||
private int sampleRate;
|
private int sampleRate;
|
||||||
private int sampleCount;
|
private long sampleCount;
|
||||||
private float durationInSeconds;
|
private float durationInSeconds;
|
||||||
|
|
||||||
Bitstream bitStream;
|
Bitstream bitstream;
|
||||||
MP3Decoder decoder;
|
MP3Decoder decoder;
|
||||||
|
OutputBuffer sampleBuffer;
|
||||||
|
Mp3.Music test;
|
||||||
public Mp3AudioData(FileHandle audioFile) {
|
public Mp3AudioData(FileHandle audioFile) {
|
||||||
try {
|
try {
|
||||||
MP3File mp3File = new MP3File(audioFile.file());
|
MP3File mp3File = new MP3File(audioFile.file());
|
||||||
|
sampleCount = mp3File.getMP3AudioHeader().getNumberOfFrames();
|
||||||
sampleCount = (int) mp3File.getMP3AudioHeader().getNumberOfFrames();
|
|
||||||
durationInSeconds = mp3File.getMP3AudioHeader().getNumberOfFrames()/readWindowSize;
|
durationInSeconds = mp3File.getMP3AudioHeader().getNumberOfFrames()/readWindowSize;
|
||||||
sampleRate = mp3File.getMP3AudioHeader().getSampleRateAsNumber();
|
sampleRate = mp3File.getMP3AudioHeader().getSampleRateAsNumber();
|
||||||
|
} catch (IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||||
bitStream = new Bitstream(audioFile.read());
|
e.printStackTrace();
|
||||||
decoder = new MP3Decoder();
|
}
|
||||||
} catch (IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e1) {
|
|
||||||
e1.printStackTrace();
|
bitstream = new Bitstream(audioFile.read());
|
||||||
|
decoder = new MP3Decoder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Header header = bitstream.readFrame();
|
||||||
|
if (header == null) throw new GdxRuntimeException("Empty MP3");
|
||||||
|
int channels = header.mode() == Header.SINGLE_CHANNEL ? 1 : 2;
|
||||||
|
sampleBuffer = new OutputBuffer(channels, false);
|
||||||
|
decoder.setOutputBuffer(sampleBuffer);
|
||||||
|
} catch (BitstreamException e) {
|
||||||
|
throw new GdxRuntimeException("error while preloading mp3", e);
|
||||||
}
|
}
|
||||||
reset();
|
|
||||||
|
|
||||||
playbackMusic = Gdx.audio.newMusic(audioFile);
|
playbackMusic = Gdx.audio.newMusic(audioFile);
|
||||||
|
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,7 +87,7 @@ public class Mp3AudioData implements AudioData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSampleCount() {
|
public long getFrameCount() {
|
||||||
return sampleCount;
|
return sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +95,11 @@ public class Mp3AudioData implements AudioData {
|
|||||||
public void dispose() {
|
public void dispose() {
|
||||||
reset();
|
reset();
|
||||||
playbackMusic.dispose();
|
playbackMusic.dispose();
|
||||||
|
try {
|
||||||
|
bitstream.close();
|
||||||
|
} catch (BitstreamException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -90,26 +109,37 @@ public class Mp3AudioData implements AudioData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int readSamples(float[] samples) {
|
public int readSamples(float[] samples) {
|
||||||
int samplesRead = 0;
|
int totalRead = 0;
|
||||||
|
|
||||||
|
for (int sid = 0; sid < samples.length; sid++) {
|
||||||
try {
|
try {
|
||||||
OutputBuffer samplesBuffer = decoder.decodeFrame(bitStream.readFrame(), bitStream);
|
Header header = bitstream.readFrame();
|
||||||
byte[] frameBuffer = samplesBuffer.getBuffer();
|
|
||||||
for (int sampleID = 0; sampleID < samples.length; sampleID++) {
|
|
||||||
|
|
||||||
samples[sampleID] += (short) ((frameBuffer[1] << 8) + (frameBuffer[0] & 0xff));
|
if (header == null) break;
|
||||||
if (samplesBuffer.isStereo()) {
|
|
||||||
samples[sampleID] = (short) ((frameBuffer[3] << 8) + (frameBuffer[2] & 0xff));
|
|
||||||
|
|
||||||
samples[sampleID] /= 2;
|
try {
|
||||||
|
decoder.decodeFrame(header, bitstream);
|
||||||
|
} catch (ArrayIndexOutOfBoundsException | DecoderException e) {
|
||||||
|
System.out.println(e);
|
||||||
|
}
|
||||||
|
bitstream.closeFrame();
|
||||||
|
sampleBuffer.reset();
|
||||||
|
byte[] buffer = sampleBuffer.getBuffer();
|
||||||
|
|
||||||
|
samples[sid] += (buffer[1] << 8) + (buffer[0] & 0x00ff);
|
||||||
|
if (sampleBuffer.isStereo()) {
|
||||||
|
samples[sid] += (buffer[3] << 8) + (buffer[2] & 0x00ff);
|
||||||
|
samples[sid] /= 2;
|
||||||
|
}
|
||||||
|
totalRead++;
|
||||||
|
|
||||||
|
samples[sid] /= Short.MAX_VALUE + 1;
|
||||||
|
} catch (BitstreamException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
samples[sampleID] /= Short.MAX_VALUE+1;
|
return totalRead;
|
||||||
samplesRead ++;
|
|
||||||
}
|
|
||||||
} catch (DecoderException | BitstreamException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return samplesRead;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -117,4 +147,6 @@ public class Mp3AudioData implements AudioData {
|
|||||||
return sampleRate;
|
return sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,8 @@ public class WavAudioData implements AudioData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSampleCount() {
|
public long getFrameCount() {
|
||||||
return decoder.getDataSize()/(2*decoder.getChannels());
|
return decoder.getFrameCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,6 +6,7 @@ import javax.sound.sampled.AudioInputStream;
|
|||||||
import javax.sound.sampled.AudioSystem;
|
import javax.sound.sampled.AudioSystem;
|
||||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
public class WavDecoder {
|
public class WavDecoder {
|
||||||
@ -13,16 +14,20 @@ public class WavDecoder {
|
|||||||
|
|
||||||
private int channels;
|
private int channels;
|
||||||
private double sampleRate;
|
private double sampleRate;
|
||||||
private int dataSize;
|
|
||||||
private int byteRate;
|
|
||||||
private String fileName;
|
private String fileName;
|
||||||
private byte[] buffer;
|
private byte[] buffer;
|
||||||
private AudioInputStream audioInputStream;
|
private AudioInputStream audioInputStream;
|
||||||
|
|
||||||
public WavDecoder(FileHandle file) throws IOException {
|
public WavDecoder(FileHandle file) throws IOException {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
try {
|
try {
|
||||||
audioInputStream = AudioSystem.getAudioInputStream(file.read());
|
audioInputStream = AudioSystem.getAudioInputStream(file.file());
|
||||||
|
Gdx.app.debug("WAVDecoder", String.valueOf(audioInputStream.getFormat().getFrameSize()));
|
||||||
buffer = new byte[audioInputStream.getFormat().getFrameSize()];
|
buffer = new byte[audioInputStream.getFormat().getFrameSize()];
|
||||||
|
|
||||||
|
channels = audioInputStream.getFormat().getChannels();
|
||||||
|
sampleRate = audioInputStream.getFormat().getSampleRate();
|
||||||
|
fileName = file.name();
|
||||||
} catch (UnsupportedAudioFileException e) {
|
} catch (UnsupportedAudioFileException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -32,20 +37,16 @@ public class WavDecoder {
|
|||||||
return channels;
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getByteRate() {
|
|
||||||
return byteRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDataSize() {
|
|
||||||
return dataSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getSampleRate() {
|
public double getSampleRate() {
|
||||||
return sampleRate;
|
return sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDurationInSeconds() {
|
public float getDurationInSeconds() {
|
||||||
return (long) (dataSize/byteRate);
|
return audioInputStream.getFrameLength()/audioInputStream.getFormat().getFrameRate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFrameCount() {
|
||||||
|
return audioInputStream.getFrameLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
@ -57,22 +58,23 @@ public class WavDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int readSamples(float[] samples) throws IOException {
|
public int readSamples(float[] samples) throws IOException {
|
||||||
int samplesRead = 0;
|
int framesRead = 0;
|
||||||
|
|
||||||
for (int sampleID = 0; sampleID < samples.length; sampleID++) {
|
for (int sampleID = 0; sampleID < samples.length; sampleID++) {
|
||||||
audioInputStream.read(buffer);
|
if (audioInputStream.read(buffer) > 0) {
|
||||||
|
samples[sampleID] += (buffer[1] << 8) + (buffer[0] & 0x00ff);
|
||||||
samples[sampleID] += (short) ((buffer[1] << 8) + (buffer[0] & 0xff));
|
|
||||||
if (audioInputStream.getFormat().getChannels() > 1) {
|
if (audioInputStream.getFormat().getChannels() > 1) {
|
||||||
samples[sampleID] = (short) ((buffer[3] << 8) + (buffer[2] & 0xff));
|
samples[sampleID] += (buffer[3] << 8) + (buffer[2] & 0x00ff);
|
||||||
samples[sampleID] /= 2;
|
samples[sampleID] /= 2;
|
||||||
}
|
}
|
||||||
|
framesRead ++;
|
||||||
samples[sampleID] /= Short.MAX_VALUE+1;
|
|
||||||
samplesRead ++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return samplesRead;
|
|
||||||
|
samples[sampleID] /= Short.MAX_VALUE+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return framesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanAndClose() {
|
public void cleanAndClose() {
|
||||||
|
@ -14,7 +14,7 @@ public class DesktopLauncher {
|
|||||||
|
|
||||||
config.resizable = false;
|
config.resizable = false;
|
||||||
config.useHDPI = true;
|
config.useHDPI = true;
|
||||||
System.setProperty("org.lwjgl.opengl.Window.undecorated", "true");
|
// System.setProperty("org.lwjgl.opengl.Window.undecorated", "true");
|
||||||
|
|
||||||
|
|
||||||
new LwjglApplication(new RhythmBullet(), config);
|
new LwjglApplication(new RhythmBullet(), config);
|
||||||
|
Loading…
Reference in New Issue
Block a user