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");
|
||||
defaultSkin.add("default", defaultTextButton);
|
||||
|
||||
TextButtonStyle subTextbutton = new TextButtonStyle(defaultTextButton);
|
||||
subTextbutton.font = defaultSkin.getFont("sub-font");
|
||||
defaultSkin.add("sub", subTextbutton);
|
||||
|
||||
|
||||
TextButtonStyle textButtonLeft = new TextButtonStyle();
|
||||
textButtonLeft.up = defaultSkin.getDrawable("left-button");
|
||||
textButtonLeft.down = defaultSkin.getDrawable("left-button-down");
|
||||
|
@ -213,8 +213,8 @@ public class AudioAnalyzer {
|
||||
overlappedBeats.shrink();
|
||||
}
|
||||
|
||||
public void startAnalyticalThread(final AudioData audiofile) {
|
||||
|
||||
public void startAnalyticalThread(AudioData audiofile) {
|
||||
audioPCM = new float[audiofile.getReadWindowSize()];
|
||||
fftData = new float[audiofile.getReadWindowSize()];
|
||||
spectrum = 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 com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
public interface AudioData {
|
||||
/**
|
||||
@ -18,11 +17,6 @@ public interface AudioData {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -23,22 +23,6 @@ public class Mp3AudioData implements AudioData {
|
||||
|
||||
|
||||
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();
|
||||
try {
|
||||
audStream = AudioSystem.getAudioInputStream(setAudio.file());
|
||||
@ -51,7 +35,17 @@ public class Mp3AudioData implements AudioData {
|
||||
|
||||
|
||||
playbackMusic = Gdx.audio.newMusic(setAudio);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void readIndexUpdate() {
|
||||
readIndex = (int) (playbackMusic.getPosition() * audioFormat.getSampleRate() / readWindowSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadIndex() {
|
||||
return readIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,7 +10,6 @@ import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
import zero1hd.wavedecoder.WavDecoder;
|
||||
import zero1hd.wavedecoder.WavInfo;
|
||||
|
||||
public class WavAudioData implements AudioData {
|
||||
private int readWindowSize = 1024;
|
||||
@ -18,15 +17,24 @@ public class WavAudioData implements AudioData {
|
||||
int readIndex;
|
||||
Music playbackMusic;
|
||||
WavDecoder decoder;
|
||||
WavInfo wavinfo;
|
||||
|
||||
public WavAudioData(FileHandle audioFileHandle) {
|
||||
setAudioFile(audioFileHandle);
|
||||
public WavAudioData(FileHandle file) {
|
||||
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
|
||||
public void readIndexUpdate() {
|
||||
readIndex = (int) (playbackMusic.getPosition() * wavinfo.getSampleRate() / readWindowSize);
|
||||
readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -34,23 +42,6 @@ public class WavAudioData implements AudioData {
|
||||
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
|
||||
public void reset() {
|
||||
if (playbackMusic != null) {
|
||||
|
@ -14,6 +14,7 @@ import zero1hd.polyjet.Polyjet;
|
||||
import zero1hd.polyjet.audio.AudioAnalyzer;
|
||||
import zero1hd.polyjet.audio.WavAudioData;
|
||||
import zero1hd.polyjet.maps.RhythmMap;
|
||||
import zero1hd.polyjet.ui.pages.AnalyzePage;
|
||||
import zero1hd.polyjet.ui.pages.MusicSelectionPage;
|
||||
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);
|
||||
stage.addActor(cyberCircle1);
|
||||
|
||||
analyzePage = new AnalyzePage(core.defaultSkin);
|
||||
analyzePage = new AnalyzePage(core.defaultSkin, cameraTarget);
|
||||
analyzePage.setPosition(1f*Gdx.graphics.getWidth(), 0);
|
||||
stage.addActor(analyzePage);
|
||||
|
||||
|
@ -2,6 +2,7 @@ package zero1hd.polyjet.ui.builders;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||
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.Disposable;
|
||||
|
||||
import zero1hd.wavedecoder.WavInfo;
|
||||
|
||||
public class MusicSelectable extends Button implements Disposable {
|
||||
private boolean invalidMusic;
|
||||
private long durationInSeconds;
|
||||
private String songName;
|
||||
private Texture albumCover;
|
||||
WavInfo wavinfo;
|
||||
private String author;
|
||||
private int previousTop;
|
||||
private int ratedDifficulty;
|
||||
@ -77,13 +75,13 @@ public class MusicSelectable extends Button implements Disposable {
|
||||
}
|
||||
|
||||
} else {
|
||||
wavinfo = new WavInfo(musicFile.file());
|
||||
durationInSeconds = wavinfo.getDurationInSeconds();
|
||||
|
||||
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);
|
||||
author = wavTag.getFirst(FieldKey.ARTIST);
|
||||
durationInSeconds = audioFile.getAudioHeader().getTrackLength();
|
||||
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException
|
||||
| InvalidAudioFrameException e) {
|
||||
// TODO Auto-generated catch block
|
||||
@ -174,10 +172,6 @@ public class MusicSelectable extends Button implements Disposable {
|
||||
return albumCover;
|
||||
}
|
||||
|
||||
public WavInfo getWavinfo() {
|
||||
return wavinfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 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.ui.Label;
|
||||
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.AudioData;
|
||||
import zero1hd.polyjet.ui.pages.Page;
|
||||
|
||||
public class AnalyzePage extends Page {
|
||||
AudioAnalyzer audioAnalyzer;
|
||||
AudioData music;
|
||||
|
||||
Vector3 cameraPos;
|
||||
|
||||
Table songInfo;
|
||||
Slider difficultyModifier;
|
||||
Label difficultyModifierPercentage;
|
||||
|
||||
public AnalyzePage(Skin skin) {
|
||||
public AnalyzePage(Skin skin, Vector3 camPos) {
|
||||
super("Results", skin);
|
||||
|
||||
cameraPos = camPos;
|
||||
audioAnalyzer = new AudioAnalyzer();
|
||||
songInfo = new Table(skin);
|
||||
}
|
||||
|
||||
public void setSong(AudioData music, SnapshotArray<Actor> uiMusicInfo) {
|
||||
cameraPos.x = 1.5f*getWidth();
|
||||
this.music = music;
|
||||
audioAnalyzer.startAnalyticalThread(music);
|
||||
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.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
|
||||
import zero1hd.polyjet.Polyjet;
|
||||
import zero1hd.polyjet.audio.Audio;
|
||||
import zero1hd.polyjet.audio.AudioData;
|
||||
import zero1hd.polyjet.screens.AnalyzePage;
|
||||
import zero1hd.polyjet.screens.MainMenu;
|
||||
import zero1hd.polyjet.ui.builders.MusicSelectable;
|
||||
import zero1hd.polyjet.ui.windows.LoadingWindow;
|
||||
@ -73,6 +70,7 @@ public class MusicSelectionPage extends Page {
|
||||
|
||||
loadingWindow.toFront();
|
||||
back.toFront();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -112,28 +110,8 @@ public class MusicSelectionPage extends Page {
|
||||
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
final NoticeWindow notice = new NoticeWindow(core.defaultSkin, "tinted", "are you sure?", "Analyze this song?");
|
||||
notice.setSize(0.3f*getWidth(), 0.3f*getHeight());
|
||||
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();
|
||||
System.out.println();
|
||||
ap.setSong(Audio.getAudioData(selectable.getMusicFile()), selectable.getChildren());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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.AudioAnalyzer;
|
||||
import zero1hd.polyjet.audio.AudioData;
|
||||
import zero1hd.polyjet.audio.Mp3AudioData;
|
||||
import zero1hd.polyjet.audio.WavAudioData;
|
||||
import zero1hd.polyjet.screens.MainMenu;
|
||||
import zero1hd.polyjet.ui.windows.BeatViewer;
|
||||
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 zero1hd.polyjet.audio.AudioData;
|
||||
import zero1hd.polyjet.audio.WavAudioData;
|
||||
|
||||
public class MusicController extends Window {
|
||||
boolean musicReady;
|
||||
|
@ -31,7 +31,7 @@ public class NoticeWindow extends Window {
|
||||
}
|
||||
|
||||
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);
|
||||
add(button).align(alignment);
|
||||
}
|
||||
|
@ -1,16 +1,128 @@
|
||||
package zero1hd.wavedecoder;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidParameterException;
|
||||
|
||||
public class WavDecoder {
|
||||
private WavInfo initialData;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
public void setAudioFile(WavInfo info) throws InvalidParameterException, IOException {
|
||||
initialData = info;
|
||||
initialData.initDataStream();
|
||||
initialData.getHeaderInfo();
|
||||
public class WavDecoder {
|
||||
private FileHandle file;
|
||||
|
||||
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) {
|
||||
int samplesRead = 0;
|
||||
|
||||
@ -18,15 +130,15 @@ public class WavDecoder {
|
||||
try {
|
||||
|
||||
int currentSample = 0;
|
||||
for (int channel = 0; channel < initialData.getChannels(); channel++) {
|
||||
currentSample += initialData.readLittleEndianShort();
|
||||
for (int channel = 0; channel < getChannels(); channel++) {
|
||||
currentSample += readLittleEndianShort();
|
||||
}
|
||||
currentSample /= initialData.getChannels()*Short.MAX_VALUE+1;
|
||||
currentSample /= getChannels()*Short.MAX_VALUE+1;
|
||||
samples[i] = currentSample;
|
||||
samplesRead++;
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
initialData.closeStreams();
|
||||
closeStreams();
|
||||
} catch (IOException e1) {
|
||||
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