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