1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
6 * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis 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.35 2001/01/01 21:31:15 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){
65 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
66 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
67 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
68 if(bytes==0 && errno)return(-1);
74 /* save a tiny smidge of verbosity to make the code more readable */
75 static void _seek_helper(OggVorbis_File *vf,long offset){
77 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
79 ogg_sync_reset(&vf->oy);
81 /* shouldn't happen unless someone writes a broken callback */
86 /* The read/seek functions track absolute position within the stream */
88 /* from the head of the stream, get the next page. boundary specifies
89 if the function is allowed to fetch more data from the stream (and
90 how much) or only use internally buffered data.
92 boundary: -1) unbounded search
93 0) read no additional data; use cached only
94 n) search for a new page beginning for n bytes
96 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
97 n) found a page at absolute offset n */
99 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
100 if(boundary>0)boundary+=vf->offset;
104 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
105 more=ogg_sync_pageseek(&vf->oy,og);
108 /* skipped n bytes */
112 /* send more paramedics */
113 if(!boundary)return(OV_FALSE);
115 long ret=_get_data(vf);
116 if(ret==0)return(OV_EOF);
117 if(ret<0)return(OV_EREAD);
120 /* got a page. Return the offset at the page beginning,
121 advance the internal offset past the page end */
131 /* find the latest page beginning before the current stream cursor
132 position. Much dirtier than the above as Ogg doesn't have any
133 backward search linkage. no 'readp' as it will certainly have to
135 /* returns offset or OV_EREAD, OV_FAULT */
136 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
137 long begin=vf->offset;
143 _seek_helper(vf,begin);
144 while(vf->offset<begin+CHUNKSIZE){
145 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
146 if(ret==OV_EREAD)return(OV_EREAD);
155 /* we have the offset. Actually snork and hold the page now */
156 _seek_helper(vf,offset);
157 ret=_get_next_page(vf,og,CHUNKSIZE);
159 /* this shouldn't be possible */
165 /* finds each bitstream link one at a time using a bisection search
166 (has to begin by knowing the offset of the lb's initial page).
167 Recurses for each link so it can alloc the link storage after
168 finding them all, then unroll and fill the cache at the same time */
169 static int _bisect_forward_serialno(OggVorbis_File *vf,
175 long endsearched=end;
180 /* the below guards against garbage seperating the last and
181 first pages of two links. */
182 while(searched<endsearched){
185 if(endsearched-searched<CHUNKSIZE){
188 bisect=(searched+endsearched)/2;
191 _seek_helper(vf,bisect);
192 ret=_get_next_page(vf,&og,-1);
193 if(ret==OV_EREAD)return(OV_EREAD);
194 if(ret<0 || ogg_page_serialno(&og)!=currentno){
198 searched=ret+og.header_len+og.body_len;
202 _seek_helper(vf,next);
203 ret=_get_next_page(vf,&og,-1);
204 if(ret==OV_EREAD)return(OV_EREAD);
206 if(searched>=end || ret<0){
208 vf->offsets=_ogg_malloc((m+2)*sizeof(ogg_int64_t));
209 vf->offsets[m+1]=searched;
211 ret=_bisect_forward_serialno(vf,next,vf->offset,
212 end,ogg_page_serialno(&og),m+1);
213 if(ret==OV_EREAD)return(OV_EREAD);
216 vf->offsets[m]=begin;
220 /* uses the local ogg_stream storage in vf; this is important for
221 non-streaming input sources */
222 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
223 long *serialno,ogg_page *og_ptr){
229 ret=_get_next_page(vf,&og,CHUNKSIZE);
230 if(ret==OV_EREAD)return(OV_EREAD);
231 if(ret<0)return OV_ENOTVORBIS;
235 if(serialno)*serialno=ogg_page_serialno(og_ptr);
236 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
238 /* extract the initial header from the first page and verify that the
239 Ogg bitstream is in fact Vorbis data */
241 vorbis_info_init(vi);
242 vorbis_comment_init(vc);
246 ogg_stream_pagein(&vf->os,og_ptr);
248 int result=ogg_stream_packetout(&vf->os,&op);
254 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
260 if(_get_next_page(vf,og_ptr,1)<0){
268 vorbis_info_clear(vi);
269 vorbis_comment_clear(vc);
270 ogg_stream_clear(&vf->os);
274 /* last step of the OggVorbis_File initialization; get all the
275 vorbis_info structs and PCM positions. Only called by the seekable
276 initialization (local stream storage is hacked slightly; pay
277 attention to how that's done) */
279 /* this is void and does not propogate errors up because we want to be
280 able to open and use damaged bitstreams as well as we can. Just
281 watch out for missing information for links in the OggVorbis_File
283 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
284 vorbis_comment *first_c,
289 vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
290 vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
291 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
292 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
293 vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
295 for(i=0;i<vf->links;i++){
296 if(first_i && first_c && i==0){
297 /* we already grabbed the initial header earlier. This just
298 saves the waste of grabbing it again */
299 memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
300 memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
301 vf->dataoffsets[i]=dataoffset;
304 /* seek to the location of the initial header */
306 _seek_helper(vf,vf->offsets[i]);
307 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
308 vf->dataoffsets[i]=-1;
310 vf->dataoffsets[i]=vf->offset;
311 ogg_stream_clear(&vf->os);
315 /* get the serial number and PCM length of this link. To do this,
316 get the last page of the stream */
318 long end=vf->offsets[i+1];
319 _seek_helper(vf,end);
322 ret=_get_prev_page(vf,&og);
324 /* this should not be possible, actually */
325 vorbis_info_clear(vf->vi+i);
326 vorbis_comment_clear(vf->vc+i);
329 if(ogg_page_granulepos(&og)!=-1){
330 vf->serialnos[i]=ogg_page_serialno(&og);
331 vf->pcmlengths[i]=ogg_page_granulepos(&og);
339 static void _make_decode_ready(OggVorbis_File *vf){
340 if(vf->decode_ready)return;
342 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
344 vorbis_synthesis_init(&vf->vd,vf->vi);
346 vorbis_block_init(&vf->vd,&vf->vb);
351 static int _open_seekable(OggVorbis_File *vf){
352 vorbis_info initial_i;
353 vorbis_comment initial_c;
359 /* is this even vorbis...? */
360 ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno,NULL);
361 dataoffset=vf->offset;
362 ogg_stream_clear(&vf->os);
363 if(ret<0)return(ret);
365 /* we can seek, so set out learning all about this file */
367 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
368 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
370 /* We get the offset for the last page of the physical bitstream.
371 Most OggVorbis files will contain a single logical bitstream */
372 end=_get_prev_page(vf,&og);
374 ogg_stream_clear(&vf->os);
378 /* more than one logical bitstream? */
379 if(ogg_page_serialno(&og)!=serialno){
381 /* Chained bitstream. Bisect-search each logical bitstream
382 section. Do so based on serial number only */
383 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
384 ogg_stream_clear(&vf->os);
390 /* Only one logical bitstream */
391 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
392 ogg_stream_clear(&vf->os);
398 _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
399 return(ov_raw_seek(vf,0));
403 static int _open_nonseekable(OggVorbis_File *vf){
405 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
407 vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
408 vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
410 /* Try to fetch the headers, maintaining all the storage */
411 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0)
413 _make_decode_ready(vf);
418 /* clear out the current logical bitstream decoder */
419 static void _decode_clear(OggVorbis_File *vf){
420 ogg_stream_clear(&vf->os);
421 vorbis_dsp_clear(&vf->vd);
422 vorbis_block_clear(&vf->vb);
429 /* fetch and process a packet. Handles the case where we're at a
430 bitstream boundary and dumps the decoding machine. If the decoding
431 machine is unloaded, it loads it. It also keeps pcm_offset up to
432 date (seek and read both use this. seek uses a special hack with
435 return: <0) error, OV_HOLE (lost packet) or OV_EOF
436 0) need more data (only if readp==0)
440 static int _process_packet(OggVorbis_File *vf,int readp){
443 /* handle one packet. Try to fetch it from current stream state */
444 /* extract packets from page */
447 /* process a packet if we can. If the machine isn't loaded,
449 if(vf->decode_ready){
451 int result=ogg_stream_packetout(&vf->os,&op);
452 ogg_int64_t granulepos;
454 if(result==-1)return(OV_HOLE); /* hole in the data. */
456 /* got a packet. process it */
457 granulepos=op.granulepos;
458 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
460 header packets aren't
463 vorbis_synthesis will
466 /* suck in the synthesis data and track bitrate */
468 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
469 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
470 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
471 vf->bittrack+=op.bytes*8;
474 /* update the pcm offset. */
475 if(granulepos!=-1 && !op.e_o_s){
476 int link=(vf->seekable?vf->current_link:0);
479 /* this packet has a pcm_offset on it (the last packet
480 completed on a page carries the offset) After processing
481 (above), we know the pcm position of the *last* sample
482 ready to be returned. Find the offset of the *first*
484 As an aside, this trick is inaccurate if we begin
485 reading anew right at the last page; the end-of-stream
486 granulepos declares the last frame in the stream, and the
487 last packet of the last page may be a partial frame.
488 So, we need a previous granulepos from an in-sequence page
489 to have a reference point. Thus the !op.e_o_s clause
492 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
496 granulepos+=vf->pcmlengths[i];
497 vf->pcm_offset=granulepos;
505 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. leave unitialized */
507 /* bitrate tracking; add the header's bytes here, the body bytes
508 are done by packet above */
509 vf->bittrack+=og.header_len*8;
511 /* has our decoding just traversed a bitstream boundary? */
512 if(vf->decode_ready){
513 if(vf->current_serialno!=ogg_page_serialno(&og)){
518 /* Do we need to load a new machine before submitting the page? */
519 /* This is different in the seekable and non-seekable cases.
521 In the seekable case, we already have all the header
522 information loaded and cached; we just initialize the machine
523 with it and continue on our merry way.
525 In the non-seekable (streaming) case, we'll only be at a
526 boundary if we just left the previous logical bitstream and
527 we're now nominally at the header of the next bitstream
530 if(!vf->decode_ready){
533 vf->current_serialno=ogg_page_serialno(&og);
535 /* match the serialno to bitstream section. We use this rather than
536 offset positions to avoid problems near logical bitstream
538 for(link=0;link<vf->links;link++)
539 if(vf->serialnos[link]==vf->current_serialno)break;
540 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
545 vf->current_link=link;
547 ogg_stream_init(&vf->os,vf->current_serialno);
548 ogg_stream_reset(&vf->os);
551 /* we're streaming */
552 /* fetch the three header packets, build the info struct */
554 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
559 _make_decode_ready(vf);
561 ogg_stream_pagein(&vf->os,&og);
565 /**********************************************************************
566 * The helpers are over; it's all toplevel interface from here on out */
568 /* clear out the OggVorbis_File struct */
569 int ov_clear(OggVorbis_File *vf){
571 vorbis_block_clear(&vf->vb);
572 vorbis_dsp_clear(&vf->vd);
573 ogg_stream_clear(&vf->os);
575 if(vf->vi && vf->links){
577 for(i=0;i<vf->links;i++){
578 vorbis_info_clear(vf->vi+i);
579 vorbis_comment_clear(vf->vc+i);
584 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
585 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
586 if(vf->serialnos)_ogg_free(vf->serialnos);
587 if(vf->offsets)_ogg_free(vf->offsets);
588 ogg_sync_clear(&vf->oy);
589 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
590 memset(vf,0,sizeof(OggVorbis_File));
598 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
599 if(f==NULL)return(-1);
600 return fseek(f,(int)off,whence);
603 /* inspects the OggVorbis file and finds/documents all the logical
604 bitstreams contained in it. Tries to be tolerant of logical
605 bitstream sections that are truncated/woogie.
611 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
612 ov_callbacks callbacks = {
613 (size_t (*)(void *, size_t, size_t, void *)) fread,
614 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
615 (int (*)(void *)) fclose,
616 (long (*)(void *)) ftell
619 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
623 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
624 ov_callbacks callbacks)
626 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
629 memset(vf,0,sizeof(OggVorbis_File));
631 vf->callbacks = callbacks;
633 /* init the framing state */
634 ogg_sync_init(&vf->oy);
636 /* perhaps some data was previously read into a buffer for testing
637 against other stream types. Allow initialization from this
638 previously read data (as we may be reading from a non-seekable
641 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
642 memcpy(buffer,initial,ibytes);
643 ogg_sync_wrote(&vf->oy,ibytes);
646 /* can we seek? Stevens suggests the seek test was portable */
648 ret=_open_seekable(vf);
650 ret=_open_nonseekable(vf);
659 /* How many logical bitstreams in this physical bitstream? */
660 long ov_streams(OggVorbis_File *vf){
664 /* Is the FILE * associated with vf seekable? */
665 long ov_seekable(OggVorbis_File *vf){
669 /* returns the bitrate for a given logical bitstream or the entire
670 physical bitstream. If the file is open for random access, it will
671 find the *actual* average bitrate. If the file is streaming, it
672 returns the nominal bitrate (if set) else the average of the
673 upper/lower bounds (if set) else -1 (unset).
675 If you want the actual bitrate field settings, get them from the
676 vorbis_info structs */
678 long ov_bitrate(OggVorbis_File *vf,int i){
679 if(i>=vf->links)return(OV_EINVAL);
680 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
684 for(i=0;i<vf->links;i++)
685 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
686 return(rint(bits/ov_time_total(vf,-1)));
689 /* return the actual bitrate */
690 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
692 /* return nominal if set */
693 if(vf->vi[i].bitrate_nominal>0){
694 return vf->vi[i].bitrate_nominal;
696 if(vf->vi[i].bitrate_upper>0){
697 if(vf->vi[i].bitrate_lower>0){
698 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
700 return vf->vi[i].bitrate_upper;
709 /* returns the actual bitrate since last call. returns -1 if no
710 additional data to offer since last call (or at beginning of stream) */
711 long ov_bitrate_instant(OggVorbis_File *vf){
712 int link=(vf->seekable?vf->current_link:0);
714 if(vf->samptrack==0)return(OV_FALSE);
715 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
722 long ov_serialnumber(OggVorbis_File *vf,int i){
723 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
724 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
726 return(vf->current_serialno);
728 return(vf->serialnos[i]);
732 /* returns: total raw (compressed) length of content if i==-1
733 raw (compressed) length of that logical bitstream for i==0 to n
734 -1 if the stream is not seekable (we can't know the length)
736 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
737 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
741 for(i=0;i<vf->links;i++)
742 acc+=ov_raw_total(vf,i);
745 return(vf->offsets[i+1]-vf->offsets[i]);
749 /* returns: total PCM length (samples) of content if i==-1
750 PCM length (samples) of that logical bitstream for i==0 to n
751 -1 if the stream is not seekable (we can't know the length)
753 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
754 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
758 for(i=0;i<vf->links;i++)
759 acc+=ov_pcm_total(vf,i);
762 return(vf->pcmlengths[i]);
766 /* returns: total seconds of content if i==-1
767 seconds in that logical bitstream for i==0 to n
768 -1 if the stream is not seekable (we can't know the length)
770 double ov_time_total(OggVorbis_File *vf,int i){
771 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
775 for(i=0;i<vf->links;i++)
776 acc+=ov_time_total(vf,i);
779 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
783 /* seek to an offset relative to the *compressed* data. This also
784 immediately sucks in and decodes pages to update the PCM cursor. It
785 will cross a logical bitstream boundary, but only if it can't get
786 any packets out of the tail of the bitstream we seek to (so no
789 returns zero on success, nonzero on failure */
791 int ov_raw_seek(OggVorbis_File *vf,long pos){
793 if(!vf->seekable)return(OV_ENOSEEK); /* don't dump machine if we can't seek */
794 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
796 /* clear out decoding machine state */
801 _seek_helper(vf,pos);
803 /* we need to make sure the pcm_offset is set. We use the
804 _fetch_packet helper to process one packet with readp set, then
805 call it until it returns '0' with readp not set (the last packet
806 from a page has the 'granulepos' field set, and that's how the
807 helper updates the offset */
810 switch(_process_packet(vf,1)){
812 /* oh, eof. There are no packets remaining. Set the pcm offset to
814 vf->pcm_offset=ov_pcm_total(vf,-1);
828 /* don't have to check each time through for the updated granule;
829 it's always the last complete packet on a page */
830 switch(_process_packet(vf,0)){
832 /* the offset is set unless it's a bogus bitstream with no
833 offset information but that's not our fault. We still run
834 gracefully, we're just missing the offset */
839 /* continue processing packets */
845 /* dump the machine so we're in a known state */
851 /* Page granularity seek (faster than sample granularity because we
852 don't do the last bit of decode to find a specific sample).
854 Seek to the last [granule marked] page preceeding the specified pos
855 location, such that decoding past the returned point will quickly
856 arrive at the requested position. */
857 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
860 ogg_int64_t total=ov_pcm_total(vf,-1);
862 if(!vf->seekable)return(OV_ENOSEEK);
863 if(pos<0 || pos>total)return(OV_EINVAL);
865 /* which bitstream section does this pcm offset occur in? */
866 for(link=vf->links-1;link>=0;link--){
867 total-=vf->pcmlengths[link];
871 /* search within the logical bitstream for the page with the highest
872 pcm_pos preceeding (or equal to) pos. There is a danger here;
873 missing pages or incorrect frame number information in the
874 bitstream could make our task impossible. Account for that (it
875 would be an error condition) */
877 ogg_int64_t target=pos-total;
878 long end=vf->offsets[link+1];
879 long begin=vf->offsets[link];
886 if(end-begin<CHUNKSIZE){
889 bisect=(end+begin)/2;
892 _seek_helper(vf,bisect);
893 ret=_get_next_page(vf,&og,end-bisect);
895 case OV_FALSE: case OV_EOF:
902 ogg_int64_t granulepos=ogg_page_granulepos(&og);
903 if(granulepos<target){
904 best=ret; /* raw offset of packet with granulepos */
905 begin=vf->offset; /* raw offset of next packet */
913 /* found our page. seek to it (call raw_seek). */
915 if((ret=ov_raw_seek(vf,best)))goto seek_error;
919 if(vf->pcm_offset>=pos || pos>ov_pcm_total(vf,-1)){
926 /* dump machine so we're in a known state */
932 /* seek to a sample offset relative to the decompressed pcm stream
933 returns zero on success, nonzero on failure */
935 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
936 int ret=ov_pcm_seek_page(vf,pos);
937 if(ret<0)return(ret);
939 /* discard samples until we reach the desired position. Crossing a
940 logical bitstream boundary with abandon is OK. */
941 while(vf->pcm_offset<pos){
943 long target=pos-vf->pcm_offset;
944 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
946 if(samples>target)samples=target;
947 vorbis_synthesis_read(&vf->vd,samples);
948 vf->pcm_offset+=samples;
951 if(_process_packet(vf,1)==0)
952 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
957 /* seek to a playback time relative to the decompressed pcm stream
958 returns zero on success, nonzero on failure */
959 int ov_time_seek(OggVorbis_File *vf,double seconds){
960 /* translate time to PCM position and call ov_pcm_seek */
963 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
964 double time_total=ov_time_total(vf,-1);
966 if(!vf->seekable)return(OV_ENOSEEK);
967 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
969 /* which bitstream section does this time offset occur in? */
970 for(link=vf->links-1;link>=0;link--){
971 pcm_total-=vf->pcmlengths[link];
972 time_total-=ov_time_total(vf,link);
973 if(seconds>=time_total)break;
976 /* enough information to convert time offset to pcm offset */
978 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
979 return(ov_pcm_seek(vf,target));
983 /* page-granularity version of ov_time_seek
984 returns zero on success, nonzero on failure */
985 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
986 /* translate time to PCM position and call ov_pcm_seek */
989 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
990 double time_total=ov_time_total(vf,-1);
992 if(!vf->seekable)return(OV_ENOSEEK);
993 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
995 /* which bitstream section does this time offset occur in? */
996 for(link=vf->links-1;link>=0;link--){
997 pcm_total-=vf->pcmlengths[link];
998 time_total-=ov_time_total(vf,link);
999 if(seconds>=time_total)break;
1002 /* enough information to convert time offset to pcm offset */
1004 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1005 return(ov_pcm_seek_page(vf,target));
1009 /* tell the current stream offset cursor. Note that seek followed by
1010 tell will likely not give the set offset due to caching */
1011 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1015 /* return PCM offset (sample) of next PCM sample to be read */
1016 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1017 return(vf->pcm_offset);
1020 /* return time offset (seconds) of next PCM sample to be read */
1021 double ov_time_tell(OggVorbis_File *vf){
1022 /* translate time to PCM position and call ov_pcm_seek */
1025 ogg_int64_t pcm_total=0;
1026 double time_total=0.f;
1029 pcm_total=ov_pcm_total(vf,-1);
1030 time_total=ov_time_total(vf,-1);
1032 /* which bitstream section does this time offset occur in? */
1033 for(link=vf->links-1;link>=0;link--){
1034 pcm_total-=vf->pcmlengths[link];
1035 time_total-=ov_time_total(vf,link);
1036 if(vf->pcm_offset>=pcm_total)break;
1040 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1043 /* link: -1) return the vorbis_info struct for the bitstream section
1044 currently being decoded
1045 0-n) to request information for a specific bitstream section
1047 In the case of a non-seekable bitstream, any call returns the
1048 current bitstream. NULL in the case that the machine is not
1051 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1054 if(vf->decode_ready)
1055 return vf->vi+vf->current_link;
1064 if(vf->decode_ready)
1071 /* grr, strong typing, grr, no templates/inheritence, grr */
1072 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1075 if(vf->decode_ready)
1076 return vf->vc+vf->current_link;
1085 if(vf->decode_ready)
1092 int host_is_big_endian() {
1093 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1094 unsigned char *bytewise = (unsigned char *)&pattern;
1095 if (bytewise[0] == 0xfe) return 1;
1099 /* up to this point, everything could more or less hide the multiple
1100 logical bitstream nature of chaining from the toplevel application
1101 if the toplevel application didn't particularly care. However, at
1102 the point that we actually read audio back, the multiple-section
1103 nature must surface: Multiple bitstream sections do not necessarily
1104 have to have the same number of channels or sampling rate.
1106 ov_read returns the sequential logical bitstream number currently
1107 being decoded along with the PCM data in order that the toplevel
1108 application can take action on channel/sample rate changes. This
1109 number will be incremented even for streamed (non-seekable) streams
1110 (for seekable streams, it represents the actual logical bitstream
1111 index within the physical bitstream. Note that the accessor
1112 functions above are aware of this dichotomy).
1114 input values: buffer) a buffer to hold packed PCM data for return
1115 length) the byte length requested to be placed into buffer
1116 bigendianp) should the data be packed LSB first (0) or
1118 word) word size for output. currently 1 (byte) or
1121 return values: <0) error/hole in data (OV_HOLE)
1123 n) number of bytes of PCM actually returned. The
1124 below works on a packet-by-packet basis, so the
1125 return length is not related to the 'length' passed
1126 in, just guaranteed to fit.
1128 *section) set to the logical bitstream number */
1130 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1131 int bigendianp,int word,int sgned,int *bitstream){
1133 int host_endian = host_is_big_endian();
1136 if(vf->decode_ready){
1138 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1140 /* yay! proceed to pack data into the byte buffer */
1142 long channels=ov_info(vf,-1)->channels;
1143 long bytespersample=word * channels;
1144 vorbis_fpu_control fpu;
1145 if(samples>length/bytespersample)samples=length/bytespersample;
1147 /* a tight loop to pack each size */
1151 int off=(sgned?0:128);
1152 vorbis_fpu_setround(&fpu);
1153 for(j=0;j<samples;j++)
1154 for(i=0;i<channels;i++){
1155 val=vorbis_ftoi(pcm[i][j]*128.f);
1157 else if(val<-128)val=-128;
1160 vorbis_fpu_restore(fpu);
1162 int off=(sgned?0:32768);
1164 if(host_endian==bigendianp){
1167 vorbis_fpu_setround(&fpu);
1168 for(i=0;i<channels;i++) { /* It's faster in this order */
1170 short *dest=((short *)buffer)+i;
1171 for(j=0;j<samples;j++) {
1172 val=vorbis_ftoi(src[j]*32768.f);
1173 if(val>32767)val=32767;
1174 else if(val<-32768)val=-32768;
1179 vorbis_fpu_restore(fpu);
1183 vorbis_fpu_setround(&fpu);
1184 for(i=0;i<channels;i++) {
1186 short *dest=((short *)buffer)+i;
1187 for(j=0;j<samples;j++) {
1188 val=vorbis_ftoi(src[j]*32768.f);
1189 if(val>32767)val=32767;
1190 else if(val<-32768)val=-32768;
1195 vorbis_fpu_restore(fpu);
1198 }else if(bigendianp){
1200 vorbis_fpu_setround(&fpu);
1201 for(j=0;j<samples;j++)
1202 for(i=0;i<channels;i++){
1203 val=vorbis_ftoi(pcm[i][j]*32768.f);
1204 if(val>32767)val=32767;
1205 else if(val<-32768)val=-32768;
1208 *buffer++=(val&0xff);
1210 vorbis_fpu_restore(fpu);
1214 vorbis_fpu_setround(&fpu);
1215 for(j=0;j<samples;j++)
1216 for(i=0;i<channels;i++){
1217 val=vorbis_ftoi(pcm[i][j]*32768.f);
1218 if(val>32767)val=32767;
1219 else if(val<-32768)val=-32768;
1221 *buffer++=(val&0xff);
1224 vorbis_fpu_restore(fpu);
1230 vorbis_synthesis_read(&vf->vd,samples);
1231 vf->pcm_offset+=samples;
1232 if(bitstream)*bitstream=vf->current_link;
1233 return(samples*bytespersample);
1237 /* suck in another packet */
1238 switch(_process_packet(vf,1)){
1244 return(OV_EBADLINK);