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