starting work on visualizer

This commit is contained in:
Harrison Deng 2017-09-04 01:55:56 -05:00
parent 3fca2c57bf
commit c45551f1d2
11 changed files with 73 additions and 24 deletions

View File

@ -12,7 +12,6 @@ import zero1hd.rhythmbullet.util.MiniSender;
public class AudioAnalyzer { public class AudioAnalyzer {
private boolean containsData; private boolean containsData;
FloatFFT_1D fft;
private CoreMusicInfo musicInfo; private CoreMusicInfo musicInfo;
float[] audioPCM; float[] audioPCM;
@ -91,7 +90,7 @@ public class AudioAnalyzer {
Gdx.app.debug("Threshold Calc Range M", String.valueOf(umThresholdCalcRange)); Gdx.app.debug("Threshold Calc Range M", String.valueOf(umThresholdCalcRange));
Gdx.app.debug("Threshold Calc Range Bass", String.valueOf(bassThresholdCalcRange)); Gdx.app.debug("Threshold Calc Range Bass", String.valueOf(bassThresholdCalcRange));
fft = new FloatFFT_1D(musicInfo.getReadWindowSize()); FloatFFT_1D fft = new FloatFFT_1D(musicInfo.getReadWindowSize());
int seedDigit = 0; int seedDigit = 0;
while (musicInfo.readSamples(audioPCM) > 0 && work) { while (musicInfo.readSamples(audioPCM) > 0 && work) {
@ -311,12 +310,6 @@ public class AudioAnalyzer {
exec.submit(analysisAlgorithm); exec.submit(analysisAlgorithm);
} }
public void shrinkData() {
bassSpectralFlux = null;
mSpectralFlux = null;
umSpectralFlux = null;
}
public void runThresholdCleaning(float rangeModifier) { public void runThresholdCleaning(float rangeModifier) {
this.bassThresholdMultiplier -= rangeModifier; this.bassThresholdMultiplier -= rangeModifier;
this.umThresholdMultiplier -= rangeModifier; this.umThresholdMultiplier -= rangeModifier;

View File

@ -46,8 +46,6 @@ public class AudioInfo implements Disposable {
e.printStackTrace(); e.printStackTrace();
} }
// invalidMusic = true;
} else { } else {
try { try {

View File

@ -9,13 +9,13 @@ public interface CoreMusicInfo extends Disposable {
* sets a integer variable to the current window of audio data the playback is at. * sets a integer variable to the current window of audio data the playback is at.
* Useful for efficiency because we compute once for that frame then get the values everytime it is required instead of calculating every time we get the index. * Useful for efficiency because we compute once for that frame then get the values everytime it is required instead of calculating every time we get the index.
*/ */
public void readIndexUpdate(); public void playbackIndexUpdate();
/** /**
* Gets the current position in seconds s * Gets the current position in seconds s
* @return the current frame of audio. * @return the current frame of audio.
*/ */
public int getReadIndex(); public int getPlaybackIndexPosition();
/** /**
* Completely resets the current audio data. Think of pooling, except, only one instance which is reused instead of multiple. * Completely resets the current audio data. Think of pooling, except, only one instance which is reused instead of multiple.
@ -59,4 +59,10 @@ public interface CoreMusicInfo extends Disposable {
* @return sample rate as float * @return sample rate as float
*/ */
public float getSampleRate(); public float getSampleRate();
/**
* The current numerical value of the last window read
* @return
*/
public int getCurrentReadWindowIndex();
} }

View File

@ -23,6 +23,7 @@ import javazoom.jl.decoder.OutputBuffer;
public class Mp3AudioData implements CoreMusicInfo { public class Mp3AudioData implements CoreMusicInfo {
private int readWindowSize = 1024; private int readWindowSize = 1024;
private int currentReadWindowIndex;
private Music playbackMusic; private Music playbackMusic;
private int readIndex; private int readIndex;
@ -67,12 +68,12 @@ public class Mp3AudioData implements CoreMusicInfo {
} }
@Override @Override
public void readIndexUpdate() { public void playbackIndexUpdate() {
readIndex = (int) (playbackMusic.getPosition() * sampleRate / readWindowSize); readIndex = (int) (playbackMusic.getPosition() * sampleRate / readWindowSize);
} }
@Override @Override
public int getReadIndex() { public int getPlaybackIndexPosition() {
return readIndex; return readIndex;
} }
@ -130,6 +131,9 @@ public class Mp3AudioData implements CoreMusicInfo {
samples[sid] /= Short.MAX_VALUE+1; samples[sid] /= Short.MAX_VALUE+1;
} }
} }
if (framesRead != 0) {
currentReadWindowIndex++;
}
return framesRead; return framesRead;
} }
@ -175,4 +179,9 @@ public class Mp3AudioData implements CoreMusicInfo {
public float getSampleRate() { public float getSampleRate() {
return sampleRate; return sampleRate;
} }
@Override
public int getCurrentReadWindowIndex() {
return currentReadWindowIndex;
}
} }

View File

@ -14,7 +14,8 @@ import zero1hd.wavedecoder.WavDecoder;
public class WavAudioData implements CoreMusicInfo { public class WavAudioData implements CoreMusicInfo {
private int readWindowSize = 1024; private int readWindowSize = 1024;
private AudioFormat format; private AudioFormat format;
int readIndex; private int readIndex;
private int currentReadWindowIndex;
Music playbackMusic; Music playbackMusic;
WavDecoder decoder; WavDecoder decoder;
@ -31,12 +32,12 @@ public class WavAudioData implements CoreMusicInfo {
} }
@Override @Override
public void readIndexUpdate() { public void playbackIndexUpdate() {
readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize); readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize);
} }
@Override @Override
public int getReadIndex() { public int getPlaybackIndexPosition() {
return readIndex; return readIndex;
} }
@ -65,6 +66,10 @@ public class WavAudioData implements CoreMusicInfo {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (samplesRead != 0) {
currentReadWindowIndex++;
}
return samplesRead; return samplesRead;
} }
@ -89,4 +94,9 @@ public class WavAudioData implements CoreMusicInfo {
public float getSampleRate() { public float getSampleRate() {
return format.getSampleRate(); return format.getSampleRate();
} }
@Override
public int getCurrentReadWindowIndex() {
return currentReadWindowIndex;
}
} }

View File

@ -91,8 +91,8 @@ public class GamePlayMap {
} }
public MapWindowData getCurrentWindowBasedOnIndex() { public MapWindowData getCurrentWindowBasedOnIndex() {
if (index != musicData.getReadIndex()) { if (index != musicData.getPlaybackIndexPosition()) {
index = musicData.getReadIndex(); index = musicData.getPlaybackIndexPosition();
if (index < spawnList.length) { if (index < spawnList.length) {
return spawnList[index]; return spawnList[index];
} }

View File

@ -60,7 +60,7 @@ public class GamePlayArea extends Stage {
public void act(float delta) { public void act(float delta) {
MapWindowData mwd; MapWindowData mwd;
if (audioMap != null && audioMap.getMusicData().getPlaybackMusic().isPlaying()) { if (audioMap != null && audioMap.getMusicData().getPlaybackMusic().isPlaying()) {
audioMap.getMusicData().readIndexUpdate(); audioMap.getMusicData().playbackIndexUpdate();
if ((mwd = audioMap.getCurrentWindowBasedOnIndex()) != null) { if ((mwd = audioMap.getCurrentWindowBasedOnIndex()) != null) {
EntitySpawnInfo[] currentSpawnInfo = mwd.getArray(); EntitySpawnInfo[] currentSpawnInfo = mwd.getArray();
if (currentSpawnInfo != null) { if (currentSpawnInfo != null) {

View File

@ -123,7 +123,7 @@ public class AudioGraph extends Actor {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (audioData != null) { if (audioData != null) {
setAudioDataIndex(audioData.getReadIndex()); setAudioDataIndex(audioData.getPlaybackIndexPosition());
} }
super.act(delta); super.act(delta);
} }

View File

@ -123,7 +123,7 @@ public class AudioGraphRelation extends Actor {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (audioData != null) { if (audioData != null) {
setAudioDataIndex(audioData.getReadIndex()); setAudioDataIndex(audioData.getPlaybackIndexPosition());
} }
super.act(delta); super.act(delta);
} }

View File

@ -0,0 +1,33 @@
package zero1hd.rhythmbullet.ui.builders;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.Actor;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
import zero1hd.rhythmbullet.audio.CoreMusicInfo;
public class Visualizer extends Actor {
private CoreMusicInfo cmi;
private FloatFFT_1D fft;
float[] audioPCM;
public Visualizer() {
fft = new FloatFFT_1D(cmi.getReadWindowSize());
audioPCM = new float[cmi.getReadWindowSize()];
setSize(Gdx.graphics.getHeight()*0.6f, Gdx.graphics.getHeight()*0.6f);
}
@Override
public void act(float delta) {
if (cmi.getPlaybackIndexPosition() > cmi.getCurrentReadWindowIndex()) {
cmi.readSamples(audioPCM);
Gdx.app.debug("Visualizer", "Skipping a frame to catch up to music.");
} else {
Gdx.app.debug("Visualizer", "Not reading so music can catch up.");
}
fft.realForward(audioPCM);
super.act(delta);
}
}

View File

@ -120,7 +120,7 @@ public class BeatViewer extends Window {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (music != null) { if (music != null) {
songIndex = music.getReadIndex(); songIndex = music.getPlaybackIndexPosition();
} }
super.act(delta); super.act(delta);
} }