began work on integrating analysis system, cleaned up audio system
This commit is contained in:
parent
cc2d9329b5
commit
dce73a662f
@ -173,6 +173,11 @@ public class Polyjet extends Game {
|
|||||||
defaultTextButton.disabled = defaultSkin.getDrawable("default-round-disabled");
|
defaultTextButton.disabled = defaultSkin.getDrawable("default-round-disabled");
|
||||||
defaultSkin.add("default", defaultTextButton);
|
defaultSkin.add("default", defaultTextButton);
|
||||||
|
|
||||||
|
TextButtonStyle subTextbutton = new TextButtonStyle(defaultTextButton);
|
||||||
|
subTextbutton.font = defaultSkin.getFont("sub-font");
|
||||||
|
defaultSkin.add("sub", subTextbutton);
|
||||||
|
|
||||||
|
|
||||||
TextButtonStyle textButtonLeft = new TextButtonStyle();
|
TextButtonStyle textButtonLeft = new TextButtonStyle();
|
||||||
textButtonLeft.up = defaultSkin.getDrawable("left-button");
|
textButtonLeft.up = defaultSkin.getDrawable("left-button");
|
||||||
textButtonLeft.down = defaultSkin.getDrawable("left-button-down");
|
textButtonLeft.down = defaultSkin.getDrawable("left-button-down");
|
||||||
|
@ -213,8 +213,8 @@ public class AudioAnalyzer {
|
|||||||
overlappedBeats.shrink();
|
overlappedBeats.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startAnalyticalThread(final AudioData audiofile) {
|
public void startAnalyticalThread(AudioData audiofile) {
|
||||||
|
audioPCM = new float[audiofile.getReadWindowSize()];
|
||||||
fftData = new float[audiofile.getReadWindowSize()];
|
fftData = new float[audiofile.getReadWindowSize()];
|
||||||
spectrum = new float[(audiofile.getReadWindowSize()/2)+1];
|
spectrum = new float[(audiofile.getReadWindowSize()/2)+1];
|
||||||
lastSpectrum = new float[(audiofile.getReadWindowSize()/2)+1];
|
lastSpectrum = new float[(audiofile.getReadWindowSize()/2)+1];
|
||||||
|
@ -3,7 +3,6 @@ package zero1hd.polyjet.audio;
|
|||||||
import javax.sound.sampled.AudioFormat;
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
|
||||||
import com.badlogic.gdx.audio.Music;
|
import com.badlogic.gdx.audio.Music;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
|
||||||
|
|
||||||
public interface AudioData {
|
public interface AudioData {
|
||||||
/**
|
/**
|
||||||
@ -18,11 +17,6 @@ public interface AudioData {
|
|||||||
*/
|
*/
|
||||||
public int getReadIndex();
|
public int getReadIndex();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current audio file
|
|
||||||
*/
|
|
||||||
public void setAudioFile(FileHandle setAudio);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Completely resets the current audio data. Think of pooling, except, only one instance which is reused instead of multiple.
|
* Completely resets the current audio data. Think of pooling, except, only one instance which is reused instead of multiple.
|
||||||
*/
|
*/
|
||||||
|
@ -23,22 +23,6 @@ public class Mp3AudioData implements AudioData {
|
|||||||
|
|
||||||
|
|
||||||
public Mp3AudioData(FileHandle setAudio) {
|
public Mp3AudioData(FileHandle setAudio) {
|
||||||
setAudioFile(setAudio);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readIndexUpdate() {
|
|
||||||
readIndex = (int) (playbackMusic.getPosition() * audioFormat.getSampleRate() / readWindowSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getReadIndex() {
|
|
||||||
return readIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAudioFile(FileHandle setAudio) {
|
|
||||||
reset();
|
reset();
|
||||||
try {
|
try {
|
||||||
audStream = AudioSystem.getAudioInputStream(setAudio.file());
|
audStream = AudioSystem.getAudioInputStream(setAudio.file());
|
||||||
@ -51,7 +35,17 @@ public class Mp3AudioData implements AudioData {
|
|||||||
|
|
||||||
|
|
||||||
playbackMusic = Gdx.audio.newMusic(setAudio);
|
playbackMusic = Gdx.audio.newMusic(setAudio);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readIndexUpdate() {
|
||||||
|
readIndex = (int) (playbackMusic.getPosition() * audioFormat.getSampleRate() / readWindowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getReadIndex() {
|
||||||
|
return readIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,7 +10,6 @@ import com.badlogic.gdx.audio.Music;
|
|||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
import zero1hd.wavedecoder.WavDecoder;
|
import zero1hd.wavedecoder.WavDecoder;
|
||||||
import zero1hd.wavedecoder.WavInfo;
|
|
||||||
|
|
||||||
public class WavAudioData implements AudioData {
|
public class WavAudioData implements AudioData {
|
||||||
private int readWindowSize = 1024;
|
private int readWindowSize = 1024;
|
||||||
@ -18,15 +17,24 @@ public class WavAudioData implements AudioData {
|
|||||||
int readIndex;
|
int readIndex;
|
||||||
Music playbackMusic;
|
Music playbackMusic;
|
||||||
WavDecoder decoder;
|
WavDecoder decoder;
|
||||||
WavInfo wavinfo;
|
|
||||||
|
|
||||||
public WavAudioData(FileHandle audioFileHandle) {
|
public WavAudioData(FileHandle file) {
|
||||||
setAudioFile(audioFileHandle);
|
reset();
|
||||||
|
try {
|
||||||
|
decoder = new WavDecoder(file);
|
||||||
|
decoder.initDataStream();
|
||||||
|
decoder.getHeaderInfo();
|
||||||
|
} catch (InvalidParameterException | IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
playbackMusic = Gdx.audio.newMusic(file);
|
||||||
|
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, (float) decoder.getSampleRate(), 16, decoder.getChannels(), decoder.getChannels()*2, (float) decoder.getSampleRate(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readIndexUpdate() {
|
public void readIndexUpdate() {
|
||||||
readIndex = (int) (playbackMusic.getPosition() * wavinfo.getSampleRate() / readWindowSize);
|
readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -34,23 +42,6 @@ public class WavAudioData implements AudioData {
|
|||||||
return readIndex;
|
return readIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInfo(WavInfo wavinfo) {
|
|
||||||
this.wavinfo = wavinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAudioFile(FileHandle audioFileHandle) {
|
|
||||||
reset();
|
|
||||||
try {
|
|
||||||
decoder.setAudioFile(wavinfo);
|
|
||||||
} catch (InvalidParameterException | IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
playbackMusic = Gdx.audio.newMusic(audioFileHandle);
|
|
||||||
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, (float) wavinfo.getSampleRate(), 16, wavinfo.getChannels(), wavinfo.getChannels()*2, (float) wavinfo.getSampleRate(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
if (playbackMusic != null) {
|
if (playbackMusic != null) {
|
||||||
|
@ -14,6 +14,7 @@ import zero1hd.polyjet.Polyjet;
|
|||||||
import zero1hd.polyjet.audio.AudioAnalyzer;
|
import zero1hd.polyjet.audio.AudioAnalyzer;
|
||||||
import zero1hd.polyjet.audio.WavAudioData;
|
import zero1hd.polyjet.audio.WavAudioData;
|
||||||
import zero1hd.polyjet.maps.RhythmMap;
|
import zero1hd.polyjet.maps.RhythmMap;
|
||||||
|
import zero1hd.polyjet.ui.pages.AnalyzePage;
|
||||||
import zero1hd.polyjet.ui.pages.MusicSelectionPage;
|
import zero1hd.polyjet.ui.pages.MusicSelectionPage;
|
||||||
import zero1hd.polyjet.util.TransitionAdapter;
|
import zero1hd.polyjet.util.TransitionAdapter;
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ public class PreGameScreen extends ScreenAdapter implements TransitionAdapter {
|
|||||||
cyberCircle1.setPosition(Gdx.graphics.getWidth()-cyberCircle1.getWidth()/2-10, -cyberCircle1.getHeight()*2/4f);
|
cyberCircle1.setPosition(Gdx.graphics.getWidth()-cyberCircle1.getWidth()/2-10, -cyberCircle1.getHeight()*2/4f);
|
||||||
stage.addActor(cyberCircle1);
|
stage.addActor(cyberCircle1);
|
||||||
|
|
||||||
analyzePage = new AnalyzePage(core.defaultSkin);
|
analyzePage = new AnalyzePage(core.defaultSkin, cameraTarget);
|
||||||
analyzePage.setPosition(1f*Gdx.graphics.getWidth(), 0);
|
analyzePage.setPosition(1f*Gdx.graphics.getWidth(), 0);
|
||||||
stage.addActor(analyzePage);
|
stage.addActor(analyzePage);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package zero1hd.polyjet.ui.builders;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jaudiotagger.audio.AudioFile;
|
||||||
import org.jaudiotagger.audio.AudioFileIO;
|
import org.jaudiotagger.audio.AudioFileIO;
|
||||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||||
@ -26,14 +27,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
|||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
import zero1hd.wavedecoder.WavInfo;
|
|
||||||
|
|
||||||
public class MusicSelectable extends Button implements Disposable {
|
public class MusicSelectable extends Button implements Disposable {
|
||||||
private boolean invalidMusic;
|
private boolean invalidMusic;
|
||||||
private long durationInSeconds;
|
private long durationInSeconds;
|
||||||
private String songName;
|
private String songName;
|
||||||
private Texture albumCover;
|
private Texture albumCover;
|
||||||
WavInfo wavinfo;
|
|
||||||
private String author;
|
private String author;
|
||||||
private int previousTop;
|
private int previousTop;
|
||||||
private int ratedDifficulty;
|
private int ratedDifficulty;
|
||||||
@ -77,13 +75,13 @@ public class MusicSelectable extends Button implements Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
wavinfo = new WavInfo(musicFile.file());
|
|
||||||
durationInSeconds = wavinfo.getDurationInSeconds();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
WavTag wavTag = (WavTag) AudioFileIO.read(wavinfo.getFile()).getTag();
|
AudioFile audioFile = AudioFileIO.read(musicFile.file());
|
||||||
|
WavTag wavTag = (WavTag) AudioFileIO.read(musicFile.file()).getTag();
|
||||||
songName = wavTag.getFirst(FieldKey.TITLE);
|
songName = wavTag.getFirst(FieldKey.TITLE);
|
||||||
author = wavTag.getFirst(FieldKey.ARTIST);
|
author = wavTag.getFirst(FieldKey.ARTIST);
|
||||||
|
durationInSeconds = audioFile.getAudioHeader().getTrackLength();
|
||||||
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException
|
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException
|
||||||
| InvalidAudioFrameException e) {
|
| InvalidAudioFrameException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
@ -174,10 +172,6 @@ public class MusicSelectable extends Button implements Disposable {
|
|||||||
return albumCover;
|
return albumCover;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WavInfo getWavinfo() {
|
|
||||||
return wavinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
albumCover.dispose();
|
albumCover.dispose();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package zero1hd.polyjet.screens;
|
package zero1hd.polyjet.ui.pages;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector3;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
@ -9,22 +10,27 @@ import com.badlogic.gdx.utils.SnapshotArray;
|
|||||||
|
|
||||||
import zero1hd.polyjet.audio.AudioAnalyzer;
|
import zero1hd.polyjet.audio.AudioAnalyzer;
|
||||||
import zero1hd.polyjet.audio.AudioData;
|
import zero1hd.polyjet.audio.AudioData;
|
||||||
import zero1hd.polyjet.ui.pages.Page;
|
|
||||||
|
|
||||||
public class AnalyzePage extends Page {
|
public class AnalyzePage extends Page {
|
||||||
AudioAnalyzer audioAnalyzer;
|
AudioAnalyzer audioAnalyzer;
|
||||||
AudioData music;
|
AudioData music;
|
||||||
|
|
||||||
|
Vector3 cameraPos;
|
||||||
|
|
||||||
Table songInfo;
|
Table songInfo;
|
||||||
Slider difficultyModifier;
|
Slider difficultyModifier;
|
||||||
Label difficultyModifierPercentage;
|
Label difficultyModifierPercentage;
|
||||||
|
|
||||||
public AnalyzePage(Skin skin) {
|
public AnalyzePage(Skin skin, Vector3 camPos) {
|
||||||
super("Results", skin);
|
super("Results", skin);
|
||||||
|
|
||||||
|
cameraPos = camPos;
|
||||||
audioAnalyzer = new AudioAnalyzer();
|
audioAnalyzer = new AudioAnalyzer();
|
||||||
|
songInfo = new Table(skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSong(AudioData music, SnapshotArray<Actor> uiMusicInfo) {
|
public void setSong(AudioData music, SnapshotArray<Actor> uiMusicInfo) {
|
||||||
|
cameraPos.x = 1.5f*getWidth();
|
||||||
this.music = music;
|
this.music = music;
|
||||||
audioAnalyzer.startAnalyticalThread(music);
|
audioAnalyzer.startAnalyticalThread(music);
|
||||||
songInfo.add(uiMusicInfo.get(0)).spaceBottom(20f);
|
songInfo.add(uiMusicInfo.get(0)).spaceBottom(20f);
|
@ -14,12 +14,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
import com.badlogic.gdx.utils.Align;
|
|
||||||
|
|
||||||
import zero1hd.polyjet.Polyjet;
|
import zero1hd.polyjet.Polyjet;
|
||||||
import zero1hd.polyjet.audio.Audio;
|
import zero1hd.polyjet.audio.Audio;
|
||||||
import zero1hd.polyjet.audio.AudioData;
|
|
||||||
import zero1hd.polyjet.screens.AnalyzePage;
|
|
||||||
import zero1hd.polyjet.screens.MainMenu;
|
import zero1hd.polyjet.screens.MainMenu;
|
||||||
import zero1hd.polyjet.ui.builders.MusicSelectable;
|
import zero1hd.polyjet.ui.builders.MusicSelectable;
|
||||||
import zero1hd.polyjet.ui.windows.LoadingWindow;
|
import zero1hd.polyjet.ui.windows.LoadingWindow;
|
||||||
@ -73,6 +70,7 @@ public class MusicSelectionPage extends Page {
|
|||||||
|
|
||||||
loadingWindow.toFront();
|
loadingWindow.toFront();
|
||||||
back.toFront();
|
back.toFront();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -112,28 +110,8 @@ public class MusicSelectionPage extends Page {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
final NoticeWindow notice = new NoticeWindow(core.defaultSkin, "tinted", "are you sure?", "Analyze this song?");
|
System.out.println();
|
||||||
notice.setSize(0.3f*getWidth(), 0.3f*getHeight());
|
ap.setSong(Audio.getAudioData(selectable.getMusicFile()), selectable.getChildren());
|
||||||
notice.setPosition((getWidth()-notice.getWidth())/2f, (getHeight()-notice.getHeight())/2f);
|
|
||||||
notice.setupButton("cancel", new ChangeListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
|
||||||
notice.remove();
|
|
||||||
}
|
|
||||||
}, Align.left);
|
|
||||||
notice.setupButton("confirm", new ChangeListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
|
||||||
ap.setSong(Audio.getAudioData(selectable.getMusicFile()), selectable.getChildren());
|
|
||||||
}
|
|
||||||
}, Align.right);
|
|
||||||
|
|
||||||
notice.setModal(true);
|
|
||||||
notice.setMovable(false);
|
|
||||||
addActor(notice);
|
|
||||||
back.toFront();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package zero1hd.polyjet.ui.stages;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
|
||||||
|
|
||||||
import zero1hd.polyjet.Polyjet;
|
|
||||||
import zero1hd.polyjet.maps.RhythmMap;
|
|
||||||
|
|
||||||
public class AnalysisResults extends Stage {
|
|
||||||
Label DR;
|
|
||||||
Image circle1;
|
|
||||||
Image circle2;
|
|
||||||
Label proceed;
|
|
||||||
RhythmMap rhythmMap;
|
|
||||||
public boolean next;
|
|
||||||
|
|
||||||
public AnalysisResults(Polyjet core, RhythmMap rhythmMap) {
|
|
||||||
this.rhythmMap = rhythmMap;
|
|
||||||
this.DR = new Label("Ready?", core.defaultSkin, "large-font", Color.WHITE);
|
|
||||||
this.DR.setPosition(Gdx.graphics.getWidth()/2 - this.DR.getWidth()/2, Gdx.graphics.getHeight()/2 - this.DR.getHeight()/2);
|
|
||||||
proceed = new Label("Waiting for user input...", core.defaultSkin, "small-font", Color.WHITE);
|
|
||||||
|
|
||||||
proceed.setPosition((Gdx.graphics.getWidth()-proceed.getWidth())/2, Gdx.graphics.getHeight()-proceed.getHeight()-20);
|
|
||||||
proceed.addAction(Actions.forever(Actions.sequence(Actions.alpha(0.25f, 0.75f), Actions.alpha(1f, 0.75f))));
|
|
||||||
|
|
||||||
circle1 = new Image(core.assetManager.get("circle.png", Texture.class));
|
|
||||||
circle1.setPosition(0, 0);
|
|
||||||
circle2 = new Image(core.assetManager.get("circle.png", Texture.class));
|
|
||||||
circle2.setPosition(Gdx.graphics.getWidth()-circle2.getWidth(), Gdx.graphics.getHeight()-circle2.getHeight());
|
|
||||||
addActor(circle1);
|
|
||||||
addActor(circle2);
|
|
||||||
addActor(this.DR);
|
|
||||||
addActor(proceed);
|
|
||||||
|
|
||||||
addListener(new ClickListener() {
|
|
||||||
@Override
|
|
||||||
public void clicked(InputEvent event, float x, float y) {
|
|
||||||
next = true;
|
|
||||||
super.clicked(event, x, y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void act(float delta) {
|
|
||||||
super.act(delta);
|
|
||||||
|
|
||||||
//TODO set text to data difficulty
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
super.draw();
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,8 +17,6 @@ import zero1hd.polyjet.Polyjet;
|
|||||||
import zero1hd.polyjet.audio.Audio;
|
import zero1hd.polyjet.audio.Audio;
|
||||||
import zero1hd.polyjet.audio.AudioAnalyzer;
|
import zero1hd.polyjet.audio.AudioAnalyzer;
|
||||||
import zero1hd.polyjet.audio.AudioData;
|
import zero1hd.polyjet.audio.AudioData;
|
||||||
import zero1hd.polyjet.audio.Mp3AudioData;
|
|
||||||
import zero1hd.polyjet.audio.WavAudioData;
|
|
||||||
import zero1hd.polyjet.screens.MainMenu;
|
import zero1hd.polyjet.screens.MainMenu;
|
||||||
import zero1hd.polyjet.ui.windows.BeatViewer;
|
import zero1hd.polyjet.ui.windows.BeatViewer;
|
||||||
import zero1hd.polyjet.ui.windows.FPSWindow;
|
import zero1hd.polyjet.ui.windows.FPSWindow;
|
||||||
|
@ -14,7 +14,6 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||||
|
|
||||||
import zero1hd.polyjet.audio.AudioData;
|
import zero1hd.polyjet.audio.AudioData;
|
||||||
import zero1hd.polyjet.audio.WavAudioData;
|
|
||||||
|
|
||||||
public class MusicController extends Window {
|
public class MusicController extends Window {
|
||||||
boolean musicReady;
|
boolean musicReady;
|
||||||
|
@ -31,7 +31,7 @@ public class NoticeWindow extends Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setupButton(String text, ChangeListener changeListener, int alignment) {
|
public void setupButton(String text, ChangeListener changeListener, int alignment) {
|
||||||
TextButton button = new TextButton(text, skin, "sub-font");
|
TextButton button = new TextButton(text, skin, "sub");
|
||||||
button.addListener(changeListener);
|
button.addListener(changeListener);
|
||||||
add(button).align(alignment);
|
add(button).align(alignment);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,128 @@
|
|||||||
package zero1hd.wavedecoder;
|
package zero1hd.wavedecoder;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
public class WavDecoder {
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
private WavInfo initialData;
|
|
||||||
|
|
||||||
public void setAudioFile(WavInfo info) throws InvalidParameterException, IOException {
|
public class WavDecoder {
|
||||||
initialData = info;
|
private FileHandle file;
|
||||||
initialData.initDataStream();
|
|
||||||
initialData.getHeaderInfo();
|
private int channels;
|
||||||
|
private double sampleRate;
|
||||||
|
private int dataSize;
|
||||||
|
private int byteRate;
|
||||||
|
private DataInputStream readStream;
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
public WavDecoder(FileHandle file) throws IOException {
|
||||||
|
this.file = file;
|
||||||
|
initDataStream();
|
||||||
|
getHeaderInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getHeaderInfo() throws IOException {
|
||||||
|
if (!readBytesToString(4).equals("RIFF")) { //4 for RIFF tag
|
||||||
|
throw new InvalidParameterException("RIFF tag not found in header.");
|
||||||
|
}
|
||||||
|
dataSize = littleEndianIntBytes(); //4 for Chunk size
|
||||||
|
|
||||||
|
if (!readBytesToString(4).equals("WAVE")) { //4 for WAVE tag
|
||||||
|
throw new InvalidParameterException("WAVE format tag not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readBytesToString(4).equals("fmt ")) { //4 for 'fmt '
|
||||||
|
throw new InvalidParameterException("fmt header not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (littleEndianIntBytes() != 16) { //subchunk1size (4 bytes)
|
||||||
|
throw new InvalidParameterException("Data not pcm?");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readStream.readByte() != 1) { //1 pcm
|
||||||
|
throw new InvalidParameterException("Data not pcm?");
|
||||||
|
}
|
||||||
|
readStream.skip(1); //1
|
||||||
|
|
||||||
|
channels = readStream.readByte(); //1 channel count
|
||||||
|
readStream.skip(1); //1
|
||||||
|
|
||||||
|
sampleRate = littleEndianIntBytes(); //4 sample rate
|
||||||
|
|
||||||
|
byteRate = littleEndianIntBytes(); //4
|
||||||
|
|
||||||
|
readStream.skip(4);
|
||||||
|
|
||||||
|
String moreInfo = readBytesToString(4);
|
||||||
|
if (moreInfo.equals("LIST")) { // 4
|
||||||
|
readStream.skip(30);
|
||||||
|
if (!readBytesToString(4).equals("data")) {
|
||||||
|
throw new InvalidParameterException("failed to read data with extra info.");
|
||||||
|
}
|
||||||
|
} else if (!moreInfo.equals("data")) {
|
||||||
|
throw new InvalidParameterException("failed to read data.");
|
||||||
|
}
|
||||||
|
|
||||||
|
readStream.skip(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initDataStream() {
|
||||||
|
readStream = new DataInputStream(file.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeStreams() throws IOException {
|
||||||
|
readStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readBytesToString(int bytesToRead) throws IOException {
|
||||||
|
byte byteString[] = new byte[bytesToRead];
|
||||||
|
readStream.read(byteString);
|
||||||
|
return new String(byteString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int littleEndianIntBytes() throws IOException {
|
||||||
|
int data = readStream.readInt();
|
||||||
|
return Integer.reverseBytes(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short readLittleEndianShort() throws IOException {
|
||||||
|
short data = readStream.readShort();
|
||||||
|
return Short.reverseBytes(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataInputStream getReadStream() {
|
||||||
|
return readStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChannels() {
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getByteRate() {
|
||||||
|
return byteRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDataSize() {
|
||||||
|
return dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSampleRate() {
|
||||||
|
return sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDurationInSeconds() {
|
||||||
|
return (long) (dataSize/byteRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileHandle getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
public int readSamples(float[] samples) {
|
public int readSamples(float[] samples) {
|
||||||
int samplesRead = 0;
|
int samplesRead = 0;
|
||||||
|
|
||||||
@ -18,15 +130,15 @@ public class WavDecoder {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
int currentSample = 0;
|
int currentSample = 0;
|
||||||
for (int channel = 0; channel < initialData.getChannels(); channel++) {
|
for (int channel = 0; channel < getChannels(); channel++) {
|
||||||
currentSample += initialData.readLittleEndianShort();
|
currentSample += readLittleEndianShort();
|
||||||
}
|
}
|
||||||
currentSample /= initialData.getChannels()*Short.MAX_VALUE+1;
|
currentSample /= getChannels()*Short.MAX_VALUE+1;
|
||||||
samples[i] = currentSample;
|
samples[i] = currentSample;
|
||||||
samplesRead++;
|
samplesRead++;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
initialData.closeStreams();
|
closeStreams();
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
package zero1hd.wavedecoder;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.InvalidParameterException;
|
|
||||||
|
|
||||||
public class WavInfo {
|
|
||||||
private int channels;
|
|
||||||
private double sampleRate;
|
|
||||||
private int dataSize;
|
|
||||||
private int byteRate;
|
|
||||||
private FileInputStream audioFile;
|
|
||||||
private DataInputStream readStream;
|
|
||||||
private String fileName;
|
|
||||||
|
|
||||||
private File file;
|
|
||||||
public WavInfo(File file) throws InvalidParameterException {
|
|
||||||
try {
|
|
||||||
fileName = file.getName();
|
|
||||||
this.file = file;
|
|
||||||
audioFile = new FileInputStream(file);
|
|
||||||
initDataStream();
|
|
||||||
getHeaderInfo();
|
|
||||||
closeStreams();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void getHeaderInfo() throws IOException {
|
|
||||||
if (!readBytesToString(4).equals("RIFF")) { //4 for RIFF tag
|
|
||||||
throw new InvalidParameterException("RIFF tag not found in header.");
|
|
||||||
}
|
|
||||||
dataSize = littleEndianIntBytes(); //4 for Chunk size
|
|
||||||
|
|
||||||
if (!readBytesToString(4).equals("WAVE")) { //4 for WAVE tag
|
|
||||||
throw new InvalidParameterException("WAVE format tag not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!readBytesToString(4).equals("fmt ")) { //4 for 'fmt '
|
|
||||||
throw new InvalidParameterException("fmt header not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (littleEndianIntBytes() != 16) { //subchunk1size (4 bytes)
|
|
||||||
throw new InvalidParameterException("Data not pcm?");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readStream.readByte() != 1) { //1 pcm
|
|
||||||
throw new InvalidParameterException("Data not pcm?");
|
|
||||||
}
|
|
||||||
readStream.skip(1); //1
|
|
||||||
|
|
||||||
channels = readStream.readByte(); //1 channel count
|
|
||||||
readStream.skip(1); //1
|
|
||||||
|
|
||||||
sampleRate = littleEndianIntBytes(); //4 sample rate
|
|
||||||
|
|
||||||
byteRate = littleEndianIntBytes(); //4
|
|
||||||
|
|
||||||
readStream.skip(4);
|
|
||||||
|
|
||||||
String moreInfo = readBytesToString(4);
|
|
||||||
if (moreInfo.equals("LIST")) { // 4
|
|
||||||
readStream.skip(30);
|
|
||||||
if (!readBytesToString(4).equals("data")) {
|
|
||||||
throw new InvalidParameterException("failed to read data with extra info.");
|
|
||||||
}
|
|
||||||
} else if (!moreInfo.equals("data")) {
|
|
||||||
throw new InvalidParameterException("failed to read data.");
|
|
||||||
}
|
|
||||||
|
|
||||||
readStream.skip(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void initDataStream() {
|
|
||||||
readStream = new DataInputStream(audioFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void closeStreams() throws IOException {
|
|
||||||
readStream.close();
|
|
||||||
audioFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readBytesToString(int bytesToRead) throws IOException {
|
|
||||||
byte byteString[] = new byte[bytesToRead];
|
|
||||||
readStream.read(byteString);
|
|
||||||
return new String(byteString);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int littleEndianIntBytes() throws IOException {
|
|
||||||
int data = readStream.readInt();
|
|
||||||
return Integer.reverseBytes(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected short readLittleEndianShort() throws IOException {
|
|
||||||
short data = readStream.readShort();
|
|
||||||
return Short.reverseBytes(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected DataInputStream getReadStream() {
|
|
||||||
return readStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChannels() {
|
|
||||||
return channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getByteRate() {
|
|
||||||
return byteRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDataSize() {
|
|
||||||
return dataSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getSampleRate() {
|
|
||||||
return sampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDurationInSeconds() {
|
|
||||||
return (long) (dataSize/byteRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user