001/* JOrbis
002 * Copyright (C) 2000 ymnk, JCraft,Inc.
003 *  
004 * Written by: 2000 ymnk<ymnk@jcaft.com>
005 *   
006 * Many thanks to 
007 *   Monty <monty@xiph.org> and 
008 *   The XIPHOPHORUS Company http://www.xiph.org/ .
009 * JOrbis has been based on their awesome works, Vorbis codec.
010 *   
011 * This program is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Library General Public License
013 * as published by the Free Software Foundation; either version 2 of
014 * the License, or (at your option) any later version.
015   
016 * This program is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 * GNU Library General Public License for more details.
020 * 
021 * You should have received a copy of the GNU Library General Public
022 * License along with this program; if not, write to the Free Software
023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
024 */
025
026package com.jcraft.jorbis;
027
028import com.jcraft.jogg.*;
029import java.io.InputStream;
030
031public class VorbisFile{
032  static final int CHUNKSIZE=8500;
033  static final int SEEK_SET=0;
034  static final int SEEK_CUR=1;
035  static final int SEEK_END=2;
036
037  static final int OV_FALSE=-1;
038  static final int OV_EOF=-2;
039  static final int OV_HOLE=-3;
040
041  static final int OV_EREAD=-128;
042  static final int OV_EFAULT=-129;
043  static final int OV_EIMPL=-130;
044  static final int OV_EINVAL=-131;
045  static final int OV_ENOTVORBIS=-132;
046  static final int OV_EBADHEADER=-133;
047  static final int OV_EVERSION=-134;
048  static final int OV_ENOTAUDIO=-135;
049  static final int OV_EBADPACKET=-136;
050  static final int OV_EBADLINK=-137;
051  static final int OV_ENOSEEK=-138;
052
053  InputStream datasource;
054  boolean seekable=false;
055  long offset;
056  long end;
057  
058  SyncState oy=new SyncState();
059
060  int links;
061  long[] offsets;
062  long[] dataoffsets;
063  int[] serialnos;
064  long[] pcmlengths;
065  Info[] vi;
066  Comment[] vc;
067
068  // Decoding working state local storage
069  long pcm_offset;
070  boolean decode_ready=false;
071  int current_serialno;
072  int current_link;
073
074  float bittrack;
075  float samptrack;
076
077  StreamState os=new StreamState(); // take physical pages, weld into a logical
078                                    // stream of packets
079  DspState vd=new DspState(); // central working state for 
080                              // the packet->PCM decoder
081  Block vb=new Block(vd);     // local working space for packet->PCM decode
082
083  //ov_callbacks callbacks;
084
085  public VorbisFile(String file) throws JOrbisException {
086    super();
087    InputStream is=null;
088    /*
089    try{ is=new java.io.FileInputStream(file);}
090    catch(Exception e){
091      throw new JOrbisException("VorbisFile: "+e.toString());
092    }
093    */
094    try{ is=new SeekableInputStream(file);}
095    catch(Exception e){
096      throw new JOrbisException("VorbisFile: "+e.toString());
097    }
098    int ret=open(is, null, 0);
099    if(ret==-1){
100      throw new JOrbisException("VorbisFile: open return -1");
101    }
102  }
103
104  public VorbisFile(InputStream is, byte[] initial, int ibytes)
105    throws JOrbisException {
106    super();
107    int ret=open(is, initial, ibytes);
108    if(ret==-1){
109    }
110  }
111
112  private int get_data(){
113    int index=oy.buffer(CHUNKSIZE);
114    byte[] buffer=oy.data;
115//  int bytes=callbacks.read_func(buffer, index, 1, CHUNKSIZE, datasource);
116    int bytes=0;
117    try{
118      bytes=datasource.read(buffer, index, CHUNKSIZE);
119    }
120    catch(Exception e){
121      System.err.println(e);
122      return OV_EREAD;
123    }
124    oy.wrote(bytes);
125    if(bytes==-1){
126//      System.out.println("bytes="+bytes);
127      bytes=0;
128    }
129    return bytes;
130  }
131
132  private void seek_helper(long offst){
133    //callbacks.seek_func(datasource, offst, SEEK_SET);
134    fseek(datasource, offst, SEEK_SET);
135    this.offset=offst;
136    oy.reset();
137  }
138
139  private int get_next_page(Page page, long boundary){
140    if(boundary>0) boundary+=offset;
141    while(true){
142      int more;
143      if(boundary>0 && offset>=boundary)return OV_FALSE;
144      more=oy.pageseek(page);
145      if(more<0){offset-=more;}
146      else{
147        if(more==0){
148          if(boundary==0)return OV_FALSE;
149//        if(get_data()<=0)return -1;
150          int ret=get_data();
151          if(ret==0) return OV_EOF;
152          if(ret<0) return OV_EREAD; 
153        }
154        else{
155          int ret=(int)offset; //!!!
156          offset+=more;
157          return ret;
158        }
159      }
160    }
161  }
162
163  private int get_prev_page(Page page){
164    long begin=offset; //!!!
165    int ret;
166    int offst=-1;
167    while(offst==-1){
168      begin-=CHUNKSIZE;
169      if(begin<0)
170        begin=0;
171      seek_helper(begin);
172      while(offset<begin+CHUNKSIZE){
173        ret=get_next_page(page, begin+CHUNKSIZE-offset);
174        if(ret==OV_EREAD){ return OV_EREAD; }
175        if(ret<0){ break; }
176        else{ offst=ret; }
177      }
178    }
179    seek_helper(offst); //!!!
180    ret=get_next_page(page, CHUNKSIZE);
181    if(ret<0){
182      //System.err.println("Missed page fencepost at end of logical bitstream Exiting");
183      //System.exit(1);
184      return OV_EFAULT;
185    }
186    return offst;
187  }
188
189  int bisect_forward_serialno(long begin, long searched, long end, int currentno, int m){
190    long endsearched=end;
191    long next=end;
192    Page page=new Page();
193    int ret;
194
195    while(searched<endsearched){
196      long bisect;
197      if(endsearched-searched<CHUNKSIZE){
198        bisect=searched;
199      }
200      else{
201        bisect=(searched+endsearched)/2;
202      }
203
204      seek_helper(bisect);
205      ret=get_next_page(page, -1);
206      if(ret==OV_EREAD) return OV_EREAD;
207      if(ret<0 || page.serialno()!=currentno){
208        endsearched=bisect;
209        if(ret>=0)next=ret;
210      }
211      else{
212        searched=ret+page.header_len+page.body_len;
213      }
214    }
215    seek_helper(next);
216    ret=get_next_page(page, -1);
217    if(ret==OV_EREAD) return OV_EREAD;
218
219    if(searched>=end || ret==-1){
220      links=m+1;
221      offsets=new long[m+2];
222      offsets[m+1]=searched;
223    }
224    else{
225      ret=bisect_forward_serialno(next, offset, end, page.serialno(), m+1);
226      if(ret==OV_EREAD)return OV_EREAD;
227    }
228    offsets[m]=begin;
229    return 0;  
230  }
231
232  // uses the local ogg_stream storage in vf; this is important for
233  // non-streaming input sources
234  int fetch_headers(Info vi, Comment vc, int[] serialno, Page og_ptr){
235    //System.err.println("fetch_headers");
236    Page og=new Page();
237    Packet op=new Packet();
238    int ret;
239
240    if(og_ptr==null){
241      ret=get_next_page(og, CHUNKSIZE);
242      if(ret==OV_EREAD)return OV_EREAD;
243      if(ret<0) return OV_ENOTVORBIS;
244      og_ptr=og;
245    }
246  
247    if(serialno!=null)serialno[0]=og_ptr.serialno();
248
249    os.init(og_ptr.serialno());
250  
251    // extract the initial header from the first page and verify that the
252    // Ogg bitstream is in fact Vorbis data
253  
254    vi.init();
255    vc.init();
256  
257    int i=0;
258    while(i<3){
259      os.pagein(og_ptr);
260      while(i<3){
261        int result=os.packetout(op);
262        if(result==0)break;
263        if(result==-1){
264          System.err.println("Corrupt header in logical bitstream.");
265          //goto bail_header;
266          vi.clear();
267          vc.clear();
268          os.clear();
269           return -1;
270        }
271        if(vi.synthesis_headerin(vc, op)!=0){
272          System.err.println("Illegal header in logical bitstream.");
273          //goto bail_header;
274          vi.clear();
275          vc.clear();
276          os.clear();
277          return -1;
278        }
279        i++;
280      }
281      if(i<3)
282        if(get_next_page(og_ptr, 1)<0){
283          System.err.println("Missing header in logical bitstream.");
284          //goto bail_header;
285          vi.clear();
286          vc.clear();
287          os.clear();
288          return -1;
289        }
290    }
291    return 0; 
292
293//  bail_header:
294//    vorbis_info_clear(vi);
295//    vorbis_comment_clear(vc);
296//    ogg_stream_clear(&vf->os);
297//    return -1;
298  }
299
300  // last step of the OggVorbis_File initialization; get all the
301  // vorbis_info structs and PCM positions.  Only called by the seekable
302  // initialization (local stream storage is hacked slightly; pay
303  // attention to how that's done)
304  void prefetch_all_headers(Info first_i,Comment first_c, int dataoffset){
305    Page og=new Page();
306    int ret;
307  
308    vi=new Info[links];
309    vc=new Comment[links];
310    dataoffsets=new long[links];
311    pcmlengths=new long[links];
312    serialnos=new int[links];
313  
314    for(int i=0;i<links;i++){
315      if(first_i!=null && first_c!=null && i==0){
316        // we already grabbed the initial header earlier.  This just
317        // saves the waste of grabbing it again
318        // !!!!!!!!!!!!!
319        vi[i]=first_i;
320        //memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
321        vc[i]=first_c;
322        //memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
323        dataoffsets[i]=dataoffset;
324      }
325      else{
326        // seek to the location of the initial header
327        seek_helper(offsets[i]); //!!!
328        if(fetch_headers(vi[i], vc[i], null, null)==-1){
329          System.err.println("Error opening logical bitstream #"+(i+1)+"\n");
330          dataoffsets[i]=-1;
331        }
332        else{
333          dataoffsets[i]=offset;
334          os.clear();
335        }
336      }
337
338      // get the serial number and PCM length of this link. To do this,
339      // get the last page of the stream
340      {
341        long end=offsets[i+1]; //!!!
342        seek_helper(end);
343
344        while(true){
345          ret=get_prev_page(og);
346          if(ret==-1){
347            // this should not be possible
348            System.err.println("Could not find last page of logical "+
349                               "bitstream #"+(i)+"\n");
350            vi[i].clear();
351            vc[i].clear();
352            break;
353          }
354          if(og.granulepos()!=-1){
355            serialnos[i]=og.serialno();
356            pcmlengths[i]=og.granulepos();
357            break;
358          }
359        }
360      }
361    }
362  }
363
364  int make_decode_ready(){
365    if(decode_ready)System.exit(1);
366    vd.synthesis_init(vi[0]);
367    vb.init(vd);
368    decode_ready=true;
369    return(0);
370  }
371
372  int open_seekable(){
373    Info initial_i=new Info();
374    Comment initial_c=new Comment();
375    int serialno;
376    long end;
377    int ret;
378    int dataoffset;
379    Page og=new Page();
380    // is this even vorbis...?
381    int[] foo=new int[1];
382    ret=fetch_headers(initial_i, initial_c, foo, null);
383    serialno=foo[0];
384    dataoffset=(int)offset; //!!
385    os.clear();
386    if(ret==-1)return(-1);
387    // we can seek, so set out learning all about this file
388    seekable=true;
389    //(callbacks.seek_func)(datasource, 0, SEEK_END);
390    fseek(datasource, 0, SEEK_END);
391    //offset=end=(callbacks.tell_func)(datasource);
392    offset=ftell(datasource);
393    end=offset;
394    // We get the offset for the last page of the physical bitstream.
395    // Most OggVorbis files will contain a single logical bitstream
396    end=get_prev_page(og);
397    // moer than one logical bitstream?
398    if(og.serialno()!=serialno){
399      // Chained bitstream. Bisect-search each logical bitstream
400      // section.  Do so based on serial number only
401      if(bisect_forward_serialno(0,0,end+1,serialno,0)<0){
402        clear();
403        return OV_EREAD;
404      }
405    }
406    else{
407      // Only one logical bitstream
408      if(bisect_forward_serialno(0,end,end+1,serialno,0)<0){
409        clear();
410        return OV_EREAD;
411      }
412    }
413    prefetch_all_headers(initial_i, initial_c, dataoffset);
414    return(raw_seek(0));
415  }
416
417  int open_nonseekable(){
418    //System.err.println("open_nonseekable");
419    // we cannot seek. Set up a 'single' (current) logical bitstream entry
420    links=1;
421    vi=new Info[links]; vi[0]=new Info(); // ??
422    vc=new Comment[links]; vc[0]=new Comment(); // ?? bug?
423
424    // Try to fetch the headers, maintaining all the storage
425    int[]foo=new int[1];
426    if(fetch_headers(vi[0], vc[0], foo, null)==-1)return(-1);
427    current_serialno=foo[0];
428    make_decode_ready();
429    return 0;
430  }
431
432  // clear out the current logical bitstream decoder
433  void decode_clear(){
434    os.clear();
435    vd.clear();
436    vb.clear();
437    decode_ready=false;
438    bittrack=0.f;
439    samptrack=0.f;
440  }
441
442  // fetch and process a packet.  Handles the case where we're at a
443  // bitstream boundary and dumps the decoding machine.  If the decoding
444  // machine is unloaded, it loads it.  It also keeps pcm_offset up to
445  // date (seek and read both use this.  seek uses a special hack with
446  // readp). 
447  //
448  // return: -1) hole in the data (lost packet) 
449  //          0) need more date (only if readp==0)/eof
450  //          1) got a packet 
451
452  int process_packet(int readp){
453    Page og=new Page();
454
455    // handle one packet.  Try to fetch it from current stream state
456    // extract packets from page
457    while(true){
458      // process a packet if we can.  If the machine isn't loaded,
459      // neither is a page
460      if(decode_ready){
461        Packet op=new Packet();
462        int result=os.packetout(op);
463        long granulepos;
464        // if(result==-1)return(-1); // hole in the data. For now, swallow
465                                     // and go. We'll need to add a real
466                                     // error code in a bit.
467        if(result>0){
468          // got a packet.  process it
469          granulepos=op.granulepos;
470          if(vb.synthesis(op)==0){ // lazy check for lazy
471                                   // header handling.  The
472                                   // header packets aren't
473                                   // audio, so if/when we
474                                   // submit them,
475                                   // vorbis_synthesis will
476                                   // reject them
477            // suck in the synthesis data and track bitrate
478            {
479              int oldsamples=vd.synthesis_pcmout(null, null);
480              vd.synthesis_blockin(vb);
481              samptrack+=vd.synthesis_pcmout(null, null)-oldsamples;
482              bittrack+=op.bytes*8;
483            }
484          
485            // update the pcm offset.
486            if(granulepos!=-1 && op.e_o_s==0){
487              int link=(seekable?current_link:0);
488              int samples;
489              // this packet has a pcm_offset on it (the last packet
490              // completed on a page carries the offset) After processing
491              // (above), we know the pcm position of the *last* sample
492              // ready to be returned. Find the offset of the *first*
493              // 
494              // As an aside, this trick is inaccurate if we begin
495              // reading anew right at the last page; the end-of-stream
496              // granulepos declares the last frame in the stream, and the
497              // last packet of the last page may be a partial frame.
498              // So, we need a previous granulepos from an in-sequence page
499              // to have a reference point.  Thus the !op.e_o_s clause above
500            
501              samples=vd.synthesis_pcmout(null, null);
502              granulepos-=samples;
503              for(int i=0;i<link;i++){
504                granulepos+=pcmlengths[i];
505              }
506              pcm_offset=granulepos;
507            }
508            return(1);
509          }
510        }
511      }
512
513      if(readp==0)return(0);
514      if(get_next_page(og,-1)<0)return(0); // eof. leave unitialized
515
516      // bitrate tracking; add the header's bytes here, the body bytes
517      // are done by packet above
518      bittrack+=og.header_len*8;
519
520      // has our decoding just traversed a bitstream boundary?
521      if(decode_ready){
522        if(current_serialno!=og.serialno()){
523          decode_clear();
524        }
525      }
526
527      // Do we need to load a new machine before submitting the page?
528      // This is different in the seekable and non-seekable cases.  
529      // 
530      // In the seekable case, we already have all the header
531      // information loaded and cached; we just initialize the machine
532      // with it and continue on our merry way.
533      // 
534      // In the non-seekable (streaming) case, we'll only be at a
535      // boundary if we just left the previous logical bitstream and
536      // we're now nominally at the header of the next bitstream
537
538      if(!decode_ready){
539        int i;
540        if(seekable){
541          current_serialno=og.serialno();
542        
543          // match the serialno to bitstream section.  We use this rather than
544          // offset positions to avoid problems near logical bitstream
545          // boundaries
546          for(i=0;i<links;i++){
547            if(serialnos[i]==current_serialno)break;
548          }
549          if(i==links)return(-1); // sign of a bogus stream.  error out,
550                                  // leave machine uninitialized
551          current_link=i;
552
553          os.init(current_serialno);
554          os.reset(); 
555
556        }
557        else{
558          // we're streaming
559          // fetch the three header packets, build the info struct
560          int foo[]=new int[1];
561          int ret=fetch_headers(vi[0], vc[0], foo, og);
562          current_serialno=foo[0];
563          if(ret!=0)return ret;
564          current_link++;
565          i=0;
566        }
567        make_decode_ready();
568      }
569      os.pagein(og);
570    }
571  }
572
573  //The helpers are over; it's all toplevel interface from here on out
574  // clear out the OggVorbis_File struct
575  int clear(){
576    vb.clear();
577    vd.clear();
578    os.clear();
579    
580    if(vi!=null && links!=0){
581      for(int i=0;i<links;i++){
582        vi[i].clear();
583        vc[i].clear();
584      }
585      vi=null;
586      vc=null;
587    }
588    if(dataoffsets!=null)dataoffsets=null;
589    if(pcmlengths!=null)pcmlengths=null;
590    if(serialnos!=null)serialnos=null;
591    if(offsets!=null)offsets=null;
592    oy.clear();
593    //if(datasource!=null)(vf->callbacks.close_func)(vf->datasource);
594    //memset(vf,0,sizeof(OggVorbis_File));
595    return(0);
596  }
597
598  static int fseek(InputStream fis,
599                          //int64_t off,
600                          long off,
601                          int whence){
602    if(fis instanceof SeekableInputStream){
603      SeekableInputStream sis=(SeekableInputStream)fis;
604      try{
605      if(whence==SEEK_SET){
606        sis.seek(off);
607      }
608      else if(whence==SEEK_END){
609        sis.seek(sis.getLength()-off);
610      }
611      else{
612        System.out.println("seek: "+whence+" is not supported");
613      }
614      }
615      catch(Exception e){
616      }
617      return 0;
618    }
619    try{
620      if(whence==0){ fis.reset(); }
621      fis.skip(off);
622    }
623    catch(Exception e){return -1;}
624    return 0;
625  }
626
627  static long ftell(InputStream fis){
628    try{
629    if(fis instanceof SeekableInputStream){
630      SeekableInputStream sis=(SeekableInputStream)fis;
631      return (sis.tell());
632    }
633    }
634    catch(Exception e){
635    }
636    return 0;
637  }
638
639  // inspects the OggVorbis file and finds/documents all the logical
640  // bitstreams contained in it.  Tries to be tolerant of logical
641  // bitstream sections that are truncated/woogie. 
642  //
643  // return: -1) error
644  //          0) OK
645
646  int open(InputStream is, byte[] initial, int ibytes){
647    //callbacks callbacks = {
648    // (size_t (*)(void *, size_t, size_t, void *))  fread,
649    // (int (*)(void *, int64_t, int))              _fseek,
650    // (int (*)(void *))                             fclose,
651    // (long (*)(void *))                            ftell
652    // };
653    return open_callbacks(is, initial, ibytes//, callbacks
654                             );
655  }
656
657  int open_callbacks(InputStream is, byte[] initial, 
658                        int ibytes//, callbacks callbacks
659                        ){
660    int ret;
661    datasource=is;
662    //callbacks = _callbacks;
663    // init the framing state
664    oy.init();
665
666    // perhaps some data was previously read into a buffer for testing
667    // against other stream types.  Allow initialization from this
668    // previously read data (as we may be reading from a non-seekable
669    // stream)
670    if(initial!=null){
671      int index=oy.buffer(ibytes);
672      System.arraycopy(initial, 0, oy.data, index, ibytes);
673      oy.wrote(ibytes);
674    }
675    // can we seek? Stevens suggests the seek test was portable
676    if(is instanceof SeekableInputStream){ ret=open_seekable(); }
677    else{ ret=open_nonseekable(); }
678    if(ret!=0){
679      datasource=null;
680      clear();
681    }
682    return(ret);
683  }
684
685  // How many logical bitstreams in this physical bitstream?
686  public int streams(){
687    return links;
688  }
689
690  // Is the FILE * associated with vf seekable?
691  public boolean seekable(){
692    return seekable;
693  }
694
695  // returns the bitrate for a given logical bitstream or the entire
696  // physical bitstream.  If the file is open for random access, it will
697  // find the *actual* average bitrate.  If the file is streaming, it
698  // returns the nominal bitrate (if set) else the average of the
699  // upper/lower bounds (if set) else -1 (unset).
700  // 
701  // If you want the actual bitrate field settings, get them from the
702  // vorbis_info structs
703
704  public int bitrate(int i){
705    if(i>=links)return(-1);
706    if(!seekable && i!=0)return(bitrate(0));
707    if(i<0){
708      long bits=0;
709      for(int j=0;j<links;j++){
710        bits+=(offsets[j+1]-dataoffsets[j])*8;
711      }
712      return((int)Math.rint(bits/time_total(-1)));
713    }
714    else{
715      if(seekable){
716        // return the actual bitrate
717        return((int)Math.rint((offsets[i+1]-dataoffsets[i])*8/time_total(i)));
718      }
719      else{
720        // return nominal if set
721        if(vi[i].bitrate_nominal>0){
722          return vi[i].bitrate_nominal;
723        }
724        else{
725          if(vi[i].bitrate_upper>0){
726            if(vi[i].bitrate_lower>0){
727              return (vi[i].bitrate_upper+vi[i].bitrate_lower)/2;
728            }else{
729              return vi[i].bitrate_upper;
730            }
731          }
732          return(-1);
733        }
734      }
735    }
736  }
737
738  // returns the actual bitrate since last call.  returns -1 if no
739  // additional data to offer since last call (or at beginning of stream)
740  public int bitrate_instant(){
741    int _link=(seekable?current_link:0);
742    if(samptrack==0)return(-1);
743    int ret=(int)(bittrack/samptrack*vi[_link].rate+.5);
744    bittrack=0.f;
745    samptrack=0.f;
746    return(ret);
747  }
748
749  public int serialnumber(int i){
750    if(i>=links)return(-1);
751    if(!seekable && i>=0)return(serialnumber(-1));
752    if(i<0){
753      return(current_serialno);
754    }
755    else{
756      return(serialnos[i]);
757    }
758  }
759
760  // returns: total raw (compressed) length of content if i==-1
761  //          raw (compressed) length of that logical bitstream for i==0 to n
762  //          -1 if the stream is not seekable (we can't know the length)
763
764  public long raw_total(int i){
765    if(!seekable || i>=links)return(-1);
766    if(i<0){
767      long acc=0;               // bug?
768      for(int j=0;j<links;j++){
769        acc+=raw_total(j);
770      }
771      return(acc);
772    }
773    else{
774      return(offsets[i+1]-offsets[i]);
775    }
776  }
777
778  // returns: total PCM length (samples) of content if i==-1
779  //          PCM length (samples) of that logical bitstream for i==0 to n
780  //          -1 if the stream is not seekable (we can't know the length)
781  public long pcm_total(int i){
782    if(!seekable || i>=links)return(-1);
783    if(i<0){
784      long acc=0;
785      for(int j=0;j<links;j++){
786        acc+=pcm_total(j);
787      }
788      return(acc);
789    }
790    else{
791      return(pcmlengths[i]);
792    }
793  }
794
795  // returns: total seconds of content if i==-1
796  //          seconds in that logical bitstream for i==0 to n
797  //          -1 if the stream is not seekable (we can't know the length)
798  public float time_total(int i){
799    if(!seekable || i>=links)return(-1);
800    if(i<0){
801      float acc=0;
802      for(int j=0;j<links;j++){
803        acc+=time_total(j);
804      }
805      return(acc);
806    }
807    else{
808      return((float)(pcmlengths[i])/vi[i].rate);
809    }
810  }
811
812  // seek to an offset relative to the *compressed* data. This also
813  // immediately sucks in and decodes pages to update the PCM cursor. It
814  // will cross a logical bitstream boundary, but only if it can't get
815  // any packets out of the tail of the bitstream we seek to (so no
816  // surprises). 
817  // 
818  // returns zero on success, nonzero on failure
819
820  public int raw_seek(int pos){
821    if(!seekable)return(-1); // don't dump machine if we can't seek
822    if(pos<0 || pos>offsets[links]){
823      //goto seek_error;
824      pcm_offset=-1;
825      decode_clear();
826      return -1;
827    }
828
829    // clear out decoding machine state
830    pcm_offset=-1;
831    decode_clear();
832
833    // seek
834    seek_helper(pos);
835
836    // we need to make sure the pcm_offset is set.  We use the
837    // _fetch_packet helper to process one packet with readp set, then
838    // call it until it returns '0' with readp not set (the last packet
839    // from a page has the 'granulepos' field set, and that's how the
840    // helper updates the offset
841
842    switch(process_packet(1)){
843    case 0:
844      // oh, eof. There are no packets remaining.  Set the pcm offset to
845      // the end of file
846      pcm_offset=pcm_total(-1);
847      return(0);
848    case -1:
849      // error! missing data or invalid bitstream structure
850      //goto seek_error;
851      pcm_offset=-1;
852      decode_clear();
853      return -1;
854    default:
855      // all OK
856      break;
857    }
858    while(true){
859      switch(process_packet(0)){
860      case 0:
861        // the offset is set.  If it's a bogus bitstream with no offset
862        // information, it's not but that's not our fault.  We still run
863        // gracefully, we're just missing the offset
864        return(0);
865      case -1:
866        // error! missing data or invalid bitstream structure
867        //goto seek_error;
868        pcm_offset=-1;
869        decode_clear();
870        return -1;
871      default:
872        // continue processing packets
873        break;
874      }
875    }
876  
877  // seek_error:
878    // dump the machine so we're in a known state
879    //pcm_offset=-1;
880    //decode_clear();
881    //return -1;
882  }
883
884  // seek to a sample offset relative to the decompressed pcm stream 
885  // returns zero on success, nonzero on failure
886
887  public int pcm_seek(long pos){
888    int link=-1;
889    long total=pcm_total(-1);
890
891    if(!seekable)return(-1); // don't dump machine if we can't seek
892    if(pos<0 || pos>total){
893      //goto seek_error;
894      pcm_offset=-1;
895      decode_clear();
896      return -1;
897    }
898
899    // which bitstream section does this pcm offset occur in?
900    for(link=links-1;link>=0;link--){
901      total-=pcmlengths[link];
902      if(pos>=total)break;
903    }
904
905    // search within the logical bitstream for the page with the highest
906    // pcm_pos preceeding (or equal to) pos.  There is a danger here;
907    // missing pages or incorrect frame number information in the
908    // bitstream could make our task impossible.  Account for that (it
909    // would be an error condition)
910    {
911      long target=pos-total;
912      long end=offsets[link+1];
913      long begin=offsets[link];
914      int best=(int)begin;
915
916      Page og=new Page();
917      while(begin<end){
918        long bisect;
919        int ret;
920    
921        if(end-begin<CHUNKSIZE){
922          bisect=begin;
923        }
924        else{
925          bisect=(end+begin)/2;
926        }
927    
928        seek_helper(bisect);
929        ret=get_next_page(og,end-bisect);
930      
931        if(ret==-1){
932          end=bisect;
933        }
934        else{
935          long granulepos=og.granulepos();
936          if(granulepos<target){
937            best=ret;  // raw offset of packet with granulepos
938            begin=offset; // raw offset of next packet
939          }
940          else{
941            end=bisect;
942          }
943        }
944      }
945      // found our page. seek to it (call raw_seek).
946      if(raw_seek(best)!=0){
947        //goto seek_error;
948        pcm_offset=-1;
949        decode_clear();
950        return -1;
951      }
952    }
953
954    // verify result
955    if(pcm_offset>=pos){
956      //goto seek_error;
957      pcm_offset=-1;
958      decode_clear();
959      return -1;
960    }
961    if(pos>pcm_total(-1)){
962      //goto seek_error;
963      pcm_offset=-1;
964      decode_clear();
965      return -1;
966    }
967
968    // discard samples until we reach the desired position. Crossing a
969    // logical bitstream boundary with abandon is OK.
970    while(pcm_offset<pos){
971      float[][] pcm;
972      int target=(int)(pos-pcm_offset);
973      float[][][] _pcm=new float[1][][];
974      int[] _index=new int[getInfo(-1).channels];
975      int samples=vd.synthesis_pcmout(_pcm, _index);
976      pcm=_pcm[0];
977
978      if(samples>target)samples=target;
979      vd.synthesis_read(samples);
980      pcm_offset+=samples;
981    
982      if(samples<target)
983        if(process_packet(1)==0){
984          pcm_offset=pcm_total(-1); // eof
985        }
986    }
987    return 0;
988  
989  // seek_error:
990    // dump machine so we're in a known state
991    //pcm_offset=-1;
992    //decode_clear();
993    //return -1;
994  }
995
996  // seek to a playback time relative to the decompressed pcm stream 
997  // returns zero on success, nonzero on failure
998  int time_seek(float seconds){
999    // translate time to PCM position and call pcm_seek
1000
1001    int link=-1;
1002    long pcm_total=pcm_total(-1);
1003    float time_total=time_total(-1);
1004
1005    if(!seekable)return(-1); // don't dump machine if we can't seek
1006    if(seconds<0 || seconds>time_total){
1007      //goto seek_error;
1008      pcm_offset=-1;
1009      decode_clear();
1010      return -1;
1011    }
1012  
1013    // which bitstream section does this time offset occur in?
1014    for(link=links-1;link>=0;link--){
1015      pcm_total-=pcmlengths[link];
1016      time_total-=time_total(link);
1017      if(seconds>=time_total)break;
1018    }
1019
1020    // enough information to convert time offset to pcm offset
1021    {
1022      long target=(long)(pcm_total+(seconds-time_total)*vi[link].rate);
1023      return(pcm_seek(target));
1024    }
1025
1026  //seek_error:
1027    // dump machine so we're in a known state
1028    //pcm_offset=-1;
1029    //decode_clear();
1030    //return -1;
1031  }
1032
1033  // tell the current stream offset cursor.  Note that seek followed by
1034  // tell will likely not give the set offset due to caching
1035  public long raw_tell(){
1036    return(offset);
1037  }
1038
1039  // return PCM offset (sample) of next PCM sample to be read
1040  public long pcm_tell(){
1041    return(pcm_offset);
1042  }
1043
1044  // return time offset (seconds) of next PCM sample to be read
1045  public float time_tell(){
1046    // translate time to PCM position and call pcm_seek
1047
1048    int link=-1;
1049    long pcm_total=0;
1050    float time_total=0.f;
1051  
1052    if(seekable){
1053      pcm_total=pcm_total(-1);
1054      time_total=time_total(-1);
1055  
1056      // which bitstream section does this time offset occur in?
1057      for(link=links-1;link>=0;link--){
1058        pcm_total-=pcmlengths[link];
1059        time_total-=time_total(link);
1060        if(pcm_offset>=pcm_total)break;
1061      }
1062    }
1063
1064    return((float)time_total+(float)(pcm_offset-pcm_total)/vi[link].rate);
1065  }
1066
1067  //  link:   -1) return the vorbis_info struct for the bitstream section
1068  //              currently being decoded
1069  //         0-n) to request information for a specific bitstream section
1070  //
1071  // In the case of a non-seekable bitstream, any call returns the
1072  // current bitstream.  NULL in the case that the machine is not
1073  // initialized
1074
1075  public Info getInfo(int link){
1076    if(seekable){
1077      if(link<0){
1078        if(decode_ready){
1079          return vi[current_link];
1080        }
1081        else{
1082          return null;
1083        }
1084      }
1085      else{
1086        if(link>=links){
1087          return null;
1088        }
1089        else{
1090          return vi[link];
1091        }
1092      }
1093    }
1094    else{
1095      if(decode_ready){
1096        return vi[0];
1097      }
1098      else{
1099        return null;
1100      }
1101    }
1102  }
1103
1104  public Comment getComment(int link){
1105    if(seekable){
1106      if(link<0){
1107        if(decode_ready){ return vc[current_link]; }
1108        else{ return null; }
1109      }
1110      else{
1111        if(link>=links){ return null;}
1112        else{ return vc[link]; }
1113      }
1114    }
1115    else{
1116      if(decode_ready){ return vc[0]; }
1117      else{ return null; }
1118    }
1119  }
1120
1121  int host_is_big_endian() {
1122    return 1;
1123//    short pattern = 0xbabe;
1124//    unsigned char *bytewise = (unsigned char *)&pattern;
1125//    if (bytewise[0] == 0xba) return 1;
1126//    assert(bytewise[0] == 0xbe);
1127//    return 0;
1128  }
1129
1130  // up to this point, everything could more or less hide the multiple
1131  // logical bitstream nature of chaining from the toplevel application
1132  // if the toplevel application didn't particularly care.  However, at
1133  // the point that we actually read audio back, the multiple-section
1134  // nature must surface: Multiple bitstream sections do not necessarily
1135  // have to have the same number of channels or sampling rate.
1136  // 
1137  // read returns the sequential logical bitstream number currently
1138  // being decoded along with the PCM data in order that the toplevel
1139  // application can take action on channel/sample rate changes.  This
1140  // number will be incremented even for streamed (non-seekable) streams
1141  // (for seekable streams, it represents the actual logical bitstream
1142  // index within the physical bitstream.  Note that the accessor
1143  // functions above are aware of this dichotomy).
1144  //
1145  // input values: buffer) a buffer to hold packed PCM data for return
1146  //               length) the byte length requested to be placed into buffer
1147  //               bigendianp) should the data be packed LSB first (0) or
1148  //                           MSB first (1)
1149  //               word) word size for output.  currently 1 (byte) or 
1150  //                     2 (16 bit short)
1151  // 
1152  // return values: -1) error/hole in data
1153  //                 0) EOF
1154  //                 n) number of bytes of PCM actually returned.  The
1155  //                    below works on a packet-by-packet basis, so the
1156  //                    return length is not related to the 'length' passed
1157  //                    in, just guaranteed to fit.
1158  // 
1159  // *section) set to the logical bitstream number
1160
1161  int read(byte[] buffer,int length,
1162           int bigendianp, int word, int sgned, int[] bitstream){
1163    int host_endian = host_is_big_endian();
1164    int index=0;
1165
1166    while(true){
1167      if(decode_ready){
1168        float[][] pcm;
1169        float[][][] _pcm=new float[1][][];
1170        int[] _index=new int[getInfo(-1).channels];
1171        int samples=vd.synthesis_pcmout(_pcm, _index);
1172        pcm=_pcm[0];
1173        if(samples!=0){
1174          // yay! proceed to pack data into the byte buffer
1175          int channels=getInfo(-1).channels;
1176          int bytespersample=word * channels;
1177          if(samples>length/bytespersample)samples=length/bytespersample;
1178        
1179          // a tight loop to pack each size
1180          {
1181            int val;
1182            if(word==1){
1183              int off=(sgned!=0?0:128);
1184              for(int j=0;j<samples;j++){
1185                for(int i=0;i<channels;i++){
1186                  val=(int)(pcm[i][_index[i]+j]*128. + 0.5);
1187                  if(val>127)val=127;
1188                  else if(val<-128)val=-128;
1189                  buffer[index++]=(byte)(val+off);
1190                }
1191              }
1192            }
1193            else{
1194              int off=(sgned!=0?0:32768);
1195
1196              if(host_endian==bigendianp){
1197                if(sgned!=0){
1198                  for(int i=0;i<channels;i++) { // It's faster in this order
1199                    int src=_index[i];
1200                    int dest=i;
1201                    for(int j=0;j<samples;j++) {
1202                      val=(int)(pcm[i][src+j]*32768. + 0.5);
1203                      if(val>32767)val=32767;
1204                      else if(val<-32768)val=-32768;
1205                      buffer[dest]=(byte)(val>>>8);
1206                      buffer[dest+1]=(byte)(val);
1207                      dest+=channels*2;
1208                    }
1209                  }
1210                }
1211                else{
1212                  for(int i=0;i<channels;i++) {
1213                    float[] src=pcm[i];
1214                    int dest=i;
1215                    for(int j=0;j<samples;j++) {
1216                      val=(int)(src[j]*32768. + 0.5);
1217                      if(val>32767)val=32767;
1218                      else if(val<-32768)val=-32768;
1219                      buffer[dest]=(byte)((val+off)>>>8);
1220                      buffer[dest+1]=(byte)(val+off);
1221                      dest+=channels*2;
1222                    }
1223                  }
1224                }
1225              }
1226              else if(bigendianp!=0){
1227                for(int j=0;j<samples;j++){
1228                  for(int i=0;i<channels;i++){
1229                    val=(int)(pcm[i][j]*32768. + 0.5);
1230                    if(val>32767)val=32767;
1231                    else if(val<-32768)val=-32768;
1232                    val+=off;
1233                    buffer[index++]=(byte)(val>>>8);
1234                    buffer[index++]=(byte)val;
1235                  }
1236                }
1237              }
1238              else{
1239                //int val;
1240                for(int j=0;j<samples;j++){
1241                  for(int i=0;i<channels;i++){
1242                    val=(int)(pcm[i][j]*32768. + 0.5);
1243                    if(val>32767)val=32767;
1244                    else if(val<-32768)val=-32768;
1245                    val+=off;
1246                    buffer[index++]=(byte)val;
1247                    buffer[index++]=(byte)(val>>>8);
1248                  }
1249                }
1250              }
1251            }
1252          }
1253        
1254          vd.synthesis_read(samples);
1255          pcm_offset+=samples;
1256          if(bitstream!=null)bitstream[0]=current_link;
1257          return(samples*bytespersample);
1258        }
1259      }
1260
1261      // suck in another packet
1262      switch(process_packet(1)){
1263      case 0:
1264        return(0);
1265      case -1:
1266        return -1;
1267      default:
1268        break;
1269      }
1270    }
1271  }
1272
1273  public Info[] getInfo(){return vi;}
1274  public Comment[] getComment(){return vc;}
1275
1276  public static void main(String[] arg){
1277    try{
1278      VorbisFile foo=new VorbisFile(arg[0]);
1279      int links=foo.streams();
1280      System.out.println("links="+links);
1281      Comment[] comment=foo.getComment();
1282      Info[] info=foo.getInfo();
1283      for(int i=0; i<links; i++){
1284        System.out.println(info[i]);
1285        System.out.println(comment[i]);
1286      }
1287      System.out.println("raw_total: "+foo.raw_total(-1));
1288      System.out.println("pcm_total: "+foo.pcm_total(-1));
1289      System.out.println("time_total: "+foo.time_total(-1));
1290    }
1291    catch(Exception e){
1292      System.err.println(e);
1293    }
1294  }
1295
1296  class SeekableInputStream extends InputStream {
1297    java.io.RandomAccessFile raf=null;
1298    static final String mode="r";
1299    private SeekableInputStream(){
1300    }
1301    SeekableInputStream(String file) throws java.io.FileNotFoundException{
1302      raf=new java.io.RandomAccessFile(file, mode);
1303    }
1304    public int read() throws java.io.IOException{
1305      return raf.read();
1306    }
1307    public int read(byte[] buf) throws java.io.IOException{
1308      return raf.read(buf);
1309    }
1310    public int read(byte[] buf , int s, int len) throws java.io.IOException{
1311      return raf.read(buf, s, len);
1312    }
1313    public long skip(long n) throws java.io.IOException{
1314      return (long)(raf.skipBytes((int)n));
1315    }
1316    public long getLength() throws java.io.IOException{
1317      return raf.length();
1318    }
1319    public long tell() throws java.io.IOException{
1320      return raf.getFilePointer();
1321    }
1322    public int available() throws java.io.IOException{
1323      return (raf.length()==raf.getFilePointer())? 0 : 1;
1324    }
1325    public void close() throws java.io.IOException{
1326      raf.close();
1327    }
1328    public synchronized void mark(int m){
1329    }
1330    public synchronized void reset() throws java.io.IOException{
1331    }
1332    public boolean markSupported(){
1333      return false;
1334    }
1335    public void seek(long pos) throws java.io.IOException{
1336      raf.seek(pos);
1337    }
1338  }
1339
1340}