예제 #1
0
  /**
   * Open callbacks.
   *
   * @param is input stream
   * @param initial initial bytes
   * @param ibytes initial count
   * @return success flag
   * @throws JOrbisException if an error occurs
   */
  int openCallbacks(InputStream is, byte[] initial, int ibytes) throws JOrbisException {
    int ret;
    datasource = is;

    oy.init();

    // perhaps some data was previously read into a buffer for testing
    // against other stream types. Allow initialization from this
    // previously read data (as we may be reading from a non-seekable
    // stream)
    if (initial != null) {
      int index = oy.buffer(ibytes);
      System.arraycopy(initial, 0, oy.data, index, ibytes);
      oy.wrote(ibytes);
    }
    // can we seek? Stevens suggests the seek test was portable
    if (is instanceof SeekableInputStream) {
      ret = openSeekable();
    } else {
      ret = openNonseekable();
    }
    if (ret != 0) {
      datasource = null;
      clear();
    }
    return ret;
  }
예제 #2
0
 /**
  * Get the data.
  *
  * @return the number of bytes read
  */
 private int getData() {
   int index = oy.buffer(CHUNKSIZE);
   byte[] buffer = oy.data;
   int bytes = 0;
   try {
     bytes = datasource.read(buffer, index, CHUNKSIZE);
   } catch (Exception e) {
     return OV_EREAD;
   }
   oy.wrote(bytes);
   if (bytes == -1) {
     bytes = 0;
   }
   return bytes;
 }
예제 #3
0
  private void pageOut() throws IOException {
    if (oggPage == null) {
      oggPage = new Page();
    }

    for (; ; ) {
      switch (oggSyncState.pageout(oggPage)) {
        case 0:
          return;
        case 1:
          if (oggStreamState == null) {
            oggStreamState = new StreamState();
            oggStreamState.init(oggPage.serialno());
            oggStreamState.reset();
          }
          if (oggStreamState.pagein(oggPage) < 0) {
            throw new IOException("error reading ogg page");
          } else {
            packetOut();
            if (oggPage.eos() != 0) {
              throw new EOFException();
            }
          }
          break;
        default:
          throw new IOException("ogg input format error");
      }
    }
  }
예제 #4
0
 /**
  * Get next page.
  *
  * @param page the page
  * @param boundary the boundary
  * @return the offset or error code OV_*
  */
 private int getNextPage(Page page, long boundary) {
   if (boundary > 0) {
     boundary += offset;
   }
   while (true) {
     int more;
     if (boundary > 0 && offset >= boundary) {
       return OV_FALSE;
     }
     more = oy.pageseek(page);
     if (more < 0) {
       offset -= more;
     } else {
       if (more == 0) {
         if (boundary == 0) {
           return OV_FALSE;
         }
         int ret = getData();
         if (ret == 0) {
           return OV_EOF;
         }
         if (ret < 0) {
           return OV_EREAD;
         }
       } else {
         int ret = (int) offset; // !!!
         offset += more;
         return ret;
       }
     }
   }
 }
 /** Initializes all the jOrbis and jOgg vars that are used for song playback. */
 private void init_jorbis() {
   oggSyncState_ = new SyncState();
   oggStreamState_ = new StreamState();
   oggPage_ = new Page();
   oggPacket_ = new Packet();
   vorbisInfo = new Info();
   vorbisComment = new Comment();
   vorbisDspState = new DspState();
   vorbisBlock = new Block(vorbisDspState);
   buffer = null;
   bytes = 0;
   oggSyncState_.init();
 }
예제 #6
0
  /*
   * Taken from the JOrbis Player
   */
  private void initJOrbis() {
    oy = new SyncState();
    os = new StreamState();
    og = new Page();
    op = new Packet();

    vi = new Info();
    vc = new Comment();
    vd = new DspState();
    vb = new Block(vd);

    buffer = null;
    bytes = 0;

    oy.init();
  }
예제 #7
0
  /**
   * The helpers are over; it's all toplevel interface from here on out clear out the OggVorbis_File
   * struct.
   */
  void clear() {
    vb.clear();
    vd.clear();
    os.clear();

    if (vi != null && links != 0) {
      for (int i = 0; i < links; i++) {
        vi[i].clear();
        vc[i].clear();
      }
      vi = null;
      vc = null;
    }
    dataoffsets = null;
    pcmlengths = null;
    serialnos = null;
    offsets = null;
    oy.clear();
  }
예제 #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();
      }
    }
  }
예제 #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();
  }
 /** Reads headers and comments. */
 private void readHeaders(HashMap aff_properties, HashMap af_properties) throws IOException {
   if (TDebug.TraceAudioConverter) TDebug.out("readHeaders(");
   index = oggSyncState_.buffer(bufferSize_);
   buffer = oggSyncState_.data;
   bytes = readFromStream(buffer, index, bufferSize_);
   if (bytes == -1) {
     if (TDebug.TraceAudioConverter)
       TDebug.out("Cannot get any data from selected Ogg bitstream.");
     throw new IOException("Cannot get any data from selected Ogg bitstream.");
   }
   oggSyncState_.wrote(bytes);
   if (oggSyncState_.pageout(oggPage_) != 1) {
     if (bytes < bufferSize_) {
       throw new IOException("EOF");
     }
     if (TDebug.TraceAudioConverter) TDebug.out("Input does not appear to be an Ogg bitstream.");
     throw new IOException("Input does not appear to be an Ogg bitstream.");
   }
   oggStreamState_.init(oggPage_.serialno());
   vorbisInfo.init();
   vorbisComment.init();
   aff_properties.put("ogg.serial", new Integer(oggPage_.serialno()));
   if (oggStreamState_.pagein(oggPage_) < 0) {
     // error; stream version mismatch perhaps
     if (TDebug.TraceAudioConverter) TDebug.out("Error reading first page of Ogg bitstream data.");
     throw new IOException("Error reading first page of Ogg bitstream data.");
   }
   if (oggStreamState_.packetout(oggPacket_) != 1) {
     // no page? must not be vorbis
     if (TDebug.TraceAudioConverter) TDebug.out("Error reading initial header packet.");
     throw new IOException("Error reading initial header packet.");
   }
   if (vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_) < 0) {
     // error case; not a vorbis header
     if (TDebug.TraceAudioConverter)
       TDebug.out("This Ogg bitstream does not contain Vorbis audio data.");
     throw new IOException("This Ogg bitstream does not contain Vorbis audio data.");
   }
   int i = 0;
   while (i < 2) {
     while (i < 2) {
       int result = oggSyncState_.pageout(oggPage_);
       if (result == 0) {
         break;
       } // Need more data
       if (result == 1) {
         oggStreamState_.pagein(oggPage_);
         while (i < 2) {
           result = oggStreamState_.packetout(oggPacket_);
           if (result == 0) {
             break;
           }
           if (result == -1) {
             if (TDebug.TraceAudioConverter) TDebug.out("Corrupt secondary header.  Exiting.");
             throw new IOException("Corrupt secondary header.  Exiting.");
           }
           vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_);
           i++;
         }
       }
     }
     index = oggSyncState_.buffer(bufferSize_);
     buffer = oggSyncState_.data;
     bytes = readFromStream(buffer, index, bufferSize_);
     if (bytes == -1) {
       break;
     }
     if (bytes == 0 && i < 2) {
       if (TDebug.TraceAudioConverter)
         TDebug.out("End of file before finding all Vorbis headers!");
       throw new IOException("End of file before finding all Vorbis  headers!");
     }
     oggSyncState_.wrote(bytes);
   }
   // Read Ogg Vorbis comments.
   byte[][] ptr = vorbisComment.user_comments;
   String currComment = "";
   int c = 0;
   for (int j = 0; j < ptr.length; j++) {
     if (ptr[j] == null) {
       break;
     }
     currComment = (new String(ptr[j], 0, ptr[j].length - 1, "UTF-8")).trim();
     if (TDebug.TraceAudioConverter) TDebug.out(currComment);
     if (currComment.toLowerCase().startsWith("artist")) {
       aff_properties.put("author", currComment.substring(7));
     } else if (currComment.toLowerCase().startsWith("title")) {
       aff_properties.put("title", currComment.substring(6));
     } else if (currComment.toLowerCase().startsWith("album")) {
       aff_properties.put("album", currComment.substring(6));
     } else if (currComment.toLowerCase().startsWith("date")) {
       aff_properties.put("date", currComment.substring(5));
     } else if (currComment.toLowerCase().startsWith("copyright")) {
       aff_properties.put("copyright", currComment.substring(10));
     } else if (currComment.toLowerCase().startsWith("comment")) {
       aff_properties.put("comment", currComment.substring(8));
     } else if (currComment.toLowerCase().startsWith("genre")) {
       aff_properties.put("ogg.comment.genre", currComment.substring(6));
     } else if (currComment.toLowerCase().startsWith("tracknumber")) {
       aff_properties.put("ogg.comment.track", currComment.substring(12));
     } else {
       c++;
       aff_properties.put("ogg.comment.ext." + c, currComment);
     }
     aff_properties.put(
         "ogg.comment.encodedby",
         new String(vorbisComment.vendor, 0, vorbisComment.vendor.length - 1));
   }
 }
예제 #11
0
 /**
  * Seek helper function.
  *
  * @param offst the offset to seek
  */
 private void seekHelper(long offst) {
   fseek(datasource, offst, SEEK_SET);
   this.offset = offst;
   oy.reset();
 }