1 /********************************************************************
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. *
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/ *
12 ********************************************************************
14 function: stdio-based convenience library for opening/seeking/decoding
15 last mod: $Id: vorbisfile.c,v 1.21 2000/04/23 15:34:12 msmith Exp $
17 ********************************************************************/
23 #include "vorbis/codec.h"
24 #include "vorbis/vorbisfile.h"
29 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
30 one logical bitstream arranged end to end (the only form of Ogg
31 multiplexing allowed in a Vorbis bitstream; grouping [parallel
32 multiplexing] is not allowed in Vorbis) */
34 /* A Vorbis file can be played beginning to end (streamed) without
35 worrying ahead of time about chaining (see decoder_example.c). If
36 we have the whole file, however, and want random access
37 (seeking/scrubbing) or desire to know the total length/time of a
38 file, we need to account for the possibility of chaining. */
40 /* We can handle things a number of ways; we can determine the entire
41 bitstream structure right off the bat, or find pieces on demand.
42 This example determines and caches structure for the entire
43 bitstream, but builds a virtual decoder on the fly when moving
44 between links in the chain. */
46 /* There are also different ways to implement seeking. Enough
47 information exists in an Ogg bitstream to seek to
48 sample-granularity positions in the output. Or, one can seek by
49 picking some portion of the stream roughly in the desired area if
50 we only want course navigation through the stream. */
52 /*************************************************************************
53 * Many, many internal helpers. The intention is not to be confusing;
54 * rampant duplication and monolithic function implementation would be
55 * harder to understand anyway. The high level functions are last. Begin
56 * grokking near the end of the file */
58 /* read a little more data from the file/pipe into the ogg_sync framer */
59 #define CHUNKSIZE 4096
60 static long _get_data(OggVorbis_File *vf){
61 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
62 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
63 ogg_sync_wrote(&vf->oy,bytes);
67 /* save a tiny smidge of verbosity to make the code more readable */
68 static void _seek_helper(OggVorbis_File *vf,long offset){
69 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
71 ogg_sync_reset(&vf->oy);
74 /* The read/seek functions track absolute position within the stream */
76 /* from the head of the stream, get the next page. boundary specifies
77 if the function is allowed to fetch more data from the stream (and
78 how much) or only use internally buffered data.
80 boundary: -1) unbounded search
81 0) read no additional data; use cached only
82 n) search for a new page beginning for n bytes
84 return: -1) did not find a page
85 n) found a page at absolute offset n */
87 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
88 if(boundary>0)boundary+=vf->offset;
92 if(boundary>0 && vf->offset>=boundary)return(-1);
93 more=ogg_sync_pageseek(&vf->oy,og);
100 /* send more paramedics */
101 if(!boundary)return(-1);
102 if(_get_data(vf)<=0)return(-1);
104 /* got a page. Return the offset at the page beginning,
105 advance the internal offset past the page end */
115 /* find the latest page beginning before the current stream cursor
116 position. Much dirtier than the above as Ogg doesn't have any
117 backward search linkage. no 'readp' as it will certainly have to
119 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
120 long begin=vf->offset;
126 _seek_helper(vf,begin);
127 while(vf->offset<begin+CHUNKSIZE){
128 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
137 /* we have the offset. Actually snork and hold the page now */
138 _seek_helper(vf,offset);
139 ret=_get_next_page(vf,og,CHUNKSIZE);
141 /* this shouldn't be possible */
142 fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
149 /* finds each bitstream link one at a time using a bisection search
150 (has to begin by knowing the offset of the lb's initial page).
151 Recurses for each link so it can alloc the link storage after
152 finding them all, then unroll and fill the cache at the same time */
153 static void _bisect_forward_serialno(OggVorbis_File *vf,
159 long endsearched=end;
164 /* the below guards against garbage seperating the last and
165 first pages of two links. */
166 while(searched<endsearched){
169 if(endsearched-searched<CHUNKSIZE){
172 bisect=(searched+endsearched)/2;
175 _seek_helper(vf,bisect);
176 ret=_get_next_page(vf,&og,-1);
177 if(ret<0 || ogg_page_serialno(&og)!=currentno){
181 searched=ret+og.header_len+og.body_len;
185 _seek_helper(vf,next);
186 ret=_get_next_page(vf,&og,-1);
188 if(searched>=end || ret==-1){
190 vf->offsets=malloc((m+2)*sizeof(long));
191 vf->offsets[m+1]=searched;
193 _bisect_forward_serialno(vf,next,vf->offset,
194 end,ogg_page_serialno(&og),m+1);
197 vf->offsets[m]=begin;
200 /* uses the local ogg_stream storage in vf; this is important for
201 non-streaming input sources */
202 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
208 ret=_get_next_page(vf,&og,CHUNKSIZE);
210 fprintf(stderr,"Did not find initial header for bitstream.\n");
214 if(serialno)*serialno=ogg_page_serialno(&og);
215 ogg_stream_init(&vf->os,ogg_page_serialno(&og));
217 /* extract the initial header from the first page and verify that the
218 Ogg bitstream is in fact Vorbis data */
220 vorbis_info_init(vi);
221 vorbis_comment_init(vc);
225 ogg_stream_pagein(&vf->os,&og);
227 int result=ogg_stream_packetout(&vf->os,&op);
230 fprintf(stderr,"Corrupt header in logical bitstream.\n");
233 if(vorbis_synthesis_headerin(vi,vc,&op)){
234 fprintf(stderr,"Illegal header in logical bitstream.\n");
240 if(_get_next_page(vf,&og,1)<0){
241 fprintf(stderr,"Missing header in logical bitstream.\n");
248 vorbis_info_clear(vi);
249 vorbis_comment_clear(vc);
250 ogg_stream_clear(&vf->os);
254 /* last step of the OggVorbis_File initialization; get all the
255 vorbis_info structs and PCM positions. Only called by the seekable
256 initialization (local stream storage is hacked slightly; pay
257 attention to how that's done) */
258 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
259 vorbis_comment *first_c,
264 vf->vi=calloc(vf->links,sizeof(vorbis_info));
265 vf->vc=calloc(vf->links,sizeof(vorbis_info));
266 vf->dataoffsets=malloc(vf->links*sizeof(long));
267 vf->pcmlengths=malloc(vf->links*sizeof(int64_t));
268 vf->serialnos=malloc(vf->links*sizeof(long));
270 for(i=0;i<vf->links;i++){
271 if(first_i && first_c && i==0){
272 /* we already grabbed the initial header earlier. This just
273 saves the waste of grabbing it again */
274 memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
275 memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
276 vf->dataoffsets[i]=dataoffset;
279 /* seek to the location of the initial header */
281 _seek_helper(vf,vf->offsets[i]);
282 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL)==-1){
283 fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
284 vf->dataoffsets[i]=-1;
286 vf->dataoffsets[i]=vf->offset;
287 ogg_stream_clear(&vf->os);
291 /* get the serial number and PCM length of this link. To do this,
292 get the last page of the stream */
294 long end=vf->offsets[i+1];
295 _seek_helper(vf,end);
298 ret=_get_prev_page(vf,&og);
300 /* this should not be possible */
301 fprintf(stderr,"Could not find last page of logical "
302 "bitstream #%d\n\n",i);
303 vorbis_info_clear(vf->vi+i);
304 vorbis_comment_clear(vf->vc+i);
307 if(ogg_page_frameno(&og)!=-1){
308 vf->serialnos[i]=ogg_page_serialno(&og);
309 vf->pcmlengths[i]=ogg_page_frameno(&og);
317 static int _make_decode_ready(OggVorbis_File *vf){
318 if(vf->decode_ready)exit(1);
319 vorbis_synthesis_init(&vf->vd,vf->vi);
320 vorbis_block_init(&vf->vd,&vf->vb);
325 static int _open_seekable(OggVorbis_File *vf){
326 vorbis_info initial_i;
327 vorbis_comment initial_c;
333 /* is this even vorbis...? */
334 ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno);
335 dataoffset=vf->offset;
336 ogg_stream_clear(&vf->os);
337 if(ret==-1)return(-1);
339 /* we can seek, so set out learning all about this file */
341 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
342 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
344 /* We get the offset for the last page of the physical bitstream.
345 Most OggVorbis files will contain a single logical bitstream */
346 end=_get_prev_page(vf,&og);
348 /* moer than one logical bitstream? */
349 if(ogg_page_serialno(&og)!=serialno){
351 /* Chained bitstream. Bisect-search each logical bitstream
352 section. Do so based on serial number only */
353 _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
357 /* Only one logical bitstream */
358 _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
362 _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
368 static int _open_nonseekable(OggVorbis_File *vf){
369 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
371 vf->vi=malloc(sizeof(vorbis_info));
372 vf->vc=malloc(sizeof(vorbis_info));
374 /* Try to fetch the headers, maintaining all the storage */
375 if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno)==-1)return(-1);
376 _make_decode_ready(vf);
381 /* clear out the current logical bitstream decoder */
382 static void _decode_clear(OggVorbis_File *vf){
383 ogg_stream_clear(&vf->os);
384 vorbis_dsp_clear(&vf->vd);
385 vorbis_block_clear(&vf->vb);
390 /* fetch and process a packet. Handles the case where we're at a
391 bitstream boundary and dumps the decoding machine. If the decoding
392 machine is unloaded, it loads it. It also keeps pcm_offset up to
393 date (seek and read both use this. seek uses a special hack with
396 return: -1) hole in the data (lost packet)
397 0) need more date (only if readp==0)/eof
401 static int _process_packet(OggVorbis_File *vf,int readp){
404 /* handle one packet. Try to fetch it from current stream state */
405 /* extract packets from page */
408 /* process a packet if we can. If the machine isn't loaded,
410 if(vf->decode_ready){
412 int result=ogg_stream_packetout(&vf->os,&op);
415 if(result==-1)return(-1); /* hole in the data. alert the toplevel */
417 /* got a packet. process it */
419 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
421 header packets aren't
424 vorbis_synthesis will
426 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
428 /* update the pcm offset. */
430 int link=(vf->seekable?vf->current_link:0);
434 /* this packet has a pcm_offset on it (the last packet
435 completed on a page carries the offset) After processing
436 (above), we know the pcm position of the *last* sample
437 ready to be returned. Find the offset of the *first* */
439 samples=vorbis_synthesis_pcmout(&vf->vd,&dummy);
443 frameno+=vf->pcmlengths[i];
444 vf->pcm_offset=frameno;
452 if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
454 /* has our decoding just traversed a bitstream boundary? */
455 if(vf->decode_ready){
456 if(vf->current_serialno!=ogg_page_serialno(&og)){
461 /* Do we need to load a new machine before submitting the page? */
462 /* This is different in the seekable and non-seekable cases.
464 In the seekable case, we already have all the header
465 information loaded and cached; we just initialize the machine
466 with it and continue on our merry way.
468 In the non-seekable (streaming) case, we'll only be at a
469 boundary if we just left the previous logical bitstream and
470 we're now nominally at the header of the next bitstream
473 if(!vf->decode_ready){
476 vf->current_serialno=ogg_page_serialno(&og);
478 /* match the serialno to bitstream section. We use this rather than
479 offset positions to avoid problems near logical bitstream
481 for(link=0;link<vf->links;link++)
482 if(vf->serialnos[link]==vf->current_serialno)break;
483 if(link==vf->links)return(-1); /* sign of a bogus stream. error out,
484 leave machine uninitialized */
486 vf->current_link=link;
488 ogg_stream_init(&vf->os,vf->current_serialno);
489 ogg_stream_reset(&vf->os);
492 /* we're streaming */
493 /* fetch the three header packets, build the info struct */
495 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
500 _make_decode_ready(vf);
502 ogg_stream_pagein(&vf->os,&og);
506 /**********************************************************************
507 * The helpers are over; it's all toplevel interface from here on out */
509 /* clear out the OggVorbis_File struct */
510 int ov_clear(OggVorbis_File *vf){
512 vorbis_block_clear(&vf->vb);
513 vorbis_dsp_clear(&vf->vd);
514 ogg_stream_clear(&vf->os);
516 if(vf->vi && vf->links){
518 for(i=0;i<vf->links;i++){
519 vorbis_info_clear(vf->vi+i);
520 vorbis_comment_clear(vf->vc+i);
525 if(vf->dataoffsets)free(vf->dataoffsets);
526 if(vf->pcmlengths)free(vf->pcmlengths);
527 if(vf->serialnos)free(vf->serialnos);
528 if(vf->offsets)free(vf->offsets);
529 ogg_sync_clear(&vf->oy);
530 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
531 memset(vf,0,sizeof(OggVorbis_File));
539 /* inspects the OggVorbis file and finds/documents all the logical
540 bitstreams contained in it. Tries to be tolerant of logical
541 bitstream sections that are truncated/woogie.
547 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
548 ov_callbacks callbacks = {
549 (size_t (*)(void *, size_t, size_t, void *)) fread,
550 (int (*)(void *, long, int)) fseek,
551 (int (*)(void *)) fclose,
552 (long (*)(void *)) ftell
555 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
559 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
560 ov_callbacks callbacks)
562 long offset=callbacks.seek_func(f,0,SEEK_CUR);
565 memset(vf,0,sizeof(OggVorbis_File));
567 vf->callbacks = callbacks;
569 /* init the framing state */
570 ogg_sync_init(&vf->oy);
572 /* perhaps some data was previously read into a buffer for testing
573 against other stream types. Allow initialization from this
574 previously read data (as we may be reading from a non-seekable
577 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
578 memcpy(buffer,initial,ibytes);
579 ogg_sync_wrote(&vf->oy,ibytes);
582 /* can we seek? Stevens suggests the seek test was portable */
584 ret=_open_seekable(vf);
586 ret=_open_nonseekable(vf);
595 /* How many logical bitstreams in this physical bitstream? */
596 long ov_streams(OggVorbis_File *vf){
600 /* Is the FILE * associated with vf seekable? */
601 long ov_seekable(OggVorbis_File *vf){
605 /* returns the bitrate for a given logical bitstream or the entire
606 physical bitstream. If the file is open for random access, it will
607 find the *actual* average bitrate. If the file is streaming, it
608 returns the nominal bitrate (if set) else the average of the
609 upper/lower bounds (if set) else -1 (unset).
611 If you want the actual bitrate field settings, get them from the
612 vorbis_info structs */
614 long ov_bitrate(OggVorbis_File *vf,int i){
615 if(i>=vf->links)return(-1);
616 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
620 for(i=0;i<vf->links;i++)
621 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
622 return(rint(bits/ov_time_total(vf,-1)));
625 /* return the actual bitrate */
626 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
628 /* return nominal if set */
629 if(vf->vi[i].bitrate_nominal>0){
630 return vf->vi[i].bitrate_nominal;
632 if(vf->vi[i].bitrate_upper>0){
633 if(vf->vi[i].bitrate_lower>0){
634 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
636 return vf->vi[i].bitrate_upper;
646 long ov_serialnumber(OggVorbis_File *vf,int i){
647 if(i>=vf->links)return(-1);
648 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
650 return(vf->current_serialno);
652 return(vf->serialnos[i]);
656 /* returns: total raw (compressed) length of content if i==-1
657 raw (compressed) length of that logical bitstream for i==0 to n
658 -1 if the stream is not seekable (we can't know the length)
660 long ov_raw_total(OggVorbis_File *vf,int i){
661 if(!vf->seekable || i>=vf->links)return(-1);
665 for(i=0;i<vf->links;i++)
666 acc+=ov_raw_total(vf,i);
669 return(vf->offsets[i+1]-vf->offsets[i]);
673 /* returns: total PCM length (samples) of content if i==-1
674 PCM length (samples) of that logical bitstream for i==0 to n
675 -1 if the stream is not seekable (we can't know the length)
677 int64_t ov_pcm_total(OggVorbis_File *vf,int i){
678 if(!vf->seekable || i>=vf->links)return(-1);
682 for(i=0;i<vf->links;i++)
683 acc+=ov_pcm_total(vf,i);
686 return(vf->pcmlengths[i]);
690 /* returns: total seconds of content if i==-1
691 seconds in that logical bitstream for i==0 to n
692 -1 if the stream is not seekable (we can't know the length)
694 double ov_time_total(OggVorbis_File *vf,int i){
695 if(!vf->seekable || i>=vf->links)return(-1);
699 for(i=0;i<vf->links;i++)
700 acc+=ov_time_total(vf,i);
703 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
707 /* seek to an offset relative to the *compressed* data. This also
708 immediately sucks in and decodes pages to update the PCM cursor. It
709 will cross a logical bitstream boundary, but only if it can't get
710 any packets out of the tail of the bitstream we seek to (so no
713 returns zero on success, nonzero on failure */
715 int ov_raw_seek(OggVorbis_File *vf,long pos){
717 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
718 if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
720 /* clear out decoding machine state */
724 _seek_helper(vf,pos);
726 /* we need to make sure the pcm_offset is set. We use the
727 _fetch_packet helper to process one packet with readp set, then
728 call it until it returns '0' with readp not set (the last packet
729 from a page has the 'frameno' field set, and that's how the
730 helper updates the offset */
732 switch(_process_packet(vf,1)){
734 /* oh, eof. There are no packets remaining. Set the pcm offset to
736 vf->pcm_offset=ov_pcm_total(vf,-1);
739 /* error! missing data or invalid bitstream structure */
747 switch(_process_packet(vf,0)){
749 /* the offset is set. If it's a bogus bitstream with no offset
750 information, it's not but that's not our fault. We still run
751 gracefully, we're just missing the offset */
754 /* error! missing data or invalid bitstream structure */
757 /* continue processing packets */
763 /* dump the machine so we're in a known state */
768 /* seek to a sample offset relative to the decompressed pcm stream
770 returns zero on success, nonzero on failure */
772 int ov_pcm_seek(OggVorbis_File *vf,int64_t pos){
774 int64_t total=ov_pcm_total(vf,-1);
776 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
777 if(pos<0 || pos>total)goto seek_error;
779 /* which bitstream section does this pcm offset occur in? */
780 for(link=vf->links-1;link>=0;link--){
781 total-=vf->pcmlengths[link];
785 /* search within the logical bitstream for the page with the highest
786 pcm_pos preceeding (or equal to) pos. There is a danger here;
787 missing pages or incorrect frame number information in the
788 bitstream could make our task impossible. Account for that (it
789 would be an error condition) */
791 int64_t target=pos-total;
792 long end=vf->offsets[link+1];
793 long begin=vf->offsets[link];
801 if(end-begin<CHUNKSIZE){
804 bisect=(end+begin)/2;
807 _seek_helper(vf,bisect);
808 ret=_get_next_page(vf,&og,end-bisect);
813 int64_t frameno=ogg_page_frameno(&og);
815 best=ret; /* raw offset of packet with frameno */
816 begin=vf->offset; /* raw offset of next packet */
823 /* found our page. seek to it (call raw_seek). */
825 if(ov_raw_seek(vf,best))goto seek_error;
829 if(vf->pcm_offset>=pos)goto seek_error;
830 if(pos>ov_pcm_total(vf,-1))goto seek_error;
832 /* discard samples until we reach the desired position. Crossing a
833 logical bitstream boundary with abandon is OK. */
834 while(vf->pcm_offset<pos){
836 long target=pos-vf->pcm_offset;
837 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
839 if(samples>target)samples=target;
840 vorbis_synthesis_read(&vf->vd,samples);
841 vf->pcm_offset+=samples;
844 if(_process_packet(vf,1)==0)
845 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
850 /* dump machine so we're in a known state */
855 /* seek to a playback time relative to the decompressed pcm stream
856 returns zero on success, nonzero on failure */
857 int ov_time_seek(OggVorbis_File *vf,double seconds){
858 /* translate time to PCM position and call ov_pcm_seek */
861 int64_t pcm_total=ov_pcm_total(vf,-1);
862 double time_total=ov_time_total(vf,-1);
864 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
865 if(seconds<0 || seconds>time_total)goto seek_error;
867 /* which bitstream section does this time offset occur in? */
868 for(link=vf->links-1;link>=0;link--){
869 pcm_total-=vf->pcmlengths[link];
870 time_total-=ov_time_total(vf,link);
871 if(seconds>=time_total)break;
874 /* enough information to convert time offset to pcm offset */
876 int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
877 return(ov_pcm_seek(vf,target));
881 /* dump machine so we're in a known state */
886 /* tell the current stream offset cursor. Note that seek followed by
887 tell will likely not give the set offset due to caching */
888 long ov_raw_tell(OggVorbis_File *vf){
892 /* return PCM offset (sample) of next PCM sample to be read */
893 int64_t ov_pcm_tell(OggVorbis_File *vf){
894 return(vf->pcm_offset);
897 /* return time offset (seconds) of next PCM sample to be read */
898 double ov_time_tell(OggVorbis_File *vf){
899 /* translate time to PCM position and call ov_pcm_seek */
903 double time_total=0.;
906 pcm_total=ov_pcm_total(vf,-1);
907 time_total=ov_time_total(vf,-1);
909 /* which bitstream section does this time offset occur in? */
910 for(link=vf->links-1;link>=0;link--){
911 pcm_total-=vf->pcmlengths[link];
912 time_total-=ov_time_total(vf,link);
913 if(vf->pcm_offset>pcm_total)break;
917 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
920 /* link: -1) return the vorbis_info struct for the bitstream section
921 currently being decoded
922 0-n) to request information for a specific bitstream section
924 In the case of a non-seekable bitstream, any call returns the
925 current bitstream. NULL in the case that the machine is not
928 vorbis_info *ov_info(OggVorbis_File *vf,int link){
932 return vf->vi+vf->current_link;
948 /* grr, strong typing, grr, no templates/inheritence, grr */
949 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
953 return vf->vc+vf->current_link;
969 /* up to this point, everything could more or less hide the multiple
970 logical bitstream nature of chaining from the toplevel application
971 if the toplevel application didn't particularly care. However, at
972 the point that we actually read audio back, the multiple-section
973 nature must surface: Multiple bitstream sections do not necessarily
974 have to have the same number of channels or sampling rate.
976 ov_read returns the sequential logical bitstream number currently
977 being decoded along with the PCM data in order that the toplevel
978 application can take action on channel/sample rate changes. This
979 number will be incremented even for streamed (non-seekable) streams
980 (for seekable streams, it represents the actual logical bitstream
981 index within the physical bitstream. Note that the accessor
982 functions above are aware of this dichotomy).
984 input values: buffer) a buffer to hold packed PCM data for return
985 length) the byte length requested to be placed into buffer
986 bigendianp) should the data be packed LSB first (0) or
988 word) word size for output. currently 1 (byte) or
991 return values: -1) error/hole in data
993 n) number of bytes of PCM actually returned. The
994 below works on a packet-by-packet basis, so the
995 return length is not related to the 'length' passed
996 in, just guaranteed to fit.
998 *section) set to the logical bitstream number */
1000 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1001 int bigendianp,int word,int sgned,int *bitstream){
1005 if(vf->decode_ready){
1007 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1009 /* yay! proceed to pack data into the byte buffer */
1011 long channels=ov_info(vf,-1)->channels;
1012 long bytespersample=word * channels;
1013 if(samples>length/bytespersample)samples=length/bytespersample;
1015 /* a tight loop to pack each size */
1019 int off=(sgned?0:128);
1020 for(j=0;j<samples;j++)
1021 for(i=0;i<channels;i++){
1022 val=(int)(pcm[i][j]*128. + 0.5);
1024 else if(val<-128)val=-128;
1028 int off=(sgned?0:32768);
1031 for(j=0;j<samples;j++)
1032 for(i=0;i<channels;i++){
1033 val=(int)(pcm[i][j]*32768. + 0.5);
1034 if(val>32767)val=32767;
1035 else if(val<-32768)val=-32768;
1038 *buffer++=(val&0xff);
1042 for(j=0;j<samples;j++)
1043 for(i=0;i<channels;i++){
1044 val=(int)(pcm[i][j]*32768. + 0.5);
1045 if(val>32767)val=32767;
1046 else if(val<-32768)val=-32768;
1048 *buffer++=(val&0xff);
1056 vorbis_synthesis_read(&vf->vd,samples);
1057 vf->pcm_offset+=samples;
1058 if(bitstream)*bitstream=vf->current_link;
1059 return(samples*bytespersample);
1063 /* suck in another packet */
1064 switch(_process_packet(vf,1)){