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-1999 *
9 * by 1999 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 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Nov 04 1999
19 ********************************************************************/
25 #include "vorbisfile.h"
27 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
28 one logical bitstream arranged end to end (the only form of Ogg
29 multiplexing allowed in a Vorbis bitstream; grouping [parallel
30 multiplexing] is not allowed in Vorbis) */
32 /* A Vorbis file can be played beginning to end (streamed) without
33 worrying ahead of time about chaining (see decoder_example.c). If
34 we have the whole file, however, and want random access
35 (seeking/scrubbing) or desire to know the total length/time of a
36 file, we need to account for the possibility of chaining. */
38 /* We can handle things a number of ways; we can determine the entire
39 bitstream structure right off the bat, or find pieces on demand.
40 This example determines and caches structure for the entire
41 bitstream, but builds a virtual decoder on the fly when moving
42 between links in the chain. */
44 /* There are also different ways to implement seeking. Enough
45 information exists in an Ogg bitstream to seek to
46 sample-granularity positions in the output. Or, one can seek by
47 picking some portion of the stream roughly in the desired area if
48 we only want course navigation through the stream. */
50 /*************************************************************************
51 * Many, many internal helpers. The intention is not to be confusing;
52 * rampant duplication and monolithic function implementation would be
53 * harder to understand anyway. The high level functions are last. Begin
54 * grokking near the end of the file */
56 /* read a little more data from the file/pipe into the ogg_sync framer */
57 #define CHUNKSIZE 4096
58 static long _get_data(OggVorbis_File *vf){
59 char *buffer=ogg_sync_buffer(&vf->oy,4096);
60 long bytes=fread(buffer,1,4096,vf->f);
61 ogg_sync_wrote(&vf->oy,bytes);
65 /* save a tiny smidge of verbosity to make the code more readable */
66 static void _seek_helper(OggVorbis_File *vf,long offset){
67 fseek(vf->f,offset,SEEK_SET);
69 ogg_sync_reset(&vf->oy);
72 /* The read/seek functions track absolute position within the stream */
74 /* from the head of the stream, get the next page. boundary specifies
75 if the function is allowed to fetch more data from the stream (and
76 how much) or only use internally buffered data.
78 boundary: -1) unbounded search
79 0) read no additional data; use cached only
80 n) search for a new page beginning for n bytes
82 return: -1) did not find a page
83 n) found a page at absolute offset n */
85 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
86 if(boundary>0)boundary+=vf->offset;
90 if(boundary>0 && vf->offset>=boundary)return(-1);
91 more=ogg_sync_pageseek(&vf->oy,og);
98 /* send more paramedics */
99 if(!boundary)return(-1);
100 if(_get_data(vf)<=0)return(-1);
102 /* got a page. Return the offset at the page beginning,
103 advance the internal offset past the page end */
113 /* find the latest page beginning before the current stream cursor
114 position. Much dirtier than the above as Ogg doesn't have any
115 backward search linkage. no 'readp' as it will certainly have to
117 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
118 long begin=vf->offset;
124 _seek_helper(vf,begin);
125 while(vf->offset<begin+CHUNKSIZE){
126 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
135 /* we have the offset. Actually snork and hold the page now */
136 _seek_helper(vf,offset);
137 ret=_get_next_page(vf,og,CHUNKSIZE);
139 /* this shouldn't be possible */
140 fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
147 /* finds each bitstream link one at a time using a bisection search
148 (has to begin by knowing the offset of the lb's initial page).
149 Recurses for each link so it can alloc the link storage after
150 finding them all, then unroll and fill the cache at the same time */
151 static void _bisect_forward_serialno(OggVorbis_File *vf,
157 long endsearched=end;
162 /* the below guards against garbage seperating the last and
163 first pages of two links. */
164 while(searched<endsearched){
167 if(endsearched-searched<CHUNKSIZE){
170 bisect=(searched+endsearched)/2;
173 _seek_helper(vf,bisect);
174 ret=_get_next_page(vf,&og,-1);
175 if(ret<0 || ogg_page_serialno(&og)!=currentno){
179 searched=ret+og.header_len+og.body_len;
183 _seek_helper(vf,next);
184 ret=_get_next_page(vf,&og,-1);
186 if(searched>=end || ret==-1){
188 vf->offsets=malloc((m+2)*sizeof(long));
189 vf->offsets[m+1]=searched;
191 _bisect_forward_serialno(vf,next,vf->offset,
192 end,ogg_page_serialno(&og),m+1);
195 vf->offsets[m]=begin;
198 /* uses the local ogg_stream storage in vf; this is important for
199 non-streaming input sources */
200 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
205 ret=_get_next_page(vf,&og,CHUNKSIZE);
207 fprintf(stderr,"Did not find initial header for bitstream.\n");
211 if(serialno)*serialno=ogg_page_serialno(&og);
212 ogg_stream_init(&vf->os,ogg_page_serialno(&og));
214 /* extract the initial header from the first page and verify that the
215 Ogg bitstream is in fact Vorbis data */
217 vorbis_info_init(vi);
221 ogg_stream_pagein(&vf->os,&og);
223 int result=ogg_stream_packetout(&vf->os,&op);
226 fprintf(stderr,"Corrupt header in logical bitstream.\n");
229 if(vorbis_info_headerin(vi,&op)){
230 fprintf(stderr,"Illegal header in logical bitstream.\n");
236 if(_get_next_page(vf,&og,1)<0){
237 fprintf(stderr,"Missing header in logical bitstream.\n");
244 vorbis_info_clear(vi);
245 ogg_stream_clear(&vf->os);
249 /* last step of the OggVorbis_File initialization; get all the
250 vorbis_info structs and PCM positions. Only called by the seekable
251 initialization (local stream storage is hacked slightly; pay
252 attention to how that's done) */
253 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first,
258 vf->vi=malloc(vf->links*sizeof(vorbis_info));
259 vf->dataoffsets=malloc(vf->links*sizeof(long));
260 vf->pcmlengths=malloc(vf->links*sizeof(size64));
261 vf->serialnos=malloc(vf->links*sizeof(long));
263 for(i=0;i<vf->links;i++){
265 /* we already grabbed the initial header earlier. This just
266 saves the waste of grabbing it again */
267 memcpy(vf->vi+i,first,sizeof(vorbis_info));
268 memset(first,0,sizeof(vorbis_info));
269 vf->dataoffsets[i]=dataoffset;
272 /* seek to the location of the initial header */
274 _seek_helper(vf,vf->offsets[i]);
275 if(_fetch_headers(vf,vf->vi+i,NULL)==-1){
276 vorbis_info_clear(vf->vi+i);
277 fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
279 ogg_stream_clear(&vf->os); /* clear local storage. This is not
280 done in _fetch_headers, as that may
281 be called in a non-seekable stream
282 (in which case, we need to preserve
283 the stream local storage) */
284 vf->dataoffsets[i]=-1;
286 vf->dataoffsets[i]=vf->offset;
289 /* get the serial number and PCM length of this link. To do this,
290 get the last page of the stream */
292 long end=vf->offsets[i+1];
293 _seek_helper(vf,end);
296 ret=_get_prev_page(vf,&og);
298 /* this should not be possible */
299 fprintf(stderr,"Could not find last page of logical "
300 "bitstream #%d\n\n",i);
301 vorbis_info_clear(vf->vi+i);
304 if(ogg_page_frameno(&og)!=-1){
305 vf->serialnos[i]=ogg_page_serialno(&og);
306 vf->pcmlengths[i]=ogg_page_frameno(&og);
314 static int _open_seekable(OggVorbis_File *vf){
321 /* is this even vorbis...? */
322 ret=_fetch_headers(vf,&initial,&serialno);
323 dataoffset=vf->offset;
324 ogg_stream_clear(&vf->os);
325 if(ret==-1)return(-1);
327 /* we can seek, so set out learning all about this file */
329 fseek(vf->f,0,SEEK_END);
330 vf->offset=vf->end=ftell(vf->f);
332 /* We get the offset for the last page of the physical bitstream.
333 Most OggVorbis files will contain a single logical bitstream */
334 end=_get_prev_page(vf,&og);
336 /* moer than one logical bitstream? */
337 if(ogg_page_serialno(&og)!=serialno){
339 /* Chained bitstream. Bisect-search each logical bitstream
340 section. Do so based on serial number only */
341 _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
345 /* Only one logical bitstream */
346 _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
350 _prefetch_all_headers(vf,&initial,dataoffset);
355 static int _open_nonseekable(OggVorbis_File *vf){
356 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
358 vf->vi=malloc(sizeof(vorbis_info));
360 /* Try to fetch the headers, maintaining all the storage */
361 if(_fetch_headers(vf,vf->vi,&vf->current_serialno)==-1)return(-1);
366 /* clear out the current logical bitstream decoder */
367 static void _decode_clear(OggVorbis_File *vf){
368 ogg_stream_clear(&vf->os);
369 vorbis_dsp_clear(&vf->vd);
370 vorbis_block_clear(&vf->vb);
375 /* fetch and process a packet. Handles the case where we're at a
376 bitstream boundary and dumps the decoding machine. If the decoding
377 machine is unloaded, it loads it. It also keeps pcm_offset up to
378 date (seek and read both use this. seek uses a special hack with
381 return: -1) hole in the data (lost packet)
382 0) need more date (only if readp==0)/eof
386 static int _process_packet(OggVorbis_File *vf,int readp){
389 /* handle one packet. Try to fetch it from current stream state */
390 /* extract packets from page */
393 /* process a packet if we can. If the machine isn't loaded,
395 if(vf->decode_ready){
397 int result=ogg_stream_packetout(&vf->os,&op);
400 if(result==-1)return(-1); /* hole in the data. alert the toplevel */
402 /* got a packet. process it */
404 vorbis_synthesis(&vf->vb,&op);
405 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
407 /* update the pcm offset. */
409 int link=(vf->seekable?vf->current_link:0);
413 /* this packet has a pcm_offset on it (the last packet
414 completed on a page carries the offset) After processing
415 (above), we know the pcm position of the *last* sample
416 ready to be returned. Find the offset of the *first* */
418 samples=vorbis_synthesis_pcmout(&vf->vd,&dummy);
422 frameno+=vf->pcmlengths[i];
423 vf->pcm_offset=frameno;
430 if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
432 /* has our decoding just traversed a bitstream boundary? */
433 if(vf->decode_ready){
434 if(vf->current_serialno!=ogg_page_serialno(&og)){
439 /* Do we need to load a new machine before submitting the page? */
440 /* This is different in the seekable and non-seekable cases.
442 In the seekable case, we already have all the header
443 information loaded and cached; we just initialize the machine
444 with it and continue on our merry way.
446 In the non-seekable (streaming) case, we'll only be at a
447 boundary if we just left the previous logical bitstream and
448 we're now nominally at the header of the next bitstream
451 if(!vf->decode_ready){
454 vf->current_serialno=ogg_page_serialno(&og);
456 /* match the serialno to bitstream section. We use this rather than
457 offset positions to avoid problems near logical bitstream
459 for(link=0;link<vf->links;link++)
460 if(vf->serialnos[link]==vf->current_serialno)break;
461 if(link==vf->links)return(-1); /* sign of a bogus stream. error out,
462 leave machine uninitialized */
464 vf->current_link=link;
466 /* we're streaming */
467 /* fetch the three header packets, build the info struct */
469 _fetch_headers(vf,vf->vi,&vf->current_serialno);
475 ogg_stream_init(&vf->os,vf->current_serialno);
476 vorbis_synthesis_init(&vf->vd,vf->vi+link);
477 vorbis_block_init(&vf->vd,&vf->vb);
480 ogg_stream_pagein(&vf->os,&og);
484 /**********************************************************************
485 * The helpers are over; it's all toplevel interface from here on out */
487 /* clear out the OggVorbis_File struct */
488 int ov_clear(OggVorbis_File *vf){
490 vorbis_block_clear(&vf->vb);
491 vorbis_dsp_clear(&vf->vd);
492 ogg_stream_clear(&vf->os);
494 if(vf->vi && vf->links){
496 for(i=0;i<vf->links;i++)
497 vorbis_info_clear(vf->vi+i);
500 if(vf->dataoffsets)free(vf->dataoffsets);
501 if(vf->pcmlengths)free(vf->pcmlengths);
502 if(vf->serialnos)free(vf->serialnos);
503 if(vf->offsets)free(vf->offsets);
504 ogg_sync_clear(&vf->oy);
505 if(vf->f)fclose(vf->f);
506 memset(vf,0,sizeof(OggVorbis_File));
511 /* inspects the OggVorbis file and finds/documents all the logical
512 bitstreams contained in it. Tries to be tolerant of logical
513 bitstream sections that are truncated/woogie.
519 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
520 long offset=fseek(f,0,SEEK_CUR);
523 memset(vf,0,sizeof(OggVorbis_File));
526 /* init the framing state */
527 ogg_sync_init(&vf->oy);
529 /* perhaps some data was previously read into a buffer for testing
530 against other stream types. Allow initialization from this
531 previously read data (as we may be reading from a non-seekable
534 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
535 memcpy(buffer,initial,ibytes);
536 ogg_sync_wrote(&vf->oy,ibytes);
539 /* can we seek? Stevens suggests the seek test was portable */
541 ret=_open_seekable(vf);
543 ret=_open_nonseekable(vf);
549 ogg_stream_init(&vf->os,vf->current_serialno);
550 vorbis_synthesis_init(&vf->vd,vf->vi);
551 vorbis_block_init(&vf->vd,&vf->vb);
557 /* How many logical bitstreams in this physical bitstream? */
558 long ov_streams(OggVorbis_File *vf){
562 /* Is the FILE * associated with vf seekable? */
563 long ov_seekable(OggVorbis_File *vf){
567 /* returns the bitrate for a given logical bitstream or the entire
568 physical bitstream. If the file is open for random access, it will
569 find the *actual* average bitrate. If the file is streaming, it
570 returns the nominal bitrate (if set) else the average of the
571 upper/lower bounds (if set) else -1 (unset).
573 If you want the actual bitrate field settings, get them from the
574 vorbis_info structs */
576 long ov_bitrate(OggVorbis_File *vf,int i){
577 if(i>=vf->links)return(-1);
578 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
582 for(i=0;i<vf->links;i++)
583 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
584 return(rint(bits/ov_time_total(vf,-1)));
587 /* return the actual bitrate */
588 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
590 /* return nominal if set */
591 if(vf->vi[i].bitrate_nominal>0){
592 return vf->vi[i].bitrate_nominal;
594 if(vf->vi[i].bitrate_upper>0){
595 if(vf->vi[i].bitrate_lower>0){
596 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
598 return vf->vi[i].bitrate_upper;
608 long ov_serialnumber(OggVorbis_File *vf,int i){
609 if(i>=vf->links)return(-1);
610 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
612 return(vf->current_serialno);
614 return(vf->serialnos[i]);
618 /* returns: total raw (compressed) length of content if i==-1
619 raw (compressed) length of that logical bitstream for i==0 to n
620 -1 if the stream is not seekable (we can't know the length)
622 long ov_raw_total(OggVorbis_File *vf,int i){
623 if(!vf->seekable || i>=vf->links)return(-1);
627 for(i=0;i<vf->links;i++)
628 acc+=ov_raw_total(vf,i);
631 return(vf->offsets[i+1]-vf->offsets[i]);
635 /* returns: total PCM length (samples) of content if i==-1
636 PCM length (samples) of that logical bitstream for i==0 to n
637 -1 if the stream is not seekable (we can't know the length)
639 size64 ov_pcm_total(OggVorbis_File *vf,int i){
640 if(!vf->seekable || i>=vf->links)return(-1);
644 for(i=0;i<vf->links;i++)
645 acc+=ov_pcm_total(vf,i);
648 return(vf->pcmlengths[i]);
652 /* returns: total seconds of content if i==-1
653 seconds in that logical bitstream for i==0 to n
654 -1 if the stream is not seekable (we can't know the length)
656 double ov_time_total(OggVorbis_File *vf,int i){
657 if(!vf->seekable || i>=vf->links)return(-1);
661 for(i=0;i<vf->links;i++)
662 acc+=ov_time_total(vf,i);
665 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
669 /* seek to an offset relative to the *compressed* data. This also
670 immediately sucks in and decodes pages to update the PCM cursor. It
671 will cross a logical bitstream boundary, but only if it can't get
672 any packets out of the tail of the bitstream we seek to (so no
675 returns zero on success, nonzero on failure */
677 int ov_raw_seek(OggVorbis_File *vf,long pos){
679 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
680 if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
682 /* clear out decoding machine state */
686 _seek_helper(vf,pos);
688 /* we need to make sure the pcm_offset is set. We use the
689 _fetch_packet helper to process one packet with readp set, then
690 call it until it returns '0' with readp not set (the last packet
691 from a page has the 'frameno' field set, and that's how the
692 helper updates the offset */
694 switch(_process_packet(vf,1)){
696 /* oh, eof. There are no packets remaining. Set the pcm offset to
698 vf->pcm_offset=ov_pcm_total(vf,-1);
701 /* error! missing data or invalid bitstream structure */
709 switch(_process_packet(vf,0)){
711 /* the offset is set. If it's a bogus bitstream with no offset
712 information, it's not but that's not our fault. We still run
713 gracefully, we're just missing the offset */
716 /* error! missing data or invalid bitstream structure */
719 /* continue processing packets */
725 /* dump the machine so we're in a known state */
730 /* seek to a sample offset relative to the decompressed pcm stream
732 returns zero on success, nonzero on failure */
734 int ov_pcm_seek(OggVorbis_File *vf,size64 pos){
736 size64 total=ov_pcm_total(vf,-1);
738 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
739 if(pos<0 || pos>total)goto seek_error;
741 /* which bitstream section does this pcm offset occur in? */
742 for(link=vf->links-1;link>=0;link--){
743 total-=vf->pcmlengths[link];
747 /* seach within the logical bitstream for the page with the highest
748 pcm_pos preceeding (or equal to) pos. There is a danger here;
749 missing pages or incorrect frame number information in the
750 bitstream could make our task impossible. Account for that (it
751 would be an error condition) */
753 size64 target=pos-total;
754 long end=vf->offsets[link+1];
755 long begin=vf->offsets[link];
763 if(end-begin<CHUNKSIZE){
766 bisect=(end+begin)/2;
769 _seek_helper(vf,bisect);
773 ret=_get_next_page(vf,&og,-1);
778 size64 frameno=ogg_page_frameno(&og);
780 if(frameno==-1)continue;
782 best=bisect+acc; /* raw offset of packet with frameno */
783 begin=vf->offset; /* raw offset of next packet */
792 /* found our page. seek to it (call raw_seek). */
794 if(ov_raw_seek(vf,best))goto seek_error;
798 if(vf->pcm_offset>=pos)goto seek_error;
799 if(pos>ov_pcm_total(vf,-1))goto seek_error;
801 /* discard samples until we reach the desired position. Crossing a
802 logical bitstream boundary with abandon is OK. */
803 while(vf->pcm_offset<pos){
805 long target=pos-vf->pcm_offset;
806 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
808 if(samples>target)samples=target;
809 vorbis_synthesis_read(&vf->vd,samples);
810 vf->pcm_offset+=samples;
813 if(_process_packet(vf,1)==0)
814 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
819 /* dump machine so we're in a known state */
824 /* seek to a playback time relative to the decompressed pcm stream
825 returns zero on success, nonzero on failure */
826 int ov_time_seek(OggVorbis_File *vf,double seconds){
827 /* translate time to PCM position and call ov_pcm_seek */
830 size64 pcm_total=ov_pcm_total(vf,-1);
831 double time_total=ov_time_total(vf,-1);
833 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
834 if(seconds<0 || seconds>time_total)goto seek_error;
836 /* which bitstream section does this time offset occur in? */
837 for(link=vf->links-1;link>=0;link--){
838 pcm_total-=vf->pcmlengths[link];
839 time_total-=ov_time_total(vf,link);
840 if(seconds>=time_total)break;
843 /* enough information to convert time offset to pcm offset */
845 size64 target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
846 return(ov_pcm_seek(vf,target));
850 /* dump machine so we're in a known state */
855 /* tell the current stream offset cursor. Note that seek followed by
856 tell will likely not give the set offset due to caching */
857 long ov_raw_tell(OggVorbis_File *vf){
861 /* return PCM offset (sample) of next PCM sample to be read */
862 size64 ov_pcm_tell(OggVorbis_File *vf){
863 return(vf->pcm_offset);
866 /* return time offset (seconds) of next PCM sample to be read */
867 double ov_time_tell(OggVorbis_File *vf){
868 /* translate time to PCM position and call ov_pcm_seek */
872 double time_total=0.;
875 pcm_total=ov_pcm_total(vf,-1);
876 time_total=ov_time_total(vf,-1);
878 /* which bitstream section does this time offset occur in? */
879 for(link=vf->links-1;link>=0;link--){
880 pcm_total-=vf->pcmlengths[link];
881 time_total-=ov_time_total(vf,link);
882 if(vf->pcm_offset>pcm_total)break;
886 return(time_total+(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
889 /* link: -1) return the vorbis_info struct for the bitstream section
890 currently being decoded
891 0-n) to request information for a specific bitstream section
893 In the case of a non-seekable bitstream, any call returns the
894 current bitstream. NULL in the case that the machine is not
897 vorbis_info *ov_info(OggVorbis_File *vf,int link){
901 return vf->vi+vf->current_link;
917 /* up to this point, everything could more or less hide the multiple
918 logical bitstream nature of chaining from the toplevel application
919 if the toplevel application didn't particularly care. However, at
920 the point that we actually read audio back, the multiple-section
921 nature must surface: Multiple bitstream sections do not necessarily
922 have to have the same number of channels or sampling rate.
924 ov_read returns the sequential logical bitstream number currently
925 being decoded along with the PCM data in order that the toplevel
926 application can take action on channel/sample rate changes. This
927 number will be incremented even for streamed (non-seekable) streams
928 (for seekable streams, it represents the actual logical bitstream
929 index within the physical bitstream. Note that the accessor
930 functions above are aware of this dichotomy).
932 input values: buffer) a buffer to hold packed PCM data for return
933 length) the byte length requested to be placed into buffer
934 bigendianp) should the data be packed LSB first (0) or
936 word) word size for output. currently 1 (byte) or
939 return values: -1) error/hole in data
941 n) number of bytes of PCM actually returned. The
942 below works on a packet-by-packet basis, so the
943 return length is not related to the 'length' passed
944 in, just guaranteed to fit.
946 *section) set to the logical bitstream number */
948 long ov_read(OggVorbis_File *vf,char *buffer,int length,
949 int bigendianp,int word,int sgned,int *bitstream){
953 if(vf->decode_ready){
955 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
957 /* yay! proceed to pack data into the byte buffer */
959 long channels=ov_info(vf,-1)->channels;
960 long bytespersample=word * channels;
961 if(samples>length/bytespersample)samples=length/bytespersample;
963 /* a tight loop to pack each size */
966 int off=(sgned?0:128);
967 for(j=0;j<samples;j++)
968 for(i=0;i<channels;i++){
969 int val=rint(pcm[i][j]*128.);
971 if(val<-128)val=-128;
975 int off=(sgned?0:32768);
978 for(j=0;j<samples;j++)
979 for(i=0;i<channels;i++){
980 int val=rint(pcm[i][j]*32768.);
981 if(val>32767)val=32767;
982 if(val<-32768)val=-32768;
985 *buffer++=(val&0xff);
988 for(j=0;j<samples;j++)
989 for(i=0;i<channels;i++){
990 int val=rint(pcm[i][j]*32768.);
991 if(val>32767)val=32767;
992 if(val<-32768)val=-32768;
994 *buffer++=(val&0xff);
1002 vorbis_synthesis_read(&vf->vd,samples);
1003 vf->pcm_offset+=samples;
1004 *bitstream=vf->current_link;
1005 return(samples*bytespersample);
1009 /* suck in another packet */
1010 switch(_process_packet(vf,1)){