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