|
@@ -49,8 +49,6 @@ import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
import java.nio.ByteBuffer;
|
|
|
import java.util.Collection;
|
|
|
-import java.util.logging.Level;
|
|
|
-import java.util.logging.Logger;
|
|
|
|
|
|
public class OGGLoader implements AssetLoader {
|
|
|
|
|
@@ -66,9 +64,13 @@ public class OGGLoader implements AssetLoader {
|
|
|
private static class JOggInputStream extends InputStream {
|
|
|
|
|
|
private boolean endOfStream = false;
|
|
|
- protected final VorbisStream vs;
|
|
|
+ protected PhysicalOggStream ps;
|
|
|
+ protected LogicalOggStream ls;
|
|
|
+ protected VorbisStream vs;
|
|
|
|
|
|
- public JOggInputStream(VorbisStream vs){
|
|
|
+ public JOggInputStream(PhysicalOggStream ps, LogicalOggStream ls, VorbisStream vs){
|
|
|
+ this.ps = ps;
|
|
|
+ this.ls = ls;
|
|
|
this.vs = vs;
|
|
|
}
|
|
|
|
|
@@ -83,35 +85,34 @@ public class OGGLoader implements AssetLoader {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public int read(byte[] buf, int offset, int length) throws IOException{
|
|
|
- if (endOfStream)
|
|
|
+ public int read(byte[] buf, int offset, int length) throws IOException {
|
|
|
+ if (endOfStream) {
|
|
|
return -1;
|
|
|
+ }
|
|
|
|
|
|
int bytesRead = 0, cnt = 0;
|
|
|
assert length % 2 == 0; // read buffer should be even
|
|
|
-
|
|
|
- while (bytesRead <length) {
|
|
|
- if ((cnt = vs.readPcm(buf, offset + bytesRead,length - bytesRead)) <= 0) {
|
|
|
- System.out.println("Read "+cnt+" bytes");
|
|
|
- System.out.println("offset "+offset);
|
|
|
- System.out.println("bytesRead "+bytesRead);
|
|
|
- System.out.println("buf length "+length);
|
|
|
+
|
|
|
+ while (bytesRead < length) {
|
|
|
+ if ((cnt = vs.readPcm(buf, offset + bytesRead, length - bytesRead)) <= 0) {
|
|
|
+ System.out.println("Read " + cnt + " bytes");
|
|
|
+ System.out.println("offset " + offset);
|
|
|
+ System.out.println("bytesRead " + bytesRead);
|
|
|
+ System.out.println("buf length " + length);
|
|
|
for (int i = 0; i < bytesRead; i++) {
|
|
|
- System.out.print(buf[i]);
|
|
|
+ System.out.print(buf[i]);
|
|
|
}
|
|
|
System.out.println("");
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
System.out.println("EOS");
|
|
|
- endOfStream = true;
|
|
|
+ endOfStream = true;
|
|
|
break;
|
|
|
- }
|
|
|
- bytesRead += cnt;
|
|
|
- }
|
|
|
-
|
|
|
+ }
|
|
|
+ bytesRead += cnt;
|
|
|
+ }
|
|
|
+
|
|
|
swapBytes(buf, offset, bytesRead);
|
|
|
return bytesRead;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -122,30 +123,25 @@ public class OGGLoader implements AssetLoader {
|
|
|
}
|
|
|
|
|
|
private static class SeekableJOggInputStream extends JOggInputStream implements SeekableStream {
|
|
|
-
|
|
|
- private LogicalOggStream los;
|
|
|
- private float duration;
|
|
|
-
|
|
|
- public SeekableJOggInputStream(VorbisStream vs, LogicalOggStream los, float duration){
|
|
|
- super(vs);
|
|
|
- this.los = los;
|
|
|
- this.duration = duration;
|
|
|
+
|
|
|
+ public SeekableJOggInputStream(PhysicalOggStream ps, LogicalOggStream ls, VorbisStream vs){
|
|
|
+ super(ps, ls, vs);
|
|
|
}
|
|
|
|
|
|
public void setTime(float time) {
|
|
|
- System.out.println("--setTime--)");
|
|
|
- System.out.println("max granule : "+los.getMaximumGranulePosition());
|
|
|
- System.out.println("current granule : "+los.getTime());
|
|
|
- System.out.println("asked Time : "+time);
|
|
|
- System.out.println("new granule : "+(time/duration*los.getMaximumGranulePosition()));
|
|
|
- System.out.println("new granule2 : "+(time*vs.getIdentificationHeader().getSampleRate()));
|
|
|
-
|
|
|
-
|
|
|
+ if (time != 0.0) {
|
|
|
+ throw new UnsupportedOperationException("OGG/Vorbis seeking only supported for time = 0");
|
|
|
+ }
|
|
|
|
|
|
try {
|
|
|
- los.setTime((long)(time*vs.getIdentificationHeader().getSampleRate()));
|
|
|
+ // HACK: Reload the logical and vorbis streams from scratch
|
|
|
+ // based on the existing ogg page data.
|
|
|
+ // This fixes an audio discontinuity issue when looping
|
|
|
+ // an streaming OGG file via setTime(0).
|
|
|
+ ls = ((CachedOggStream) ps).reloadLogicalOggStream();
|
|
|
+ vs = new VorbisStream(ls);
|
|
|
} catch (IOException ex) {
|
|
|
- Logger.getLogger(OGGLoader.class.getName()).log(Level.SEVERE, null, ex);
|
|
|
+ ex.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -237,11 +233,11 @@ public class OGGLoader implements AssetLoader {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private InputStream readToStream(boolean seekable,float streamDuration){
|
|
|
- if(seekable){
|
|
|
- return new SeekableJOggInputStream(vorbisStream,loStream,streamDuration);
|
|
|
- }else{
|
|
|
- return new JOggInputStream(vorbisStream);
|
|
|
+ private InputStream readToStream(boolean seekable) {
|
|
|
+ if (seekable) {
|
|
|
+ return new SeekableJOggInputStream(oggStream, loStream, vorbisStream);
|
|
|
+ } else {
|
|
|
+ return new JOggInputStream(oggStream, loStream, vorbisStream);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -275,7 +271,7 @@ public class OGGLoader implements AssetLoader {
|
|
|
// might return -1 if unknown
|
|
|
float streamDuration = computeStreamDuration();
|
|
|
|
|
|
- audioStream.updateData(readToStream(oggStream.isSeekable(),streamDuration), streamDuration);
|
|
|
+ audioStream.updateData(readToStream(oggStream.isSeekable()), streamDuration);
|
|
|
return audioStream;
|
|
|
}
|
|
|
}
|
|
@@ -292,12 +288,7 @@ public class OGGLoader implements AssetLoader {
|
|
|
InputStream in = null;
|
|
|
try {
|
|
|
in = info.openStream();
|
|
|
- AudioData data = load(in, readStream, streamCache);
|
|
|
- if (data instanceof AudioStream){
|
|
|
- // audio streams must remain open
|
|
|
- in = null;
|
|
|
- }
|
|
|
- return data;
|
|
|
+ return load(in, readStream, streamCache);
|
|
|
} finally {
|
|
|
if (in != null){
|
|
|
in.close();
|