UNTESTED; basic mp3spi setup done; more efficient way of skipping bytes now; syncing of playback and read implemented
This commit is contained in:
parent
677ada45b6
commit
cebf36dff9
@ -22,8 +22,9 @@ import zero1hd.rhythmbullet.audio.wavedecoder.AudioSampleReader;
|
||||
public class Mp3Manager implements MusicManager {
|
||||
private int readWindowSize = 1024;
|
||||
private Music music;
|
||||
private int playbackIndex;
|
||||
private int playbackIndex, readIndex;
|
||||
private FileHandle fileHandle;
|
||||
AudioInputStream in;
|
||||
private AudioInputStream ais;
|
||||
private AudioFormat af;
|
||||
private AudioSampleReader d;
|
||||
@ -32,7 +33,6 @@ public class Mp3Manager implements MusicManager {
|
||||
public Mp3Manager(FileHandle file) {
|
||||
this.fileHandle = file;
|
||||
try {
|
||||
AudioInputStream in;
|
||||
in = AudioSystem.getAudioInputStream(file.file());
|
||||
AudioFormat baseFormat = in.getFormat();
|
||||
properties = ((TAudioFormat)baseFormat).properties();
|
||||
@ -43,7 +43,6 @@ public class Mp3Manager implements MusicManager {
|
||||
baseFormat.getChannels()*2,
|
||||
baseFormat.getSampleRate(), false);
|
||||
ais = AudioSystem.getAudioInputStream(baseFormat, in);
|
||||
in.close();
|
||||
d = new AudioSampleReader(ais);
|
||||
music = Gdx.audio.newMusic(file);
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
@ -56,6 +55,7 @@ public class Mp3Manager implements MusicManager {
|
||||
music.dispose();
|
||||
try {
|
||||
ais.close();
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -79,6 +79,7 @@ public class Mp3Manager implements MusicManager {
|
||||
@Override
|
||||
public int readSamples(float[] samples) {
|
||||
try {
|
||||
readIndex++;
|
||||
return d.readSamples(samples);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -152,22 +153,10 @@ public class Mp3Manager implements MusicManager {
|
||||
return fileHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long position) {
|
||||
long totalSkipped = 0;
|
||||
long skipped = 0;
|
||||
closeStream();
|
||||
reInitStream();
|
||||
while (totalSkipped < position) {
|
||||
try {
|
||||
skipped = ais.skip(position-totalSkipped);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (skipped == 0) break;
|
||||
totalSkipped += skipped;
|
||||
}
|
||||
skip(position);
|
||||
}
|
||||
|
||||
private void closeStream() {
|
||||
@ -194,4 +183,32 @@ public class Mp3Manager implements MusicManager {
|
||||
public void synchronize() {
|
||||
seek(MathUtils.round(((Integer) properties.get("audio.length.bytes")).intValue() * (getPositionInSeconds()/getDuration())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadIndex() {
|
||||
return readIndex;
|
||||
}
|
||||
|
||||
public void skip(long bytes) {
|
||||
long totalSkipped = 0;
|
||||
long skipped = 0;
|
||||
|
||||
while (totalSkipped < bytes) {
|
||||
try {
|
||||
skipped = ais.skip(bytes-totalSkipped);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (skipped == 0) break;
|
||||
totalSkipped += skipped;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipReadWindow() {
|
||||
skip(readWindowSize*af.getFrameSize());
|
||||
readIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -82,14 +82,15 @@ public interface MusicManager extends Disposable {
|
||||
*/
|
||||
public FileHandle getMusicFile();
|
||||
|
||||
/**
|
||||
* sets the reading position to the given position;
|
||||
* @param position the byte to skip to.
|
||||
*/
|
||||
public void seek(long position);
|
||||
|
||||
/**
|
||||
* Synchronizes the playback and read threads
|
||||
*/
|
||||
public void synchronize();
|
||||
|
||||
/**
|
||||
* @return the window that the current read index is on
|
||||
*/
|
||||
public int getReadIndex();
|
||||
|
||||
public void skipReadWindow();
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import zero1hd.rhythmbullet.audio.wavedecoder.AudioSampleReader;
|
||||
|
||||
public class WAVManager implements MusicManager {
|
||||
private int readWindowSize = 1024;
|
||||
private int playbackIndex;
|
||||
private int playbackIndex, readIndex;
|
||||
private Music music;
|
||||
private FileHandle fileHandle;
|
||||
private AudioInputStream ais;
|
||||
@ -64,6 +64,7 @@ public class WAVManager implements MusicManager {
|
||||
@Override
|
||||
public int readSamples(float[] samples) {
|
||||
try {
|
||||
readIndex++;
|
||||
return d.readSamples(samples);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -136,22 +137,9 @@ public class WAVManager implements MusicManager {
|
||||
return fileHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long position) {
|
||||
long totalSkipped = 0;
|
||||
long skipped = 0;
|
||||
|
||||
restartStream();
|
||||
while (totalSkipped < position) {
|
||||
try {
|
||||
skipped = ais.skip(position-totalSkipped);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (skipped == 0) break;
|
||||
totalSkipped += skipped;
|
||||
}
|
||||
skip(position);
|
||||
}
|
||||
|
||||
private void restartStream() {
|
||||
@ -162,9 +150,7 @@ public class WAVManager implements MusicManager {
|
||||
}
|
||||
|
||||
try {
|
||||
AudioInputStream in = AudioSystem.getAudioInputStream(fileHandle.file());
|
||||
ais = AudioSystem.getAudioInputStream(af, in);
|
||||
in.close();
|
||||
ais = AudioSystem.getAudioInputStream(fileHandle.file());
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -173,5 +159,32 @@ public class WAVManager implements MusicManager {
|
||||
@Override
|
||||
public void synchronize() {
|
||||
seek(MathUtils.round(getPositionInSeconds()*getSampleRate()));
|
||||
readIndex = playbackIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadIndex() {
|
||||
return readIndex;
|
||||
}
|
||||
|
||||
public void skip(long bytes) {
|
||||
long totalSkipped = 0;
|
||||
long skipped = 0;
|
||||
while (totalSkipped < bytes) {
|
||||
try {
|
||||
skipped = ais.skip(bytes-totalSkipped);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (skipped == 0) break;
|
||||
totalSkipped += skipped;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipReadWindow() {
|
||||
skip(af.getFrameSize()*readWindowSize);
|
||||
readIndex++;
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,10 @@ public class VisualizerCore implements Disposable {
|
||||
updateTimer += delta;
|
||||
if (updateTimer >= updateRate) {
|
||||
mm.playbackIndexUpdate();
|
||||
while (mm.getPlaybackIndexPosition() > mm.getReadIndex()) {
|
||||
mm.skipReadWindow();
|
||||
}
|
||||
lock.lock();
|
||||
mm.setReadIndexToPlaybackIndex();
|
||||
mm.readSamples(audioPCM);
|
||||
fft.realForward(audioPCM);
|
||||
lock.unlock();
|
||||
|
@ -8,8 +8,8 @@ public class AudioSampleReader {
|
||||
private int channels;
|
||||
private double sampleRate;
|
||||
private byte[] buffer;
|
||||
private int sampleSize;
|
||||
private AudioInputStream audioInputStream;
|
||||
private boolean mergeChannels;
|
||||
|
||||
public AudioSampleReader(AudioInputStream ais) throws IOException {
|
||||
audioInputStream = ais;
|
||||
@ -17,7 +17,6 @@ public class AudioSampleReader {
|
||||
|
||||
channels = audioInputStream.getFormat().getChannels();
|
||||
sampleRate = audioInputStream.getFormat().getSampleRate();
|
||||
sampleSize = audioInputStream.getFormat().getSampleSizeInBits();
|
||||
}
|
||||
|
||||
public int getChannels() {
|
||||
@ -28,30 +27,51 @@ public class AudioSampleReader {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
public float getDurationInSeconds() {
|
||||
return audioInputStream.getFrameLength()/audioInputStream.getFormat().getFrameRate();
|
||||
}
|
||||
|
||||
public long getFrameLength() {
|
||||
return audioInputStream.getFrameLength();
|
||||
}
|
||||
|
||||
public int readSamples(float[] samples) throws IOException {
|
||||
int framesRead = 0;
|
||||
for (int sampleID = 0; sampleID < samples.length; sampleID++) {
|
||||
if (audioInputStream.read(buffer) > 0) {
|
||||
samples[sampleID] += (buffer[1] << 8) + (buffer[0] & 0x00ff);
|
||||
if (audioInputStream.getFormat().getChannels() > 1) {
|
||||
short altChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff));
|
||||
if (mergeChannels) {
|
||||
samples[sampleID] = altChan > samples[sampleID] ? altChan : samples[sampleID];
|
||||
} else {
|
||||
sampleID++;
|
||||
samples[sampleID] = altChan;
|
||||
}
|
||||
}
|
||||
framesRead ++;
|
||||
samples[sampleID] /= Short.MAX_VALUE+1;
|
||||
}
|
||||
|
||||
}
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
public int readSamples(short[] samples) throws IOException {
|
||||
int framesRead = 0;
|
||||
|
||||
for (int sampleID = 0; sampleID < samples.length; sampleID++) {
|
||||
if (audioInputStream.read(buffer) > 0) {
|
||||
samples[sampleID] += (buffer[1] << 8) + (buffer[0] & 0x00ff);
|
||||
if (audioInputStream.getFormat().getChannels() > 1) {
|
||||
short altChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff));
|
||||
samples[sampleID] = altChan > samples[sampleID] ? altChan : samples[sampleID];
|
||||
if (mergeChannels) {
|
||||
samples[sampleID] = altChan > samples[sampleID] ? altChan : samples[sampleID];
|
||||
} else {
|
||||
sampleID++;
|
||||
samples[sampleID] = altChan;
|
||||
}
|
||||
}
|
||||
framesRead ++;
|
||||
samples[sampleID] /= Short.MAX_VALUE+1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
@ -59,15 +79,12 @@ public class AudioSampleReader {
|
||||
return audioInputStream;
|
||||
}
|
||||
|
||||
public int getSampleSizeInBits() {
|
||||
return sampleSize;
|
||||
|
||||
public void setMergeChannels(boolean mergeChannels) {
|
||||
this.mergeChannels = mergeChannels;
|
||||
}
|
||||
public boolean isMergeChannels() {
|
||||
return mergeChannels;
|
||||
}
|
||||
|
||||
public void cleanAndClose() {
|
||||
try {
|
||||
audioInputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user