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