progress on mp3 pcm processor

This commit is contained in:
Harrison Deng 2018-06-25 20:52:00 -05:00
parent 92ff8871a9
commit aceaa7c89f
5 changed files with 89 additions and 48 deletions

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -13,7 +13,7 @@ public interface PCMProcessor extends Disposable {
/**
* @return number of channels
*/
public int getChannels();
public boolean isStereo();
/**
* @return sample rate

View File

@ -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();
}
}
}