From 51ce1466111d536d65ea05803767d85d2fb6dd0e Mon Sep 17 00:00:00 2001 From: Recrown Date: Sun, 10 Dec 2017 01:45:10 -0600 Subject: [PATCH] random access files now used to sync visualizer with song (optimization) --- .../rhythmbullet/audio/Mp3Manager.java | 46 +++++++++++++------ .../rhythmbullet/audio/MusicManager.java | 8 +++- .../rhythmbullet/audio/WAVManager.java | 33 +++++++++---- .../audio/visualizer/BasicVisualizer.java | 2 +- .../audio/visualizer/VisualizerCore.java | 31 +++++++++---- .../audio/wavedecoder/WavDecoder.java | 24 +++------- .../graphics/ui/components/Visualizer.java | 2 +- 7 files changed, 93 insertions(+), 53 deletions(-) diff --git a/core/src/zero1hd/rhythmbullet/audio/Mp3Manager.java b/core/src/zero1hd/rhythmbullet/audio/Mp3Manager.java index ac6b315..630c96d 100755 --- a/core/src/zero1hd/rhythmbullet/audio/Mp3Manager.java +++ b/core/src/zero1hd/rhythmbullet/audio/Mp3Manager.java @@ -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(); } } diff --git a/core/src/zero1hd/rhythmbullet/audio/MusicManager.java b/core/src/zero1hd/rhythmbullet/audio/MusicManager.java index c740316..4069578 100755 --- a/core/src/zero1hd/rhythmbullet/audio/MusicManager.java +++ b/core/src/zero1hd/rhythmbullet/audio/MusicManager.java @@ -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(); } diff --git a/core/src/zero1hd/rhythmbullet/audio/WAVManager.java b/core/src/zero1hd/rhythmbullet/audio/WAVManager.java index 0c35af0..e10d211 100755 --- a/core/src/zero1hd/rhythmbullet/audio/WAVManager.java +++ b/core/src/zero1hd/rhythmbullet/audio/WAVManager.java @@ -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 diff --git a/core/src/zero1hd/rhythmbullet/audio/visualizer/BasicVisualizer.java b/core/src/zero1hd/rhythmbullet/audio/visualizer/BasicVisualizer.java index 2902935..38572c0 100755 --- a/core/src/zero1hd/rhythmbullet/audio/visualizer/BasicVisualizer.java +++ b/core/src/zero1hd/rhythmbullet/audio/visualizer/BasicVisualizer.java @@ -172,7 +172,7 @@ public class BasicVisualizer extends VisualizerCore { } public void flip() { - flip = flip ? false : true; + flip = !flip; } public boolean isFlipped() { diff --git a/core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java b/core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java index c767d79..55bb058 100755 --- a/core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java +++ b/core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java @@ -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; + } } diff --git a/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WavDecoder.java b/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WavDecoder.java index 4bdf749..0fff39e 100755 --- a/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WavDecoder.java +++ b/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WavDecoder.java @@ -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(); diff --git a/core/src/zero1hd/rhythmbullet/graphics/ui/components/Visualizer.java b/core/src/zero1hd/rhythmbullet/graphics/ui/components/Visualizer.java index ee033e4..305fc33 100755 --- a/core/src/zero1hd/rhythmbullet/graphics/ui/components/Visualizer.java +++ b/core/src/zero1hd/rhythmbullet/graphics/ui/components/Visualizer.java @@ -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); }