Home | History | Annotate | Download | only in lib
      1 /********************************************************************
      2  *                                                                  *
      3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
      4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
      5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
      6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
      7  *                                                                  *
      8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
      9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
     10  *                                                                  *
     11  ********************************************************************
     12 
     13  function: stdio-based convenience library for opening/seeking/decoding
     14  last mod: $Id: vorbisfile.c 17012 2010-03-24 07:37:36Z xiphmont $
     15 
     16  ********************************************************************/
     17 
     18 #include <stdlib.h>
     19 #include <stdio.h>
     20 #include <errno.h>
     21 #include <string.h>
     22 #include <math.h>
     23 
     24 #include "vorbis/codec.h"
     25 
     26 /* we don't need or want the static callback symbols here */
     27 #define OV_EXCLUDE_STATIC_CALLBACKS
     28 #include "vorbis/vorbisfile.h"
     29 
     30 #include "os.h"
     31 #include "misc.h"
     32 
     33 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
     34    one logical bitstream arranged end to end (the only form of Ogg
     35    multiplexing allowed in a Vorbis bitstream; grouping [parallel
     36    multiplexing] is not allowed in Vorbis) */
     37 
     38 /* A Vorbis file can be played beginning to end (streamed) without
     39    worrying ahead of time about chaining (see decoder_example.c).  If
     40    we have the whole file, however, and want random access
     41    (seeking/scrubbing) or desire to know the total length/time of a
     42    file, we need to account for the possibility of chaining. */
     43 
     44 /* We can handle things a number of ways; we can determine the entire
     45    bitstream structure right off the bat, or find pieces on demand.
     46    This example determines and caches structure for the entire
     47    bitstream, but builds a virtual decoder on the fly when moving
     48    between links in the chain. */
     49 
     50 /* There are also different ways to implement seeking.  Enough
     51    information exists in an Ogg bitstream to seek to
     52    sample-granularity positions in the output.  Or, one can seek by
     53    picking some portion of the stream roughly in the desired area if
     54    we only want coarse navigation through the stream. */
     55 
     56 /*************************************************************************
     57  * Many, many internal helpers.  The intention is not to be confusing;
     58  * rampant duplication and monolithic function implementation would be
     59  * harder to understand anyway.  The high level functions are last.  Begin
     60  * grokking near the end of the file */
     61 
     62 /* read a little more data from the file/pipe into the ogg_sync framer
     63 */
     64 #define CHUNKSIZE 65536 /* greater-than-page-size granularity seeking */
     65 #define READSIZE 2048 /* a smaller read size is needed for low-rate streaming. */
     66 
     67 static long _get_data(OggVorbis_File *vf){
     68   errno=0;
     69   if(!(vf->callbacks.read_func))return(-1);
     70   if(vf->datasource){
     71     char *buffer=ogg_sync_buffer(&vf->oy,READSIZE);
     72     long bytes=(vf->callbacks.read_func)(buffer,1,READSIZE,vf->datasource);
     73     if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
     74     if(bytes==0 && errno)return(-1);
     75     return(bytes);
     76   }else
     77     return(0);
     78 }
     79 
     80 /* save a tiny smidge of verbosity to make the code more readable */
     81 static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
     82   if(vf->datasource){
     83     if(!(vf->callbacks.seek_func)||
     84        (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
     85       return OV_EREAD;
     86     vf->offset=offset;
     87     ogg_sync_reset(&vf->oy);
     88   }else{
     89     /* shouldn't happen unless someone writes a broken callback */
     90     return OV_EFAULT;
     91   }
     92   return 0;
     93 }
     94 
     95 /* The read/seek functions track absolute position within the stream */
     96 
     97 /* from the head of the stream, get the next page.  boundary specifies
     98    if the function is allowed to fetch more data from the stream (and
     99    how much) or only use internally buffered data.
    100 
    101    boundary: -1) unbounded search
    102               0) read no additional data; use cached only
    103               n) search for a new page beginning for n bytes
    104 
    105    return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
    106               n) found a page at absolute offset n */
    107 
    108 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
    109                                   ogg_int64_t boundary){
    110   if(boundary>0)boundary+=vf->offset;
    111   while(1){
    112     long more;
    113 
    114     if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
    115     more=ogg_sync_pageseek(&vf->oy,og);
    116 
    117     if(more<0){
    118       /* skipped n bytes */
    119       vf->offset-=more;
    120     }else{
    121       if(more==0){
    122         /* send more paramedics */
    123         if(!boundary)return(OV_FALSE);
    124         {
    125           long ret=_get_data(vf);
    126           if(ret==0)return(OV_EOF);
    127           if(ret<0)return(OV_EREAD);
    128         }
    129       }else{
    130         /* got a page.  Return the offset at the page beginning,
    131            advance the internal offset past the page end */
    132         ogg_int64_t ret=vf->offset;
    133         vf->offset+=more;
    134         return(ret);
    135 
    136       }
    137     }
    138   }
    139 }
    140 
    141 /* find the latest page beginning before the current stream cursor
    142    position. Much dirtier than the above as Ogg doesn't have any
    143    backward search linkage.  no 'readp' as it will certainly have to
    144    read. */
    145 /* returns offset or OV_EREAD, OV_FAULT */
    146 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
    147   ogg_int64_t begin=vf->offset;
    148   ogg_int64_t end=begin;
    149   ogg_int64_t ret;
    150   ogg_int64_t offset=-1;
    151 
    152   while(offset==-1){
    153     begin-=CHUNKSIZE;
    154     if(begin<0)
    155       begin=0;
    156 
    157     ret=_seek_helper(vf,begin);
    158     if(ret)return(ret);
    159 
    160     while(vf->offset<end){
    161       memset(og,0,sizeof(*og));
    162       ret=_get_next_page(vf,og,end-vf->offset);
    163       if(ret==OV_EREAD)return(OV_EREAD);
    164       if(ret<0){
    165         break;
    166       }else{
    167         offset=ret;
    168       }
    169     }
    170   }
    171 
    172   /* In a fully compliant, non-multiplexed stream, we'll still be
    173      holding the last page.  In multiplexed (or noncompliant streams),
    174      we will probably have to re-read the last page we saw */
    175   if(og->header_len==0){
    176     ret=_seek_helper(vf,offset);
    177     if(ret)return(ret);
    178 
    179     ret=_get_next_page(vf,og,CHUNKSIZE);
    180     if(ret<0)
    181       /* this shouldn't be possible */
    182       return(OV_EFAULT);
    183   }
    184 
    185   return(offset);
    186 }
    187 
    188 static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
    189   long s = ogg_page_serialno(og);
    190   (*n)++;
    191 
    192   if(*serialno_list){
    193     *serialno_list = _ogg_realloc(*serialno_list, sizeof(**serialno_list)*(*n));
    194   }else{
    195     *serialno_list = _ogg_malloc(sizeof(**serialno_list));
    196   }
    197 
    198   (*serialno_list)[(*n)-1] = s;
    199 }
    200 
    201 /* returns nonzero if found */
    202 static int _lookup_serialno(long s, long *serialno_list, int n){
    203   if(serialno_list){
    204     while(n--){
    205       if(*serialno_list == s) return 1;
    206       serialno_list++;
    207     }
    208   }
    209   return 0;
    210 }
    211 
    212 static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
    213   long s = ogg_page_serialno(og);
    214   return _lookup_serialno(s,serialno_list,n);
    215 }
    216 
    217 /* performs the same search as _get_prev_page, but prefers pages of
    218    the specified serial number. If a page of the specified serialno is
    219    spotted during the seek-back-and-read-forward, it will return the
    220    info of last page of the matching serial number instead of the very
    221    last page.  If no page of the specified serialno is seen, it will
    222    return the info of last page and alter *serialno.  */
    223 static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
    224                                          long *serial_list, int serial_n,
    225                                          int *serialno, ogg_int64_t *granpos){
    226   ogg_page og;
    227   ogg_int64_t begin=vf->offset;
    228   ogg_int64_t end=begin;
    229   ogg_int64_t ret;
    230 
    231   ogg_int64_t prefoffset=-1;
    232   ogg_int64_t offset=-1;
    233   ogg_int64_t ret_serialno=-1;
    234   ogg_int64_t ret_gran=-1;
    235 
    236   while(offset==-1){
    237     begin-=CHUNKSIZE;
    238     if(begin<0)
    239       begin=0;
    240 
    241     ret=_seek_helper(vf,begin);
    242     if(ret)return(ret);
    243 
    244     while(vf->offset<end){
    245       ret=_get_next_page(vf,&og,end-vf->offset);
    246       if(ret==OV_EREAD)return(OV_EREAD);
    247       if(ret<0){
    248         break;
    249       }else{
    250         ret_serialno=ogg_page_serialno(&og);
    251         ret_gran=ogg_page_granulepos(&og);
    252         offset=ret;
    253 
    254         if(ret_serialno == *serialno){
    255           prefoffset=ret;
    256           *granpos=ret_gran;
    257         }
    258 
    259         if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){
    260           /* we fell off the end of the link, which means we seeked
    261              back too far and shouldn't have been looking in that link
    262              to begin with.  If we found the preferred serial number,
    263              forget that we saw it. */
    264           prefoffset=-1;
    265         }
    266       }
    267     }
    268   }
    269 
    270   /* we're not interested in the page... just the serialno and granpos. */
    271   if(prefoffset>=0)return(prefoffset);
    272 
    273   *serialno = ret_serialno;
    274   *granpos = ret_gran;
    275   return(offset);
    276 
    277 }
    278 
    279 /* uses the local ogg_stream storage in vf; this is important for
    280    non-streaming input sources */
    281 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
    282                           long **serialno_list, int *serialno_n,
    283                           ogg_page *og_ptr){
    284   ogg_page og;
    285   ogg_packet op;
    286   int i,ret;
    287   int allbos=0;
    288 
    289   if(!og_ptr){
    290     ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
    291     if(llret==OV_EREAD)return(OV_EREAD);
    292     if(llret<0)return(OV_ENOTVORBIS);
    293     og_ptr=&og;
    294   }
    295 
    296   vorbis_info_init(vi);
    297   vorbis_comment_init(vc);
    298   vf->ready_state=OPENED;
    299 
    300   /* extract the serialnos of all BOS pages + the first set of vorbis
    301      headers we see in the link */
    302 
    303   while(ogg_page_bos(og_ptr)){
    304     if(serialno_list){
    305       if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
    306         /* a dupe serialnumber in an initial header packet set == invalid stream */
    307         if(*serialno_list)_ogg_free(*serialno_list);
    308         *serialno_list=0;
    309         *serialno_n=0;
    310         ret=OV_EBADHEADER;
    311         goto bail_header;
    312       }
    313 
    314       _add_serialno(og_ptr,serialno_list,serialno_n);
    315     }
    316 
    317     if(vf->ready_state<STREAMSET){
    318       /* we don't have a vorbis stream in this link yet, so begin
    319          prospective stream setup. We need a stream to get packets */
    320       ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
    321       ogg_stream_pagein(&vf->os,og_ptr);
    322 
    323       if(ogg_stream_packetout(&vf->os,&op) > 0 &&
    324          vorbis_synthesis_idheader(&op)){
    325         /* vorbis header; continue setup */
    326         vf->ready_state=STREAMSET;
    327         if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
    328           ret=OV_EBADHEADER;
    329           goto bail_header;
    330         }
    331       }
    332     }
    333 
    334     /* get next page */
    335     {
    336       ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
    337       if(llret==OV_EREAD){
    338         ret=OV_EREAD;
    339         goto bail_header;
    340       }
    341       if(llret<0){
    342         ret=OV_ENOTVORBIS;
    343         goto bail_header;
    344       }
    345 
    346       /* if this page also belongs to our vorbis stream, submit it and break */
    347       if(vf->ready_state==STREAMSET &&
    348          vf->os.serialno == ogg_page_serialno(og_ptr)){
    349         ogg_stream_pagein(&vf->os,og_ptr);
    350         break;
    351       }
    352     }
    353   }
    354 
    355   if(vf->ready_state!=STREAMSET){
    356     ret = OV_ENOTVORBIS;
    357     goto bail_header;
    358   }
    359 
    360   while(1){
    361 
    362     i=0;
    363     while(i<2){ /* get a page loop */
    364 
    365       while(i<2){ /* get a packet loop */
    366 
    367         int result=ogg_stream_packetout(&vf->os,&op);
    368         if(result==0)break;
    369         if(result==-1){
    370           ret=OV_EBADHEADER;
    371           goto bail_header;
    372         }
    373 
    374         if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
    375           goto bail_header;
    376 
    377         i++;
    378       }
    379 
    380       while(i<2){
    381         if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
    382           ret=OV_EBADHEADER;
    383           goto bail_header;
    384         }
    385 
    386         /* if this page belongs to the correct stream, go parse it */
    387         if(vf->os.serialno == ogg_page_serialno(og_ptr)){
    388           ogg_stream_pagein(&vf->os,og_ptr);
    389           break;
    390         }
    391 
    392         /* if we never see the final vorbis headers before the link
    393            ends, abort */
    394         if(ogg_page_bos(og_ptr)){
    395           if(allbos){
    396             ret = OV_EBADHEADER;
    397             goto bail_header;
    398           }else
    399             allbos=1;
    400         }
    401 
    402         /* otherwise, keep looking */
    403       }
    404     }
    405 
    406     return 0;
    407   }
    408 
    409  bail_header:
    410   vorbis_info_clear(vi);
    411   vorbis_comment_clear(vc);
    412   vf->ready_state=OPENED;
    413 
    414   return ret;
    415 }
    416 
    417 /* Starting from current cursor position, get initial PCM offset of
    418    next page.  Consumes the page in the process without decoding
    419    audio, however this is only called during stream parsing upon
    420    seekable open. */
    421 static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
    422   ogg_page    og;
    423   ogg_int64_t accumulated=0;
    424   long        lastblock=-1;
    425   int         result;
    426   int         serialno = vf->os.serialno;
    427 
    428   while(1){
    429     ogg_packet op;
    430     if(_get_next_page(vf,&og,-1)<0)
    431       break; /* should not be possible unless the file is truncated/mangled */
    432 
    433     if(ogg_page_bos(&og)) break;
    434     if(ogg_page_serialno(&og)!=serialno) continue;
    435 
    436     /* count blocksizes of all frames in the page */
    437     ogg_stream_pagein(&vf->os,&og);
    438     while((result=ogg_stream_packetout(&vf->os,&op))){
    439       if(result>0){ /* ignore holes */
    440         long thisblock=vorbis_packet_blocksize(vi,&op);
    441         if(lastblock!=-1)
    442           accumulated+=(lastblock+thisblock)>>2;
    443         lastblock=thisblock;
    444       }
    445     }
    446 
    447     if(ogg_page_granulepos(&og)!=-1){
    448       /* pcm offset of last packet on the first audio page */
    449       accumulated= ogg_page_granulepos(&og)-accumulated;
    450       break;
    451     }
    452   }
    453 
    454   /* less than zero?  This is a stream with samples trimmed off
    455      the beginning, a normal occurrence; set the offset to zero */
    456   if(accumulated<0)accumulated=0;
    457 
    458   return accumulated;
    459 }
    460 
    461 /* finds each bitstream link one at a time using a bisection search
    462    (has to begin by knowing the offset of the lb's initial page).
    463    Recurses for each link so it can alloc the link storage after
    464    finding them all, then unroll and fill the cache at the same time */
    465 static int _bisect_forward_serialno(OggVorbis_File *vf,
    466                                     ogg_int64_t begin,
    467                                     ogg_int64_t searched,
    468                                     ogg_int64_t end,
    469                                     ogg_int64_t endgran,
    470                                     int endserial,
    471                                     long *currentno_list,
    472                                     int  currentnos,
    473                                     long m){
    474   ogg_int64_t pcmoffset;
    475   ogg_int64_t dataoffset=searched;
    476   ogg_int64_t endsearched=end;
    477   ogg_int64_t next=end;
    478   ogg_int64_t searchgran=-1;
    479   ogg_page og;
    480   ogg_int64_t ret,last;
    481   int serialno = vf->os.serialno;
    482 
    483   /* invariants:
    484      we have the headers and serialnos for the link beginning at 'begin'
    485      we have the offset and granpos of the last page in the file (potentially
    486        not a page we care about)
    487   */
    488 
    489   /* Is the last page in our list of current serialnumbers? */
    490   if(_lookup_serialno(endserial,currentno_list,currentnos)){
    491 
    492     /* last page is in the starting serialno list, so we've bisected
    493        down to (or just started with) a single link.  Now we need to
    494        find the last vorbis page belonging to the first vorbis stream
    495        for this link. */
    496 
    497     while(endserial != serialno){
    498       endserial = serialno;
    499       vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran);
    500     }
    501 
    502     vf->links=m+1;
    503     if(vf->offsets)_ogg_free(vf->offsets);
    504     if(vf->serialnos)_ogg_free(vf->serialnos);
    505     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
    506 
    507     vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
    508     vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
    509     vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
    510     vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
    511     vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
    512     vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
    513 
    514     vf->offsets[m+1]=end;
    515     vf->offsets[m]=begin;
    516     vf->pcmlengths[m*2+1]=endgran;
    517 
    518   }else{
    519 
    520     long *next_serialno_list=NULL;
    521     int next_serialnos=0;
    522     vorbis_info vi;
    523     vorbis_comment vc;
    524 
    525     /* the below guards against garbage seperating the last and
    526        first pages of two links. */
    527     while(searched<endsearched){
    528       ogg_int64_t bisect;
    529 
    530       if(endsearched-searched<CHUNKSIZE){
    531         bisect=searched;
    532       }else{
    533         bisect=(searched+endsearched)/2;
    534       }
    535 
    536       ret=_seek_helper(vf,bisect);
    537       if(ret)return(ret);
    538 
    539       last=_get_next_page(vf,&og,-1);
    540       if(last==OV_EREAD)return(OV_EREAD);
    541       if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
    542         endsearched=bisect;
    543         if(last>=0)next=last;
    544       }else{
    545         searched=last+og.header_len+og.body_len;
    546       }
    547     }
    548 
    549     /* Bisection point found */
    550 
    551     /* for the time being, fetch end PCM offset the simple way */
    552     {
    553       int testserial = serialno+1;
    554       vf->offset = next;
    555       while(testserial != serialno){
    556         testserial = serialno;
    557         vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&testserial,&searchgran);
    558       }
    559     }
    560 
    561     if(vf->offset!=next){
    562       ret=_seek_helper(vf,next);
    563       if(ret)return(ret);
    564     }
    565 
    566     ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
    567     if(ret)return(ret);
    568     serialno = vf->os.serialno;
    569     dataoffset = vf->offset;
    570 
    571     /* this will consume a page, however the next bistection always
    572        starts with a raw seek */
    573     pcmoffset = _initial_pcmoffset(vf,&vi);
    574 
    575     ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
    576                                  next_serialno_list,next_serialnos,m+1);
    577     if(ret)return(ret);
    578 
    579     if(next_serialno_list)_ogg_free(next_serialno_list);
    580 
    581     vf->offsets[m+1]=next;
    582     vf->serialnos[m+1]=serialno;
    583     vf->dataoffsets[m+1]=dataoffset;
    584 
    585     vf->vi[m+1]=vi;
    586     vf->vc[m+1]=vc;
    587 
    588     vf->pcmlengths[m*2+1]=searchgran;
    589     vf->pcmlengths[m*2+2]=pcmoffset;
    590     vf->pcmlengths[m*2+3]-=pcmoffset;
    591 
    592   }
    593   return(0);
    594 }
    595 
    596 static int _make_decode_ready(OggVorbis_File *vf){
    597   if(vf->ready_state>STREAMSET)return 0;
    598   if(vf->ready_state<STREAMSET)return OV_EFAULT;
    599   if(vf->seekable){
    600     if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
    601       return OV_EBADLINK;
    602   }else{
    603     if(vorbis_synthesis_init(&vf->vd,vf->vi))
    604       return OV_EBADLINK;
    605   }
    606   vorbis_block_init(&vf->vd,&vf->vb);
    607   vf->ready_state=INITSET;
    608   vf->bittrack=0.f;
    609   vf->samptrack=0.f;
    610   return 0;
    611 }
    612 
    613 static int _open_seekable2(OggVorbis_File *vf){
    614   ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
    615   int endserial=vf->os.serialno;
    616   int serialno=vf->os.serialno;
    617 
    618   /* we're partially open and have a first link header state in
    619      storage in vf */
    620 
    621   /* fetch initial PCM offset */
    622   ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
    623 
    624   /* we can seek, so set out learning all about this file */
    625   if(vf->callbacks.seek_func && vf->callbacks.tell_func){
    626     (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
    627     vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
    628   }else{
    629     vf->offset=vf->end=-1;
    630   }
    631 
    632   /* If seek_func is implemented, tell_func must also be implemented */
    633   if(vf->end==-1) return(OV_EINVAL);
    634 
    635   /* Get the offset of the last page of the physical bitstream, or, if
    636      we're lucky the last vorbis page of this link as most OggVorbis
    637      files will contain a single logical bitstream */
    638   end=_get_prev_page_serial(vf,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
    639   if(end<0)return(end);
    640 
    641   /* now determine bitstream structure recursively */
    642   if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial,
    643                               vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
    644 
    645   vf->offsets[0]=0;
    646   vf->serialnos[0]=serialno;
    647   vf->dataoffsets[0]=dataoffset;
    648   vf->pcmlengths[0]=pcmoffset;
    649   vf->pcmlengths[1]-=pcmoffset;
    650 
    651   return(ov_raw_seek(vf,dataoffset));
    652 }
    653 
    654 /* clear out the current logical bitstream decoder */
    655 static void _decode_clear(OggVorbis_File *vf){
    656   vorbis_dsp_clear(&vf->vd);
    657   vorbis_block_clear(&vf->vb);
    658   vf->ready_state=OPENED;
    659 }
    660 
    661 /* fetch and process a packet.  Handles the case where we're at a
    662    bitstream boundary and dumps the decoding machine.  If the decoding
    663    machine is unloaded, it loads it.  It also keeps pcm_offset up to
    664    date (seek and read both use this.  seek uses a special hack with
    665    readp).
    666 
    667    return: <0) error, OV_HOLE (lost packet) or OV_EOF
    668             0) need more data (only if readp==0)
    669             1) got a packet
    670 */
    671 
    672 static int _fetch_and_process_packet(OggVorbis_File *vf,
    673                                      ogg_packet *op_in,
    674                                      int readp,
    675                                      int spanp){
    676   ogg_page og;
    677 
    678   /* handle one packet.  Try to fetch it from current stream state */
    679   /* extract packets from page */
    680   while(1){
    681 
    682     if(vf->ready_state==STREAMSET){
    683       int ret=_make_decode_ready(vf);
    684       if(ret<0)return ret;
    685     }
    686 
    687     /* process a packet if we can. */
    688 
    689     if(vf->ready_state==INITSET){
    690       while(1) {
    691               ogg_packet op;
    692               ogg_packet *op_ptr=(op_in?op_in:&op);
    693         int result=ogg_stream_packetout(&vf->os,op_ptr);
    694         ogg_int64_t granulepos;
    695 
    696         op_in=NULL;
    697         if(result==-1)return(OV_HOLE); /* hole in the data. */
    698         if(result>0){
    699           /* got a packet.  process it */
    700           granulepos=op_ptr->granulepos;
    701           if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
    702                                                     header handling.  The
    703                                                     header packets aren't
    704                                                     audio, so if/when we
    705                                                     submit them,
    706                                                     vorbis_synthesis will
    707                                                     reject them */
    708 
    709             /* suck in the synthesis data and track bitrate */
    710             {
    711               int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
    712               /* for proper use of libvorbis within libvorbisfile,
    713                  oldsamples will always be zero. */
    714               if(oldsamples)return(OV_EFAULT);
    715 
    716               vorbis_synthesis_blockin(&vf->vd,&vf->vb);
    717               vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
    718               vf->bittrack+=op_ptr->bytes*8;
    719             }
    720 
    721             /* update the pcm offset. */
    722             if(granulepos!=-1 && !op_ptr->e_o_s){
    723               int link=(vf->seekable?vf->current_link:0);
    724               int i,samples;
    725 
    726               /* this packet has a pcm_offset on it (the last packet
    727                  completed on a page carries the offset) After processing
    728                  (above), we know the pcm position of the *last* sample
    729                  ready to be returned. Find the offset of the *first*
    730 
    731                  As an aside, this trick is inaccurate if we begin
    732                  reading anew right at the last page; the end-of-stream
    733                  granulepos declares the last frame in the stream, and the
    734                  last packet of the last page may be a partial frame.
    735                  So, we need a previous granulepos from an in-sequence page
    736                  to have a reference point.  Thus the !op_ptr->e_o_s clause
    737                  above */
    738 
    739               if(vf->seekable && link>0)
    740                 granulepos-=vf->pcmlengths[link*2];
    741               if(granulepos<0)granulepos=0; /* actually, this
    742                                                shouldn't be possible
    743                                                here unless the stream
    744                                                is very broken */
    745 
    746               samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
    747 
    748               granulepos-=samples;
    749               for(i=0;i<link;i++)
    750                 granulepos+=vf->pcmlengths[i*2+1];
    751               vf->pcm_offset=granulepos;
    752             }
    753             return(1);
    754           }
    755         }
    756         else
    757           break;
    758       }
    759     }
    760 
    761     if(vf->ready_state>=OPENED){
    762       ogg_int64_t ret;
    763 
    764       while(1){
    765         /* the loop is not strictly necessary, but there's no sense in
    766            doing the extra checks of the larger loop for the common
    767            case in a multiplexed bistream where the page is simply
    768            part of a different logical bitstream; keep reading until
    769            we get one with the correct serialno */
    770 
    771         if(!readp)return(0);
    772         if((ret=_get_next_page(vf,&og,-1))<0){
    773           return(OV_EOF); /* eof. leave unitialized */
    774         }
    775 
    776         /* bitrate tracking; add the header's bytes here, the body bytes
    777            are done by packet above */
    778         vf->bittrack+=og.header_len*8;
    779 
    780         if(vf->ready_state==INITSET){
    781           if(vf->current_serialno!=ogg_page_serialno(&og)){
    782 
    783             /* two possibilities:
    784                1) our decoding just traversed a bitstream boundary
    785                2) another stream is multiplexed into this logical section */
    786 
    787             if(ogg_page_bos(&og)){
    788               /* boundary case */
    789               if(!spanp)
    790                 return(OV_EOF);
    791 
    792               _decode_clear(vf);
    793 
    794               if(!vf->seekable){
    795                 vorbis_info_clear(vf->vi);
    796                 vorbis_comment_clear(vf->vc);
    797               }
    798               break;
    799 
    800             }else
    801               continue; /* possibility #2 */
    802           }
    803         }
    804 
    805         break;
    806       }
    807     }
    808 
    809     /* Do we need to load a new machine before submitting the page? */
    810     /* This is different in the seekable and non-seekable cases.
    811 
    812        In the seekable case, we already have all the header
    813        information loaded and cached; we just initialize the machine
    814        with it and continue on our merry way.
    815 
    816        In the non-seekable (streaming) case, we'll only be at a
    817        boundary if we just left the previous logical bitstream and
    818        we're now nominally at the header of the next bitstream
    819     */
    820 
    821     if(vf->ready_state!=INITSET){
    822       int link;
    823 
    824       if(vf->ready_state<STREAMSET){
    825         if(vf->seekable){
    826           long serialno = ogg_page_serialno(&og);
    827 
    828           /* match the serialno to bitstream section.  We use this rather than
    829              offset positions to avoid problems near logical bitstream
    830              boundaries */
    831 
    832           for(link=0;link<vf->links;link++)
    833             if(vf->serialnos[link]==serialno)break;
    834 
    835           if(link==vf->links) continue; /* not the desired Vorbis
    836                                            bitstream section; keep
    837                                            trying */
    838 
    839           vf->current_serialno=serialno;
    840           vf->current_link=link;
    841 
    842           ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
    843           vf->ready_state=STREAMSET;
    844 
    845         }else{
    846           /* we're streaming */
    847           /* fetch the three header packets, build the info struct */
    848 
    849           int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
    850           if(ret)return(ret);
    851           vf->current_serialno=vf->os.serialno;
    852           vf->current_link++;
    853           link=0;
    854         }
    855       }
    856     }
    857 
    858     /* the buffered page is the data we want, and we're ready for it;
    859        add it to the stream state */
    860     ogg_stream_pagein(&vf->os,&og);
    861 
    862   }
    863 }
    864 
    865 /* if, eg, 64 bit stdio is configured by default, this will build with
    866    fseek64 */
    867 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
    868   if(f==NULL)return(-1);
    869   return fseek(f,off,whence);
    870 }
    871 
    872 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
    873                      long ibytes, ov_callbacks callbacks){
    874   int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
    875   long *serialno_list=NULL;
    876   int serialno_list_size=0;
    877   int ret;
    878 
    879   memset(vf,0,sizeof(*vf));
    880   vf->datasource=f;
    881   vf->callbacks = callbacks;
    882 
    883   /* init the framing state */
    884   ogg_sync_init(&vf->oy);
    885 
    886   /* perhaps some data was previously read into a buffer for testing
    887      against other stream types.  Allow initialization from this
    888      previously read data (especially as we may be reading from a
    889      non-seekable stream) */
    890   if(initial){
    891     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
    892     memcpy(buffer,initial,ibytes);
    893     ogg_sync_wrote(&vf->oy,ibytes);
    894   }
    895 
    896   /* can we seek? Stevens suggests the seek test was portable */
    897   if(offsettest!=-1)vf->seekable=1;
    898 
    899   /* No seeking yet; Set up a 'single' (current) logical bitstream
    900      entry for partial open */
    901   vf->links=1;
    902   vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
    903   vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
    904   ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
    905 
    906   /* Fetch all BOS pages, store the vorbis header and all seen serial
    907      numbers, load subsequent vorbis setup headers */
    908   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
    909     vf->datasource=NULL;
    910     ov_clear(vf);
    911   }else{
    912     /* serial number list for first link needs to be held somewhere
    913        for second stage of seekable stream open; this saves having to
    914        seek/reread first link's serialnumber data then. */
    915     vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos));
    916     vf->serialnos[0]=vf->current_serialno;
    917     vf->serialnos[1]=serialno_list_size;
    918     memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
    919 
    920     vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
    921     vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
    922     vf->offsets[0]=0;
    923     vf->dataoffsets[0]=vf->offset;
    924     vf->current_serialno=vf->os.serialno;
    925 
    926     vf->ready_state=PARTOPEN;
    927   }
    928   if(serialno_list)_ogg_free(serialno_list);
    929   return(ret);
    930 }
    931 
    932 static int _ov_open2(OggVorbis_File *vf){
    933   if(vf->ready_state != PARTOPEN) return OV_EINVAL;
    934   vf->ready_state=OPENED;
    935   if(vf->seekable){
    936     int ret=_open_seekable2(vf);
    937     if(ret){
    938       vf->datasource=NULL;
    939       ov_clear(vf);
    940     }
    941     return(ret);
    942   }else
    943     vf->ready_state=STREAMSET;
    944 
    945   return 0;
    946 }
    947 
    948 
    949 /* clear out the OggVorbis_File struct */
    950 int ov_clear(OggVorbis_File *vf){
    951   if(vf){
    952     vorbis_block_clear(&vf->vb);
    953     vorbis_dsp_clear(&vf->vd);
    954     ogg_stream_clear(&vf->os);
    955 
    956     if(vf->vi && vf->links){
    957       int i;
    958       for(i=0;i<vf->links;i++){
    959         vorbis_info_clear(vf->vi+i);
    960         vorbis_comment_clear(vf->vc+i);
    961       }
    962       _ogg_free(vf->vi);
    963       _ogg_free(vf->vc);
    964     }
    965     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
    966     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
    967     if(vf->serialnos)_ogg_free(vf->serialnos);
    968     if(vf->offsets)_ogg_free(vf->offsets);
    969     ogg_sync_clear(&vf->oy);
    970     if(vf->datasource && vf->callbacks.close_func)
    971       (vf->callbacks.close_func)(vf->datasource);
    972     memset(vf,0,sizeof(*vf));
    973   }
    974 #ifdef DEBUG_LEAKS
    975   _VDBG_dump();
    976 #endif
    977   return(0);
    978 }
    979 
    980 /* inspects the OggVorbis file and finds/documents all the logical
    981    bitstreams contained in it.  Tries to be tolerant of logical
    982    bitstream sections that are truncated/woogie.
    983 
    984    return: -1) error
    985             0) OK
    986 */
    987 
    988 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
    989     ov_callbacks callbacks){
    990   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
    991   if(ret)return ret;
    992   return _ov_open2(vf);
    993 }
    994 
    995 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
    996   ov_callbacks callbacks = {
    997     (size_t (*)(void *, size_t, size_t, void *))  fread,
    998     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
    999     (int (*)(void *))                             fclose,
   1000     (long (*)(void *))                            ftell
   1001   };
   1002 
   1003   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
   1004 }
   1005 
   1006 int ov_fopen(char *path,OggVorbis_File *vf){
   1007   int ret;
   1008   FILE *f = fopen(path,"rb");
   1009   if(!f) return -1;
   1010 
   1011   ret = ov_open(f,vf,NULL,0);
   1012   if(ret) fclose(f);
   1013   return ret;
   1014 }
   1015 
   1016 
   1017 /* cheap hack for game usage where downsampling is desirable; there's
   1018    no need for SRC as we can just do it cheaply in libvorbis. */
   1019 
   1020 int ov_halfrate(OggVorbis_File *vf,int flag){
   1021   int i;
   1022   if(vf->vi==NULL)return OV_EINVAL;
   1023   if(!vf->seekable)return OV_EINVAL;
   1024   if(vf->ready_state>=STREAMSET)
   1025     _decode_clear(vf); /* clear out stream state; later on libvorbis
   1026                           will be able to swap this on the fly, but
   1027                           for now dumping the decode machine is needed
   1028                           to reinit the MDCT lookups.  1.1 libvorbis
   1029                           is planned to be able to switch on the fly */
   1030 
   1031   for(i=0;i<vf->links;i++){
   1032     if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
   1033       ov_halfrate(vf,0);
   1034       return OV_EINVAL;
   1035     }
   1036   }
   1037   return 0;
   1038 }
   1039 
   1040 int ov_halfrate_p(OggVorbis_File *vf){
   1041   if(vf->vi==NULL)return OV_EINVAL;
   1042   return vorbis_synthesis_halfrate_p(vf->vi);
   1043 }
   1044 
   1045 /* Only partially open the vorbis file; test for Vorbisness, and load
   1046    the headers for the first chain.  Do not seek (although test for
   1047    seekability).  Use ov_test_open to finish opening the file, else
   1048    ov_clear to close/free it. Same return codes as open. */
   1049 
   1050 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
   1051     ov_callbacks callbacks)
   1052 {
   1053   return _ov_open1(f,vf,initial,ibytes,callbacks);
   1054 }
   1055 
   1056 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
   1057   ov_callbacks callbacks = {
   1058     (size_t (*)(void *, size_t, size_t, void *))  fread,
   1059     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
   1060     (int (*)(void *))                             fclose,
   1061     (long (*)(void *))                            ftell
   1062   };
   1063 
   1064   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
   1065 }
   1066 
   1067 int ov_test_open(OggVorbis_File *vf){
   1068   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
   1069   return _ov_open2(vf);
   1070 }
   1071 
   1072 /* How many logical bitstreams in this physical bitstream? */
   1073 long ov_streams(OggVorbis_File *vf){
   1074   return vf->links;
   1075 }
   1076 
   1077 /* Is the FILE * associated with vf seekable? */
   1078 long ov_seekable(OggVorbis_File *vf){
   1079   return vf->seekable;
   1080 }
   1081 
   1082 /* returns the bitrate for a given logical bitstream or the entire
   1083    physical bitstream.  If the file is open for random access, it will
   1084    find the *actual* average bitrate.  If the file is streaming, it
   1085    returns the nominal bitrate (if set) else the average of the
   1086    upper/lower bounds (if set) else -1 (unset).
   1087 
   1088    If you want the actual bitrate field settings, get them from the
   1089    vorbis_info structs */
   1090 
   1091 long ov_bitrate(OggVorbis_File *vf,int i){
   1092   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1093   if(i>=vf->links)return(OV_EINVAL);
   1094   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
   1095   if(i<0){
   1096     ogg_int64_t bits=0;
   1097     int i;
   1098     float br;
   1099     for(i=0;i<vf->links;i++)
   1100       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
   1101     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
   1102      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
   1103      * so this is slightly transformed to make it work.
   1104      */
   1105     br = bits/ov_time_total(vf,-1);
   1106     return(rint(br));
   1107   }else{
   1108     if(vf->seekable){
   1109       /* return the actual bitrate */
   1110       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
   1111     }else{
   1112       /* return nominal if set */
   1113       if(vf->vi[i].bitrate_nominal>0){
   1114         return vf->vi[i].bitrate_nominal;
   1115       }else{
   1116         if(vf->vi[i].bitrate_upper>0){
   1117           if(vf->vi[i].bitrate_lower>0){
   1118             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
   1119           }else{
   1120             return vf->vi[i].bitrate_upper;
   1121           }
   1122         }
   1123         return(OV_FALSE);
   1124       }
   1125     }
   1126   }
   1127 }
   1128 
   1129 /* returns the actual bitrate since last call.  returns -1 if no
   1130    additional data to offer since last call (or at beginning of stream),
   1131    EINVAL if stream is only partially open
   1132 */
   1133 long ov_bitrate_instant(OggVorbis_File *vf){
   1134   int link=(vf->seekable?vf->current_link:0);
   1135   long ret;
   1136   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1137   if(vf->samptrack==0)return(OV_FALSE);
   1138   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
   1139   vf->bittrack=0.f;
   1140   vf->samptrack=0.f;
   1141   return(ret);
   1142 }
   1143 
   1144 /* Guess */
   1145 long ov_serialnumber(OggVorbis_File *vf,int i){
   1146   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
   1147   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
   1148   if(i<0){
   1149     return(vf->current_serialno);
   1150   }else{
   1151     return(vf->serialnos[i]);
   1152   }
   1153 }
   1154 
   1155 /* returns: total raw (compressed) length of content if i==-1
   1156             raw (compressed) length of that logical bitstream for i==0 to n
   1157             OV_EINVAL if the stream is not seekable (we can't know the length)
   1158             or if stream is only partially open
   1159 */
   1160 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
   1161   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1162   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   1163   if(i<0){
   1164     ogg_int64_t acc=0;
   1165     int i;
   1166     for(i=0;i<vf->links;i++)
   1167       acc+=ov_raw_total(vf,i);
   1168     return(acc);
   1169   }else{
   1170     return(vf->offsets[i+1]-vf->offsets[i]);
   1171   }
   1172 }
   1173 
   1174 /* returns: total PCM length (samples) of content if i==-1 PCM length
   1175             (samples) of that logical bitstream for i==0 to n
   1176             OV_EINVAL if the stream is not seekable (we can't know the
   1177             length) or only partially open
   1178 */
   1179 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
   1180   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1181   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   1182   if(i<0){
   1183     ogg_int64_t acc=0;
   1184     int i;
   1185     for(i=0;i<vf->links;i++)
   1186       acc+=ov_pcm_total(vf,i);
   1187     return(acc);
   1188   }else{
   1189     return(vf->pcmlengths[i*2+1]);
   1190   }
   1191 }
   1192 
   1193 /* returns: total seconds of content if i==-1
   1194             seconds in that logical bitstream for i==0 to n
   1195             OV_EINVAL if the stream is not seekable (we can't know the
   1196             length) or only partially open
   1197 */
   1198 double ov_time_total(OggVorbis_File *vf,int i){
   1199   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1200   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   1201   if(i<0){
   1202     double acc=0;
   1203     int i;
   1204     for(i=0;i<vf->links;i++)
   1205       acc+=ov_time_total(vf,i);
   1206     return(acc);
   1207   }else{
   1208     return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
   1209   }
   1210 }
   1211 
   1212 /* seek to an offset relative to the *compressed* data. This also
   1213    scans packets to update the PCM cursor. It will cross a logical
   1214    bitstream boundary, but only if it can't get any packets out of the
   1215    tail of the bitstream we seek to (so no surprises).
   1216 
   1217    returns zero on success, nonzero on failure */
   1218 
   1219 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
   1220   ogg_stream_state work_os;
   1221   int ret;
   1222 
   1223   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1224   if(!vf->seekable)
   1225     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
   1226 
   1227   if(pos<0 || pos>vf->end)return(OV_EINVAL);
   1228 
   1229   /* don't yet clear out decoding machine (if it's initialized), in
   1230      the case we're in the same link.  Restart the decode lapping, and
   1231      let _fetch_and_process_packet deal with a potential bitstream
   1232      boundary */
   1233   vf->pcm_offset=-1;
   1234   ogg_stream_reset_serialno(&vf->os,
   1235                             vf->current_serialno); /* must set serialno */
   1236   vorbis_synthesis_restart(&vf->vd);
   1237 
   1238   ret=_seek_helper(vf,pos);
   1239   if(ret)goto seek_error;
   1240 
   1241   /* we need to make sure the pcm_offset is set, but we don't want to
   1242      advance the raw cursor past good packets just to get to the first
   1243      with a granulepos.  That's not equivalent behavior to beginning
   1244      decoding as immediately after the seek position as possible.
   1245 
   1246      So, a hack.  We use two stream states; a local scratch state and
   1247      the shared vf->os stream state.  We use the local state to
   1248      scan, and the shared state as a buffer for later decode.
   1249 
   1250      Unfortuantely, on the last page we still advance to last packet
   1251      because the granulepos on the last page is not necessarily on a
   1252      packet boundary, and we need to make sure the granpos is
   1253      correct.
   1254   */
   1255 
   1256   {
   1257     ogg_page og;
   1258     ogg_packet op;
   1259     int lastblock=0;
   1260     int accblock=0;
   1261     int thisblock=0;
   1262     int lastflag=0;
   1263     int firstflag=0;
   1264     ogg_int64_t pagepos=-1;
   1265 
   1266     ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
   1267     ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
   1268                                    return from not necessarily
   1269                                    starting from the beginning */
   1270 
   1271     while(1){
   1272       if(vf->ready_state>=STREAMSET){
   1273         /* snarf/scan a packet if we can */
   1274         int result=ogg_stream_packetout(&work_os,&op);
   1275 
   1276         if(result>0){
   1277 
   1278           if(vf->vi[vf->current_link].codec_setup){
   1279             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
   1280             if(thisblock<0){
   1281               ogg_stream_packetout(&vf->os,NULL);
   1282               thisblock=0;
   1283             }else{
   1284 
   1285               /* We can't get a guaranteed correct pcm position out of the
   1286                  last page in a stream because it might have a 'short'
   1287                  granpos, which can only be detected in the presence of a
   1288                  preceeding page.  However, if the last page is also the first
   1289                  page, the granpos rules of a first page take precedence.  Not
   1290                  only that, but for first==last, the EOS page must be treated
   1291                  as if its a normal first page for the stream to open/play. */
   1292               if(lastflag && !firstflag)
   1293                 ogg_stream_packetout(&vf->os,NULL);
   1294               else
   1295                 if(lastblock)accblock+=(lastblock+thisblock)>>2;
   1296             }
   1297 
   1298             if(op.granulepos!=-1){
   1299               int i,link=vf->current_link;
   1300               ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
   1301               if(granulepos<0)granulepos=0;
   1302 
   1303               for(i=0;i<link;i++)
   1304                 granulepos+=vf->pcmlengths[i*2+1];
   1305               vf->pcm_offset=granulepos-accblock;
   1306               if(vf->pcm_offset<0)vf->pcm_offset=0;
   1307               break;
   1308             }
   1309             lastblock=thisblock;
   1310             continue;
   1311           }else
   1312             ogg_stream_packetout(&vf->os,NULL);
   1313         }
   1314       }
   1315 
   1316       if(!lastblock){
   1317         pagepos=_get_next_page(vf,&og,-1);
   1318         if(pagepos<0){
   1319           vf->pcm_offset=ov_pcm_total(vf,-1);
   1320           break;
   1321         }
   1322       }else{
   1323         /* huh?  Bogus stream with packets but no granulepos */
   1324         vf->pcm_offset=-1;
   1325         break;
   1326       }
   1327 
   1328       /* has our decoding just traversed a bitstream boundary? */
   1329       if(vf->ready_state>=STREAMSET){
   1330         if(vf->current_serialno!=ogg_page_serialno(&og)){
   1331 
   1332           /* two possibilities:
   1333              1) our decoding just traversed a bitstream boundary
   1334              2) another stream is multiplexed into this logical section? */
   1335 
   1336           if(ogg_page_bos(&og)){
   1337             /* we traversed */
   1338             _decode_clear(vf); /* clear out stream state */
   1339             ogg_stream_clear(&work_os);
   1340           } /* else, do nothing; next loop will scoop another page */
   1341         }
   1342       }
   1343 
   1344       if(vf->ready_state<STREAMSET){
   1345         int link;
   1346         long serialno = ogg_page_serialno(&og);
   1347 
   1348         for(link=0;link<vf->links;link++)
   1349           if(vf->serialnos[link]==serialno)break;
   1350 
   1351         if(link==vf->links) continue; /* not the desired Vorbis
   1352                                          bitstream section; keep
   1353                                          trying */
   1354         vf->current_link=link;
   1355         vf->current_serialno=serialno;
   1356         ogg_stream_reset_serialno(&vf->os,serialno);
   1357         ogg_stream_reset_serialno(&work_os,serialno);
   1358         vf->ready_state=STREAMSET;
   1359         firstflag=(pagepos<=vf->dataoffsets[link]);
   1360       }
   1361 
   1362       ogg_stream_pagein(&vf->os,&og);
   1363       ogg_stream_pagein(&work_os,&og);
   1364       lastflag=ogg_page_eos(&og);
   1365 
   1366     }
   1367   }
   1368 
   1369   ogg_stream_clear(&work_os);
   1370   vf->bittrack=0.f;
   1371   vf->samptrack=0.f;
   1372   return(0);
   1373 
   1374  seek_error:
   1375   /* dump the machine so we're in a known state */
   1376   vf->pcm_offset=-1;
   1377   ogg_stream_clear(&work_os);
   1378   _decode_clear(vf);
   1379   return OV_EBADLINK;
   1380 }
   1381 
   1382 /* Page granularity seek (faster than sample granularity because we
   1383    don't do the last bit of decode to find a specific sample).
   1384 
   1385    Seek to the last [granule marked] page preceeding the specified pos
   1386    location, such that decoding past the returned point will quickly
   1387    arrive at the requested position. */
   1388 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
   1389   int link=-1;
   1390   ogg_int64_t result=0;
   1391   ogg_int64_t total=ov_pcm_total(vf,-1);
   1392 
   1393   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1394   if(!vf->seekable)return(OV_ENOSEEK);
   1395 
   1396   if(pos<0 || pos>total)return(OV_EINVAL);
   1397 
   1398   /* which bitstream section does this pcm offset occur in? */
   1399   for(link=vf->links-1;link>=0;link--){
   1400     total-=vf->pcmlengths[link*2+1];
   1401     if(pos>=total)break;
   1402   }
   1403 
   1404   /* search within the logical bitstream for the page with the highest
   1405      pcm_pos preceeding (or equal to) pos.  There is a danger here;
   1406      missing pages or incorrect frame number information in the
   1407      bitstream could make our task impossible.  Account for that (it
   1408      would be an error condition) */
   1409 
   1410   /* new search algorithm by HB (Nicholas Vinen) */
   1411   {
   1412     ogg_int64_t end=vf->offsets[link+1];
   1413     ogg_int64_t begin=vf->offsets[link];
   1414     ogg_int64_t begintime = vf->pcmlengths[link*2];
   1415     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
   1416     ogg_int64_t target=pos-total+begintime;
   1417     ogg_int64_t best=begin;
   1418 
   1419     ogg_page og;
   1420     while(begin<end){
   1421       ogg_int64_t bisect;
   1422 
   1423       if(end-begin<CHUNKSIZE){
   1424         bisect=begin;
   1425       }else{
   1426         /* take a (pretty decent) guess. */
   1427         bisect=begin +
   1428           (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime))
   1429           - CHUNKSIZE;
   1430         if(bisect<=begin)
   1431           bisect=begin+1;
   1432       }
   1433 
   1434       result=_seek_helper(vf,bisect);
   1435       if(result) goto seek_error;
   1436 
   1437       while(begin<end){
   1438         result=_get_next_page(vf,&og,end-vf->offset);
   1439         if(result==OV_EREAD) goto seek_error;
   1440         if(result<0){
   1441           if(bisect<=begin+1)
   1442             end=begin; /* found it */
   1443           else{
   1444             if(bisect==0) goto seek_error;
   1445             bisect-=CHUNKSIZE;
   1446             if(bisect<=begin)bisect=begin+1;
   1447             result=_seek_helper(vf,bisect);
   1448             if(result) goto seek_error;
   1449           }
   1450         }else{
   1451           ogg_int64_t granulepos;
   1452 
   1453           if(ogg_page_serialno(&og)!=vf->serialnos[link])
   1454             continue;
   1455 
   1456           granulepos=ogg_page_granulepos(&og);
   1457           if(granulepos==-1)continue;
   1458 
   1459           if(granulepos<target){
   1460             best=result;  /* raw offset of packet with granulepos */
   1461             begin=vf->offset; /* raw offset of next page */
   1462             begintime=granulepos;
   1463 
   1464             if(target-begintime>44100)break;
   1465             bisect=begin; /* *not* begin + 1 */
   1466           }else{
   1467             if(bisect<=begin+1)
   1468               end=begin;  /* found it */
   1469             else{
   1470               if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
   1471                 end=result;
   1472                 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
   1473                 if(bisect<=begin)bisect=begin+1;
   1474                 result=_seek_helper(vf,bisect);
   1475                 if(result) goto seek_error;
   1476               }else{
   1477                 end=bisect;
   1478                 endtime=granulepos;
   1479                 break;
   1480               }
   1481             }
   1482           }
   1483         }
   1484       }
   1485     }
   1486 
   1487     /* found our page. seek to it, update pcm offset. Easier case than
   1488        raw_seek, don't keep packets preceeding granulepos. */
   1489     {
   1490       ogg_page og;
   1491       ogg_packet op;
   1492 
   1493       /* seek */
   1494       result=_seek_helper(vf,best);
   1495       vf->pcm_offset=-1;
   1496       if(result) goto seek_error;
   1497       result=_get_next_page(vf,&og,-1);
   1498       if(result<0) goto seek_error;
   1499 
   1500       if(link!=vf->current_link){
   1501         /* Different link; dump entire decode machine */
   1502         _decode_clear(vf);
   1503 
   1504         vf->current_link=link;
   1505         vf->current_serialno=vf->serialnos[link];
   1506         vf->ready_state=STREAMSET;
   1507 
   1508       }else{
   1509         vorbis_synthesis_restart(&vf->vd);
   1510       }
   1511 
   1512       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
   1513       ogg_stream_pagein(&vf->os,&og);
   1514 
   1515       /* pull out all but last packet; the one with granulepos */
   1516       while(1){
   1517         result=ogg_stream_packetpeek(&vf->os,&op);
   1518         if(result==0){
   1519           /* !!! the packet finishing this page originated on a
   1520              preceeding page. Keep fetching previous pages until we
   1521              get one with a granulepos or without the 'continued' flag
   1522              set.  Then just use raw_seek for simplicity. */
   1523 
   1524           result=_seek_helper(vf,best);
   1525           if(result<0) goto seek_error;
   1526 
   1527           while(1){
   1528             result=_get_prev_page(vf,&og);
   1529             if(result<0) goto seek_error;
   1530             if(ogg_page_serialno(&og)==vf->current_serialno &&
   1531                (ogg_page_granulepos(&og)>-1 ||
   1532                 !ogg_page_continued(&og))){
   1533               return ov_raw_seek(vf,result);
   1534             }
   1535             vf->offset=result;
   1536           }
   1537         }
   1538         if(result<0){
   1539           result = OV_EBADPACKET;
   1540           goto seek_error;
   1541         }
   1542         if(op.granulepos!=-1){
   1543           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
   1544           if(vf->pcm_offset<0)vf->pcm_offset=0;
   1545           vf->pcm_offset+=total;
   1546           break;
   1547         }else
   1548           result=ogg_stream_packetout(&vf->os,NULL);
   1549       }
   1550     }
   1551   }
   1552 
   1553   /* verify result */
   1554   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
   1555     result=OV_EFAULT;
   1556     goto seek_error;
   1557   }
   1558   vf->bittrack=0.f;
   1559   vf->samptrack=0.f;
   1560   return(0);
   1561 
   1562  seek_error:
   1563   /* dump machine so we're in a known state */
   1564   vf->pcm_offset=-1;
   1565   _decode_clear(vf);
   1566   return (int)result;
   1567 }
   1568 
   1569 /* seek to a sample offset relative to the decompressed pcm stream
   1570    returns zero on success, nonzero on failure */
   1571 
   1572 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
   1573   int thisblock,lastblock=0;
   1574   int ret=ov_pcm_seek_page(vf,pos);
   1575   if(ret<0)return(ret);
   1576   if((ret=_make_decode_ready(vf)))return ret;
   1577 
   1578   /* discard leading packets we don't need for the lapping of the
   1579      position we want; don't decode them */
   1580 
   1581   while(1){
   1582     ogg_packet op;
   1583     ogg_page og;
   1584 
   1585     int ret=ogg_stream_packetpeek(&vf->os,&op);
   1586     if(ret>0){
   1587       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
   1588       if(thisblock<0){
   1589         ogg_stream_packetout(&vf->os,NULL);
   1590         continue; /* non audio packet */
   1591       }
   1592       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
   1593 
   1594       if(vf->pcm_offset+((thisblock+
   1595                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
   1596 
   1597       /* remove the packet from packet queue and track its granulepos */
   1598       ogg_stream_packetout(&vf->os,NULL);
   1599       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
   1600                                                    only tracking, no
   1601                                                    pcm_decode */
   1602       vorbis_synthesis_blockin(&vf->vd,&vf->vb);
   1603 
   1604       /* end of logical stream case is hard, especially with exact
   1605          length positioning. */
   1606 
   1607       if(op.granulepos>-1){
   1608         int i;
   1609         /* always believe the stream markers */
   1610         vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
   1611         if(vf->pcm_offset<0)vf->pcm_offset=0;
   1612         for(i=0;i<vf->current_link;i++)
   1613           vf->pcm_offset+=vf->pcmlengths[i*2+1];
   1614       }
   1615 
   1616       lastblock=thisblock;
   1617 
   1618     }else{
   1619       if(ret<0 && ret!=OV_HOLE)break;
   1620 
   1621       /* suck in a new page */
   1622       if(_get_next_page(vf,&og,-1)<0)break;
   1623       if(ogg_page_bos(&og))_decode_clear(vf);
   1624 
   1625       if(vf->ready_state<STREAMSET){
   1626         long serialno=ogg_page_serialno(&og);
   1627         int link;
   1628 
   1629         for(link=0;link<vf->links;link++)
   1630           if(vf->serialnos[link]==serialno)break;
   1631         if(link==vf->links) continue;
   1632         vf->current_link=link;
   1633 
   1634         vf->ready_state=STREAMSET;
   1635         vf->current_serialno=ogg_page_serialno(&og);
   1636         ogg_stream_reset_serialno(&vf->os,serialno);
   1637         ret=_make_decode_ready(vf);
   1638         if(ret)return ret;
   1639         lastblock=0;
   1640       }
   1641 
   1642       ogg_stream_pagein(&vf->os,&og);
   1643     }
   1644   }
   1645 
   1646   vf->bittrack=0.f;
   1647   vf->samptrack=0.f;
   1648   /* discard samples until we reach the desired position. Crossing a
   1649      logical bitstream boundary with abandon is OK. */
   1650   while(vf->pcm_offset<pos){
   1651     ogg_int64_t target=pos-vf->pcm_offset;
   1652     long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
   1653 
   1654     if(samples>target)samples=target;
   1655     vorbis_synthesis_read(&vf->vd,samples);
   1656     vf->pcm_offset+=samples;
   1657 
   1658     if(samples<target)
   1659       if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
   1660         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
   1661   }
   1662   return 0;
   1663 }
   1664 
   1665 /* seek to a playback time relative to the decompressed pcm stream
   1666    returns zero on success, nonzero on failure */
   1667 int ov_time_seek(OggVorbis_File *vf,double seconds){
   1668   /* translate time to PCM position and call ov_pcm_seek */
   1669 
   1670   int link=-1;
   1671   ogg_int64_t pcm_total=0;
   1672   double time_total=0.;
   1673 
   1674   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1675   if(!vf->seekable)return(OV_ENOSEEK);
   1676   if(seconds<0)return(OV_EINVAL);
   1677 
   1678   /* which bitstream section does this time offset occur in? */
   1679   for(link=0;link<vf->links;link++){
   1680     double addsec = ov_time_total(vf,link);
   1681     if(seconds<time_total+addsec)break;
   1682     time_total+=addsec;
   1683     pcm_total+=vf->pcmlengths[link*2+1];
   1684   }
   1685 
   1686   if(link==vf->links)return(OV_EINVAL);
   1687 
   1688   /* enough information to convert time offset to pcm offset */
   1689   {
   1690     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
   1691     return(ov_pcm_seek(vf,target));
   1692   }
   1693 }
   1694 
   1695 /* page-granularity version of ov_time_seek
   1696    returns zero on success, nonzero on failure */
   1697 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
   1698   /* translate time to PCM position and call ov_pcm_seek */
   1699 
   1700   int link=-1;
   1701   ogg_int64_t pcm_total=0;
   1702   double time_total=0.;
   1703 
   1704   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1705   if(!vf->seekable)return(OV_ENOSEEK);
   1706   if(seconds<0)return(OV_EINVAL);
   1707 
   1708   /* which bitstream section does this time offset occur in? */
   1709   for(link=0;link<vf->links;link++){
   1710     double addsec = ov_time_total(vf,link);
   1711     if(seconds<time_total+addsec)break;
   1712     time_total+=addsec;
   1713     pcm_total+=vf->pcmlengths[link*2+1];
   1714   }
   1715 
   1716   if(link==vf->links)return(OV_EINVAL);
   1717 
   1718   /* enough information to convert time offset to pcm offset */
   1719   {
   1720     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
   1721     return(ov_pcm_seek_page(vf,target));
   1722   }
   1723 }
   1724 
   1725 /* tell the current stream offset cursor.  Note that seek followed by
   1726    tell will likely not give the set offset due to caching */
   1727 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
   1728   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1729   return(vf->offset);
   1730 }
   1731 
   1732 /* return PCM offset (sample) of next PCM sample to be read */
   1733 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
   1734   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1735   return(vf->pcm_offset);
   1736 }
   1737 
   1738 /* return time offset (seconds) of next PCM sample to be read */
   1739 double ov_time_tell(OggVorbis_File *vf){
   1740   int link=0;
   1741   ogg_int64_t pcm_total=0;
   1742   double time_total=0.f;
   1743 
   1744   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1745   if(vf->seekable){
   1746     pcm_total=ov_pcm_total(vf,-1);
   1747     time_total=ov_time_total(vf,-1);
   1748 
   1749     /* which bitstream section does this time offset occur in? */
   1750     for(link=vf->links-1;link>=0;link--){
   1751       pcm_total-=vf->pcmlengths[link*2+1];
   1752       time_total-=ov_time_total(vf,link);
   1753       if(vf->pcm_offset>=pcm_total)break;
   1754     }
   1755   }
   1756 
   1757   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
   1758 }
   1759 
   1760 /*  link:   -1) return the vorbis_info struct for the bitstream section
   1761                 currently being decoded
   1762            0-n) to request information for a specific bitstream section
   1763 
   1764     In the case of a non-seekable bitstream, any call returns the
   1765     current bitstream.  NULL in the case that the machine is not
   1766     initialized */
   1767 
   1768 vorbis_info *ov_info(OggVorbis_File *vf,int link){
   1769   if(vf->seekable){
   1770     if(link<0)
   1771       if(vf->ready_state>=STREAMSET)
   1772         return vf->vi+vf->current_link;
   1773       else
   1774       return vf->vi;
   1775     else
   1776       if(link>=vf->links)
   1777         return NULL;
   1778       else
   1779         return vf->vi+link;
   1780   }else{
   1781     return vf->vi;
   1782   }
   1783 }
   1784 
   1785 /* grr, strong typing, grr, no templates/inheritence, grr */
   1786 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
   1787   if(vf->seekable){
   1788     if(link<0)
   1789       if(vf->ready_state>=STREAMSET)
   1790         return vf->vc+vf->current_link;
   1791       else
   1792         return vf->vc;
   1793     else
   1794       if(link>=vf->links)
   1795         return NULL;
   1796       else
   1797         return vf->vc+link;
   1798   }else{
   1799     return vf->vc;
   1800   }
   1801 }
   1802 
   1803 static int host_is_big_endian() {
   1804   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
   1805   unsigned char *bytewise = (unsigned char *)&pattern;
   1806   if (bytewise[0] == 0xfe) return 1;
   1807   return 0;
   1808 }
   1809 
   1810 /* up to this point, everything could more or less hide the multiple
   1811    logical bitstream nature of chaining from the toplevel application
   1812    if the toplevel application didn't particularly care.  However, at
   1813    the point that we actually read audio back, the multiple-section
   1814    nature must surface: Multiple bitstream sections do not necessarily
   1815    have to have the same number of channels or sampling rate.
   1816 
   1817    ov_read returns the sequential logical bitstream number currently
   1818    being decoded along with the PCM data in order that the toplevel
   1819    application can take action on channel/sample rate changes.  This
   1820    number will be incremented even for streamed (non-seekable) streams
   1821    (for seekable streams, it represents the actual logical bitstream
   1822    index within the physical bitstream.  Note that the accessor
   1823    functions above are aware of this dichotomy).
   1824 
   1825    ov_read_filter is exactly the same as ov_read except that it processes
   1826    the decoded audio data through a filter before packing it into the
   1827    requested format. This gives greater accuracy than applying a filter
   1828    after the audio has been converted into integral PCM.
   1829 
   1830    input values: buffer) a buffer to hold packed PCM data for return
   1831                  length) the byte length requested to be placed into buffer
   1832                  bigendianp) should the data be packed LSB first (0) or
   1833                              MSB first (1)
   1834                  word) word size for output.  currently 1 (byte) or
   1835                        2 (16 bit short)
   1836 
   1837    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
   1838                    0) EOF
   1839                    n) number of bytes of PCM actually returned.  The
   1840                    below works on a packet-by-packet basis, so the
   1841                    return length is not related to the 'length' passed
   1842                    in, just guaranteed to fit.
   1843 
   1844             *section) set to the logical bitstream number */
   1845 
   1846 long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
   1847                     int bigendianp,int word,int sgned,int *bitstream,
   1848                     void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
   1849   int i,j;
   1850   int host_endian = host_is_big_endian();
   1851 
   1852   float **pcm;
   1853   long samples;
   1854 
   1855   if(vf->ready_state<OPENED)return(OV_EINVAL);
   1856 
   1857   while(1){
   1858     if(vf->ready_state==INITSET){
   1859       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
   1860       if(samples)break;
   1861     }
   1862 
   1863     /* suck in another packet */
   1864     {
   1865       int ret=_fetch_and_process_packet(vf,NULL,1,1);
   1866       if(ret==OV_EOF)
   1867         return(0);
   1868       if(ret<=0)
   1869         return(ret);
   1870     }
   1871 
   1872   }
   1873 
   1874   if(samples>0){
   1875 
   1876     /* yay! proceed to pack data into the byte buffer */
   1877 
   1878     long channels=ov_info(vf,-1)->channels;
   1879     long bytespersample=word * channels;
   1880     vorbis_fpu_control fpu;
   1881     if(samples>length/bytespersample)samples=length/bytespersample;
   1882 
   1883     if(samples <= 0)
   1884       return OV_EINVAL;
   1885 
   1886     /* Here. */
   1887     if(filter)
   1888       filter(pcm,channels,samples,filter_param);
   1889 
   1890     /* a tight loop to pack each size */
   1891     {
   1892       int val;
   1893       if(word==1){
   1894         int off=(sgned?0:128);
   1895         vorbis_fpu_setround(&fpu);
   1896         for(j=0;j<samples;j++)
   1897           for(i=0;i<channels;i++){
   1898             val=vorbis_ftoi(pcm[i][j]*128.f);
   1899             if(val>127)val=127;
   1900             else if(val<-128)val=-128;
   1901             *buffer++=val+off;
   1902           }
   1903         vorbis_fpu_restore(fpu);
   1904       }else{
   1905         int off=(sgned?0:32768);
   1906 
   1907         if(host_endian==bigendianp){
   1908           if(sgned){
   1909 
   1910             vorbis_fpu_setround(&fpu);
   1911             for(i=0;i<channels;i++) { /* It's faster in this order */
   1912               float *src=pcm[i];
   1913               short *dest=((short *)buffer)+i;
   1914               for(j=0;j<samples;j++) {
   1915                 val=vorbis_ftoi(src[j]*32768.f);
   1916                 if(val>32767)val=32767;
   1917                 else if(val<-32768)val=-32768;
   1918                 *dest=val;
   1919                 dest+=channels;
   1920               }
   1921             }
   1922             vorbis_fpu_restore(fpu);
   1923 
   1924           }else{
   1925 
   1926             vorbis_fpu_setround(&fpu);
   1927             for(i=0;i<channels;i++) {
   1928               float *src=pcm[i];
   1929               short *dest=((short *)buffer)+i;
   1930               for(j=0;j<samples;j++) {
   1931                 val=vorbis_ftoi(src[j]*32768.f);
   1932                 if(val>32767)val=32767;
   1933                 else if(val<-32768)val=-32768;
   1934                 *dest=val+off;
   1935                 dest+=channels;
   1936               }
   1937             }
   1938             vorbis_fpu_restore(fpu);
   1939 
   1940           }
   1941         }else if(bigendianp){
   1942 
   1943           vorbis_fpu_setround(&fpu);
   1944           for(j=0;j<samples;j++)
   1945             for(i=0;i<channels;i++){
   1946               val=vorbis_ftoi(pcm[i][j]*32768.f);
   1947               if(val>32767)val=32767;
   1948               else if(val<-32768)val=-32768;
   1949               val+=off;
   1950               *buffer++=(val>>8);
   1951               *buffer++=(val&0xff);
   1952             }
   1953           vorbis_fpu_restore(fpu);
   1954 
   1955         }else{
   1956           int val;
   1957           vorbis_fpu_setround(&fpu);
   1958           for(j=0;j<samples;j++)
   1959             for(i=0;i<channels;i++){
   1960               val=vorbis_ftoi(pcm[i][j]*32768.f);
   1961               if(val>32767)val=32767;
   1962               else if(val<-32768)val=-32768;
   1963               val+=off;
   1964               *buffer++=(val&0xff);
   1965               *buffer++=(val>>8);
   1966                   }
   1967           vorbis_fpu_restore(fpu);
   1968 
   1969         }
   1970       }
   1971     }
   1972 
   1973     vorbis_synthesis_read(&vf->vd,samples);
   1974     vf->pcm_offset+=samples;
   1975     if(bitstream)*bitstream=vf->current_link;
   1976     return(samples*bytespersample);
   1977   }else{
   1978     return(samples);
   1979   }
   1980 }
   1981 
   1982 long ov_read(OggVorbis_File *vf,char *buffer,int length,
   1983              int bigendianp,int word,int sgned,int *bitstream){
   1984   return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
   1985 }
   1986 
   1987 /* input values: pcm_channels) a float vector per channel of output
   1988                  length) the sample length being read by the app
   1989 
   1990    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
   1991                    0) EOF
   1992                    n) number of samples of PCM actually returned.  The
   1993                    below works on a packet-by-packet basis, so the
   1994                    return length is not related to the 'length' passed
   1995                    in, just guaranteed to fit.
   1996 
   1997             *section) set to the logical bitstream number */
   1998 
   1999 
   2000 
   2001 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
   2002                    int *bitstream){
   2003 
   2004   if(vf->ready_state<OPENED)return(OV_EINVAL);
   2005 
   2006   while(1){
   2007     if(vf->ready_state==INITSET){
   2008       float **pcm;
   2009       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
   2010       if(samples){
   2011         if(pcm_channels)*pcm_channels=pcm;
   2012         if(samples>length)samples=length;
   2013         vorbis_synthesis_read(&vf->vd,samples);
   2014         vf->pcm_offset+=samples;
   2015         if(bitstream)*bitstream=vf->current_link;
   2016         return samples;
   2017 
   2018       }
   2019     }
   2020 
   2021     /* suck in another packet */
   2022     {
   2023       int ret=_fetch_and_process_packet(vf,NULL,1,1);
   2024       if(ret==OV_EOF)return(0);
   2025       if(ret<=0)return(ret);
   2026     }
   2027 
   2028   }
   2029 }
   2030 
   2031 extern float *vorbis_window(vorbis_dsp_state *v,int W);
   2032 
   2033 static void _ov_splice(float **pcm,float **lappcm,
   2034                        int n1, int n2,
   2035                        int ch1, int ch2,
   2036                        float *w1, float *w2){
   2037   int i,j;
   2038   float *w=w1;
   2039   int n=n1;
   2040 
   2041   if(n1>n2){
   2042     n=n2;
   2043     w=w2;
   2044   }
   2045 
   2046   /* splice */
   2047   for(j=0;j<ch1 && j<ch2;j++){
   2048     float *s=lappcm[j];
   2049     float *d=pcm[j];
   2050 
   2051     for(i=0;i<n;i++){
   2052       float wd=w[i]*w[i];
   2053       float ws=1.-wd;
   2054       d[i]=d[i]*wd + s[i]*ws;
   2055     }
   2056   }
   2057   /* window from zero */
   2058   for(;j<ch2;j++){
   2059     float *d=pcm[j];
   2060     for(i=0;i<n;i++){
   2061       float wd=w[i]*w[i];
   2062       d[i]=d[i]*wd;
   2063     }
   2064   }
   2065 
   2066 }
   2067 
   2068 /* make sure vf is INITSET */
   2069 static int _ov_initset(OggVorbis_File *vf){
   2070   while(1){
   2071     if(vf->ready_state==INITSET)break;
   2072     /* suck in another packet */
   2073     {
   2074       int ret=_fetch_and_process_packet(vf,NULL,1,0);
   2075       if(ret<0 && ret!=OV_HOLE)return(ret);
   2076     }
   2077   }
   2078   return 0;
   2079 }
   2080 
   2081 /* make sure vf is INITSET and that we have a primed buffer; if
   2082    we're crosslapping at a stream section boundary, this also makes
   2083    sure we're sanity checking against the right stream information */
   2084 static int _ov_initprime(OggVorbis_File *vf){
   2085   vorbis_dsp_state *vd=&vf->vd;
   2086   while(1){
   2087     if(vf->ready_state==INITSET)
   2088       if(vorbis_synthesis_pcmout(vd,NULL))break;
   2089 
   2090     /* suck in another packet */
   2091     {
   2092       int ret=_fetch_and_process_packet(vf,NULL,1,0);
   2093       if(ret<0 && ret!=OV_HOLE)return(ret);
   2094     }
   2095   }
   2096   return 0;
   2097 }
   2098 
   2099 /* grab enough data for lapping from vf; this may be in the form of
   2100    unreturned, already-decoded pcm, remaining PCM we will need to
   2101    decode, or synthetic postextrapolation from last packets. */
   2102 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
   2103                        float **lappcm,int lapsize){
   2104   int lapcount=0,i;
   2105   float **pcm;
   2106 
   2107   /* try first to decode the lapping data */
   2108   while(lapcount<lapsize){
   2109     int samples=vorbis_synthesis_pcmout(vd,&pcm);
   2110     if(samples){
   2111       if(samples>lapsize-lapcount)samples=lapsize-lapcount;
   2112       for(i=0;i<vi->channels;i++)
   2113         memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
   2114       lapcount+=samples;
   2115       vorbis_synthesis_read(vd,samples);
   2116     }else{
   2117     /* suck in another packet */
   2118       int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
   2119       if(ret==OV_EOF)break;
   2120     }
   2121   }
   2122   if(lapcount<lapsize){
   2123     /* failed to get lapping data from normal decode; pry it from the
   2124        postextrapolation buffering, or the second half of the MDCT
   2125        from the last packet */
   2126     int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
   2127     if(samples==0){
   2128       for(i=0;i<vi->channels;i++)
   2129         memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
   2130       lapcount=lapsize;
   2131     }else{
   2132       if(samples>lapsize-lapcount)samples=lapsize-lapcount;
   2133       for(i=0;i<vi->channels;i++)
   2134         memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
   2135       lapcount+=samples;
   2136     }
   2137   }
   2138 }
   2139 
   2140 /* this sets up crosslapping of a sample by using trailing data from
   2141    sample 1 and lapping it into the windowing buffer of sample 2 */
   2142 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
   2143   vorbis_info *vi1,*vi2;
   2144   float **lappcm;
   2145   float **pcm;
   2146   float *w1,*w2;
   2147   int n1,n2,i,ret,hs1,hs2;
   2148 
   2149   if(vf1==vf2)return(0); /* degenerate case */
   2150   if(vf1->ready_state<OPENED)return(OV_EINVAL);
   2151   if(vf2->ready_state<OPENED)return(OV_EINVAL);
   2152 
   2153   /* the relevant overlap buffers must be pre-checked and pre-primed
   2154      before looking at settings in the event that priming would cross
   2155      a bitstream boundary.  So, do it now */
   2156 
   2157   ret=_ov_initset(vf1);
   2158   if(ret)return(ret);
   2159   ret=_ov_initprime(vf2);
   2160   if(ret)return(ret);
   2161 
   2162   vi1=ov_info(vf1,-1);
   2163   vi2=ov_info(vf2,-1);
   2164   hs1=ov_halfrate_p(vf1);
   2165   hs2=ov_halfrate_p(vf2);
   2166 
   2167   lappcm=alloca(sizeof(*lappcm)*vi1->channels);
   2168   n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
   2169   n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
   2170   w1=vorbis_window(&vf1->vd,0);
   2171   w2=vorbis_window(&vf2->vd,0);
   2172 
   2173   for(i=0;i<vi1->channels;i++)
   2174     lappcm[i]=alloca(sizeof(**lappcm)*n1);
   2175 
   2176   _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
   2177 
   2178   /* have a lapping buffer from vf1; now to splice it into the lapping
   2179      buffer of vf2 */
   2180   /* consolidate and expose the buffer. */
   2181   vorbis_synthesis_lapout(&vf2->vd,&pcm);
   2182 
   2183 #if 0
   2184   _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
   2185   _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
   2186 #endif
   2187 
   2188   /* splice */
   2189   _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
   2190 
   2191   /* done */
   2192   return(0);
   2193 }
   2194 
   2195 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
   2196                            int (*localseek)(OggVorbis_File *,ogg_int64_t)){
   2197   vorbis_info *vi;
   2198   float **lappcm;
   2199   float **pcm;
   2200   float *w1,*w2;
   2201   int n1,n2,ch1,ch2,hs;
   2202   int i,ret;
   2203 
   2204   if(vf->ready_state<OPENED)return(OV_EINVAL);
   2205   ret=_ov_initset(vf);
   2206   if(ret)return(ret);
   2207   vi=ov_info(vf,-1);
   2208   hs=ov_halfrate_p(vf);
   2209 
   2210   ch1=vi->channels;
   2211   n1=vorbis_info_blocksize(vi,0)>>(1+hs);
   2212   w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
   2213                                    persistent; even if the decode state
   2214                                    from this link gets dumped, this
   2215                                    window array continues to exist */
   2216 
   2217   lappcm=alloca(sizeof(*lappcm)*ch1);
   2218   for(i=0;i<ch1;i++)
   2219     lappcm[i]=alloca(sizeof(**lappcm)*n1);
   2220   _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
   2221 
   2222   /* have lapping data; seek and prime the buffer */
   2223   ret=localseek(vf,pos);
   2224   if(ret)return ret;
   2225   ret=_ov_initprime(vf);
   2226   if(ret)return(ret);
   2227 
   2228  /* Guard against cross-link changes; they're perfectly legal */
   2229   vi=ov_info(vf,-1);
   2230   ch2=vi->channels;
   2231   n2=vorbis_info_blocksize(vi,0)>>(1+hs);
   2232   w2=vorbis_window(&vf->vd,0);
   2233 
   2234   /* consolidate and expose the buffer. */
   2235   vorbis_synthesis_lapout(&vf->vd,&pcm);
   2236 
   2237   /* splice */
   2238   _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
   2239 
   2240   /* done */
   2241   return(0);
   2242 }
   2243 
   2244 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
   2245   return _ov_64_seek_lap(vf,pos,ov_raw_seek);
   2246 }
   2247 
   2248 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
   2249   return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
   2250 }
   2251 
   2252 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
   2253   return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
   2254 }
   2255 
   2256 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
   2257                            int (*localseek)(OggVorbis_File *,double)){
   2258   vorbis_info *vi;
   2259   float **lappcm;
   2260   float **pcm;
   2261   float *w1,*w2;
   2262   int n1,n2,ch1,ch2,hs;
   2263   int i,ret;
   2264 
   2265   if(vf->ready_state<OPENED)return(OV_EINVAL);
   2266   ret=_ov_initset(vf);
   2267   if(ret)return(ret);
   2268   vi=ov_info(vf,-1);
   2269   hs=ov_halfrate_p(vf);
   2270 
   2271   ch1=vi->channels;
   2272   n1=vorbis_info_blocksize(vi,0)>>(1+hs);
   2273   w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
   2274                                    persistent; even if the decode state
   2275                                    from this link gets dumped, this
   2276                                    window array continues to exist */
   2277 
   2278   lappcm=alloca(sizeof(*lappcm)*ch1);
   2279   for(i=0;i<ch1;i++)
   2280     lappcm[i]=alloca(sizeof(**lappcm)*n1);
   2281   _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
   2282 
   2283   /* have lapping data; seek and prime the buffer */
   2284   ret=localseek(vf,pos);
   2285   if(ret)return ret;
   2286   ret=_ov_initprime(vf);
   2287   if(ret)return(ret);
   2288 
   2289  /* Guard against cross-link changes; they're perfectly legal */
   2290   vi=ov_info(vf,-1);
   2291   ch2=vi->channels;
   2292   n2=vorbis_info_blocksize(vi,0)>>(1+hs);
   2293   w2=vorbis_window(&vf->vd,0);
   2294 
   2295   /* consolidate and expose the buffer. */
   2296   vorbis_synthesis_lapout(&vf->vd,&pcm);
   2297 
   2298   /* splice */
   2299   _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
   2300 
   2301   /* done */
   2302   return(0);
   2303 }
   2304 
   2305 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
   2306   return _ov_d_seek_lap(vf,pos,ov_time_seek);
   2307 }
   2308 
   2309 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
   2310   return _ov_d_seek_lap(vf,pos,ov_time_seek_page);
   2311 }
   2312