1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 function: stdio-based convenience library for opening/seeking/decoding
14 last mod: $Id: vorbisfile.c,v 1.59 2002/03/07 03:41:03 xiphmont Exp $
16 ********************************************************************/
24 #include "vorbis/codec.h"
25 #include "vorbis/vorbisfile.h"
30 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
31 one logical bitstream arranged end to end (the only form of Ogg
32 multiplexing allowed in a Vorbis bitstream; grouping [parallel
33 multiplexing] is not allowed in Vorbis) */
35 /* A Vorbis file can be played beginning to end (streamed) without
36 worrying ahead of time about chaining (see decoder_example.c). If
37 we have the whole file, however, and want random access
38 (seeking/scrubbing) or desire to know the total length/time of a
39 file, we need to account for the possibility of chaining. */
41 /* We can handle things a number of ways; we can determine the entire
42 bitstream structure right off the bat, or find pieces on demand.
43 This example determines and caches structure for the entire
44 bitstream, but builds a virtual decoder on the fly when moving
45 between links in the chain. */
47 /* There are also different ways to implement seeking. Enough
48 information exists in an Ogg bitstream to seek to
49 sample-granularity positions in the output. Or, one can seek by
50 picking some portion of the stream roughly in the desired area if
51 we only want coarse navigation through the stream. */
53 /*************************************************************************
54 * Many, many internal helpers. The intention is not to be confusing;
55 * rampant duplication and monolithic function implementation would be
56 * harder to understand anyway. The high level functions are last. Begin
57 * grokking near the end of the file */
59 /* read a little more data from the file/pipe into the ogg_sync framer
61 #define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
62 over 8k gets what they deserve */
63 static long _get_data(OggVorbis_File *vf){
66 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
67 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
68 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
69 if(bytes==0 && errno)return(-1);
75 /* save a tiny smidge of verbosity to make the code more readable */
76 static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
78 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
80 ogg_sync_reset(&vf->oy);
82 /* shouldn't happen unless someone writes a broken callback */
87 /* The read/seek functions track absolute position within the stream */
89 /* from the head of the stream, get the next page. boundary specifies
90 if the function is allowed to fetch more data from the stream (and
91 how much) or only use internally buffered data.
93 boundary: -1) unbounded search
94 0) read no additional data; use cached only
95 n) search for a new page beginning for n bytes
97 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
98 n) found a page at absolute offset n */
100 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
101 ogg_int64_t boundary){
102 if(boundary>0)boundary+=vf->offset;
106 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
107 more=ogg_sync_pageseek(&vf->oy,og);
110 /* skipped n bytes */
114 /* send more paramedics */
115 if(!boundary)return(OV_FALSE);
117 long ret=_get_data(vf);
118 if(ret==0)return(OV_EOF);
119 if(ret<0)return(OV_EREAD);
122 /* got a page. Return the offset at the page beginning,
123 advance the internal offset past the page end */
124 ogg_int64_t ret=vf->offset;
133 /* find the latest page beginning before the current stream cursor
134 position. Much dirtier than the above as Ogg doesn't have any
135 backward search linkage. no 'readp' as it will certainly have to
137 /* returns offset or OV_EREAD, OV_FAULT */
138 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
139 ogg_int64_t begin=vf->offset;
140 ogg_int64_t end=begin;
142 ogg_int64_t offset=-1;
148 _seek_helper(vf,begin);
149 while(vf->offset<end){
150 ret=_get_next_page(vf,og,end-vf->offset);
151 if(ret==OV_EREAD)return(OV_EREAD);
160 /* we have the offset. Actually snork and hold the page now */
161 _seek_helper(vf,offset);
162 ret=_get_next_page(vf,og,CHUNKSIZE);
164 /* this shouldn't be possible */
170 /* finds each bitstream link one at a time using a bisection search
171 (has to begin by knowing the offset of the lb's initial page).
172 Recurses for each link so it can alloc the link storage after
173 finding them all, then unroll and fill the cache at the same time */
174 static int _bisect_forward_serialno(OggVorbis_File *vf,
176 ogg_int64_t searched,
180 ogg_int64_t endsearched=end;
181 ogg_int64_t next=end;
185 /* the below guards against garbage seperating the last and
186 first pages of two links. */
187 while(searched<endsearched){
190 if(endsearched-searched<CHUNKSIZE){
193 bisect=(searched+endsearched)/2;
196 _seek_helper(vf,bisect);
197 ret=_get_next_page(vf,&og,-1);
198 if(ret==OV_EREAD)return(OV_EREAD);
199 if(ret<0 || ogg_page_serialno(&og)!=currentno){
203 searched=ret+og.header_len+og.body_len;
207 _seek_helper(vf,next);
208 ret=_get_next_page(vf,&og,-1);
209 if(ret==OV_EREAD)return(OV_EREAD);
211 if(searched>=end || ret<0){
213 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
214 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
215 vf->offsets[m+1]=searched;
217 ret=_bisect_forward_serialno(vf,next,vf->offset,
218 end,ogg_page_serialno(&og),m+1);
219 if(ret==OV_EREAD)return(OV_EREAD);
222 vf->offsets[m]=begin;
223 vf->serialnos[m]=currentno;
227 /* uses the local ogg_stream storage in vf; this is important for
228 non-streaming input sources */
229 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
230 long *serialno,ogg_page *og_ptr){
236 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
237 if(llret==OV_EREAD)return(OV_EREAD);
238 if(llret<0)return OV_ENOTVORBIS;
242 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
243 if(serialno)*serialno=vf->os.serialno;
244 vf->ready_state=STREAMSET;
246 /* extract the initial header from the first page and verify that the
247 Ogg bitstream is in fact Vorbis data */
249 vorbis_info_init(vi);
250 vorbis_comment_init(vc);
254 ogg_stream_pagein(&vf->os,og_ptr);
256 int result=ogg_stream_packetout(&vf->os,&op);
262 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
268 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
276 vorbis_info_clear(vi);
277 vorbis_comment_clear(vc);
278 vf->ready_state=OPENED;
283 /* last step of the OggVorbis_File initialization; get all the
284 vorbis_info structs and PCM positions. Only called by the seekable
285 initialization (local stream storage is hacked slightly; pay
286 attention to how that's done) */
288 /* this is void and does not propogate errors up because we want to be
289 able to open and use damaged bitstreams as well as we can. Just
290 watch out for missing information for links in the OggVorbis_File
292 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
297 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
298 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
299 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
300 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
302 for(i=0;i<vf->links;i++){
304 /* we already grabbed the initial header earlier. Just set the offset */
305 vf->dataoffsets[i]=dataoffset;
306 _seek_helper(vf,dataoffset);
310 /* seek to the location of the initial header */
312 _seek_helper(vf,vf->offsets[i]);
313 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
314 vf->dataoffsets[i]=-1;
316 vf->dataoffsets[i]=vf->offset;
320 /* fetch beginning PCM offset */
322 if(vf->dataoffsets[i]!=-1){
323 ogg_int64_t accumulated=0;
327 ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]);
332 ret=_get_next_page(vf,&og,-1);
334 /* this should not be possible unless the file is
338 if(ogg_page_serialno(&og)!=vf->serialnos[i])
341 /* count blocksizes of all frames in the page */
342 ogg_stream_pagein(&vf->os,&og);
343 while((result=ogg_stream_packetout(&vf->os,&op))){
344 if(result>0){ /* ignore holes */
345 long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
347 accumulated+=(lastblock+thisblock)>>2;
352 if(ogg_page_granulepos(&og)!=-1){
353 /* pcm offset of last packet on the first audio page */
354 accumulated= ogg_page_granulepos(&og)-accumulated;
359 /* less than zero? This is a stream with samples trimmed off
360 the beginning, a normal occurrence; set the offset to zero */
361 if(accumulated<0)accumulated=0;
363 vf->pcmlengths[i*2]=accumulated;
366 /* get the PCM length of this link. To do this,
367 get the last page of the stream */
369 ogg_int64_t end=vf->offsets[i+1];
370 _seek_helper(vf,end);
373 ret=_get_prev_page(vf,&og);
375 /* this should not be possible */
376 vorbis_info_clear(vf->vi+i);
377 vorbis_comment_clear(vf->vc+i);
380 if(ogg_page_granulepos(&og)!=-1){
381 vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
390 static void _make_decode_ready(OggVorbis_File *vf){
391 if(vf->ready_state!=STREAMSET)return;
393 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
395 vorbis_synthesis_init(&vf->vd,vf->vi);
397 vorbis_block_init(&vf->vd,&vf->vb);
398 vf->ready_state=INITSET;
402 static int _open_seekable2(OggVorbis_File *vf){
403 long serialno=vf->current_serialno,end;
404 ogg_int64_t dataoffset=vf->offset;
407 /* we're partially open and have a first link header state in
409 /* we can seek, so set out learning all about this file */
410 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
411 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
413 /* We get the offset for the last page of the physical bitstream.
414 Most OggVorbis files will contain a single logical bitstream */
415 end=_get_prev_page(vf,&og);
416 if(end<0)return(end);
418 /* more than one logical bitstream? */
419 if(ogg_page_serialno(&og)!=serialno){
421 /* Chained bitstream. Bisect-search each logical bitstream
422 section. Do so based on serial number only */
423 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
427 /* Only one logical bitstream */
428 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
432 /* the initial header memory is referenced by vf after; don't free it */
433 _prefetch_all_headers(vf,dataoffset);
434 return(ov_raw_seek(vf,0));
437 /* clear out the current logical bitstream decoder */
438 static void _decode_clear(OggVorbis_File *vf){
439 vorbis_dsp_clear(&vf->vd);
440 vorbis_block_clear(&vf->vb);
441 vf->ready_state=OPENED;
447 /* fetch and process a packet. Handles the case where we're at a
448 bitstream boundary and dumps the decoding machine. If the decoding
449 machine is unloaded, it loads it. It also keeps pcm_offset up to
450 date (seek and read both use this. seek uses a special hack with
453 return: <0) error, OV_HOLE (lost packet) or OV_EOF
454 0) need more data (only if readp==0)
458 static int _fetch_and_process_packet(OggVorbis_File *vf,
463 /* handle one packet. Try to fetch it from current stream state */
464 /* extract packets from page */
467 /* process a packet if we can. If the machine isn't loaded,
469 if(vf->ready_state==INITSET){
472 ogg_packet *op_ptr=(op_in?op_in:&op);
473 int result=ogg_stream_packetout(&vf->os,op_ptr);
474 ogg_int64_t granulepos;
477 if(result==-1)return(OV_HOLE); /* hole in the data. */
479 /* got a packet. process it */
480 granulepos=op_ptr->granulepos;
481 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
483 header packets aren't
486 vorbis_synthesis will
489 /* suck in the synthesis data and track bitrate */
491 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
492 /* for proper use of libvorbis within libvorbisfile,
493 oldsamples will always be zero. */
494 if(oldsamples)return(OV_EFAULT);
496 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
497 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
498 vf->bittrack+=op_ptr->bytes*8;
501 /* update the pcm offset. */
502 if(granulepos!=-1 && !op_ptr->e_o_s){
503 int link=(vf->seekable?vf->current_link:0);
506 /* this packet has a pcm_offset on it (the last packet
507 completed on a page carries the offset) After processing
508 (above), we know the pcm position of the *last* sample
509 ready to be returned. Find the offset of the *first*
511 As an aside, this trick is inaccurate if we begin
512 reading anew right at the last page; the end-of-stream
513 granulepos declares the last frame in the stream, and the
514 last packet of the last page may be a partial frame.
515 So, we need a previous granulepos from an in-sequence page
516 to have a reference point. Thus the !op_ptr->e_o_s clause
519 granulepos-=vf->pcmlengths[link*2];
520 if(granulepos<0)granulepos=0; /* actually, this
521 shouldn't be possible
522 here unless the stream
525 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
529 granulepos+=vf->pcmlengths[i*2+1];
530 vf->pcm_offset=granulepos;
540 if(vf->ready_state>=OPENED){
542 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
544 /* bitrate tracking; add the header's bytes here, the body bytes
545 are done by packet above */
546 vf->bittrack+=og.header_len*8;
548 /* has our decoding just traversed a bitstream boundary? */
549 if(vf->ready_state==INITSET){
550 if(vf->current_serialno!=ogg_page_serialno(&og)){
554 vorbis_info_clear(vf->vi);
555 vorbis_comment_clear(vf->vc);
561 /* Do we need to load a new machine before submitting the page? */
562 /* This is different in the seekable and non-seekable cases.
564 In the seekable case, we already have all the header
565 information loaded and cached; we just initialize the machine
566 with it and continue on our merry way.
568 In the non-seekable (streaming) case, we'll only be at a
569 boundary if we just left the previous logical bitstream and
570 we're now nominally at the header of the next bitstream
573 if(vf->ready_state!=INITSET){
576 if(vf->ready_state<STREAMSET){
578 vf->current_serialno=ogg_page_serialno(&og);
580 /* match the serialno to bitstream section. We use this rather than
581 offset positions to avoid problems near logical bitstream
583 for(link=0;link<vf->links;link++)
584 if(vf->serialnos[link]==vf->current_serialno)break;
585 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
590 vf->current_link=link;
592 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
593 vf->ready_state=STREAMSET;
596 /* we're streaming */
597 /* fetch the three header packets, build the info struct */
599 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
606 _make_decode_ready(vf);
608 ogg_stream_pagein(&vf->os,&og);
612 /* if, eg, 64 bit stdio is configured by default, this will build with
614 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
615 if(f==NULL)return(-1);
616 return fseek(f,off,whence);
619 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
620 long ibytes, ov_callbacks callbacks){
621 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
624 memset(vf,0,sizeof(*vf));
626 vf->callbacks = callbacks;
628 /* init the framing state */
629 ogg_sync_init(&vf->oy);
631 /* perhaps some data was previously read into a buffer for testing
632 against other stream types. Allow initialization from this
633 previously read data (as we may be reading from a non-seekable
636 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
637 memcpy(buffer,initial,ibytes);
638 ogg_sync_wrote(&vf->oy,ibytes);
641 /* can we seek? Stevens suggests the seek test was portable */
642 if(offsettest!=-1)vf->seekable=1;
644 /* No seeking yet; Set up a 'single' (current) logical bitstream
645 entry for partial open */
647 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
648 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
649 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
651 /* Try to fetch the headers, maintaining all the storage */
652 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
655 }else if(vf->ready_state < PARTOPEN)
656 vf->ready_state=PARTOPEN;
660 static int _ov_open2(OggVorbis_File *vf){
661 if(vf->ready_state < OPENED)
662 vf->ready_state=OPENED;
664 int ret=_open_seekable2(vf);
675 /* clear out the OggVorbis_File struct */
676 int ov_clear(OggVorbis_File *vf){
678 vorbis_block_clear(&vf->vb);
679 vorbis_dsp_clear(&vf->vd);
680 ogg_stream_clear(&vf->os);
682 if(vf->vi && vf->links){
684 for(i=0;i<vf->links;i++){
685 vorbis_info_clear(vf->vi+i);
686 vorbis_comment_clear(vf->vc+i);
691 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
692 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
693 if(vf->serialnos)_ogg_free(vf->serialnos);
694 if(vf->offsets)_ogg_free(vf->offsets);
695 ogg_sync_clear(&vf->oy);
696 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
697 memset(vf,0,sizeof(*vf));
705 /* inspects the OggVorbis file and finds/documents all the logical
706 bitstreams contained in it. Tries to be tolerant of logical
707 bitstream sections that are truncated/woogie.
713 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
714 ov_callbacks callbacks){
715 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
717 return _ov_open2(vf);
720 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
721 ov_callbacks callbacks = {
722 (size_t (*)(void *, size_t, size_t, void *)) fread,
723 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
724 (int (*)(void *)) fclose,
725 (long (*)(void *)) ftell
728 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
731 /* Only partially open the vorbis file; test for Vorbisness, and load
732 the headers for the first chain. Do not seek (although test for
733 seekability). Use ov_test_open to finish opening the file, else
734 ov_clear to close/free it. Same return codes as open. */
736 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
737 ov_callbacks callbacks)
739 return _ov_open1(f,vf,initial,ibytes,callbacks);
742 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
743 ov_callbacks callbacks = {
744 (size_t (*)(void *, size_t, size_t, void *)) fread,
745 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
746 (int (*)(void *)) fclose,
747 (long (*)(void *)) ftell
750 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
753 int ov_test_open(OggVorbis_File *vf){
754 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
755 return _ov_open2(vf);
758 /* How many logical bitstreams in this physical bitstream? */
759 long ov_streams(OggVorbis_File *vf){
763 /* Is the FILE * associated with vf seekable? */
764 long ov_seekable(OggVorbis_File *vf){
768 /* returns the bitrate for a given logical bitstream or the entire
769 physical bitstream. If the file is open for random access, it will
770 find the *actual* average bitrate. If the file is streaming, it
771 returns the nominal bitrate (if set) else the average of the
772 upper/lower bounds (if set) else -1 (unset).
774 If you want the actual bitrate field settings, get them from the
775 vorbis_info structs */
777 long ov_bitrate(OggVorbis_File *vf,int i){
778 if(vf->ready_state<OPENED)return(OV_EINVAL);
779 if(i>=vf->links)return(OV_EINVAL);
780 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
784 for(i=0;i<vf->links;i++)
785 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
786 return(rint(bits/ov_time_total(vf,-1)));
789 /* return the actual bitrate */
790 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
792 /* return nominal if set */
793 if(vf->vi[i].bitrate_nominal>0){
794 return vf->vi[i].bitrate_nominal;
796 if(vf->vi[i].bitrate_upper>0){
797 if(vf->vi[i].bitrate_lower>0){
798 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
800 return vf->vi[i].bitrate_upper;
809 /* returns the actual bitrate since last call. returns -1 if no
810 additional data to offer since last call (or at beginning of stream),
811 EINVAL if stream is only partially open
813 long ov_bitrate_instant(OggVorbis_File *vf){
814 int link=(vf->seekable?vf->current_link:0);
816 if(vf->ready_state<OPENED)return(OV_EINVAL);
817 if(vf->samptrack==0)return(OV_FALSE);
818 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
825 long ov_serialnumber(OggVorbis_File *vf,int i){
826 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
827 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
829 return(vf->current_serialno);
831 return(vf->serialnos[i]);
835 /* returns: total raw (compressed) length of content if i==-1
836 raw (compressed) length of that logical bitstream for i==0 to n
837 OV_EINVAL if the stream is not seekable (we can't know the length)
838 or if stream is only partially open
840 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
841 if(vf->ready_state<OPENED)return(OV_EINVAL);
842 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
846 for(i=0;i<vf->links;i++)
847 acc+=ov_raw_total(vf,i);
850 return(vf->offsets[i+1]-vf->offsets[i]);
854 /* returns: total PCM length (samples) of content if i==-1 PCM length
855 (samples) of that logical bitstream for i==0 to n
856 OV_EINVAL if the stream is not seekable (we can't know the
857 length) or only partially open
859 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
860 if(vf->ready_state<OPENED)return(OV_EINVAL);
861 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
865 for(i=0;i<vf->links;i++)
866 acc+=ov_pcm_total(vf,i);
869 return(vf->pcmlengths[i*2+1]);
873 /* returns: total seconds of content if i==-1
874 seconds in that logical bitstream for i==0 to n
875 OV_EINVAL if the stream is not seekable (we can't know the
876 length) or only partially open
878 double ov_time_total(OggVorbis_File *vf,int i){
879 if(vf->ready_state<OPENED)return(OV_EINVAL);
880 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
884 for(i=0;i<vf->links;i++)
885 acc+=ov_time_total(vf,i);
888 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
892 /* seek to an offset relative to the *compressed* data. This also
893 scans packets to update the PCM cursor. It will cross a logical
894 bitstream boundary, but only if it can't get any packets out of the
895 tail of the bitstream we seek to (so no surprises).
897 returns zero on success, nonzero on failure */
899 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
900 ogg_stream_state work_os;
902 if(vf->ready_state<OPENED)return(OV_EINVAL);
904 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
906 if(pos<0 || pos>vf->end)return(OV_EINVAL);
908 /* clear out decoding machine state */
912 _seek_helper(vf,pos);
914 /* we need to make sure the pcm_offset is set, but we don't want to
915 advance the raw cursor past good packets just to get to the first
916 with a granulepos. That's not equivalent behavior to beginning
917 decoding as immediately after the seek position as possible.
919 So, a hack. We use two stream states; a local scratch state and
920 a the shared vf->os stream state. We use the local state to
921 scan, and the shared state as a buffer for later decode.
923 Unfortuantely, on the last page we still advance to last packet
924 because the granulepos on the last page is not necessarily on a
925 packet boundary, and we need to make sure the granpos is
937 ogg_stream_init(&work_os,-1); /* get the memory ready */
940 if(vf->ready_state==STREAMSET){
941 /* snarf/scan a packet if we can */
942 int result=ogg_stream_packetout(&work_os,&op);
946 if(vf->vi[vf->current_link].codec_setup)
947 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
949 ogg_stream_packetout(&vf->os,NULL);
951 if(lastblock)accblock+=(lastblock+thisblock)>>2;
953 if(op.granulepos!=-1){
954 int i,link=vf->current_link;
955 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
956 if(granulepos<0)granulepos=0;
959 granulepos+=vf->pcmlengths[i*2+1];
960 vf->pcm_offset=granulepos-accblock;
969 if(_get_next_page(vf,&og,-1)<0){
970 vf->pcm_offset=ov_pcm_total(vf,-1);
974 /* huh? Bogus stream with packets but no granulepos */
979 /* has our decoding just traversed a bitstream boundary? */
980 if(vf->ready_state==STREAMSET)
981 if(vf->current_serialno!=ogg_page_serialno(&og)){
982 _decode_clear(vf); /* clear out stream state */
983 ogg_stream_clear(&work_os);
986 if(vf->ready_state<STREAMSET){
989 vf->current_serialno=ogg_page_serialno(&og);
990 for(link=0;link<vf->links;link++)
991 if(vf->serialnos[link]==vf->current_serialno)break;
992 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
994 machine uninitialized */
995 vf->current_link=link;
997 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
998 ogg_stream_reset_serialno(&work_os,vf->current_serialno);
999 vf->ready_state=STREAMSET;
1003 ogg_stream_pagein(&vf->os,&og);
1004 ogg_stream_pagein(&work_os,&og);
1005 eosflag=ogg_page_eos(&og);
1009 ogg_stream_clear(&work_os);
1013 /* dump the machine so we're in a known state */
1015 ogg_stream_clear(&work_os);
1020 /* Page granularity seek (faster than sample granularity because we
1021 don't do the last bit of decode to find a specific sample).
1023 Seek to the last [granule marked] page preceeding the specified pos
1024 location, such that decoding past the returned point will quickly
1025 arrive at the requested position. */
1026 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1029 ogg_int64_t total=ov_pcm_total(vf,-1);
1031 if(vf->ready_state<OPENED)return(OV_EINVAL);
1032 if(!vf->seekable)return(OV_ENOSEEK);
1034 if(pos<0 || pos>total)return(OV_EINVAL);
1036 /* which bitstream section does this pcm offset occur in? */
1037 for(link=vf->links-1;link>=0;link--){
1038 total-=vf->pcmlengths[link*2+1];
1039 if(pos>=total)break;
1042 /* search within the logical bitstream for the page with the highest
1043 pcm_pos preceeding (or equal to) pos. There is a danger here;
1044 missing pages or incorrect frame number information in the
1045 bitstream could make our task impossible. Account for that (it
1046 would be an error condition) */
1048 /* new search algorithm by HB (Nicholas Vinen) */
1050 ogg_int64_t end=vf->offsets[link+1];
1051 ogg_int64_t begin=vf->offsets[link];
1052 ogg_int64_t begintime = vf->pcmlengths[link*2];
1053 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1054 ogg_int64_t target=pos-total+begintime;
1055 ogg_int64_t best=begin;
1061 if(end-begin<CHUNKSIZE){
1064 /* take a (pretty decent) guess. */
1066 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1071 _seek_helper(vf,bisect);
1074 result=_get_next_page(vf,&og,end-vf->offset);
1075 if(result==OV_EREAD) goto seek_error;
1078 end=begin; /* found it */
1080 if(bisect==0)goto seek_error;
1082 if(bisect<=begin)bisect=begin+1;
1083 _seek_helper(vf,bisect);
1086 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1087 if(granulepos==-1)continue;
1088 if(granulepos<target){
1089 best=result; /* raw offset of packet with granulepos */
1090 begin=vf->offset; /* raw offset of next page */
1091 begintime=granulepos;
1093 if(target-begintime>44100)break;
1094 bisect=begin; /* *not* begin + 1 */
1097 end=begin; /* found it */
1099 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1101 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1102 if(bisect<=begin)bisect=begin+1;
1103 _seek_helper(vf,bisect);
1115 /* found our page. seek to it, update pcm offset. Easier case than
1116 raw_seek, don't keep packets preceeding granulepos. */
1120 /* clear out decoding machine state */
1123 _seek_helper(vf,best);
1125 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1126 vf->current_serialno=ogg_page_serialno(&og);
1127 vf->current_link=link;
1129 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1130 vf->ready_state=STREAMSET;
1131 ogg_stream_pagein(&vf->os,&og);
1133 /* pull out all but last packet; the one with granulepos */
1135 result=ogg_stream_packetpeek(&vf->os,&op);
1137 /* !!! the packet finishing this page originated on a
1138 preceeding page. Keep fetching previous pages until we
1139 get one with a granulepos or without the 'continued' flag
1140 set. Then just use raw_seek for simplicity. */
1143 _seek_helper(vf,best);
1146 result=_get_prev_page(vf,&og);
1147 if(result<0)goto seek_error;
1148 if(ogg_page_granulepos(&og)>-1 ||
1149 !ogg_page_continued(&og)){
1150 return ov_raw_seek(vf,result);
1155 if(result<0)goto seek_error;
1156 if(op.granulepos!=-1){
1157 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1158 if(vf->pcm_offset<0)vf->pcm_offset=0;
1159 vf->pcm_offset+=total;
1162 result=ogg_stream_packetout(&vf->os,NULL);
1168 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1175 /* dump machine so we're in a known state */
1181 /* seek to a sample offset relative to the decompressed pcm stream
1182 returns zero on success, nonzero on failure */
1184 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1185 int thisblock,lastblock=0;
1186 int ret=ov_pcm_seek_page(vf,pos);
1187 if(ret<0)return(ret);
1188 _make_decode_ready(vf);
1190 /* discard leading packets we don't need for the lapping of the
1191 position we want; don't decode them */
1197 int ret=ogg_stream_packetpeek(&vf->os,&op);
1199 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1200 if(thisblock<0)thisblock=0; /* non audio packet */
1201 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1203 if(vf->pcm_offset+((thisblock+
1204 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1206 /* remove the packet from packet queue and track its granulepos */
1207 ogg_stream_packetout(&vf->os,NULL);
1208 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1211 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1213 /* end of logical stream case is hard, especially with exact
1214 length positioning. */
1216 if(op.granulepos>-1){
1218 /* always believe the stream markers */
1219 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1220 if(vf->pcm_offset<0)vf->pcm_offset=0;
1221 for(i=0;i<vf->current_link;i++)
1222 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1225 lastblock=thisblock;
1228 if(ret<0 && ret!=OV_HOLE)break;
1230 /* suck in a new page */
1231 if(_get_next_page(vf,&og,-1)<0)break;
1232 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1234 if(vf->ready_state<STREAMSET){
1237 vf->current_serialno=ogg_page_serialno(&og);
1238 for(link=0;link<vf->links;link++)
1239 if(vf->serialnos[link]==vf->current_serialno)break;
1240 if(link==vf->links)return(OV_EBADLINK);
1241 vf->current_link=link;
1243 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1244 vf->ready_state=STREAMSET;
1245 _make_decode_ready(vf);
1249 ogg_stream_pagein(&vf->os,&og);
1253 /* discard samples until we reach the desired position. Crossing a
1254 logical bitstream boundary with abandon is OK. */
1255 while(vf->pcm_offset<pos){
1257 ogg_int64_t target=pos-vf->pcm_offset;
1258 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1260 if(samples>target)samples=target;
1261 vorbis_synthesis_read(&vf->vd,samples);
1262 vf->pcm_offset+=samples;
1265 if(_fetch_and_process_packet(vf,NULL,1)<=0)
1266 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1271 /* seek to a playback time relative to the decompressed pcm stream
1272 returns zero on success, nonzero on failure */
1273 int ov_time_seek(OggVorbis_File *vf,double seconds){
1274 /* translate time to PCM position and call ov_pcm_seek */
1277 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1278 double time_total=ov_time_total(vf,-1);
1280 if(vf->ready_state<OPENED)return(OV_EINVAL);
1281 if(!vf->seekable)return(OV_ENOSEEK);
1282 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1284 /* which bitstream section does this time offset occur in? */
1285 for(link=vf->links-1;link>=0;link--){
1286 pcm_total-=vf->pcmlengths[link*2+1];
1287 time_total-=ov_time_total(vf,link);
1288 if(seconds>=time_total)break;
1291 /* enough information to convert time offset to pcm offset */
1293 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1294 return(ov_pcm_seek(vf,target));
1298 /* page-granularity version of ov_time_seek
1299 returns zero on success, nonzero on failure */
1300 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1301 /* translate time to PCM position and call ov_pcm_seek */
1304 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1305 double time_total=ov_time_total(vf,-1);
1307 if(vf->ready_state<OPENED)return(OV_EINVAL);
1308 if(!vf->seekable)return(OV_ENOSEEK);
1309 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1311 /* which bitstream section does this time offset occur in? */
1312 for(link=vf->links-1;link>=0;link--){
1313 pcm_total-=vf->pcmlengths[link*2+1];
1314 time_total-=ov_time_total(vf,link);
1315 if(seconds>=time_total)break;
1318 /* enough information to convert time offset to pcm offset */
1320 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1321 return(ov_pcm_seek_page(vf,target));
1325 /* tell the current stream offset cursor. Note that seek followed by
1326 tell will likely not give the set offset due to caching */
1327 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1328 if(vf->ready_state<OPENED)return(OV_EINVAL);
1332 /* return PCM offset (sample) of next PCM sample to be read */
1333 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1334 if(vf->ready_state<OPENED)return(OV_EINVAL);
1335 return(vf->pcm_offset);
1338 /* return time offset (seconds) of next PCM sample to be read */
1339 double ov_time_tell(OggVorbis_File *vf){
1340 /* translate time to PCM position and call ov_pcm_seek */
1343 ogg_int64_t pcm_total=0;
1344 double time_total=0.f;
1346 if(vf->ready_state<OPENED)return(OV_EINVAL);
1348 pcm_total=ov_pcm_total(vf,-1);
1349 time_total=ov_time_total(vf,-1);
1351 /* which bitstream section does this time offset occur in? */
1352 for(link=vf->links-1;link>=0;link--){
1353 pcm_total-=vf->pcmlengths[link*2+1];
1354 time_total-=ov_time_total(vf,link);
1355 if(vf->pcm_offset>=pcm_total)break;
1359 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1362 /* link: -1) return the vorbis_info struct for the bitstream section
1363 currently being decoded
1364 0-n) to request information for a specific bitstream section
1366 In the case of a non-seekable bitstream, any call returns the
1367 current bitstream. NULL in the case that the machine is not
1370 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1373 if(vf->ready_state>=STREAMSET)
1374 return vf->vi+vf->current_link;
1387 /* grr, strong typing, grr, no templates/inheritence, grr */
1388 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1391 if(vf->ready_state>=STREAMSET)
1392 return vf->vc+vf->current_link;
1405 static int host_is_big_endian() {
1406 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1407 unsigned char *bytewise = (unsigned char *)&pattern;
1408 if (bytewise[0] == 0xfe) return 1;
1412 /* up to this point, everything could more or less hide the multiple
1413 logical bitstream nature of chaining from the toplevel application
1414 if the toplevel application didn't particularly care. However, at
1415 the point that we actually read audio back, the multiple-section
1416 nature must surface: Multiple bitstream sections do not necessarily
1417 have to have the same number of channels or sampling rate.
1419 ov_read returns the sequential logical bitstream number currently
1420 being decoded along with the PCM data in order that the toplevel
1421 application can take action on channel/sample rate changes. This
1422 number will be incremented even for streamed (non-seekable) streams
1423 (for seekable streams, it represents the actual logical bitstream
1424 index within the physical bitstream. Note that the accessor
1425 functions above are aware of this dichotomy).
1427 input values: buffer) a buffer to hold packed PCM data for return
1428 length) the byte length requested to be placed into buffer
1429 bigendianp) should the data be packed LSB first (0) or
1431 word) word size for output. currently 1 (byte) or
1434 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1436 n) number of bytes of PCM actually returned. The
1437 below works on a packet-by-packet basis, so the
1438 return length is not related to the 'length' passed
1439 in, just guaranteed to fit.
1441 *section) set to the logical bitstream number */
1443 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1444 int bigendianp,int word,int sgned,int *bitstream){
1446 int host_endian = host_is_big_endian();
1451 if(vf->ready_state<OPENED)return(OV_EINVAL);
1454 if(vf->ready_state>=STREAMSET){
1455 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1459 /* suck in another packet */
1461 int ret=_fetch_and_process_packet(vf,NULL,1);
1462 if(ret==OV_EOF)return(0);
1463 if(ret<=0)return(ret);
1470 /* yay! proceed to pack data into the byte buffer */
1472 long channels=ov_info(vf,-1)->channels;
1473 long bytespersample=word * channels;
1474 vorbis_fpu_control fpu;
1475 if(samples>length/bytespersample)samples=length/bytespersample;
1477 /* a tight loop to pack each size */
1481 int off=(sgned?0:128);
1482 vorbis_fpu_setround(&fpu);
1483 for(j=0;j<samples;j++)
1484 for(i=0;i<channels;i++){
1485 val=vorbis_ftoi(pcm[i][j]*128.f);
1487 else if(val<-128)val=-128;
1490 vorbis_fpu_restore(fpu);
1492 int off=(sgned?0:32768);
1494 if(host_endian==bigendianp){
1497 vorbis_fpu_setround(&fpu);
1498 for(i=0;i<channels;i++) { /* It's faster in this order */
1500 short *dest=((short *)buffer)+i;
1501 for(j=0;j<samples;j++) {
1502 val=vorbis_ftoi(src[j]*32768.f);
1503 if(val>32767)val=32767;
1504 else if(val<-32768)val=-32768;
1509 vorbis_fpu_restore(fpu);
1513 vorbis_fpu_setround(&fpu);
1514 for(i=0;i<channels;i++) {
1516 short *dest=((short *)buffer)+i;
1517 for(j=0;j<samples;j++) {
1518 val=vorbis_ftoi(src[j]*32768.f);
1519 if(val>32767)val=32767;
1520 else if(val<-32768)val=-32768;
1525 vorbis_fpu_restore(fpu);
1528 }else if(bigendianp){
1530 vorbis_fpu_setround(&fpu);
1531 for(j=0;j<samples;j++)
1532 for(i=0;i<channels;i++){
1533 val=vorbis_ftoi(pcm[i][j]*32768.f);
1534 if(val>32767)val=32767;
1535 else if(val<-32768)val=-32768;
1538 *buffer++=(val&0xff);
1540 vorbis_fpu_restore(fpu);
1544 vorbis_fpu_setround(&fpu);
1545 for(j=0;j<samples;j++)
1546 for(i=0;i<channels;i++){
1547 val=vorbis_ftoi(pcm[i][j]*32768.f);
1548 if(val>32767)val=32767;
1549 else if(val<-32768)val=-32768;
1551 *buffer++=(val&0xff);
1554 vorbis_fpu_restore(fpu);
1560 vorbis_synthesis_read(&vf->vd,samples);
1561 vf->pcm_offset+=samples;
1562 if(bitstream)*bitstream=vf->current_link;
1563 return(samples*bytespersample);
1569 /* input values: pcm_channels) a float vector per channel of output
1570 length) the sample length being read by the app
1572 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1574 n) number of samples of PCM actually returned. The
1575 below works on a packet-by-packet basis, so the
1576 return length is not related to the 'length' passed
1577 in, just guaranteed to fit.
1579 *section) set to the logical bitstream number */
1583 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1586 if(vf->ready_state<OPENED)return(OV_EINVAL);
1589 if(vf->ready_state>=STREAMSET){
1591 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1593 if(pcm_channels)*pcm_channels=pcm;
1594 if(samples>length)samples=length;
1595 vorbis_synthesis_read(&vf->vd,samples);
1596 vf->pcm_offset+=samples;
1597 if(bitstream)*bitstream=vf->current_link;
1603 /* suck in another packet */
1605 int ret=_fetch_and_process_packet(vf,NULL,1);
1606 if(ret==OV_EOF)return(0);
1607 if(ret<=0)return(ret);