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