random access files now used to sync visualizer with song (optimization)
This commit is contained in:
parent
8023987148
commit
51ce146611
@ -1,6 +1,12 @@
|
||||
package zero1hd.rhythmbullet.audio;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.channels.Channels;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -30,9 +36,9 @@ import javazoom.jl.decoder.OutputBuffer;
|
||||
public class Mp3Manager implements MusicManager {
|
||||
private int readWindowSize = 1024;
|
||||
|
||||
private int currentReadWindowIndex;
|
||||
private int readWindowIndex;
|
||||
private Music playbackMusic;
|
||||
private int readIndex;
|
||||
private int playbackIndex;
|
||||
|
||||
private int sampleRate;
|
||||
private long sampleCount;
|
||||
@ -41,10 +47,11 @@ public class Mp3Manager implements MusicManager {
|
||||
Bitstream bitstream;
|
||||
MP3Decoder decoder;
|
||||
OutputBuffer sampleBuffer;
|
||||
InputStream inputStream;
|
||||
private byte[] currentByteSet;
|
||||
private byte[] workset;
|
||||
private int indexHead = -1;
|
||||
|
||||
private RandomAccessFile raf;
|
||||
private FileHandle file;
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
@ -71,9 +78,14 @@ public class Mp3Manager implements MusicManager {
|
||||
lock.unlock();
|
||||
});
|
||||
|
||||
bitstream = new Bitstream(audioFile.read());
|
||||
decoder = new MP3Decoder();
|
||||
|
||||
try {
|
||||
raf = new RandomAccessFile(audioFile.file(), "r");
|
||||
bitstream = new Bitstream(inputStream = Channels.newInputStream(raf.getChannel()));
|
||||
decoder = new MP3Decoder();
|
||||
} catch (FileNotFoundException e2) {
|
||||
e2.printStackTrace();
|
||||
throw new InvalidParameterException("Error with creating RandomAccessFile.");
|
||||
}
|
||||
try {
|
||||
Header header = bitstream.readFrame();
|
||||
if (header == null) throw new GdxRuntimeException("Empty MP3");
|
||||
@ -88,15 +100,22 @@ public class Mp3Manager implements MusicManager {
|
||||
playbackMusic = Gdx.audio.newMusic(audioFile);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadIndexToPlaybackIndex() {
|
||||
try {
|
||||
raf.seek((long) (getPositionInSeconds()*(long)sampleRate));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void playbackIndexUpdate() {
|
||||
readIndex = (int) (playbackMusic.getPosition() * sampleRate / readWindowSize);
|
||||
playbackIndex = (int) (playbackMusic.getPosition() * sampleRate / readWindowSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlaybackIndexPosition() {
|
||||
return readIndex;
|
||||
return playbackIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -132,7 +151,7 @@ public class Mp3Manager implements MusicManager {
|
||||
samples[sid] /= Short.MAX_VALUE+1;
|
||||
}
|
||||
}
|
||||
currentReadWindowIndex++;
|
||||
readWindowIndex++;
|
||||
|
||||
return framesRead;
|
||||
}
|
||||
@ -185,8 +204,8 @@ public class Mp3Manager implements MusicManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentReadWindowIndex() {
|
||||
return currentReadWindowIndex;
|
||||
public int getreadWindowIndex() {
|
||||
return readWindowIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -262,7 +281,8 @@ public class Mp3Manager implements MusicManager {
|
||||
try {
|
||||
bitstream.close();
|
||||
bitstream = null;
|
||||
} catch (BitstreamException e) {
|
||||
inputStream.close();
|
||||
} catch (BitstreamException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public interface MusicManager extends Disposable {
|
||||
public void playbackIndexUpdate();
|
||||
|
||||
/**
|
||||
* Gets the current position in seconds s
|
||||
* Gets the current position in seconds
|
||||
* @return the current frame of audio.
|
||||
*/
|
||||
public int getPlaybackIndexPosition();
|
||||
@ -54,7 +54,7 @@ public interface MusicManager extends Disposable {
|
||||
* The current numerical value of the last window read
|
||||
* @return
|
||||
*/
|
||||
public int getCurrentReadWindowIndex();
|
||||
public int getreadWindowIndex();
|
||||
|
||||
public void pause();
|
||||
|
||||
@ -87,4 +87,8 @@ public interface MusicManager extends Disposable {
|
||||
* @return the song filehandle.
|
||||
*/
|
||||
public FileHandle getMusicFile();
|
||||
|
||||
/**
|
||||
*/
|
||||
public void setReadIndexToPlaybackIndex();
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package zero1hd.rhythmbullet.audio;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.channels.Channels;
|
||||
import java.security.InvalidParameterException;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
@ -15,17 +18,20 @@ import zero1hd.rhythmbullet.audio.wavedecoder.WavDecoder;
|
||||
public class WAVManager implements MusicManager {
|
||||
private int readWindowSize = 1024;
|
||||
private AudioFormat format;
|
||||
private int readIndex;
|
||||
private int currentReadWindowIndex;
|
||||
private int playbackIndex;
|
||||
private int readWindowIndex;
|
||||
private Music playbackMusic;
|
||||
WavDecoder decoder;
|
||||
private FileHandle file;
|
||||
private String basicSongName;
|
||||
private RandomAccessFile raf;
|
||||
|
||||
public WAVManager(FileHandle file) {
|
||||
this.file = file;
|
||||
basicSongName = file.name();
|
||||
try {
|
||||
decoder = new WavDecoder(file);
|
||||
raf = new RandomAccessFile(file.file(), "r");
|
||||
decoder = new WavDecoder(new BufferedInputStream(Channels.newInputStream(raf.getChannel())));
|
||||
} catch (InvalidParameterException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
@ -36,19 +42,28 @@ public class WAVManager implements MusicManager {
|
||||
|
||||
@Override
|
||||
public void playbackIndexUpdate() {
|
||||
readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize);
|
||||
playbackIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlaybackIndexPosition() {
|
||||
return readIndex;
|
||||
return playbackIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadWindowSize() {
|
||||
return readWindowSize;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setReadIndexToPlaybackIndex() {
|
||||
try {
|
||||
raf.seek((long) (getPositionInSeconds()*(long)getSampleRate()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readSamples(float[] samples) {
|
||||
int samplesRead = 0;
|
||||
@ -59,7 +74,7 @@ public class WAVManager implements MusicManager {
|
||||
}
|
||||
|
||||
if (samplesRead != 0) {
|
||||
currentReadWindowIndex++;
|
||||
readWindowIndex++;
|
||||
}
|
||||
return samplesRead;
|
||||
}
|
||||
@ -87,8 +102,8 @@ public class WAVManager implements MusicManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentReadWindowIndex() {
|
||||
return currentReadWindowIndex;
|
||||
public int getreadWindowIndex() {
|
||||
return readWindowIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -172,7 +172,7 @@ public class BasicVisualizer extends VisualizerCore {
|
||||
}
|
||||
|
||||
public void flip() {
|
||||
flip = flip ? false : true;
|
||||
flip = !flip;
|
||||
}
|
||||
|
||||
public boolean isFlipped() {
|
||||
|
@ -17,26 +17,29 @@ public class VisualizerCore implements Disposable {
|
||||
protected int barCount;
|
||||
private boolean calc;
|
||||
private ReentrantLock lock;
|
||||
private float updateRate;
|
||||
private float updateTimer;
|
||||
public VisualizerCore(int width, int height, int x, int y) {
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.xPos = x;
|
||||
this.yPos = y;
|
||||
|
||||
updateRate = 1f/30f;
|
||||
lock = new ReentrantLock();
|
||||
}
|
||||
|
||||
public void calculate() {
|
||||
if (mm != null) {
|
||||
mm.playbackIndexUpdate();
|
||||
lock.lock();
|
||||
while (calc && mm.isPlaying() && mm.getPlaybackIndexPosition() > mm.getCurrentReadWindowIndex()) {
|
||||
public void calculate(float delta) {
|
||||
if (mm != null && calc && mm.isPlaying()) {
|
||||
updateTimer += delta;
|
||||
if (updateTimer >= updateRate) {
|
||||
mm.playbackIndexUpdate();
|
||||
lock.lock();
|
||||
mm.setReadIndexToPlaybackIndex();
|
||||
mm.readSamples(audioPCM);
|
||||
if (mm.getPlaybackIndexPosition() == mm.getCurrentReadWindowIndex()) {
|
||||
fft.realForward(audioPCM);
|
||||
}
|
||||
fft.realForward(audioPCM);
|
||||
lock.unlock();
|
||||
updateTimer = 0;
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,4 +98,12 @@ public class VisualizerCore implements Disposable {
|
||||
public MusicManager getMm() {
|
||||
return mm;
|
||||
}
|
||||
|
||||
public void setUpdateRate(float updateRate) {
|
||||
this.updateRate = updateRate;
|
||||
}
|
||||
|
||||
public float getUpdateRate() {
|
||||
return updateRate;
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,25 @@
|
||||
package zero1hd.rhythmbullet.audio.wavedecoder;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
public class WavDecoder {
|
||||
private FileHandle file;
|
||||
|
||||
private int channels;
|
||||
private double sampleRate;
|
||||
private String fileName;
|
||||
private byte[] buffer;
|
||||
private AudioInputStream audioInputStream;
|
||||
|
||||
public WavDecoder(FileHandle file) throws IOException {
|
||||
this.file = file;
|
||||
public WavDecoder(BufferedInputStream inputStream) throws IOException {
|
||||
try {
|
||||
audioInputStream = AudioSystem.getAudioInputStream(file.file());
|
||||
audioInputStream = AudioSystem.getAudioInputStream(inputStream);
|
||||
buffer = new byte[audioInputStream.getFormat().getFrameSize()];
|
||||
|
||||
channels = audioInputStream.getFormat().getChannels();
|
||||
sampleRate = audioInputStream.getFormat().getSampleRate();
|
||||
fileName = file.name();
|
||||
} catch (UnsupportedAudioFileException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -47,14 +41,6 @@ public class WavDecoder {
|
||||
return audioInputStream.getFrameLength();
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public FileHandle getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public int readSamples(float[] samples) throws IOException {
|
||||
int framesRead = 0;
|
||||
|
||||
@ -74,6 +60,10 @@ public class WavDecoder {
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
public AudioInputStream getAudioInputStream() {
|
||||
return audioInputStream;
|
||||
}
|
||||
|
||||
public void cleanAndClose() {
|
||||
try {
|
||||
audioInputStream.close();
|
||||
|
@ -40,7 +40,7 @@ public class Visualizer extends Widget implements Disposable {
|
||||
vis.updatePositionInfo();
|
||||
vis.setxPos((getWidth() - vis.getActualWidth())/2f);
|
||||
}
|
||||
vis.calculate();
|
||||
vis.calculate(delta);
|
||||
super.act(delta);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user