Java AudioInputStream how to support skip with negative number of bytes

后端 未结 2 1964
悲&欢浪女
悲&欢浪女 2021-01-24 00:47

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

相关标签:
2条回答
  • 2021-01-24 00:55

    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!

    0 讨论(0)
  • 2021-01-24 01:00

    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); }
    }
    
    0 讨论(0)
提交回复
热议问题