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