From aceaa7c89fd955d4ed21554b762544a162001bc7 Mon Sep 17 00:00:00 2001 From: Recrown Date: Mon, 25 Jun 2018 20:52:00 -0500 Subject: [PATCH] progress on mp3 pcm processor --- .../audio/RhythmBulletAudioThread.java | 4 +- .../rhythmbullet/audio/VisualizableMusic.java | 17 ++-- .../audio/processor/MP3PCMProcessor.java | 85 ++++++++++++++----- .../audio/processor/PCMProcessor.java | 2 +- .../audio/processor/WAVPCMProcessor.java | 29 ++++--- 5 files changed, 89 insertions(+), 48 deletions(-) diff --git a/core/src/zero1hd/rhythmbullet/audio/RhythmBulletAudioThread.java b/core/src/zero1hd/rhythmbullet/audio/RhythmBulletAudioThread.java index 3d98512..13b85c1 100755 --- a/core/src/zero1hd/rhythmbullet/audio/RhythmBulletAudioThread.java +++ b/core/src/zero1hd/rhythmbullet/audio/RhythmBulletAudioThread.java @@ -19,7 +19,7 @@ public class RhythmBulletAudioThread extends Thread { public RhythmBulletAudioThread(int windowSize, VisualizableMusic vm) { music = vm; this.sp = vm.getSampleProcessor(); - pcm = new short[sp.getChannels()*windowSize*2]; + pcm = new short[(sp.isStereo() ? 2 : 1)*windowSize]; setName("RhythmBullet-AudioPlayback-Thread"); play(); start(); @@ -29,7 +29,7 @@ public class RhythmBulletAudioThread extends Thread { @Override public void run() { sp.initiate(); - this.ad = Gdx.audio.newAudioDevice(sp.getSampleRate(), (sp.getChannels() > 1 ? false : true)); + this.ad = Gdx.audio.newAudioDevice(sp.getSampleRate(), !sp.isStereo()); while (!terminated && sp.readSamples(pcm, this) > 0) { ad.writeSamples(pcm, 0, pcm.length); diff --git a/core/src/zero1hd/rhythmbullet/audio/VisualizableMusic.java b/core/src/zero1hd/rhythmbullet/audio/VisualizableMusic.java index 1ca5142..70ced92 100755 --- a/core/src/zero1hd/rhythmbullet/audio/VisualizableMusic.java +++ b/core/src/zero1hd/rhythmbullet/audio/VisualizableMusic.java @@ -1,12 +1,11 @@ package zero1hd.rhythmbullet.audio; -import java.io.File; import java.io.IOException; +import java.nio.file.Paths; import javax.sound.sampled.UnsupportedAudioFileException; import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.files.FileHandle; import zero1hd.rhythmbullet.audio.processor.MP3PCMProcessor; import zero1hd.rhythmbullet.audio.processor.PCMProcessor; @@ -17,19 +16,19 @@ public class VisualizableMusic implements Music { private OnCompletionListener ocl; private boolean looping; private RhythmBulletAudioThread rat; - private File musicFile; + private String fileLoc; private PCMProcessor sampleProcessor; - public VisualizableMusic(FileHandle file) { - musicFile = file.file(); - if (musicFile.getName().toLowerCase().endsWith("wav")) { + public VisualizableMusic(String fileLoc) { + this.fileLoc = fileLoc; + if (fileLoc.toLowerCase().endsWith("wav")) { try { - sampleProcessor = new WAVPCMProcessor(musicFile, windowSize); + sampleProcessor = new WAVPCMProcessor(Paths.get(fileLoc), windowSize); } catch (IOException | UnsupportedAudioFileException e) { e.printStackTrace(); } - } else if (musicFile.getName().toLowerCase().endsWith("mp3")) { - sampleProcessor = new MP3PCMProcessor(musicFile, windowSize); + } else if (fileLoc.toLowerCase().endsWith("mp3")) { + sampleProcessor = new MP3PCMProcessor(Paths.get(fileLoc), windowSize); } } diff --git a/core/src/zero1hd/rhythmbullet/audio/processor/MP3PCMProcessor.java b/core/src/zero1hd/rhythmbullet/audio/processor/MP3PCMProcessor.java index 7c36ec1..1f38c58 100755 --- a/core/src/zero1hd/rhythmbullet/audio/processor/MP3PCMProcessor.java +++ b/core/src/zero1hd/rhythmbullet/audio/processor/MP3PCMProcessor.java @@ -1,68 +1,107 @@ package zero1hd.rhythmbullet.audio.processor; -import java.io.File; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import fr.delthas.javamp3.Sound; public class MP3PCMProcessor implements PCMProcessor { - private int channels; + private boolean stereo; private int sampleRate; - private byte[] buffer; private volatile float volume, pan; private boolean initiated; - - public MP3PCMProcessor(File musicFile, int windowSize) { - + private Sound audioInputStream; + private Path path; + private byte[] buffer; + + public MP3PCMProcessor(Path path, int windowSize) { + try(Sound sound = new Sound(new BufferedInputStream(Files.newInputStream(path)))) { + sampleRate = sound.getSamplingFrequency(); + stereo = sound.isStereo(); + } catch (IOException e) { + e.printStackTrace(); + } } @Override public void initiate() { + try { + audioInputStream = new Sound(new BufferedInputStream(Files.newInputStream(path))); + } catch (IOException e) { + e.printStackTrace(); + } + buffer = new byte[audioInputStream.getAudioFormat().getFrameSize()]; + initiated = true; } @Override - public int getChannels() { - // TODO Auto-generated method stub - return 0; + public boolean isStereo() { + return stereo; } @Override public int getSampleRate() { - // TODO Auto-generated method stub - return 0; + return sampleRate; } @Override public int readSamples(short[] pcm, Object syncObj) { - // TODO Auto-generated method stub - return 0; + if (initiated) { + synchronized (syncObj) { + int framesRead = 0; + for (int sampleID = 0; sampleID < pcm.length; sampleID++) { + try { + if (audioInputStream.read(buffer) > 0) { + pcm[sampleID] = (short) ((buffer[1] << 8) + (buffer[0] & 0x00ff)); + pcm[sampleID] *= volume * (Math.min(1-pan, 1)); + if (stereo) { + short secondChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff)); + secondChan *= volume * (Math.min(1+pan, 1)); + sampleID++; + pcm[sampleID] = secondChan; + } + framesRead++; + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return framesRead; + } + } else { + throw new IllegalStateException("Stream has not been initialized."); + } } @Override public void setVolume(float volume) { - // TODO Auto-generated method stub - + this.volume = volume; } @Override public float getVolume() { - // TODO Auto-generated method stub - return 0; + return volume; } @Override public void setPan(float pan) { - // TODO Auto-generated method stub - + this.pan = pan; } @Override public float getPan() { - // TODO Auto-generated method stub - return 0; + return pan; } @Override public void dispose() { - // TODO Auto-generated method stub - + try { + audioInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } } } diff --git a/core/src/zero1hd/rhythmbullet/audio/processor/PCMProcessor.java b/core/src/zero1hd/rhythmbullet/audio/processor/PCMProcessor.java index d0e3a3d..65e24e9 100755 --- a/core/src/zero1hd/rhythmbullet/audio/processor/PCMProcessor.java +++ b/core/src/zero1hd/rhythmbullet/audio/processor/PCMProcessor.java @@ -13,7 +13,7 @@ public interface PCMProcessor extends Disposable { /** * @return number of channels */ - public int getChannels(); + public boolean isStereo(); /** * @return sample rate diff --git a/core/src/zero1hd/rhythmbullet/audio/processor/WAVPCMProcessor.java b/core/src/zero1hd/rhythmbullet/audio/processor/WAVPCMProcessor.java index c054b56..ce29fe9 100755 --- a/core/src/zero1hd/rhythmbullet/audio/processor/WAVPCMProcessor.java +++ b/core/src/zero1hd/rhythmbullet/audio/processor/WAVPCMProcessor.java @@ -1,7 +1,7 @@ package zero1hd.rhythmbullet.audio.processor; -import java.io.File; import java.io.IOException; +import java.nio.file.Path; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; @@ -9,18 +9,18 @@ import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; public class WAVPCMProcessor implements PCMProcessor { - private int channels; + private boolean stereo; private int sampleRate; private byte[] buffer; - private File file; + private Path path; private AudioInputStream audioInputStream; private volatile float volume, pan; private boolean initiated; - public WAVPCMProcessor(File musicFile, int windowSize) throws IOException, UnsupportedAudioFileException { - this.file = musicFile; - AudioFormat format = AudioSystem.getAudioFileFormat(file).getFormat(); - channels = format.getChannels(); + public WAVPCMProcessor(Path path, int windowSize) throws IOException, UnsupportedAudioFileException { + this.path = path; + AudioFormat format = AudioSystem.getAudioFileFormat(path.toFile()).getFormat(); + stereo = format.getChannels() > 1 ? true : false; sampleRate = (int) format.getSampleRate(); volume = 1f; } @@ -28,7 +28,7 @@ public class WAVPCMProcessor implements PCMProcessor { @Override public void initiate() { try { - audioInputStream = AudioSystem.getAudioInputStream(file); + audioInputStream = AudioSystem.getAudioInputStream(path.toFile()); } catch (UnsupportedAudioFileException | IOException e) { e.printStackTrace(); } @@ -36,8 +36,8 @@ public class WAVPCMProcessor implements PCMProcessor { initiated = true; } - public int getChannels() { - return channels; + public boolean isStereo() { + return stereo; } public int getSampleRate() { @@ -54,7 +54,7 @@ public class WAVPCMProcessor implements PCMProcessor { if (audioInputStream.read(buffer) > 0) { pcm[sampleID] = (short) ((buffer[1] << 8) + (buffer[0] & 0x00ff)); pcm[sampleID] *= volume * (Math.min(1-pan, 1)); - if (audioInputStream.getFormat().getChannels() > 1) { + if (stereo) { short secondChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff)); secondChan *= volume * (Math.min(1+pan, 1)); sampleID++; @@ -96,7 +96,10 @@ public class WAVPCMProcessor implements PCMProcessor { @Override public void dispose() { - // TODO Auto-generated method stub - + try { + audioInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } } } \ No newline at end of file