OSDN Git Service

[fixed] Issue 292, WAV headers not read and skip not working with buffered streams.
authornathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Sun, 9 Oct 2011 19:53:02 +0000 (19:53 +0000)
committernathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Sun, 9 Oct 2011 19:53:02 +0000 (19:53 +0000)
backends/gdx-openal/src/com/badlogic/gdx/backends/openal/Wav.java
tests/gdx-tests/src/com/badlogic/gdx/tests/SoundTest.java

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