From: nathan.sweet Date: Sun, 9 Oct 2011 19:53:02 +0000 (+0000) Subject: [fixed] Issue 292, WAV headers not read and skip not working with buffered streams. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=8d0526e99e3f7f0422934280726836ee597bd1ac;p=mikumikustudio%2Flibgdx-mikumikustudio.git [fixed] Issue 292, WAV headers not read and skip not working with buffered streams. --- diff --git a/backends/gdx-openal/src/com/badlogic/gdx/backends/openal/Wav.java b/backends/gdx-openal/src/com/badlogic/gdx/backends/openal/Wav.java index 2c0101b8b..48a617ce6 100644 --- a/backends/gdx-openal/src/com/badlogic/gdx/backends/openal/Wav.java +++ b/backends/gdx-openal/src/com/badlogic/gdx/backends/openal/Wav.java @@ -17,6 +17,7 @@ package com.badlogic.gdx.backends.openal; import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.FilterInputStream; import java.io.IOException; @@ -84,15 +85,12 @@ public class Wav { if (read() != 'R' || read() != 'I' || read() != 'F' || read() != 'F') throw new GdxRuntimeException("RIFF header not found: " + file); - skip(4); + skipFully(4); if (read() != 'W' || read() != 'A' || read() != 'V' || read() != 'E') throw new GdxRuntimeException("Invalid wave file header: " + file); - if (read() != 'f' || read() != 'm' || read() != 't' || read() != ' ') - throw new GdxRuntimeException("fmt header not found: " + file); - - int waveChunkLength = read() & 0xff | (read() & 0xff) << 8 | (read() & 0xff) << 16 | (read() & 0xff) << 24; + int fmtChunkLength = seekToChunk('f', 'm', 't', ' '); int type = read() & 0xff | (read() & 0xff) << 8; if (type != 1) throw new GdxRuntimeException("WAV files must be PCM: " + type); @@ -103,17 +101,14 @@ public class Wav { sampleRate = read() & 0xff | (read() & 0xff) << 8 | (read() & 0xff) << 16 | (read() & 0xff) << 24; - skip(6); + skipFully(6); int bitsPerSample = read() & 0xff | (read() & 0xff) << 8; if (bitsPerSample != 16) throw new GdxRuntimeException("WAV files must have 16 bits per sample: " + bitsPerSample); - skip(waveChunkLength - 16); - - if (read() != 'd' || read() != 'a' || read() != 't' || read() != 'a') - throw new GdxRuntimeException("data header not found: " + file); + skipFully(fmtChunkLength - 16); - dataRemaining = read() & 0xff | (read() & 0xff) << 8 | (read() & 0xff) << 16 | (read() & 0xff) << 24; + dataRemaining = seekToChunk('d', 'a', 't', 'a'); } catch (Throwable ex) { try { close(); @@ -123,6 +118,27 @@ public class Wav { } } + private int seekToChunk (char c1, char c2, char c3, char c4) throws IOException { + while (true) { + boolean found = read() == c1; + found &= read() == c2; + found &= read() == c3; + found &= read() == c4; + int chunkLength = read() & 0xff | (read() & 0xff) << 8 | (read() & 0xff) << 16 | (read() & 0xff) << 24; + if (chunkLength == -1) throw new IOException("Chunk not found: " + c1 + c2 + c3 + c4); + if (found) return chunkLength; + skipFully(chunkLength); + } + } + + private void skipFully (int count) throws IOException { + while (count > 0) { + long skipped = in.skip(count); + if (skipped <= 0) throw new EOFException("Unable to skip."); + count -= skipped; + } + } + public int readData (byte[] buffer) throws IOException { if (dataRemaining == 0) return -1; int length = Math.min(read(buffer), dataRemaining); diff --git a/tests/gdx-tests/src/com/badlogic/gdx/tests/SoundTest.java b/tests/gdx-tests/src/com/badlogic/gdx/tests/SoundTest.java index 17ea5041b..93d43c200 100644 --- a/tests/gdx-tests/src/com/badlogic/gdx/tests/SoundTest.java +++ b/tests/gdx-tests/src/com/badlogic/gdx/tests/SoundTest.java @@ -46,7 +46,7 @@ public class SoundTest extends GdxTest { @Override public void create () { sound = Gdx.audio.newSound(Gdx.files.getFileHandle("data/shotgun.wav", FileType.Internal)); - + Skin skin = new Skin(Gdx.files.internal("data/uiskin.json"), Gdx.files.internal("data/uiskin.png")); ui = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true); Button play = new Button("Play", skin); @@ -61,8 +61,9 @@ public class SoundTest extends GdxTest { final Slider pan = new Slider(-1f, 1f, 0.1f, skin); pan.setValue(0); final Label panValue = new Label("0.0", skin); - table.width = Gdx.graphics.getWidth(); table.height = Gdx.graphics.getHeight(); - + table.width = Gdx.graphics.getWidth(); + table.height = Gdx.graphics.getHeight(); + table.align(Align.CENTER | Align.TOP); table.add(play); table.add(stop); @@ -79,7 +80,7 @@ public class SoundTest extends GdxTest { table.add(pan); table.add(panValue); ui.addActor(table); - + play.setClickListener(new ClickListener() { @Override public void click (Actor actor) { @@ -88,7 +89,7 @@ public class SoundTest extends GdxTest { sound.setPan(soundId, pan.getValue(), volume.getValue()); } }); - + stop.setClickListener(new ClickListener() { @Override public void click (Actor actor) { @@ -113,12 +114,12 @@ public class SoundTest extends GdxTest { @Override public void changed (Slider slider, float value) { sound.setPan(soundId, value, volume.getValue()); + panValue.setText("" + value); } }); Gdx.input.setInputProcessor(ui); } - - + @Override public void render () { Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); @@ -126,7 +127,6 @@ public class SoundTest extends GdxTest { ui.draw(); } - @Override public boolean needsGL20 () { return false;