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