Beispiel #1
0
 /** @return -1 for lost packet, 0 not enough data, or 1 for success */
 private int processPacket(boolean readPage) {
   Page og = new Page();
   while (true) {
     if (decodeReady) {
       Packet op = new Packet();
       int result = os.packetout(op);
       if (result > 0) {
         int granulepos = (int) op.granulepos;
         if (vb.synthesis(op) == 0) {
           vd.synthesis_blockin(vb);
           if (granulepos != -1 && op.e_o_s == 0) {
             int samples = vd.synthesis_pcmout(null, null);
             granulepos -= samples;
             framePosition = granulepos;
           }
           return 1;
         }
       }
     }
     if (!readPage || getNextPage(og, -1) < 0) {
       return 0;
     }
     if (!decodeReady) {
       os.init(serialno);
       os.reset();
       vd.synthesis_init(info);
       vb.init(vd);
       decodeReady = true;
     }
     os.pagein(og);
   }
 }
Beispiel #2
0
 private void pcmOut() throws IOException {
   if (vorbisDspState == null) {
     mpcm = new float[1][][];
     mindex = new int[vorbisInfo.channels];
     vorbisDspState = new DspState();
     vorbisDspState.synthesis_init(vorbisInfo);
     vorbisBlock = new Block(vorbisDspState);
     sampleBuffer = new byte[BUFFER_SIZE * 2];
   }
   if (out == null) {
     openOutput();
   }
   if (vorbisBlock.synthesis(oggPacket) == 0) {
     vorbisDspState.synthesis_blockin(vorbisBlock);
   }
   int n;
   int[] idx = mindex;
   int nch = vorbisInfo.channels;
   int max = sampleBuffer.length;
   while ((n = vorbisDspState.synthesis_pcmout(mpcm, idx)) > 0) {
     int len = (n < max ? n : max);
     float[][] pcm = mpcm[0];
     int off = 0;
     for (int i = 0; i < len; i++) {
       for (int ch = 0; ch < nch; ch++) {
         int m = (int) (pcm[ch][idx[ch] + i] * SHORT_RANGE);
         if (m < Short.MIN_VALUE) {
           sampleBuffer[off++] = (byte) 0x00;
           sampleBuffer[off++] = (byte) 0x80;
         } else if (m > Short.MAX_VALUE) {
           sampleBuffer[off++] = (byte) 0xff;
           sampleBuffer[off++] = (byte) 0x7f;
         } else {
           short s = (short) m;
           sampleBuffer[off++] = (byte) s;
           sampleBuffer[off++] = (byte) (s >>> 8);
         }
       }
     }
     out.write(sampleBuffer, 0, 2 * nch * len);
     vorbisDspState.synthesis_read(len);
   }
 }
Beispiel #3
0
  public void decodeDsp(Packet packet) {
    if (block.synthesis(packet) == 0) {
      dsp.synthesis_blockin(block);
    }

    int samplesAvail;
    int channels = info.channels;
    while ((samplesAvail = dsp.synthesis_pcmout(pcmAll, index)) > 0) {
      float[][] pcm = pcmAll[0];
      int samplesCanRead = UNCOMP_BUFSIZE / (channels * 2);
      int samplesToRead = (samplesAvail < samplesCanRead ? samplesAvail : samplesCanRead);

      // convert floats to 16 bit signed ints and interleave
      for (int i = 0; i < channels; i++) {
        // each sample is two bytes, the sample for the 2nd
        // channel is at index 2, etc.
        int writeOff = i * 2;
        int readOff = index[i];
        for (int j = 0; j < samplesToRead; j++) {
          int val = (int) (pcm[i][readOff + j] * 32767.0);
          // guard against clipping
          if (val > 32767) {
            val = 32767;
          }
          if (val < -32768) {
            val = -32768;
          }
          uncompBuf[writeOff] = (byte) (val);
          uncompBuf[writeOff + 1] = (byte) (val >> 8);

          writeOff += 2 * channels; // each sample is 2 bytes
        }
      }

      ringBuffer.write(uncompBuf, 0, samplesToRead * channels * 2);

      // tell vorbis how many samples were actualy consumed
      dsp.synthesis_read(samplesToRead);
    }
  }
Beispiel #4
0
 /** @return number of frames skipped, or -1 on error. */
 private int skip(int numFrames) {
   if (state == State.INIT) {
     open();
   }
   if (state != State.OPEN) {
     return 0;
   }
   while (true) {
     if (decodeReady) {
       int frames = vd.synthesis_pcmout(_pcm, _index);
       if (frames != 0) {
         if (frames > numFrames) {
           frames = numFrames;
         }
         vd.synthesis_read(frames);
         framePosition += frames;
         return frames;
       }
     }
     if (processPacket(true) <= 0) {
       return -1;
     }
   }
 }
Beispiel #5
0
  public void decode(Packet packet) {
    if (packetIndex < 3) {
      if (info.synthesis_headerin(comment, packet) < 0) {
        // error case; not a Vorbis header
        System.err.println("does not contain Vorbis audio data.");
        return;
      }
      if (packetIndex == 2) {
        dsp.synthesis_init(info);
        block.init(dsp);
        System.out.println("vorbis: " + info);
        System.out.println(comment.toString());
        index = new int[info.channels];

        if (stream == null) {
          stream = new AudioStream();
          stream.setupFormat(info.channels, 16, info.rate);
          stream.updateData(this, -1);
        }

        if (masterClock instanceof SystemClock) {
          SystemClock clock = (SystemClock) masterClock;
          if (clock.needReset()) {
            clock.reset();
            System.out.println("Note: master clock was reset by audio");
          }
        }
      }
    } else {
      long gp = packet.granulepos;
      if (gp != -1) {
        lastPts = (gp * Clock.SECONDS_TO_NANOS) / info.rate;
        lastWritten = ringBuffer.getTotalWritten();
        lastRead = ringBuffer.getTotalRead();
        lastPtsWrite = System.nanoTime();
      }

      decodeDsp(packet);
    }
    packetIndex++;
  }
Beispiel #6
0
 /**
  * @param dest destination buffer
  * @param destOffset offset in the destination buffer
  * @param destChannels number of channels in the destination (either 1 or 2).
  * @param numFrames number of frames to read.
  * @return number of frames read, or -1 on error. Always fails if this Vorbis file has more than
  *     two channels.
  */
 public int read(byte[] dest, int destOffset, int destChannels, int numFrames) {
   if (state == State.INIT) {
     open();
   }
   if (state == State.INVALID) {
     return -1;
   } else if (state != State.OPEN) {
     return 0;
   }
   while (true) {
     if (decodeReady) {
       int frames = vd.synthesis_pcmout(_pcm, _index);
       if (frames != 0) {
         int channels = info.channels;
         if (frames > numFrames) {
           frames = numFrames;
         }
         if (destChannels == channels) {
           // Mono-to-mono or stereo-to-stereo
           int frameSize = 2 * channels;
           for (int i = 0; i < channels; i++) {
             int ptr = destOffset + 2 * i;
             int mono = _index[i];
             float[] pcm_row = _pcm[0][i];
             for (int j = 0; j < frames; j++) {
               int sample = (int) (pcm_row[mono + j] * 32767);
               if (sample > 32767) {
                 sample = 32767;
               } else if (sample < -32768) {
                 sample = -32768;
               }
               dest[ptr] = (byte) sample;
               dest[ptr + 1] = (byte) (sample >> 8);
               ptr += frameSize;
             }
           }
         } else if (channels == 1 && destChannels == 2) {
           // Mono-to-stereo
           int ptr = destOffset;
           int mono = _index[0];
           float[] pcm_row = _pcm[0][0];
           for (int j = 0; j < frames; j++) {
             int sample = (int) (pcm_row[mono + j] * 32767);
             if (sample > 32767) {
               sample = 32767;
             } else if (sample < -32768) {
               sample = -32768;
             }
             byte a = (byte) sample;
             byte b = (byte) (sample >> 8);
             dest[ptr++] = a;
             dest[ptr++] = b;
             dest[ptr++] = a;
             dest[ptr++] = b;
           }
         } else if (destChannels == 1) {
           // Mix all channels to 1 (not tested)
           for (int j = 0; j < frames * 2; j++) {
             dest[destOffset + j] = 0;
           }
           for (int i = 0; i < channels; i++) {
             int ptr = destOffset;
             int mono = _index[i];
             float[] pcm_row = _pcm[0][i];
             for (int j = 0; j < frames; j++) {
               int oldSample = (dest[ptr] & 255) | (dest[ptr + 1] << 8);
               int sample = (int) (oldSample + pcm_row[mono + j] * 32767 / channels);
               if (sample > 32767) {
                 sample = 32767;
               } else if (sample < -32768) {
                 sample = -32768;
               }
               dest[ptr++] = (byte) sample;
               dest[ptr++] = (byte) (sample >> 8);
             }
           }
         } else {
           return -1;
         }
         vd.synthesis_read(frames);
         framePosition += frames;
         return frames;
       }
     }
     if (processPacket(true) <= 0) {
       return -1;
     }
   }
 }
Beispiel #7
0
  /**
   * @return a negative number if not enough data available, 0 for failure or a positive number for
   *     success.
   */
  private int getHeaders(Info tempInfo, Comment tempComment) {
    Page og = new Page();
    Packet op = new Packet();
    boolean done = false;
    int packets = 0;

    // Parse the headers
    // Only interested in Vorbis stream
    while (!done) {
      int ret = getDataChunk();
      if (ret <= 0) {
        return ret;
      }
      while (oy.pageout(og) > 0) {
        StreamState test = new StreamState();

        // is this a mandated initial header? If not, stop parsing
        if (og.bos() == 0) {
          if (os != null) {
            os.pagein(og);
          }
          done = true;
          break;
        }

        int testSerialNo = og.serialno();
        test.init(testSerialNo);
        test.pagein(og);
        test.packetout(op);

        if (packets == 0 && tempInfo.synthesis_headerin(tempComment, op) >= 0) {
          os = test;
          serialno = testSerialNo;
          packets = 1;
        } else {
          // Ignore unknown stream
          test.clear();
        }
      }
    }

    if (packets == 0) {
      return 0;
    }

    // we've now identified all the bitstreams. parse the secondary header packets.
    while (packets < 3) {
      int ret;

      // look for more vorbis header packets
      while (packets < 3 && ((ret = os.packetout(op)) != 0)) {
        if (ret < 0 || tempInfo.synthesis_headerin(tempComment, op) != 0) {
          return 0;
        }
        packets++;
      }

      // The header pages/packets will arrive before anything else we
      // care about, or the stream is not obeying spec
      if (oy.pageout(og) > 0) {
        os.pagein(og);
      } else {
        ret = getDataChunk();
        if (ret <= 0) {
          return ret;
        }
      }
    }

    vd.synthesis_init(tempInfo);
    return 1;
  }
Beispiel #8
0
  public void run() {
    if (Thread.currentThread() != this) {
      throw new IllegalStateException("not this thread");
    }
    try {
      SyncState syncState = this.oggSyncState = new SyncState();
      while (in != null) {
        int off = syncState.buffer(BUFFER_SIZE);
        int n = in.read(syncState.data, off, BUFFER_SIZE);
        if (n > 0) {
          syncState.wrote(n);
          pageOut();
        } else {
          break;
        }
      }
    } catch (EOFException e) {

    } catch (IOException e) {
      failure = e;
      e.printStackTrace();
    } finally {
      try {
        if (in != null) {
          in.close();
          in = null;
        }
      } catch (IOException e) {
        if (failure != null) {
          failure = e;
        }
        e.printStackTrace();
      }
      if (out != null) {
        out.stop();
        out.close();
      }
      if (vorbisBlock != null) {
        vorbisBlock.clear();
        vorbisBlock = null;
      }
      if (vorbisDspState != null) {
        vorbisDspState.clear();
        vorbisDspState = null;
      }
      if (vorbisInfo != null) {
        vorbisInfo.clear();
        vorbisInfo = null;
      }
      if (oggStreamState != null) {
        oggStreamState.clear();
        oggStreamState = null;
      }
      if (oggSyncState != null) {
        oggSyncState.clear();
        oggSyncState = null;
      }
      synchronized (this) {
        notifyAll();
      }
    }
  }
Beispiel #9
0
  /*
   * Taken from the JOrbis Player
   */
  private void playStream(Thread me) throws InternalException {
    boolean chained = false;

    initJOrbis();

    while (true) {
      if (checkState()) {
        return;
      }

      int eos = 0;

      int index = oy.buffer(BUFSIZE);
      buffer = oy.data;
      try {
        bytes = bitStream.read(buffer, index, BUFSIZE);
      } catch (Exception e) {
        throw new InternalException(e);
      }
      oy.wrote(bytes);

      if (chained) {
        chained = false;
      } else {
        if (oy.pageout(og) != 1) {
          if (bytes < BUFSIZE) break;
          throw new InternalException("Input does not appear to be an Ogg bitstream.");
        }
      }
      os.init(og.serialno());
      os.reset();

      vi.init();
      vc.init();

      if (os.pagein(og) < 0) {
        // error; stream version mismatch perhaps
        throw new InternalException("Error reading first page of Ogg bitstream data.");
      }

      if (os.packetout(op) != 1) {
        // no page? must not be vorbis
        throw new InternalException("Error reading initial header packet.");
      }

      if (vi.synthesis_headerin(vc, op) < 0) {
        // error case; not a vorbis header
        throw new InternalException("This Ogg bitstream does not contain Vorbis audio data.");
      }

      int i = 0;

      while (i < 2) {
        while (i < 2) {
          if (checkState()) {
            return;
          }

          int result = oy.pageout(og);
          if (result == 0) break; // Need more data
          if (result == 1) {
            os.pagein(og);
            while (i < 2) {
              result = os.packetout(op);
              if (result == 0) break;
              if (result == -1) {
                throw new InternalException("Corrupt secondary header.  Exiting.");
              }
              vi.synthesis_headerin(vc, op);
              i++;
            }
          }
        }

        index = oy.buffer(BUFSIZE);
        buffer = oy.data;
        try {
          bytes = bitStream.read(buffer, index, BUFSIZE);
        } catch (Exception e) {
          throw new InternalException(e);
        }
        if (bytes == 0 && i < 2) {
          throw new InternalException("End of file before finding all Vorbis headers!");
        }
        oy.wrote(bytes);
      }

      convsize = BUFSIZE / vi.channels;

      vd.synthesis_init(vi);
      vb.init(vd);

      float[][][] _pcmf = new float[1][][];
      int[] _index = new int[vi.channels];

      getOutputLine(vi.channels, vi.rate);

      while (eos == 0) {
        while (eos == 0) {
          if (player != me) {
            return;
          }

          int result = oy.pageout(og);
          if (result == 0) break; // need more data
          if (result == -1) { // missing or corrupt data at this page
            // position
            // System.err.println("Corrupt or missing data in
            // bitstream;
            // continuing...");
          } else {
            os.pagein(og);

            if (og.granulepos() == 0) { //
              chained = true; //
              eos = 1; //
              break; //
            } //

            while (true) {
              if (checkState()) {
                return;
              }

              result = os.packetout(op);
              if (result == 0) break; // need more data
              if (result == -1) { // missing or corrupt data at
                // this page position
                // no reason to complain; already complained
                // above

                // System.err.println("no reason to complain;
                // already complained above");
              } else {
                // we have a packet. Decode it
                int samples;
                if (vb.synthesis(op) == 0) { // test for
                  // success!
                  vd.synthesis_blockin(vb);
                }
                while ((samples = vd.synthesis_pcmout(_pcmf, _index)) > 0) {
                  if (checkState()) {
                    return;
                  }

                  float[][] pcmf = _pcmf[0];
                  int bout = (samples < convsize ? samples : convsize);

                  // convert doubles to 16 bit signed ints
                  // (host order) and
                  // interleave
                  for (i = 0; i < vi.channels; i++) {
                    int ptr = i * 2;
                    // int ptr=i;
                    int mono = _index[i];
                    for (int j = 0; j < bout; j++) {
                      int val = (int) (pcmf[i][mono + j] * 32767.);
                      if (val > 32767) {
                        val = 32767;
                      }
                      if (val < -32768) {
                        val = -32768;
                      }
                      if (val < 0) val = val | 0x8000;
                      convbuffer[ptr] = (byte) (val);
                      convbuffer[ptr + 1] = (byte) (val >>> 8);
                      ptr += 2 * (vi.channels);
                    }
                  }
                  outputLine.write(convbuffer, 0, 2 * vi.channels * bout);
                  vd.synthesis_read(bout);
                }
              }
            }
            if (og.eos() != 0) eos = 1;
          }
        }

        if (eos == 0) {
          index = oy.buffer(BUFSIZE);
          buffer = oy.data;
          try {
            bytes = bitStream.read(buffer, index, BUFSIZE);
          } catch (Exception e) {
            throw new InternalException(e);
          }
          if (bytes == -1) {
            break;
          }
          oy.wrote(bytes);
          if (bytes == 0) eos = 1;
        }
      }

      os.clear();
      vb.clear();
      vd.clear();
      vi.clear();
    }

    oy.clear();
  }