diff --git a/core/src/zero1hd/polyjet/Polyjet.java b/core/src/zero1hd/polyjet/Polyjet.java index e887b62..4e302b3 100755 --- a/core/src/zero1hd/polyjet/Polyjet.java +++ b/core/src/zero1hd/polyjet/Polyjet.java @@ -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"); diff --git a/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java b/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java index 7863a4c..779fd51 100755 --- a/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java +++ b/core/src/zero1hd/polyjet/audio/AudioAnalyzer.java @@ -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]; diff --git a/core/src/zero1hd/polyjet/audio/AudioData.java b/core/src/zero1hd/polyjet/audio/AudioData.java index e1a6c35..3170e62 100755 --- a/core/src/zero1hd/polyjet/audio/AudioData.java +++ b/core/src/zero1hd/polyjet/audio/AudioData.java @@ -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. */ diff --git a/core/src/zero1hd/polyjet/audio/Mp3AudioData.java b/core/src/zero1hd/polyjet/audio/Mp3AudioData.java index a26a086..f88dd0e 100755 --- a/core/src/zero1hd/polyjet/audio/Mp3AudioData.java +++ b/core/src/zero1hd/polyjet/audio/Mp3AudioData.java @@ -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 diff --git a/core/src/zero1hd/polyjet/audio/WavAudioData.java b/core/src/zero1hd/polyjet/audio/WavAudioData.java index da36729..b35094c 100755 --- a/core/src/zero1hd/polyjet/audio/WavAudioData.java +++ b/core/src/zero1hd/polyjet/audio/WavAudioData.java @@ -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) { diff --git a/core/src/zero1hd/polyjet/screens/PreGameScreen.java b/core/src/zero1hd/polyjet/screens/PreGameScreen.java index 7de1d87..5d4267d 100755 --- a/core/src/zero1hd/polyjet/screens/PreGameScreen.java +++ b/core/src/zero1hd/polyjet/screens/PreGameScreen.java @@ -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); diff --git a/core/src/zero1hd/polyjet/ui/builders/MusicSelectable.java b/core/src/zero1hd/polyjet/ui/builders/MusicSelectable.java index a028bf5..b6c7398 100755 --- a/core/src/zero1hd/polyjet/ui/builders/MusicSelectable.java +++ b/core/src/zero1hd/polyjet/ui/builders/MusicSelectable.java @@ -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(); diff --git a/core/src/zero1hd/polyjet/screens/AnalyzePage.java b/core/src/zero1hd/polyjet/ui/pages/AnalyzePage.java similarity index 80% rename from core/src/zero1hd/polyjet/screens/AnalyzePage.java rename to core/src/zero1hd/polyjet/ui/pages/AnalyzePage.java index 136ed25..1c0dbd7 100755 --- a/core/src/zero1hd/polyjet/screens/AnalyzePage.java +++ b/core/src/zero1hd/polyjet/ui/pages/AnalyzePage.java @@ -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 uiMusicInfo) { + cameraPos.x = 1.5f*getWidth(); this.music = music; audioAnalyzer.startAnalyticalThread(music); songInfo.add(uiMusicInfo.get(0)).spaceBottom(20f); diff --git a/core/src/zero1hd/polyjet/ui/pages/MusicSelectionPage.java b/core/src/zero1hd/polyjet/ui/pages/MusicSelectionPage.java index e73a388..7c1995d 100755 --- a/core/src/zero1hd/polyjet/ui/pages/MusicSelectionPage.java +++ b/core/src/zero1hd/polyjet/ui/pages/MusicSelectionPage.java @@ -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()); } }); } diff --git a/core/src/zero1hd/polyjet/ui/stages/AnalysisResults.java b/core/src/zero1hd/polyjet/ui/stages/AnalysisResults.java deleted file mode 100755 index 731d74f..0000000 --- a/core/src/zero1hd/polyjet/ui/stages/AnalysisResults.java +++ /dev/null @@ -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(); - } -} diff --git a/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java b/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java index d13cb1c..ca2af11 100755 --- a/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java +++ b/core/src/zero1hd/polyjet/ui/stages/CreativeStage.java @@ -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; diff --git a/core/src/zero1hd/polyjet/ui/windows/MusicController.java b/core/src/zero1hd/polyjet/ui/windows/MusicController.java index b76bf88..af98e20 100755 --- a/core/src/zero1hd/polyjet/ui/windows/MusicController.java +++ b/core/src/zero1hd/polyjet/ui/windows/MusicController.java @@ -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; diff --git a/core/src/zero1hd/polyjet/ui/windows/NoticeWindow.java b/core/src/zero1hd/polyjet/ui/windows/NoticeWindow.java index 69bb76c..2439011 100755 --- a/core/src/zero1hd/polyjet/ui/windows/NoticeWindow.java +++ b/core/src/zero1hd/polyjet/ui/windows/NoticeWindow.java @@ -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); } diff --git a/core/src/zero1hd/wavedecoder/WavDecoder.java b/core/src/zero1hd/wavedecoder/WavDecoder.java index a3ea1be..c023f08 100755 --- a/core/src/zero1hd/wavedecoder/WavDecoder.java +++ b/core/src/zero1hd/wavedecoder/WavDecoder.java @@ -1,16 +1,128 @@ package zero1hd.wavedecoder; +import java.io.DataInputStream; import java.io.IOException; import java.security.InvalidParameterException; +import com.badlogic.gdx.files.FileHandle; + public class WavDecoder { - private WavInfo initialData; + private FileHandle file; - public void setAudioFile(WavInfo info) throws InvalidParameterException, IOException { - initialData = info; - 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) { 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(); } diff --git a/core/src/zero1hd/wavedecoder/WavInfo.java b/core/src/zero1hd/wavedecoder/WavInfo.java deleted file mode 100755 index 70640f0..0000000 --- a/core/src/zero1hd/wavedecoder/WavInfo.java +++ /dev/null @@ -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; - } -}