Fixed a link-crossing bug in libvorbis (total time was reset to -1
[platform/upstream/libvorbis.git] / lib / vorbisfile.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
6  * PLEASE READ THESE TERMS DISTRIBUTING.                            *
7  *                                                                  *
8  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
9  * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: stdio-based convenience library for opening/seeking/decoding
15  last mod: $Id: vorbisfile.c,v 1.25 2000/06/15 12:17:03 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <math.h>
23 #include <assert.h>
24
25 #include "vorbis/codec.h"
26 #include "vorbis/vorbisfile.h"
27
28 #include "os.h"
29 #include "misc.h"
30
31 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
32    one logical bitstream arranged end to end (the only form of Ogg
33    multiplexing allowed in a Vorbis bitstream; grouping [parallel
34    multiplexing] is not allowed in Vorbis) */
35
36 /* A Vorbis file can be played beginning to end (streamed) without
37    worrying ahead of time about chaining (see decoder_example.c).  If
38    we have the whole file, however, and want random access
39    (seeking/scrubbing) or desire to know the total length/time of a
40    file, we need to account for the possibility of chaining. */
41
42 /* We can handle things a number of ways; we can determine the entire
43    bitstream structure right off the bat, or find pieces on demand.
44    This example determines and caches structure for the entire
45    bitstream, but builds a virtual decoder on the fly when moving
46    between links in the chain. */
47
48 /* There are also different ways to implement seeking.  Enough
49    information exists in an Ogg bitstream to seek to
50    sample-granularity positions in the output.  Or, one can seek by
51    picking some portion of the stream roughly in the desired area if
52    we only want course navigation through the stream. */
53
54 /*************************************************************************
55  * Many, many internal helpers.  The intention is not to be confusing; 
56  * rampant duplication and monolithic function implementation would be 
57  * harder to understand anyway.  The high level functions are last.  Begin
58  * grokking near the end of the file */
59
60 /* read a little more data from the file/pipe into the ogg_sync framer */
61 #define CHUNKSIZE 4096
62 static long _get_data(OggVorbis_File *vf){
63   char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
64   long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
65   ogg_sync_wrote(&vf->oy,bytes);
66   return(bytes);
67 }
68
69 /* save a tiny smidge of verbosity to make the code more readable */
70 static void _seek_helper(OggVorbis_File *vf,long offset){
71   (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
72   vf->offset=offset;
73   ogg_sync_reset(&vf->oy);
74 }
75
76 /* The read/seek functions track absolute position within the stream */
77
78 /* from the head of the stream, get the next page.  boundary specifies
79    if the function is allowed to fetch more data from the stream (and
80    how much) or only use internally buffered data.
81
82    boundary: -1) unbounded search
83               0) read no additional data; use cached only
84               n) search for a new page beginning for n bytes
85
86    return:   -1) did not find a page 
87               n) found a page at absolute offset n */
88
89 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
90   if(boundary>0)boundary+=vf->offset;
91   while(1){
92     long more;
93
94     if(boundary>0 && vf->offset>=boundary)return(-1);
95     more=ogg_sync_pageseek(&vf->oy,og);
96     
97     if(more<0){
98       /* skipped n bytes */
99       vf->offset-=more;
100     }else{
101       if(more==0){
102         /* send more paramedics */
103         if(!boundary)return(-1);
104         if(_get_data(vf)<=0)return(-1);
105       }else{
106         /* got a page.  Return the offset at the page beginning,
107            advance the internal offset past the page end */
108         long ret=vf->offset;
109         vf->offset+=more;
110         return(ret);
111         
112       }
113     }
114   }
115 }
116
117 /* find the latest page beginning before the current stream cursor
118    position. Much dirtier than the above as Ogg doesn't have any
119    backward search linkage.  no 'readp' as it will certainly have to
120    read. */
121 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
122   long begin=vf->offset;
123   long ret;
124   int offset=-1;
125
126   while(offset==-1){
127     begin-=CHUNKSIZE;
128     _seek_helper(vf,begin);
129     while(vf->offset<begin+CHUNKSIZE){
130       ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
131       if(ret==-1){
132         break;
133       }else{
134         offset=ret;
135       }
136     }
137   }
138
139   /* we have the offset.  Actually snork and hold the page now */
140   _seek_helper(vf,offset);
141   ret=_get_next_page(vf,og,CHUNKSIZE);
142   if(ret==-1){
143     /* this shouldn't be possible */
144     fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
145             "Exiting.\n");
146     exit(1);
147   }
148   return(offset);
149 }
150
151 /* finds each bitstream link one at a time using a bisection search
152    (has to begin by knowing the offset of the lb's initial page).
153    Recurses for each link so it can alloc the link storage after
154    finding them all, then unroll and fill the cache at the same time */
155 static void _bisect_forward_serialno(OggVorbis_File *vf,
156                                      long begin,
157                                      long searched,
158                                      long end,
159                                      long currentno,
160                                      long m){
161   long endsearched=end;
162   long next=end;
163   ogg_page og;
164   long ret;
165   
166   /* the below guards against garbage seperating the last and
167      first pages of two links. */
168   while(searched<endsearched){
169     long bisect;
170     
171     if(endsearched-searched<CHUNKSIZE){
172       bisect=searched;
173     }else{
174       bisect=(searched+endsearched)/2;
175     }
176     
177     _seek_helper(vf,bisect);
178     ret=_get_next_page(vf,&og,-1);
179     if(ret<0 || ogg_page_serialno(&og)!=currentno){
180       endsearched=bisect;
181       if(ret>=0)next=ret;
182     }else{
183       searched=ret+og.header_len+og.body_len;
184     }
185   }
186
187   _seek_helper(vf,next);
188   ret=_get_next_page(vf,&og,-1);
189   
190   if(searched>=end || ret==-1){
191     vf->links=m+1;
192     vf->offsets=malloc((m+2)*sizeof(int64_t));
193     vf->offsets[m+1]=searched;
194   }else{
195     _bisect_forward_serialno(vf,next,vf->offset,
196                              end,ogg_page_serialno(&og),m+1);
197   }
198   
199   vf->offsets[m]=begin;
200 }
201
202 /* uses the local ogg_stream storage in vf; this is important for
203    non-streaming input sources */
204 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
205                           long *serialno){
206   ogg_page og;
207   ogg_packet op;
208   int i,ret;
209
210   ret=_get_next_page(vf,&og,CHUNKSIZE);
211   if(ret==-1){
212     fprintf(stderr,"Did not find initial header for bitstream.\n");
213     return -1;
214   }
215   
216   if(serialno)*serialno=ogg_page_serialno(&og);
217   ogg_stream_init(&vf->os,ogg_page_serialno(&og));
218   
219   /* extract the initial header from the first page and verify that the
220      Ogg bitstream is in fact Vorbis data */
221   
222   vorbis_info_init(vi);
223   vorbis_comment_init(vc);
224   
225   i=0;
226   while(i<3){
227     ogg_stream_pagein(&vf->os,&og);
228     while(i<3){
229       int result=ogg_stream_packetout(&vf->os,&op);
230       if(result==0)break;
231       if(result==-1){
232         fprintf(stderr,"Corrupt header in logical bitstream.\n");
233         goto bail_header;
234       }
235       if(vorbis_synthesis_headerin(vi,vc,&op)){
236         fprintf(stderr,"Illegal header in logical bitstream.\n");
237         goto bail_header;
238       }
239       i++;
240     }
241     if(i<3)
242       if(_get_next_page(vf,&og,1)<0){
243         fprintf(stderr,"Missing header in logical bitstream.\n");
244         goto bail_header;
245       }
246   }
247   return 0; 
248
249  bail_header:
250   vorbis_info_clear(vi);
251   vorbis_comment_clear(vc);
252   ogg_stream_clear(&vf->os);
253   return -1;
254 }
255
256 /* last step of the OggVorbis_File initialization; get all the
257    vorbis_info structs and PCM positions.  Only called by the seekable
258    initialization (local stream storage is hacked slightly; pay
259    attention to how that's done) */
260 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
261                                   vorbis_comment *first_c,
262                                   long dataoffset){
263   ogg_page og;
264   int i,ret;
265   
266   vf->vi=calloc(vf->links,sizeof(vorbis_info));
267   vf->vc=calloc(vf->links,sizeof(vorbis_info));
268   vf->dataoffsets=malloc(vf->links*sizeof(int64_t));
269   vf->pcmlengths=malloc(vf->links*sizeof(int64_t));
270   vf->serialnos=malloc(vf->links*sizeof(long));
271   
272   for(i=0;i<vf->links;i++){
273     if(first_i && first_c && i==0){
274       /* we already grabbed the initial header earlier.  This just
275          saves the waste of grabbing it again */
276       memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
277       memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
278       vf->dataoffsets[i]=dataoffset;
279     }else{
280
281       /* seek to the location of the initial header */
282
283       _seek_helper(vf,vf->offsets[i]);
284       if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL)==-1){
285         fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
286         vf->dataoffsets[i]=-1;
287       }else{
288         vf->dataoffsets[i]=vf->offset;
289         ogg_stream_clear(&vf->os);
290       }
291     }
292
293     /* get the serial number and PCM length of this link. To do this,
294        get the last page of the stream */
295     {
296       long end=vf->offsets[i+1];
297       _seek_helper(vf,end);
298
299       while(1){
300         ret=_get_prev_page(vf,&og);
301         if(ret==-1){
302           /* this should not be possible */
303           fprintf(stderr,"Could not find last page of logical "
304                   "bitstream #%d\n\n",i);
305           vorbis_info_clear(vf->vi+i);
306           vorbis_comment_clear(vf->vc+i);
307           break;
308         }
309         if(ogg_page_frameno(&og)!=-1){
310           vf->serialnos[i]=ogg_page_serialno(&og);
311           vf->pcmlengths[i]=ogg_page_frameno(&og);
312           break;
313         }
314       }
315     }
316   }
317 }
318
319 static int _make_decode_ready(OggVorbis_File *vf){
320   if(vf->decode_ready)exit(1);
321   vorbis_synthesis_init(&vf->vd,vf->vi);
322   vorbis_block_init(&vf->vd,&vf->vb);
323   vf->decode_ready=1;
324   return(0);
325 }
326
327 static int _open_seekable(OggVorbis_File *vf){
328   vorbis_info initial_i;
329   vorbis_comment initial_c;
330   long serialno,end;
331   int ret;
332   long dataoffset;
333   ogg_page og;
334   
335   /* is this even vorbis...? */
336   ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno);
337   dataoffset=vf->offset;
338   ogg_stream_clear(&vf->os);
339   if(ret==-1)return(-1);
340   
341   /* we can seek, so set out learning all about this file */
342   vf->seekable=1;
343   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
344   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
345   
346   /* We get the offset for the last page of the physical bitstream.
347      Most OggVorbis files will contain a single logical bitstream */
348   end=_get_prev_page(vf,&og);
349
350   /* moer than one logical bitstream? */
351   if(ogg_page_serialno(&og)!=serialno){
352
353     /* Chained bitstream. Bisect-search each logical bitstream
354        section.  Do so based on serial number only */
355     _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
356
357   }else{
358
359     /* Only one logical bitstream */
360     _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
361
362   }
363
364   _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
365   ov_raw_seek(vf,0);
366
367   return(0);
368 }
369
370 static int _open_nonseekable(OggVorbis_File *vf){
371   /* we cannot seek. Set up a 'single' (current) logical bitstream entry  */
372   vf->links=1;
373   vf->vi=calloc(vf->links,sizeof(vorbis_info));
374   vf->vc=calloc(vf->links,sizeof(vorbis_info));
375
376   /* Try to fetch the headers, maintaining all the storage */
377   if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno)==-1)return(-1);
378   _make_decode_ready(vf);
379
380   return 0;
381 }
382
383 /* clear out the current logical bitstream decoder */ 
384 static void _decode_clear(OggVorbis_File *vf){
385   ogg_stream_clear(&vf->os);
386   vorbis_dsp_clear(&vf->vd);
387   vorbis_block_clear(&vf->vb);
388   vf->decode_ready=0;
389
390   vf->bittrack=0.;
391   vf->samptrack=0.;
392 }
393
394 /* fetch and process a packet.  Handles the case where we're at a
395    bitstream boundary and dumps the decoding machine.  If the decoding
396    machine is unloaded, it loads it.  It also keeps pcm_offset up to
397    date (seek and read both use this.  seek uses a special hack with
398    readp). 
399
400    return: -1) hole in the data (lost packet) 
401             0) need more date (only if readp==0)/eof
402             1) got a packet 
403 */
404
405 static int _process_packet(OggVorbis_File *vf,int readp){
406   ogg_page og;
407
408   /* handle one packet.  Try to fetch it from current stream state */
409   /* extract packets from page */
410   while(1){
411     
412     /* process a packet if we can.  If the machine isn't loaded,
413        neither is a page */
414     if(vf->decode_ready){
415       ogg_packet op;
416       int result=ogg_stream_packetout(&vf->os,&op);
417       int64_t frameno;
418       
419       if(result==-1)return(-1); /* hole in the data. alert the toplevel */
420       if(result>0){
421         /* got a packet.  process it */
422         frameno=op.frameno;
423         if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
424                                                header handling.  The
425                                                header packets aren't
426                                                audio, so if/when we
427                                                submit them,
428                                                vorbis_synthesis will
429                                                reject them */
430
431           /* suck in the synthesis data and track bitrate */
432           {
433             int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
434             vorbis_synthesis_blockin(&vf->vd,&vf->vb);
435             vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
436             vf->bittrack+=op.bytes*8;
437           }
438           
439           /* update the pcm offset. */
440           if(frameno!=-1 && !op.e_o_s){
441             int link=(vf->seekable?vf->current_link:0);
442             int i,samples;
443             
444             /* this packet has a pcm_offset on it (the last packet
445                completed on a page carries the offset) After processing
446                (above), we know the pcm position of the *last* sample
447                ready to be returned. Find the offset of the *first*
448
449                As an aside, this trick is inaccurate if we begin
450                reading anew right at the last page; the end-of-stream
451                frameno declares the last frame in the stream, and the
452                last packet of the last page may be a partial frame.
453                So, we need a previous frameno from an in-sequence page
454                to have a reference point.  Thus the !op.e_o_s clause
455                above */
456             
457             samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
458             
459             frameno-=samples;
460             for(i=0;i<link;i++)
461               frameno+=vf->pcmlengths[i];
462             vf->pcm_offset=frameno;
463           }
464           return(1);
465         }
466       }
467     }
468
469     if(!readp)return(0);
470     if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
471
472     /* bitrate tracking; add the header's bytes here, the body bytes
473        are done by packet above */
474     vf->bittrack+=og.header_len*8;
475
476     /* has our decoding just traversed a bitstream boundary? */
477     if(vf->decode_ready){
478       if(vf->current_serialno!=ogg_page_serialno(&og)){
479         _decode_clear(vf);
480       }
481     }
482
483     /* Do we need to load a new machine before submitting the page? */
484     /* This is different in the seekable and non-seekable cases.  
485
486        In the seekable case, we already have all the header
487        information loaded and cached; we just initialize the machine
488        with it and continue on our merry way.
489
490        In the non-seekable (streaming) case, we'll only be at a
491        boundary if we just left the previous logical bitstream and
492        we're now nominally at the header of the next bitstream
493     */
494
495     if(!vf->decode_ready){
496       int link;
497       if(vf->seekable){
498         vf->current_serialno=ogg_page_serialno(&og);
499         
500         /* match the serialno to bitstream section.  We use this rather than
501            offset positions to avoid problems near logical bitstream
502            boundaries */
503         for(link=0;link<vf->links;link++)
504           if(vf->serialnos[link]==vf->current_serialno)break;
505         if(link==vf->links)return(-1); /* sign of a bogus stream.  error out,
506                                           leave machine uninitialized */
507         
508         vf->current_link=link;
509
510         ogg_stream_init(&vf->os,vf->current_serialno);
511         ogg_stream_reset(&vf->os); 
512
513       }else{
514         /* we're streaming */
515         /* fetch the three header packets, build the info struct */
516         
517         _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
518         vf->current_link++;
519         link=0;
520       }
521       
522       _make_decode_ready(vf);
523     }
524     ogg_stream_pagein(&vf->os,&og);
525   }
526 }
527
528 /**********************************************************************
529  * The helpers are over; it's all toplevel interface from here on out */
530  
531 /* clear out the OggVorbis_File struct */
532 int ov_clear(OggVorbis_File *vf){
533   if(vf){
534     vorbis_block_clear(&vf->vb);
535     vorbis_dsp_clear(&vf->vd);
536     ogg_stream_clear(&vf->os);
537     
538     if(vf->vi && vf->links){
539       int i;
540       for(i=0;i<vf->links;i++){
541         vorbis_info_clear(vf->vi+i);
542         vorbis_comment_clear(vf->vc+i);
543       }
544       free(vf->vi);
545       free(vf->vc);
546     }
547     if(vf->dataoffsets)free(vf->dataoffsets);
548     if(vf->pcmlengths)free(vf->pcmlengths);
549     if(vf->serialnos)free(vf->serialnos);
550     if(vf->offsets)free(vf->offsets);
551     ogg_sync_clear(&vf->oy);
552     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
553     memset(vf,0,sizeof(OggVorbis_File));
554   }
555 #ifdef DEBUG_LEAKS
556   _VDBG_dump();
557 #endif
558   return(0);
559 }
560
561 static int _fseek64_wrap(FILE *f,int64_t off,int whence){
562   return fseek(f,(int)off,whence);
563 }
564
565 /* inspects the OggVorbis file and finds/documents all the logical
566    bitstreams contained in it.  Tries to be tolerant of logical
567    bitstream sections that are truncated/woogie. 
568
569    return: -1) error
570             0) OK
571 */
572
573 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
574   ov_callbacks callbacks = {
575     (size_t (*)(void *, size_t, size_t, void *))  fread,
576     (int (*)(void *, int64_t, int))              _fseek64_wrap,
577     (int (*)(void *))                             fclose,
578     (long (*)(void *))                            ftell
579   };
580
581   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
582 }
583   
584
585 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
586     ov_callbacks callbacks)
587 {
588   long offset=callbacks.seek_func(f,0,SEEK_CUR);
589   int ret;
590
591   memset(vf,0,sizeof(OggVorbis_File));
592   vf->datasource=f;
593   vf->callbacks = callbacks;
594
595   /* init the framing state */
596   ogg_sync_init(&vf->oy);
597
598   /* perhaps some data was previously read into a buffer for testing
599      against other stream types.  Allow initialization from this
600      previously read data (as we may be reading from a non-seekable
601      stream) */
602   if(initial){
603     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
604     memcpy(buffer,initial,ibytes);
605     ogg_sync_wrote(&vf->oy,ibytes);
606   }
607
608   /* can we seek? Stevens suggests the seek test was portable */
609   if(offset!=-1){
610     ret=_open_seekable(vf);
611   }else{
612     ret=_open_nonseekable(vf);
613   }
614   if(ret){
615     vf->datasource=NULL;
616     ov_clear(vf);
617   }
618   return(ret);
619 }
620
621 /* How many logical bitstreams in this physical bitstream? */
622 long ov_streams(OggVorbis_File *vf){
623   return vf->links;
624 }
625
626 /* Is the FILE * associated with vf seekable? */
627 long ov_seekable(OggVorbis_File *vf){
628   return vf->seekable;
629 }
630
631 /* returns the bitrate for a given logical bitstream or the entire
632    physical bitstream.  If the file is open for random access, it will
633    find the *actual* average bitrate.  If the file is streaming, it
634    returns the nominal bitrate (if set) else the average of the
635    upper/lower bounds (if set) else -1 (unset).
636
637    If you want the actual bitrate field settings, get them from the
638    vorbis_info structs */
639
640 long ov_bitrate(OggVorbis_File *vf,int i){
641   if(i>=vf->links)return(-1);
642   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
643   if(i<0){
644     int64_t bits=0;
645     int i;
646     for(i=0;i<vf->links;i++)
647       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
648     return(rint(bits/ov_time_total(vf,-1)));
649   }else{
650     if(vf->seekable){
651       /* return the actual bitrate */
652       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
653     }else{
654       /* return nominal if set */
655       if(vf->vi[i].bitrate_nominal>0){
656         return vf->vi[i].bitrate_nominal;
657       }else{
658         if(vf->vi[i].bitrate_upper>0){
659           if(vf->vi[i].bitrate_lower>0){
660             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
661           }else{
662             return vf->vi[i].bitrate_upper;
663           }
664         }
665         return(-1);
666       }
667     }
668   }
669 }
670
671 /* returns the actual bitrate since last call.  returns -1 if no
672    additional data to offer since last call (or at beginning of stream) */
673 long ov_bitrate_instant(OggVorbis_File *vf){
674   int link=(vf->seekable?vf->current_link:0);
675   long ret;
676   if(vf->samptrack==0)return(-1);
677   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
678   vf->bittrack=0.;
679   vf->samptrack=0.;
680   return(ret);
681 }
682
683 /* Guess */
684 long ov_serialnumber(OggVorbis_File *vf,int i){
685   if(i>=vf->links)return(-1);
686   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
687   if(i<0){
688     return(vf->current_serialno);
689   }else{
690     return(vf->serialnos[i]);
691   }
692 }
693
694 /* returns: total raw (compressed) length of content if i==-1
695             raw (compressed) length of that logical bitstream for i==0 to n
696             -1 if the stream is not seekable (we can't know the length)
697 */
698 int64_t ov_raw_total(OggVorbis_File *vf,int i){
699   if(!vf->seekable || i>=vf->links)return(-1);
700   if(i<0){
701     long acc=0;
702     int i;
703     for(i=0;i<vf->links;i++)
704       acc+=ov_raw_total(vf,i);
705     return(acc);
706   }else{
707     return(vf->offsets[i+1]-vf->offsets[i]);
708   }
709 }
710
711 /* returns: total PCM length (samples) of content if i==-1
712             PCM length (samples) of that logical bitstream for i==0 to n
713             -1 if the stream is not seekable (we can't know the length)
714 */
715 int64_t ov_pcm_total(OggVorbis_File *vf,int i){
716   if(!vf->seekable || i>=vf->links)return(-1);
717   if(i<0){
718     int64_t acc=0;
719     int i;
720     for(i=0;i<vf->links;i++)
721       acc+=ov_pcm_total(vf,i);
722     return(acc);
723   }else{
724     return(vf->pcmlengths[i]);
725   }
726 }
727
728 /* returns: total seconds of content if i==-1
729             seconds in that logical bitstream for i==0 to n
730             -1 if the stream is not seekable (we can't know the length)
731 */
732 double ov_time_total(OggVorbis_File *vf,int i){
733   if(!vf->seekable || i>=vf->links)return(-1);
734   if(i<0){
735     double acc=0;
736     int i;
737     for(i=0;i<vf->links;i++)
738       acc+=ov_time_total(vf,i);
739     return(acc);
740   }else{
741     return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
742   }
743 }
744
745 /* seek to an offset relative to the *compressed* data. This also
746    immediately sucks in and decodes pages to update the PCM cursor. It
747    will cross a logical bitstream boundary, but only if it can't get
748    any packets out of the tail of the bitstream we seek to (so no
749    surprises). 
750
751    returns zero on success, nonzero on failure */
752
753 int ov_raw_seek(OggVorbis_File *vf,long pos){
754
755   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
756   if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
757
758   /* clear out decoding machine state */
759   vf->pcm_offset=-1;
760   _decode_clear(vf);
761
762   /* seek */
763   _seek_helper(vf,pos);
764
765   /* we need to make sure the pcm_offset is set.  We use the
766      _fetch_packet helper to process one packet with readp set, then
767      call it until it returns '0' with readp not set (the last packet
768      from a page has the 'frameno' field set, and that's how the
769      helper updates the offset */
770
771   switch(_process_packet(vf,1)){
772   case 0:
773     /* oh, eof. There are no packets remaining.  Set the pcm offset to
774        the end of file */
775     vf->pcm_offset=ov_pcm_total(vf,-1);
776     return(0);
777   case -1:
778     /* error! missing data or invalid bitstream structure */
779     goto seek_error;
780   default:
781     /* all OK */
782     break;
783   }
784
785   while(1){
786     switch(_process_packet(vf,0)){
787     case 0:
788       /* the offset is set.  If it's a bogus bitstream with no offset
789          information, it's not but that's not our fault.  We still run
790          gracefully, we're just missing the offset */
791       return(0);
792     case -1:
793       /* error! missing data or invalid bitstream structure */
794       goto seek_error;
795     default:
796       /* continue processing packets */
797       break;
798     }
799   }
800   
801  seek_error:
802   /* dump the machine so we're in a known state */
803   vf->pcm_offset=-1;
804   _decode_clear(vf);
805   return -1;
806 }
807
808 /* seek to a sample offset relative to the decompressed pcm stream 
809
810    returns zero on success, nonzero on failure */
811
812 int ov_pcm_seek(OggVorbis_File *vf,int64_t pos){
813   int link=-1;
814   int64_t total=ov_pcm_total(vf,-1);
815
816   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
817   if(pos<0 || pos>total)goto seek_error;
818
819   /* which bitstream section does this pcm offset occur in? */
820   for(link=vf->links-1;link>=0;link--){
821     total-=vf->pcmlengths[link];
822     if(pos>=total)break;
823   }
824
825   /* search within the logical bitstream for the page with the highest
826      pcm_pos preceeding (or equal to) pos.  There is a danger here;
827      missing pages or incorrect frame number information in the
828      bitstream could make our task impossible.  Account for that (it
829      would be an error condition) */
830   {
831     int64_t target=pos-total;
832     long end=vf->offsets[link+1];
833     long begin=vf->offsets[link];
834     long best=begin;
835
836     ogg_page og;
837     while(begin<end){
838       long bisect;
839       long ret;
840     
841       if(end-begin<CHUNKSIZE){
842         bisect=begin;
843       }else{
844         bisect=(end+begin)/2;
845       }
846     
847       _seek_helper(vf,bisect);
848       ret=_get_next_page(vf,&og,end-bisect);
849       
850       if(ret==-1){
851         end=bisect;
852       }else{
853         int64_t frameno=ogg_page_frameno(&og);
854         if(frameno<target){
855           best=ret;  /* raw offset of packet with frameno */ 
856           begin=vf->offset; /* raw offset of next packet */
857         }else{
858           end=bisect;
859         }
860       }
861     }
862
863     /* found our page. seek to it (call raw_seek). */
864     
865     if(ov_raw_seek(vf,best))goto seek_error;
866   }
867
868   /* verify result */
869   if(vf->pcm_offset>=pos)goto seek_error;
870   if(pos>ov_pcm_total(vf,-1))goto seek_error;
871
872   /* discard samples until we reach the desired position. Crossing a
873      logical bitstream boundary with abandon is OK. */
874   while(vf->pcm_offset<pos){
875     double **pcm;
876     long target=pos-vf->pcm_offset;
877     long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
878
879     if(samples>target)samples=target;
880     vorbis_synthesis_read(&vf->vd,samples);
881     vf->pcm_offset+=samples;
882     
883     if(samples<target)
884       if(_process_packet(vf,1)==0)
885         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
886   }
887   return 0;
888   
889  seek_error:
890   /* dump machine so we're in a known state */
891   vf->pcm_offset=-1;
892   _decode_clear(vf);
893   return -1;
894 }
895
896 /* seek to a playback time relative to the decompressed pcm stream 
897    returns zero on success, nonzero on failure */
898 int ov_time_seek(OggVorbis_File *vf,double seconds){
899   /* translate time to PCM position and call ov_pcm_seek */
900
901   int link=-1;
902   int64_t pcm_total=ov_pcm_total(vf,-1);
903   double time_total=ov_time_total(vf,-1);
904
905   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
906   if(seconds<0 || seconds>time_total)goto seek_error;
907   
908   /* which bitstream section does this time offset occur in? */
909   for(link=vf->links-1;link>=0;link--){
910     pcm_total-=vf->pcmlengths[link];
911     time_total-=ov_time_total(vf,link);
912     if(seconds>=time_total)break;
913   }
914
915   /* enough information to convert time offset to pcm offset */
916   {
917     int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
918     return(ov_pcm_seek(vf,target));
919   }
920
921  seek_error:
922   /* dump machine so we're in a known state */
923   vf->pcm_offset=-1;
924   _decode_clear(vf);
925   return -1;
926 }
927
928 /* tell the current stream offset cursor.  Note that seek followed by
929    tell will likely not give the set offset due to caching */
930 int64_t ov_raw_tell(OggVorbis_File *vf){
931   return(vf->offset);
932 }
933
934 /* return PCM offset (sample) of next PCM sample to be read */
935 int64_t ov_pcm_tell(OggVorbis_File *vf){
936   return(vf->pcm_offset);
937 }
938
939 /* return time offset (seconds) of next PCM sample to be read */
940 double ov_time_tell(OggVorbis_File *vf){
941   /* translate time to PCM position and call ov_pcm_seek */
942
943   int link=-1;
944   int64_t pcm_total=0;
945   double time_total=0.;
946   
947   if(vf->seekable){
948     pcm_total=ov_pcm_total(vf,-1);
949     time_total=ov_time_total(vf,-1);
950   
951     /* which bitstream section does this time offset occur in? */
952     for(link=vf->links-1;link>=0;link--){
953       pcm_total-=vf->pcmlengths[link];
954       time_total-=ov_time_total(vf,link);
955       if(vf->pcm_offset>=pcm_total)break;
956     }
957   }
958
959   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
960 }
961
962 /*  link:   -1) return the vorbis_info struct for the bitstream section
963                 currently being decoded
964            0-n) to request information for a specific bitstream section
965     
966     In the case of a non-seekable bitstream, any call returns the
967     current bitstream.  NULL in the case that the machine is not
968     initialized */
969
970 vorbis_info *ov_info(OggVorbis_File *vf,int link){
971   if(vf->seekable){
972     if(link<0)
973       if(vf->decode_ready)
974         return vf->vi+vf->current_link;
975       else
976         return NULL;
977     else
978       if(link>=vf->links)
979         return NULL;
980       else
981         return vf->vi+link;
982   }else{
983     if(vf->decode_ready)
984       return vf->vi;
985     else
986       return NULL;
987   }
988 }
989
990 /* grr, strong typing, grr, no templates/inheritence, grr */
991 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
992   if(vf->seekable){
993     if(link<0)
994       if(vf->decode_ready)
995         return vf->vc+vf->current_link;
996       else
997         return NULL;
998     else
999       if(link>=vf->links)
1000         return NULL;
1001       else
1002         return vf->vc+link;
1003   }else{
1004     if(vf->decode_ready)
1005       return vf->vc;
1006     else
1007       return NULL;
1008   }
1009 }
1010
1011 int host_is_big_endian() {
1012   short pattern = 0xbabe;
1013   unsigned char *bytewise = (unsigned char *)&pattern;
1014   if (bytewise[0] == 0xba) return 1;
1015
1016   assert(bytewise[0] == 0xbe);
1017   return 0;
1018 }
1019
1020 /* up to this point, everything could more or less hide the multiple
1021    logical bitstream nature of chaining from the toplevel application
1022    if the toplevel application didn't particularly care.  However, at
1023    the point that we actually read audio back, the multiple-section
1024    nature must surface: Multiple bitstream sections do not necessarily
1025    have to have the same number of channels or sampling rate.
1026
1027    ov_read returns the sequential logical bitstream number currently
1028    being decoded along with the PCM data in order that the toplevel
1029    application can take action on channel/sample rate changes.  This
1030    number will be incremented even for streamed (non-seekable) streams
1031    (for seekable streams, it represents the actual logical bitstream
1032    index within the physical bitstream.  Note that the accessor
1033    functions above are aware of this dichotomy).
1034
1035    input values: buffer) a buffer to hold packed PCM data for return
1036                  length) the byte length requested to be placed into buffer
1037                  bigendianp) should the data be packed LSB first (0) or
1038                              MSB first (1)
1039                  word) word size for output.  currently 1 (byte) or 
1040                        2 (16 bit short)
1041
1042    return values: -1) error/hole in data
1043                    0) EOF
1044                    n) number of bytes of PCM actually returned.  The
1045                    below works on a packet-by-packet basis, so the
1046                    return length is not related to the 'length' passed
1047                    in, just guaranteed to fit.
1048
1049             *section) set to the logical bitstream number */
1050
1051 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1052                     int bigendianp,int word,int sgned,int *bitstream){
1053   int i,j;
1054   int host_endian = host_is_big_endian();
1055
1056   while(1){
1057     if(vf->decode_ready){
1058       double **pcm;
1059       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1060       if(samples){
1061         /* yay! proceed to pack data into the byte buffer */
1062
1063         long channels=ov_info(vf,-1)->channels;
1064         long bytespersample=word * channels;
1065         if(samples>length/bytespersample)samples=length/bytespersample;
1066         
1067         /* a tight loop to pack each size */
1068         {
1069           int val;
1070           if(word==1){
1071             int off=(sgned?0:128);
1072             for(j=0;j<samples;j++)
1073               for(i=0;i<channels;i++){
1074                 val=(int)(pcm[i][j]*128. + 0.5);
1075                 if(val>127)val=127;
1076                 else if(val<-128)val=-128;
1077                 *buffer++=val+off;
1078               }
1079           }else{
1080             int off=(sgned?0:32768);
1081
1082             if(host_endian==bigendianp){
1083               if(sgned){
1084                 for(i=0;i<channels;i++) { /* It's faster in this order */
1085                   double *src=pcm[i];
1086                   short *dest=((short *)buffer)+i;
1087                   for(j=0;j<samples;j++) {
1088                     val=(int)(src[j]*32768. + 0.5);
1089                     if(val>32767)val=32767;
1090                     else if(val<-32768)val=-32768;
1091                     *dest=val;
1092                     dest+=channels;
1093                   }
1094                 }
1095               }else{
1096                 for(i=0;i<channels;i++) {
1097                   double *src=pcm[i];
1098                   short *dest=((short *)buffer)+i;
1099                   for(j=0;j<samples;j++) {
1100                     val=(int)(src[j]*32768. + 0.5);
1101                     if(val>32767)val=32767;
1102                     else if(val<-32768)val=-32768;
1103                     *dest=val+off;
1104                     dest+=channels;
1105                   }
1106                 }
1107               }
1108             }else if(bigendianp){
1109               for(j=0;j<samples;j++)
1110                 for(i=0;i<channels;i++){
1111                   val=(int)(pcm[i][j]*32768. + 0.5);
1112                   if(val>32767)val=32767;
1113                   else if(val<-32768)val=-32768;
1114                   val+=off;
1115                   *buffer++=(val>>8);
1116                   *buffer++=(val&0xff);
1117                 }
1118             }else{
1119               int val;
1120               for(j=0;j<samples;j++)
1121                 for(i=0;i<channels;i++){
1122                   val=(int)(pcm[i][j]*32768. + 0.5);
1123                   if(val>32767)val=32767;
1124                   else if(val<-32768)val=-32768;
1125                   val+=off;
1126                   *buffer++=(val&0xff);
1127                   *buffer++=(val>>8);
1128                 }
1129
1130             }
1131           }
1132         }
1133         
1134         vorbis_synthesis_read(&vf->vd,samples);
1135         vf->pcm_offset+=samples;
1136         if(bitstream)*bitstream=vf->current_link;
1137         return(samples*bytespersample);
1138       }
1139     }
1140
1141     /* suck in another packet */
1142     switch(_process_packet(vf,1)){
1143     case 0:
1144       return(0);
1145     case -1:
1146       return -1;
1147     default:
1148       break;
1149     }
1150   }
1151 }
1152
1153
1154
1155