temporarily disabled mp3's, began adding small event system

This commit is contained in:
Harrison Deng 2017-05-19 00:31:16 -05:00
parent 1e2ed0c68a
commit 14cd210024
12 changed files with 143 additions and 68 deletions

View File

@ -1,15 +1,16 @@
package zero1hd.polyjet.audio; package zero1hd.polyjet.audio;
import org.jaudiotagger.audio.AudioFile;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D; import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
import zero1hd.polyjet.util.MiniEvents;
import zero1hd.polyjet.util.MiniListener;
public class AudioAnalyzer { public class AudioAnalyzer {
private boolean containsData; private boolean containsData;
private boolean finalized;
FloatFFT_1D fft; FloatFFT_1D fft;
public AudioData audiofile; public AudioData audiofile;
@ -44,9 +45,12 @@ public class AudioAnalyzer {
int UMThresholdCalcRange; int UMThresholdCalcRange;
int bassThresholdCalcRange; int bassThresholdCalcRange;
private Array<MiniListener> listeners;
private volatile int progress; private volatile int progress;
public AudioAnalyzer() { public AudioAnalyzer() {
listeners = new Array<>();
analysisAlgorithm = new Runnable() { analysisAlgorithm = new Runnable() {
@Override @Override
@ -108,6 +112,8 @@ public class AudioAnalyzer {
shrinkData(); shrinkData();
containsData = true; containsData = true;
send(MiniEvents.SPECTRAL_FLUX_DONE);
} }
}; };
@ -188,6 +194,8 @@ public class AudioAnalyzer {
} }
Gdx.app.debug("Audio Analyzer", "overlapped beats checked."); Gdx.app.debug("Audio Analyzer", "overlapped beats checked.");
finalized = true;
} }
}; };
@ -242,6 +250,11 @@ public class AudioAnalyzer {
thresholdClean.start(); thresholdClean.start();
} }
public void runThresholdCleaning() {
Thread thresholdClean = new Thread(thresholdCalculator);
thresholdClean.start();
}
public FloatArray getBassPeaks() { public FloatArray getBassPeaks() {
return bassPeaks; return bassPeaks;
} }
@ -287,4 +300,18 @@ public class AudioAnalyzer {
public synchronized int getProgress() { public synchronized int getProgress() {
return progress; return progress;
} }
public boolean isFinalized() {
return finalized;
}
public void addListener(MiniListener listener) {
listeners.add(listener);
}
public void send(MiniEvents ID) {
while (listeners.iterator().hasNext()) {
listeners.iterator().next().handle(ID);
}
}
} }

View File

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

View File

@ -101,4 +101,8 @@ public class MusicSelectable extends Button implements Disposable {
audioInfo.dispose(); audioInfo.dispose();
} }
public boolean isMusicInvalid() {
return audioInfo.isInvalidMusic();
}
} }

View File

@ -106,10 +106,14 @@ public class MusicSelectionPage extends Page {
selectable.addInfoToPanel(musicChoiceScroller, panelWidthCalc(getWidth()) - 20f); selectable.addInfoToPanel(musicChoiceScroller, panelWidthCalc(getWidth()) - 20f);
selectable.addListener(new ChangeListener() { selectable.addListener(new ChangeListener() {
@Override @Override
public void changed(ChangeEvent event, Actor actor) { public void changed(ChangeEvent event, Actor actor) {
if (!selectable.isMusicInvalid()) {
ap.setSong(Audio.getAudioData(selectable.getMusicFile()), selectable.getAudioInfo()); ap.setSong(Audio.getAudioData(selectable.getMusicFile()), selectable.getAudioInfo());
} else {
//Play "no" sound
}
} }
}); });
} }

View File

@ -24,11 +24,14 @@ import zero1hd.polyjet.ui.windows.GraphWindow;
import zero1hd.polyjet.ui.windows.MusicController; import zero1hd.polyjet.ui.windows.MusicController;
import zero1hd.polyjet.ui.windows.MusicSelector; import zero1hd.polyjet.ui.windows.MusicSelector;
import zero1hd.polyjet.ui.windows.VolumeWindow; import zero1hd.polyjet.ui.windows.VolumeWindow;
import zero1hd.polyjet.util.MiniEvents;
import zero1hd.polyjet.util.MiniListener;
public class CreativeStage extends Stage { public class CreativeStage extends Stage implements MiniListener {
MusicController musicPlayBackControls; MusicController musicPlayBackControls;
MusicSelector musicSelector; MusicSelector musicSelector;
FPSWindow fpsViewer; FPSWindow fpsViewer;
BeatViewer beatViewer; BeatViewer beatViewer;
GraphWindow graphViewer; GraphWindow graphViewer;
VolumeWindow volumeWindow; VolumeWindow volumeWindow;
@ -36,17 +39,22 @@ public class CreativeStage extends Stage {
AudioAnalyzer analyzer; AudioAnalyzer analyzer;
Window toolbox; Window toolbox;
Polyjet core; Polyjet core;
boolean postAnalysisComplete;
private AudioData audioWrapper; private AudioData audioWrapper;
public CreativeStage(final Polyjet core, final MainMenu mainMenu) { public CreativeStage(final Polyjet core, final MainMenu mainMenu) {
this.core = core; this.core = core;
analyzer = new AudioAnalyzer(); analyzer = new AudioAnalyzer();
analyzer.addListener(this);
musicSelector = new MusicSelector("Select Audio File", core.getDefaultSkin(), core.prefs.getString("music dir"), "default"); musicSelector = new MusicSelector("Select Audio File", core.getDefaultSkin(), core.prefs.getString("music dir"), "default");
musicSelector.addListener(this);
musicSelector.postInit(); musicSelector.postInit();
musicSelector.refresh(); musicSelector.refresh();
fpsViewer = new FPSWindow("FPS", core.getDefaultSkin()); fpsViewer = new FPSWindow("FPS", core.getDefaultSkin());
beatViewer = new BeatViewer("Beat", core.getDefaultSkin(), core, analyzer); beatViewer = new BeatViewer("Beat", core.getDefaultSkin(), core, analyzer);
graphViewer = new GraphWindow("Peak Values", core.getDefaultSkin()); graphViewer = new GraphWindow("Peak Values", core.getDefaultSkin());
volumeWindow = new VolumeWindow("Volume adjustments", core.getDefaultSkin(), core.prefs); volumeWindow = new VolumeWindow("Volume adjustments", core.getDefaultSkin(), core.prefs);
@ -85,6 +93,7 @@ public class CreativeStage extends Stage {
toolboxToolSet.add(musicSelectorCheckbox); toolboxToolSet.add(musicSelectorCheckbox);
toolboxToolSet.row(); toolboxToolSet.row();
musicPlayBackControls = new MusicController(core.getDefaultSkin());
final CheckBox musicPlayBackCheckbox = new CheckBox(" Playback controls", core.getDefaultSkin()); final CheckBox musicPlayBackCheckbox = new CheckBox(" Playback controls", core.getDefaultSkin());
musicPlayBackCheckbox.addListener(new ChangeListener() { musicPlayBackCheckbox.addListener(new ChangeListener() {
@ -178,34 +187,9 @@ public class CreativeStage extends Stage {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (musicSelector.isConfirmed()) { if (musicPlayBackControls.getAudiofile() != null) {
audioWrapper = Audio.getAudioData(musicSelector.getSelectedMusic()); musicPlayBackControls.getAudiofile().readIndexUpdate();
audioWrapper.getPlaybackMusic().setVolume(core.prefs.getFloat("music vol")/100f);
analyzer.resetVars();
analyzer.startAnalyticalThread(audioWrapper);
musicPlayBackControls.setMusicReady(false);
beatViewer.setMusicReady(false);
graphViewer.setData(analyzer.getBassPeaks(), analyzer.getUMPeaks());
postAnalysisComplete = false;
} }
if (!postAnalysisComplete && analyzer.containsData()) {
postAnalysisComplete = true;
musicPlayBackControls.setMusicReady(true);
beatViewer.setMusicReady(true);
}
if (analyzer.audiofile != null) {
if (volumeWindow.isUpdateRequired()) {
analyzer.audiofile.getPlaybackMusic().setVolume(core.prefs.getFloat("music vol")/100f);
}
analyzer.audiofile.readIndexUpdate();
beatViewer.setSongIndex(analyzer.getReadIndex());
graphViewer.getGraph().setAudioDataIndex(analyzer.getReadIndex());
}
super.act(delta);
} }
@Override @Override
@ -216,4 +200,24 @@ public class CreativeStage extends Stage {
super.dispose(); super.dispose();
} }
@Override
public void handle(MiniEvents ID) {
switch (ID) {
case MUSIC_SELECTED:
beatViewer.setMusic(null);
volumeWindow.setMusic(null);
graphViewer.setData(null, null, null);
musicPlayBackControls.setAudiofile(null);
analyzer.startAnalyticalThread(Audio.getAudioData(musicSelector.getSelectedMusic()));
break;
case SPECTRAL_FLUX_DONE:
analyzer.runThresholdCleaning();
break;
case MUSIC_DATA_CLEANED:
musicPlayBackControls.setAudiofile(Audio.getAudioData(musicSelector.getSelectedMusic()));
volumeWindow.setMusic(musicPlayBackControls.getAudiofile());
beatViewer.setMusic(musicPlayBackControls.getAudiofile());
graphViewer.setData(analyzer.getBassPeaks(), analyzer.getUMPeaks(), musicPlayBackControls.getAudiofile());
}
}
} }

View File

@ -11,11 +11,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.Window;
import zero1hd.polyjet.Polyjet; import zero1hd.polyjet.Polyjet;
import zero1hd.polyjet.audio.AudioAnalyzer; import zero1hd.polyjet.audio.AudioAnalyzer;
import zero1hd.polyjet.audio.AudioData;
public class BeatViewer extends Window { public class BeatViewer extends Window {
Pixmap lights; Pixmap lights;
int songIndex; int songIndex;
boolean musicReady; AudioData music;
Texture lightOn; Texture lightOn;
public BeatViewer(String title, Skin skin, Polyjet core, final AudioAnalyzer data) { public BeatViewer(String title, Skin skin, Polyjet core, final AudioAnalyzer data) {
@ -39,7 +40,7 @@ public class BeatViewer extends Window {
final Image bassBarFill = new Image(core.getDefaultSkin().getPatch("bar-fill")) { final Image bassBarFill = new Image(core.getDefaultSkin().getPatch("bar-fill")) {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (musicReady && data.getBassPeaks().get(songIndex) >= 1f) { if (music != null && data.getBassPeaks().get(songIndex) >= 1f) {
clearActions(); clearActions();
addAction(Actions.sequence(Actions.sizeTo(getWidth(), (data.getBassPeaks().get(songIndex)/data.getBassMaxValue())*bgBassBar.getHeight()), Actions.sizeTo(getWidth(), 0, 0.3f))); addAction(Actions.sequence(Actions.sizeTo(getWidth(), (data.getBassPeaks().get(songIndex)/data.getBassMaxValue())*bgBassBar.getHeight()), Actions.sizeTo(getWidth(), 0, 0.3f)));
} }
@ -58,7 +59,7 @@ public class BeatViewer extends Window {
Image UMBarFill = new Image(core.getDefaultSkin().getPatch("bar-fill")) { Image UMBarFill = new Image(core.getDefaultSkin().getPatch("bar-fill")) {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (musicReady && data.getUMPeaks().get(songIndex) >= 1f) { if (music != null && data.getUMPeaks().get(songIndex) >= 1f) {
clearActions(); clearActions();
addAction(Actions.sequence(Actions.sizeTo(getWidth(), (data.getUMPeaks().get(songIndex)/data.getUMMaxValue())*bgUMBar.getHeight()), Actions.sizeTo(getWidth(), 0f, 0.3f))); addAction(Actions.sequence(Actions.sizeTo(getWidth(), (data.getUMPeaks().get(songIndex)/data.getUMMaxValue())*bgUMBar.getHeight()), Actions.sizeTo(getWidth(), 0f, 0.3f)));
} }
@ -76,7 +77,7 @@ public class BeatViewer extends Window {
Image bassIndicator = new Image(lightOn) { Image bassIndicator = new Image(lightOn) {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (musicReady && data.getBassPeaks().get(songIndex) >= 2) { if (music != null && data.getBassPeaks().get(songIndex) >= 2) {
clearActions(); clearActions();
addAction(Actions.sequence(Actions.alpha(1f), Actions.fadeOut(0.15f))); addAction(Actions.sequence(Actions.alpha(1f), Actions.fadeOut(0.15f)));
} }
@ -91,7 +92,7 @@ public class BeatViewer extends Window {
Image UMIndicator = new Image(lightOn) { Image UMIndicator = new Image(lightOn) {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (musicReady && data.getUMPeaks().get(songIndex) >= 1) { if (music != null && data.getUMPeaks().get(songIndex) >= 1) {
clearActions(); clearActions();
addAction(Actions.sequence(Actions.alpha(1f), Actions.fadeOut(0.15f))); addAction(Actions.sequence(Actions.alpha(1f), Actions.fadeOut(0.15f)));
} }
@ -102,11 +103,13 @@ public class BeatViewer extends Window {
add(UMIndicator).center(); add(UMIndicator).center();
} }
public void setSongIndex(int songIndex) { @Override
this.songIndex = songIndex; public void act(float delta) {
songIndex = music.getReadIndex();
super.act(delta);
} }
public void setMusicReady(boolean musicReady) { public void setMusic(AudioData audioData) {
this.musicReady = musicReady; this.music = audioData;
} }
} }

View File

@ -4,10 +4,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Window; import com.badlogic.gdx.scenes.scene2d.ui.Window;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
import zero1hd.polyjet.audio.AudioData;
import zero1hd.polyjet.ui.builders.AudioGraph; import zero1hd.polyjet.ui.builders.AudioGraph;
public class GraphWindow extends Window { public class GraphWindow extends Window {
AudioGraph graph; AudioGraph graph;
AudioData audioData;
public GraphWindow(String title, Skin skin) { public GraphWindow(String title, Skin skin) {
super(title, skin); super(title, skin);
@ -18,15 +20,13 @@ public class GraphWindow extends Window {
@Override @Override
public void act(float delta) { public void act(float delta) {
graph.setAudioDataIndex(audioData.getReadIndex());
super.act(delta); super.act(delta);
} }
public void setData(FloatArray dataSet1, FloatArray dataSet2) { public void setData(FloatArray dataSet1, FloatArray dataSet2, AudioData audioData) {
this.audioData = audioData;
graph.setGraphingData(dataSet1, dataSet2); graph.setGraphingData(dataSet1, dataSet2);
} }
public AudioGraph getGraph() {
return graph;
}
} }

View File

@ -16,15 +16,13 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import zero1hd.polyjet.audio.AudioData; import zero1hd.polyjet.audio.AudioData;
public class MusicController extends Window { public class MusicController extends Window {
boolean musicReady;
Skin skin; Skin skin;
private Image togglePlay; private Image togglePlay;
private TextField info; private TextField info;
private AudioData audiofile; private AudioData audiofile;
public MusicController(final Skin skin, final AudioData audiofile) { public MusicController(final Skin skin) {
super("Playback Controller", skin); super("Playback Controller", skin);
this.audiofile = audiofile;
defaults().space(5f); defaults().space(5f);
@ -49,7 +47,7 @@ public class MusicController extends Window {
if (audiofile.getPlaybackMusic() != null) { if (audiofile.getPlaybackMusic() != null) {
if (audiofile.getPlaybackMusic().isPlaying()) { if (audiofile.getPlaybackMusic().isPlaying()) {
setDrawable(skin.getDrawable("pause")); setDrawable(skin.getDrawable("pause"));
} else if (!audiofile.getPlaybackMusic().isPlaying() && musicReady) { } else if (!audiofile.getPlaybackMusic().isPlaying() && audiofile != null) {
setDrawable(skin.getDrawable("arrow")); setDrawable(skin.getDrawable("arrow"));
} }
} }
@ -63,7 +61,7 @@ public class MusicController extends Window {
if (audiofile.getPlaybackMusic().isPlaying()) { if (audiofile.getPlaybackMusic().isPlaying()) {
audiofile.getPlaybackMusic().pause(); audiofile.getPlaybackMusic().pause();
} else { } else {
if (musicReady) { if (audiofile != null) {
audiofile.getPlaybackMusic().play(); audiofile.getPlaybackMusic().play();
} }
} }
@ -115,9 +113,12 @@ public class MusicController extends Window {
setSize(260, 75); setSize(260, 75);
} }
public void setMusicReady(boolean musicReady) {
this.musicReady = musicReady; public void setAudiofile(AudioData audiofile) {
if (!musicReady) { this.audiofile.reset();
this.audiofile = audiofile;
if (audiofile == null) {
togglePlay.setDrawable(skin.getDrawable("loading")); togglePlay.setDrawable(skin.getDrawable("loading"));
info.setText("Analyzing..."); info.setText("Analyzing...");
} else { } else {
@ -126,11 +127,10 @@ public class MusicController extends Window {
audiofile.getPlaybackMusic().play(); audiofile.getPlaybackMusic().play();
audiofile.getPlaybackMusic().pause(); audiofile.getPlaybackMusic().pause();
} }
} }
@Override public AudioData getAudiofile() {
public void act(float delta) { return audiofile;
// TODO Auto-generated method stub
super.act(delta);
} }
} }

View File

@ -11,6 +11,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.Window;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import zero1hd.polyjet.util.MiniEvents;
import zero1hd.polyjet.util.MiniListener;
public class MusicSelector extends Window { public class MusicSelector extends Window {
boolean confirmed; boolean confirmed;
boolean back; boolean back;
@ -19,6 +22,9 @@ public class MusicSelector extends Window {
private List<String> musicList; private List<String> musicList;
private String path; private String path;
private ScrollPane listScroller; private ScrollPane listScroller;
private Array<MiniListener> listeners;
public MusicSelector(String title, Skin skin, final String path, String listStyle) { public MusicSelector(String title, Skin skin, final String path, String listStyle) {
super(title, skin); super(title, skin);
this.path = path; this.path = path;
@ -26,6 +32,8 @@ public class MusicSelector extends Window {
padLeft(5f); padLeft(5f);
padRight(5f); padRight(5f);
listeners = new Array<>();
setSize(Gdx.graphics.getWidth()*0.5f, Gdx.graphics.getHeight()*0.5f); setSize(Gdx.graphics.getWidth()*0.5f, Gdx.graphics.getHeight()*0.5f);
fileNames = new Array<>(); fileNames = new Array<>();
@ -38,6 +46,7 @@ public class MusicSelector extends Window {
public void changed(ChangeEvent event, Actor actor) { public void changed(ChangeEvent event, Actor actor) {
confirmed = true; confirmed = true;
selectedMusic = Gdx.files.absolute(path+System.getProperty("file.separator")+musicList.getSelected()); selectedMusic = Gdx.files.absolute(path+System.getProperty("file.separator")+musicList.getSelected());
send(MiniEvents.MUSIC_SELECTED);
} }
}); });
add(confirmButton).right(); add(confirmButton).right();
@ -80,4 +89,14 @@ public class MusicSelector extends Window {
public FileHandle getSelectedMusic() { public FileHandle getSelectedMusic() {
return selectedMusic; return selectedMusic;
} }
private void send(MiniEvents ID) {
while (listeners.iterator().hasNext()) {
listeners.iterator().next().handle(ID);
}
}
public void addListener(MiniListener handler) {
listeners.add(handler);
}
} }

View File

@ -9,13 +9,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.Slider;
import com.badlogic.gdx.scenes.scene2d.ui.Window; import com.badlogic.gdx.scenes.scene2d.ui.Window;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import zero1hd.polyjet.audio.AudioData;
public class VolumeWindow extends Window { public class VolumeWindow extends Window {
private Slider fxVolSlider; private Slider fxVolSlider;
private Slider musicVolSlider; private Slider musicVolSlider;
private Preferences prefs; private Preferences prefs;
boolean updateRequired;
private AudioData music;
public VolumeWindow(String title, Skin skin, Preferences prefs) { public VolumeWindow(String title, Skin skin, Preferences prefs) {
super(title, skin); super(title, skin);
this.prefs = prefs; this.prefs = prefs;
@ -32,6 +34,9 @@ public class VolumeWindow extends Window {
public void changed(ChangeEvent event, Actor actor) { public void changed(ChangeEvent event, Actor actor) {
save(); save();
musicVolPercentage.setText(MathUtils.round(musicVolSlider.getValue()) + "%"); musicVolPercentage.setText(MathUtils.round(musicVolSlider.getValue()) + "%");
if (music != null) {
music.getPlaybackMusic().setVolume(musicVolSlider.getValue()/100f);
}
} }
}); });
@ -59,13 +64,10 @@ public class VolumeWindow extends Window {
public void save() { public void save() {
prefs.putFloat("music vol", musicVolSlider.getValue()); prefs.putFloat("music vol", musicVolSlider.getValue());
prefs.putFloat("fx vol", fxVolSlider.getValue()); prefs.putFloat("fx vol", fxVolSlider.getValue());
updateRequired = true;
prefs.flush(); prefs.flush();
} }
public boolean isUpdateRequired() { public void setMusic(AudioData music) {
boolean isUpdateRequired = updateRequired; this.music = music;
updateRequired = false;
return isUpdateRequired;
} }
} }

View File

@ -0,0 +1,5 @@
package zero1hd.polyjet.util;
public enum MiniEvents {
SPECTRAL_FLUX_DONE, MUSIC_DATA_CLEANED, MUSIC_SELECTED;
}

View File

@ -0,0 +1,5 @@
package zero1hd.polyjet.util;
public interface MiniListener {
public void handle(MiniEvents ID);
}