initial attempt at implementing mp3
This commit is contained in:
parent
d92af2b964
commit
d32794152d
@ -68,18 +68,15 @@ project(":android") {
|
||||
|
||||
project(":core") {
|
||||
apply plugin: "java"
|
||||
|
||||
|
||||
dependencies {
|
||||
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
|
||||
compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
|
||||
|
||||
compile group: 'com.googlecode.soundlibs', name: 'mp3spi', version: '1.9.5.4'
|
||||
|
||||
compile group: 'com.badlogicgames.jlayer', name: 'jlayer', version: '1.0.1-gdx'
|
||||
compile "org.apache.commons:commons-math3:3.2"
|
||||
|
||||
compile "com.github.rwl:jtransforms:2.4.0"
|
||||
|
||||
|
||||
compile "org:jaudiotagger:2.0.3"
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public class AudioAnalyzer {
|
||||
mThresholdCalcRange = thresholdRangeCalc(0.4f);
|
||||
umThresholdCalcRange = thresholdRangeCalc(0.4f);
|
||||
|
||||
Gdx.app.debug("Read freq", String.valueOf(audioData.getFormat().getSampleRate()));
|
||||
Gdx.app.debug("Read freq", String.valueOf(audioData.getSampleRate()));
|
||||
Gdx.app.debug("Using following bin ranges", "\nBass freq begin: " + bassBinBegin + "\nBass freq end: " + bassBinEnd + "\nMain freq begin: " + umBinBegin + "\nMain freq end: " + umBinEnd);
|
||||
|
||||
|
||||
@ -221,7 +221,7 @@ public class AudioAnalyzer {
|
||||
}
|
||||
Gdx.app.debug("Audio Analyzer", "Data prunned.");
|
||||
|
||||
secondsPerWindow = audioData.getReadWindowSize()/audioData.getFormat().getSampleRate();
|
||||
secondsPerWindow = audioData.getReadWindowSize()/audioData.getSampleRate();
|
||||
//peak detection
|
||||
|
||||
int lastID = 0;
|
||||
@ -349,7 +349,7 @@ public class AudioAnalyzer {
|
||||
}
|
||||
|
||||
private int thresholdRangeCalc(float durationOfRange) {
|
||||
return (int) (durationOfRange/(audioData.getReadWindowSize()/audioData.getFormat().getSampleRate()));
|
||||
return (int) (durationOfRange/(audioData.getReadWindowSize()/audioData.getSampleRate()));
|
||||
}
|
||||
|
||||
public float getBassMaxValue() {
|
||||
|
@ -1,7 +1,5 @@
|
||||
package zero1hd.rhythmbullet.audio;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
@ -42,12 +40,6 @@ public interface AudioData extends Disposable {
|
||||
*/
|
||||
public int readSamples(float[] samples);
|
||||
|
||||
/**
|
||||
* Returns properly setup AudioFormat object.
|
||||
* @return
|
||||
*/
|
||||
public AudioFormat getFormat();
|
||||
|
||||
/**
|
||||
* returns sample count
|
||||
* @return
|
||||
@ -59,4 +51,10 @@ public interface AudioData extends Disposable {
|
||||
* @return
|
||||
*/
|
||||
public float getDuration();
|
||||
|
||||
/**
|
||||
* returns sample rate
|
||||
* @return sample rate as float
|
||||
*/
|
||||
public float getSampleRate();
|
||||
}
|
||||
|
@ -1,14 +1,6 @@
|
||||
package zero1hd.rhythmbullet.audio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
@ -19,54 +11,45 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
import javazoom.jl.decoder.Decoder;
|
||||
import javazoom.jl.decoder.Bitstream;
|
||||
import javazoom.jl.decoder.BitstreamException;
|
||||
import javazoom.jl.decoder.DecoderException;
|
||||
import javazoom.jl.decoder.MP3Decoder;
|
||||
import javazoom.jl.decoder.OutputBuffer;
|
||||
|
||||
public class Mp3AudioData implements AudioData {
|
||||
private int readWindowSize = 1024;
|
||||
|
||||
private AudioInputStream din;
|
||||
|
||||
private AudioFormat decodedFormat;
|
||||
private Music playbackMusic;
|
||||
private int readIndex;
|
||||
|
||||
|
||||
private int sampleRate;
|
||||
private int sampleCount;
|
||||
private float durationInSeconds;
|
||||
|
||||
private AudioInputStream in;
|
||||
|
||||
Decoder decoder = new Decoder();
|
||||
Bitstream bitStream;
|
||||
MP3Decoder decoder;
|
||||
public Mp3AudioData(FileHandle audioFile) {
|
||||
try {
|
||||
MP3File mp3File = new MP3File(audioFile.file());
|
||||
|
||||
sampleCount = (int) mp3File.getMP3AudioHeader().getNumberOfFrames();
|
||||
durationInSeconds = mp3File.getMP3AudioHeader().getNumberOfFrames()/readWindowSize;
|
||||
sampleRate = mp3File.getMP3AudioHeader().getSampleRateAsNumber();
|
||||
|
||||
bitStream = new Bitstream(audioFile.read());
|
||||
decoder = new MP3Decoder();
|
||||
} catch (IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
reset();
|
||||
|
||||
try {
|
||||
File file = audioFile.file();
|
||||
in = AudioSystem.getAudioInputStream(file);
|
||||
din = null;
|
||||
AudioFormat baseFormat = in.getFormat();
|
||||
decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,
|
||||
baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
|
||||
din = AudioSystem.getAudioInputStream(decodedFormat, in);
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
playbackMusic = Gdx.audio.newMusic(audioFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readIndexUpdate() {
|
||||
readIndex = (int) (playbackMusic.getPosition() * decodedFormat.getSampleRate() / readWindowSize);
|
||||
readIndex = (int) (playbackMusic.getPosition() * sampleRate / readWindowSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,9 +59,7 @@ public class Mp3AudioData implements AudioData {
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
if (playbackMusic != null) {
|
||||
playbackMusic.stop();
|
||||
}
|
||||
playbackMusic.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,48 +72,6 @@ public class Mp3AudioData implements AudioData {
|
||||
return playbackMusic;
|
||||
}
|
||||
|
||||
byte[] toBeConverted = new byte[2];
|
||||
|
||||
@Override
|
||||
public int readSamples(float[] samples) {
|
||||
int samplesRead = 0;
|
||||
short sampleAverage = 0;
|
||||
|
||||
|
||||
for (int currentSample = 0; currentSample < samples.length; currentSample++) {
|
||||
for (int channel = 0; channel < decodedFormat.getChannels(); channel++) {
|
||||
try {
|
||||
int readCount = din.read(toBeConverted, 0, toBeConverted.length);
|
||||
|
||||
ByteBuffer bBuffer = ByteBuffer.allocate(2);
|
||||
bBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
bBuffer.put(toBeConverted[0]);
|
||||
bBuffer.put(toBeConverted[1]);
|
||||
|
||||
sampleAverage += bBuffer.getShort(0);
|
||||
|
||||
if (readCount == -1) {
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
sampleAverage /= decodedFormat.getChannels() * Short.MAX_VALUE + 1;
|
||||
samples[currentSample] = sampleAverage;
|
||||
sampleAverage = 0;
|
||||
samplesRead++;
|
||||
}
|
||||
return samplesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioFormat getFormat() {
|
||||
return decodedFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSampleCount() {
|
||||
return sampleCount;
|
||||
@ -142,15 +81,6 @@ public class Mp3AudioData implements AudioData {
|
||||
public void dispose() {
|
||||
reset();
|
||||
playbackMusic.dispose();
|
||||
if (din != null) {
|
||||
try {
|
||||
din.close();
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -158,4 +88,33 @@ public class Mp3AudioData implements AudioData {
|
||||
return durationInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readSamples(float[] samples) {
|
||||
int samplesRead = 0;
|
||||
try {
|
||||
OutputBuffer samplesBuffer = decoder.decodeFrame(bitStream.readFrame(), bitStream);
|
||||
byte[] frameBuffer = samplesBuffer.getBuffer();
|
||||
for (int sampleID = 0; sampleID < samples.length; sampleID++) {
|
||||
|
||||
samples[sampleID] += (short) ((frameBuffer[1] << 8) + (frameBuffer[0] & 0xff));
|
||||
if (samplesBuffer.isStereo()) {
|
||||
samples[sampleID] = (short) ((frameBuffer[3] << 8) + (frameBuffer[2] & 0xff));
|
||||
|
||||
samples[sampleID] /= 2;
|
||||
}
|
||||
|
||||
samples[sampleID] /= Short.MAX_VALUE+1;
|
||||
samplesRead ++;
|
||||
}
|
||||
} catch (DecoderException | BitstreamException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return samplesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSampleRate() {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,11 +64,6 @@ public class WavAudioData implements AudioData {
|
||||
return decoder.readSamples(samples);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioFormat getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSampleCount() {
|
||||
return decoder.getDataSize()/(2*decoder.getChannels());
|
||||
@ -85,4 +80,9 @@ public class WavAudioData implements AudioData {
|
||||
public float getDuration() {
|
||||
return decoder.getDurationInSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSampleRate() {
|
||||
return format.getSampleRate();
|
||||
}
|
||||
}
|
||||
|
@ -114,13 +114,6 @@ public class RhythmMapAlgorithm implements Runnable {
|
||||
esi.parameters.put("fuse", avgSPB*10f);
|
||||
esi.parameters.put("angle", angle);
|
||||
} else {
|
||||
float xSpawnLocation = (rand.nextFloat()*(RhythmBullet.GAME_AREA_WIDTH-2))+1;
|
||||
|
||||
esi = map.addEntity(em.pellet, null);
|
||||
esi.parameters.put("x", xSpawnLocation);
|
||||
esi.parameters.put("y", RhythmBullet.GAME_AREA_HEIGHT-0.25f);
|
||||
esi.parameters.put("angle", 140*rand.nextFloat()+200f);
|
||||
esi.parameters.put("speed", (RhythmBullet.GAME_AREA_HEIGHT/8f)/avgSPB);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -158,6 +158,7 @@ public class Entity extends Actor implements Poolable {
|
||||
sprite.setPosition(0, 0);
|
||||
hitbox.set(0, 0, 0, 0);
|
||||
sprite.setRotation(0);
|
||||
sprite.setColor(Color.WHITE);
|
||||
setPosition(0, 0);
|
||||
center.set(0, 0);
|
||||
angle = 0;
|
||||
|
@ -37,7 +37,6 @@ public class Flake extends Entity {
|
||||
this.timer = fuse;
|
||||
this.totalTime = fuse;
|
||||
this.angle = angle;
|
||||
hitbox.setSize(getWidth(), getHeight());
|
||||
setPosition(x-getWidth()/2f, y-getHeight()/2f);
|
||||
|
||||
}
|
||||
@ -86,7 +85,7 @@ public class Flake extends Entity {
|
||||
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
sprite.setColor(0.1f,0.1f,0.1f, timer/totalTime);
|
||||
sprite.setColor(0f, 0f, 0f, 1-(timer/totalTime));
|
||||
super.draw(batch, parentAlpha);
|
||||
}
|
||||
|
||||
@ -109,7 +108,6 @@ public class Flake extends Entity {
|
||||
public void reset() {
|
||||
timer = 0;
|
||||
shards = null;
|
||||
hitbox.set(0, 0, 0, 0);
|
||||
totalTime = 0;
|
||||
super.reset();
|
||||
}
|
||||
|
@ -72,6 +72,8 @@ public class Shard extends Entity {
|
||||
public void collided(Entity entity) {
|
||||
if (entity.getClass() == Laser.class) {
|
||||
hp --;
|
||||
} else {
|
||||
dead = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class CreativeScreen extends ScreenAdapter {
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1f);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
bgBatch.begin();
|
||||
bgBatch.draw(background, 0f, 0f);
|
||||
|
@ -95,7 +95,7 @@ public class GameScreen extends ScreenAdapter {
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
//Background stuff should literally span the whole screen so no matrice stuff
|
||||
bgBatch.begin();
|
||||
if (bgShader != null) {
|
||||
|
@ -120,14 +120,18 @@ public class GameHUD extends Stage {
|
||||
setScore(sm.getScore());
|
||||
}
|
||||
|
||||
if (gpa.getAudioMap() != null && gpa.getAudioMap().getHudType()[gpa.getAudioMap().getIndex()] != 0) {
|
||||
switch (gpa.getAudioMap().getHudType()[gpa.getAudioMap().getIndex()]) {
|
||||
case 1:
|
||||
changeStatusColor(bass, 0.2f, original);
|
||||
break;
|
||||
case 2:
|
||||
changeStatusColor(um, 0.2f, original);
|
||||
try {
|
||||
if (gpa.getAudioMap() != null && gpa.getAudioMap().getHudType()[gpa.getAudioMap().getIndex()] != 0) {
|
||||
switch (gpa.getAudioMap().getHudType()[gpa.getAudioMap().getIndex()]) {
|
||||
case 1:
|
||||
changeStatusColor(bass, 0.2f, original);
|
||||
break;
|
||||
case 2:
|
||||
changeStatusColor(um, 0.2f, original);
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
Gdx.app.debug("GameHUD", "reached end of status data.");
|
||||
}
|
||||
super.act(delta);
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ public class MusicController extends Window implements OnCompletionListener {
|
||||
info.setText("Ready.");
|
||||
audiofile.getPlaybackMusic().play();
|
||||
audiofile.getPlaybackMusic().pause();
|
||||
audiofile.getPlaybackMusic().setOnCompletionListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user