Much faster seeking internal to libvorbisfile. Makes more intelligent guesses when...
[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 SOURCE IS GOVERNED BY *
5  * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH    *
6  * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.        *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
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.38 2001/02/14 13:12:15 msmith 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 course 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 #define CHUNKSIZE 4096
61 static long _get_data(OggVorbis_File *vf){
62   errno=0;
63   if(vf->datasource){
64     char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
65     long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
66     if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
67     if(bytes==0 && errno)return(-1);
68     return(bytes);
69   }else
70     return(0);
71 }
72
73 /* save a tiny smidge of verbosity to make the code more readable */
74 static void _seek_helper(OggVorbis_File *vf,long offset){
75   if(vf->datasource){ 
76     (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
77     vf->offset=offset;
78     ogg_sync_reset(&vf->oy);
79   }else{
80     /* shouldn't happen unless someone writes a broken callback */
81     return;
82   }
83 }
84
85 /* The read/seek functions track absolute position within the stream */
86
87 /* from the head of the stream, get the next page.  boundary specifies
88    if the function is allowed to fetch more data from the stream (and
89    how much) or only use internally buffered data.
90
91    boundary: -1) unbounded search
92               0) read no additional data; use cached only
93               n) search for a new page beginning for n bytes
94
95    return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
96               n) found a page at absolute offset n */
97
98 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
99   if(boundary>0)boundary+=vf->offset;
100   while(1){
101     long more;
102
103     if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
104     more=ogg_sync_pageseek(&vf->oy,og);
105     
106     if(more<0){
107       /* skipped n bytes */
108       vf->offset-=more;
109     }else{
110       if(more==0){
111         /* send more paramedics */
112         if(!boundary)return(OV_FALSE);
113         {
114           long ret=_get_data(vf);
115           if(ret==0)return(OV_EOF);
116           if(ret<0)return(OV_EREAD);
117         }
118       }else{
119         /* got a page.  Return the offset at the page beginning,
120            advance the internal offset past the page end */
121         long ret=vf->offset;
122         vf->offset+=more;
123         return(ret);
124         
125       }
126     }
127   }
128 }
129
130 /* find the latest page beginning before the current stream cursor
131    position. Much dirtier than the above as Ogg doesn't have any
132    backward search linkage.  no 'readp' as it will certainly have to
133    read. */
134 /* returns offset or OV_EREAD, OV_FAULT */
135 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
136   long begin=vf->offset;
137   long ret;
138   int offset=-1;
139
140   while(offset==-1){
141     begin-=CHUNKSIZE;
142     _seek_helper(vf,begin);
143     while(vf->offset<begin+CHUNKSIZE){
144       ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
145       if(ret==OV_EREAD)return(OV_EREAD);
146       if(ret<0){
147         break;
148       }else{
149         offset=ret;
150       }
151     }
152   }
153
154   /* we have the offset.  Actually snork and hold the page now */
155   _seek_helper(vf,offset);
156   ret=_get_next_page(vf,og,CHUNKSIZE);
157   if(ret<0)
158     /* this shouldn't be possible */
159     return(OV_EFAULT);
160
161   return(offset);
162 }
163
164 /* finds each bitstream link one at a time using a bisection search
165    (has to begin by knowing the offset of the lb's initial page).
166    Recurses for each link so it can alloc the link storage after
167    finding them all, then unroll and fill the cache at the same time */
168 static int _bisect_forward_serialno(OggVorbis_File *vf,
169                                     long begin,
170                                     long searched,
171                                     long end,
172                                     long currentno,
173                                     long m){
174   long endsearched=end;
175   long next=end;
176   ogg_page og;
177   long ret;
178   
179   /* the below guards against garbage seperating the last and
180      first pages of two links. */
181   while(searched<endsearched){
182     long bisect;
183     
184     if(endsearched-searched<CHUNKSIZE){
185       bisect=searched;
186     }else{
187       bisect=(searched+endsearched)/2;
188     }
189     
190     _seek_helper(vf,bisect);
191     ret=_get_next_page(vf,&og,-1);
192     if(ret==OV_EREAD)return(OV_EREAD);
193     if(ret<0 || ogg_page_serialno(&og)!=currentno){
194       endsearched=bisect;
195       if(ret>=0)next=ret;
196     }else{
197       searched=ret+og.header_len+og.body_len;
198     }
199   }
200
201   _seek_helper(vf,next);
202   ret=_get_next_page(vf,&og,-1);
203   if(ret==OV_EREAD)return(OV_EREAD);
204   
205   if(searched>=end || ret<0){
206     vf->links=m+1;
207     vf->offsets=_ogg_malloc((m+2)*sizeof(ogg_int64_t));
208     vf->offsets[m+1]=searched;
209   }else{
210     ret=_bisect_forward_serialno(vf,next,vf->offset,
211                                  end,ogg_page_serialno(&og),m+1);
212     if(ret==OV_EREAD)return(OV_EREAD);
213   }
214   
215   vf->offsets[m]=begin;
216   return(0);
217 }
218
219 /* uses the local ogg_stream storage in vf; this is important for
220    non-streaming input sources */
221 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
222                           long *serialno,ogg_page *og_ptr){
223   ogg_page og;
224   ogg_packet op;
225   int i,ret=0;
226   
227   if(!og_ptr){
228     ret=_get_next_page(vf,&og,CHUNKSIZE);
229     if(ret==OV_EREAD)return(OV_EREAD);
230     if(ret<0)return OV_ENOTVORBIS;
231     og_ptr=&og;
232   }
233
234   if(serialno)*serialno=ogg_page_serialno(og_ptr);
235   ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
236   
237   /* extract the initial header from the first page and verify that the
238      Ogg bitstream is in fact Vorbis data */
239   
240   vorbis_info_init(vi);
241   vorbis_comment_init(vc);
242   
243   i=0;
244   while(i<3){
245     ogg_stream_pagein(&vf->os,og_ptr);
246     while(i<3){
247       int result=ogg_stream_packetout(&vf->os,&op);
248       if(result==0)break;
249       if(result==-1){
250         ret=OV_EBADHEADER;
251         goto bail_header;
252       }
253       if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
254         goto bail_header;
255       }
256       i++;
257     }
258     if(i<3)
259       if(_get_next_page(vf,og_ptr,1)<0){
260         ret=OV_EBADHEADER;
261         goto bail_header;
262       }
263   }
264   return 0; 
265
266  bail_header:
267   vorbis_info_clear(vi);
268   vorbis_comment_clear(vc);
269   ogg_stream_clear(&vf->os);
270   return ret;
271 }
272
273 /* last step of the OggVorbis_File initialization; get all the
274    vorbis_info structs and PCM positions.  Only called by the seekable
275    initialization (local stream storage is hacked slightly; pay
276    attention to how that's done) */
277
278 /* this is void and does not propogate errors up because we want to be
279    able to open and use damaged bitstreams as well as we can.  Just
280    watch out for missing information for links in the OggVorbis_File
281    struct */
282 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
283                                   vorbis_comment *first_c,
284                                   long dataoffset){
285   ogg_page og;
286   int i,ret;
287   
288   vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
289   vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
290   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
291   vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
292   vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
293   
294   for(i=0;i<vf->links;i++){
295     if(first_i && first_c && i==0){
296       /* we already grabbed the initial header earlier.  This just
297          saves the waste of grabbing it again */
298       memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
299       memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
300       vf->dataoffsets[i]=dataoffset;
301     }else{
302
303       /* seek to the location of the initial header */
304
305       _seek_helper(vf,vf->offsets[i]);
306       if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
307         vf->dataoffsets[i]=-1;
308       }else{
309         vf->dataoffsets[i]=vf->offset;
310         ogg_stream_clear(&vf->os);
311       }
312     }
313
314     /* get the serial number and PCM length of this link. To do this,
315        get the last page of the stream */
316     {
317       long end=vf->offsets[i+1];
318       _seek_helper(vf,end);
319
320       while(1){
321         ret=_get_prev_page(vf,&og);
322         if(ret<0){
323           /* this should not be possible, actually */
324           vorbis_info_clear(vf->vi+i);
325           vorbis_comment_clear(vf->vc+i);
326           break;
327         }
328         if(ogg_page_granulepos(&og)!=-1){
329           vf->serialnos[i]=ogg_page_serialno(&og);
330           vf->pcmlengths[i]=ogg_page_granulepos(&og);
331           break;
332         }
333       }
334     }
335   }
336 }
337
338 static void _make_decode_ready(OggVorbis_File *vf){
339   if(vf->decode_ready)return;
340   if(vf->seekable){
341     vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
342   }else{
343     vorbis_synthesis_init(&vf->vd,vf->vi);
344   }    
345   vorbis_block_init(&vf->vd,&vf->vb);
346   vf->decode_ready=1;
347   return;
348 }
349
350 static int _open_seekable(OggVorbis_File *vf){
351   vorbis_info initial_i;
352   vorbis_comment initial_c;
353   long serialno,end;
354   int ret;
355   long dataoffset;
356   ogg_page og;
357   
358   /* is this even vorbis...? */
359   ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno,NULL);
360   dataoffset=vf->offset;
361   ogg_stream_clear(&vf->os);
362   if(ret<0)return(ret);
363   
364   /* we can seek, so set out learning all about this file */
365   vf->seekable=1;
366   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
367   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
368   
369   /* We get the offset for the last page of the physical bitstream.
370      Most OggVorbis files will contain a single logical bitstream */
371   end=_get_prev_page(vf,&og);
372   if(end<0){
373     ogg_stream_clear(&vf->os);
374     return(end);
375   }
376
377   /* more than one logical bitstream? */
378   if(ogg_page_serialno(&og)!=serialno){
379
380     /* Chained bitstream. Bisect-search each logical bitstream
381        section.  Do so based on serial number only */
382     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
383       ogg_stream_clear(&vf->os);
384       return(OV_EREAD);
385     }
386
387   }else{
388
389     /* Only one logical bitstream */
390     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
391       ogg_stream_clear(&vf->os);
392       return(OV_EREAD);
393     }
394
395   }
396
397   _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
398   return(ov_raw_seek(vf,0));
399
400 }
401
402 static int _open_nonseekable(OggVorbis_File *vf){
403   int ret;
404   /* we cannot seek. Set up a 'single' (current) logical bitstream entry  */
405   vf->links=1;
406   vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
407   vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
408
409   /* Try to fetch the headers, maintaining all the storage */
410   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0)
411     return(ret);
412   _make_decode_ready(vf);
413
414   return 0;
415 }
416
417 /* clear out the current logical bitstream decoder */ 
418 static void _decode_clear(OggVorbis_File *vf){
419   ogg_stream_clear(&vf->os);
420   vorbis_dsp_clear(&vf->vd);
421   vorbis_block_clear(&vf->vb);
422   vf->decode_ready=0;
423
424   vf->bittrack=0.f;
425   vf->samptrack=0.f;
426 }
427
428 /* fetch and process a packet.  Handles the case where we're at a
429    bitstream boundary and dumps the decoding machine.  If the decoding
430    machine is unloaded, it loads it.  It also keeps pcm_offset up to
431    date (seek and read both use this.  seek uses a special hack with
432    readp). 
433
434    return: <0) error, OV_HOLE (lost packet) or OV_EOF
435             0) need more data (only if readp==0)
436             1) got a packet 
437 */
438
439 static int _process_packet(OggVorbis_File *vf,int readp){
440   ogg_page og;
441
442   /* handle one packet.  Try to fetch it from current stream state */
443   /* extract packets from page */
444   while(1){
445     
446     /* process a packet if we can.  If the machine isn't loaded,
447        neither is a page */
448     if(vf->decode_ready){
449       ogg_packet op;
450       int result=ogg_stream_packetout(&vf->os,&op);
451       ogg_int64_t granulepos;
452       
453       if(result==-1)return(OV_HOLE); /* hole in the data. */
454       if(result>0){
455         /* got a packet.  process it */
456         granulepos=op.granulepos;
457         if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
458                                                header handling.  The
459                                                header packets aren't
460                                                audio, so if/when we
461                                                submit them,
462                                                vorbis_synthesis will
463                                                reject them */
464
465           /* suck in the synthesis data and track bitrate */
466           {
467             int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
468             vorbis_synthesis_blockin(&vf->vd,&vf->vb);
469             vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
470             vf->bittrack+=op.bytes*8;
471           }
472           
473           /* update the pcm offset. */
474           if(granulepos!=-1 && !op.e_o_s){
475             int link=(vf->seekable?vf->current_link:0);
476             int i,samples;
477             
478             /* this packet has a pcm_offset on it (the last packet
479                completed on a page carries the offset) After processing
480                (above), we know the pcm position of the *last* sample
481                ready to be returned. Find the offset of the *first*
482
483                As an aside, this trick is inaccurate if we begin
484                reading anew right at the last page; the end-of-stream
485                granulepos declares the last frame in the stream, and the
486                last packet of the last page may be a partial frame.
487                So, we need a previous granulepos from an in-sequence page
488                to have a reference point.  Thus the !op.e_o_s clause
489                above */
490             
491             samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
492             
493             granulepos-=samples;
494             for(i=0;i<link;i++)
495               granulepos+=vf->pcmlengths[i];
496             vf->pcm_offset=granulepos;
497           }
498           return(1);
499         }
500       }
501     }
502
503     if(!readp)return(0);
504     if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. leave unitialized */
505
506     /* bitrate tracking; add the header's bytes here, the body bytes
507        are done by packet above */
508     vf->bittrack+=og.header_len*8;
509
510     /* has our decoding just traversed a bitstream boundary? */
511     if(vf->decode_ready){
512       if(vf->current_serialno!=ogg_page_serialno(&og)){
513         _decode_clear(vf);
514       }
515     }
516
517     /* Do we need to load a new machine before submitting the page? */
518     /* This is different in the seekable and non-seekable cases.  
519
520        In the seekable case, we already have all the header
521        information loaded and cached; we just initialize the machine
522        with it and continue on our merry way.
523
524        In the non-seekable (streaming) case, we'll only be at a
525        boundary if we just left the previous logical bitstream and
526        we're now nominally at the header of the next bitstream
527     */
528
529     if(!vf->decode_ready){
530       int link;
531       if(vf->seekable){
532         vf->current_serialno=ogg_page_serialno(&og);
533         
534         /* match the serialno to bitstream section.  We use this rather than
535            offset positions to avoid problems near logical bitstream
536            boundaries */
537         for(link=0;link<vf->links;link++)
538           if(vf->serialnos[link]==vf->current_serialno)break;
539         if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
540                                                    stream.  error out,
541                                                    leave machine
542                                                    uninitialized */
543         
544         vf->current_link=link;
545         
546         ogg_stream_init(&vf->os,vf->current_serialno);
547         ogg_stream_reset(&vf->os); 
548         
549       }else{
550         /* we're streaming */
551         /* fetch the three header packets, build the info struct */
552         
553         _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
554         vf->current_link++;
555         link=0;
556       }
557       
558       _make_decode_ready(vf);
559     }
560     ogg_stream_pagein(&vf->os,&og);
561   }
562 }
563
564 /**********************************************************************
565  * The helpers are over; it's all toplevel interface from here on out */
566  
567 /* clear out the OggVorbis_File struct */
568 int ov_clear(OggVorbis_File *vf){
569   if(vf){
570     vorbis_block_clear(&vf->vb);
571     vorbis_dsp_clear(&vf->vd);
572     ogg_stream_clear(&vf->os);
573     
574     if(vf->vi && vf->links){
575       int i;
576       for(i=0;i<vf->links;i++){
577         vorbis_info_clear(vf->vi+i);
578         vorbis_comment_clear(vf->vc+i);
579       }
580       _ogg_free(vf->vi);
581       _ogg_free(vf->vc);
582     }
583     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
584     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
585     if(vf->serialnos)_ogg_free(vf->serialnos);
586     if(vf->offsets)_ogg_free(vf->offsets);
587     ogg_sync_clear(&vf->oy);
588     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
589     memset(vf,0,sizeof(OggVorbis_File));
590   }
591 #ifdef DEBUG_LEAKS
592   _VDBG_dump();
593 #endif
594   return(0);
595 }
596
597 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
598   if(f==NULL)return(-1);
599   return fseek(f,(int)off,whence);
600 }
601
602 /* inspects the OggVorbis file and finds/documents all the logical
603    bitstreams contained in it.  Tries to be tolerant of logical
604    bitstream sections that are truncated/woogie. 
605
606    return: -1) error
607             0) OK
608 */
609
610 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
611   ov_callbacks callbacks = {
612     (size_t (*)(void *, size_t, size_t, void *))  fread,
613     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
614     (int (*)(void *))                             fclose,
615     (long (*)(void *))                            ftell
616   };
617
618   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
619 }
620   
621
622 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
623     ov_callbacks callbacks)
624 {
625   long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
626   int ret;
627
628   memset(vf,0,sizeof(OggVorbis_File));
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(offset!=-1){
647     ret=_open_seekable(vf);
648   }else{
649     ret=_open_nonseekable(vf);
650   }
651   if(ret){
652     vf->datasource=NULL;
653     ov_clear(vf);
654   }
655   return(ret);
656 }
657
658 /* How many logical bitstreams in this physical bitstream? */
659 long ov_streams(OggVorbis_File *vf){
660   return vf->links;
661 }
662
663 /* Is the FILE * associated with vf seekable? */
664 long ov_seekable(OggVorbis_File *vf){
665   return vf->seekable;
666 }
667
668 /* returns the bitrate for a given logical bitstream or the entire
669    physical bitstream.  If the file is open for random access, it will
670    find the *actual* average bitrate.  If the file is streaming, it
671    returns the nominal bitrate (if set) else the average of the
672    upper/lower bounds (if set) else -1 (unset).
673
674    If you want the actual bitrate field settings, get them from the
675    vorbis_info structs */
676
677 long ov_bitrate(OggVorbis_File *vf,int i){
678   if(i>=vf->links)return(OV_EINVAL);
679   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
680   if(i<0){
681     ogg_int64_t bits=0;
682     int i;
683     for(i=0;i<vf->links;i++)
684       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
685     return(rint(bits/ov_time_total(vf,-1)));
686   }else{
687     if(vf->seekable){
688       /* return the actual bitrate */
689       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
690     }else{
691       /* return nominal if set */
692       if(vf->vi[i].bitrate_nominal>0){
693         return vf->vi[i].bitrate_nominal;
694       }else{
695         if(vf->vi[i].bitrate_upper>0){
696           if(vf->vi[i].bitrate_lower>0){
697             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
698           }else{
699             return vf->vi[i].bitrate_upper;
700           }
701         }
702         return(OV_FALSE);
703       }
704     }
705   }
706 }
707
708 /* returns the actual bitrate since last call.  returns -1 if no
709    additional data to offer since last call (or at beginning of stream) */
710 long ov_bitrate_instant(OggVorbis_File *vf){
711   int link=(vf->seekable?vf->current_link:0);
712   long ret;
713   if(vf->samptrack==0)return(OV_FALSE);
714   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
715   vf->bittrack=0.f;
716   vf->samptrack=0.f;
717   return(ret);
718 }
719
720 /* Guess */
721 long ov_serialnumber(OggVorbis_File *vf,int i){
722   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
723   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
724   if(i<0){
725     return(vf->current_serialno);
726   }else{
727     return(vf->serialnos[i]);
728   }
729 }
730
731 /* returns: total raw (compressed) length of content if i==-1
732             raw (compressed) length of that logical bitstream for i==0 to n
733             -1 if the stream is not seekable (we can't know the length)
734 */
735 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
736   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
737   if(i<0){
738     long acc=0;
739     int i;
740     for(i=0;i<vf->links;i++)
741       acc+=ov_raw_total(vf,i);
742     return(acc);
743   }else{
744     return(vf->offsets[i+1]-vf->offsets[i]);
745   }
746 }
747
748 /* returns: total PCM length (samples) of content if i==-1
749             PCM length (samples) of that logical bitstream for i==0 to n
750             -1 if the stream is not seekable (we can't know the length)
751 */
752 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
753   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
754   if(i<0){
755     ogg_int64_t acc=0;
756     int i;
757     for(i=0;i<vf->links;i++)
758       acc+=ov_pcm_total(vf,i);
759     return(acc);
760   }else{
761     return(vf->pcmlengths[i]);
762   }
763 }
764
765 /* returns: total seconds of content if i==-1
766             seconds in that logical bitstream for i==0 to n
767             -1 if the stream is not seekable (we can't know the length)
768 */
769 double ov_time_total(OggVorbis_File *vf,int i){
770   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
771   if(i<0){
772     double acc=0;
773     int i;
774     for(i=0;i<vf->links;i++)
775       acc+=ov_time_total(vf,i);
776     return(acc);
777   }else{
778     return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
779   }
780 }
781
782 /* seek to an offset relative to the *compressed* data. This also
783    immediately sucks in and decodes pages to update the PCM cursor. It
784    will cross a logical bitstream boundary, but only if it can't get
785    any packets out of the tail of the bitstream we seek to (so no
786    surprises). 
787
788    returns zero on success, nonzero on failure */
789
790 int ov_raw_seek(OggVorbis_File *vf,long pos){
791   int flag=0;
792   if(!vf->seekable)return(OV_ENOSEEK); /* don't dump machine if we can't seek */
793   if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
794
795   /* clear out decoding machine state */
796   vf->pcm_offset=-1;
797   _decode_clear(vf);
798   
799   /* seek */
800   _seek_helper(vf,pos);
801
802   /* we need to make sure the pcm_offset is set.  We use the
803      _fetch_packet helper to process one packet with readp set, then
804      call it until it returns '0' with readp not set (the last packet
805      from a page has the 'granulepos' field set, and that's how the
806      helper updates the offset */
807
808   while(!flag){
809     switch(_process_packet(vf,1)){
810     case 0:case OV_EOF:
811       /* oh, eof. There are no packets remaining.  Set the pcm offset to
812          the end of file */
813       vf->pcm_offset=ov_pcm_total(vf,-1);
814       return(0);
815     case OV_HOLE:
816       break;
817     case OV_EBADLINK:
818       goto seek_error;
819     default:
820       /* all OK */
821       flag=1;
822       break;
823     }
824   }
825   
826   while(1){
827     /* don't have to check each time through for the updated granule;
828        it's always the last complete packet on a page */
829     switch(_process_packet(vf,0)){
830     case 0:case OV_EOF:
831       /* the offset is set unless it's a bogus bitstream with no
832          offset information but that's not our fault.  We still run
833          gracefully, we're just missing the offset */
834       return(0);
835     case OV_EBADLINK:
836       goto seek_error;
837     default:
838       /* continue processing packets */
839       break;
840     }
841   }
842   
843  seek_error:
844   /* dump the machine so we're in a known state */
845   vf->pcm_offset=-1;
846   _decode_clear(vf);
847   return OV_EBADLINK;
848 }
849
850 int ov_raw_seek2(OggVorbis_File *vf,long pos, int offset, int link){
851   int flag=0;
852   if(!vf->seekable)return(OV_ENOSEEK); /* don't dump machine if we can't seek */
853   if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
854
855   /* clear out decoding machine state */
856   vf->pcm_offset=-1;
857   _decode_clear(vf);
858 //  ogg_stream_clear(&vf->os);
859 //  vf->decode_ready=0;
860
861 //  vf->bittrack=0.f;
862 //  vf->samptrack=0.f;
863   
864   /* seek */
865   _seek_helper(vf,pos);
866
867   /* we need to make sure the pcm_offset is set.  We use the
868      _fetch_packet helper to process one packet with readp set, then
869      call it until it returns '0' with readp not set (the last packet
870      from a page has the 'granulepos' field set, and that's how the
871      helper updates the offset */
872
873   {
874     int ret;
875     ogg_page og;
876     ret=_get_next_page(vf,&og,vf->offsets[link+1]-vf->offset);
877     if( ret < 0 )
878       return ret;
879     vf->pcm_offset = offset;
880   }
881
882   return 0;
883
884 }
885
886 /* Page granularity seek (faster than sample granularity because we
887    don't do the last bit of decode to find a specific sample).
888
889    Seek to the last [granule marked] page preceeding the specified pos
890    location, such that decoding past the returned point will quickly
891    arrive at the requested position. */
892 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
893   int link=-1;
894   long ret;
895   ogg_int64_t total=ov_pcm_total(vf,-1);
896
897   if(!vf->seekable)return(OV_ENOSEEK);
898   if(pos<0 || pos>total)return(OV_EINVAL);
899
900   /* which bitstream section does this pcm offset occur in? */
901   for(link=vf->links-1;link>=0;link--){
902     total-=vf->pcmlengths[link];
903     if(pos>=total)break;
904   }
905
906   /* search within the logical bitstream for the page with the highest
907      pcm_pos preceeding (or equal to) pos.  There is a danger here;
908      missing pages or incorrect frame number information in the
909      bitstream could make our task impossible.  Account for that (it
910      would be an error condition) */
911
912 #if 1
913   // HB (Nicholas Vinen)
914   // I think this should be much faster.
915   {
916     ogg_int64_t target=pos-total;
917     long end=vf->offsets[link+1];
918     long begin=vf->offsets[link];
919     ogg_int64_t endtime = vf->pcmlengths[link];
920     ogg_int64_t begintime = 0;
921     long best=begin;
922
923     ogg_page og;
924     while(begin<end){
925       long bisect;
926
927       if(end-begin<CHUNKSIZE){
928         bisect=begin;
929       }else{
930         //take a (pretty decent) guess.
931         bisect=begin + (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
932         if(bisect<=begin)
933           bisect=begin+1;
934       }
935     
936      TryAgain:
937       _seek_helper(vf,bisect);
938       ret=_get_next_page(vf,&og,end-bisect);
939       switch(ret){
940       case OV_FALSE: case OV_EOF:
941         if(bisect==begin+1)
942           goto found_it;
943         if(bisect==0)
944           goto seek_error;
945         bisect-=CHUNKSIZE;
946         if(bisect<=begin)
947           bisect=begin+1;
948         goto TryAgain;
949       case OV_EREAD:
950         goto seek_error;
951       default:
952         {
953           ogg_int64_t granulepos=ogg_page_granulepos(&og);
954           if(granulepos<target){
955             best=ret;  /* raw offset of packet with granulepos */ 
956             begin=vf->offset; /* raw offset of next packet */
957             begintime=granulepos;
958
959             if(target-begintime<2000) { //less than 1s before we hit the right page.
960               bisect=begin+1;
961               goto TryAgain;
962             }
963
964           }else{
965             if(bisect<=begin+1)
966               goto found_it;
967
968             if(end==vf->offset){
969               //we're pretty close - we'd be stuck in an endless loop otherwise...
970               bisect-=CHUNKSIZE;
971               goto TryAgain;    //sorry, I like gotos :)
972             }
973             end=vf->offset;
974             endtime=granulepos;
975           }
976         }
977       }
978     }
979
980     /* found our page. seek to it (call raw_seek). */
981    found_it:
982     if(link!=vf->current_link){
983       if((ret=ov_raw_seek(vf,best)))goto seek_error;
984     } else {
985       if((ret=ov_raw_seek2(vf,best,begintime,link)))goto seek_error;
986     }
987   }
988
989 #else
990   {
991     ogg_int64_t target=pos-total;
992     long end=vf->offsets[link+1];
993     long begin=vf->offsets[link];
994     long best=begin;
995
996     ogg_page og;
997     while(begin<end){
998       long bisect;
999     
1000       if(end-begin<CHUNKSIZE){
1001         bisect=begin;
1002       }else{
1003         bisect=(end+begin)/2;
1004       }
1005     
1006       _seek_helper(vf,bisect);
1007       ret=_get_next_page(vf,&og,end-bisect);
1008       switch(ret){
1009       case OV_FALSE: case OV_EOF:
1010         end=bisect;
1011         break;
1012       case OV_EREAD:
1013         goto seek_error;
1014       default:
1015         {
1016           ogg_int64_t granulepos=ogg_page_granulepos(&og);
1017           if(granulepos<target){
1018             best=ret;  /* raw offset of packet with granulepos */ 
1019             begin=vf->offset; /* raw offset of next packet */
1020           }else{
1021             end=bisect;
1022           }
1023         }
1024       }
1025     }
1026
1027     /* found our page. seek to it (call raw_seek). */
1028     
1029     if((ret=ov_raw_seek(vf,best)))goto seek_error;
1030   }
1031 #endif
1032
1033   /* verify result */
1034   if(vf->pcm_offset>=pos || pos>ov_pcm_total(vf,-1)){
1035     ret=OV_EFAULT;
1036     goto seek_error;
1037   }
1038   return(0);
1039   
1040  seek_error:
1041   /* dump machine so we're in a known state */
1042   vf->pcm_offset=-1;
1043   _decode_clear(vf);
1044   return ret;
1045 }
1046
1047 /* seek to a sample offset relative to the decompressed pcm stream 
1048    returns zero on success, nonzero on failure */
1049
1050 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1051   int ret=ov_pcm_seek_page(vf,pos);
1052   if(ret<0)return(ret);
1053   
1054   /* discard samples until we reach the desired position. Crossing a
1055      logical bitstream boundary with abandon is OK. */
1056   while(vf->pcm_offset<pos){
1057     float **pcm;
1058     long target=pos-vf->pcm_offset;
1059     long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1060     if( samples == 0 )
1061        break;
1062
1063     if(samples>target)samples=target;
1064     vorbis_synthesis_read(&vf->vd,samples);
1065     vf->pcm_offset+=samples;
1066     
1067     if(samples<target)
1068       if(_process_packet(vf,1)==0)
1069         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1070   }
1071   return 0;
1072 }
1073
1074 /* seek to a playback time relative to the decompressed pcm stream 
1075    returns zero on success, nonzero on failure */
1076 int ov_time_seek(OggVorbis_File *vf,double seconds){
1077   /* translate time to PCM position and call ov_pcm_seek */
1078
1079   int link=-1;
1080   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1081   double time_total=ov_time_total(vf,-1);
1082
1083   if(!vf->seekable)return(OV_ENOSEEK);
1084   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1085   
1086   /* which bitstream section does this time offset occur in? */
1087   for(link=vf->links-1;link>=0;link--){
1088     pcm_total-=vf->pcmlengths[link];
1089     time_total-=ov_time_total(vf,link);
1090     if(seconds>=time_total)break;
1091   }
1092
1093   /* enough information to convert time offset to pcm offset */
1094   {
1095     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1096     return(ov_pcm_seek(vf,target));
1097   }
1098 }
1099
1100 /* page-granularity version of ov_time_seek 
1101    returns zero on success, nonzero on failure */
1102 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1103   /* translate time to PCM position and call ov_pcm_seek */
1104
1105   int link=-1;
1106   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1107   double time_total=ov_time_total(vf,-1);
1108
1109   if(!vf->seekable)return(OV_ENOSEEK);
1110   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1111   
1112   /* which bitstream section does this time offset occur in? */
1113   for(link=vf->links-1;link>=0;link--){
1114     pcm_total-=vf->pcmlengths[link];
1115     time_total-=ov_time_total(vf,link);
1116     if(seconds>=time_total)break;
1117   }
1118
1119   /* enough information to convert time offset to pcm offset */
1120   {
1121     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1122     return(ov_pcm_seek_page(vf,target));
1123   }
1124 }
1125
1126 /* tell the current stream offset cursor.  Note that seek followed by
1127    tell will likely not give the set offset due to caching */
1128 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1129   return(vf->offset);
1130 }
1131
1132 /* return PCM offset (sample) of next PCM sample to be read */
1133 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1134   return(vf->pcm_offset);
1135 }
1136
1137 /* return time offset (seconds) of next PCM sample to be read */
1138 double ov_time_tell(OggVorbis_File *vf){
1139   /* translate time to PCM position and call ov_pcm_seek */
1140
1141   int link=-1;
1142   ogg_int64_t pcm_total=0;
1143   double time_total=0.f;
1144   
1145   if(vf->seekable){
1146     pcm_total=ov_pcm_total(vf,-1);
1147     time_total=ov_time_total(vf,-1);
1148   
1149     /* which bitstream section does this time offset occur in? */
1150     for(link=vf->links-1;link>=0;link--){
1151       pcm_total-=vf->pcmlengths[link];
1152       time_total-=ov_time_total(vf,link);
1153       if(vf->pcm_offset>=pcm_total)break;
1154     }
1155   }
1156
1157   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1158 }
1159
1160 /*  link:   -1) return the vorbis_info struct for the bitstream section
1161                 currently being decoded
1162            0-n) to request information for a specific bitstream section
1163     
1164     In the case of a non-seekable bitstream, any call returns the
1165     current bitstream.  NULL in the case that the machine is not
1166     initialized */
1167
1168 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1169   if(vf->seekable){
1170     if(link<0)
1171       if(vf->decode_ready)
1172         return vf->vi+vf->current_link;
1173       else
1174         return NULL;
1175     else
1176       if(link>=vf->links)
1177         return NULL;
1178       else
1179         return vf->vi+link;
1180   }else{
1181     if(vf->decode_ready)
1182       return vf->vi;
1183     else
1184       return NULL;
1185   }
1186 }
1187
1188 /* grr, strong typing, grr, no templates/inheritence, grr */
1189 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1190   if(vf->seekable){
1191     if(link<0)
1192       if(vf->decode_ready)
1193         return vf->vc+vf->current_link;
1194       else
1195         return NULL;
1196     else
1197       if(link>=vf->links)
1198         return NULL;
1199       else
1200         return vf->vc+link;
1201   }else{
1202     if(vf->decode_ready)
1203       return vf->vc;
1204     else
1205       return NULL;
1206   }
1207 }
1208
1209 int host_is_big_endian() {
1210   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1211   unsigned char *bytewise = (unsigned char *)&pattern;
1212   if (bytewise[0] == 0xfe) return 1;
1213   return 0;
1214 }
1215
1216 /* up to this point, everything could more or less hide the multiple
1217    logical bitstream nature of chaining from the toplevel application
1218    if the toplevel application didn't particularly care.  However, at
1219    the point that we actually read audio back, the multiple-section
1220    nature must surface: Multiple bitstream sections do not necessarily
1221    have to have the same number of channels or sampling rate.
1222
1223    ov_read returns the sequential logical bitstream number currently
1224    being decoded along with the PCM data in order that the toplevel
1225    application can take action on channel/sample rate changes.  This
1226    number will be incremented even for streamed (non-seekable) streams
1227    (for seekable streams, it represents the actual logical bitstream
1228    index within the physical bitstream.  Note that the accessor
1229    functions above are aware of this dichotomy).
1230
1231    input values: buffer) a buffer to hold packed PCM data for return
1232                  length) the byte length requested to be placed into buffer
1233                  bigendianp) should the data be packed LSB first (0) or
1234                              MSB first (1)
1235                  word) word size for output.  currently 1 (byte) or 
1236                        2 (16 bit short)
1237
1238    return values: <0) error/hole in data (OV_HOLE)
1239                    0) EOF
1240                    n) number of bytes of PCM actually returned.  The
1241                    below works on a packet-by-packet basis, so the
1242                    return length is not related to the 'length' passed
1243                    in, just guaranteed to fit.
1244
1245             *section) set to the logical bitstream number */
1246
1247 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1248                     int bigendianp,int word,int sgned,int *bitstream){
1249   int i,j;
1250   int host_endian = host_is_big_endian();
1251
1252   while(1){
1253     if(vf->decode_ready){
1254       float **pcm;
1255       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1256       if(samples){
1257         /* yay! proceed to pack data into the byte buffer */
1258
1259         long channels=ov_info(vf,-1)->channels;
1260         long bytespersample=word * channels;
1261         vorbis_fpu_control fpu;
1262         if(samples>length/bytespersample)samples=length/bytespersample;
1263         
1264         /* a tight loop to pack each size */
1265         {
1266           int val;
1267           if(word==1){
1268             int off=(sgned?0:128);
1269             vorbis_fpu_setround(&fpu);
1270             for(j=0;j<samples;j++)
1271               for(i=0;i<channels;i++){
1272                 val=vorbis_ftoi(pcm[i][j]*128.f);
1273                 if(val>127)val=127;
1274                 else if(val<-128)val=-128;
1275                 *buffer++=val+off;
1276               }
1277             vorbis_fpu_restore(fpu);
1278           }else{
1279             int off=(sgned?0:32768);
1280
1281             if(host_endian==bigendianp){
1282               if(sgned){
1283
1284                 vorbis_fpu_setround(&fpu);
1285                 for(i=0;i<channels;i++) { /* It's faster in this order */
1286                   float *src=pcm[i];
1287                   short *dest=((short *)buffer)+i;
1288                   for(j=0;j<samples;j++) {
1289                     val=vorbis_ftoi(src[j]*32768.f);
1290                     if(val>32767)val=32767;
1291                     else if(val<-32768)val=-32768;
1292                     *dest=val;
1293                     dest+=channels;
1294                   }
1295                 }
1296                 vorbis_fpu_restore(fpu);
1297
1298               }else{
1299
1300                 vorbis_fpu_setround(&fpu);
1301                 for(i=0;i<channels;i++) {
1302                   float *src=pcm[i];
1303                   short *dest=((short *)buffer)+i;
1304                   for(j=0;j<samples;j++) {
1305                     val=vorbis_ftoi(src[j]*32768.f);
1306                     if(val>32767)val=32767;
1307                     else if(val<-32768)val=-32768;
1308                     *dest=val+off;
1309                     dest+=channels;
1310                   }
1311                 }
1312                 vorbis_fpu_restore(fpu);
1313
1314               }
1315             }else if(bigendianp){
1316
1317               vorbis_fpu_setround(&fpu);
1318               for(j=0;j<samples;j++)
1319                 for(i=0;i<channels;i++){
1320                   val=vorbis_ftoi(pcm[i][j]*32768.f);
1321                   if(val>32767)val=32767;
1322                   else if(val<-32768)val=-32768;
1323                   val+=off;
1324                   *buffer++=(val>>8);
1325                   *buffer++=(val&0xff);
1326                 }
1327               vorbis_fpu_restore(fpu);
1328
1329             }else{
1330               int val;
1331               vorbis_fpu_setround(&fpu);
1332               for(j=0;j<samples;j++)
1333                 for(i=0;i<channels;i++){
1334                   val=vorbis_ftoi(pcm[i][j]*32768.f);
1335                   if(val>32767)val=32767;
1336                   else if(val<-32768)val=-32768;
1337                   val+=off;
1338                   *buffer++=(val&0xff);
1339                   *buffer++=(val>>8);
1340                 }
1341               vorbis_fpu_restore(fpu);  
1342
1343             }
1344           }
1345         }
1346         
1347         vorbis_synthesis_read(&vf->vd,samples);
1348         vf->pcm_offset+=samples;
1349         if(bitstream)*bitstream=vf->current_link;
1350         return(samples*bytespersample);
1351       }
1352     }
1353
1354     /* suck in another packet */
1355     switch(_process_packet(vf,1)){
1356     case 0:case OV_EOF:
1357       return(0);
1358     case OV_HOLE:
1359       return(OV_HOLE);
1360     case OV_EBADLINK:
1361       return(OV_EBADLINK);
1362     }
1363   }
1364 }
1365
1366
1367
1368