OSDN Git Service

[added] Modified version of the JLayer MP3 decoder. Stripped everything but the decod...
authornathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Sat, 8 Jan 2011 04:43:58 +0000 (04:43 +0000)
committernathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Sat, 8 Jan 2011 04:43:58 +0000 (04:43 +0000)
[added] MP3 music and sound support to gdx-audio.
[added] Simple test class.

backends/gdx-audio/.classpath
backends/gdx-audio/lib/jlayer-1.0.1-libgdx.jar [new file with mode: 0644]
backends/gdx-audio/lib/jlayer-1.0.1-libgdx.zip [new file with mode: 0644]
backends/gdx-audio/src/com/baglogic/gdx/audio/Mp3Music.java [new file with mode: 0644]
backends/gdx-audio/src/com/baglogic/gdx/audio/Mp3Sound.java [new file with mode: 0644]
backends/gdx-audio/src/com/baglogic/gdx/audio/OpenALAudio.java
backends/gdx-audio/src/com/baglogic/gdx/audio/Test.java [new file with mode: 0644]

index 34b7554..a629758 100644 (file)
@@ -3,5 +3,6 @@
        <classpathentry excluding="**/.svn/*" kind="src" path="src"/>\r
        <classpathentry combineaccessrules="false" kind="src" path="/gdx-backend-lwjgl"/>\r
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+       <classpathentry kind="lib" path="lib/jlayer-1.0.1-libgdx.jar"/>\r
        <classpathentry kind="output" path="bin"/>\r
 </classpath>\r
diff --git a/backends/gdx-audio/lib/jlayer-1.0.1-libgdx.jar b/backends/gdx-audio/lib/jlayer-1.0.1-libgdx.jar
new file mode 100644 (file)
index 0000000..2a58f57
Binary files /dev/null and b/backends/gdx-audio/lib/jlayer-1.0.1-libgdx.jar differ
diff --git a/backends/gdx-audio/lib/jlayer-1.0.1-libgdx.zip b/backends/gdx-audio/lib/jlayer-1.0.1-libgdx.zip
new file mode 100644 (file)
index 0000000..607be88
Binary files /dev/null and b/backends/gdx-audio/lib/jlayer-1.0.1-libgdx.zip differ
diff --git a/backends/gdx-audio/src/com/baglogic/gdx/audio/Mp3Music.java b/backends/gdx-audio/src/com/baglogic/gdx/audio/Mp3Music.java
new file mode 100644 (file)
index 0000000..69c5aff
--- /dev/null
@@ -0,0 +1,69 @@
+\r
+package com.baglogic.gdx.audio;\r
+\r
+import javazoom.jl.decoder.Bitstream;\r
+import javazoom.jl.decoder.BitstreamException;\r
+import javazoom.jl.decoder.Header;\r
+import javazoom.jl.decoder.MP3Decoder;\r
+import javazoom.jl.decoder.OutputBuffer;\r
+\r
+import com.badlogic.gdx.files.FileHandle;\r
+import com.badlogic.gdx.utils.GdxRuntimeException;\r
+\r
+public class Mp3Music extends OpenALMusic {\r
+       private Bitstream bitstream;\r
+       private OutputBuffer outputBuffer;\r
+       private MP3Decoder decoder;\r
+\r
+       public Mp3Music (OpenALAudio audio, FileHandle file) {\r
+               super(audio, file);\r
+       }\r
+\r
+       protected int read (byte[] buffer) {\r
+               try {\r
+                       boolean setup = bitstream == null;\r
+                       if (setup) {\r
+                               bitstream = new Bitstream(file.read());\r
+\r
+                               outputBuffer = new OutputBuffer(2, false);\r
+\r
+                               decoder = new MP3Decoder();\r
+                               decoder.setOutputBuffer(outputBuffer);\r
+                       }\r
+\r
+                       int totalLength = 0;\r
+                       int minRequiredLength = buffer.length - OutputBuffer.BUFFERSIZE * 2 - 1;\r
+                       while (totalLength < minRequiredLength) {\r
+                               Header header = bitstream.readFrame();\r
+                               if (header == null) break;\r
+                               if (setup) {\r
+                                       setup(outputBuffer.isStereo() ? 2 : 1, header.getSampleRate());\r
+                                       setup = false;\r
+                               }\r
+                               try {\r
+                                       decoder.decodeFrame(header, bitstream);\r
+                               } catch (Exception ignored) {\r
+                                       // JLayer's decoder throws ArrayIndexOutOfBoundsException sometimes!?\r
+                               }\r
+                               bitstream.closeFrame();\r
+\r
+                               int length = outputBuffer.reset();\r
+                               System.arraycopy(outputBuffer.getBuffer(), 0, buffer, totalLength, length);\r
+                               totalLength += length;\r
+                       }\r
+                       return totalLength;\r
+               } catch (Throwable ex) {\r
+                       reset();\r
+                       throw new GdxRuntimeException("Error reading audio data.", ex);\r
+               }\r
+       }\r
+\r
+       protected void reset () {\r
+               if (bitstream == null) return;\r
+               try {\r
+                       bitstream.close();\r
+               } catch (BitstreamException ignored) {\r
+               }\r
+               bitstream = null;\r
+       }\r
+}\r
diff --git a/backends/gdx-audio/src/com/baglogic/gdx/audio/Mp3Sound.java b/backends/gdx-audio/src/com/baglogic/gdx/audio/Mp3Sound.java
new file mode 100644 (file)
index 0000000..3fbbb14
--- /dev/null
@@ -0,0 +1,47 @@
+\r
+package com.baglogic.gdx.audio;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+\r
+import javazoom.jl.decoder.Bitstream;\r
+import javazoom.jl.decoder.Header;\r
+import javazoom.jl.decoder.MP3Decoder;\r
+import javazoom.jl.decoder.OutputBuffer;\r
+\r
+import com.badlogic.gdx.files.FileHandle;\r
+import com.badlogic.gdx.utils.GdxRuntimeException;\r
+\r
+public class Mp3Sound extends OpenALSound {\r
+       public Mp3Sound (OpenALAudio audio, FileHandle file) {\r
+               super(audio);\r
+\r
+               ByteArrayOutputStream output = new ByteArrayOutputStream(4096);\r
+\r
+               Bitstream bitstream = new Bitstream(file.read());\r
+\r
+               OutputBuffer outputBuffer = new OutputBuffer(2, false);\r
+\r
+               MP3Decoder decoder = new MP3Decoder();\r
+               decoder.setOutputBuffer(outputBuffer);\r
+\r
+               try {\r
+                       int sampleRate = -1;\r
+                       while (true) {\r
+                               Header header = bitstream.readFrame();\r
+                               if (header == null) break;\r
+                               if (sampleRate == -1) sampleRate = header.getSampleRate();\r
+                               try {\r
+                                       decoder.decodeFrame(header, bitstream);\r
+                               } catch (Exception ignored) {\r
+                                       // JLayer's decoder throws ArrayIndexOutOfBoundsException sometimes!?\r
+                               }\r
+                               bitstream.closeFrame();\r
+                               output.write(outputBuffer.getBuffer(), 0, outputBuffer.reset());\r
+                       }\r
+                       bitstream.close();\r
+                       setup(output.toByteArray(), outputBuffer.isStereo() ? 2 : 1, sampleRate);\r
+               } catch (Throwable ex) {\r
+                       throw new GdxRuntimeException("Error reading audio data.", ex);\r
+               }\r
+       }\r
+}\r
index 258b2a8..0e03590 100644 (file)
@@ -58,13 +58,21 @@ public class OpenALAudio implements Audio {
 \r
        public OpenALSound newSound (FileHandle file) {\r
                String extension = file.extension();\r
-               if (extension.equals("ogg")) return new OggSound(this, file);\r
+               if (extension.equals("ogg")) {\r
+                       return new OggSound(this, file);\r
+               } else if (extension.equals("mp3")) {\r
+                       return new Mp3Sound(this, file);\r
+               }\r
                throw new GdxRuntimeException("Unknown file extension for sound: " + file);\r
        }\r
 \r
        public OpenALMusic newMusic (FileHandle file) {\r
                String extension = file.extension();\r
-               if (extension.equals("ogg")) return new OggMusic(this, file);\r
+               if (extension.equals("ogg")) {\r
+                       return new OggMusic(this, file);\r
+               } else if (extension.equals("mp3")) {\r
+                       return new Mp3Music(this, file);\r
+               }\r
                throw new GdxRuntimeException("Unknown file extension for music: " + file);\r
        }\r
 \r
diff --git a/backends/gdx-audio/src/com/baglogic/gdx/audio/Test.java b/backends/gdx-audio/src/com/baglogic/gdx/audio/Test.java
new file mode 100644 (file)
index 0000000..47bde52
--- /dev/null
@@ -0,0 +1,54 @@
+\r
+package com.baglogic.gdx.audio;\r
+\r
+import com.badlogic.gdx.ApplicationListener;\r
+import com.badlogic.gdx.Gdx;\r
+import com.badlogic.gdx.backends.lwjgl.LwjglApplication;\r
+\r
+public class Test implements ApplicationListener {\r
+       public void create () {\r
+               final OpenALAudio audio = new OpenALAudio(8);\r
+\r
+               Thread thread = new Thread() {\r
+                       public void run () {\r
+                               while (true) {\r
+                                       audio.update();\r
+                                       try {\r
+                                               Thread.sleep(100);\r
+                                       } catch (InterruptedException ignored) {\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
+               thread.setDaemon(true);\r
+               thread.start();\r
+\r
+               // String path = "C:/Dev/libgdx/tests/gdx-tests-lwjgl/data/cloudconnected.ogg";\r
+               String path = "C:/Users/Nate/Desktop/reggae/10 - Rainbow In The Sky.mp3";\r
+\r
+               OpenALSound sound = audio.newSound(Gdx.files.absolute(path));\r
+               sound.play();\r
+\r
+               // OpenALMusic music = audio.newMusic(Gdx.files.absolute(path));\r
+               // music.play();\r
+       }\r
+\r
+       public void resize (int width, int height) {\r
+       }\r
+\r
+       public void render () {\r
+       }\r
+\r
+       public void resume () {\r
+       }\r
+\r
+       public void pause () {\r
+       }\r
+\r
+       public void dispose () {\r
+       }\r
+\r
+       public static void main (String[] args) throws Exception {\r
+               new LwjglApplication(new Test(), "Test", 480, 320, false);\r
+       }\r
+}\r