main menu now displays current song name; visualizer made slightly more efficient

This commit is contained in:
Harrison Deng 2017-10-15 01:55:03 -05:00
parent f345e1de8c
commit 160f87b801
15 changed files with 174 additions and 82 deletions

View File

@ -386,3 +386,11 @@ rect-disabled
orig: 14, 14 orig: 14, 14
offset: 0, 0 offset: 0, 0
index: -1 index: -1
side-bars
rotate: false
xy: 221, 35
size: 5, 14
split: 2, 2, 0, 0
orig: 5, 14
offset: 0, 0
index: -1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -47,9 +47,10 @@ public class Mp3Manager implements MusicManager {
private ExecutorService exec; private ExecutorService exec;
private String basicSongName;
public Mp3Manager(FileHandle audioFile) { public Mp3Manager(FileHandle audioFile) {
lock = new ReentrantLock(); lock = new ReentrantLock();
this.basicSongName = audioFile.name();
exec = Executors.newSingleThreadExecutor(); exec = Executors.newSingleThreadExecutor();
exec.submit(() -> { exec.submit(() -> {
lock.lock(); lock.lock();
@ -230,11 +231,23 @@ public class Mp3Manager implements MusicManager {
@Override @Override
public boolean isFinishedLoading() { public boolean isFinishedLoading() {
if (lock.isHeldByCurrentThread()) {
return true;
} else {
try { try {
return lock.tryLock(0, TimeUnit.SECONDS); if (lock.tryLock(0, TimeUnit.SECONDS)) {
return true;
} else {
return false;
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace();
return false; return false;
} }
} }
} }
@Override
public String getBasicSongName() {
return basicSongName;
}
}

View File

@ -74,4 +74,11 @@ public interface MusicManager extends Disposable {
* @return whether its done loading * @return whether its done loading
*/ */
public boolean isFinishedLoading(); public boolean isFinishedLoading();
/**
* Basic song name is the name of the file of the song, meaning we do not check tags for proper song name.
* Thats left up to the song info object.
* @return basic song name
*/
public String getBasicSongName();
} }

View File

@ -32,12 +32,15 @@ public class SongInfo implements Disposable {
private FileHandle musicFile; private FileHandle musicFile;
private Preferences musicAnnotation; private Preferences musicAnnotation;
public SongInfo(FileHandle musicFile, Preferences musicData) { public SongInfo(FileHandle musicFile, Preferences musicData) {
this.musicFile = musicFile; this.musicFile = musicFile;
this.musicAnnotation = musicData; this.musicAnnotation = musicData;
} }
/**
* loads the information for this song.
* should be called in non-render thread as is blocking and depends on IO speed.
*/
public void loadInfo() { public void loadInfo() {
if (musicFile.extension().toLowerCase().equals("mp3")) { if (musicFile.extension().toLowerCase().equals("mp3")) {
MP3File mp3File; MP3File mp3File;

View File

@ -30,8 +30,8 @@ public class SongListController implements OnCompletionListener {
this.prefs = prefs; this.prefs = prefs;
listeners = new Array<>(); listeners = new Array<>();
this.songList = songList; this.songList = songList;
changeSong();
rand = new Random(); rand = new Random();
changeSong();
} }
public void play() { public void play() {
@ -105,7 +105,11 @@ public class SongListController implements OnCompletionListener {
} }
if (shuffle) { if (shuffle) {
if (songList.getAmountOfSongs() == 0) {
currentPlaybackID = 0;
} else {
currentPlaybackID = rand.nextInt(songList.getAmountOfSongs()); currentPlaybackID = rand.nextInt(songList.getAmountOfSongs());
}
} else { } else {
if (currentPlaybackID > songList.getAmountOfSongs() -1) { if (currentPlaybackID > songList.getAmountOfSongs() -1) {
currentPlaybackID = 0; currentPlaybackID = 0;

View File

@ -20,7 +20,9 @@ public class WAVManager implements MusicManager {
private Music playbackMusic; private Music playbackMusic;
WavDecoder decoder; WavDecoder decoder;
private String basicSongName;
public WAVManager(FileHandle file) { public WAVManager(FileHandle file) {
basicSongName = file.name();
try { try {
decoder = new WavDecoder(file); decoder = new WavDecoder(file);
} catch (InvalidParameterException | IOException e) { } catch (InvalidParameterException | IOException e) {
@ -127,4 +129,9 @@ public class WAVManager implements MusicManager {
public boolean isFinishedLoading() { public boolean isFinishedLoading() {
return true; return true;
} }
@Override
public String getBasicSongName() {
return basicSongName;
}
} }

View File

@ -29,13 +29,15 @@ public class VisualizerCore implements Disposable {
public void calculate() { public void calculate() {
if (mm != null) { if (mm != null) {
mm.playbackIndexUpdate(); mm.playbackIndexUpdate();
while (calc && mm.isPlaying() && mm.getPlaybackIndexPosition() > mm.getCurrentReadWindowIndex()) {
lock.lock(); lock.lock();
while (calc && mm.isPlaying() && mm.getPlaybackIndexPosition() > mm.getCurrentReadWindowIndex()) {
mm.readSamples(audioPCM); mm.readSamples(audioPCM);
if (mm.getPlaybackIndexPosition() == mm.getCurrentReadWindowIndex()) {
fft.realForward(audioPCM); fft.realForward(audioPCM);
lock.unlock();
} }
} }
lock.unlock();
}
} }
public void setMM(MusicManager mm) { public void setMM(MusicManager mm) {
@ -90,4 +92,7 @@ public class VisualizerCore implements Disposable {
return height; return height;
} }
public MusicManager getMm() {
return mm;
}
} }

View File

@ -98,6 +98,7 @@ public class MusicControls extends HorizontalGroup {
if (disableTimer <= 0) { if (disableTimer <= 0) {
forward.setDisabled(false); forward.setDisabled(false);
reverse.setDisabled(false); reverse.setDisabled(false);
disableTimer = 0;
} }
} }
super.act(delta); super.act(delta);

View File

@ -41,7 +41,7 @@ public class MusicSelectable extends Widget implements Disposable {
imageIcon = new Image(albumCover); imageIcon = new Image(albumCover);
table.add(imageIcon); table.add(imageIcon);
displayName = new ScrollText(musicFile.name(), skin, true); displayName = new ScrollText(musicFile.name(), null, skin, true, false);
table.add(displayName); table.add(displayName);
table.row(); table.row();
@ -54,6 +54,10 @@ public class MusicSelectable extends Widget implements Disposable {
table.defaults().pad(10f); table.defaults().pad(10f);
} }
/**
* updates the UI side of information.
* needs to be called in thread with gl context.
*/
public void updateInfo() { public void updateInfo() {
durationLabel.setText("Runtime: " durationLabel.setText("Runtime: "
+ ((songInfo.getDurationInSeconds() / 60 < 1) ? "00" : songInfo.getDurationInSeconds() / 60) + ":" + ((songInfo.getDurationInSeconds() / 60 < 1) ? "00" : songInfo.getDurationInSeconds() / 60) + ":"

View File

@ -1,9 +1,11 @@
package zero1hd.rhythmbullet.graphics.ui.components; package zero1hd.rhythmbullet.graphics.ui.components;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Actor;
@ -18,63 +20,46 @@ public class ScrollText extends Widget {
Rectangle clipBounds = new Rectangle(); Rectangle clipBounds = new Rectangle();
GlyphLayout gLayout; GlyphLayout gLayout;
String text; String text1;
String text2;
BitmapFont font; BitmapFont font;
private float fontHeight; private float textHeight;
private float fontWidth; private float text1Width;
private float text2Width;
private boolean scrollOnHover; private boolean scrollOnHover;
private boolean scroll; private boolean scroll;
private float textOffset; private float text1Offset, text2Offset;
private NinePatch background;
private Vector2 coords; private Vector2 coords;
public ScrollText(String text, Skin skin, boolean scrollOnHover) { public ScrollText(String text, String text2, Skin skin, boolean scrollOnHover, boolean useBackground) {
super(); super();
setName(text);
this.scrollOnHover = scrollOnHover;
this.text = text;
font = skin.getFont("default-font"); font = skin.getFont("default-font");
font.setColor(skin.getColor("default")); init(text, text2, skin, scrollOnHover, useBackground);
gLayout = new GlyphLayout(font, text);
fontHeight = gLayout.height;
fontWidth = gLayout.width;
coords = new Vector2();
addListener(new ClickListener() {
@Override
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
scroll = true;
super.enter(event, x, y, pointer, fromActor);
} }
@Override public ScrollText(String text, String text2, Skin skin, String fontName, Color color, boolean scrollOnHover, boolean useBackground) {
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
scroll = false;
super.exit(event, x, y, pointer, toActor);
}
@Override
public void clicked(InputEvent event, float x, float y) {
}
});
}
public ScrollText(String text, Skin skin, String fontName, Color color, boolean scrollOnHover) {
super(); super();
setName(text);
this.scrollOnHover = scrollOnHover;
this.text = text;
font = skin.getFont(fontName); font = skin.getFont(fontName);
font.setColor(color); font.setColor(color);
gLayout = new GlyphLayout(font, text); init(text, text2, skin, scrollOnHover, useBackground);
}
fontHeight = gLayout.height; private void init(String text1, String text2, Skin skin, boolean scrollOnHover, boolean useBackground) {
fontWidth = gLayout.width; setName(text1);
if (useBackground) {
this.background = skin.getPatch("side-bars");
}
this.scrollOnHover = scrollOnHover;
if (text1 == null) {
text1 = "";
}
setText(text1, text2);
coords = new Vector2(); coords = new Vector2();
@ -98,55 +83,74 @@ public class ScrollText extends Widget {
} }
public float getFontHeight() { public float getFontHeight() {
return fontHeight; return textHeight;
} }
public float getFontWidth() { public float getFontWidth() {
return fontWidth; return text1Width;
} }
@Override @Override
public void layout() { public void layout() {
setHeight(fontHeight+4); if (getHeight() < (textHeight+4)) {
clipBounds.setSize(getWidth(), getHeight()*1.5f); setHeight(textHeight + 4);
}
clipBounds.setSize(getWidth()-1, getHeight()*1.5f);
super.layout(); super.layout();
} }
@Override @Override
public void act(float delta) { public void act(float delta) {
if (fontWidth > clipBounds.getWidth()) { validate();
if (text1Width + text2Width > clipBounds.getWidth()) {
if (scrollOnHover) { if (scrollOnHover) {
if ((int) textOffset != 0 || scroll) { if (scroll) {
if (textOffset < -fontWidth) { scroll(delta);
textOffset = clipBounds.getWidth();
}
textOffset -= 60*delta;
} }
} else { } else {
if (textOffset < -fontWidth) { scroll(delta);
textOffset = clipBounds.getWidth();
}
textOffset -= 60*delta;
} }
} }
super.act(delta); super.act(delta);
} }
public void scroll(float delta) {
if (text1Offset >= -text1Width) {
text1Offset -= 60*delta;
if ((text1Offset < - Math.abs((text1Width - clipBounds.getWidth())) - 50) || text2Offset != clipBounds.getWidth()) {
text2Offset -= 60*delta;
if (text2Offset <= -text2Width) {
text2Offset = clipBounds.getWidth();
}
}
} else {
text2Offset -= 60*delta;
if (text2Offset < - Math.abs((text2Width - clipBounds.getWidth())) - 50) {
text1Offset = clipBounds.getWidth();
}
}
}
@Override @Override
public void draw(Batch batch, float parentAlpha) { public void draw(Batch batch, float parentAlpha) {
if (background != null) {
background.draw(batch, getX(), getY(), getWidth(), getHeight());
}
coords.x = getX(); coords.x = getX();
coords.y = getY(); coords.y = getY();
clipBounds.setX(coords.x); clipBounds.setX(coords.x+1);
clipBounds.setY(coords.y - 0.5f*getHeight()); clipBounds.setY(coords.y - 0.5f*getHeight());
getStage().calculateScissors(clipBounds, scissors); getStage().calculateScissors(clipBounds, scissors);
batch.flush(); batch.flush();
if (ScissorStack.pushScissors(scissors)) { if (ScissorStack.pushScissors(scissors)) {
font.draw(batch, text, coords.x + textOffset, coords.y + getFontHeight()); font.draw(batch, text1, coords.x + text1Offset, coords.y + getFontHeight() + getHeight()/4f);
font.draw(batch, text2, coords.x + text2Offset, coords.y + getFontHeight() + getHeight()/4f);
batch.flush(); batch.flush();
ScissorStack.popScissors(); ScissorStack.popScissors();
}; };
@ -154,6 +158,30 @@ public class ScrollText extends Widget {
@Override @Override
public float getMinHeight() { public float getMinHeight() {
return fontHeight; return textHeight;
}
/**
* Sets the two strings that will be scrolling.
* @param text1 cannot be null.
* @param text2 can be null.
*/
public void setText(String text1, String text2) {
this.text1 = text1;
gLayout = new GlyphLayout(font, text1);
text1Width = gLayout.width;
textHeight = gLayout.height;
text2Offset = clipBounds.getWidth();
if (text1Width < clipBounds.getWidth()) {
text1Offset = (clipBounds.getWidth()-text1Width)/2f;
}
if (text2 != null) {
this.text2 = text2;
gLayout = new GlyphLayout(font, text2);
text2Width = gLayout.width;
} else {
this.text2 = text1;
this.text2Width = text1Width;
}
} }
} }

View File

@ -85,11 +85,10 @@ public class TitleBarVisualizer extends Group implements Disposable {
@Override @Override
public void act(float delta) { public void act(float delta) {
if (!lastEffect) { if (!lastEffect) {
if (visual.getVis().getCurrentAvg() > visual.getVis().getMaxAvgHeight()*0.55f) { if (visual.getVis().getMm() != null && visual.getVis().getMm().isPlaying() && visual.getVis().getCurrentAvg() > visual.getVis().getMaxAvgHeight()*0.55f) {
PooledEffect effect = beatEffectPool.obtain(); PooledEffect effect = beatEffectPool.obtain();
effect.setPosition(0, 0); effect.setPosition(0, 0);
effects.add(effect); effects.add(effect);
lastEffect = true; lastEffect = true;
} }
} else { } else {

View File

@ -70,8 +70,6 @@ public class Visualizer extends Widget {
} }
public void setUpdatePositioning(boolean updatePositioning) { public void setUpdatePositioning(boolean updatePositioning) {
updateVisualPosition();
vis.setxPos(((vis.getWidth() - vis.getActualWidth())/2f));
updateVisualPosition(); updateVisualPosition();
this.updatePositioning = updatePositioning; this.updatePositioning = updatePositioning;
} }
@ -79,6 +77,9 @@ public class Visualizer extends Widget {
public void updateVisualPosition() { public void updateVisualPosition() {
setVisualizerPosProp(); setVisualizerPosProp();
vis.updatePositionInfo(); vis.updatePositionInfo();
vis.setxPos(((vis.getWidth() - vis.getActualWidth())/2f));
Gdx.app.debug("Visualizer", "currently offseting visualizer by (px): " + vis.getxPos());
vis.updatePositionInfo();
} }
public boolean isUpdatePositioning() { public boolean isUpdatePositioning() {

View File

@ -201,7 +201,7 @@ public class AnalyzePage extends Page implements MiniListener, Disposable {
audioAnalyzer.sender.addListener(this); audioAnalyzer.sender.addListener(this);
songInfo.add(new ScrollText(audioInfo.getSongName(), skin, true)).expandX().fillX().spaceBottom(20f); songInfo.add(new ScrollText(audioInfo.getSongName(), null, skin, true, false)).expandX().fillX().spaceBottom(20f);
for (int i = 0; i < info.length; i++) { for (int i = 0; i < info.length; i++) {
info[i].setColor(1f, 1f, 1f, 0f); info[i].setColor(1f, 1f, 1f, 0f);

View File

@ -15,6 +15,7 @@ import zero1hd.rhythmbullet.audio.MusicManager;
import zero1hd.rhythmbullet.audio.SongListController; import zero1hd.rhythmbullet.audio.SongListController;
import zero1hd.rhythmbullet.events.OnDifferentSongListener; import zero1hd.rhythmbullet.events.OnDifferentSongListener;
import zero1hd.rhythmbullet.graphics.ui.components.MusicControls; import zero1hd.rhythmbullet.graphics.ui.components.MusicControls;
import zero1hd.rhythmbullet.graphics.ui.components.ScrollText;
import zero1hd.rhythmbullet.graphics.ui.components.TitleBarVisualizer; import zero1hd.rhythmbullet.graphics.ui.components.TitleBarVisualizer;
public class MainPage extends Page implements OnDifferentSongListener { public class MainPage extends Page implements OnDifferentSongListener {
@ -28,13 +29,13 @@ public class MainPage extends Page implements OnDifferentSongListener {
private TextButton quitButton; private TextButton quitButton;
private MusicControls musicControls; private MusicControls musicControls;
private ScrollText scrollText;
public MainPage(RhythmBullet core, Vector3 targetPosition, SongListController sc) { public MainPage(RhythmBullet core, Vector3 targetPosition, SongListController sc) {
this.sc = sc; this.sc = sc;
titleBar = new TitleBarVisualizer(core.getAssetManager()); titleBar = new TitleBarVisualizer(core.getAssetManager());
addActor(titleBar); addActor(titleBar);
titleBar.getHvisual().setMM(sc.getCurrentSong());
sc.addOnDifferentSongListener(this); sc.addOnDifferentSongListener(this);
versionLabel = new Label("Version: " + RhythmBullet.VERSION, core.getDefaultSkin(), "sub-font", versionLabel = new Label("Version: " + RhythmBullet.VERSION, core.getDefaultSkin(), "sub-font",
@ -81,7 +82,17 @@ public class MainPage extends Page implements OnDifferentSongListener {
musicControls = new MusicControls(core.getDefaultSkin(), sc); musicControls = new MusicControls(core.getDefaultSkin(), sc);
musicControls.setPosition((getWidth()-musicControls.getMinWidth() - 20f), getHeight()-musicControls.getMinHeight()); musicControls.setPosition((getWidth()-musicControls.getMinWidth() - 20f), getHeight()-musicControls.getMinHeight());
musicControls.invalidate();
addActor(musicControls); addActor(musicControls);
scrollText = new ScrollText("...", "...", core.getDefaultSkin(), false, true);
scrollText.setWidth(0.5f*getWidth());
scrollText.setHeight(musicControls.getMinHeight());
scrollText.setPosition((getWidth() - scrollText.getWidth())/2f, musicControls.getY() - 22f);
scrollText.invalidate();
addActor(scrollText);
onDifferentSong(sc.getCurrentSong());
} }
@Override @Override
@ -97,6 +108,7 @@ public class MainPage extends Page implements OnDifferentSongListener {
@Override @Override
public void onDifferentSong(MusicManager mdp) { public void onDifferentSong(MusicManager mdp) {
titleBar.getHvisual().setMM(mdp); titleBar.getHvisual().setMM(mdp);
scrollText.setText(mdp.getBasicSongName(), null);
} }
@Override @Override