Fix _fecth_and_process_packet for non-seekable streams
[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.60 2002/03/19 17:49:59 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,end;
404   ogg_int64_t dataoffset=vf->offset;
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   ogg_page og;
462
463   /* handle one packet.  Try to fetch it from current stream state */
464   /* extract packets from page */
465   while(1){
466     
467     /* process a packet if we can.  If the machine isn't loaded,
468        neither is a page */
469     if(vf->ready_state==INITSET){
470       while(1) {
471         ogg_packet op;
472         ogg_packet *op_ptr=(op_in?op_in:&op);
473         int result=ogg_stream_packetout(&vf->os,op_ptr);
474         ogg_int64_t granulepos;
475
476         op_in=NULL;
477         if(result==-1)return(OV_HOLE); /* hole in the data. */
478         if(result>0){
479           /* got a packet.  process it */
480           granulepos=op_ptr->granulepos;
481           if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
482                                                     header handling.  The
483                                                     header packets aren't
484                                                     audio, so if/when we
485                                                     submit them,
486                                                     vorbis_synthesis will
487                                                     reject them */
488
489             /* suck in the synthesis data and track bitrate */
490             {
491               int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
492               /* for proper use of libvorbis within libvorbisfile,
493                  oldsamples will always be zero. */
494               if(oldsamples)return(OV_EFAULT);
495               
496               vorbis_synthesis_blockin(&vf->vd,&vf->vb);
497               vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
498               vf->bittrack+=op_ptr->bytes*8;
499             }
500           
501             /* update the pcm offset. */
502             if(granulepos!=-1 && !op_ptr->e_o_s){
503               int link=(vf->seekable?vf->current_link:0);
504               int i,samples;
505             
506               /* this packet has a pcm_offset on it (the last packet
507                  completed on a page carries the offset) After processing
508                  (above), we know the pcm position of the *last* sample
509                  ready to be returned. Find the offset of the *first*
510
511                  As an aside, this trick is inaccurate if we begin
512                  reading anew right at the last page; the end-of-stream
513                  granulepos declares the last frame in the stream, and the
514                  last packet of the last page may be a partial frame.
515                  So, we need a previous granulepos from an in-sequence page
516                  to have a reference point.  Thus the !op_ptr->e_o_s clause
517                  above */
518
519               if(vf->seekable && link>0)
520                 granulepos-=vf->pcmlengths[link*2];
521               if(granulepos<0)granulepos=0; /* actually, this
522                                                shouldn't be possible
523                                                here unless the stream
524                                                is very broken */
525
526               samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
527             
528               granulepos-=samples;
529               for(i=0;i<link;i++)
530                 granulepos+=vf->pcmlengths[i*2+1];
531               vf->pcm_offset=granulepos;
532             }
533             return(1);
534           }
535         }
536         else 
537           break;
538       }
539     }
540
541     if(vf->ready_state>=OPENED){
542       if(!readp)return(0);
543       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. 
544                                                         leave unitialized */
545       /* bitrate tracking; add the header's bytes here, the body bytes
546          are done by packet above */
547       vf->bittrack+=og.header_len*8;
548       
549       /* has our decoding just traversed a bitstream boundary? */
550       if(vf->ready_state==INITSET){
551         if(vf->current_serialno!=ogg_page_serialno(&og)){
552           _decode_clear(vf);
553           
554           if(!vf->seekable){
555             vorbis_info_clear(vf->vi);
556             vorbis_comment_clear(vf->vc);
557           }
558         }
559       }
560     }
561
562     /* Do we need to load a new machine before submitting the page? */
563     /* This is different in the seekable and non-seekable cases.  
564
565        In the seekable case, we already have all the header
566        information loaded and cached; we just initialize the machine
567        with it and continue on our merry way.
568
569        In the non-seekable (streaming) case, we'll only be at a
570        boundary if we just left the previous logical bitstream and
571        we're now nominally at the header of the next bitstream
572     */
573
574     if(vf->ready_state!=INITSET){ 
575       int link;
576
577       if(vf->ready_state<STREAMSET){
578         if(vf->seekable){
579           vf->current_serialno=ogg_page_serialno(&og);
580           
581           /* match the serialno to bitstream section.  We use this rather than
582              offset positions to avoid problems near logical bitstream
583              boundaries */
584           for(link=0;link<vf->links;link++)
585             if(vf->serialnos[link]==vf->current_serialno)break;
586           if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
587                                                      stream.  error out,
588                                                      leave machine
589                                                      uninitialized */
590           
591           vf->current_link=link;
592           
593           ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
594           vf->ready_state=STREAMSET;
595           
596         }else{
597           /* we're streaming */
598           /* fetch the three header packets, build the info struct */
599           
600           int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
601           if(ret)return(ret);
602           vf->current_link++;
603           link=0;
604         }
605       }
606       
607       _make_decode_ready(vf);
608     }
609     ogg_stream_pagein(&vf->os,&og);
610   }
611 }
612
613 /* if, eg, 64 bit stdio is configured by default, this will build with
614    fseek64 */
615 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
616   if(f==NULL)return(-1);
617   return fseek(f,off,whence);
618 }
619
620 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
621                      long ibytes, ov_callbacks callbacks){
622   int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
623   int ret;
624
625   memset(vf,0,sizeof(*vf));
626   vf->datasource=f;
627   vf->callbacks = callbacks;
628
629   /* init the framing state */
630   ogg_sync_init(&vf->oy);
631
632   /* perhaps some data was previously read into a buffer for testing
633      against other stream types.  Allow initialization from this
634      previously read data (as we may be reading from a non-seekable
635      stream) */
636   if(initial){
637     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
638     memcpy(buffer,initial,ibytes);
639     ogg_sync_wrote(&vf->oy,ibytes);
640   }
641
642   /* can we seek? Stevens suggests the seek test was portable */
643   if(offsettest!=-1)vf->seekable=1;
644
645   /* No seeking yet; Set up a 'single' (current) logical bitstream
646      entry for partial open */
647   vf->links=1;
648   vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
649   vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
650   ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
651
652   /* Try to fetch the headers, maintaining all the storage */
653   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
654     vf->datasource=NULL;
655     ov_clear(vf);
656   }else if(vf->ready_state < PARTOPEN)
657     vf->ready_state=PARTOPEN;
658   return(ret);
659 }
660
661 static int _ov_open2(OggVorbis_File *vf){
662   if(vf->ready_state < OPENED)
663     vf->ready_state=OPENED;
664   if(vf->seekable){
665     int ret=_open_seekable2(vf);
666     if(ret){
667       vf->datasource=NULL;
668       ov_clear(vf);
669     }
670     return(ret);
671   }
672   return 0;
673 }
674
675
676 /* clear out the OggVorbis_File struct */
677 int ov_clear(OggVorbis_File *vf){
678   if(vf){
679     vorbis_block_clear(&vf->vb);
680     vorbis_dsp_clear(&vf->vd);
681     ogg_stream_clear(&vf->os);
682     
683     if(vf->vi && vf->links){
684       int i;
685       for(i=0;i<vf->links;i++){
686         vorbis_info_clear(vf->vi+i);
687         vorbis_comment_clear(vf->vc+i);
688       }
689       _ogg_free(vf->vi);
690       _ogg_free(vf->vc);
691     }
692     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
693     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
694     if(vf->serialnos)_ogg_free(vf->serialnos);
695     if(vf->offsets)_ogg_free(vf->offsets);
696     ogg_sync_clear(&vf->oy);
697     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
698     memset(vf,0,sizeof(*vf));
699   }
700 #ifdef DEBUG_LEAKS
701   _VDBG_dump();
702 #endif
703   return(0);
704 }
705
706 /* inspects the OggVorbis file and finds/documents all the logical
707    bitstreams contained in it.  Tries to be tolerant of logical
708    bitstream sections that are truncated/woogie. 
709
710    return: -1) error
711             0) OK
712 */
713
714 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
715     ov_callbacks callbacks){
716   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
717   if(ret)return ret;
718   return _ov_open2(vf);
719 }
720
721 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
722   ov_callbacks callbacks = {
723     (size_t (*)(void *, size_t, size_t, void *))  fread,
724     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
725     (int (*)(void *))                             fclose,
726     (long (*)(void *))                            ftell
727   };
728
729   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
730 }
731   
732 /* Only partially open the vorbis file; test for Vorbisness, and load
733    the headers for the first chain.  Do not seek (although test for
734    seekability).  Use ov_test_open to finish opening the file, else
735    ov_clear to close/free it. Same return codes as open. */
736
737 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
738     ov_callbacks callbacks)
739 {
740   return _ov_open1(f,vf,initial,ibytes,callbacks);
741 }
742
743 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
744   ov_callbacks callbacks = {
745     (size_t (*)(void *, size_t, size_t, void *))  fread,
746     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
747     (int (*)(void *))                             fclose,
748     (long (*)(void *))                            ftell
749   };
750
751   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
752 }
753   
754 int ov_test_open(OggVorbis_File *vf){
755   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
756   return _ov_open2(vf);
757 }
758
759 /* How many logical bitstreams in this physical bitstream? */
760 long ov_streams(OggVorbis_File *vf){
761   return vf->links;
762 }
763
764 /* Is the FILE * associated with vf seekable? */
765 long ov_seekable(OggVorbis_File *vf){
766   return vf->seekable;
767 }
768
769 /* returns the bitrate for a given logical bitstream or the entire
770    physical bitstream.  If the file is open for random access, it will
771    find the *actual* average bitrate.  If the file is streaming, it
772    returns the nominal bitrate (if set) else the average of the
773    upper/lower bounds (if set) else -1 (unset).
774
775    If you want the actual bitrate field settings, get them from the
776    vorbis_info structs */
777
778 long ov_bitrate(OggVorbis_File *vf,int i){
779   if(vf->ready_state<OPENED)return(OV_EINVAL);
780   if(i>=vf->links)return(OV_EINVAL);
781   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
782   if(i<0){
783     ogg_int64_t bits=0;
784     int i;
785     for(i=0;i<vf->links;i++)
786       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
787     return(rint(bits/ov_time_total(vf,-1)));
788   }else{
789     if(vf->seekable){
790       /* return the actual bitrate */
791       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
792     }else{
793       /* return nominal if set */
794       if(vf->vi[i].bitrate_nominal>0){
795         return vf->vi[i].bitrate_nominal;
796       }else{
797         if(vf->vi[i].bitrate_upper>0){
798           if(vf->vi[i].bitrate_lower>0){
799             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
800           }else{
801             return vf->vi[i].bitrate_upper;
802           }
803         }
804         return(OV_FALSE);
805       }
806     }
807   }
808 }
809
810 /* returns the actual bitrate since last call.  returns -1 if no
811    additional data to offer since last call (or at beginning of stream),
812    EINVAL if stream is only partially open 
813 */
814 long ov_bitrate_instant(OggVorbis_File *vf){
815   int link=(vf->seekable?vf->current_link:0);
816   long ret;
817   if(vf->ready_state<OPENED)return(OV_EINVAL);
818   if(vf->samptrack==0)return(OV_FALSE);
819   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
820   vf->bittrack=0.f;
821   vf->samptrack=0.f;
822   return(ret);
823 }
824
825 /* Guess */
826 long ov_serialnumber(OggVorbis_File *vf,int i){
827   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
828   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
829   if(i<0){
830     return(vf->current_serialno);
831   }else{
832     return(vf->serialnos[i]);
833   }
834 }
835
836 /* returns: total raw (compressed) length of content if i==-1
837             raw (compressed) length of that logical bitstream for i==0 to n
838             OV_EINVAL if the stream is not seekable (we can't know the length)
839             or if stream is only partially open
840 */
841 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
842   if(vf->ready_state<OPENED)return(OV_EINVAL);
843   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
844   if(i<0){
845     ogg_int64_t acc=0;
846     int i;
847     for(i=0;i<vf->links;i++)
848       acc+=ov_raw_total(vf,i);
849     return(acc);
850   }else{
851     return(vf->offsets[i+1]-vf->offsets[i]);
852   }
853 }
854
855 /* returns: total PCM length (samples) of content if i==-1 PCM length
856             (samples) of that logical bitstream for i==0 to n
857             OV_EINVAL if the stream is not seekable (we can't know the
858             length) or only partially open 
859 */
860 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
861   if(vf->ready_state<OPENED)return(OV_EINVAL);
862   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
863   if(i<0){
864     ogg_int64_t acc=0;
865     int i;
866     for(i=0;i<vf->links;i++)
867       acc+=ov_pcm_total(vf,i);
868     return(acc);
869   }else{
870     return(vf->pcmlengths[i*2+1]);
871   }
872 }
873
874 /* returns: total seconds of content if i==-1
875             seconds in that logical bitstream for i==0 to n
876             OV_EINVAL if the stream is not seekable (we can't know the
877             length) or only partially open 
878 */
879 double ov_time_total(OggVorbis_File *vf,int i){
880   if(vf->ready_state<OPENED)return(OV_EINVAL);
881   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
882   if(i<0){
883     double acc=0;
884     int i;
885     for(i=0;i<vf->links;i++)
886       acc+=ov_time_total(vf,i);
887     return(acc);
888   }else{
889     return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
890   }
891 }
892
893 /* seek to an offset relative to the *compressed* data. This also
894    scans packets to update the PCM cursor. It will cross a logical
895    bitstream boundary, but only if it can't get any packets out of the
896    tail of the bitstream we seek to (so no surprises).
897
898    returns zero on success, nonzero on failure */
899
900 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
901   ogg_stream_state work_os;
902
903   if(vf->ready_state<OPENED)return(OV_EINVAL);
904   if(!vf->seekable)
905     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
906
907   if(pos<0 || pos>vf->end)return(OV_EINVAL);
908
909   /* clear out decoding machine state */
910   vf->pcm_offset=-1;
911   _decode_clear(vf);
912   
913   _seek_helper(vf,pos);
914
915   /* we need to make sure the pcm_offset is set, but we don't want to
916      advance the raw cursor past good packets just to get to the first
917      with a granulepos.  That's not equivalent behavior to beginning
918      decoding as immediately after the seek position as possible.
919
920      So, a hack.  We use two stream states; a local scratch state and
921      a the shared vf->os stream state.  We use the local state to
922      scan, and the shared state as a buffer for later decode. 
923
924      Unfortuantely, on the last page we still advance to last packet
925      because the granulepos on the last page is not necessarily on a
926      packet boundary, and we need to make sure the granpos is
927      correct. 
928   */
929
930   {
931     ogg_page og;
932     ogg_packet op;
933     int lastblock=0;
934     int accblock=0;
935     int thisblock;
936     int eosflag;
937
938     ogg_stream_init(&work_os,-1); /* get the memory ready */
939
940     while(1){
941       if(vf->ready_state==STREAMSET){
942         /* snarf/scan a packet if we can */
943         int result=ogg_stream_packetout(&work_os,&op);
944       
945         if(result>0){
946
947           if(vf->vi[vf->current_link].codec_setup)
948             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
949           if(eosflag)
950             ogg_stream_packetout(&vf->os,NULL);
951           else
952             if(lastblock)accblock+=(lastblock+thisblock)>>2;
953
954           if(op.granulepos!=-1){
955             int i,link=vf->current_link;
956             ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
957             if(granulepos<0)granulepos=0;
958             
959             for(i=0;i<link;i++)
960               granulepos+=vf->pcmlengths[i*2+1];
961             vf->pcm_offset=granulepos-accblock;
962             break;
963           }
964           lastblock=thisblock;
965           continue;
966         }
967       }
968       
969       if(!lastblock){
970         if(_get_next_page(vf,&og,-1)<0){
971           vf->pcm_offset=ov_pcm_total(vf,-1);
972           break;
973         }
974       }else{
975         /* huh?  Bogus stream with packets but no granulepos */
976         vf->pcm_offset=-1;
977         break;
978       }
979       
980       /* has our decoding just traversed a bitstream boundary? */
981       if(vf->ready_state==STREAMSET)
982         if(vf->current_serialno!=ogg_page_serialno(&og)){
983         _decode_clear(vf); /* clear out stream state */
984         ogg_stream_clear(&work_os);
985       }
986
987       if(vf->ready_state<STREAMSET){
988         int link;
989         
990         vf->current_serialno=ogg_page_serialno(&og);
991         for(link=0;link<vf->links;link++)
992           if(vf->serialnos[link]==vf->current_serialno)break;
993         if(link==vf->links)goto seek_error; /* sign of a bogus stream.
994                                                error out, leave
995                                                machine uninitialized */
996         vf->current_link=link;
997         
998         ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
999         ogg_stream_reset_serialno(&work_os,vf->current_serialno); 
1000         vf->ready_state=STREAMSET;
1001         
1002       }
1003     
1004       ogg_stream_pagein(&vf->os,&og);
1005       ogg_stream_pagein(&work_os,&og);
1006       eosflag=ogg_page_eos(&og);
1007     }
1008   }
1009
1010   ogg_stream_clear(&work_os);
1011   return(0);
1012
1013  seek_error:
1014   /* dump the machine so we're in a known state */
1015   vf->pcm_offset=-1;
1016   ogg_stream_clear(&work_os);
1017   _decode_clear(vf);
1018   return OV_EBADLINK;
1019 }
1020
1021 /* Page granularity seek (faster than sample granularity because we
1022    don't do the last bit of decode to find a specific sample).
1023
1024    Seek to the last [granule marked] page preceeding the specified pos
1025    location, such that decoding past the returned point will quickly
1026    arrive at the requested position. */
1027 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1028   int link=-1,ret=0;
1029   ogg_int64_t result;
1030   ogg_int64_t total=ov_pcm_total(vf,-1);
1031
1032   if(vf->ready_state<OPENED)return(OV_EINVAL);
1033   if(!vf->seekable)return(OV_ENOSEEK);
1034
1035   if(pos<0 || pos>total)return(OV_EINVAL);
1036  
1037   /* which bitstream section does this pcm offset occur in? */
1038   for(link=vf->links-1;link>=0;link--){
1039     total-=vf->pcmlengths[link*2+1];
1040     if(pos>=total)break;
1041   }
1042
1043   /* search within the logical bitstream for the page with the highest
1044      pcm_pos preceeding (or equal to) pos.  There is a danger here;
1045      missing pages or incorrect frame number information in the
1046      bitstream could make our task impossible.  Account for that (it
1047      would be an error condition) */
1048
1049   /* new search algorithm by HB (Nicholas Vinen) */
1050   {
1051     ogg_int64_t end=vf->offsets[link+1];
1052     ogg_int64_t begin=vf->offsets[link];
1053     ogg_int64_t begintime = vf->pcmlengths[link*2];
1054     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1055     ogg_int64_t target=pos-total+begintime;
1056     ogg_int64_t best=begin;
1057     
1058     ogg_page og;
1059     while(begin<end){
1060       ogg_int64_t bisect;
1061       
1062       if(end-begin<CHUNKSIZE){
1063         bisect=begin;
1064       }else{
1065         /* take a (pretty decent) guess. */
1066         bisect=begin + 
1067           (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1068         if(bisect<=begin)
1069           bisect=begin+1;
1070       }
1071       
1072       _seek_helper(vf,bisect);
1073     
1074       while(begin<end){
1075         result=_get_next_page(vf,&og,end-vf->offset);
1076         if(result==OV_EREAD) goto seek_error;
1077         if(result<0){
1078           if(bisect<=begin+1)
1079             end=begin; /* found it */
1080           else{
1081             if(bisect==0)goto seek_error;
1082             bisect-=CHUNKSIZE;
1083             if(bisect<=begin)bisect=begin+1;
1084             _seek_helper(vf,bisect);
1085           }
1086         }else{
1087           ogg_int64_t granulepos=ogg_page_granulepos(&og);
1088           if(granulepos==-1)continue;
1089           if(granulepos<target){
1090             best=result;  /* raw offset of packet with granulepos */ 
1091             begin=vf->offset; /* raw offset of next page */
1092             begintime=granulepos;
1093             
1094             if(target-begintime>44100)break;
1095             bisect=begin; /* *not* begin + 1 */
1096           }else{
1097             if(bisect<=begin+1)
1098               end=begin;  /* found it */
1099             else{
1100               if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1101                 end=result;
1102                 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1103                 if(bisect<=begin)bisect=begin+1;
1104                 _seek_helper(vf,bisect);
1105               }else{
1106                 end=result;
1107                 endtime=granulepos;
1108                 break;
1109               }
1110             }
1111           }
1112         }
1113       }
1114     }
1115
1116     /* found our page. seek to it, update pcm offset. Easier case than
1117        raw_seek, don't keep packets preceeding granulepos. */
1118     {
1119       ogg_page og;
1120       ogg_packet op;
1121       /* clear out decoding machine state */
1122       _decode_clear(vf);  
1123       /* seek */
1124       _seek_helper(vf,best);
1125       
1126       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1127       vf->current_serialno=ogg_page_serialno(&og);
1128       vf->current_link=link;
1129       
1130       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1131       vf->ready_state=STREAMSET;
1132       ogg_stream_pagein(&vf->os,&og);
1133
1134       /* pull out all but last packet; the one with granulepos */
1135       while(1){
1136         result=ogg_stream_packetpeek(&vf->os,&op);
1137         if(result==0){
1138           /* !!! the packet finishing this page originated on a
1139              preceeding page. Keep fetching previous pages until we
1140              get one with a granulepos or without the 'continued' flag
1141              set.  Then just use raw_seek for simplicity. */
1142
1143           _decode_clear(vf);  
1144           _seek_helper(vf,best);
1145
1146           while(1){
1147             result=_get_prev_page(vf,&og);
1148             if(result<0)goto seek_error;
1149             if(ogg_page_granulepos(&og)>-1 ||
1150                !ogg_page_continued(&og)){
1151               return ov_raw_seek(vf,result);
1152             }
1153             vf->offset=result;
1154           }
1155         }
1156         if(result<0)goto seek_error;
1157         if(op.granulepos!=-1){
1158           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1159           if(vf->pcm_offset<0)vf->pcm_offset=0;
1160           vf->pcm_offset+=total;
1161           break;
1162         }else
1163           result=ogg_stream_packetout(&vf->os,NULL);
1164       }
1165     }
1166   }
1167   
1168   /* verify result */
1169   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1170     ret=OV_EFAULT;
1171     goto seek_error;
1172   }
1173   return(0);
1174   
1175  seek_error:
1176   /* dump machine so we're in a known state */
1177   vf->pcm_offset=-1;
1178   _decode_clear(vf);
1179   return ret;
1180 }
1181
1182 /* seek to a sample offset relative to the decompressed pcm stream 
1183    returns zero on success, nonzero on failure */
1184
1185 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1186   int thisblock,lastblock=0;
1187   int ret=ov_pcm_seek_page(vf,pos);
1188   if(ret<0)return(ret);
1189   _make_decode_ready(vf);
1190
1191   /* discard leading packets we don't need for the lapping of the
1192      position we want; don't decode them */
1193
1194   while(1){
1195     ogg_packet op;
1196     ogg_page og;
1197
1198     int ret=ogg_stream_packetpeek(&vf->os,&op);
1199     if(ret>0){
1200       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1201       if(thisblock<0)thisblock=0; /* non audio packet */
1202       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1203       
1204       if(vf->pcm_offset+((thisblock+
1205                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1206       
1207       /* remove the packet from packet queue and track its granulepos */
1208       ogg_stream_packetout(&vf->os,NULL);
1209       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1210                                                    only tracking, no
1211                                                    pcm_decode */
1212       vorbis_synthesis_blockin(&vf->vd,&vf->vb); 
1213       
1214       /* end of logical stream case is hard, especially with exact
1215          length positioning. */
1216       
1217       if(op.granulepos>-1){
1218         int i;
1219         /* always believe the stream markers */
1220         vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1221         if(vf->pcm_offset<0)vf->pcm_offset=0;
1222         for(i=0;i<vf->current_link;i++)
1223           vf->pcm_offset+=vf->pcmlengths[i*2+1];
1224       }
1225         
1226       lastblock=thisblock;
1227       
1228     }else{
1229       if(ret<0 && ret!=OV_HOLE)break;
1230       
1231       /* suck in a new page */
1232       if(_get_next_page(vf,&og,-1)<0)break;
1233       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1234       
1235       if(vf->ready_state<STREAMSET){
1236         int link;
1237         
1238         vf->current_serialno=ogg_page_serialno(&og);
1239         for(link=0;link<vf->links;link++)
1240           if(vf->serialnos[link]==vf->current_serialno)break;
1241         if(link==vf->links)return(OV_EBADLINK);
1242         vf->current_link=link;
1243         
1244         ogg_stream_reset_serialno(&vf->os,vf->current_serialno); 
1245         vf->ready_state=STREAMSET;      
1246         _make_decode_ready(vf);
1247         lastblock=0;
1248       }
1249
1250       ogg_stream_pagein(&vf->os,&og);
1251     }
1252   }
1253
1254   /* discard samples until we reach the desired position. Crossing a
1255      logical bitstream boundary with abandon is OK. */
1256   while(vf->pcm_offset<pos){
1257     float **pcm;
1258     ogg_int64_t target=pos-vf->pcm_offset;
1259     long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1260
1261     if(samples>target)samples=target;
1262     vorbis_synthesis_read(&vf->vd,samples);
1263     vf->pcm_offset+=samples;
1264     
1265     if(samples<target)
1266       if(_fetch_and_process_packet(vf,NULL,1)<=0)
1267         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1268   }
1269   return 0;
1270 }
1271
1272 /* seek to a playback time relative to the decompressed pcm stream 
1273    returns zero on success, nonzero on failure */
1274 int ov_time_seek(OggVorbis_File *vf,double seconds){
1275   /* translate time to PCM position and call ov_pcm_seek */
1276
1277   int link=-1;
1278   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1279   double time_total=ov_time_total(vf,-1);
1280
1281   if(vf->ready_state<OPENED)return(OV_EINVAL);
1282   if(!vf->seekable)return(OV_ENOSEEK);
1283   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1284   
1285   /* which bitstream section does this time offset occur in? */
1286   for(link=vf->links-1;link>=0;link--){
1287     pcm_total-=vf->pcmlengths[link*2+1];
1288     time_total-=ov_time_total(vf,link);
1289     if(seconds>=time_total)break;
1290   }
1291
1292   /* enough information to convert time offset to pcm offset */
1293   {
1294     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1295     return(ov_pcm_seek(vf,target));
1296   }
1297 }
1298
1299 /* page-granularity version of ov_time_seek 
1300    returns zero on success, nonzero on failure */
1301 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1302   /* translate time to PCM position and call ov_pcm_seek */
1303
1304   int link=-1;
1305   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1306   double time_total=ov_time_total(vf,-1);
1307
1308   if(vf->ready_state<OPENED)return(OV_EINVAL);
1309   if(!vf->seekable)return(OV_ENOSEEK);
1310   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1311   
1312   /* which bitstream section does this time offset occur in? */
1313   for(link=vf->links-1;link>=0;link--){
1314     pcm_total-=vf->pcmlengths[link*2+1];
1315     time_total-=ov_time_total(vf,link);
1316     if(seconds>=time_total)break;
1317   }
1318
1319   /* enough information to convert time offset to pcm offset */
1320   {
1321     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1322     return(ov_pcm_seek_page(vf,target));
1323   }
1324 }
1325
1326 /* tell the current stream offset cursor.  Note that seek followed by
1327    tell will likely not give the set offset due to caching */
1328 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1329   if(vf->ready_state<OPENED)return(OV_EINVAL);
1330   return(vf->offset);
1331 }
1332
1333 /* return PCM offset (sample) of next PCM sample to be read */
1334 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1335   if(vf->ready_state<OPENED)return(OV_EINVAL);
1336   return(vf->pcm_offset);
1337 }
1338
1339 /* return time offset (seconds) of next PCM sample to be read */
1340 double ov_time_tell(OggVorbis_File *vf){
1341   /* translate time to PCM position and call ov_pcm_seek */
1342
1343   int link=-1;
1344   ogg_int64_t pcm_total=0;
1345   double time_total=0.f;
1346   
1347   if(vf->ready_state<OPENED)return(OV_EINVAL);
1348   if(vf->seekable){
1349     pcm_total=ov_pcm_total(vf,-1);
1350     time_total=ov_time_total(vf,-1);
1351   
1352     /* which bitstream section does this time offset occur in? */
1353     for(link=vf->links-1;link>=0;link--){
1354       pcm_total-=vf->pcmlengths[link*2+1];
1355       time_total-=ov_time_total(vf,link);
1356       if(vf->pcm_offset>=pcm_total)break;
1357     }
1358   }
1359
1360   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1361 }
1362
1363 /*  link:   -1) return the vorbis_info struct for the bitstream section
1364                 currently being decoded
1365            0-n) to request information for a specific bitstream section
1366     
1367     In the case of a non-seekable bitstream, any call returns the
1368     current bitstream.  NULL in the case that the machine is not
1369     initialized */
1370
1371 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1372   if(vf->seekable){
1373     if(link<0)
1374       if(vf->ready_state>=STREAMSET)
1375         return vf->vi+vf->current_link;
1376       else
1377       return vf->vi;
1378     else
1379       if(link>=vf->links)
1380         return NULL;
1381       else
1382         return vf->vi+link;
1383   }else{
1384     return vf->vi;
1385   }
1386 }
1387
1388 /* grr, strong typing, grr, no templates/inheritence, grr */
1389 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1390   if(vf->seekable){
1391     if(link<0)
1392       if(vf->ready_state>=STREAMSET)
1393         return vf->vc+vf->current_link;
1394       else
1395         return vf->vc;
1396     else
1397       if(link>=vf->links)
1398         return NULL;
1399       else
1400         return vf->vc+link;
1401   }else{
1402     return vf->vc;
1403   }
1404 }
1405
1406 static int host_is_big_endian() {
1407   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1408   unsigned char *bytewise = (unsigned char *)&pattern;
1409   if (bytewise[0] == 0xfe) return 1;
1410   return 0;
1411 }
1412
1413 /* up to this point, everything could more or less hide the multiple
1414    logical bitstream nature of chaining from the toplevel application
1415    if the toplevel application didn't particularly care.  However, at
1416    the point that we actually read audio back, the multiple-section
1417    nature must surface: Multiple bitstream sections do not necessarily
1418    have to have the same number of channels or sampling rate.
1419
1420    ov_read returns the sequential logical bitstream number currently
1421    being decoded along with the PCM data in order that the toplevel
1422    application can take action on channel/sample rate changes.  This
1423    number will be incremented even for streamed (non-seekable) streams
1424    (for seekable streams, it represents the actual logical bitstream
1425    index within the physical bitstream.  Note that the accessor
1426    functions above are aware of this dichotomy).
1427
1428    input values: buffer) a buffer to hold packed PCM data for return
1429                  length) the byte length requested to be placed into buffer
1430                  bigendianp) should the data be packed LSB first (0) or
1431                              MSB first (1)
1432                  word) word size for output.  currently 1 (byte) or 
1433                        2 (16 bit short)
1434
1435    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1436                    0) EOF
1437                    n) number of bytes of PCM actually returned.  The
1438                    below works on a packet-by-packet basis, so the
1439                    return length is not related to the 'length' passed
1440                    in, just guaranteed to fit.
1441
1442             *section) set to the logical bitstream number */
1443
1444 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1445                     int bigendianp,int word,int sgned,int *bitstream){
1446   int i,j;
1447   int host_endian = host_is_big_endian();
1448
1449   float **pcm;
1450   long samples;
1451
1452   if(vf->ready_state<OPENED)return(OV_EINVAL);
1453
1454   while(1){
1455     if(vf->ready_state>=STREAMSET){
1456       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1457       if(samples)break;
1458     }
1459
1460     /* suck in another packet */
1461     {
1462       int ret=_fetch_and_process_packet(vf,NULL,1);
1463       if(ret==OV_EOF)return(0);
1464       if(ret<=0)return(ret);
1465     }
1466
1467   }
1468
1469   if(samples>0){
1470   
1471     /* yay! proceed to pack data into the byte buffer */
1472     
1473     long channels=ov_info(vf,-1)->channels;
1474     long bytespersample=word * channels;
1475     vorbis_fpu_control fpu;
1476     if(samples>length/bytespersample)samples=length/bytespersample;
1477     
1478     /* a tight loop to pack each size */
1479     {
1480       int val;
1481       if(word==1){
1482         int off=(sgned?0:128);
1483         vorbis_fpu_setround(&fpu);
1484         for(j=0;j<samples;j++)
1485           for(i=0;i<channels;i++){
1486             val=vorbis_ftoi(pcm[i][j]*128.f);
1487             if(val>127)val=127;
1488             else if(val<-128)val=-128;
1489             *buffer++=val+off;
1490           }
1491         vorbis_fpu_restore(fpu);
1492       }else{
1493         int off=(sgned?0:32768);
1494         
1495         if(host_endian==bigendianp){
1496           if(sgned){
1497             
1498             vorbis_fpu_setround(&fpu);
1499             for(i=0;i<channels;i++) { /* It's faster in this order */
1500               float *src=pcm[i];
1501               short *dest=((short *)buffer)+i;
1502               for(j=0;j<samples;j++) {
1503                 val=vorbis_ftoi(src[j]*32768.f);
1504                 if(val>32767)val=32767;
1505                 else if(val<-32768)val=-32768;
1506                 *dest=val;
1507                 dest+=channels;
1508               }
1509             }
1510             vorbis_fpu_restore(fpu);
1511             
1512           }else{
1513             
1514             vorbis_fpu_setround(&fpu);
1515             for(i=0;i<channels;i++) {
1516               float *src=pcm[i];
1517               short *dest=((short *)buffer)+i;
1518               for(j=0;j<samples;j++) {
1519                 val=vorbis_ftoi(src[j]*32768.f);
1520                 if(val>32767)val=32767;
1521                 else if(val<-32768)val=-32768;
1522                 *dest=val+off;
1523                 dest+=channels;
1524               }
1525             }
1526             vorbis_fpu_restore(fpu);
1527             
1528           }
1529         }else if(bigendianp){
1530           
1531           vorbis_fpu_setround(&fpu);
1532           for(j=0;j<samples;j++)
1533             for(i=0;i<channels;i++){
1534               val=vorbis_ftoi(pcm[i][j]*32768.f);
1535               if(val>32767)val=32767;
1536               else if(val<-32768)val=-32768;
1537               val+=off;
1538               *buffer++=(val>>8);
1539               *buffer++=(val&0xff);
1540             }
1541           vorbis_fpu_restore(fpu);
1542           
1543         }else{
1544           int val;
1545           vorbis_fpu_setround(&fpu);
1546           for(j=0;j<samples;j++)
1547             for(i=0;i<channels;i++){
1548               val=vorbis_ftoi(pcm[i][j]*32768.f);
1549               if(val>32767)val=32767;
1550               else if(val<-32768)val=-32768;
1551               val+=off;
1552               *buffer++=(val&0xff);
1553               *buffer++=(val>>8);
1554                 }
1555           vorbis_fpu_restore(fpu);  
1556           
1557         }
1558       }
1559     }
1560     
1561     vorbis_synthesis_read(&vf->vd,samples);
1562     vf->pcm_offset+=samples;
1563     if(bitstream)*bitstream=vf->current_link;
1564     return(samples*bytespersample);
1565   }else{
1566     return(samples);
1567   }
1568 }
1569
1570 /* input values: pcm_channels) a float vector per channel of output
1571                  length) the sample length being read by the app
1572
1573    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1574                    0) EOF
1575                    n) number of samples of PCM actually returned.  The
1576                    below works on a packet-by-packet basis, so the
1577                    return length is not related to the 'length' passed
1578                    in, just guaranteed to fit.
1579
1580             *section) set to the logical bitstream number */
1581
1582
1583
1584 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1585                    int *bitstream){
1586
1587   if(vf->ready_state<OPENED)return(OV_EINVAL);
1588
1589   while(1){
1590     if(vf->ready_state>=STREAMSET){
1591       float **pcm;
1592       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1593       if(samples){
1594         if(pcm_channels)*pcm_channels=pcm;
1595         if(samples>length)samples=length;
1596         vorbis_synthesis_read(&vf->vd,samples);
1597         vf->pcm_offset+=samples;
1598         if(bitstream)*bitstream=vf->current_link;
1599         return samples;
1600
1601       }
1602     }
1603
1604     /* suck in another packet */
1605     {
1606       int ret=_fetch_and_process_packet(vf,NULL,1);
1607       if(ret==OV_EOF)return(0);
1608       if(ret<=0)return(ret);
1609     }
1610
1611   }
1612 }
1613