removed creative screen; re-organized analysis system; analysis page progress; problems with analysis system needs to be fixed
This commit is contained in:
parent
07cc783624
commit
7d0f3a365d
0
android/assets/shaders/chrome_abb.fsh
Executable file
0
android/assets/shaders/chrome_abb.fsh
Executable file
@ -1,358 +0,0 @@
|
||||
package zero1hd.rhythmbullet.audio;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
|
||||
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
|
||||
import zero1hd.rhythmbullet.util.MiniEvents;
|
||||
import zero1hd.rhythmbullet.util.MiniSender;
|
||||
|
||||
public class AudioAnalyzer {
|
||||
private boolean containsData;
|
||||
private MusicManager musicInfo;
|
||||
|
||||
float[] audioPCM;
|
||||
float[] spectrum;
|
||||
float[] lastSpectrum;
|
||||
|
||||
private ExecutorService exec = Executors.newSingleThreadExecutor();
|
||||
private Runnable analysisAlgorithm;
|
||||
private Runnable thresholdCalculator;
|
||||
|
||||
int bassBinBegin;
|
||||
int bassBinEnd;
|
||||
private FloatArray bassSpectralFlux = new FloatArray();
|
||||
private float bassMaxValue;
|
||||
private float bassAvg;
|
||||
float bassThresholdMultiplier;
|
||||
int bassThresholdCalcRange;
|
||||
|
||||
int mBinBegin;
|
||||
int mBinEnd;
|
||||
private FloatArray mSpectralFlux = new FloatArray();
|
||||
private float mMaxValue;
|
||||
private float mAvg;
|
||||
float mThresholdMultiplier;
|
||||
int mThresholdCalcRange;
|
||||
|
||||
int umBinBegin;
|
||||
int umBinEnd;
|
||||
private FloatArray umSpectralFlux = new FloatArray();
|
||||
private float umMaxValue;
|
||||
private float umAvg;
|
||||
float umThresholdMultiplier;
|
||||
int umThresholdCalcRange;
|
||||
|
||||
public MiniSender sender;
|
||||
|
||||
private float avgSPB;
|
||||
|
||||
int PUID;
|
||||
boolean work;
|
||||
private int progress;
|
||||
private float secondsPerWindow;
|
||||
|
||||
private AudioDataPackage pack;
|
||||
public AudioAnalyzer(MusicManager audiofile) {
|
||||
sender = new MiniSender();
|
||||
|
||||
analysisAlgorithm = () -> {
|
||||
progress = 0;
|
||||
int tasksDone = 0;
|
||||
long totalTasks = musicInfo.getSampleCount()/musicInfo.getReadWindowSize();
|
||||
|
||||
bassThresholdMultiplier = 1.5f;
|
||||
mThresholdMultiplier = 1.4f;
|
||||
umThresholdMultiplier = 1.4f;
|
||||
|
||||
bassBinBegin = 0;
|
||||
bassBinEnd = 12;
|
||||
|
||||
mBinBegin = 50;
|
||||
mBinEnd = 250;
|
||||
|
||||
umBinBegin = 350;
|
||||
umBinEnd = 513;
|
||||
|
||||
bassThresholdCalcRange = thresholdRangeCalc(0.27f);
|
||||
mThresholdCalcRange = thresholdRangeCalc(0.4f);
|
||||
umThresholdCalcRange = thresholdRangeCalc(0.4f);
|
||||
|
||||
Gdx.app.debug("Read freq", String.valueOf(musicInfo.getSampleRate()));
|
||||
Gdx.app.debug("Using following bin ranges", "\nBass freq begin: " + bassBinBegin + "\nBass freq end: " + bassBinEnd + "\nMain freq begin: " + umBinBegin + "\nMain freq end: " + umBinEnd);
|
||||
|
||||
Gdx.app.debug("Total tasks", String.valueOf(totalTasks));
|
||||
|
||||
Gdx.app.debug("Threshold Calc Range UM", String.valueOf(umThresholdCalcRange));
|
||||
Gdx.app.debug("Threshold Calc Range M", String.valueOf(umThresholdCalcRange));
|
||||
Gdx.app.debug("Threshold Calc Range Bass", String.valueOf(bassThresholdCalcRange));
|
||||
|
||||
FloatFFT_1D fft = new FloatFFT_1D(musicInfo.getReadWindowSize());
|
||||
int seedDigit = 0;
|
||||
|
||||
while (musicInfo.readSamples(audioPCM) > 0 && work) {
|
||||
|
||||
fft.realForward(audioPCM);
|
||||
|
||||
//Building a PUID (Pseudo unique ID)
|
||||
if (tasksDone == (seedDigit*totalTasks/9)) {
|
||||
float avg = 0;
|
||||
for (int frame = 0; frame < spectrum.length; frame++) {
|
||||
avg += spectrum[frame];
|
||||
}
|
||||
avg /= spectrum.length;
|
||||
if (avg < 0) {
|
||||
avg *= -1f;
|
||||
}
|
||||
PUID +=(int) Math.pow(10, 9-seedDigit) * ((int)(avg*1000f)-(int)(avg*100f)*10);
|
||||
seedDigit ++;
|
||||
}
|
||||
|
||||
System.arraycopy(spectrum, 0, lastSpectrum, 0, spectrum.length);
|
||||
System.arraycopy(audioPCM, 0, spectrum, 0, spectrum.length);
|
||||
|
||||
float fluxVal;
|
||||
//bass detection
|
||||
fluxVal = 0;
|
||||
for (int i = bassBinBegin; i < bassBinEnd; i++) {
|
||||
fluxVal += ((spectrum[i] - lastSpectrum[i])) < 0
|
||||
? 0 : (spectrum[i] - lastSpectrum[i]);
|
||||
}
|
||||
bassSpectralFlux.add(fluxVal);
|
||||
|
||||
//m detection
|
||||
fluxVal = 0;
|
||||
for (int i = mBinBegin; i < mBinEnd; i++) {
|
||||
fluxVal += ((spectrum[i] - lastSpectrum[i])) < 0
|
||||
? 0 : (spectrum[i] - lastSpectrum[i]);
|
||||
}
|
||||
mSpectralFlux.add(fluxVal);
|
||||
|
||||
//um detection
|
||||
fluxVal = 0;
|
||||
for (int i = umBinBegin; i < umBinEnd; i++) {
|
||||
fluxVal += ((spectrum[i] - lastSpectrum[i])) < 0
|
||||
? 0 : (spectrum[i] - lastSpectrum[i]);
|
||||
}
|
||||
umSpectralFlux.add(fluxVal);
|
||||
tasksDone++;
|
||||
progress = (int) (100f*tasksDone/totalTasks);
|
||||
sender.send(MiniEvents.ANALYZER_ITERATED);
|
||||
}
|
||||
|
||||
if (work) {
|
||||
Gdx.app.debug("Audio Analyzer", "Done getting spectral flux.");
|
||||
Gdx.app.debug("Audio Analyzer", "window count: " + bassSpectralFlux.size);
|
||||
containsData = true;
|
||||
Gdx.app.debug("Audio Analyzer", "USING SEED: " + PUID);
|
||||
progress = 100;
|
||||
sender.send(MiniEvents.SPECTRAL_FLUX_DONE);
|
||||
}
|
||||
};
|
||||
|
||||
thresholdCalculator = () -> {
|
||||
Gdx.app.debug("Audio Analyzer", "beginning threshold calc.");
|
||||
FloatArray bassThreshold = new FloatArray();
|
||||
FloatArray mThreshold = new FloatArray();
|
||||
FloatArray umThreshold = new FloatArray();
|
||||
//threshold calculation
|
||||
for (int i = 0; i < umSpectralFlux.size && work; i++) {
|
||||
int start = Math.max(0, i - umThresholdCalcRange/2);
|
||||
int end = Math.min(umSpectralFlux.size - 1, i + umThresholdCalcRange/2);
|
||||
|
||||
float average = 0;
|
||||
for (int j = start; j <= end; j++) {
|
||||
average += bassSpectralFlux.get(j);
|
||||
}
|
||||
average /= (end - start);
|
||||
bassThreshold.add(average * bassThresholdMultiplier);
|
||||
|
||||
average = 0;
|
||||
for (int j = start; j <= end; j++) {
|
||||
average+= mSpectralFlux.get(j);
|
||||
}
|
||||
average /= (end - start);
|
||||
mThreshold.add(average*mThresholdMultiplier);
|
||||
|
||||
average = 0;
|
||||
for (int j = start; j <= end; j++) {
|
||||
average+= umSpectralFlux.get(j);
|
||||
}
|
||||
average /= (end - start);
|
||||
umThreshold.add(average*umThresholdMultiplier);
|
||||
}
|
||||
|
||||
Gdx.app.debug("Audio Analyzer", "Threshold calculated.");
|
||||
|
||||
//pruning data
|
||||
float prunnedCurrentVal;
|
||||
FloatArray bassPrunned = new FloatArray();
|
||||
FloatArray mPrunned = new FloatArray();
|
||||
FloatArray umPrunned = new FloatArray();
|
||||
for (int i = 0; i < umSpectralFlux.size && work; i++) {
|
||||
prunnedCurrentVal = bassSpectralFlux.get(i) - bassThreshold.get(i);
|
||||
if (prunnedCurrentVal >= 0) {
|
||||
bassPrunned.add(prunnedCurrentVal);
|
||||
} else {
|
||||
bassPrunned.add(0);
|
||||
}
|
||||
|
||||
prunnedCurrentVal = mSpectralFlux.get(i) - mThreshold.get(i);
|
||||
if (prunnedCurrentVal >= 0 ) {
|
||||
mPrunned.add(prunnedCurrentVal);
|
||||
} else {
|
||||
mPrunned.add(0);
|
||||
}
|
||||
|
||||
prunnedCurrentVal = umSpectralFlux.get(i) - umThreshold.get(i);
|
||||
if (prunnedCurrentVal >= 0 ) {
|
||||
umPrunned.add(prunnedCurrentVal);
|
||||
} else {
|
||||
umPrunned.add(0);
|
||||
}
|
||||
}
|
||||
Gdx.app.debug("Audio Analyzer", "Data prunned.");
|
||||
|
||||
secondsPerWindow = musicInfo.getReadWindowSize()/musicInfo.getSampleRate();
|
||||
//peak detection
|
||||
|
||||
int lastID = 0;
|
||||
float bassBeats = 0;
|
||||
float mBeats = 0;
|
||||
float umBeats = 0;
|
||||
avgSPB = -1f;
|
||||
FloatArray bassPeaks = new FloatArray();
|
||||
FloatArray mPeaks = new FloatArray();
|
||||
FloatArray umPeaks = new FloatArray();
|
||||
for (int i = 0; i < umPrunned.size-1 && work; i++) {
|
||||
bassPeaks.add((bassPrunned.get(i) > bassPrunned.get(i+1) ? bassPrunned.get(i) : 0f));
|
||||
if (bassPeaks.get(i) > bassMaxValue) {
|
||||
bassMaxValue = bassPeaks.get(i);
|
||||
}
|
||||
|
||||
mPeaks.add((mPrunned.get(i) > mPrunned.get(i+1) ? mPrunned.get(i) : 0f));
|
||||
if (mPeaks.get(i) > mMaxValue) {
|
||||
mMaxValue = mPeaks.get(i);
|
||||
}
|
||||
|
||||
umPeaks.add((umPrunned.get(i) > umPrunned.get(i+1) ? umPrunned.get(i) : 0f));
|
||||
if (umPeaks.get(i) > umMaxValue) {
|
||||
umMaxValue = umPeaks.get(i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (avgSPB != -1) {
|
||||
if (bassPeaks.get(i) == 0) {
|
||||
avgSPB ++;
|
||||
} else {
|
||||
lastID = i;
|
||||
}
|
||||
} else if (bassPeaks.get(i) != 0) {
|
||||
avgSPB = 0;
|
||||
}
|
||||
|
||||
if (bassPeaks.get(i) != 0) {
|
||||
bassAvg += bassPeaks.get(i);
|
||||
bassBeats++;
|
||||
}
|
||||
|
||||
if (mPeaks.get(i) != 0) {
|
||||
mAvg += mPeaks.get(i);
|
||||
mBeats++;
|
||||
}
|
||||
|
||||
if (umPeaks.get(i) != 0) {
|
||||
umAvg += umPeaks.get(i);
|
||||
umBeats++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//then we minus one from the beats so it actually works out
|
||||
avgSPB -= bassPrunned.size-lastID;
|
||||
avgSPB *= secondsPerWindow;
|
||||
avgSPB /= bassBeats;
|
||||
Gdx.app.debug("Audio Analyzer", "Avg SPB: " + avgSPB);
|
||||
|
||||
bassAvg /= bassBeats;
|
||||
mAvg /= mBeats;
|
||||
umAvg /= umBeats;
|
||||
Gdx.app.debug("Audio Analyzer", "Avg bass: " + bassAvg);
|
||||
Gdx.app.debug("Audio Analyzer", "Avg M: " + mAvg);
|
||||
Gdx.app.debug("Audio Analyzer", "Avg UM: " + umAvg);
|
||||
|
||||
pack = new AudioDataPackage();
|
||||
pack.setBassData(bassPeaks, bassMaxValue, bassAvg);
|
||||
pack.setmData(mPeaks, mMaxValue, mAvg);
|
||||
pack.setUmData(umPeaks, umMaxValue, umAvg);
|
||||
|
||||
pack.setPUID(PUID);
|
||||
pack.setAvgSPB(avgSPB);
|
||||
pack.setSecPerWin(secondsPerWindow);
|
||||
pack.setMusicInfo(musicInfo);
|
||||
|
||||
if (work) {
|
||||
Gdx.app.debug("Audio Analyzer", "data cleaned and ready for map gen.");
|
||||
sender.send(MiniEvents.MUSIC_DATA_CLEANED);
|
||||
}
|
||||
};
|
||||
|
||||
audioPCM = new float[audiofile.getReadWindowSize()];
|
||||
spectrum = new float[(audiofile.getReadWindowSize()/2)+1];
|
||||
lastSpectrum = new float[(audiofile.getReadWindowSize()/2)+1];
|
||||
this.musicInfo = audiofile;
|
||||
work = true;
|
||||
|
||||
exec.submit(analysisAlgorithm);
|
||||
}
|
||||
|
||||
public void runThresholdCleaning(float rangeModifier) {
|
||||
this.bassThresholdMultiplier -= rangeModifier;
|
||||
this.umThresholdMultiplier -= rangeModifier;
|
||||
work = true;
|
||||
|
||||
if (containsData) {
|
||||
exec.submit(thresholdCalculator);
|
||||
} else {
|
||||
throw new NullPointerException("Either you didn't start the spectral flux gen, or you didn't let it finish.");
|
||||
}
|
||||
}
|
||||
|
||||
public void runThresholdCleaning() {
|
||||
work = true;
|
||||
if (containsData) {
|
||||
exec.submit(thresholdCalculator);
|
||||
} else {
|
||||
throw new NullPointerException("Either you didn't start the spectral flux gen, or you didn't let it finish.");
|
||||
}
|
||||
}
|
||||
|
||||
private int thresholdRangeCalc(float durationOfRange) {
|
||||
return (int) (durationOfRange/(musicInfo.getReadWindowSize()/musicInfo.getSampleRate()));
|
||||
}
|
||||
|
||||
public boolean containsData() {
|
||||
return containsData;
|
||||
}
|
||||
|
||||
public synchronized int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
work = false;
|
||||
exec.shutdown();
|
||||
}
|
||||
public synchronized AudioDataPackage getAudioDataPackage() {
|
||||
if (pack != null) {
|
||||
exec.shutdown();
|
||||
return pack;
|
||||
} else {
|
||||
throw new NullPointerException("Pack isn't filled yet... You made a mistake somewhere!");
|
||||
}
|
||||
}
|
||||
}
|
@ -45,6 +45,11 @@ public class MusicList extends Observable {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an audio manager for the given music file.
|
||||
* @param file
|
||||
* @return a music manager of the given music file.
|
||||
*/
|
||||
public MusicManager getAudioData(FileHandle file) {
|
||||
if (file.extension().equalsIgnoreCase("wav")) {
|
||||
return new WAVManager(file);
|
||||
|
50
core/src/zero1hd/rhythmbullet/audio/analyzer/AudioAnalyzer.java
Executable file
50
core/src/zero1hd/rhythmbullet/audio/analyzer/AudioAnalyzer.java
Executable file
@ -0,0 +1,50 @@
|
||||
package zero1hd.rhythmbullet.audio.analyzer;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
|
||||
public class AudioAnalyzer extends Observable implements Disposable {
|
||||
private ExecutorService exec;
|
||||
|
||||
private SpectralFluxAnalysisRunnable sfar;
|
||||
private ThresholdCalcRunnable tcr;
|
||||
private PruneFluxRunnable pfr;
|
||||
private PeakDetectionRunnable pdr;
|
||||
|
||||
public AudioAnalyzer(MusicManager musicManager) {
|
||||
exec = Executors.newSingleThreadExecutor();
|
||||
sfar = new SpectralFluxAnalysisRunnable(musicManager);
|
||||
tcr = new ThresholdCalcRunnable(sfar);
|
||||
pfr = new PruneFluxRunnable(tcr);
|
||||
pdr = new PeakDetectionRunnable(pfr, sfar.getPUID());
|
||||
}
|
||||
|
||||
public void start() {
|
||||
exec.submit(sfar);
|
||||
exec.submit(tcr);
|
||||
exec.submit(pfr);
|
||||
exec.submit(pdr);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
sfar.work = false;
|
||||
tcr.work = false;
|
||||
pfr.work = false;
|
||||
pdr.work = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
stop();
|
||||
exec.shutdown();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return (sfar.isDone() && tcr.isDone() && pfr.isDone() && pdr.isDone());
|
||||
}
|
||||
}
|
123
core/src/zero1hd/rhythmbullet/audio/analyzer/PeakDetectionRunnable.java
Executable file
123
core/src/zero1hd/rhythmbullet/audio/analyzer/PeakDetectionRunnable.java
Executable file
@ -0,0 +1,123 @@
|
||||
package zero1hd.rhythmbullet.audio.analyzer;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.AudioDataPackage;
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
|
||||
public class PeakDetectionRunnable implements Runnable {
|
||||
boolean work, done;
|
||||
private FloatArray bassPrunned;
|
||||
private FloatArray mPrunned;
|
||||
private FloatArray umPrunned;
|
||||
private FloatArray bassPeaks = new FloatArray();
|
||||
private FloatArray mPeaks = new FloatArray();
|
||||
private FloatArray umPeaks = new FloatArray();
|
||||
private float bassMaxValue;
|
||||
private float mMaxValue;
|
||||
private float umMaxValue;
|
||||
private float secondsPerWindow;
|
||||
private float mAvg;
|
||||
private float bassAvg;
|
||||
private float umAvg;
|
||||
private MusicManager musicManager;
|
||||
private AudioDataPackage pack;
|
||||
private int PUID;
|
||||
|
||||
public PeakDetectionRunnable(PruneFluxRunnable pfr, int PUID) {
|
||||
bassPrunned = pfr.getBassPrunned();
|
||||
mPrunned = pfr.getmPrunned();
|
||||
umPrunned = pfr.getUmPrunned();
|
||||
musicManager = pfr.getMusicManager();
|
||||
this.PUID = PUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int lastID = 0;
|
||||
float bassBeats = 0;
|
||||
float mBeats = 0;
|
||||
float umBeats = 0;
|
||||
float avgSPB = -1f;
|
||||
|
||||
for (int i = 0; i < umPrunned.size-1 && work; i++) {
|
||||
bassPeaks.add((bassPrunned.get(i) > bassPrunned.get(i+1) ? bassPrunned.get(i) : 0f));
|
||||
if (bassPeaks.get(i) > bassMaxValue) {
|
||||
bassMaxValue = bassPeaks.get(i);
|
||||
}
|
||||
|
||||
mPeaks.add((mPrunned.get(i) > mPrunned.get(i+1) ? mPrunned.get(i) : 0f));
|
||||
if (mPeaks.get(i) > mMaxValue) {
|
||||
mMaxValue = mPeaks.get(i);
|
||||
}
|
||||
|
||||
umPeaks.add((umPrunned.get(i) > umPrunned.get(i+1) ? umPrunned.get(i) : 0f));
|
||||
if (umPeaks.get(i) > umMaxValue) {
|
||||
umMaxValue = umPeaks.get(i);
|
||||
}
|
||||
|
||||
|
||||
if (avgSPB != -1) {
|
||||
if (bassPeaks.get(i) == 0) {
|
||||
avgSPB ++;
|
||||
} else {
|
||||
lastID = i;
|
||||
}
|
||||
} else if (bassPeaks.get(i) != 0) {
|
||||
avgSPB = 0;
|
||||
}
|
||||
|
||||
if (bassPeaks.get(i) != 0) {
|
||||
bassAvg += bassPeaks.get(i);
|
||||
bassBeats++;
|
||||
}
|
||||
|
||||
if (mPeaks.get(i) != 0) {
|
||||
mAvg += mPeaks.get(i);
|
||||
mBeats++;
|
||||
}
|
||||
|
||||
if (umPeaks.get(i) != 0) {
|
||||
umAvg += umPeaks.get(i);
|
||||
umBeats++;
|
||||
}
|
||||
}
|
||||
|
||||
secondsPerWindow = musicManager.getReadWindowSize()/musicManager.getSampleRate();
|
||||
|
||||
//then we minus one from the beats so it actually works out
|
||||
avgSPB -= bassPrunned.size-lastID;
|
||||
avgSPB *= secondsPerWindow;
|
||||
avgSPB /= bassBeats;
|
||||
Gdx.app.debug("Audio Analyzer", "Avg SPB: " + avgSPB);
|
||||
|
||||
bassAvg /= bassBeats;
|
||||
mAvg /= mBeats;
|
||||
umAvg /= umBeats;
|
||||
Gdx.app.debug("Audio Analyzer", "Avg bass: " + bassAvg);
|
||||
Gdx.app.debug("Audio Analyzer", "Avg M: " + mAvg);
|
||||
Gdx.app.debug("Audio Analyzer", "Avg UM: " + umAvg);
|
||||
|
||||
pack = new AudioDataPackage();
|
||||
pack.setBassData(bassPeaks, bassMaxValue, bassAvg);
|
||||
pack.setmData(mPeaks, mMaxValue, mAvg);
|
||||
pack.setUmData(umPeaks, umMaxValue, umAvg);
|
||||
|
||||
pack.setPUID(PUID);
|
||||
pack.setAvgSPB(avgSPB);
|
||||
pack.setSecPerWin(secondsPerWindow);
|
||||
pack.setMusicInfo(musicManager);
|
||||
if (work) {
|
||||
Gdx.app.debug("Audio Analyzer", "data cleaned and ready for map gen.");
|
||||
}
|
||||
}
|
||||
|
||||
public AudioDataPackage getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
}
|
96
core/src/zero1hd/rhythmbullet/audio/analyzer/PruneFluxRunnable.java
Executable file
96
core/src/zero1hd/rhythmbullet/audio/analyzer/PruneFluxRunnable.java
Executable file
@ -0,0 +1,96 @@
|
||||
package zero1hd.rhythmbullet.audio.analyzer;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
|
||||
public class PruneFluxRunnable implements Runnable {
|
||||
boolean work;
|
||||
private boolean done;
|
||||
private FloatArray bassSpectralFlux;
|
||||
private FloatArray mSpectralFlux;
|
||||
private FloatArray umSpectralFlux;
|
||||
private FloatArray bassThreshold, mThreshold, umThreshold;
|
||||
private FloatArray bassPrunned = new FloatArray();
|
||||
private FloatArray mPrunned = new FloatArray();
|
||||
private FloatArray umPrunned = new FloatArray();
|
||||
private MusicManager musicManager;
|
||||
public PruneFluxRunnable(ThresholdCalcRunnable tcr) {
|
||||
bassSpectralFlux = tcr.getBassSpectralFlux();
|
||||
mSpectralFlux = tcr.getmSpectralFlux();
|
||||
umSpectralFlux = tcr.getUmSpectralFlux();
|
||||
|
||||
bassThreshold = tcr.getBassThreshold();
|
||||
umThreshold = tcr.getUmThreshold();
|
||||
mThreshold = tcr.getmThreshold();
|
||||
|
||||
this.musicManager = tcr.getMusicManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//pruning data
|
||||
float prunnedCurrentVal;
|
||||
|
||||
for (int i = 0; i < umSpectralFlux.size && work; i++) {
|
||||
prunnedCurrentVal = bassSpectralFlux.get(i) - bassThreshold.get(i);
|
||||
if (prunnedCurrentVal >= 0) {
|
||||
bassPrunned.add(prunnedCurrentVal);
|
||||
} else {
|
||||
bassPrunned.add(0);
|
||||
}
|
||||
|
||||
prunnedCurrentVal = mSpectralFlux.get(i) - mThreshold.get(i);
|
||||
if (prunnedCurrentVal >= 0 ) {
|
||||
mPrunned.add(prunnedCurrentVal);
|
||||
} else {
|
||||
mPrunned.add(0);
|
||||
}
|
||||
|
||||
prunnedCurrentVal = umSpectralFlux.get(i) - umThreshold.get(i);
|
||||
if (prunnedCurrentVal >= 0 ) {
|
||||
umPrunned.add(prunnedCurrentVal);
|
||||
} else {
|
||||
umPrunned.add(0);
|
||||
}
|
||||
}
|
||||
done = true;
|
||||
Gdx.app.debug("Audio Analyzer", "Data prunned.");
|
||||
}
|
||||
|
||||
public FloatArray getBassSpectralFlux() {
|
||||
return bassSpectralFlux;
|
||||
}
|
||||
public FloatArray getmSpectralFlux() {
|
||||
return mSpectralFlux;
|
||||
}
|
||||
public FloatArray getBassThreshold() {
|
||||
return bassThreshold;
|
||||
}
|
||||
public FloatArray getmThreshold() {
|
||||
return mThreshold;
|
||||
}
|
||||
public FloatArray getUmSpectralFlux() {
|
||||
return umSpectralFlux;
|
||||
}
|
||||
public FloatArray getUmThreshold() {
|
||||
return umThreshold;
|
||||
}
|
||||
public FloatArray getBassPrunned() {
|
||||
return bassPrunned;
|
||||
}
|
||||
public FloatArray getmPrunned() {
|
||||
return mPrunned;
|
||||
}
|
||||
public FloatArray getUmPrunned() {
|
||||
return umPrunned;
|
||||
}
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
|
||||
public MusicManager getMusicManager() {
|
||||
return musicManager;
|
||||
}
|
||||
}
|
140
core/src/zero1hd/rhythmbullet/audio/analyzer/SpectralFluxAnalysisRunnable.java
Executable file
140
core/src/zero1hd/rhythmbullet/audio/analyzer/SpectralFluxAnalysisRunnable.java
Executable file
@ -0,0 +1,140 @@
|
||||
package zero1hd.rhythmbullet.audio.analyzer;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
|
||||
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
|
||||
public class SpectralFluxAnalysisRunnable implements Runnable {
|
||||
boolean work;
|
||||
private boolean done;
|
||||
|
||||
private FloatArray bassSpectralFlux = new FloatArray();
|
||||
private FloatArray mSpectralFlux = new FloatArray();
|
||||
private FloatArray umSpectralFlux = new FloatArray();
|
||||
|
||||
|
||||
MusicManager musicManager;
|
||||
|
||||
private int PUID;
|
||||
private int progress;
|
||||
|
||||
public SpectralFluxAnalysisRunnable(MusicManager mm) {
|
||||
this.musicManager = mm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
progress = 0;
|
||||
int tasksDone = 0;
|
||||
long totalTasks = musicManager.getSampleCount()/musicManager.getReadWindowSize();
|
||||
|
||||
float[] audioPCM = new float[musicManager.getReadWindowSize()];
|
||||
float[] spectrum = new float[(musicManager.getReadWindowSize()/2)+1];
|
||||
float[] lastSpectrum = new float[(musicManager.getReadWindowSize()/2)+1];
|
||||
|
||||
int bassBinBegin = 0;
|
||||
int bassBinEnd = 12;
|
||||
|
||||
int mBinBegin = 50;
|
||||
int mBinEnd = 250;
|
||||
|
||||
int umBinBegin = 350;
|
||||
int umBinEnd = 513;
|
||||
|
||||
Gdx.app.debug("Analyzing Song", musicManager.getBasicSongName());
|
||||
Gdx.app.debug("Read freq", String.valueOf(musicManager.getSampleRate()));
|
||||
Gdx.app.debug("Using following bin ranges", "\nBass freq begin: " + bassBinBegin + "\nBass freq end: " + bassBinEnd + "\nMain freq begin: " + umBinBegin + "\nMain freq end: " + umBinEnd);
|
||||
|
||||
Gdx.app.debug("Total tasks", String.valueOf(totalTasks));
|
||||
|
||||
FloatFFT_1D fft = new FloatFFT_1D(musicManager.getReadWindowSize());
|
||||
int seedDigit = 0;
|
||||
|
||||
while (musicManager.readSamples(audioPCM) > 0 && work) {
|
||||
|
||||
fft.realForward(audioPCM);
|
||||
|
||||
//Building a PUID (Pseudo unique ID)
|
||||
if (tasksDone == (seedDigit*totalTasks/9)) {
|
||||
float avg = 0;
|
||||
for (int frame = 0; frame < spectrum.length; frame++) {
|
||||
avg += spectrum[frame];
|
||||
}
|
||||
avg /= spectrum.length;
|
||||
if (avg < 0) {
|
||||
avg *= -1f;
|
||||
}
|
||||
PUID +=(int) Math.pow(10, 9-seedDigit) * ((int)(avg*1000f)-(int)(avg*100f)*10);
|
||||
seedDigit ++;
|
||||
}
|
||||
|
||||
System.arraycopy(spectrum, 0, lastSpectrum, 0, spectrum.length);
|
||||
System.arraycopy(audioPCM, 0, spectrum, 0, spectrum.length);
|
||||
|
||||
float fluxVal;
|
||||
//bass detection
|
||||
fluxVal = 0;
|
||||
for (int i = bassBinBegin; i < bassBinEnd; i++) {
|
||||
fluxVal += ((spectrum[i] - lastSpectrum[i])) < 0
|
||||
? 0 : (spectrum[i] - lastSpectrum[i]);
|
||||
}
|
||||
bassSpectralFlux.add(fluxVal);
|
||||
|
||||
//m detection
|
||||
fluxVal = 0;
|
||||
for (int i = mBinBegin; i < mBinEnd; i++) {
|
||||
fluxVal += ((spectrum[i] - lastSpectrum[i])) < 0
|
||||
? 0 : (spectrum[i] - lastSpectrum[i]);
|
||||
}
|
||||
mSpectralFlux.add(fluxVal);
|
||||
|
||||
//um detection
|
||||
fluxVal = 0;
|
||||
for (int i = umBinBegin; i < umBinEnd; i++) {
|
||||
fluxVal += ((spectrum[i] - lastSpectrum[i])) < 0
|
||||
? 0 : (spectrum[i] - lastSpectrum[i]);
|
||||
}
|
||||
umSpectralFlux.add(fluxVal);
|
||||
tasksDone++;
|
||||
progress = (int) (100f*tasksDone/totalTasks);
|
||||
}
|
||||
|
||||
if (work) {
|
||||
Gdx.app.debug("Audio Analyzer", "Done getting spectral flux.");
|
||||
Gdx.app.debug("Audio Analyzer", "window count: " + bassSpectralFlux.size);
|
||||
done = true;
|
||||
Gdx.app.debug("Audio Analyzer", "USING SEED: " + PUID);
|
||||
progress = 100;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
public FloatArray getBassSpectralFlux() {
|
||||
return bassSpectralFlux;
|
||||
}
|
||||
public FloatArray getmSpectralFlux() {
|
||||
return mSpectralFlux;
|
||||
}
|
||||
public FloatArray getUmSpectralFlux() {
|
||||
return umSpectralFlux;
|
||||
}
|
||||
public int getPUID() {
|
||||
return PUID;
|
||||
}
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
public boolean isWorking() {
|
||||
return work;
|
||||
}
|
||||
public void setWork(boolean work) {
|
||||
this.work = work;
|
||||
}
|
||||
public MusicManager getMusicManager() {
|
||||
return musicManager;
|
||||
}
|
||||
}
|
102
core/src/zero1hd/rhythmbullet/audio/analyzer/ThresholdCalcRunnable.java
Executable file
102
core/src/zero1hd/rhythmbullet/audio/analyzer/ThresholdCalcRunnable.java
Executable file
@ -0,0 +1,102 @@
|
||||
package zero1hd.rhythmbullet.audio.analyzer;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
|
||||
public class ThresholdCalcRunnable implements Runnable {
|
||||
boolean work;
|
||||
private boolean done;
|
||||
|
||||
private MusicManager musicManager;
|
||||
|
||||
private FloatArray bassSpectralFlux;
|
||||
private FloatArray mSpectralFlux;
|
||||
private FloatArray umSpectralFlux;
|
||||
private FloatArray bassThreshold = new FloatArray();
|
||||
private FloatArray mThreshold = new FloatArray();
|
||||
private FloatArray umThreshold = new FloatArray();
|
||||
|
||||
public ThresholdCalcRunnable(SpectralFluxAnalysisRunnable sfar) {
|
||||
this.bassSpectralFlux = sfar.getBassSpectralFlux();
|
||||
this.mSpectralFlux = sfar.getmSpectralFlux();
|
||||
this.umSpectralFlux = sfar.getUmSpectralFlux();
|
||||
this.musicManager = sfar.getMusicManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Gdx.app.debug("Audio Analyzer", "beginning threshold calc.");
|
||||
|
||||
float bassThresholdMultiplier = 1.5f;
|
||||
float mThresholdMultiplier = 1.4f;
|
||||
float umThresholdMultiplier = 1.4f;
|
||||
|
||||
int bassThresholdCalcRange = thresholdRangeCalc(0.27f);
|
||||
int mThresholdCalcRange = thresholdRangeCalc(0.4f);
|
||||
int umThresholdCalcRange = thresholdRangeCalc(0.4f);
|
||||
//threshold calculation
|
||||
for (int i = 0; i < umSpectralFlux.size && work; i++) {
|
||||
int start = Math.max(0, i - bassThresholdCalcRange/2);
|
||||
int end = Math.min(umSpectralFlux.size - 1, i + bassThresholdCalcRange/2);
|
||||
float average = 0;
|
||||
for (int j = start; j <= end; j++) {
|
||||
average += bassSpectralFlux.get(j);
|
||||
}
|
||||
average /= (end - start);
|
||||
bassThreshold.add(average * bassThresholdMultiplier);
|
||||
|
||||
start = Math.max(0, i - mThresholdCalcRange/2);
|
||||
end = Math.min(umSpectralFlux.size - 1, i + mThresholdCalcRange/2);
|
||||
average = 0;
|
||||
for (int j = start; j <= end; j++) {
|
||||
average+= mSpectralFlux.get(j);
|
||||
}
|
||||
average /= (end - start);
|
||||
mThreshold.add(average*mThresholdMultiplier);
|
||||
|
||||
start = Math.max(0, i - umThresholdCalcRange/2);
|
||||
end = Math.min(umSpectralFlux.size - 1, i + umThresholdCalcRange/2);
|
||||
average = 0;
|
||||
for (int j = start; j <= end; j++) {
|
||||
average+= umSpectralFlux.get(j);
|
||||
}
|
||||
average /= (end - start);
|
||||
umThreshold.add(average*umThresholdMultiplier);
|
||||
}
|
||||
done = true;
|
||||
Gdx.app.debug("Audio Analyzer", "Threshold calculated.");
|
||||
}
|
||||
|
||||
private int thresholdRangeCalc(float durationOfRange) {
|
||||
return (int) (durationOfRange/(musicManager.getReadWindowSize()/musicManager.getSampleRate()));
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
|
||||
public FloatArray getBassSpectralFlux() {
|
||||
return bassSpectralFlux;
|
||||
}
|
||||
public FloatArray getmSpectralFlux() {
|
||||
return mSpectralFlux;
|
||||
}
|
||||
public FloatArray getUmSpectralFlux() {
|
||||
return umSpectralFlux;
|
||||
}
|
||||
public FloatArray getBassThreshold() {
|
||||
return bassThreshold;
|
||||
}
|
||||
public FloatArray getmThreshold() {
|
||||
return mThreshold;
|
||||
}
|
||||
public FloatArray getUmThreshold() {
|
||||
return umThreshold;
|
||||
}
|
||||
|
||||
public MusicManager getMusicManager() {
|
||||
return musicManager;
|
||||
}
|
||||
}
|
109
core/src/zero1hd/rhythmbullet/graphics/ui/pages/AnalysisPage.java
Executable file
109
core/src/zero1hd/rhythmbullet/graphics/ui/pages/AnalysisPage.java
Executable file
@ -0,0 +1,109 @@
|
||||
package zero1hd.rhythmbullet.graphics.ui.pages;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
import com.badlogic.gdx.assets.AssetManager;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Slider;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.audio.analyzer.AudioAnalyzer;
|
||||
|
||||
public class AnalysisPage extends Page implements Observer {
|
||||
private boolean confirmed;
|
||||
private volatile AudioAnalyzer aa;
|
||||
private Table table;
|
||||
private Label difficultyModLabel, healthModLabel, speedModLabel;
|
||||
private Slider difficultyModifierSlider, healthModifierSlider, speedModifierSlider;
|
||||
private Label diffModPercentLabel, heltModPercentLabel, speeModPercentLabel;
|
||||
private Label progressLabel;
|
||||
private TextButton confirmButton;
|
||||
public AnalysisPage(Skin skin, AssetManager assets) {
|
||||
setTextureBackground(assets.get("gradients.atlas", TextureAtlas.class).findRegion("red-round"));
|
||||
table = new Table();
|
||||
table.setFillParent(true);
|
||||
table.defaults().space(10f);
|
||||
addActor(table);
|
||||
|
||||
difficultyModLabel = new Label("Difficulty Modifier: ", skin, "sub-font", skin.getColor("default"));
|
||||
difficultyModifierSlider = new Slider(1, 3, 0.5f, false, skin);
|
||||
diffModPercentLabel = new Label(String.valueOf(difficultyModifierSlider.getValue()) + "x", skin);
|
||||
difficultyModifierSlider.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
diffModPercentLabel.setText(String.valueOf(difficultyModifierSlider.getValue()) + "x");
|
||||
}
|
||||
});
|
||||
table.add(difficultyModLabel);
|
||||
table.add(difficultyModifierSlider).minWidth(0.5f*getWidth());
|
||||
table.add(diffModPercentLabel).minWidth(diffModPercentLabel.getWidth()*1.5f);
|
||||
table.row();
|
||||
healthModLabel = new Label("Health Modifier: ", skin, "sub-font", skin.getColor("default"));
|
||||
healthModifierSlider = new Slider(1f, 3f, 0.5f, false, skin);
|
||||
heltModPercentLabel = new Label(String.valueOf(healthModifierSlider.getValue()) + "x", skin);
|
||||
healthModifierSlider.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
heltModPercentLabel.setText(String.valueOf(healthModifierSlider.getValue()) + "x");
|
||||
}
|
||||
});
|
||||
table.add(healthModLabel);
|
||||
table.add(healthModifierSlider).fillX();
|
||||
table.add(heltModPercentLabel).fillX();
|
||||
table.row();
|
||||
speedModLabel = new Label("Speed Modifier: ", skin, "sub-font", skin.getColor("default"));
|
||||
speedModifierSlider = new Slider(1, 3, 0.5f, false, skin);
|
||||
speeModPercentLabel = new Label(String.valueOf(speedModifierSlider.getValue()) + "x", skin);
|
||||
speedModifierSlider.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
speeModPercentLabel.setText(String.valueOf(speedModifierSlider.getValue()) + "x");
|
||||
}
|
||||
});
|
||||
table.add(speedModLabel);
|
||||
table.add(speedModifierSlider).fillX();
|
||||
table.add(speeModPercentLabel).fillX();
|
||||
table.row();
|
||||
|
||||
confirmButton = new TextButton("Confirm", skin);
|
||||
confirmButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
confirmed = true;
|
||||
confirmButton.setDisabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
table.add(confirmButton);
|
||||
table.row().colspan(3).fillX();
|
||||
progressLabel = new Label("Loading... ", skin);
|
||||
table.add(progressLabel).colspan(2).left().spaceTop(20f);
|
||||
}
|
||||
|
||||
public void processSong(MusicManager mm) {
|
||||
aa = new AudioAnalyzer(mm);
|
||||
aa.addObserver(this);
|
||||
aa.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Observable arg0, Object arg1) {
|
||||
if (arg0 == aa) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
if (aa != null && aa.isDone() && confirmed) {
|
||||
//TODO GAMESCREEN!!!
|
||||
}
|
||||
super.act(delta);
|
||||
}
|
||||
}
|
@ -1,323 +0,0 @@
|
||||
package zero1hd.rhythmbullet.graphics.ui.pages;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.math.Interpolation;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Slider;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.AudioAnalyzer;
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.audio.SongInfo;
|
||||
import zero1hd.rhythmbullet.audio.map.GamePlayMap;
|
||||
import zero1hd.rhythmbullet.audio.map.RhythmMapAlgorithm;
|
||||
import zero1hd.rhythmbullet.graphics.ui.components.ScrollText;
|
||||
import zero1hd.rhythmbullet.screens.GameScreen;
|
||||
import zero1hd.rhythmbullet.util.MiniEvents;
|
||||
import zero1hd.rhythmbullet.util.MiniListener;
|
||||
|
||||
public class AnalyzePage extends Page implements MiniListener, Disposable {
|
||||
private AnalyzePage ap = this;
|
||||
|
||||
AudioAnalyzer audioAnalyzer;
|
||||
MusicManager music;
|
||||
RhythmMapAlgorithm mapGenAlgorithm;
|
||||
|
||||
private Table songInfo;
|
||||
private Label[] info;
|
||||
|
||||
Table difficultyTable;
|
||||
private Label diffTitle;
|
||||
private Slider sensitivityRating;
|
||||
private Label sensitivityRatingTitle;
|
||||
private Slider speedModifier;
|
||||
private Label speedModifierTitle;
|
||||
private Slider healthModifier;
|
||||
private Label healthModifierTitle;
|
||||
private TextButton confirmDiffButton;
|
||||
private boolean confirmed;
|
||||
private Skin skin;
|
||||
|
||||
private Table beginTable;
|
||||
private TextButton beginButton;
|
||||
|
||||
private TextButton back;
|
||||
private Image loadingCircle;
|
||||
private long startTime, endTime;
|
||||
|
||||
private Thread mapGenThread;
|
||||
private GameScreen gameScreen;
|
||||
|
||||
private RhythmBullet core;
|
||||
public AnalyzePage(RhythmBullet core) {
|
||||
super("Results", core.getDefaultSkin());
|
||||
this.skin = core.getDefaultSkin();
|
||||
this.core = core;
|
||||
|
||||
songInfo = new Table(skin);
|
||||
songInfo.align(Align.top);
|
||||
songInfo.pad(15f);
|
||||
songInfo.setBackground(skin.getDrawable("large-pane"));
|
||||
addActor(songInfo);
|
||||
|
||||
difficultyTable = new Table(skin);
|
||||
difficultyTable.setBackground(skin.getDrawable("large-pane"));
|
||||
addActor(difficultyTable);
|
||||
|
||||
diffTitle = new Label("Difficulty", skin);
|
||||
difficultyTable.add(diffTitle).expandX().left();
|
||||
|
||||
difficultyTable.row();
|
||||
|
||||
sensitivityRating = new Slider(0f, 1f, 0.01f, false, skin);
|
||||
sensitivityRating.setValue(0f);
|
||||
sensitivityRating.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
sensitivityRatingTitle.setText("Base Difficulty: " + MathUtils.round(sensitivityRating.getValue()*100) + "%");
|
||||
}
|
||||
});
|
||||
|
||||
sensitivityRatingTitle = new Label("Base Difficulty: " + sensitivityRating.getValue(), skin, "sub-font", skin.getColor("default"));
|
||||
difficultyTable.add(sensitivityRatingTitle);
|
||||
difficultyTable.row();
|
||||
difficultyTable.add(sensitivityRating).fillX();
|
||||
|
||||
difficultyTable.row();
|
||||
|
||||
speedModifier = new Slider(1f, 3f, 0.25f, false, skin);
|
||||
speedModifier.setValue(1f);
|
||||
speedModifier.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
speedModifierTitle.setText("Speed Modifier: x" + speedModifier.getValue());
|
||||
}
|
||||
});
|
||||
speedModifierTitle = new Label("Speed Modifier: x" + speedModifier.getValue(), skin, "sub-font", skin.getColor("default"));
|
||||
difficultyTable.add(speedModifierTitle);
|
||||
difficultyTable.row();
|
||||
difficultyTable.add(speedModifier).fillX();
|
||||
|
||||
difficultyTable.row();
|
||||
|
||||
healthModifier = new Slider(0f, 5f, 1f, false, skin);
|
||||
healthModifier.setValue(0f);
|
||||
healthModifier.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
healthModifierTitle.setText("Health modifier: +" + healthModifier.getValue());
|
||||
}
|
||||
});
|
||||
healthModifierTitle = new Label("Health modifier: +" + healthModifier.getValue(), skin, "sub-font", skin.getColor("default"));
|
||||
difficultyTable.add(healthModifierTitle);
|
||||
difficultyTable.row();
|
||||
difficultyTable.add(healthModifier).fillX().spaceBottom(15f);
|
||||
|
||||
difficultyTable.row();
|
||||
|
||||
confirmDiffButton = new TextButton("Confirm", skin);
|
||||
confirmDiffButton.setDisabled(true);
|
||||
confirmDiffButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
info[2].setText("Confirmed.");
|
||||
confirmed = true;
|
||||
confirmDiffButton.setDisabled(true);
|
||||
sensitivityRating.setDisabled(true);
|
||||
speedModifier.setDisabled(true);
|
||||
healthModifier.setDisabled(true);
|
||||
|
||||
if (audioAnalyzer.containsData() ) {
|
||||
finalizeData();
|
||||
}
|
||||
}
|
||||
});
|
||||
difficultyTable.add(confirmDiffButton);
|
||||
|
||||
difficultyTable.pack();
|
||||
|
||||
beginTable = new Table(skin);
|
||||
beginTable.pad(15f);
|
||||
beginButton = new TextButton("Begin", skin);
|
||||
beginTable.add(beginButton);
|
||||
beginTable.setBackground(skin.getDrawable("large-pane"));
|
||||
beginTable.pack();
|
||||
addActor(beginTable);
|
||||
|
||||
loadingCircle = new Image(core.getAssetManager().get("cybercircle1.png", Texture.class));
|
||||
loadingCircle.setPosition((getWidth()-loadingCircle.getWidth())/2, (getHeightBelowTitle()-loadingCircle.getHeight())/2);
|
||||
loadingCircle.setColor(0.8f,0.8f,0.8f,0.7f);
|
||||
loadingCircle.setOrigin(loadingCircle.getWidth()/2, loadingCircle.getHeight()/2);
|
||||
loadingCircle.addAction(Actions.forever(Actions.rotateBy(-360f, 4f)));
|
||||
addActor(loadingCircle);
|
||||
loadingCircle.toBack();
|
||||
|
||||
back = new TextButton("Back", skin);
|
||||
back.setPosition(getWidth()-back.getWidth()-15f, getHeightBelowTitle());
|
||||
back.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
miniSender.send(MiniEvents.BACK);
|
||||
if (audioAnalyzer != null) {
|
||||
audioAnalyzer.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
info = new Label[6];
|
||||
for (int i = 0; i < info.length; i++) {
|
||||
info[i] = new Label(null, skin, "sub-font", skin.getColor("default"));
|
||||
}
|
||||
|
||||
addActor(back);
|
||||
}
|
||||
|
||||
public void setSong(MusicManager music, SongInfo audioInfo, MiniListener listener) {
|
||||
confirmed = false;
|
||||
confirmDiffButton.setDisabled(false);
|
||||
sensitivityRating.setDisabled(false);
|
||||
speedModifier.setDisabled(false);
|
||||
healthModifier.setDisabled(false);
|
||||
|
||||
songInfo.clear();
|
||||
songInfo.defaults().align(Align.left | Align.top);
|
||||
this.music = music;
|
||||
|
||||
audioAnalyzer = new AudioAnalyzer(music);
|
||||
audioAnalyzer.sender.addListener(this);
|
||||
|
||||
|
||||
songInfo.add(new ScrollText(audioInfo.getMusicName(), null, skin, true, false)).expandX().fillX().spaceBottom(20f);
|
||||
|
||||
for (int i = 0; i < info.length; i++) {
|
||||
info[i].setColor(1f, 1f, 1f, 0f);
|
||||
info[i].setText(null);
|
||||
songInfo.row();
|
||||
songInfo.add(info[i]);
|
||||
}
|
||||
|
||||
songInfo.pack();
|
||||
songInfo.setWidth(getWidth()/2f);
|
||||
songInfo.setPosition((getWidth()-songInfo.getWidth())/2f, (getHeightBelowTitle()-songInfo.getHeight())/2f);
|
||||
difficultyTable.setPosition(songInfo.getX(), -difficultyTable.getHeight());
|
||||
difficultyTable.setWidth(songInfo.getWidth());
|
||||
beginTable.setPosition(difficultyTable.getX(), -beginTable.getHeight());
|
||||
beginTable.setWidth(difficultyTable.getWidth());
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
info[0].addAction(Actions.color(Color.BLACK, 2.5f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
super.act(delta);
|
||||
}
|
||||
|
||||
public boolean hasAudioData() {
|
||||
if (music != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAudioData() {
|
||||
music = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void handle(MiniEvents ID) {
|
||||
switch (ID) {
|
||||
case ANALYZER_ITERATED:
|
||||
if (audioAnalyzer.getProgress() == 50) {
|
||||
songInfo.addAction(Actions.moveTo(songInfo.getX(), getHeight()/2f, 0.75f, Interpolation.linear));
|
||||
difficultyTable.addAction(Actions.moveTo(songInfo.getX(), getHeight()/2f-difficultyTable.getHeight()-10,0.8f, Interpolation.linear));
|
||||
info[2].setText("Awaiting confirmation...");
|
||||
info[2].addAction(Actions.color(Color.BLACK, 0.75f));
|
||||
confirmDiffButton.setDisabled(false);
|
||||
}
|
||||
|
||||
info[0].setText("Initial analysis: " + audioAnalyzer.getProgress() + "%");
|
||||
break;
|
||||
case SPECTRAL_FLUX_DONE:
|
||||
endTime = System.currentTimeMillis();
|
||||
info[1].setText("Done. Analyze time: " + ((endTime - startTime)/1000f) + "s");
|
||||
info[1].addAction(Actions.color(Color.BLACK, 0.75f));
|
||||
if (confirmed) {
|
||||
finalizeData();
|
||||
}
|
||||
break;
|
||||
case MUSIC_DATA_CLEANED:
|
||||
info[3].setText("data cleaning done.");
|
||||
info[4].addAction(Actions.color(Color.BLACK, 0.75f));
|
||||
Gdx.app.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
gameScreen = new GameScreen(core, core.getScreen());
|
||||
mapGenAlgorithm = new RhythmMapAlgorithm(gameScreen.getGameArea().em, gameScreen.getGameArea().cm, audioAnalyzer.getAudioDataPackage(), speedModifier.getValue(), healthModifier.getValue(), sensitivityRating.getValue());
|
||||
mapGenAlgorithm.getSender().addListener(ap);
|
||||
mapGenThread = new Thread(mapGenAlgorithm);
|
||||
mapGenThread.start();
|
||||
}
|
||||
});
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
break;
|
||||
case MAPGEN_ITERATED:
|
||||
info[4].setText("Generating map: " + mapGenAlgorithm.getProgress() + "%");
|
||||
break;
|
||||
case MAP_GENERATED:
|
||||
endTime = System.currentTimeMillis();
|
||||
info[5].setText("Done. Generation time: " + ((endTime - startTime)/1000f) + "s");
|
||||
beginButton.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
gameScreen.setGamePlayMap(mapGenAlgorithm.getMap());
|
||||
core.setScreen(gameScreen);
|
||||
miniSender.send(MiniEvents.BACK);
|
||||
}
|
||||
});
|
||||
|
||||
info[5].addAction(Actions.color(Color.BLACK, 0.75f));
|
||||
songInfo.addAction(Actions.moveTo(songInfo.getX(), getHeight()-songInfo.getHeight()-10, 0.55f, Interpolation.linear));
|
||||
difficultyTable.addAction(Actions.sequence(Actions.delay(0.3f), Actions.moveTo(songInfo.getX(), getHeight()-songInfo.getHeight()-10-difficultyTable.getHeight()-5f,0.8f, Interpolation.linear)));
|
||||
beginTable.addAction(Actions.sequence(Actions.delay(0.5f), Actions.moveTo(difficultyTable.getX(), getHeight()-songInfo.getHeight()-10-difficultyTable.getHeight()-beginTable.getHeight()-10f,0.8f, Interpolation.linear)));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void finalizeData() {
|
||||
Gdx.app.debug("analyze", "confirmed data finalization.");
|
||||
audioAnalyzer.runThresholdCleaning();
|
||||
info[3].setText("finalizing data...");
|
||||
info[3].addAction(Actions.color(Color.BLACK, 0.75f));
|
||||
}
|
||||
|
||||
public GamePlayMap getMap() {
|
||||
return mapGenAlgorithm.getMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (audioAnalyzer != null) {
|
||||
audioAnalyzer.stop();
|
||||
audioAnalyzer = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
@ -64,7 +63,7 @@ public class MusicSelectionPage extends Page implements Observer {
|
||||
private TextButton beginButton;
|
||||
private float scrollTimer, scrollDelay = 0.2f, scrollDelMod, songSelectionTimer;
|
||||
|
||||
public MusicSelectionPage(Skin skin, MusicListController musicList, AssetManager assetManager, Vector3 cameraTarget) {
|
||||
public MusicSelectionPage(Skin skin, MusicListController musicList, AssetManager assetManager, Vector3 cameraTarget, AnalysisPage ap) {
|
||||
setTextureBackground(assetManager.get("gradients.atlas", TextureAtlas.class).findRegion("red-round"));
|
||||
this.skin = skin;
|
||||
this.mc = musicList;
|
||||
@ -130,6 +129,13 @@ public class MusicSelectionPage extends Page implements Observer {
|
||||
ratedDifficulty = new Label(null, skin, "sub-font", skin.getColor("default"));
|
||||
albumCover = new Image(assetManager.get("defaultCover.png", Texture.class));
|
||||
beginButton = new TextButton("Begin", skin);
|
||||
beginButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
cameraTarget.x = 2.5f*getWidth();
|
||||
ap.processSong(mc.getMusicList().getAudioData(getSelectedMusic()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,14 +1,11 @@
|
||||
package zero1hd.rhythmbullet.graphics.ui.pages;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input.Keys;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.Preferences;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Slider;
|
||||
@ -19,8 +16,6 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.MusicListController;
|
||||
import zero1hd.rhythmbullet.screens.CreativeScreen;
|
||||
import zero1hd.rhythmbullet.screens.MainMenu;
|
||||
|
||||
public class OptionsPage extends Page {
|
||||
Table optionsTable;
|
||||
@ -117,13 +112,6 @@ public class OptionsPage extends Page {
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
Label debugCodeLabel = new Label("Debug Code: ", core.getDefaultSkin());
|
||||
optionsTable.add(debugCodeLabel);
|
||||
final TextField debugCodeField = new TextField(null, core.getDefaultSkin());
|
||||
optionsTable.add(debugCodeField).fillX();
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
TextButton keybindSettings = new TextButton("Set Controls", core.getDefaultSkin());
|
||||
keybindSettings.addListener(new ChangeListener() {
|
||||
@Override
|
||||
@ -143,19 +131,6 @@ public class OptionsPage extends Page {
|
||||
}
|
||||
});
|
||||
optionsTable.add(graphicsSettings).colspan(2).fillX();
|
||||
addListener(new InputListener() {
|
||||
@Override
|
||||
public boolean keyUp(InputEvent event, int keycode) {
|
||||
if (keycode == Keys.ENTER) {
|
||||
Gdx.app.debug("Debug Field", debugCodeField.getText());
|
||||
if (debugCodeField.getText().equals("creative")) {
|
||||
Gdx.app.debug("Debug Field", "going to creative test room...");
|
||||
core.setScreen(new CreativeScreen(core, (MainMenu) core.getScreen(), sc.getMusicList()));
|
||||
}
|
||||
}
|
||||
return super.keyUp(event, keycode);
|
||||
}
|
||||
});
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
package zero1hd.rhythmbullet.screens;
|
||||
|
||||
import com.badlogic.gdx.Preferences;
|
||||
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.MusicList;
|
||||
import zero1hd.rhythmbullet.stages.CreativeHUD;
|
||||
|
||||
public class CreativeScreen extends GameScreen {
|
||||
CreativeHUD chud;
|
||||
|
||||
Preferences prefs;
|
||||
|
||||
public CreativeScreen(RhythmBullet core, MainMenu mainMenu, MusicList sl) {
|
||||
super(core, mainMenu);
|
||||
chud = new CreativeHUD(core, mainMenu, gameArea, gameHUD, sl);
|
||||
inputs.addProcessor(chud);
|
||||
|
||||
this.prefs = core.getPrefs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
super.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
super.render(delta);
|
||||
|
||||
chud.getViewport().apply();
|
||||
chud.act();
|
||||
chud.draw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height) {
|
||||
super.resize(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.MusicList;
|
||||
import zero1hd.rhythmbullet.audio.MusicListController;
|
||||
import zero1hd.rhythmbullet.graphics.ui.pages.AnalysisPage;
|
||||
import zero1hd.rhythmbullet.graphics.ui.pages.CreditsPage;
|
||||
import zero1hd.rhythmbullet.graphics.ui.pages.KeybindOptionsPage;
|
||||
import zero1hd.rhythmbullet.graphics.ui.pages.MainPage;
|
||||
@ -39,7 +40,7 @@ public class MainMenu extends ScreenAdapter implements TransitionAdapter {
|
||||
private KeybindOptionsPage keybindPage;
|
||||
private VideoOptionsPage graphicsPage;
|
||||
private MusicSelectionPage musicSelectionPage;
|
||||
|
||||
private AnalysisPage analysisPage;
|
||||
private RhythmBullet core;
|
||||
|
||||
private MusicListController mlc;
|
||||
@ -99,10 +100,13 @@ public class MainMenu extends ScreenAdapter implements TransitionAdapter {
|
||||
creditsPage.setPosition(0, Gdx.graphics.getHeight());
|
||||
stage.addActor(creditsPage);
|
||||
|
||||
musicSelectionPage = new MusicSelectionPage(core.getDefaultSkin(), mlc, core.getAssetManager(), cameraPosition);
|
||||
analysisPage = new AnalysisPage(core.getDefaultSkin(),core.getAssetManager());
|
||||
analysisPage.setPosition(2*Gdx.graphics.getWidth(), 0f);
|
||||
stage.addActor(analysisPage);
|
||||
|
||||
musicSelectionPage = new MusicSelectionPage(core.getDefaultSkin(), mlc, core.getAssetManager(), cameraPosition, analysisPage);
|
||||
musicSelectionPage.setPosition(1f*Gdx.graphics.getWidth(), 0f);
|
||||
stage.addActor(musicSelectionPage);
|
||||
|
||||
stage.addListener(new InputListener() {
|
||||
@Override
|
||||
public boolean keyUp(InputEvent event, int keycode) {
|
||||
|
@ -1,111 +0,0 @@
|
||||
package zero1hd.rhythmbullet.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.MusicListController;
|
||||
import zero1hd.rhythmbullet.graphics.ui.pages.AnalyzePage;
|
||||
import zero1hd.rhythmbullet.graphics.ui.pages.MusicSelectionPage;
|
||||
import zero1hd.rhythmbullet.util.MiniEvents;
|
||||
import zero1hd.rhythmbullet.util.MiniListener;
|
||||
import zero1hd.rhythmbullet.util.TransitionAdapter;
|
||||
|
||||
@Deprecated
|
||||
public class PreGameScreen extends ScreenAdapter implements TransitionAdapter, MiniListener {
|
||||
Stage stage;
|
||||
|
||||
MusicSelectionPage ms;
|
||||
public AnalyzePage ap;
|
||||
private Vector3 cameraPos;
|
||||
private RhythmBullet core;
|
||||
private MusicListController songListController;
|
||||
|
||||
public PreGameScreen(RhythmBullet core, MusicListController songList) {
|
||||
stage = new Stage(new ScreenViewport());
|
||||
cameraPos = new Vector3(stage.getCamera().position);
|
||||
this.core = core;
|
||||
this.songListController = songList;
|
||||
postTransition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
stage.getViewport().apply();
|
||||
try {
|
||||
stage.act();
|
||||
stage.draw();
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (stage.getCamera().position.x != cameraPos.x) {
|
||||
stage.getCamera().position.lerp(cameraPos, 0.25f);
|
||||
}
|
||||
super.render(delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height) {
|
||||
stage.getViewport().update(width, height, true);
|
||||
cameraPos.set(stage.getCamera().position);
|
||||
super.resize(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MiniEvents ID) {
|
||||
switch (ID) {
|
||||
case MUSIC_SELECTED:
|
||||
cameraPos.x = 1.5f*Gdx.graphics.getWidth();
|
||||
ap.setSong(songListController.getMusicList().getAudioData(ms.getSelectedMusic()), ms.getSelectedMusicInfo(), this);
|
||||
break;
|
||||
case BACK:
|
||||
if (cameraPos.x == 1.5f*Gdx.graphics.getWidth()) {
|
||||
cameraPos.x = 0.5f*Gdx.graphics.getWidth();
|
||||
} else {
|
||||
core.setScreen(new MainMenu(core));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preTransition() {
|
||||
stage.clear();
|
||||
ap.dispose();
|
||||
ms.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postTransition() {
|
||||
ms = new MusicSelectionPage(core.getDefaultSkin(), songListController, core.getAssetManager(), cameraPos);
|
||||
ms.miniSender.addListener(this);
|
||||
stage.addActor(ms);
|
||||
|
||||
ap = new AnalyzePage(core);
|
||||
ap.miniSender.addListener(this);
|
||||
ap.setPosition(Gdx.graphics.getWidth(), 0);
|
||||
stage.addActor(ap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
Gdx.input.setInputProcessor(stage);
|
||||
super.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
stage.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
@ -1,288 +0,0 @@
|
||||
package zero1hd.rhythmbullet.stages;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input.Keys;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Window;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.AudioAnalyzer;
|
||||
import zero1hd.rhythmbullet.audio.AudioDataPackage;
|
||||
import zero1hd.rhythmbullet.audio.MusicList;
|
||||
import zero1hd.rhythmbullet.audio.map.RhythmMapAlgorithm;
|
||||
import zero1hd.rhythmbullet.graphics.ui.components.AudioGraph;
|
||||
import zero1hd.rhythmbullet.graphics.ui.windows.BeatViewer;
|
||||
import zero1hd.rhythmbullet.graphics.ui.windows.DifficultyWindow;
|
||||
import zero1hd.rhythmbullet.graphics.ui.windows.FPSWindow;
|
||||
import zero1hd.rhythmbullet.graphics.ui.windows.MusicController;
|
||||
import zero1hd.rhythmbullet.graphics.ui.windows.MusicSelector;
|
||||
import zero1hd.rhythmbullet.graphics.ui.windows.SpawnerWindow;
|
||||
import zero1hd.rhythmbullet.graphics.ui.windows.VolumeWindow;
|
||||
import zero1hd.rhythmbullet.screens.MainMenu;
|
||||
import zero1hd.rhythmbullet.util.MiniEvents;
|
||||
import zero1hd.rhythmbullet.util.MiniListener;
|
||||
|
||||
public class CreativeHUD extends Stage implements MiniListener {
|
||||
MusicController musicPlayBackControls;
|
||||
MusicSelector musicSelector;
|
||||
FPSWindow fpsViewer;
|
||||
BeatViewer beatViewer;
|
||||
AudioGraph bassUMgraphWindow;
|
||||
AudioGraph mGraphWindow;
|
||||
VolumeWindow volumeWindow;
|
||||
SpawnerWindow spawnerWindow;
|
||||
DifficultyWindow diffWindow;
|
||||
|
||||
AudioAnalyzer analyzer;
|
||||
RhythmMapAlgorithm mapGen;
|
||||
Window toolbox;
|
||||
|
||||
GamePlayArea gpa;
|
||||
GameHUD ghud;
|
||||
public CreativeHUD(final RhythmBullet core, final MainMenu mainMenu, final GamePlayArea gpa, GameHUD ghud, MusicList sl) {
|
||||
this.gpa = gpa;
|
||||
this.ghud = ghud;
|
||||
|
||||
musicSelector = new MusicSelector("Select Audio File", core.getDefaultSkin(), core.getPrefs().getString("music dir"), sl);
|
||||
musicSelector.miniSender.addListener(this);
|
||||
musicSelector.refresh();
|
||||
|
||||
fpsViewer = new FPSWindow("FPS", core.getDefaultSkin());
|
||||
beatViewer = new BeatViewer("Beat", core.getDefaultSkin());
|
||||
bassUMgraphWindow = new AudioGraph(512, 256);
|
||||
bassUMgraphWindow.setPosition(getWidth() - bassUMgraphWindow.getWidth(), 0);
|
||||
mGraphWindow = new AudioGraph(512, 256);
|
||||
mGraphWindow.setPosition(getWidth() - mGraphWindow.getWidth(), bassUMgraphWindow.getHeight());
|
||||
volumeWindow = new VolumeWindow("Volume adjustments", core.getDefaultSkin(), core.getPrefs());
|
||||
spawnerWindow = new SpawnerWindow("Spawn Tool", core.getDefaultSkin(), gpa.em, gpa.cm, gpa);
|
||||
diffWindow = new DifficultyWindow(core.getDefaultSkin());
|
||||
|
||||
toolbox = new Window("Tools", core.getDefaultSkin(), "tinted");
|
||||
toolbox.defaults().pad(5f);
|
||||
|
||||
Table toolboxToolSet = new Table(core.getDefaultSkin());
|
||||
toolboxToolSet.defaults().space(5f).left();
|
||||
|
||||
//Back button
|
||||
TextButton backButton = new TextButton("Back", core.getDefaultSkin(), "window");
|
||||
backButton.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
dispose();
|
||||
core.setScreen(mainMenu);
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(backButton);
|
||||
toolboxToolSet.row();
|
||||
|
||||
final CheckBox musicSelectorCheckbox = new CheckBox(" Music selector", core.getDefaultSkin());
|
||||
musicSelectorCheckbox.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (musicSelectorCheckbox.isChecked()) {
|
||||
addActor(musicSelector);
|
||||
} else {
|
||||
musicSelector.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(musicSelectorCheckbox);
|
||||
toolboxToolSet.row();
|
||||
|
||||
musicPlayBackControls = new MusicController(core.getDefaultSkin());
|
||||
final CheckBox musicPlayBackCheckbox = new CheckBox(" Playback controls", core.getDefaultSkin());
|
||||
musicPlayBackCheckbox.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (musicPlayBackCheckbox.isChecked()) {
|
||||
addActor(musicPlayBackControls);
|
||||
} else {
|
||||
musicPlayBackControls.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(musicPlayBackCheckbox);
|
||||
toolboxToolSet.row();
|
||||
|
||||
final CheckBox beatViewerCheckbox = new CheckBox(" Beat viewer", core.getDefaultSkin());
|
||||
beatViewerCheckbox.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (beatViewerCheckbox.isChecked()) {
|
||||
addActor(beatViewer);
|
||||
} else {
|
||||
beatViewer.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(beatViewerCheckbox);
|
||||
toolboxToolSet.row();
|
||||
|
||||
final CheckBox fpsViewerCheckbox = new CheckBox(" FPS", core.getDefaultSkin());
|
||||
fpsViewerCheckbox.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (fpsViewerCheckbox.isChecked()) {
|
||||
addActor(fpsViewer);
|
||||
} else {
|
||||
fpsViewer.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(fpsViewerCheckbox);
|
||||
toolboxToolSet.row();
|
||||
|
||||
final CheckBox peakGraphCheckbox = new CheckBox(" Peak Graphs", core.getDefaultSkin());
|
||||
peakGraphCheckbox.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (peakGraphCheckbox.isChecked()) {
|
||||
addActor(bassUMgraphWindow);
|
||||
addActor(mGraphWindow);
|
||||
} else {
|
||||
bassUMgraphWindow.remove();
|
||||
mGraphWindow.remove();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(peakGraphCheckbox);
|
||||
toolboxToolSet.row();
|
||||
|
||||
final CheckBox volumeMixerCheckbox = new CheckBox(" Volume", core.getDefaultSkin());
|
||||
volumeMixerCheckbox.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (volumeMixerCheckbox.isChecked()) {
|
||||
addActor(volumeWindow);
|
||||
} else {
|
||||
volumeWindow.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(volumeMixerCheckbox);
|
||||
toolboxToolSet.row();
|
||||
|
||||
final CheckBox spawnToolCheckBox = new CheckBox(" Spawn Tool", core.getDefaultSkin());
|
||||
spawnToolCheckBox.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (spawnToolCheckBox.isChecked()) {
|
||||
addActor(spawnerWindow);
|
||||
} else {
|
||||
spawnerWindow.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(spawnToolCheckBox);
|
||||
toolboxToolSet.row();
|
||||
|
||||
final CheckBox diffAdjusterCheckBox = new CheckBox(" Difficulty", core.getDefaultSkin());
|
||||
diffAdjusterCheckBox.addListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (diffAdjusterCheckBox.isChecked()) {
|
||||
addActor(diffWindow);
|
||||
} else {
|
||||
diffWindow.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
toolboxToolSet.add(diffAdjusterCheckBox);
|
||||
|
||||
ScrollPane scroller = new ScrollPane(toolboxToolSet, core.getDefaultSkin());
|
||||
toolbox.add(scroller).height(250f).width(150f);
|
||||
addActor(toolbox);
|
||||
|
||||
addListener(new InputListener() {
|
||||
@Override
|
||||
public boolean keyUp(InputEvent event, int keycode) {
|
||||
if (keycode == Keys.ENTER || keycode == Keys.ESCAPE) {
|
||||
setKeyboardFocus(null);
|
||||
}
|
||||
return super.keyUp(event, keycode);
|
||||
}
|
||||
});
|
||||
toolbox.pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
super.act(delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (analyzer != null) {
|
||||
analyzer.getAudioDataPackage().getMusicInfo().dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MiniEvents ID) {
|
||||
switch (ID) {
|
||||
case BACK:
|
||||
|
||||
break;
|
||||
case MUSIC_SELECTED:
|
||||
beatViewer.setMusic(null, null);
|
||||
volumeWindow.setMusic(null);
|
||||
bassUMgraphWindow.setGraphingData(null, null, null);
|
||||
mGraphWindow.setGraphingData(null, null, null);
|
||||
if (musicPlayBackControls.getAudiofile() != null) {
|
||||
musicPlayBackControls.getAudiofile().dispose();
|
||||
}
|
||||
musicPlayBackControls.setAudiofile(null);
|
||||
analyzer = new AudioAnalyzer(musicSelector.getSelectedMusic());
|
||||
analyzer.sender.addListener(this);
|
||||
ghud.setMusic(null);
|
||||
|
||||
break;
|
||||
case SPECTRAL_FLUX_DONE:
|
||||
analyzer.runThresholdCleaning();
|
||||
break;
|
||||
case MUSIC_DATA_CLEANED:
|
||||
mapGen = new RhythmMapAlgorithm(gpa.em, gpa.cm, analyzer.getAudioDataPackage(), diffWindow.getSpeedModifier(), diffWindow.getHealthModifier(), diffWindow.getOverallDiffMod());
|
||||
mapGen.getSender().addListener(this);
|
||||
Thread mapGenThread = new Thread(mapGen);
|
||||
mapGenThread.start();
|
||||
break;
|
||||
case MAP_GENERATED:
|
||||
Gdx.app.debug("creative", "successfully generated map.");
|
||||
AudioDataPackage adp = analyzer.getAudioDataPackage();
|
||||
musicPlayBackControls.setAudiofile(adp.getMusicInfo());
|
||||
volumeWindow.setMusic(adp.getMusicInfo());
|
||||
beatViewer.setMusic(adp.getMusicInfo(), analyzer.getAudioDataPackage());
|
||||
|
||||
bassUMgraphWindow.setGraphingData(analyzer.getAudioDataPackage().getBassPeaks(), analyzer.getAudioDataPackage().getuMPeaks(), adp.getMusicInfo());
|
||||
bassUMgraphWindow.avgG1 = adp.getBassAvg();
|
||||
bassUMgraphWindow.normalDataG1 = adp.getBassMaxVal();
|
||||
bassUMgraphWindow.avgG2 = adp.getuMAvg();
|
||||
bassUMgraphWindow.normalDataG2 = adp.getuMMaxval();
|
||||
|
||||
mGraphWindow.setGraphingData(analyzer.getAudioDataPackage().getmPeaks(), null, adp.getMusicInfo());
|
||||
mGraphWindow.normalDataG1 = adp.getmMaxVal();
|
||||
mGraphWindow.avgG1 = adp.getmAvg();
|
||||
gpa.setAudioMap(mapGen.getMap());
|
||||
ghud.setMusic(adp.getMusicInfo());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user