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.17 2000/03/10 16:23:57 xiphmont Exp $
17 ********************************************************************/
22 #include "vorbis/codec.h"
23 #include "vorbis/vorbisfile.h"
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) */
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. */
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. */
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. */
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 */
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);
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);
70 ogg_sync_reset(&vf->oy);
73 /* The read/seek functions track absolute position within the stream */
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.
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
83 return: -1) did not find a page
84 n) found a page at absolute offset n */
86 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
87 if(boundary>0)boundary+=vf->offset;
91 if(boundary>0 && vf->offset>=boundary)return(-1);
92 more=ogg_sync_pageseek(&vf->oy,og);
99 /* send more paramedics */
100 if(!boundary)return(-1);
101 if(_get_data(vf)<=0)return(-1);
103 /* got a page. Return the offset at the page beginning,
104 advance the internal offset past the page end */
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
118 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
119 long begin=vf->offset;
125 _seek_helper(vf,begin);
126 while(vf->offset<begin+CHUNKSIZE){
127 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
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);
140 /* this shouldn't be possible */
141 fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
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,
158 long endsearched=end;
163 /* the below guards against garbage seperating the last and
164 first pages of two links. */
165 while(searched<endsearched){
168 if(endsearched-searched<CHUNKSIZE){
171 bisect=(searched+endsearched)/2;
174 _seek_helper(vf,bisect);
175 ret=_get_next_page(vf,&og,-1);
176 if(ret<0 || ogg_page_serialno(&og)!=currentno){
180 searched=ret+og.header_len+og.body_len;
184 _seek_helper(vf,next);
185 ret=_get_next_page(vf,&og,-1);
187 if(searched>=end || ret==-1){
189 vf->offsets=malloc((m+2)*sizeof(long));
190 vf->offsets[m+1]=searched;
192 _bisect_forward_serialno(vf,next,vf->offset,
193 end,ogg_page_serialno(&og),m+1);
196 vf->offsets[m]=begin;
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,
207 ret=_get_next_page(vf,&og,CHUNKSIZE);
209 fprintf(stderr,"Did not find initial header for bitstream.\n");
213 if(serialno)*serialno=ogg_page_serialno(&og);
214 ogg_stream_init(&vf->os,ogg_page_serialno(&og));
216 /* extract the initial header from the first page and verify that the
217 Ogg bitstream is in fact Vorbis data */
219 vorbis_info_init(vi);
220 vorbis_comment_init(vc);
224 ogg_stream_pagein(&vf->os,&og);
226 int result=ogg_stream_packetout(&vf->os,&op);
229 fprintf(stderr,"Corrupt header in logical bitstream.\n");
232 if(vorbis_synthesis_headerin(vi,vc,&op)){
233 fprintf(stderr,"Illegal header in logical bitstream.\n");
239 if(_get_next_page(vf,&og,1)<0){
240 fprintf(stderr,"Missing header in logical bitstream.\n");
247 vorbis_info_clear(vi);
248 vorbis_comment_clear(vc);
249 ogg_stream_clear(&vf->os);
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,
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));
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;
278 /* seek to the location of the initial header */
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;
285 vf->dataoffsets[i]=vf->offset;
286 ogg_stream_clear(&vf->os);
290 /* get the serial number and PCM length of this link. To do this,
291 get the last page of the stream */
293 long end=vf->offsets[i+1];
294 _seek_helper(vf,end);
297 ret=_get_prev_page(vf,&og);
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);
306 if(ogg_page_frameno(&og)!=-1){
307 vf->serialnos[i]=ogg_page_serialno(&og);
308 vf->pcmlengths[i]=ogg_page_frameno(&og);
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);
324 static int _open_seekable(OggVorbis_File *vf){
325 vorbis_info initial_i;
326 vorbis_comment initial_c;
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);
338 /* we can seek, so set out learning all about this file */
340 fseek(vf->f,0,SEEK_END);
341 vf->offset=vf->end=ftell(vf->f);
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);
347 /* moer than one logical bitstream? */
348 if(ogg_page_serialno(&og)!=serialno){
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);
356 /* Only one logical bitstream */
357 _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
361 _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
367 static int _open_nonseekable(OggVorbis_File *vf){
368 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
370 vf->vi=malloc(sizeof(vorbis_info));
371 vf->vc=malloc(sizeof(vorbis_info));
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);
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);
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
395 return: -1) hole in the data (lost packet)
396 0) need more date (only if readp==0)/eof
400 static int _process_packet(OggVorbis_File *vf,int readp){
403 /* handle one packet. Try to fetch it from current stream state */
404 /* extract packets from page */
407 /* process a packet if we can. If the machine isn't loaded,
409 if(vf->decode_ready){
411 int result=ogg_stream_packetout(&vf->os,&op);
414 if(result==-1)return(-1); /* hole in the data. alert the toplevel */
416 /* got a packet. process it */
418 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
420 header packets aren't
423 vorbis_synthesis will
425 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
427 /* update the pcm offset. */
429 int link=(vf->seekable?vf->current_link:0);
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* */
438 samples=vorbis_synthesis_pcmout(&vf->vd,&dummy);
442 frameno+=vf->pcmlengths[i];
443 vf->pcm_offset=frameno;
451 if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
453 /* has our decoding just traversed a bitstream boundary? */
454 if(vf->decode_ready){
455 if(vf->current_serialno!=ogg_page_serialno(&og)){
460 /* Do we need to load a new machine before submitting the page? */
461 /* This is different in the seekable and non-seekable cases.
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.
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
472 if(!vf->decode_ready){
475 vf->current_serialno=ogg_page_serialno(&og);
477 /* match the serialno to bitstream section. We use this rather than
478 offset positions to avoid problems near logical bitstream
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 */
485 vf->current_link=link;
487 ogg_stream_init(&vf->os,vf->current_serialno);
488 ogg_stream_reset(&vf->os,ogg_page_pageno(&og));
491 /* we're streaming */
492 /* fetch the three header packets, build the info struct */
494 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
499 _make_decode_ready(vf);
501 ogg_stream_pagein(&vf->os,&og);
505 /**********************************************************************
506 * The helpers are over; it's all toplevel interface from here on out */
508 /* clear out the OggVorbis_File struct */
509 int ov_clear(OggVorbis_File *vf){
511 vorbis_block_clear(&vf->vb);
512 vorbis_dsp_clear(&vf->vd);
513 ogg_stream_clear(&vf->os);
515 if(vf->vi && vf->links){
517 for(i=0;i<vf->links;i++){
518 vorbis_info_clear(vf->vi+i);
519 vorbis_comment_clear(vf->vc+i);
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));
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.
546 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
547 long offset=fseek(f,0,SEEK_CUR);
550 memset(vf,0,sizeof(OggVorbis_File));
553 /* init the framing state */
554 ogg_sync_init(&vf->oy);
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
561 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
562 memcpy(buffer,initial,ibytes);
563 ogg_sync_wrote(&vf->oy,ibytes);
566 /* can we seek? Stevens suggests the seek test was portable */
568 ret=_open_seekable(vf);
570 ret=_open_nonseekable(vf);
579 /* How many logical bitstreams in this physical bitstream? */
580 long ov_streams(OggVorbis_File *vf){
584 /* Is the FILE * associated with vf seekable? */
585 long ov_seekable(OggVorbis_File *vf){
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).
595 If you want the actual bitrate field settings, get them from the
596 vorbis_info structs */
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));
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)));
609 /* return the actual bitrate */
610 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
612 /* return nominal if set */
613 if(vf->vi[i].bitrate_nominal>0){
614 return vf->vi[i].bitrate_nominal;
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;
620 return vf->vi[i].bitrate_upper;
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));
634 return(vf->current_serialno);
636 return(vf->serialnos[i]);
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)
644 long ov_raw_total(OggVorbis_File *vf,int i){
645 if(!vf->seekable || i>=vf->links)return(-1);
649 for(i=0;i<vf->links;i++)
650 acc+=ov_raw_total(vf,i);
653 return(vf->offsets[i+1]-vf->offsets[i]);
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)
661 int64_t ov_pcm_total(OggVorbis_File *vf,int i){
662 if(!vf->seekable || i>=vf->links)return(-1);
666 for(i=0;i<vf->links;i++)
667 acc+=ov_pcm_total(vf,i);
670 return(vf->pcmlengths[i]);
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)
678 double ov_time_total(OggVorbis_File *vf,int i){
679 if(!vf->seekable || i>=vf->links)return(-1);
683 for(i=0;i<vf->links;i++)
684 acc+=ov_time_total(vf,i);
687 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
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
697 returns zero on success, nonzero on failure */
699 int ov_raw_seek(OggVorbis_File *vf,long pos){
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;
704 /* clear out decoding machine state */
708 _seek_helper(vf,pos);
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 */
716 switch(_process_packet(vf,1)){
718 /* oh, eof. There are no packets remaining. Set the pcm offset to
720 vf->pcm_offset=ov_pcm_total(vf,-1);
723 /* error! missing data or invalid bitstream structure */
731 switch(_process_packet(vf,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 */
738 /* error! missing data or invalid bitstream structure */
741 /* continue processing packets */
747 /* dump the machine so we're in a known state */
752 /* seek to a sample offset relative to the decompressed pcm stream
754 returns zero on success, nonzero on failure */
756 int ov_pcm_seek(OggVorbis_File *vf,int64_t pos){
758 int64_t total=ov_pcm_total(vf,-1);
760 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
761 if(pos<0 || pos>total)goto seek_error;
763 /* which bitstream section does this pcm offset occur in? */
764 for(link=vf->links-1;link>=0;link--){
765 total-=vf->pcmlengths[link];
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) */
775 int64_t target=pos-total;
776 long end=vf->offsets[link+1];
777 long begin=vf->offsets[link];
785 if(end-begin<CHUNKSIZE){
788 bisect=(end+begin)/2;
791 _seek_helper(vf,bisect);
792 ret=_get_next_page(vf,&og,end-bisect);
797 int64_t frameno=ogg_page_frameno(&og);
799 best=ret; /* raw offset of packet with frameno */
800 begin=vf->offset; /* raw offset of next packet */
807 /* found our page. seek to it (call raw_seek). */
809 if(ov_raw_seek(vf,best))goto seek_error;
813 if(vf->pcm_offset>=pos)goto seek_error;
814 if(pos>ov_pcm_total(vf,-1))goto seek_error;
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){
820 long target=pos-vf->pcm_offset;
821 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
823 if(samples>target)samples=target;
824 vorbis_synthesis_read(&vf->vd,samples);
825 vf->pcm_offset+=samples;
828 if(_process_packet(vf,1)==0)
829 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
834 /* dump machine so we're in a known state */
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 */
845 int64_t pcm_total=ov_pcm_total(vf,-1);
846 double time_total=ov_time_total(vf,-1);
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;
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;
858 /* enough information to convert time offset to pcm offset */
860 int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
861 return(ov_pcm_seek(vf,target));
865 /* dump machine so we're in a known state */
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){
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);
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 */
887 double time_total=0.;
890 pcm_total=ov_pcm_total(vf,-1);
891 time_total=ov_time_total(vf,-1);
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;
901 return(time_total+(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
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
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
912 vorbis_info *ov_info(OggVorbis_File *vf,int link){
916 return vf->vi+vf->current_link;
932 /* grr, strong typing, grr, no templates/inheritence, grr */
933 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
937 return vf->vc+vf->current_link;
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.
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).
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
972 word) word size for output. currently 1 (byte) or
975 return values: -1) error/hole in data
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.
982 *section) set to the logical bitstream number */
984 long ov_read(OggVorbis_File *vf,char *buffer,int length,
985 int bigendianp,int word,int sgned,int *bitstream){
989 if(vf->decode_ready){
991 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
993 /* yay! proceed to pack data into the byte buffer */
995 long channels=ov_info(vf,-1)->channels;
996 long bytespersample=word * channels;
997 if(samples>length/bytespersample)samples=length/bytespersample;
999 /* a tight loop to pack each size */
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.);
1007 if(val<-128)val=-128;
1011 int off=(sgned?0:32768);
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;
1021 *buffer++=(val&0xff);
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;
1030 *buffer++=(val&0xff);
1038 vorbis_synthesis_read(&vf->vd,samples);
1039 vf->pcm_offset+=samples;
1040 if(bitstream)*bitstream=vf->current_link;
1041 return(samples*bytespersample);
1045 /* suck in another packet */
1046 switch(_process_packet(vf,1)){