refactor; visualizer tuning; main menu updates to use metadata once

loaded;
This commit is contained in:
Harrison Deng 2018-08-23 23:51:33 -05:00
parent b97d772ee9
commit a6dc7c2559
10 changed files with 62 additions and 33 deletions

View File

@ -1,5 +1,6 @@
package zero1hd.rhythmbullet.audio; package zero1hd.rhythmbullet.audio;
import java.util.Comparator;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
@ -7,22 +8,30 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.Sort;
import zero1hd.rhythmbullet.audio.metadata.AudioMetadata; import zero1hd.rhythmbullet.audio.metadata.AudioMetadata;
import zero1hd.rhythmbullet.audio.metadata.MP3Metadata; import zero1hd.rhythmbullet.audio.metadata.MP3Metadata;
import zero1hd.rhythmbullet.audio.metadata.WAVMetadata; import zero1hd.rhythmbullet.audio.metadata.WAVMetadata;
public class MusicMetadataController extends Observable implements Disposable, Observer { public class AudioMetadataController extends Observable implements Disposable, Observer {
private MusicList musicList; private MusicList musicList;
private Array<AudioMetadata> metadataArray; private Array<AudioMetadata> metadataArray;
private MetadataLoadingThread loadingThread; private MetadataLoadingThread loadingThread;
private volatile boolean searching; private volatile boolean searching;
private Comparator<AudioMetadata> metadataComparer;
public MusicMetadataController(MusicList musicList) { public AudioMetadataController(MusicList musicList) {
this.musicList = musicList; this.musicList = musicList;
metadataArray = new Array<>(); metadataArray = new Array<>();
loadingThread = new MetadataLoadingThread(); loadingThread = new MetadataLoadingThread();
musicList.addObserver(this); musicList.addObserver(this);
metadataComparer = new Comparator<AudioMetadata>() {
@Override
public int compare(AudioMetadata o1, AudioMetadata o2) {
return o1.getTitle().compareToIgnoreCase(o2.getTitle());
}
};
} }
public MusicList getMusicList() { public MusicList getMusicList() {
@ -44,7 +53,7 @@ public class MusicMetadataController extends Observable implements Disposable, O
* if there is the same amount of metadata as there is music in the music list. * if there is the same amount of metadata as there is music in the music list.
* @return whether or not both sizes are equal. * @return whether or not both sizes are equal.
*/ */
public boolean isDone() { public boolean isSameSizeMusicList() {
return (metadataArray.size == musicList.getMusicArray().size); return (metadataArray.size == musicList.getMusicArray().size);
} }
@ -59,13 +68,18 @@ public class MusicMetadataController extends Observable implements Disposable, O
return metadataArray.size; return metadataArray.size;
} }
public AudioMetadata getMetadata(int index) { public AudioMetadata getAudioMetadata(int index) {
return metadataArray.get(index); return metadataArray.get(index);
} }
public AudioMetadata getInfo(FileHandle filehandle) { public AudioMetadata getAudioMetadata(FileHandle filehandle) {
return metadataArray.get(musicList.getMusicArray().indexOf(filehandle, true)); for (int i = 0; i < metadataArray.size; i++) {
if (metadataArray.get(i).getFileHandle() == filehandle) {
return metadataArray.get(i);
}
}
return null;
} }
public boolean isSearching() { public boolean isSearching() {
@ -97,6 +111,8 @@ public class MusicMetadataController extends Observable implements Disposable, O
} }
} }
Sort.instance().sort(tempMetadataArray, metadataComparer);
if (work) { if (work) {
metadataArray = tempMetadataArray; metadataArray = tempMetadataArray;
searching = false; searching = false;
@ -123,7 +139,7 @@ public class MusicMetadataController extends Observable implements Disposable, O
@Override @Override
public void update(Observable o, Object arg) { public void update(Observable o, Object arg) {
if (o == musicList) { if (o == musicList && arg == musicList.states.COMPLETE) {
loadAudioMetadata(); loadAudioMetadata();
} }
} }

View File

@ -25,7 +25,7 @@ public class MusicController extends Observable implements OnCompletionListener,
public final States states = new States(); public final States states = new States();
private MusicList musicList; private MusicList musicList;
private MinimalAudioHeader musicHeader; private MinimalAudioHeader musicHeader;
private Music music; private volatile Music music;
private int currentlyPlayingIndex; private int currentlyPlayingIndex;
private boolean autoPlay; private boolean autoPlay;
private boolean shuffle; private boolean shuffle;
@ -153,7 +153,6 @@ public class MusicController extends Observable implements OnCompletionListener,
musicHeader = null; musicHeader = null;
if (music != null) { if (music != null) {
music.dispose(); music.dispose();
music = null;
} }
if (currentlyPlayingIndex < 0) { if (currentlyPlayingIndex < 0) {
currentlyPlayingIndex = musicList.getTotal()-1; currentlyPlayingIndex = musicList.getTotal()-1;

View File

@ -29,7 +29,7 @@ public interface AudioMetadata extends Disposable {
/** /**
* *
* @return the title of the song in the metadata. * @return the title of the song in the metadata, or if it doesn't exist, the filename without extension and _ is given.
*/ */
public String getTitle(); public String getTitle();

View File

@ -51,7 +51,7 @@ public class MP3Metadata implements AudioMetadata {
genre = tag.getFirst(ID3v23FieldKey.GENRE); genre = tag.getFirst(ID3v23FieldKey.GENRE);
title = tag.getFirst(ID3v23FieldKey.TITLE); title = tag.getFirst(ID3v23FieldKey.TITLE);
if (title.isEmpty()) { if (title.isEmpty()) {
title = fileHandle.nameWithoutExtension(); title = fileHandle.nameWithoutExtension().replace('_', ' ');
} }
} catch (IOException | CannotWriteException | CannotReadException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { } catch (IOException | CannotWriteException | CannotReadException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
Gdx.app.error("MP3Metadata", "Failed to read metadata of file: " + fileHandle.name()); Gdx.app.error("MP3Metadata", "Failed to read metadata of file: " + fileHandle.name());

View File

@ -40,7 +40,7 @@ public class WAVMetadata implements AudioMetadata {
author = tag.getFirst(FieldKey.ARTIST); author = tag.getFirst(FieldKey.ARTIST);
genre = tag.getFirst(FieldKey.GENRE); genre = tag.getFirst(FieldKey.GENRE);
if (title.isEmpty()) { if (title.isEmpty()) {
title = fileHandle.nameWithoutExtension(); title = fileHandle.nameWithoutExtension().replace('_', ' ');
} }
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
Gdx.app.error("WAVMetadata", "Failed to read metadata of file: " + fileHandle.name()); Gdx.app.error("WAVMetadata", "Failed to read metadata of file: " + fileHandle.name());

View File

@ -25,7 +25,7 @@ public class DoubleHorizontalVisualizer implements Disposable {
private float spacePercentage = 0.7f; private float spacePercentage = 0.7f;
private float baseSensitivity = 0.009f; private float baseSensitivity = 0.009f;
private int barCount = 120; private int barCount = 120;
private float barChangeRate = 7f; private float barChangeRate = 6.5f;
private int smoothRange = 2; private int smoothRange = 2;
private int binsToInclude = 120; private int binsToInclude = 120;
private Color color = new Color(0.5f, 0.6f, 0.8f, 0.46f); private Color color = new Color(0.5f, 0.6f, 0.8f, 0.46f);
@ -81,13 +81,13 @@ public class DoubleHorizontalVisualizer implements Disposable {
pixelsMoved = MathUtils.floor(difference*targetDelta*barChangeRate); pixelsMoved = MathUtils.floor(difference*targetDelta*barChangeRate);
if (pixelsMoved >= 0) { if (pixelsMoved >= 0) {
if (barHeights[bar] + pixelsMoved > amplitudes[bar]) { if (barHeights[bar] + pixelsMoved > amplitudes[bar]) {
barHeights[bar] += MathUtils.round(difference*targetDelta); barHeights[bar] = (int) amplitudes[bar];
} else { } else {
barHeights[bar] += pixelsMoved; barHeights[bar] += pixelsMoved;
} }
} else { } else {
if (barHeights[bar] + pixelsMoved < amplitudes[bar]) { if (barHeights[bar] + pixelsMoved < amplitudes[bar]) {
barHeights[bar] += MathUtils.round(difference*targetDelta); barHeights[bar] = (int) amplitudes[bar];
} else { } else {
barHeights[bar] += pixelsMoved; barHeights[bar] += pixelsMoved;
} }

View File

@ -104,12 +104,12 @@ public class BloomShader implements Disposable {
for (int i = 0; i <= bloomLevel; i++) { for (int i = 0; i <= bloomLevel; i++) {
// Horizontal gaussian blur // Horizontal gaussian blur
hBlur.begin();
if (i > 0) { if (i > 0) {
fboRegion.setTexture(vBlur.getColorBufferTexture()); fboRegion.setTexture(vBlur.getColorBufferTexture());
} else { } else {
fboRegion.setTexture(lightFilterBuffer.getColorBufferTexture()); fboRegion.setTexture(lightFilterBuffer.getColorBufferTexture());
} }
hBlur.begin();
screenBatch.setShader(gaussianBlurShader); screenBatch.setShader(gaussianBlurShader);
gaussianBlurShader.setUniformi("horizontal", 1); gaussianBlurShader.setUniformi("horizontal", 1);
screenBatch.draw(fboRegion, 0f, 0f, width, height); screenBatch.draw(fboRegion, 0f, 0f, width, height);
@ -139,6 +139,10 @@ public class BloomShader implements Disposable {
this.bloomLevel = bloomLevel; this.bloomLevel = bloomLevel;
} }
public int getBloomLevel() {
return bloomLevel;
}
@Override @Override
public void dispose() { public void dispose() {
brightFilterShader.dispose(); brightFilterShader.dispose();

View File

@ -18,6 +18,7 @@ import com.badlogic.gdx.utils.Align;
import zero1hd.rhythmbullet.RhythmBullet; import zero1hd.rhythmbullet.RhythmBullet;
import zero1hd.rhythmbullet.audio.MusicController; import zero1hd.rhythmbullet.audio.MusicController;
import zero1hd.rhythmbullet.audio.AudioMetadataController;
import zero1hd.rhythmbullet.audio.visualizer.DoubleHorizontalVisualizer; import zero1hd.rhythmbullet.audio.visualizer.DoubleHorizontalVisualizer;
import zero1hd.rhythmbullet.desktop.audio.PCMObtainer; import zero1hd.rhythmbullet.desktop.audio.PCMObtainer;
import zero1hd.rhythmbullet.graphics.ui.Page; import zero1hd.rhythmbullet.graphics.ui.Page;
@ -27,6 +28,7 @@ import zero1hd.rhythmbullet.util.ScreenConfiguration;
public class MainPage extends Page implements Observer { public class MainPage extends Page implements Observer {
private MusicController mc; private MusicController mc;
private AudioMetadataController mmc;
private Label versionLabel; private Label versionLabel;
private Image title; private Image title;
@ -41,10 +43,12 @@ public class MainPage extends Page implements Observer {
private DoubleHorizontalVisualizer dhv; private DoubleHorizontalVisualizer dhv;
public MainPage(MusicController musicController, AssetManager assetManager, Skin skin, ScreenConfiguration screenConfiguration, ChangeListener playButtonListener, ChangeListener optionsButtonListener) { public MainPage(MusicController musicController, AudioMetadataController mmc, AssetManager assetManager, Skin skin, ScreenConfiguration screenConfiguration, ChangeListener playButtonListener, ChangeListener optionsButtonListener) {
super(0, 0); super(0, 0);
this.mc = musicController; this.mc = musicController;
this.mc.addObserver(this); this.mc.addObserver(this);
this.mmc = mmc;
this.mmc.addObserver(this);
dhv = new DoubleHorizontalVisualizer((int) getWidth(), (int) 0, getHeight(), 0, screenConfiguration.getTargetFramesPerSecond(), mc, new PCMObtainer(mc)); dhv = new DoubleHorizontalVisualizer((int) getWidth(), (int) 0, getHeight(), 0, screenConfiguration.getTargetFramesPerSecond(), mc, new PCMObtainer(mc));
dhv.setPosition(0, (int) ((getHeight() - dhv.getHeight())/2f)); dhv.setPosition(0, (int) ((getHeight() - dhv.getHeight())/2f));
@ -118,7 +122,13 @@ public class MainPage extends Page implements Observer {
@Override @Override
public void update(Observable o, Object arg) { public void update(Observable o, Object arg) {
if (o == mc) { if (o == mc) {
scrollText.setText("Currently playing: " + mc.getCurrentSongName(), null); if (mmc.isSameSizeMusicList()) {
scrollText.setText("Currently playing: " + mmc.getAudioMetadata(mc.getCurrentMusicFileHandle()).getTitle(), null);
} else {
scrollText.setText("Currently playing: " + mc.getCurrentMusicFileHandle().nameWithoutExtension().replace('_', ' '), null);
}
} else if (o == mmc) {
scrollText.setText("Currently playing: " + mmc.getAudioMetadata(mc.getCurrentMusicFileHandle()).getTitle(), null);
} }
} }
} }

View File

@ -13,7 +13,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.badlogic.gdx.utils.viewport.ScreenViewport;
import zero1hd.rhythmbullet.RhythmBullet; import zero1hd.rhythmbullet.RhythmBullet;
import zero1hd.rhythmbullet.audio.MusicMetadataController; import zero1hd.rhythmbullet.audio.AudioMetadataController;
import zero1hd.rhythmbullet.audio.MusicList; import zero1hd.rhythmbullet.audio.MusicList;
import zero1hd.rhythmbullet.audio.MusicController; import zero1hd.rhythmbullet.audio.MusicController;
import zero1hd.rhythmbullet.desktop.audio.processor.DesktopAudioProcessorFactory; import zero1hd.rhythmbullet.desktop.audio.processor.DesktopAudioProcessorFactory;
@ -37,7 +37,7 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
private AnalysisPage analysisPage; private AnalysisPage analysisPage;
private MusicController musicController; private MusicController musicController;
private MusicMetadataController musicMetadataController; private AudioMetadataController musicMetadataController;
private RhythmBullet rhythmBullet; private RhythmBullet rhythmBullet;
@ -49,6 +49,7 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
private Batch screenBatch; private Batch screenBatch;
private float targetDelta;
public MainScreen(RhythmBullet core) { public MainScreen(RhythmBullet core) {
this.rhythmBullet = core; this.rhythmBullet = core;
stage = new Stage(new ScreenViewport()); stage = new Stage(new ScreenViewport());
@ -58,10 +59,11 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
musicController = new MusicController(musicList, core.getPreferences()); musicController = new MusicController(musicList, core.getPreferences());
musicController.setAutoPlay(true); musicController.setAutoPlay(true);
musicController.setShuffle(true); musicController.setShuffle(true);
musicMetadataController = new MusicMetadataController(musicList); musicMetadataController = new AudioMetadataController(musicList);
listeners = new Listeners(); listeners = new Listeners();
screenBatch = new SpriteBatch(); screenBatch = new SpriteBatch();
targetDelta = 1f/core.getScreenConfiguration().getTargetFramesPerSecond();
} }
@Override @Override
@ -78,7 +80,7 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
} }
if (stage.getCamera().position.x != cameraPosition.x || stage.getCamera().position.y != cameraPosition.y) { if (stage.getCamera().position.x != cameraPosition.x || stage.getCamera().position.y != cameraPosition.y) {
stage.getCamera().position.lerp(cameraPosition, delta*lerpAlpha); stage.getCamera().position.lerp(cameraPosition, targetDelta*lerpAlpha);
stage.getViewport().apply(); stage.getViewport().apply();
} }
@ -113,7 +115,7 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
background = rhythmBullet.getAssetManager().get("backgrounds/mainBG.png", Texture.class); background = rhythmBullet.getAssetManager().get("backgrounds/mainBG.png", Texture.class);
mainPage = new MainPage(musicController, rhythmBullet.getAssetManager(), rhythmBullet.getSkin(), rhythmBullet.getScreenConfiguration(), listeners.musicSelectionPageButtonListener, listeners.optionsPageButtonListener); mainPage = new MainPage(musicController, musicMetadataController, rhythmBullet.getAssetManager(), rhythmBullet.getSkin(), rhythmBullet.getScreenConfiguration(), listeners.musicSelectionPageButtonListener, listeners.optionsPageButtonListener);
stage.addActor(mainPage); stage.addActor(mainPage);
//End main menu //End main menu
@ -251,7 +253,7 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
} }
if (bloomLevel > 0) { if (bloomLevel > 0) {
if (bloomShader == null) bloomShader = new BloomShader(screenBatch); if (bloomShader == null) bloomShader = new BloomShader(screenBatch);
bloomShader.setBloomLevel(bloomLevel); bloomShader.setBloomLevel((bloomLevel-1)*2);
} else if (bloomShader != null) { } else if (bloomShader != null) {
bloomShader.dispose(); bloomShader.dispose();
bloomShader = null; bloomShader = null;

View File

@ -31,7 +31,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import zero1hd.rhythmbullet.audio.MusicMetadataController; import zero1hd.rhythmbullet.audio.AudioMetadataController;
import zero1hd.rhythmbullet.audio.metadata.AudioMetadata; import zero1hd.rhythmbullet.audio.metadata.AudioMetadata;
import zero1hd.rhythmbullet.audio.MusicController; import zero1hd.rhythmbullet.audio.MusicController;
import zero1hd.rhythmbullet.graphics.ui.Page; import zero1hd.rhythmbullet.graphics.ui.Page;
@ -41,7 +41,7 @@ public class MusicSelectionPage extends Page implements Observer {
Preferences musicFileAnnotation; Preferences musicFileAnnotation;
private MusicController mc; private MusicController mc;
private MusicMetadataController mmc; private AudioMetadataController mmc;
private MusicSelectableButtonGroup selectables; private MusicSelectableButtonGroup selectables;
private VerticalGroup vGroup; private VerticalGroup vGroup;
private TextButton back; private TextButton back;
@ -62,7 +62,7 @@ public class MusicSelectionPage extends Page implements Observer {
private float scrollTimer, scrollDelay = 0.2f, scrollDelMod, songSelectionTimer; private float scrollTimer, scrollDelay = 0.2f, scrollDelMod, songSelectionTimer;
private float musicSelectDelay; private float musicSelectDelay;
public MusicSelectionPage(AssetManager assetManager, Skin skin, MusicController musicController, MusicMetadataController musicMetadataController, ChangeListener backButtonListener, ChangeListener beginButtonListener) { public MusicSelectionPage(AssetManager assetManager, Skin skin, MusicController musicController, AudioMetadataController musicMetadataController, ChangeListener backButtonListener, ChangeListener beginButtonListener) {
super(1, 0); super(1, 0);
this.assets = assetManager; this.assets = assetManager;
this.mc = musicController; this.mc = musicController;
@ -77,8 +77,6 @@ public class MusicSelectionPage extends Page implements Observer {
scrollPane = new ScrollPane(vGroup, skin); scrollPane = new ScrollPane(vGroup, skin);
scrollPane.setSize(0.45f*getWidth(), getHeight()); scrollPane.setSize(0.45f*getWidth(), getHeight());
scrollPane.setOverscroll(false, false); scrollPane.setOverscroll(false, false);
scrollPane.setClamp(true);
scrollPane.setSmoothScrolling(false);
scrollPane.setColor(Color.BLUE); scrollPane.setColor(Color.BLUE);
addActor(scrollPane); addActor(scrollPane);
back = new TextButton("Back", skin); back = new TextButton("Back", skin);
@ -179,9 +177,9 @@ public class MusicSelectionPage extends Page implements Observer {
private synchronized void updateList(float delta) { private synchronized void updateList(float delta) {
if (mc.getMusicList().isSearched()) { if (mc.getMusicList().isSearched()) {
if (mc.getMusicList().getTotal() != 0) { if (mc.getMusicList().getTotal() != 0) {
if (mmc.isDone() && !mmc.isSearching()) { if (mmc.isSameSizeMusicList() && !mmc.isSearching()) {
if (selectables.size() != mmc.size()) { if (selectables.size() != mmc.size()) {
MusicSelectable selectable = new MusicSelectable(mmc.getMetadata(selectables.size())); MusicSelectable selectable = new MusicSelectable(mmc.getAudioMetadata(selectables.size()));
selectables.add(selectable); selectables.add(selectable);
} else if (selectables.size() != vGroup.getChildren().size) { } else if (selectables.size() != vGroup.getChildren().size) {
vGroup.addActor(selectables.getButtons().get(vGroup.getChildren().size)); vGroup.addActor(selectables.getButtons().get(vGroup.getChildren().size));
@ -351,7 +349,7 @@ public class MusicSelectionPage extends Page implements Observer {
actualCoords.x = getX() + getParent().getX(); actualCoords.x = getX() + getParent().getX();
actualCoords.y = getY() + getParent().getY(); actualCoords.y = getY() + getParent().getY();
if ((actualCoords.y < 0 - getHeight() - getStage().getHeight()*1.5f || actualCoords.y > getStage().getHeight()*1.5f) && selectables.getChecked() != this) { if ((actualCoords.y < 0 - getHeight() - getStage().getHeight()*1.5f || actualCoords.y > getStage().getHeight()*2.5f) && selectables.getChecked() != this) {
offScreenAct(delta); offScreenAct(delta);
} else { } else {
onScreenAct(delta); onScreenAct(delta);