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