From 22ab329e19415a8fe4f7c4fbd1a504d48cec3f37 Mon Sep 17 00:00:00 2001 From: Recrown Date: Wed, 6 Sep 2017 23:31:10 -0500 Subject: [PATCH] Prototyping visualizer as well as design scheme --- android/assets/uiskin.png | Bin 5574 -> 5845 bytes .../zero1hd/rhythmbullet/RhythmBullet.java | 9 +- .../src/zero1hd/rhythmbullet/audio/Audio.java | 15 -- .../audio/{AudioInfo.java => SongInfo.java} | 32 +++- .../zero1hd/rhythmbullet/audio/SongList.java | 48 ++++++ .../rhythmbullet/audio/WavAudioData.java | 2 +- .../visualizer/HorizontalVisualizer.java | 59 +++++++ .../audio/visualizer/VisualizerCore.java | 49 ++++++ .../audio}/wavedecoder/WavDecoder.java | 2 +- .../rhythmbullet/screens/CreativeScreen.java | 5 +- .../rhythmbullet/screens/MainMenu.java | 15 +- .../rhythmbullet/screens/PreGameScreen.java | 13 +- .../rhythmbullet/stages/CreativeHUD.java | 5 +- .../ui/builders/MusicSelectable.java | 148 ++++++++--------- .../rhythmbullet/ui/builders/ScrollText.java | 12 +- .../rhythmbullet/ui/builders/Visualizer.java | 33 ---- .../rhythmbullet/ui/pages/AnalyzePage.java | 4 +- .../rhythmbullet/ui/pages/MainPage.java | 29 +++- .../ui/pages/MusicSelectionPage.java | 154 +++++------------- .../rhythmbullet/ui/pages/OptionsPage.java | 5 +- .../ui/windows/MusicSelector.java | 23 +-- 21 files changed, 367 insertions(+), 295 deletions(-) delete mode 100755 core/src/zero1hd/rhythmbullet/audio/Audio.java rename core/src/zero1hd/rhythmbullet/audio/{AudioInfo.java => SongInfo.java} (78%) create mode 100755 core/src/zero1hd/rhythmbullet/audio/SongList.java create mode 100755 core/src/zero1hd/rhythmbullet/audio/visualizer/HorizontalVisualizer.java create mode 100755 core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java rename core/src/zero1hd/{ => rhythmbullet/audio}/wavedecoder/WavDecoder.java (97%) delete mode 100755 core/src/zero1hd/rhythmbullet/ui/builders/Visualizer.java diff --git a/android/assets/uiskin.png b/android/assets/uiskin.png index 960d3148b670edc9f1fdfcb2b086cd7e59a5481f..1c5bd4988fd5940f3a23195653de109d7cce0bb9 100755 GIT binary patch literal 5845 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 literal 5574 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 diff --git a/core/src/zero1hd/rhythmbullet/RhythmBullet.java b/core/src/zero1hd/rhythmbullet/RhythmBullet.java index 76070fb..0b240ed 100755 --- a/core/src/zero1hd/rhythmbullet/RhythmBullet.java +++ b/core/src/zero1hd/rhythmbullet/RhythmBullet.java @@ -19,7 +19,6 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle; import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle; import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; import com.badlogic.gdx.scenes.scene2d.ui.List.ListStyle; @@ -53,7 +52,6 @@ public class RhythmBullet extends Game { private Preferences prefs; private RoundingResolutionHandler rRHandler; - @Override public void create() { Gdx.app.setLogLevel(Application.LOG_DEBUG); @@ -113,7 +111,7 @@ public class RhythmBullet extends Game { public void dispose() { Gdx.app.debug("Core", "disposing..."); if (initComplete) { -// skinAtlas.dispose(); + skinAtlas.dispose(); getDefaultSkin().dispose(); default_fontGenerator.dispose(); darktech_ldr_fontGenerator.dispose(); @@ -252,11 +250,6 @@ public class RhythmBullet extends Game { vertSlider.knob = getDefaultSkin().getDrawable("vertical-slider-knob"); getDefaultSkin().add("default-vertical", vertSlider); - ButtonStyle infoButton = new ButtonStyle(); - infoButton.up = getDefaultSkin().getDrawable("holo-pane"); - infoButton.down = getDefaultSkin().getDrawable("holo-pane-down"); - getDefaultSkin().add("info-button", infoButton); - LabelStyle defaultLabel = new LabelStyle(); defaultLabel.font = getDefaultSkin().getFont("default-font"); defaultLabel.fontColor = getDefaultSkin().getColor("default"); diff --git a/core/src/zero1hd/rhythmbullet/audio/Audio.java b/core/src/zero1hd/rhythmbullet/audio/Audio.java deleted file mode 100755 index ddfde16..0000000 --- a/core/src/zero1hd/rhythmbullet/audio/Audio.java +++ /dev/null @@ -1,15 +0,0 @@ -package zero1hd.rhythmbullet.audio; - -import com.badlogic.gdx.files.FileHandle; - -public class Audio { - public static CoreMusicInfo getAudioData(FileHandle file) { - if (file.extension().equalsIgnoreCase("wav")) { - return new WavAudioData(file); - } else if (file.extension().equalsIgnoreCase("mp3")) { - return new Mp3AudioData(file); - - } - return null; - } -} diff --git a/core/src/zero1hd/rhythmbullet/audio/AudioInfo.java b/core/src/zero1hd/rhythmbullet/audio/SongInfo.java similarity index 78% rename from core/src/zero1hd/rhythmbullet/audio/AudioInfo.java rename to core/src/zero1hd/rhythmbullet/audio/SongInfo.java index 4ca9ee9..b5ecb7c 100755 --- a/core/src/zero1hd/rhythmbullet/audio/AudioInfo.java +++ b/core/src/zero1hd/rhythmbullet/audio/SongInfo.java @@ -18,7 +18,7 @@ import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.utils.Disposable; -public class AudioInfo implements Disposable { +public class SongInfo implements Disposable { private long durationInSeconds; private String songName; private Texture albumCover; @@ -28,7 +28,17 @@ public class AudioInfo implements Disposable { private byte[] albumWorkBytes; private boolean invalidMusic; - public AudioInfo(FileHandle musicFile, Preferences musicData) { + private boolean containsInfo; + + private FileHandle musicFile; + private Preferences musicAnnotation; + + public SongInfo(FileHandle musicFile, Preferences musicData) { + this.musicFile = musicFile; + this.musicAnnotation = musicData; + } + + public void loadInfo() { if (musicFile.extension().toLowerCase().equals("mp3")) { MP3File mp3File; try { @@ -68,8 +78,8 @@ public class AudioInfo implements Disposable { songName = musicFile.nameWithoutExtension(); } - previousTop = musicData.getInteger(songName + ":previous top", -1); - ratedDifficulty = musicData.getInteger(songName + ":difficulty", -1); + previousTop = musicAnnotation.getInteger(songName + ":previous top", -1); + ratedDifficulty = musicAnnotation.getInteger(songName + ":difficulty", -1); if (author == null || author.isEmpty()) { author = "N/A"; @@ -119,4 +129,18 @@ public class AudioInfo implements Disposable { albumCover.dispose(); } + /** + * tells this song info that it does contain information + */ + public void doesContainsInformation() { + containsInfo = true; + } + + /** + * Asks if this contains information. + * @return whether this contains data + */ + public boolean hasInformation() { + return containsInfo; + } } diff --git a/core/src/zero1hd/rhythmbullet/audio/SongList.java b/core/src/zero1hd/rhythmbullet/audio/SongList.java new file mode 100755 index 0000000..2a0aa74 --- /dev/null +++ b/core/src/zero1hd/rhythmbullet/audio/SongList.java @@ -0,0 +1,48 @@ +package zero1hd.rhythmbullet.audio; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Array; + +public class SongList { + private Array songList; + private String searchPath; + + public SongList() { + songList = new Array<>(); + } + + public void refresh() { + songList.addAll(Gdx.files.absolute(searchPath).list((dir, name) -> { + if (name.endsWith("mp3") || name.endsWith("wav")) { + return true; + } + return false; + })); + } + + public void setSearchPath(String searchPath) { + this.searchPath = searchPath; + } + + public CoreMusicInfo getAudioData(FileHandle file) { + if (file.extension().equalsIgnoreCase("wav")) { + return new WavAudioData(file); + } else if (file.extension().equalsIgnoreCase("mp3")) { + return new Mp3AudioData(file); + } + return null; + } + + public CoreMusicInfo getMusicInfoFromIndex(int index) { + return getAudioData(songList.get(index)); + } + + public Array getSongList() { + return songList; + } + + public int getAmountOfSongs() { + return songList.size; + } +} diff --git a/core/src/zero1hd/rhythmbullet/audio/WavAudioData.java b/core/src/zero1hd/rhythmbullet/audio/WavAudioData.java index b71ec12..e7bb089 100755 --- a/core/src/zero1hd/rhythmbullet/audio/WavAudioData.java +++ b/core/src/zero1hd/rhythmbullet/audio/WavAudioData.java @@ -9,7 +9,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.files.FileHandle; -import zero1hd.wavedecoder.WavDecoder; +import zero1hd.rhythmbullet.audio.wavedecoder.WavDecoder; public class WavAudioData implements CoreMusicInfo { private int readWindowSize = 1024; diff --git a/core/src/zero1hd/rhythmbullet/audio/visualizer/HorizontalVisualizer.java b/core/src/zero1hd/rhythmbullet/audio/visualizer/HorizontalVisualizer.java new file mode 100755 index 0000000..4a6b753 --- /dev/null +++ b/core/src/zero1hd/rhythmbullet/audio/visualizer/HorizontalVisualizer.java @@ -0,0 +1,59 @@ +package zero1hd.rhythmbullet.audio.visualizer; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Pixmap.Format; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; + +import zero1hd.rhythmbullet.audio.CoreMusicInfo; + +public class HorizontalVisualizer extends VisualizerCore { + private Pixmap pixmap; + private Texture bar; + private int barWidth; + private int binsPerBar; + private int spaceBetweenBars; + + public HorizontalVisualizer() { + super(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()/2, 0, 0); + + pixmap = new Pixmap(2, 2, Format.RGBA8888); + pixmap.setColor(Color.GRAY); + pixmap.fill(); + bar = new Texture(pixmap); + pixmap.dispose(); + barCount = 64; + + barWidth = width/barCount; + } + + @Override + public void render(Batch batch, float parentAlpha) { + if (cmi != null) { + for (int i = 0; i < barCount; i++) { + int currentBinAvg = 0; + for (int j = i; j < binsPerBar; j++) { + currentBinAvg += audioPCM[j]; + } + currentBinAvg /= binsPerBar; + + batch.draw(bar, xPos + i*(barWidth+spaceBetweenBars), yPos, barWidth, currentBinAvg*height); + } + } + super.render(batch, parentAlpha); + } + + @Override + public void setCmi(CoreMusicInfo cmi) { + binsPerBar = audioPCM.length/barCount; + super.setCmi(cmi); + } + + @Override + public void dispose() { + bar.dispose(); + super.dispose(); + } +} diff --git a/core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java b/core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java new file mode 100755 index 0000000..dc54dd2 --- /dev/null +++ b/core/src/zero1hd/rhythmbullet/audio/visualizer/VisualizerCore.java @@ -0,0 +1,49 @@ +package zero1hd.rhythmbullet.audio.visualizer; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.utils.Disposable; + +import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D; +import zero1hd.rhythmbullet.audio.CoreMusicInfo; + +public class VisualizerCore implements Disposable { + protected CoreMusicInfo cmi; + private FloatFFT_1D fft; + float[] audioPCM; + protected int width, height; + protected int xPos, yPos; + protected int barCount; + + public VisualizerCore(int width, int height, int x, int y) { + } + + public void update() { + if (cmi != null) { + if (cmi.getPlaybackIndexPosition() > cmi.getCurrentReadWindowIndex()) { + cmi.readSamples(audioPCM); + fft.realForward(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."); + } + } + } + + public void setCmi(CoreMusicInfo cmi) { + this.cmi = cmi; + fft = new FloatFFT_1D(cmi.getReadWindowSize()); + audioPCM = new float[cmi.getReadWindowSize()]; + } + + public void render(Batch batch, float parentAlpha) { + + } + + @Override + public void dispose() { + // TODO Auto-generated method stub + + } + +} diff --git a/core/src/zero1hd/wavedecoder/WavDecoder.java b/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WavDecoder.java similarity index 97% rename from core/src/zero1hd/wavedecoder/WavDecoder.java rename to core/src/zero1hd/rhythmbullet/audio/wavedecoder/WavDecoder.java index 29e39fa..b545457 100755 --- a/core/src/zero1hd/wavedecoder/WavDecoder.java +++ b/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WavDecoder.java @@ -1,4 +1,4 @@ -package zero1hd.wavedecoder; +package zero1hd.rhythmbullet.audio.wavedecoder; import java.io.IOException; diff --git a/core/src/zero1hd/rhythmbullet/screens/CreativeScreen.java b/core/src/zero1hd/rhythmbullet/screens/CreativeScreen.java index eb9ae2a..c5f2da2 100755 --- a/core/src/zero1hd/rhythmbullet/screens/CreativeScreen.java +++ b/core/src/zero1hd/rhythmbullet/screens/CreativeScreen.java @@ -3,6 +3,7 @@ package zero1hd.rhythmbullet.screens; import com.badlogic.gdx.Preferences; import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.audio.SongList; import zero1hd.rhythmbullet.stages.CreativeHUD; public class CreativeScreen extends GameScreen { @@ -10,9 +11,9 @@ public class CreativeScreen extends GameScreen { Preferences prefs; - public CreativeScreen(RhythmBullet core, MainMenu mainMenu) { + public CreativeScreen(RhythmBullet core, MainMenu mainMenu, SongList sl) { super(core, mainMenu); - chud = new CreativeHUD(core, mainMenu, gameArea, gameHUD); + chud = new CreativeHUD(core, mainMenu, gameArea, gameHUD, sl); inputs.addProcessor(chud); this.prefs = core.getPrefs(); diff --git a/core/src/zero1hd/rhythmbullet/screens/MainMenu.java b/core/src/zero1hd/rhythmbullet/screens/MainMenu.java index 52d46ab..730b5bb 100755 --- a/core/src/zero1hd/rhythmbullet/screens/MainMenu.java +++ b/core/src/zero1hd/rhythmbullet/screens/MainMenu.java @@ -12,6 +12,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.viewport.ScreenViewport; import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.audio.SongList; import zero1hd.rhythmbullet.ui.pages.CreditsPage; import zero1hd.rhythmbullet.ui.pages.MainPage; import zero1hd.rhythmbullet.ui.pages.MoreOptionsPage; @@ -29,12 +30,16 @@ public class MainMenu extends ScreenAdapter implements TransitionAdapter { private RhythmBullet core; + private SongList songList; private float lerpAlpha; public MainMenu(final RhythmBullet core) { this.core = core; stage = new Stage(new ScreenViewport()); targetPosition = new Vector3(stage.getCamera().position); - + + songList = new SongList(); + songList.setSearchPath(core.getPrefs().getString("music dir")); + songList.refresh(); postTransition(); } @@ -49,14 +54,14 @@ public class MainMenu extends ScreenAdapter implements TransitionAdapter { @Override public void postTransition() { - mainPage = new MainPage(core, targetPosition); + mainPage = new MainPage(core, targetPosition, songList); mainPage.setPosition(0, 0); stage.addActor(mainPage); //End main menu moreOptionsPage = new MoreOptionsPage(core, targetPosition); - optionsPage = new OptionsPage(core, targetPosition, moreOptionsPage); + optionsPage = new OptionsPage(core, targetPosition, moreOptionsPage, songList); optionsPage.setPosition(Gdx.graphics.getWidth(), 0); stage.addActor(optionsPage); @@ -119,13 +124,11 @@ public class MainMenu extends ScreenAdapter implements TransitionAdapter { @Override public void render(float delta) { - Gdx.gl.glClearColor(1f, 1f, 1f, 1f); + Gdx.gl.glClearColor(0f, 0f, 0f, 1f); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); stage.act(); - stage.draw(); if (stage.getCamera().position.x != targetPosition.x || stage.getCamera().position.y != targetPosition.y) { - stage.getCamera().position.lerp(targetPosition, lerpAlpha); } diff --git a/core/src/zero1hd/rhythmbullet/screens/PreGameScreen.java b/core/src/zero1hd/rhythmbullet/screens/PreGameScreen.java index 543037b..29a0b6a 100755 --- a/core/src/zero1hd/rhythmbullet/screens/PreGameScreen.java +++ b/core/src/zero1hd/rhythmbullet/screens/PreGameScreen.java @@ -8,14 +8,14 @@ import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.viewport.ScreenViewport; import zero1hd.rhythmbullet.RhythmBullet; -import zero1hd.rhythmbullet.audio.Audio; +import zero1hd.rhythmbullet.audio.SongList; import zero1hd.rhythmbullet.ui.pages.AnalyzePage; import zero1hd.rhythmbullet.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; @@ -23,11 +23,13 @@ public class PreGameScreen extends ScreenAdapter implements TransitionAdapter, M public AnalyzePage ap; private Vector3 cameraPos; private RhythmBullet core; + private SongList songList; - public PreGameScreen(RhythmBullet core) { + public PreGameScreen(RhythmBullet core, SongList songList) { stage = new Stage(new ScreenViewport()); cameraPos = new Vector3(stage.getCamera().position); this.core = core; + this.songList = songList; postTransition(); } @@ -62,7 +64,7 @@ public class PreGameScreen extends ScreenAdapter implements TransitionAdapter, M switch (ID) { case MUSIC_SELECTED: cameraPos.x = 1.5f*Gdx.graphics.getWidth(); - ap.setSong(Audio.getAudioData(ms.getSelectedMusic()), ms.getSelectedMusicInfo(), this); + ap.setSong(songList.getAudioData(ms.getSelectedMusic()), ms.getSelectedMusicInfo(), this); break; case BACK: if (cameraPos.x == 1.5f*Gdx.graphics.getWidth()) { @@ -85,9 +87,8 @@ public class PreGameScreen extends ScreenAdapter implements TransitionAdapter, M @Override public void postTransition() { - ms = new MusicSelectionPage(core); + ms = new MusicSelectionPage(core.getDefaultSkin(), songList, core.getAssetManager()); ms.miniSender.addListener(this); - ms.beginMusicSearch(); stage.addActor(ms); ap = new AnalyzePage(core); diff --git a/core/src/zero1hd/rhythmbullet/stages/CreativeHUD.java b/core/src/zero1hd/rhythmbullet/stages/CreativeHUD.java index 6d024db..a32eba4 100755 --- a/core/src/zero1hd/rhythmbullet/stages/CreativeHUD.java +++ b/core/src/zero1hd/rhythmbullet/stages/CreativeHUD.java @@ -16,6 +16,7 @@ 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.SongList; import zero1hd.rhythmbullet.audio.map.RhythmMapAlgorithm; import zero1hd.rhythmbullet.screens.MainMenu; import zero1hd.rhythmbullet.ui.builders.AudioGraph; @@ -46,11 +47,11 @@ public class CreativeHUD extends Stage implements MiniListener { GamePlayArea gpa; GameHUD ghud; - public CreativeHUD(final RhythmBullet core, final MainMenu mainMenu, final GamePlayArea gpa, GameHUD ghud) { + public CreativeHUD(final RhythmBullet core, final MainMenu mainMenu, final GamePlayArea gpa, GameHUD ghud, SongList sl) { this.gpa = gpa; this.ghud = ghud; - musicSelector = new MusicSelector("Select Audio File", core.getDefaultSkin(), core.getPrefs().getString("music dir"), "default"); + musicSelector = new MusicSelector("Select Audio File", core.getDefaultSkin(), core.getPrefs().getString("music dir"), sl); musicSelector.miniSender.addListener(this); musicSelector.refresh(); diff --git a/core/src/zero1hd/rhythmbullet/ui/builders/MusicSelectable.java b/core/src/zero1hd/rhythmbullet/ui/builders/MusicSelectable.java index 07bcb49..e2b1ce4 100755 --- a/core/src/zero1hd/rhythmbullet/ui/builders/MusicSelectable.java +++ b/core/src/zero1hd/rhythmbullet/ui/builders/MusicSelectable.java @@ -2,107 +2,95 @@ package zero1hd.rhythmbullet.ui.builders; import com.badlogic.gdx.Preferences; import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.scenes.scene2d.ui.Button; 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.Table; -import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.scenes.scene2d.ui.Widget; import com.badlogic.gdx.utils.Disposable; -import zero1hd.rhythmbullet.audio.AudioInfo; +import zero1hd.rhythmbullet.audio.SongInfo; + +public class MusicSelectable extends Widget implements Disposable { + private Table table; -public class MusicSelectable extends Button implements Disposable { - private Image imageIcon; private ScrollText displayName; - private Label runTime; + private Label durationLabel; private Label authorLabel; - private Label previousTopLabel; - private Label ratedDifficultyLabel; - private Skin skin; - - private FileHandle musicFile; - - private Texture defaultAlbumCover; - AudioInfo audioInfo; - - public MusicSelectable(FileHandle musicFile, Preferences musicData, final Skin skin, Texture defaultAlbumC) { - super(skin, "info-button"); - this.skin = skin; - this.defaultAlbumCover = defaultAlbumC; - this.musicFile = musicFile; - - setName(musicFile.name()); - - audioInfo = new AudioInfo(musicFile, musicData); - - defaults().pad(10f); - } - - - public void addInfoToPanel(float coverSize) { - displayName = new ScrollText(audioInfo.getSongName(), skin, true); - - defaults().align(Align.top); - - add(displayName).expandX().pad(0).fillX().padTop(10f).top().padBottom(10f); - row(); - String formattedTime = "Run time: "+ String.valueOf(audioInfo.getDurationInSeconds()/60) + ":"; - if (audioInfo.getDurationInSeconds() - (audioInfo.getDurationInSeconds()/60)*60 < 10) { - formattedTime = formattedTime.concat("0"); - } - - Table songInfoTable = new Table(); - - formattedTime = formattedTime.concat(String.valueOf(audioInfo.getDurationInSeconds() - (audioInfo.getDurationInSeconds()/60)*60)); - runTime = new Label(formattedTime, skin, "sub-font", skin.getColor("default")); - songInfoTable.add(runTime).expandX().left(); - songInfoTable.row(); - - authorLabel = new Label("Author: " + audioInfo.getAuthor(), skin, "sub-font", skin.getColor("default")); - songInfoTable.add(authorLabel).left(); - songInfoTable.row(); - - previousTopLabel = new Label("High Score: " + (audioInfo.getPreviousTop() != -1 ? audioInfo.getPreviousTop() : "N/A"), skin, "sub-font", skin.getColor("default")); - songInfoTable.add(previousTopLabel).left(); - songInfoTable.row(); - - ratedDifficultyLabel = new Label("Difficulty: " + (audioInfo.getRatedDifficulty() != -1 ? audioInfo.getRatedDifficulty() : "N/A"), skin, "sub-font", skin.getColor("default")); - songInfoTable.add(ratedDifficultyLabel).left(); - songInfoTable.row(); - - row(); - add(songInfoTable).expandY().center(); - row(); - - audioInfo.setupTexture(defaultAlbumCover); - - imageIcon = new Image(audioInfo.getAlbumCover()); - if (audioInfo.isInvalidMusic()) { - imageIcon.setColor(Color.RED); - } - add(imageIcon).expandY().center().pad(15f).size(coverSize); - } + private FileHandle musicFile; + + private Texture albumCover; + private SongInfo songInfo; + private boolean selected; + + public MusicSelectable(FileHandle musicFile, Preferences musicAnnotation, Skin skin, Texture defaultAlbumC) { + table = new Table(skin); + table.setBackground("holo-pane"); + table.setFillParent(true); + + setName(musicFile.name()); + + this.albumCover = defaultAlbumC; + this.musicFile = musicFile; + songInfo = new SongInfo(musicFile, musicAnnotation); + + imageIcon = new Image(albumCover); + table.add(imageIcon); + + displayName = new ScrollText(musicFile.name(), skin, true); + table.add(displayName); + + table.row(); + + durationLabel = new Label("Loading...", skin, "sub-font"); + table.add(durationLabel); + + authorLabel = new Label("Loading...", skin, "sub-font"); + + table.defaults().pad(10f); + } + + public void updateInfo() { + durationLabel.setText("Runtime: " + + ((songInfo.getDurationInSeconds() / 60 < 1) ? "00" : songInfo.getDurationInSeconds() / 60) + ":" + + ((songInfo.getDurationInSeconds() - (songInfo.getDurationInSeconds() / 60) * 60) < 10 + ? "0" + (songInfo.getDurationInSeconds() - (songInfo.getDurationInSeconds() / 60) * 60) + : (songInfo.getDurationInSeconds() - (songInfo.getDurationInSeconds() / 60) * 60))); + authorLabel.setText("Author: " + songInfo.getAuthor()); + } + public FileHandle getMusicFile() { return musicFile; } - - public AudioInfo getAudioInfo() { - return audioInfo; + + public SongInfo getAudioInfo() { + return songInfo; } - + @Override public void dispose() { - audioInfo.dispose(); + songInfo.dispose(); } - + public boolean isMusicInvalid() { - return audioInfo.isInvalidMusic(); + return songInfo.isInvalidMusic(); } + public void select() { + table.setBackground("holo-pane-down"); + selected = true; + } + + public void diselect() { + table.setBackground("holo-pane"); + selected = false; + } + + public boolean isSelected() { + return selected; + } } diff --git a/core/src/zero1hd/rhythmbullet/ui/builders/ScrollText.java b/core/src/zero1hd/rhythmbullet/ui/builders/ScrollText.java index 94fa3ea..9962575 100755 --- a/core/src/zero1hd/rhythmbullet/ui/builders/ScrollText.java +++ b/core/src/zero1hd/rhythmbullet/ui/builders/ScrollText.java @@ -24,7 +24,7 @@ public class ScrollText extends Widget { private float fontWidth; private boolean scrollOnHover; - private boolean currentlyHovering; + private boolean scroll; private float textOffset; @@ -47,13 +47,13 @@ public class ScrollText extends Widget { addListener(new ClickListener() { @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { - currentlyHovering = true; + scroll = true; super.enter(event, x, y, pointer, fromActor); } @Override public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { - currentlyHovering = false; + scroll = false; super.exit(event, x, y, pointer, toActor); } @@ -81,13 +81,13 @@ public class ScrollText extends Widget { addListener(new ClickListener() { @Override public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { - currentlyHovering = true; + scroll = true; super.enter(event, x, y, pointer, fromActor); } @Override public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { - currentlyHovering = false; + scroll = false; super.exit(event, x, y, pointer, toActor); } @@ -116,7 +116,7 @@ public class ScrollText extends Widget { public void act(float delta) { if (fontWidth > clipBounds.getWidth()) { if (scrollOnHover) { - if ((int) textOffset != 0 || currentlyHovering) { + if ((int) textOffset != 0 || scroll) { if (textOffset < -fontWidth) { textOffset = clipBounds.getWidth(); } diff --git a/core/src/zero1hd/rhythmbullet/ui/builders/Visualizer.java b/core/src/zero1hd/rhythmbullet/ui/builders/Visualizer.java deleted file mode 100755 index f04bd49..0000000 --- a/core/src/zero1hd/rhythmbullet/ui/builders/Visualizer.java +++ /dev/null @@ -1,33 +0,0 @@ -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); - } -} diff --git a/core/src/zero1hd/rhythmbullet/ui/pages/AnalyzePage.java b/core/src/zero1hd/rhythmbullet/ui/pages/AnalyzePage.java index d0f463e..09830c6 100755 --- a/core/src/zero1hd/rhythmbullet/ui/pages/AnalyzePage.java +++ b/core/src/zero1hd/rhythmbullet/ui/pages/AnalyzePage.java @@ -20,7 +20,7 @@ import com.badlogic.gdx.utils.Disposable; import zero1hd.rhythmbullet.RhythmBullet; import zero1hd.rhythmbullet.audio.AudioAnalyzer; import zero1hd.rhythmbullet.audio.CoreMusicInfo; -import zero1hd.rhythmbullet.audio.AudioInfo; +import zero1hd.rhythmbullet.audio.SongInfo; import zero1hd.rhythmbullet.audio.map.GamePlayMap; import zero1hd.rhythmbullet.audio.map.RhythmMapAlgorithm; import zero1hd.rhythmbullet.screens.GameScreen; @@ -186,7 +186,7 @@ public class AnalyzePage extends Page implements MiniListener, Disposable { addActor(back); } - public void setSong(CoreMusicInfo music, AudioInfo audioInfo, MiniListener listener) { + public void setSong(CoreMusicInfo music, SongInfo audioInfo, MiniListener listener) { confirmed = false; confirmDiffButton.setDisabled(false); sensitivityRating.setDisabled(false); diff --git a/core/src/zero1hd/rhythmbullet/ui/pages/MainPage.java b/core/src/zero1hd/rhythmbullet/ui/pages/MainPage.java index 0b0b725..3d1a501 100755 --- a/core/src/zero1hd/rhythmbullet/ui/pages/MainPage.java +++ b/core/src/zero1hd/rhythmbullet/ui/pages/MainPage.java @@ -1,7 +1,10 @@ package zero1hd.rhythmbullet.ui.pages; +import java.util.Random; + import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; @@ -14,6 +17,9 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.audio.CoreMusicInfo; +import zero1hd.rhythmbullet.audio.SongList; +import zero1hd.rhythmbullet.audio.visualizer.HorizontalVisualizer; import zero1hd.rhythmbullet.screens.PreGameScreen; public class MainPage extends Page { @@ -25,8 +31,19 @@ public class MainPage extends Page { private TextButton quit; private TextButton credits; private WidgetGroup playButton; - - public MainPage(final RhythmBullet core, final Vector3 targetPosition) { + + private HorizontalVisualizer hvisual; + private CoreMusicInfo cmi; + private SongList songList; + private Random rand; + public MainPage(RhythmBullet core, Vector3 targetPosition, SongList sl) { + hvisual = new HorizontalVisualizer(); + this.songList = sl; + rand = new Random(); + + cmi = songList.getMusicInfoFromIndex(rand.nextInt(songList.getAmountOfSongs())); + hvisual.setCmi(cmi); + title = new Image(core.getAssetManager().get("title.png", Texture.class)); title.setPosition(10, getHeight() - title.getHeight()-30); addActor(title); @@ -98,7 +115,7 @@ public class MainPage extends Page { Actions.run(new Runnable() { @Override public void run() { - core.setScreen(new PreGameScreen(core)); + core.setScreen(new PreGameScreen(core, songList)); } }), Actions.parallel(Actions.scaleTo(1, 1), Actions.alpha(0.6f)))); } @@ -109,4 +126,10 @@ public class MainPage extends Page { // end play button } + @Override + public void draw(Batch batch, float parentAlpha) { + hvisual.update(); + hvisual.render(batch, parentAlpha); + super.draw(batch, parentAlpha); + } } diff --git a/core/src/zero1hd/rhythmbullet/ui/pages/MusicSelectionPage.java b/core/src/zero1hd/rhythmbullet/ui/pages/MusicSelectionPage.java index fa3e96e..61557f1 100755 --- a/core/src/zero1hd/rhythmbullet/ui/pages/MusicSelectionPage.java +++ b/core/src/zero1hd/rhythmbullet/ui/pages/MusicSelectionPage.java @@ -1,159 +1,95 @@ package zero1hd.rhythmbullet.ui.pages; -import java.io.File; -import java.io.FilenameFilter; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.scenes.scene2d.Actor; 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.utils.ChangeListener; +import com.badlogic.gdx.utils.Array; -import zero1hd.rhythmbullet.RhythmBullet; -import zero1hd.rhythmbullet.audio.AudioInfo; +import zero1hd.rhythmbullet.audio.SongInfo; +import zero1hd.rhythmbullet.audio.SongList; import zero1hd.rhythmbullet.ui.builders.MusicSelectable; -import zero1hd.rhythmbullet.ui.windows.LoadingWindow; -import zero1hd.rhythmbullet.ui.windows.NoticeWindow; import zero1hd.rhythmbullet.util.MiniEvents; public class MusicSelectionPage extends Page { - private volatile Table musicChoices; Preferences musicFileAnnotation; - private RhythmBullet core; - private volatile ScrollPane musicChoiceScroller; - private volatile LoadingWindow loadingWindow; - protected volatile boolean cancel; + private SongList songList; + private Array selectables; + private Table songTable; + private ScrollPane scrollbar; private TextButton back; private FileHandle selectedMusic; - private AudioInfo selectedMusicInfo; + private SongInfo selectedMusicInfo; - public MusicSelectionPage(final RhythmBullet core) { - super("Select music", core.getDefaultSkin()); - this.core = core; - + private Skin skin; + private AssetManager assets; + public MusicSelectionPage(Skin skin, SongList songList, AssetManager assetManager) { + super("Select music", skin); + this.songList = songList; musicFileAnnotation = Gdx.app.getPreferences("music_file_annotation"); - - back = new TextButton("Back", core.getDefaultSkin()); + this.assets = assetManager; + songTable = new Table(skin); + scrollbar = new ScrollPane(songTable, skin); + scrollbar.setSize(0.4f*getWidth(), getHeightBelowTitle()); + addActor(scrollbar); + selectables = new Array<>(); + this.skin = skin; + 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); - cancel = true; } }); addActor(back); - loadingWindow = new LoadingWindow(core.getDefaultSkin(), "tinted", true, core.getAssetManager(), core.getPrefs().getFloat("fx vol")); - - loadingWindow.setPosition((getWidth()-loadingWindow.getWidth())/2f, (getHeight()-loadingWindow.getHeight())/2f); - addActor(loadingWindow); - loadingWindow.playOpenSound(); - loadingWindow.setMovable(false); - loadingWindow.setModal(true); - - musicChoices = new Table(); - musicChoices.defaults().pad(10f); - musicChoiceScroller = new ScrollPane(musicChoices); - musicChoiceScroller.setScrollingDisabled(false, true); - musicChoiceScroller.setSize(getWidth(), getHeight()-(getHeight()-back.getY())); - - addActor(musicChoiceScroller); - - loadingWindow.toFront(); - back.toFront(); } @Override public void act(float delta) { - back.toFront(); super.act(delta); } - public void beginMusicSearch() { - new Thread(new Runnable() { - - @Override - public void run() { - Logger.getLogger("org.jaudiotagger").setLevel(Level.SEVERE); - - FileHandle[] musicFiles = new FileHandle(core.getPrefs().getString("music dir")).list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - if (name.endsWith("mp3") || name.endsWith("wav")) { - return true; - } - return false; - } - }); - - if (musicFiles.length > 0) { - for (int music = 0; music < musicFiles.length && !cancel; music++) { - final MusicSelectable selectable = new MusicSelectable(musicFiles[music], musicFileAnnotation, core.getDefaultSkin(), core.getAssetManager().get("defaultCover.png", Texture.class)); - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - Gdx.app.debug("Music Search Thread", "Finished loading: " + selectable.getName()); - musicChoices.add(selectable).prefSize(panelWidthCalc(getWidth()), musicChoiceScroller.getHeight()); - selectable.addInfoToPanel(panelWidthCalc(getWidth()) - 20f); - - selectable.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - - if (!selectable.isMusicInvalid()) { - selectedMusic = selectable.getMusicFile(); - selectedMusicInfo = selectable.getAudioInfo(); - miniSender.send(MiniEvents.MUSIC_SELECTED); - } else { - //Play "no" sound - } - } - }); - } - }); - - Gdx.app.debug("Music Search Thread", "Completed: " + music); - int prog = (int) (100f*music/(musicFiles.length-1f)); - loadingWindow.setProgress(prog); - } - } else { - NoticeWindow notice = new NoticeWindow(core.getDefaultSkin(), "default", "No song's found in:\n\"" + core.getPrefs().getString("music dir") + "\"\nTo change the search directory, go to game options.", core.getPrefs().getFloat("fx vol"), core.getAssetManager()); - notice.setSize(0.6f*getWidth(), 0.6f*getHeight()); - notice.setPosition((getWidth()-notice.getWidth())/2f, (getHeight()-notice.getHeight())/2f); - notice.setModal(true); - notice.setMovable(false); - addActor(notice); - notice.playOpenSound(); - } - loadingWindow.remove(); - } - }).start(); - } - - public float panelWidthCalc(float origWidth) { - return (float) (Math.sqrt(getWidth()*35f)+80f); - } - public FileHandle getSelectedMusic() { return selectedMusic; } - public AudioInfo getSelectedMusicInfo() { + public SongInfo getSelectedMusicInfo() { return selectedMusicInfo; } - @Override - public synchronized void addActor(Actor actor) { - super.addActor(actor); + public void refresh() { + for (int i = 0; i < songList.getAmountOfSongs(); i++) { + MusicSelectable selectable = new MusicSelectable(songList.getSongList().get(i), musicFileAnnotation, skin, assets.get("defaultCover.png", Texture.class)); + selectables.add(selectable); + songTable.add(selectable); + songTable.row(); + } + + ExecutorService exec = Executors.newSingleThreadExecutor(); + exec.submit(() -> { + for (int i = 0; i < selectables.size; i++) { + MusicSelectable info = selectables.get(i); + info.getAudioInfo().loadInfo(); + info.getAudioInfo().doesContainsInformation(); + Gdx.app.postRunnable(() -> { + info.updateInfo(); + }); + } + }); } } diff --git a/core/src/zero1hd/rhythmbullet/ui/pages/OptionsPage.java b/core/src/zero1hd/rhythmbullet/ui/pages/OptionsPage.java index a65700d..9e31f3d 100755 --- a/core/src/zero1hd/rhythmbullet/ui/pages/OptionsPage.java +++ b/core/src/zero1hd/rhythmbullet/ui/pages/OptionsPage.java @@ -17,6 +17,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextField; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.audio.SongList; import zero1hd.rhythmbullet.screens.CreativeScreen; import zero1hd.rhythmbullet.screens.MainMenu; @@ -26,7 +27,7 @@ public class OptionsPage extends Page { private ProgressBar fxVolSlider; private TextField directoryField; - public OptionsPage(final RhythmBullet core, final Vector3 targetPosition, final MoreOptionsPage moreOptionsPage) { + public OptionsPage(final RhythmBullet core, final Vector3 targetPosition, final MoreOptionsPage moreOptionsPage, SongList sl) { optionsTable.defaults().spaceLeft(40f).padTop(5f).padBottom(5f).left(); Label optionGeneralTitle = new Label("General", core.getDefaultSkin(), "large-font", core.getDefaultSkin().getColor("default")); @@ -128,7 +129,7 @@ public class OptionsPage extends Page { 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())); + core.setScreen(new CreativeScreen(core, (MainMenu) core.getScreen(), sl)); } } return super.keyUp(event, keycode); diff --git a/core/src/zero1hd/rhythmbullet/ui/windows/MusicSelector.java b/core/src/zero1hd/rhythmbullet/ui/windows/MusicSelector.java index a512178..e18c080 100755 --- a/core/src/zero1hd/rhythmbullet/ui/windows/MusicSelector.java +++ b/core/src/zero1hd/rhythmbullet/ui/windows/MusicSelector.java @@ -11,8 +11,8 @@ import com.badlogic.gdx.scenes.scene2d.ui.Window; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.utils.Array; -import zero1hd.rhythmbullet.audio.Audio; import zero1hd.rhythmbullet.audio.CoreMusicInfo; +import zero1hd.rhythmbullet.audio.SongList; import zero1hd.rhythmbullet.util.MiniEvents; import zero1hd.rhythmbullet.util.MiniSender; @@ -22,23 +22,23 @@ public class MusicSelector extends Window { FileHandle selectedMusic; Array fileNames; private List musicList; - private String path; private ScrollPane listScroller; + private SongList songList; public MiniSender miniSender; - public MusicSelector(String title, Skin skin, final String path, String listStyle) { + public MusicSelector(String title, Skin skin, final String path, SongList songList) { super(title, skin, "tinted"); - this.path = path; padTop(25f); padLeft(5f); padRight(5f); + this.songList = songList; miniSender = new MiniSender(); setSize(Gdx.graphics.getWidth()*0.5f, Gdx.graphics.getHeight()*0.5f); fileNames = new Array<>(); - musicList = new List(skin, listStyle); + musicList = new List(skin, "default"); TextButton confirmButton = new TextButton("confirm", skin, "window"); confirmButton.addListener(new ChangeListener() { @@ -71,15 +71,8 @@ public class MusicSelector extends Window { } public void refresh() { - fileNames.clear(); - FileHandle[] musicListArray = Gdx.files.absolute(path).list(); - for (int i = 0; i < musicListArray.length; i++) { - if (musicListArray[i].name().toLowerCase().endsWith(".wav") || musicListArray[i].name().toLowerCase().endsWith(".mp3")) { - fileNames.add(musicListArray[i].name()); - } - } - fileNames.sort(); - musicList.setItems(fileNames); + songList.refresh(); + musicList.setItems(songList.getSongList()); } @@ -97,7 +90,7 @@ public class MusicSelector extends Window { public CoreMusicInfo getSelectedMusic() { if (selectedMusic != null) { - return Audio.getAudioData(selectedMusic); + return songList.getAudioData(selectedMusic); } else { return null; }