I am trying to skip a negative number of bytes with AudioInputStream
skip(long bytes)
method .
The problem is trying to (let\'s say a small nu
Use your own buffer which holds a rolling window of history. I'd build a helper class that does this by allocating a List<byte[]>
to manage history in blocks of for example 8192 bytes. Then you need some simple overflowing mechanism that throws out the oldest block, in combination with some pointer manipulation to keep track of where you actually are in the stream. Good luck!
You can create your own buffer, It could be ByteArrayOutputStream but that is a bloated thing - always gives me Out of memory after a couple of minutes - or have your own Vector or other ArrayList.
I tried with a 10 min .wav file and it runs fine - as far as playing and adding the bytes to the buffer.
e.g.
Vector v=new Vector();
byte[] data=new byte[basicU];
while(true) {
k=audioInputStream.read(data, 0, data.length);
v.add(data);
if(k<0) break;
tot+=k;
}
--
Here is my method for playing a file with seeks. I have a thread for generating seek signals. The problem is complicated when we have multiple seeks. I use a variable K to check whether we need to add data to the buffer. I don't use skip but normal read; just don't play it in the line.
public void play() {
boolean seekingBack=false;
int i, j, k=0, seekPos=0, basicU=1024;
AudioFormat targetFormat=null;
int tot=0;
new Thread() {
public void run() {
while(true) {
numBytes=(Math.random()>0.5?1:-1)*500000;
try { Thread.sleep(5000); } catch (Exception e) {}
seekSignal=true;
}
}}.start();
try {
File fileIn=new File("........");
AudioInputStream audioInputStream=AudioSystem.getAudioInputStream(fileIn);
targetFormat=audioInputStream.getFormat();
DataLine.Info dinfo=new DataLine.Info(SourceDataLine.class, targetFormat);
SourceDataLine line=null;
line=(SourceDataLine)AudioSystem.getLine(dinfo);
if(line==null) return;
line.open(targetFormat);
line.start();
Vector v=new Vector();
byte[] data=new byte[basicU];
int K=0;
while(true) {
if(seekingBack) { // seeking backwards
K=seekPos;
k=data.length;
for(j=0; j<data.length; j++)
if(seekPos+j<v.size()) data[j]=((Byte)v.get(seekPos+j)).byteValue();
else { k=j; break; }
line.write(data, 0, k);
seekPos+=k;
K+=k;
if(seekPos>v.size()-1) seekingBack=false;
}
else { // normal playing
k=audioInputStream.read(data, 0, data.length);
if(k<0) break;
line.write(data, 0, k);
if(K>=v.size()) for(j=0; j<k; j++) v.add(data[j]);
K+=k;
}
if(seekSignal) { // received a seek signal
if(seekingBack) { // we are on a previous back seek - reading from the buffer
if(numBytes<0) {
seekPos+=numBytes;
if(seekPos<0) seekPos=0;
}
else { // depending on where the seek will go (in the buffer or actual audio stream)
if(numBytes+seekPos<v.size())
seekPos+=numBytes;
else { // actual stream
int rem=numBytes-(v.size()-seekPos);
K=v.size();
while(rem>0) {
k=audioInputStream.read(data, 0, data.length);
if(k<0) break;
if(K>=v.size()) for(j=0; j<k; j++) v.add(data[j]);
rem-=k;
K+=k;
}
}
}
}
else { // we are not processing a previous back seek
if(numBytes>=0) { // forward
while(numBytes>0) {
k=audioInputStream.read(data, 0, data.length);
if(k<0) break;
if(K>=v.size()) for(j=0; j<k; j++) v.add(data[j]);
numBytes-=k;
K+=k;
}
}
else { // backward
seekingBack=true; seekPos=v.size()+numBytes; if(seekPos<0) seekPos=0; }
}
seekSignal=false;
}
}
line.stop();
line.close();
}
catch(Exception ex) { ex.printStackTrace(); System.out.println("audio problem "+ex); }
}