vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

vorbisfile.c (57581B)


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