瀏覽代碼

WAVLoader now implements SeekableStream (but only if seeking to time = 0)

shadowislord 10 年之前
父節點
當前提交
ad2a5366e1

+ 2 - 2
jme3-core/src/main/java/com/jme3/util/LittleEndien.java

@@ -41,8 +41,8 @@ import java.io.*;
  */
 public class LittleEndien extends InputStream implements DataInput {
 
-    private BufferedInputStream in;
-    private BufferedReader inRead;
+    protected BufferedInputStream in;
+    protected BufferedReader inRead;
 
     /**
      * Creates a new LittleEndien reader from the given input stream.  The

+ 50 - 6
jme3-core/src/plugins/java/com/jme3/audio/plugins/WAVLoader.java

@@ -37,8 +37,10 @@ import com.jme3.audio.AudioBuffer;
 import com.jme3.audio.AudioData;
 import com.jme3.audio.AudioKey;
 import com.jme3.audio.AudioStream;
+import com.jme3.audio.SeekableStream;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.LittleEndien;
+import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
@@ -63,7 +65,41 @@ public class WAVLoader implements AssetLoader {
     private int bytesPerSec;
     private float duration;
 
-    private LittleEndien in;
+    private ResettableInputStream in;
+    private int inOffset = 0;
+    
+    private static class ResettableInputStream extends LittleEndien implements SeekableStream {
+        
+        private AssetInfo info;
+        private int resetOffset = 0;
+        
+        public ResettableInputStream(AssetInfo info, InputStream in) {
+            super(in);
+            this.info = info;
+        }
+        
+        public void setResetOffset(int resetOffset) {
+            this.resetOffset = resetOffset;
+        }
+
+        public void setTime(float time) {
+            if (time != 0f) {
+                throw new UnsupportedOperationException("Seeking WAV files not supported");
+            }
+            InputStream newStream = info.openStream();
+            try {
+                newStream.skip(resetOffset);
+                this.in = new BufferedInputStream(newStream);
+            } catch (IOException ex) {
+                // Resource could have gotten lost, etc.
+                try {
+                    newStream.close();
+                } catch (IOException ex2) {
+                }
+                throw new RuntimeException(ex);
+            }
+        }
+    }
 
     private void readFormatChunk(int size) throws IOException{
         // if other compressions are supported, size doesn't have to be 16
@@ -118,12 +154,14 @@ public class WAVLoader implements AssetLoader {
         in.close();
     }
 
-    private void readDataChunkForStream(int len) throws IOException {
+    private void readDataChunkForStream(int offset, int len) throws IOException {
+        in.setResetOffset(offset);
         audioStream.updateData(in, duration);
     }
 
-    private AudioData load(InputStream inputStream, boolean stream) throws IOException{
-        this.in = new LittleEndien(inputStream);
+    private AudioData load(AssetInfo info, InputStream inputStream, boolean stream) throws IOException{
+        this.in = new ResettableInputStream(info, inputStream);
+        inOffset = 0;
         
         int sig = in.readInt();
         if (sig != i_RIFF)
@@ -134,6 +172,8 @@ public class WAVLoader implements AssetLoader {
         if (in.readInt() != i_WAVE)
             throw new IOException("WAVE File does not contain audio");
 
+        inOffset += 4 * 3;
+        
         readStream = stream;
         if (readStream){
             audioStream = new AudioStream();
@@ -146,17 +186,20 @@ public class WAVLoader implements AssetLoader {
         while (true) {
             int type = in.readInt();
             int len = in.readInt();
+            
+            inOffset += 4 * 2;
 
             switch (type) {
                 case i_fmt:
                     readFormatChunk(len);
+                    inOffset += len;
                     break;
                 case i_data:
                     // Compute duration based on data chunk size
                     duration = len / bytesPerSec;
 
                     if (readStream) {
-                        readDataChunkForStream(len);
+                        readDataChunkForStream(inOffset, len);
                     } else {
                         readDataChunkForBuffer(len);
                     }
@@ -166,6 +209,7 @@ public class WAVLoader implements AssetLoader {
                     if (skipped <= 0) {
                         return null;
                     }
+                    inOffset += skipped;
                     break;
             }
         }
@@ -176,7 +220,7 @@ public class WAVLoader implements AssetLoader {
         InputStream inputStream = null;
         try {
             inputStream = info.openStream();
-            data = load(inputStream, ((AudioKey)info.getKey()).isStream());
+            data = load(info, inputStream, ((AudioKey)info.getKey()).isStream());
             if (data instanceof AudioStream){
                 inputStream = null;
             }