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