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.24 2000/06/14 10:13:35 xiphmont Exp $
17 ********************************************************************/
25 #include "vorbis/codec.h"
26 #include "vorbis/vorbisfile.h"
31 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
32 one logical bitstream arranged end to end (the only form of Ogg
33 multiplexing allowed in a Vorbis bitstream; grouping [parallel
34 multiplexing] is not allowed in Vorbis) */
36 /* A Vorbis file can be played beginning to end (streamed) without
37 worrying ahead of time about chaining (see decoder_example.c). If
38 we have the whole file, however, and want random access
39 (seeking/scrubbing) or desire to know the total length/time of a
40 file, we need to account for the possibility of chaining. */
42 /* We can handle things a number of ways; we can determine the entire
43 bitstream structure right off the bat, or find pieces on demand.
44 This example determines and caches structure for the entire
45 bitstream, but builds a virtual decoder on the fly when moving
46 between links in the chain. */
48 /* There are also different ways to implement seeking. Enough
49 information exists in an Ogg bitstream to seek to
50 sample-granularity positions in the output. Or, one can seek by
51 picking some portion of the stream roughly in the desired area if
52 we only want course navigation through the stream. */
54 /*************************************************************************
55 * Many, many internal helpers. The intention is not to be confusing;
56 * rampant duplication and monolithic function implementation would be
57 * harder to understand anyway. The high level functions are last. Begin
58 * grokking near the end of the file */
60 /* read a little more data from the file/pipe into the ogg_sync framer */
61 #define CHUNKSIZE 4096
62 static long _get_data(OggVorbis_File *vf){
63 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
64 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
65 ogg_sync_wrote(&vf->oy,bytes);
69 /* save a tiny smidge of verbosity to make the code more readable */
70 static void _seek_helper(OggVorbis_File *vf,long offset){
71 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
73 ogg_sync_reset(&vf->oy);
76 /* The read/seek functions track absolute position within the stream */
78 /* from the head of the stream, get the next page. boundary specifies
79 if the function is allowed to fetch more data from the stream (and
80 how much) or only use internally buffered data.
82 boundary: -1) unbounded search
83 0) read no additional data; use cached only
84 n) search for a new page beginning for n bytes
86 return: -1) did not find a page
87 n) found a page at absolute offset n */
89 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
90 if(boundary>0)boundary+=vf->offset;
94 if(boundary>0 && vf->offset>=boundary)return(-1);
95 more=ogg_sync_pageseek(&vf->oy,og);
102 /* send more paramedics */
103 if(!boundary)return(-1);
104 if(_get_data(vf)<=0)return(-1);
106 /* got a page. Return the offset at the page beginning,
107 advance the internal offset past the page end */
117 /* find the latest page beginning before the current stream cursor
118 position. Much dirtier than the above as Ogg doesn't have any
119 backward search linkage. no 'readp' as it will certainly have to
121 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
122 long begin=vf->offset;
128 _seek_helper(vf,begin);
129 while(vf->offset<begin+CHUNKSIZE){
130 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
139 /* we have the offset. Actually snork and hold the page now */
140 _seek_helper(vf,offset);
141 ret=_get_next_page(vf,og,CHUNKSIZE);
143 /* this shouldn't be possible */
144 fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
151 /* finds each bitstream link one at a time using a bisection search
152 (has to begin by knowing the offset of the lb's initial page).
153 Recurses for each link so it can alloc the link storage after
154 finding them all, then unroll and fill the cache at the same time */
155 static void _bisect_forward_serialno(OggVorbis_File *vf,
161 long endsearched=end;
166 /* the below guards against garbage seperating the last and
167 first pages of two links. */
168 while(searched<endsearched){
171 if(endsearched-searched<CHUNKSIZE){
174 bisect=(searched+endsearched)/2;
177 _seek_helper(vf,bisect);
178 ret=_get_next_page(vf,&og,-1);
179 if(ret<0 || ogg_page_serialno(&og)!=currentno){
183 searched=ret+og.header_len+og.body_len;
187 _seek_helper(vf,next);
188 ret=_get_next_page(vf,&og,-1);
190 if(searched>=end || ret==-1){
192 vf->offsets=malloc((m+2)*sizeof(int64_t));
193 vf->offsets[m+1]=searched;
195 _bisect_forward_serialno(vf,next,vf->offset,
196 end,ogg_page_serialno(&og),m+1);
199 vf->offsets[m]=begin;
202 /* uses the local ogg_stream storage in vf; this is important for
203 non-streaming input sources */
204 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
210 ret=_get_next_page(vf,&og,CHUNKSIZE);
212 fprintf(stderr,"Did not find initial header for bitstream.\n");
216 if(serialno)*serialno=ogg_page_serialno(&og);
217 ogg_stream_init(&vf->os,ogg_page_serialno(&og));
219 /* extract the initial header from the first page and verify that the
220 Ogg bitstream is in fact Vorbis data */
222 vorbis_info_init(vi);
223 vorbis_comment_init(vc);
227 ogg_stream_pagein(&vf->os,&og);
229 int result=ogg_stream_packetout(&vf->os,&op);
232 fprintf(stderr,"Corrupt header in logical bitstream.\n");
235 if(vorbis_synthesis_headerin(vi,vc,&op)){
236 fprintf(stderr,"Illegal header in logical bitstream.\n");
242 if(_get_next_page(vf,&og,1)<0){
243 fprintf(stderr,"Missing header in logical bitstream.\n");
250 vorbis_info_clear(vi);
251 vorbis_comment_clear(vc);
252 ogg_stream_clear(&vf->os);
256 /* last step of the OggVorbis_File initialization; get all the
257 vorbis_info structs and PCM positions. Only called by the seekable
258 initialization (local stream storage is hacked slightly; pay
259 attention to how that's done) */
260 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
261 vorbis_comment *first_c,
266 vf->vi=calloc(vf->links,sizeof(vorbis_info));
267 vf->vc=calloc(vf->links,sizeof(vorbis_info));
268 vf->dataoffsets=malloc(vf->links*sizeof(int64_t));
269 vf->pcmlengths=malloc(vf->links*sizeof(int64_t));
270 vf->serialnos=malloc(vf->links*sizeof(long));
272 for(i=0;i<vf->links;i++){
273 if(first_i && first_c && i==0){
274 /* we already grabbed the initial header earlier. This just
275 saves the waste of grabbing it again */
276 memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
277 memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
278 vf->dataoffsets[i]=dataoffset;
281 /* seek to the location of the initial header */
283 _seek_helper(vf,vf->offsets[i]);
284 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL)==-1){
285 fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
286 vf->dataoffsets[i]=-1;
288 vf->dataoffsets[i]=vf->offset;
289 ogg_stream_clear(&vf->os);
293 /* get the serial number and PCM length of this link. To do this,
294 get the last page of the stream */
296 long end=vf->offsets[i+1];
297 _seek_helper(vf,end);
300 ret=_get_prev_page(vf,&og);
302 /* this should not be possible */
303 fprintf(stderr,"Could not find last page of logical "
304 "bitstream #%d\n\n",i);
305 vorbis_info_clear(vf->vi+i);
306 vorbis_comment_clear(vf->vc+i);
309 if(ogg_page_frameno(&og)!=-1){
310 vf->serialnos[i]=ogg_page_serialno(&og);
311 vf->pcmlengths[i]=ogg_page_frameno(&og);
319 static int _make_decode_ready(OggVorbis_File *vf){
320 if(vf->decode_ready)exit(1);
321 vorbis_synthesis_init(&vf->vd,vf->vi);
322 vorbis_block_init(&vf->vd,&vf->vb);
327 static int _open_seekable(OggVorbis_File *vf){
328 vorbis_info initial_i;
329 vorbis_comment initial_c;
335 /* is this even vorbis...? */
336 ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno);
337 dataoffset=vf->offset;
338 ogg_stream_clear(&vf->os);
339 if(ret==-1)return(-1);
341 /* we can seek, so set out learning all about this file */
343 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
344 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
346 /* We get the offset for the last page of the physical bitstream.
347 Most OggVorbis files will contain a single logical bitstream */
348 end=_get_prev_page(vf,&og);
350 /* moer than one logical bitstream? */
351 if(ogg_page_serialno(&og)!=serialno){
353 /* Chained bitstream. Bisect-search each logical bitstream
354 section. Do so based on serial number only */
355 _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
359 /* Only one logical bitstream */
360 _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
364 _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
370 static int _open_nonseekable(OggVorbis_File *vf){
371 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
373 vf->vi=calloc(vf->links,sizeof(vorbis_info));
374 vf->vc=calloc(vf->links,sizeof(vorbis_info));
376 /* Try to fetch the headers, maintaining all the storage */
377 if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno)==-1)return(-1);
378 _make_decode_ready(vf);
383 /* clear out the current logical bitstream decoder */
384 static void _decode_clear(OggVorbis_File *vf){
385 ogg_stream_clear(&vf->os);
386 vorbis_dsp_clear(&vf->vd);
387 vorbis_block_clear(&vf->vb);
392 /* fetch and process a packet. Handles the case where we're at a
393 bitstream boundary and dumps the decoding machine. If the decoding
394 machine is unloaded, it loads it. It also keeps pcm_offset up to
395 date (seek and read both use this. seek uses a special hack with
398 return: -1) hole in the data (lost packet)
399 0) need more date (only if readp==0)/eof
403 static int _process_packet(OggVorbis_File *vf,int readp){
406 /* handle one packet. Try to fetch it from current stream state */
407 /* extract packets from page */
410 /* process a packet if we can. If the machine isn't loaded,
412 if(vf->decode_ready){
414 int result=ogg_stream_packetout(&vf->os,&op);
417 if(result==-1)return(-1); /* hole in the data. alert the toplevel */
419 /* got a packet. process it */
421 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
423 header packets aren't
426 vorbis_synthesis will
428 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
430 /* update the pcm offset. */
431 if(frameno!=-1 && !op.e_o_s){
432 int link=(vf->seekable?vf->current_link:0);
436 /* this packet has a pcm_offset on it (the last packet
437 completed on a page carries the offset) After processing
438 (above), we know the pcm position of the *last* sample
439 ready to be returned. Find the offset of the *first*
441 As an aside, this trick is inaccurate if we begin
442 reading anew right at the last page; the end-of-stream
443 frameno declares the last frame in the stream, and the
444 last packet of the last page may be a partial frame.
445 So, we need a previous frameno from an in-sequence page
446 to have a reference point. Thus the !op.e_o_s clause
449 samples=vorbis_synthesis_pcmout(&vf->vd,&dummy);
453 frameno+=vf->pcmlengths[i];
454 vf->pcm_offset=frameno;
462 if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
464 /* has our decoding just traversed a bitstream boundary? */
465 if(vf->decode_ready){
466 if(vf->current_serialno!=ogg_page_serialno(&og)){
471 /* Do we need to load a new machine before submitting the page? */
472 /* This is different in the seekable and non-seekable cases.
474 In the seekable case, we already have all the header
475 information loaded and cached; we just initialize the machine
476 with it and continue on our merry way.
478 In the non-seekable (streaming) case, we'll only be at a
479 boundary if we just left the previous logical bitstream and
480 we're now nominally at the header of the next bitstream
483 if(!vf->decode_ready){
486 vf->current_serialno=ogg_page_serialno(&og);
488 /* match the serialno to bitstream section. We use this rather than
489 offset positions to avoid problems near logical bitstream
491 for(link=0;link<vf->links;link++)
492 if(vf->serialnos[link]==vf->current_serialno)break;
493 if(link==vf->links)return(-1); /* sign of a bogus stream. error out,
494 leave machine uninitialized */
496 vf->current_link=link;
498 ogg_stream_init(&vf->os,vf->current_serialno);
499 ogg_stream_reset(&vf->os);
502 /* we're streaming */
503 /* fetch the three header packets, build the info struct */
505 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
510 _make_decode_ready(vf);
512 ogg_stream_pagein(&vf->os,&og);
516 /**********************************************************************
517 * The helpers are over; it's all toplevel interface from here on out */
519 /* clear out the OggVorbis_File struct */
520 int ov_clear(OggVorbis_File *vf){
522 vorbis_block_clear(&vf->vb);
523 vorbis_dsp_clear(&vf->vd);
524 ogg_stream_clear(&vf->os);
526 if(vf->vi && vf->links){
528 for(i=0;i<vf->links;i++){
529 vorbis_info_clear(vf->vi+i);
530 vorbis_comment_clear(vf->vc+i);
535 if(vf->dataoffsets)free(vf->dataoffsets);
536 if(vf->pcmlengths)free(vf->pcmlengths);
537 if(vf->serialnos)free(vf->serialnos);
538 if(vf->offsets)free(vf->offsets);
539 ogg_sync_clear(&vf->oy);
540 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
541 memset(vf,0,sizeof(OggVorbis_File));
549 static int _fseek64_wrap(FILE *f,int64_t off,int whence){
550 return fseek(f,(int)off,whence);
553 /* inspects the OggVorbis file and finds/documents all the logical
554 bitstreams contained in it. Tries to be tolerant of logical
555 bitstream sections that are truncated/woogie.
561 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
562 ov_callbacks callbacks = {
563 (size_t (*)(void *, size_t, size_t, void *)) fread,
564 (int (*)(void *, int64_t, int)) _fseek64_wrap,
565 (int (*)(void *)) fclose,
566 (long (*)(void *)) ftell
569 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
573 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
574 ov_callbacks callbacks)
576 long offset=callbacks.seek_func(f,0,SEEK_CUR);
579 memset(vf,0,sizeof(OggVorbis_File));
581 vf->callbacks = callbacks;
583 /* init the framing state */
584 ogg_sync_init(&vf->oy);
586 /* perhaps some data was previously read into a buffer for testing
587 against other stream types. Allow initialization from this
588 previously read data (as we may be reading from a non-seekable
591 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
592 memcpy(buffer,initial,ibytes);
593 ogg_sync_wrote(&vf->oy,ibytes);
596 /* can we seek? Stevens suggests the seek test was portable */
598 ret=_open_seekable(vf);
600 ret=_open_nonseekable(vf);
609 /* How many logical bitstreams in this physical bitstream? */
610 long ov_streams(OggVorbis_File *vf){
614 /* Is the FILE * associated with vf seekable? */
615 long ov_seekable(OggVorbis_File *vf){
619 /* returns the bitrate for a given logical bitstream or the entire
620 physical bitstream. If the file is open for random access, it will
621 find the *actual* average bitrate. If the file is streaming, it
622 returns the nominal bitrate (if set) else the average of the
623 upper/lower bounds (if set) else -1 (unset).
625 If you want the actual bitrate field settings, get them from the
626 vorbis_info structs */
628 long ov_bitrate(OggVorbis_File *vf,int i){
629 if(i>=vf->links)return(-1);
630 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
634 for(i=0;i<vf->links;i++)
635 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
636 return(rint(bits/ov_time_total(vf,-1)));
639 /* return the actual bitrate */
640 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
642 /* return nominal if set */
643 if(vf->vi[i].bitrate_nominal>0){
644 return vf->vi[i].bitrate_nominal;
646 if(vf->vi[i].bitrate_upper>0){
647 if(vf->vi[i].bitrate_lower>0){
648 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
650 return vf->vi[i].bitrate_upper;
660 long ov_serialnumber(OggVorbis_File *vf,int i){
661 if(i>=vf->links)return(-1);
662 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
664 return(vf->current_serialno);
666 return(vf->serialnos[i]);
670 /* returns: total raw (compressed) length of content if i==-1
671 raw (compressed) length of that logical bitstream for i==0 to n
672 -1 if the stream is not seekable (we can't know the length)
674 int64_t ov_raw_total(OggVorbis_File *vf,int i){
675 if(!vf->seekable || i>=vf->links)return(-1);
679 for(i=0;i<vf->links;i++)
680 acc+=ov_raw_total(vf,i);
683 return(vf->offsets[i+1]-vf->offsets[i]);
687 /* returns: total PCM length (samples) of content if i==-1
688 PCM length (samples) of that logical bitstream for i==0 to n
689 -1 if the stream is not seekable (we can't know the length)
691 int64_t ov_pcm_total(OggVorbis_File *vf,int i){
692 if(!vf->seekable || i>=vf->links)return(-1);
696 for(i=0;i<vf->links;i++)
697 acc+=ov_pcm_total(vf,i);
700 return(vf->pcmlengths[i]);
704 /* returns: total seconds of content if i==-1
705 seconds in that logical bitstream for i==0 to n
706 -1 if the stream is not seekable (we can't know the length)
708 double ov_time_total(OggVorbis_File *vf,int i){
709 if(!vf->seekable || i>=vf->links)return(-1);
713 for(i=0;i<vf->links;i++)
714 acc+=ov_time_total(vf,i);
717 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
721 /* seek to an offset relative to the *compressed* data. This also
722 immediately sucks in and decodes pages to update the PCM cursor. It
723 will cross a logical bitstream boundary, but only if it can't get
724 any packets out of the tail of the bitstream we seek to (so no
727 returns zero on success, nonzero on failure */
729 int ov_raw_seek(OggVorbis_File *vf,long pos){
731 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
732 if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
734 /* clear out decoding machine state */
738 _seek_helper(vf,pos);
740 /* we need to make sure the pcm_offset is set. We use the
741 _fetch_packet helper to process one packet with readp set, then
742 call it until it returns '0' with readp not set (the last packet
743 from a page has the 'frameno' field set, and that's how the
744 helper updates the offset */
746 switch(_process_packet(vf,1)){
748 /* oh, eof. There are no packets remaining. Set the pcm offset to
750 vf->pcm_offset=ov_pcm_total(vf,-1);
753 /* error! missing data or invalid bitstream structure */
761 switch(_process_packet(vf,0)){
763 /* the offset is set. If it's a bogus bitstream with no offset
764 information, it's not but that's not our fault. We still run
765 gracefully, we're just missing the offset */
768 /* error! missing data or invalid bitstream structure */
771 /* continue processing packets */
777 /* dump the machine so we're in a known state */
782 /* seek to a sample offset relative to the decompressed pcm stream
784 returns zero on success, nonzero on failure */
786 int ov_pcm_seek(OggVorbis_File *vf,int64_t pos){
788 int64_t total=ov_pcm_total(vf,-1);
790 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
791 if(pos<0 || pos>total)goto seek_error;
793 /* which bitstream section does this pcm offset occur in? */
794 for(link=vf->links-1;link>=0;link--){
795 total-=vf->pcmlengths[link];
799 /* search within the logical bitstream for the page with the highest
800 pcm_pos preceeding (or equal to) pos. There is a danger here;
801 missing pages or incorrect frame number information in the
802 bitstream could make our task impossible. Account for that (it
803 would be an error condition) */
805 int64_t target=pos-total;
806 long end=vf->offsets[link+1];
807 long begin=vf->offsets[link];
815 if(end-begin<CHUNKSIZE){
818 bisect=(end+begin)/2;
821 _seek_helper(vf,bisect);
822 ret=_get_next_page(vf,&og,end-bisect);
827 int64_t frameno=ogg_page_frameno(&og);
829 best=ret; /* raw offset of packet with frameno */
830 begin=vf->offset; /* raw offset of next packet */
837 /* found our page. seek to it (call raw_seek). */
839 if(ov_raw_seek(vf,best))goto seek_error;
843 if(vf->pcm_offset>=pos)goto seek_error;
844 if(pos>ov_pcm_total(vf,-1))goto seek_error;
846 /* discard samples until we reach the desired position. Crossing a
847 logical bitstream boundary with abandon is OK. */
848 while(vf->pcm_offset<pos){
850 long target=pos-vf->pcm_offset;
851 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
853 if(samples>target)samples=target;
854 vorbis_synthesis_read(&vf->vd,samples);
855 vf->pcm_offset+=samples;
858 if(_process_packet(vf,1)==0)
859 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
864 /* dump machine so we're in a known state */
869 /* seek to a playback time relative to the decompressed pcm stream
870 returns zero on success, nonzero on failure */
871 int ov_time_seek(OggVorbis_File *vf,double seconds){
872 /* translate time to PCM position and call ov_pcm_seek */
875 int64_t pcm_total=ov_pcm_total(vf,-1);
876 double time_total=ov_time_total(vf,-1);
878 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
879 if(seconds<0 || seconds>time_total)goto seek_error;
881 /* which bitstream section does this time offset occur in? */
882 for(link=vf->links-1;link>=0;link--){
883 pcm_total-=vf->pcmlengths[link];
884 time_total-=ov_time_total(vf,link);
885 if(seconds>=time_total)break;
888 /* enough information to convert time offset to pcm offset */
890 int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
891 return(ov_pcm_seek(vf,target));
895 /* dump machine so we're in a known state */
900 /* tell the current stream offset cursor. Note that seek followed by
901 tell will likely not give the set offset due to caching */
902 int64_t ov_raw_tell(OggVorbis_File *vf){
906 /* return PCM offset (sample) of next PCM sample to be read */
907 int64_t ov_pcm_tell(OggVorbis_File *vf){
908 return(vf->pcm_offset);
911 /* return time offset (seconds) of next PCM sample to be read */
912 double ov_time_tell(OggVorbis_File *vf){
913 /* translate time to PCM position and call ov_pcm_seek */
917 double time_total=0.;
920 pcm_total=ov_pcm_total(vf,-1);
921 time_total=ov_time_total(vf,-1);
923 /* which bitstream section does this time offset occur in? */
924 for(link=vf->links-1;link>=0;link--){
925 pcm_total-=vf->pcmlengths[link];
926 time_total-=ov_time_total(vf,link);
927 if(vf->pcm_offset>pcm_total)break;
931 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
934 /* link: -1) return the vorbis_info struct for the bitstream section
935 currently being decoded
936 0-n) to request information for a specific bitstream section
938 In the case of a non-seekable bitstream, any call returns the
939 current bitstream. NULL in the case that the machine is not
942 vorbis_info *ov_info(OggVorbis_File *vf,int link){
946 return vf->vi+vf->current_link;
962 /* grr, strong typing, grr, no templates/inheritence, grr */
963 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
967 return vf->vc+vf->current_link;
983 int host_is_big_endian() {
984 short pattern = 0xbabe;
985 unsigned char *bytewise = (unsigned char *)&pattern;
986 if (bytewise[0] == 0xba) return 1;
988 assert(bytewise[0] == 0xbe);
992 /* up to this point, everything could more or less hide the multiple
993 logical bitstream nature of chaining from the toplevel application
994 if the toplevel application didn't particularly care. However, at
995 the point that we actually read audio back, the multiple-section
996 nature must surface: Multiple bitstream sections do not necessarily
997 have to have the same number of channels or sampling rate.
999 ov_read returns the sequential logical bitstream number currently
1000 being decoded along with the PCM data in order that the toplevel
1001 application can take action on channel/sample rate changes. This
1002 number will be incremented even for streamed (non-seekable) streams
1003 (for seekable streams, it represents the actual logical bitstream
1004 index within the physical bitstream. Note that the accessor
1005 functions above are aware of this dichotomy).
1007 input values: buffer) a buffer to hold packed PCM data for return
1008 length) the byte length requested to be placed into buffer
1009 bigendianp) should the data be packed LSB first (0) or
1011 word) word size for output. currently 1 (byte) or
1014 return values: -1) error/hole in data
1016 n) number of bytes of PCM actually returned. The
1017 below works on a packet-by-packet basis, so the
1018 return length is not related to the 'length' passed
1019 in, just guaranteed to fit.
1021 *section) set to the logical bitstream number */
1023 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1024 int bigendianp,int word,int sgned,int *bitstream){
1026 int host_endian = host_is_big_endian();
1029 if(vf->decode_ready){
1031 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1033 /* yay! proceed to pack data into the byte buffer */
1035 long channels=ov_info(vf,-1)->channels;
1036 long bytespersample=word * channels;
1037 if(samples>length/bytespersample)samples=length/bytespersample;
1039 /* a tight loop to pack each size */
1043 int off=(sgned?0:128);
1044 for(j=0;j<samples;j++)
1045 for(i=0;i<channels;i++){
1046 val=(int)(pcm[i][j]*128. + 0.5);
1048 else if(val<-128)val=-128;
1052 int off=(sgned?0:32768);
1054 if(host_endian==bigendianp){
1056 for(i=0;i<channels;i++) { /* It's faster in this order */
1058 short *dest=((short *)buffer)+i;
1059 for(j=0;j<samples;j++) {
1060 val=(int)(src[j]*32768. + 0.5);
1061 if(val>32767)val=32767;
1062 else if(val<-32768)val=-32768;
1068 for(i=0;i<channels;i++) {
1070 short *dest=((short *)buffer)+i;
1071 for(j=0;j<samples;j++) {
1072 val=(int)(src[j]*32768. + 0.5);
1073 if(val>32767)val=32767;
1074 else if(val<-32768)val=-32768;
1080 }else if(bigendianp){
1081 for(j=0;j<samples;j++)
1082 for(i=0;i<channels;i++){
1083 val=(int)(pcm[i][j]*32768. + 0.5);
1084 if(val>32767)val=32767;
1085 else if(val<-32768)val=-32768;
1088 *buffer++=(val&0xff);
1092 for(j=0;j<samples;j++)
1093 for(i=0;i<channels;i++){
1094 val=(int)(pcm[i][j]*32768. + 0.5);
1095 if(val>32767)val=32767;
1096 else if(val<-32768)val=-32768;
1098 *buffer++=(val&0xff);
1106 vorbis_synthesis_read(&vf->vd,samples);
1107 vf->pcm_offset+=samples;
1108 if(bitstream)*bitstream=vf->current_link;
1109 return(samples*bytespersample);
1113 /* suck in another packet */
1114 switch(_process_packet(vf,1)){