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

experimental
shadowislord 10 years ago
parent 4e04f4629a
commit ad2a5366e1
  1. 4
      jme3-core/src/main/java/com/jme3/util/LittleEndien.java
  2. 56
      jme3-core/src/plugins/java/com/jme3/audio/plugins/WAVLoader.java

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

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

Loading…
Cancel
Save