091ea2adf0d61c68606477dc742d69c0a82181d3
[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.28 2000/08/30 06:09:21 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(ogg_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(ogg_int64_t));
269   vf->pcmlengths=malloc(vf->links*sizeof(ogg_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   return(ov_raw_seek(vf,0));
366
367 }
368
369 static int _open_nonseekable(OggVorbis_File *vf){
370   /* we cannot seek. Set up a 'single' (current) logical bitstream entry  */
371   vf->links=1;
372   vf->vi=calloc(vf->links,sizeof(vorbis_info));
373   vf->vc=calloc(vf->links,sizeof(vorbis_info));
374
375   /* Try to fetch the headers, maintaining all the storage */
376   if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno)==-1)return(-1);
377   _make_decode_ready(vf);
378
379   return 0;
380 }
381
382 /* clear out the current logical bitstream decoder */ 
383 static void _decode_clear(OggVorbis_File *vf){
384   ogg_stream_clear(&vf->os);
385   vorbis_dsp_clear(&vf->vd);
386   vorbis_block_clear(&vf->vb);
387   vf->decode_ready=0;
388
389   vf->bittrack=0.;
390   vf->samptrack=0.;
391 }
392
393 /* fetch and process a packet.  Handles the case where we're at a
394    bitstream boundary and dumps the decoding machine.  If the decoding
395    machine is unloaded, it loads it.  It also keeps pcm_offset up to
396    date (seek and read both use this.  seek uses a special hack with
397    readp). 
398
399    return: -1) hole in the data (lost packet) 
400             0) need more date (only if readp==0)/eof
401             1) got a packet 
402 */
403
404 static int _process_packet(OggVorbis_File *vf,int readp){
405   ogg_page og;
406
407   /* handle one packet.  Try to fetch it from current stream state */
408   /* extract packets from page */
409   while(1){
410     
411     /* process a packet if we can.  If the machine isn't loaded,
412        neither is a page */
413     if(vf->decode_ready){
414       ogg_packet op;
415       int result=ogg_stream_packetout(&vf->os,&op);
416       ogg_int64_t frameno;
417       
418       /* if(result==-1)return(-1); hole in the data. For now, swallow
419                                    and go. We'll need to add a real
420                                    error code in a bit. */
421       if(result>0){
422         /* got a packet.  process it */
423         frameno=op.frameno;
424         if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
425                                                header handling.  The
426                                                header packets aren't
427                                                audio, so if/when we
428                                                submit them,
429                                                vorbis_synthesis will
430                                                reject them */
431
432           /* suck in the synthesis data and track bitrate */
433           {
434             int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
435             vorbis_synthesis_blockin(&vf->vd,&vf->vb);
436             vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
437             vf->bittrack+=op.bytes*8;
438           }
439           
440           /* update the pcm offset. */
441           if(frameno!=-1 && !op.e_o_s){
442             int link=(vf->seekable?vf->current_link:0);
443             int i,samples;
444             
445             /* this packet has a pcm_offset on it (the last packet
446                completed on a page carries the offset) After processing
447                (above), we know the pcm position of the *last* sample
448                ready to be returned. Find the offset of the *first*
449
450                As an aside, this trick is inaccurate if we begin
451                reading anew right at the last page; the end-of-stream
452                frameno declares the last frame in the stream, and the
453                last packet of the last page may be a partial frame.
454                So, we need a previous frameno from an in-sequence page
455                to have a reference point.  Thus the !op.e_o_s clause
456                above */
457             
458             samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
459             
460             frameno-=samples;
461             for(i=0;i<link;i++)
462               frameno+=vf->pcmlengths[i];
463             vf->pcm_offset=frameno;
464           }
465           return(1);
466         }
467       }
468     }
469
470     if(!readp)return(0);
471     if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
472
473     /* bitrate tracking; add the header's bytes here, the body bytes
474        are done by packet above */
475     vf->bittrack+=og.header_len*8;
476
477     /* has our decoding just traversed a bitstream boundary? */
478     if(vf->decode_ready){
479       if(vf->current_serialno!=ogg_page_serialno(&og)){
480         _decode_clear(vf);
481       }
482     }
483
484     /* Do we need to load a new machine before submitting the page? */
485     /* This is different in the seekable and non-seekable cases.  
486
487        In the seekable case, we already have all the header
488        information loaded and cached; we just initialize the machine
489        with it and continue on our merry way.
490
491        In the non-seekable (streaming) case, we'll only be at a
492        boundary if we just left the previous logical bitstream and
493        we're now nominally at the header of the next bitstream
494     */
495
496     if(!vf->decode_ready){
497       int link;
498       if(vf->seekable){
499         vf->current_serialno=ogg_page_serialno(&og);
500         
501         /* match the serialno to bitstream section.  We use this rather than
502            offset positions to avoid problems near logical bitstream
503            boundaries */
504         for(link=0;link<vf->links;link++)
505           if(vf->serialnos[link]==vf->current_serialno)break;
506         if(link==vf->links)return(-1); /* sign of a bogus stream.  error out,
507                                           leave machine uninitialized */
508         
509         vf->current_link=link;
510
511         ogg_stream_init(&vf->os,vf->current_serialno);
512         ogg_stream_reset(&vf->os); 
513
514       }else{
515         /* we're streaming */
516         /* fetch the three header packets, build the info struct */
517         
518         _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
519         vf->current_link++;
520         link=0;
521       }
522       
523       _make_decode_ready(vf);
524     }
525     ogg_stream_pagein(&vf->os,&og);
526   }
527 }
528
529 /**********************************************************************
530  * The helpers are over; it's all toplevel interface from here on out */
531  
532 /* clear out the OggVorbis_File struct */
533 int ov_clear(OggVorbis_File *vf){
534   if(vf){
535     vorbis_block_clear(&vf->vb);
536     vorbis_dsp_clear(&vf->vd);
537     ogg_stream_clear(&vf->os);
538     
539     if(vf->vi && vf->links){
540       int i;
541       for(i=0;i<vf->links;i++){
542         vorbis_info_clear(vf->vi+i);
543         vorbis_comment_clear(vf->vc+i);
544       }
545       free(vf->vi);
546       free(vf->vc);
547     }
548     if(vf->dataoffsets)free(vf->dataoffsets);
549     if(vf->pcmlengths)free(vf->pcmlengths);
550     if(vf->serialnos)free(vf->serialnos);
551     if(vf->offsets)free(vf->offsets);
552     ogg_sync_clear(&vf->oy);
553     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
554     memset(vf,0,sizeof(OggVorbis_File));
555   }
556 #ifdef DEBUG_LEAKS
557   _VDBG_dump();
558 #endif
559   return(0);
560 }
561
562 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
563   return fseek(f,(int)off,whence);
564 }
565
566 /* inspects the OggVorbis file and finds/documents all the logical
567    bitstreams contained in it.  Tries to be tolerant of logical
568    bitstream sections that are truncated/woogie. 
569
570    return: -1) error
571             0) OK
572 */
573
574 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
575   ov_callbacks callbacks = {
576     (size_t (*)(void *, size_t, size_t, void *))  fread,
577     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
578     (int (*)(void *))                             fclose,
579     (long (*)(void *))                            ftell
580   };
581
582   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
583 }
584   
585
586 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
587     ov_callbacks callbacks)
588 {
589   long offset=callbacks.seek_func(f,0,SEEK_CUR);
590   int ret;
591
592   memset(vf,0,sizeof(OggVorbis_File));
593   vf->datasource=f;
594   vf->callbacks = callbacks;
595
596   /* init the framing state */
597   ogg_sync_init(&vf->oy);
598
599   /* perhaps some data was previously read into a buffer for testing
600      against other stream types.  Allow initialization from this
601      previously read data (as we may be reading from a non-seekable
602      stream) */
603   if(initial){
604     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
605     memcpy(buffer,initial,ibytes);
606     ogg_sync_wrote(&vf->oy,ibytes);
607   }
608
609   /* can we seek? Stevens suggests the seek test was portable */
610   if(offset!=-1){
611     ret=_open_seekable(vf);
612   }else{
613     ret=_open_nonseekable(vf);
614   }
615   if(ret){
616     vf->datasource=NULL;
617     ov_clear(vf);
618   }
619   return(ret);
620 }
621
622 /* How many logical bitstreams in this physical bitstream? */
623 long ov_streams(OggVorbis_File *vf){
624   return vf->links;
625 }
626
627 /* Is the FILE * associated with vf seekable? */
628 long ov_seekable(OggVorbis_File *vf){
629   return vf->seekable;
630 }
631
632 /* returns the bitrate for a given logical bitstream or the entire
633    physical bitstream.  If the file is open for random access, it will
634    find the *actual* average bitrate.  If the file is streaming, it
635    returns the nominal bitrate (if set) else the average of the
636    upper/lower bounds (if set) else -1 (unset).
637
638    If you want the actual bitrate field settings, get them from the
639    vorbis_info structs */
640
641 long ov_bitrate(OggVorbis_File *vf,int i){
642   if(i>=vf->links)return(-1);
643   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
644   if(i<0){
645     ogg_int64_t bits=0;
646     int i;
647     for(i=0;i<vf->links;i++)
648       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
649     return(rint(bits/ov_time_total(vf,-1)));
650   }else{
651     if(vf->seekable){
652       /* return the actual bitrate */
653       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
654     }else{
655       /* return nominal if set */
656       if(vf->vi[i].bitrate_nominal>0){
657         return vf->vi[i].bitrate_nominal;
658       }else{
659         if(vf->vi[i].bitrate_upper>0){
660           if(vf->vi[i].bitrate_lower>0){
661             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
662           }else{
663             return vf->vi[i].bitrate_upper;
664           }
665         }
666         return(-1);
667       }
668     }
669   }
670 }
671
672 /* returns the actual bitrate since last call.  returns -1 if no
673    additional data to offer since last call (or at beginning of stream) */
674 long ov_bitrate_instant(OggVorbis_File *vf){
675   int link=(vf->seekable?vf->current_link:0);
676   long ret;
677   if(vf->samptrack==0)return(-1);
678   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
679   vf->bittrack=0.;
680   vf->samptrack=0.;
681   return(ret);
682 }
683
684 /* Guess */
685 long ov_serialnumber(OggVorbis_File *vf,int i){
686   if(i>=vf->links)return(-1);
687   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
688   if(i<0){
689     return(vf->current_serialno);
690   }else{
691     return(vf->serialnos[i]);
692   }
693 }
694
695 /* returns: total raw (compressed) length of content if i==-1
696             raw (compressed) length of that logical bitstream for i==0 to n
697             -1 if the stream is not seekable (we can't know the length)
698 */
699 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
700   if(!vf->seekable || i>=vf->links)return(-1);
701   if(i<0){
702     long acc=0;
703     int i;
704     for(i=0;i<vf->links;i++)
705       acc+=ov_raw_total(vf,i);
706     return(acc);
707   }else{
708     return(vf->offsets[i+1]-vf->offsets[i]);
709   }
710 }
711
712 /* returns: total PCM length (samples) of content if i==-1
713             PCM length (samples) of that logical bitstream for i==0 to n
714             -1 if the stream is not seekable (we can't know the length)
715 */
716 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
717   if(!vf->seekable || i>=vf->links)return(-1);
718   if(i<0){
719     ogg_int64_t acc=0;
720     int i;
721     for(i=0;i<vf->links;i++)
722       acc+=ov_pcm_total(vf,i);
723     return(acc);
724   }else{
725     return(vf->pcmlengths[i]);
726   }
727 }
728
729 /* returns: total seconds of content if i==-1
730             seconds in that logical bitstream for i==0 to n
731             -1 if the stream is not seekable (we can't know the length)
732 */
733 double ov_time_total(OggVorbis_File *vf,int i){
734   if(!vf->seekable || i>=vf->links)return(-1);
735   if(i<0){
736     double acc=0;
737     int i;
738     for(i=0;i<vf->links;i++)
739       acc+=ov_time_total(vf,i);
740     return(acc);
741   }else{
742     return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
743   }
744 }
745
746 /* seek to an offset relative to the *compressed* data. This also
747    immediately sucks in and decodes pages to update the PCM cursor. It
748    will cross a logical bitstream boundary, but only if it can't get
749    any packets out of the tail of the bitstream we seek to (so no
750    surprises). 
751
752    returns zero on success, nonzero on failure */
753
754 int ov_raw_seek(OggVorbis_File *vf,long pos){
755
756   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
757   if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
758
759   /* clear out decoding machine state */
760   vf->pcm_offset=-1;
761   _decode_clear(vf);
762
763   /* seek */
764   _seek_helper(vf,pos);
765
766   /* we need to make sure the pcm_offset is set.  We use the
767      _fetch_packet helper to process one packet with readp set, then
768      call it until it returns '0' with readp not set (the last packet
769      from a page has the 'frameno' field set, and that's how the
770      helper updates the offset */
771
772   switch(_process_packet(vf,1)){
773   case 0:
774     /* oh, eof. There are no packets remaining.  Set the pcm offset to
775        the end of file */
776     vf->pcm_offset=ov_pcm_total(vf,-1);
777     return(0);
778   case -1:
779     /* error! missing data or invalid bitstream structure */
780     goto seek_error;
781   default:
782     /* all OK */
783     break;
784   }
785
786   while(1){
787     switch(_process_packet(vf,0)){
788     case 0:
789       /* the offset is set.  If it's a bogus bitstream with no offset
790          information, it's not but that's not our fault.  We still run
791          gracefully, we're just missing the offset */
792       return(0);
793     case -1:
794       /* error! missing data or invalid bitstream structure */
795       goto seek_error;
796     default:
797       /* continue processing packets */
798       break;
799     }
800   }
801   
802  seek_error:
803   /* dump the machine so we're in a known state */
804   vf->pcm_offset=-1;
805   _decode_clear(vf);
806   return -1;
807 }
808
809 /* seek to a sample offset relative to the decompressed pcm stream 
810
811    returns zero on success, nonzero on failure */
812
813 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
814   int link=-1;
815   ogg_int64_t total=ov_pcm_total(vf,-1);
816
817   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
818   if(pos<0 || pos>total)goto seek_error;
819
820   /* which bitstream section does this pcm offset occur in? */
821   for(link=vf->links-1;link>=0;link--){
822     total-=vf->pcmlengths[link];
823     if(pos>=total)break;
824   }
825
826   /* search within the logical bitstream for the page with the highest
827      pcm_pos preceeding (or equal to) pos.  There is a danger here;
828      missing pages or incorrect frame number information in the
829      bitstream could make our task impossible.  Account for that (it
830      would be an error condition) */
831   {
832     ogg_int64_t target=pos-total;
833     long end=vf->offsets[link+1];
834     long begin=vf->offsets[link];
835     long best=begin;
836
837     ogg_page og;
838     while(begin<end){
839       long bisect;
840       long ret;
841     
842       if(end-begin<CHUNKSIZE){
843         bisect=begin;
844       }else{
845         bisect=(end+begin)/2;
846       }
847     
848       _seek_helper(vf,bisect);
849       ret=_get_next_page(vf,&og,end-bisect);
850       
851       if(ret==-1){
852         end=bisect;
853       }else{
854         ogg_int64_t frameno=ogg_page_frameno(&og);
855         if(frameno<target){
856           best=ret;  /* raw offset of packet with frameno */ 
857           begin=vf->offset; /* raw offset of next packet */
858         }else{
859           end=bisect;
860         }
861       }
862     }
863
864     /* found our page. seek to it (call raw_seek). */
865     
866     if(ov_raw_seek(vf,best))goto seek_error;
867   }
868
869   /* verify result */
870   if(vf->pcm_offset>=pos)goto seek_error;
871   if(pos>ov_pcm_total(vf,-1))goto seek_error;
872
873   /* discard samples until we reach the desired position. Crossing a
874      logical bitstream boundary with abandon is OK. */
875   while(vf->pcm_offset<pos){
876     double **pcm;
877     long target=pos-vf->pcm_offset;
878     long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
879
880     if(samples>target)samples=target;
881     vorbis_synthesis_read(&vf->vd,samples);
882     vf->pcm_offset+=samples;
883     
884     if(samples<target)
885       if(_process_packet(vf,1)==0)
886         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
887   }
888   return 0;
889   
890  seek_error:
891   /* dump machine so we're in a known state */
892   vf->pcm_offset=-1;
893   _decode_clear(vf);
894   return -1;
895 }
896
897 /* seek to a playback time relative to the decompressed pcm stream 
898    returns zero on success, nonzero on failure */
899 int ov_time_seek(OggVorbis_File *vf,double seconds){
900   /* translate time to PCM position and call ov_pcm_seek */
901
902   int link=-1;
903   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
904   double time_total=ov_time_total(vf,-1);
905
906   if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */  
907   if(seconds<0 || seconds>time_total)goto seek_error;
908   
909   /* which bitstream section does this time offset occur in? */
910   for(link=vf->links-1;link>=0;link--){
911     pcm_total-=vf->pcmlengths[link];
912     time_total-=ov_time_total(vf,link);
913     if(seconds>=time_total)break;
914   }
915
916   /* enough information to convert time offset to pcm offset */
917   {
918     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
919     return(ov_pcm_seek(vf,target));
920   }
921
922  seek_error:
923   /* dump machine so we're in a known state */
924   vf->pcm_offset=-1;
925   _decode_clear(vf);
926   return -1;
927 }
928
929 /* tell the current stream offset cursor.  Note that seek followed by
930    tell will likely not give the set offset due to caching */
931 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
932   return(vf->offset);
933 }
934
935 /* return PCM offset (sample) of next PCM sample to be read */
936 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
937   return(vf->pcm_offset);
938 }
939
940 /* return time offset (seconds) of next PCM sample to be read */
941 double ov_time_tell(OggVorbis_File *vf){
942   /* translate time to PCM position and call ov_pcm_seek */
943
944   int link=-1;
945   ogg_int64_t pcm_total=0;
946   double time_total=0.;
947   
948   if(vf->seekable){
949     pcm_total=ov_pcm_total(vf,-1);
950     time_total=ov_time_total(vf,-1);
951   
952     /* which bitstream section does this time offset occur in? */
953     for(link=vf->links-1;link>=0;link--){
954       pcm_total-=vf->pcmlengths[link];
955       time_total-=ov_time_total(vf,link);
956       if(vf->pcm_offset>=pcm_total)break;
957     }
958   }
959
960   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
961 }
962
963 /*  link:   -1) return the vorbis_info struct for the bitstream section
964                 currently being decoded
965            0-n) to request information for a specific bitstream section
966     
967     In the case of a non-seekable bitstream, any call returns the
968     current bitstream.  NULL in the case that the machine is not
969     initialized */
970
971 vorbis_info *ov_info(OggVorbis_File *vf,int link){
972   if(vf->seekable){
973     if(link<0)
974       if(vf->decode_ready)
975         return vf->vi+vf->current_link;
976       else
977         return NULL;
978     else
979       if(link>=vf->links)
980         return NULL;
981       else
982         return vf->vi+link;
983   }else{
984     if(vf->decode_ready)
985       return vf->vi;
986     else
987       return NULL;
988   }
989 }
990
991 /* grr, strong typing, grr, no templates/inheritence, grr */
992 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
993   if(vf->seekable){
994     if(link<0)
995       if(vf->decode_ready)
996         return vf->vc+vf->current_link;
997       else
998         return NULL;
999     else
1000       if(link>=vf->links)
1001         return NULL;
1002       else
1003         return vf->vc+link;
1004   }else{
1005     if(vf->decode_ready)
1006       return vf->vc;
1007     else
1008       return NULL;
1009   }
1010 }
1011
1012 int host_is_big_endian() {
1013   short pattern = 0xbabe;
1014   unsigned char *bytewise = (unsigned char *)&pattern;
1015   if (bytewise[0] == 0xba) return 1;
1016
1017   assert(bytewise[0] == 0xbe);
1018   return 0;
1019 }
1020
1021 /* up to this point, everything could more or less hide the multiple
1022    logical bitstream nature of chaining from the toplevel application
1023    if the toplevel application didn't particularly care.  However, at
1024    the point that we actually read audio back, the multiple-section
1025    nature must surface: Multiple bitstream sections do not necessarily
1026    have to have the same number of channels or sampling rate.
1027
1028    ov_read returns the sequential logical bitstream number currently
1029    being decoded along with the PCM data in order that the toplevel
1030    application can take action on channel/sample rate changes.  This
1031    number will be incremented even for streamed (non-seekable) streams
1032    (for seekable streams, it represents the actual logical bitstream
1033    index within the physical bitstream.  Note that the accessor
1034    functions above are aware of this dichotomy).
1035
1036    input values: buffer) a buffer to hold packed PCM data for return
1037                  length) the byte length requested to be placed into buffer
1038                  bigendianp) should the data be packed LSB first (0) or
1039                              MSB first (1)
1040                  word) word size for output.  currently 1 (byte) or 
1041                        2 (16 bit short)
1042
1043    return values: -1) error/hole in data
1044                    0) EOF
1045                    n) number of bytes of PCM actually returned.  The
1046                    below works on a packet-by-packet basis, so the
1047                    return length is not related to the 'length' passed
1048                    in, just guaranteed to fit.
1049
1050             *section) set to the logical bitstream number */
1051
1052 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1053                     int bigendianp,int word,int sgned,int *bitstream){
1054   int i,j;
1055   int host_endian = host_is_big_endian();
1056
1057   while(1){
1058     if(vf->decode_ready){
1059       double **pcm;
1060       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1061       if(samples){
1062         /* yay! proceed to pack data into the byte buffer */
1063
1064         long channels=ov_info(vf,-1)->channels;
1065         long bytespersample=word * channels;
1066         if(samples>length/bytespersample)samples=length/bytespersample;
1067         
1068         /* a tight loop to pack each size */
1069         {
1070           int val;
1071           if(word==1){
1072             int off=(sgned?0:128);
1073             for(j=0;j<samples;j++)
1074               for(i=0;i<channels;i++){
1075                 val=(int)(pcm[i][j]*128. + 0.5);
1076                 if(val>127)val=127;
1077                 else if(val<-128)val=-128;
1078                 *buffer++=val+off;
1079               }
1080           }else{
1081             int off=(sgned?0:32768);
1082
1083             if(host_endian==bigendianp){
1084               if(sgned){
1085                 for(i=0;i<channels;i++) { /* It's faster in this order */
1086                   double *src=pcm[i];
1087                   short *dest=((short *)buffer)+i;
1088                   for(j=0;j<samples;j++) {
1089                     val=(int)(src[j]*32768. + 0.5);
1090                     if(val>32767)val=32767;
1091                     else if(val<-32768)val=-32768;
1092                     *dest=val;
1093                     dest+=channels;
1094                   }
1095                 }
1096               }else{
1097                 for(i=0;i<channels;i++) {
1098                   double *src=pcm[i];
1099                   short *dest=((short *)buffer)+i;
1100                   for(j=0;j<samples;j++) {
1101                     val=(int)(src[j]*32768. + 0.5);
1102                     if(val>32767)val=32767;
1103                     else if(val<-32768)val=-32768;
1104                     *dest=val+off;
1105                     dest+=channels;
1106                   }
1107                 }
1108               }
1109             }else if(bigendianp){
1110               for(j=0;j<samples;j++)
1111                 for(i=0;i<channels;i++){
1112                   val=(int)(pcm[i][j]*32768. + 0.5);
1113                   if(val>32767)val=32767;
1114                   else if(val<-32768)val=-32768;
1115                   val+=off;
1116                   *buffer++=(val>>8);
1117                   *buffer++=(val&0xff);
1118                 }
1119             }else{
1120               int val;
1121               for(j=0;j<samples;j++)
1122                 for(i=0;i<channels;i++){
1123                   val=(int)(pcm[i][j]*32768. + 0.5);
1124                   if(val>32767)val=32767;
1125                   else if(val<-32768)val=-32768;
1126                   val+=off;
1127                   *buffer++=(val&0xff);
1128                   *buffer++=(val>>8);
1129                 }
1130
1131             }
1132           }
1133         }
1134         
1135         vorbis_synthesis_read(&vf->vd,samples);
1136         vf->pcm_offset+=samples;
1137         if(bitstream)*bitstream=vf->current_link;
1138         return(samples*bytespersample);
1139       }
1140     }
1141
1142     /* suck in another packet */
1143     switch(_process_packet(vf,1)){
1144     case 0:
1145       return(0);
1146     case -1:
1147       return -1;
1148     default:
1149       break;
1150     }
1151   }
1152 }
1153
1154
1155
1156