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.64 2002/10/26 13:37:03 msmith 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;
404 ogg_int64_t dataoffset=vf->offset, end;
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 if(vf->seekable && link>0)
520 granulepos-=vf->pcmlengths[link*2];
521 if(granulepos<0)granulepos=0; /* actually, this
522 shouldn't be possible
523 here unless the stream
526 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
530 granulepos+=vf->pcmlengths[i*2+1];
531 vf->pcm_offset=granulepos;
541 if(vf->ready_state>=OPENED){
543 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
545 /* bitrate tracking; add the header's bytes here, the body bytes
546 are done by packet above */
547 vf->bittrack+=og.header_len*8;
549 /* has our decoding just traversed a bitstream boundary? */
550 if(vf->ready_state==INITSET){
551 if(vf->current_serialno!=ogg_page_serialno(&og)){
555 vorbis_info_clear(vf->vi);
556 vorbis_comment_clear(vf->vc);
562 /* Do we need to load a new machine before submitting the page? */
563 /* This is different in the seekable and non-seekable cases.
565 In the seekable case, we already have all the header
566 information loaded and cached; we just initialize the machine
567 with it and continue on our merry way.
569 In the non-seekable (streaming) case, we'll only be at a
570 boundary if we just left the previous logical bitstream and
571 we're now nominally at the header of the next bitstream
574 if(vf->ready_state!=INITSET){
577 if(vf->ready_state<STREAMSET){
579 vf->current_serialno=ogg_page_serialno(&og);
581 /* match the serialno to bitstream section. We use this rather than
582 offset positions to avoid problems near logical bitstream
584 for(link=0;link<vf->links;link++)
585 if(vf->serialnos[link]==vf->current_serialno)break;
586 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
591 vf->current_link=link;
593 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
594 vf->ready_state=STREAMSET;
597 /* we're streaming */
598 /* fetch the three header packets, build the info struct */
600 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
607 _make_decode_ready(vf);
609 ogg_stream_pagein(&vf->os,&og);
613 /* if, eg, 64 bit stdio is configured by default, this will build with
615 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
616 if(f==NULL)return(-1);
617 return fseek(f,off,whence);
620 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
621 long ibytes, ov_callbacks callbacks){
622 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
625 memset(vf,0,sizeof(*vf));
627 vf->callbacks = callbacks;
629 /* init the framing state */
630 ogg_sync_init(&vf->oy);
632 /* perhaps some data was previously read into a buffer for testing
633 against other stream types. Allow initialization from this
634 previously read data (as we may be reading from a non-seekable
637 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
638 memcpy(buffer,initial,ibytes);
639 ogg_sync_wrote(&vf->oy,ibytes);
642 /* can we seek? Stevens suggests the seek test was portable */
643 if(offsettest!=-1)vf->seekable=1;
645 /* No seeking yet; Set up a 'single' (current) logical bitstream
646 entry for partial open */
648 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
649 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
650 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
652 /* Try to fetch the headers, maintaining all the storage */
653 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
656 }else if(vf->ready_state < PARTOPEN)
657 vf->ready_state=PARTOPEN;
661 static int _ov_open2(OggVorbis_File *vf){
662 if(vf->ready_state < OPENED)
663 vf->ready_state=OPENED;
665 int ret=_open_seekable2(vf);
676 /* clear out the OggVorbis_File struct */
677 int ov_clear(OggVorbis_File *vf){
679 vorbis_block_clear(&vf->vb);
680 vorbis_dsp_clear(&vf->vd);
681 ogg_stream_clear(&vf->os);
683 if(vf->vi && vf->links){
685 for(i=0;i<vf->links;i++){
686 vorbis_info_clear(vf->vi+i);
687 vorbis_comment_clear(vf->vc+i);
692 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
693 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
694 if(vf->serialnos)_ogg_free(vf->serialnos);
695 if(vf->offsets)_ogg_free(vf->offsets);
696 ogg_sync_clear(&vf->oy);
697 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
698 memset(vf,0,sizeof(*vf));
706 /* inspects the OggVorbis file and finds/documents all the logical
707 bitstreams contained in it. Tries to be tolerant of logical
708 bitstream sections that are truncated/woogie.
714 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
715 ov_callbacks callbacks){
716 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
718 return _ov_open2(vf);
721 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
722 ov_callbacks callbacks = {
723 (size_t (*)(void *, size_t, size_t, void *)) fread,
724 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
725 (int (*)(void *)) fclose,
726 (long (*)(void *)) ftell
729 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
732 /* Only partially open the vorbis file; test for Vorbisness, and load
733 the headers for the first chain. Do not seek (although test for
734 seekability). Use ov_test_open to finish opening the file, else
735 ov_clear to close/free it. Same return codes as open. */
737 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
738 ov_callbacks callbacks)
740 return _ov_open1(f,vf,initial,ibytes,callbacks);
743 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
744 ov_callbacks callbacks = {
745 (size_t (*)(void *, size_t, size_t, void *)) fread,
746 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
747 (int (*)(void *)) fclose,
748 (long (*)(void *)) ftell
751 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
754 int ov_test_open(OggVorbis_File *vf){
755 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
756 return _ov_open2(vf);
759 /* How many logical bitstreams in this physical bitstream? */
760 long ov_streams(OggVorbis_File *vf){
764 /* Is the FILE * associated with vf seekable? */
765 long ov_seekable(OggVorbis_File *vf){
769 /* returns the bitrate for a given logical bitstream or the entire
770 physical bitstream. If the file is open for random access, it will
771 find the *actual* average bitrate. If the file is streaming, it
772 returns the nominal bitrate (if set) else the average of the
773 upper/lower bounds (if set) else -1 (unset).
775 If you want the actual bitrate field settings, get them from the
776 vorbis_info structs */
778 long ov_bitrate(OggVorbis_File *vf,int i){
779 if(vf->ready_state<OPENED)return(OV_EINVAL);
780 if(i>=vf->links)return(OV_EINVAL);
781 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
786 for(i=0;i<vf->links;i++)
787 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
788 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
789 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
790 * so this is slightly transformed to make it work.
792 br = bits/ov_time_total(vf,-1);
796 /* return the actual bitrate */
797 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
799 /* return nominal if set */
800 if(vf->vi[i].bitrate_nominal>0){
801 return vf->vi[i].bitrate_nominal;
803 if(vf->vi[i].bitrate_upper>0){
804 if(vf->vi[i].bitrate_lower>0){
805 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
807 return vf->vi[i].bitrate_upper;
816 /* returns the actual bitrate since last call. returns -1 if no
817 additional data to offer since last call (or at beginning of stream),
818 EINVAL if stream is only partially open
820 long ov_bitrate_instant(OggVorbis_File *vf){
821 int link=(vf->seekable?vf->current_link:0);
823 if(vf->ready_state<OPENED)return(OV_EINVAL);
824 if(vf->samptrack==0)return(OV_FALSE);
825 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
832 long ov_serialnumber(OggVorbis_File *vf,int i){
833 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
834 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
836 return(vf->current_serialno);
838 return(vf->serialnos[i]);
842 /* returns: total raw (compressed) length of content if i==-1
843 raw (compressed) length of that logical bitstream for i==0 to n
844 OV_EINVAL if the stream is not seekable (we can't know the length)
845 or if stream is only partially open
847 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
848 if(vf->ready_state<OPENED)return(OV_EINVAL);
849 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
853 for(i=0;i<vf->links;i++)
854 acc+=ov_raw_total(vf,i);
857 return(vf->offsets[i+1]-vf->offsets[i]);
861 /* returns: total PCM length (samples) of content if i==-1 PCM length
862 (samples) of that logical bitstream for i==0 to n
863 OV_EINVAL if the stream is not seekable (we can't know the
864 length) or only partially open
866 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
867 if(vf->ready_state<OPENED)return(OV_EINVAL);
868 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
872 for(i=0;i<vf->links;i++)
873 acc+=ov_pcm_total(vf,i);
876 return(vf->pcmlengths[i*2+1]);
880 /* returns: total seconds of content if i==-1
881 seconds in that logical bitstream for i==0 to n
882 OV_EINVAL if the stream is not seekable (we can't know the
883 length) or only partially open
885 double ov_time_total(OggVorbis_File *vf,int i){
886 if(vf->ready_state<OPENED)return(OV_EINVAL);
887 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
891 for(i=0;i<vf->links;i++)
892 acc+=ov_time_total(vf,i);
895 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
899 /* seek to an offset relative to the *compressed* data. This also
900 scans packets to update the PCM cursor. It will cross a logical
901 bitstream boundary, but only if it can't get any packets out of the
902 tail of the bitstream we seek to (so no surprises).
904 returns zero on success, nonzero on failure */
906 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
907 ogg_stream_state work_os;
909 if(vf->ready_state<OPENED)return(OV_EINVAL);
911 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
913 if(pos<0 || pos>vf->end)return(OV_EINVAL);
915 /* clear out decoding machine state */
919 _seek_helper(vf,pos);
921 /* we need to make sure the pcm_offset is set, but we don't want to
922 advance the raw cursor past good packets just to get to the first
923 with a granulepos. That's not equivalent behavior to beginning
924 decoding as immediately after the seek position as possible.
926 So, a hack. We use two stream states; a local scratch state and
927 a the shared vf->os stream state. We use the local state to
928 scan, and the shared state as a buffer for later decode.
930 Unfortuantely, on the last page we still advance to last packet
931 because the granulepos on the last page is not necessarily on a
932 packet boundary, and we need to make sure the granpos is
944 ogg_stream_init(&work_os,-1); /* get the memory ready */
947 if(vf->ready_state==STREAMSET){
948 /* snarf/scan a packet if we can */
949 int result=ogg_stream_packetout(&work_os,&op);
953 if(vf->vi[vf->current_link].codec_setup)
954 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
956 ogg_stream_packetout(&vf->os,NULL);
958 if(lastblock)accblock+=(lastblock+thisblock)>>2;
960 if(op.granulepos!=-1){
961 int i,link=vf->current_link;
962 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
963 if(granulepos<0)granulepos=0;
966 granulepos+=vf->pcmlengths[i*2+1];
967 vf->pcm_offset=granulepos-accblock;
976 if(_get_next_page(vf,&og,-1)<0){
977 vf->pcm_offset=ov_pcm_total(vf,-1);
981 /* huh? Bogus stream with packets but no granulepos */
986 /* has our decoding just traversed a bitstream boundary? */
987 if(vf->ready_state==STREAMSET)
988 if(vf->current_serialno!=ogg_page_serialno(&og)){
989 _decode_clear(vf); /* clear out stream state */
990 ogg_stream_clear(&work_os);
993 if(vf->ready_state<STREAMSET){
996 vf->current_serialno=ogg_page_serialno(&og);
997 for(link=0;link<vf->links;link++)
998 if(vf->serialnos[link]==vf->current_serialno)break;
999 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1001 machine uninitialized */
1002 vf->current_link=link;
1004 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1005 ogg_stream_reset_serialno(&work_os,vf->current_serialno);
1006 vf->ready_state=STREAMSET;
1010 ogg_stream_pagein(&vf->os,&og);
1011 ogg_stream_pagein(&work_os,&og);
1012 eosflag=ogg_page_eos(&og);
1016 ogg_stream_clear(&work_os);
1020 /* dump the machine so we're in a known state */
1022 ogg_stream_clear(&work_os);
1027 /* Page granularity seek (faster than sample granularity because we
1028 don't do the last bit of decode to find a specific sample).
1030 Seek to the last [granule marked] page preceeding the specified pos
1031 location, such that decoding past the returned point will quickly
1032 arrive at the requested position. */
1033 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1035 ogg_int64_t result=0;
1036 ogg_int64_t total=ov_pcm_total(vf,-1);
1038 if(vf->ready_state<OPENED)return(OV_EINVAL);
1039 if(!vf->seekable)return(OV_ENOSEEK);
1041 if(pos<0 || pos>total)return(OV_EINVAL);
1043 /* which bitstream section does this pcm offset occur in? */
1044 for(link=vf->links-1;link>=0;link--){
1045 total-=vf->pcmlengths[link*2+1];
1046 if(pos>=total)break;
1049 /* search within the logical bitstream for the page with the highest
1050 pcm_pos preceeding (or equal to) pos. There is a danger here;
1051 missing pages or incorrect frame number information in the
1052 bitstream could make our task impossible. Account for that (it
1053 would be an error condition) */
1055 /* new search algorithm by HB (Nicholas Vinen) */
1057 ogg_int64_t end=vf->offsets[link+1];
1058 ogg_int64_t begin=vf->offsets[link];
1059 ogg_int64_t begintime = vf->pcmlengths[link*2];
1060 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1061 ogg_int64_t target=pos-total+begintime;
1062 ogg_int64_t best=begin;
1068 if(end-begin<CHUNKSIZE){
1071 /* take a (pretty decent) guess. */
1073 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1078 _seek_helper(vf,bisect);
1081 result=_get_next_page(vf,&og,end-vf->offset);
1082 if(result==OV_EREAD) goto seek_error;
1085 end=begin; /* found it */
1087 if(bisect==0) goto seek_error;
1089 if(bisect<=begin)bisect=begin+1;
1090 _seek_helper(vf,bisect);
1093 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1094 if(granulepos==-1)continue;
1095 if(granulepos<target){
1096 best=result; /* raw offset of packet with granulepos */
1097 begin=vf->offset; /* raw offset of next page */
1098 begintime=granulepos;
1100 if(target-begintime>44100)break;
1101 bisect=begin; /* *not* begin + 1 */
1104 end=begin; /* found it */
1106 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1108 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1109 if(bisect<=begin)bisect=begin+1;
1110 _seek_helper(vf,bisect);
1122 /* found our page. seek to it, update pcm offset. Easier case than
1123 raw_seek, don't keep packets preceeding granulepos. */
1127 /* clear out decoding machine state */
1130 _seek_helper(vf,best);
1132 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1133 vf->current_serialno=ogg_page_serialno(&og);
1134 vf->current_link=link;
1136 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1137 vf->ready_state=STREAMSET;
1138 ogg_stream_pagein(&vf->os,&og);
1140 /* pull out all but last packet; the one with granulepos */
1142 result=ogg_stream_packetpeek(&vf->os,&op);
1144 /* !!! the packet finishing this page originated on a
1145 preceeding page. Keep fetching previous pages until we
1146 get one with a granulepos or without the 'continued' flag
1147 set. Then just use raw_seek for simplicity. */
1150 _seek_helper(vf,best);
1153 result=_get_prev_page(vf,&og);
1154 if(result<0) goto seek_error;
1155 if(ogg_page_granulepos(&og)>-1 ||
1156 !ogg_page_continued(&og)){
1157 return ov_raw_seek(vf,result);
1163 result = OV_EBADPACKET;
1166 if(op.granulepos!=-1){
1167 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1168 if(vf->pcm_offset<0)vf->pcm_offset=0;
1169 vf->pcm_offset+=total;
1172 result=ogg_stream_packetout(&vf->os,NULL);
1178 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1185 /* dump machine so we're in a known state */
1191 /* seek to a sample offset relative to the decompressed pcm stream
1192 returns zero on success, nonzero on failure */
1194 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1195 int thisblock,lastblock=0;
1196 int ret=ov_pcm_seek_page(vf,pos);
1197 if(ret<0)return(ret);
1198 _make_decode_ready(vf);
1200 /* discard leading packets we don't need for the lapping of the
1201 position we want; don't decode them */
1207 int ret=ogg_stream_packetpeek(&vf->os,&op);
1209 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1210 if(thisblock<0)thisblock=0; /* non audio packet */
1211 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1213 if(vf->pcm_offset+((thisblock+
1214 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1216 /* remove the packet from packet queue and track its granulepos */
1217 ogg_stream_packetout(&vf->os,NULL);
1218 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1221 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1223 /* end of logical stream case is hard, especially with exact
1224 length positioning. */
1226 if(op.granulepos>-1){
1228 /* always believe the stream markers */
1229 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1230 if(vf->pcm_offset<0)vf->pcm_offset=0;
1231 for(i=0;i<vf->current_link;i++)
1232 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1235 lastblock=thisblock;
1238 if(ret<0 && ret!=OV_HOLE)break;
1240 /* suck in a new page */
1241 if(_get_next_page(vf,&og,-1)<0)break;
1242 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1244 if(vf->ready_state<STREAMSET){
1247 vf->current_serialno=ogg_page_serialno(&og);
1248 for(link=0;link<vf->links;link++)
1249 if(vf->serialnos[link]==vf->current_serialno)break;
1250 if(link==vf->links)return(OV_EBADLINK);
1251 vf->current_link=link;
1253 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1254 vf->ready_state=STREAMSET;
1255 _make_decode_ready(vf);
1259 ogg_stream_pagein(&vf->os,&og);
1263 /* discard samples until we reach the desired position. Crossing a
1264 logical bitstream boundary with abandon is OK. */
1265 while(vf->pcm_offset<pos){
1267 ogg_int64_t target=pos-vf->pcm_offset;
1268 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1270 if(samples>target)samples=target;
1271 vorbis_synthesis_read(&vf->vd,samples);
1272 vf->pcm_offset+=samples;
1275 if(_fetch_and_process_packet(vf,NULL,1)<=0)
1276 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1281 /* seek to a playback time relative to the decompressed pcm stream
1282 returns zero on success, nonzero on failure */
1283 int ov_time_seek(OggVorbis_File *vf,double seconds){
1284 /* translate time to PCM position and call ov_pcm_seek */
1287 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1288 double time_total=ov_time_total(vf,-1);
1290 if(vf->ready_state<OPENED)return(OV_EINVAL);
1291 if(!vf->seekable)return(OV_ENOSEEK);
1292 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1294 /* which bitstream section does this time offset occur in? */
1295 for(link=vf->links-1;link>=0;link--){
1296 pcm_total-=vf->pcmlengths[link*2+1];
1297 time_total-=ov_time_total(vf,link);
1298 if(seconds>=time_total)break;
1301 /* enough information to convert time offset to pcm offset */
1303 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1304 return(ov_pcm_seek(vf,target));
1308 /* page-granularity version of ov_time_seek
1309 returns zero on success, nonzero on failure */
1310 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1311 /* translate time to PCM position and call ov_pcm_seek */
1314 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1315 double time_total=ov_time_total(vf,-1);
1317 if(vf->ready_state<OPENED)return(OV_EINVAL);
1318 if(!vf->seekable)return(OV_ENOSEEK);
1319 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1321 /* which bitstream section does this time offset occur in? */
1322 for(link=vf->links-1;link>=0;link--){
1323 pcm_total-=vf->pcmlengths[link*2+1];
1324 time_total-=ov_time_total(vf,link);
1325 if(seconds>=time_total)break;
1328 /* enough information to convert time offset to pcm offset */
1330 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1331 return(ov_pcm_seek_page(vf,target));
1335 /* tell the current stream offset cursor. Note that seek followed by
1336 tell will likely not give the set offset due to caching */
1337 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1338 if(vf->ready_state<OPENED)return(OV_EINVAL);
1342 /* return PCM offset (sample) of next PCM sample to be read */
1343 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1344 if(vf->ready_state<OPENED)return(OV_EINVAL);
1345 return(vf->pcm_offset);
1348 /* return time offset (seconds) of next PCM sample to be read */
1349 double ov_time_tell(OggVorbis_File *vf){
1351 ogg_int64_t pcm_total=0;
1352 double time_total=0.f;
1354 if(vf->ready_state<OPENED)return(OV_EINVAL);
1356 pcm_total=ov_pcm_total(vf,-1);
1357 time_total=ov_time_total(vf,-1);
1359 /* which bitstream section does this time offset occur in? */
1360 for(link=vf->links-1;link>=0;link--){
1361 pcm_total-=vf->pcmlengths[link*2+1];
1362 time_total-=ov_time_total(vf,link);
1363 if(vf->pcm_offset>=pcm_total)break;
1367 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1370 /* link: -1) return the vorbis_info struct for the bitstream section
1371 currently being decoded
1372 0-n) to request information for a specific bitstream section
1374 In the case of a non-seekable bitstream, any call returns the
1375 current bitstream. NULL in the case that the machine is not
1378 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1381 if(vf->ready_state>=STREAMSET)
1382 return vf->vi+vf->current_link;
1395 /* grr, strong typing, grr, no templates/inheritence, grr */
1396 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1399 if(vf->ready_state>=STREAMSET)
1400 return vf->vc+vf->current_link;
1413 static int host_is_big_endian() {
1414 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1415 unsigned char *bytewise = (unsigned char *)&pattern;
1416 if (bytewise[0] == 0xfe) return 1;
1420 /* up to this point, everything could more or less hide the multiple
1421 logical bitstream nature of chaining from the toplevel application
1422 if the toplevel application didn't particularly care. However, at
1423 the point that we actually read audio back, the multiple-section
1424 nature must surface: Multiple bitstream sections do not necessarily
1425 have to have the same number of channels or sampling rate.
1427 ov_read returns the sequential logical bitstream number currently
1428 being decoded along with the PCM data in order that the toplevel
1429 application can take action on channel/sample rate changes. This
1430 number will be incremented even for streamed (non-seekable) streams
1431 (for seekable streams, it represents the actual logical bitstream
1432 index within the physical bitstream. Note that the accessor
1433 functions above are aware of this dichotomy).
1435 input values: buffer) a buffer to hold packed PCM data for return
1436 length) the byte length requested to be placed into buffer
1437 bigendianp) should the data be packed LSB first (0) or
1439 word) word size for output. currently 1 (byte) or
1442 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1444 n) number of bytes of PCM actually returned. The
1445 below works on a packet-by-packet basis, so the
1446 return length is not related to the 'length' passed
1447 in, just guaranteed to fit.
1449 *section) set to the logical bitstream number */
1451 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1452 int bigendianp,int word,int sgned,int *bitstream){
1454 int host_endian = host_is_big_endian();
1459 if(vf->ready_state<OPENED)return(OV_EINVAL);
1462 if(vf->ready_state>=STREAMSET){
1463 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1467 /* suck in another packet */
1469 int ret=_fetch_and_process_packet(vf,NULL,1);
1470 if(ret==OV_EOF)return(0);
1471 if(ret<=0)return(ret);
1478 /* yay! proceed to pack data into the byte buffer */
1480 long channels=ov_info(vf,-1)->channels;
1481 long bytespersample=word * channels;
1482 vorbis_fpu_control fpu;
1483 if(samples>length/bytespersample)samples=length/bytespersample;
1488 /* a tight loop to pack each size */
1492 int off=(sgned?0:128);
1493 vorbis_fpu_setround(&fpu);
1494 for(j=0;j<samples;j++)
1495 for(i=0;i<channels;i++){
1496 val=vorbis_ftoi(pcm[i][j]*128.f);
1498 else if(val<-128)val=-128;
1501 vorbis_fpu_restore(fpu);
1503 int off=(sgned?0:32768);
1505 if(host_endian==bigendianp){
1508 vorbis_fpu_setround(&fpu);
1509 for(i=0;i<channels;i++) { /* It's faster in this order */
1511 short *dest=((short *)buffer)+i;
1512 for(j=0;j<samples;j++) {
1513 val=vorbis_ftoi(src[j]*32768.f);
1514 if(val>32767)val=32767;
1515 else if(val<-32768)val=-32768;
1520 vorbis_fpu_restore(fpu);
1524 vorbis_fpu_setround(&fpu);
1525 for(i=0;i<channels;i++) {
1527 short *dest=((short *)buffer)+i;
1528 for(j=0;j<samples;j++) {
1529 val=vorbis_ftoi(src[j]*32768.f);
1530 if(val>32767)val=32767;
1531 else if(val<-32768)val=-32768;
1536 vorbis_fpu_restore(fpu);
1539 }else if(bigendianp){
1541 vorbis_fpu_setround(&fpu);
1542 for(j=0;j<samples;j++)
1543 for(i=0;i<channels;i++){
1544 val=vorbis_ftoi(pcm[i][j]*32768.f);
1545 if(val>32767)val=32767;
1546 else if(val<-32768)val=-32768;
1549 *buffer++=(val&0xff);
1551 vorbis_fpu_restore(fpu);
1555 vorbis_fpu_setround(&fpu);
1556 for(j=0;j<samples;j++)
1557 for(i=0;i<channels;i++){
1558 val=vorbis_ftoi(pcm[i][j]*32768.f);
1559 if(val>32767)val=32767;
1560 else if(val<-32768)val=-32768;
1562 *buffer++=(val&0xff);
1565 vorbis_fpu_restore(fpu);
1571 vorbis_synthesis_read(&vf->vd,samples);
1572 vf->pcm_offset+=samples;
1573 if(bitstream)*bitstream=vf->current_link;
1574 return(samples*bytespersample);
1580 /* input values: pcm_channels) a float vector per channel of output
1581 length) the sample length being read by the app
1583 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1585 n) number of samples of PCM actually returned. The
1586 below works on a packet-by-packet basis, so the
1587 return length is not related to the 'length' passed
1588 in, just guaranteed to fit.
1590 *section) set to the logical bitstream number */
1594 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1597 if(vf->ready_state<OPENED)return(OV_EINVAL);
1600 if(vf->ready_state>=STREAMSET){
1602 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1604 if(pcm_channels)*pcm_channels=pcm;
1605 if(samples>length)samples=length;
1606 vorbis_synthesis_read(&vf->vd,samples);
1607 vf->pcm_offset+=samples;
1608 if(bitstream)*bitstream=vf->current_link;
1614 /* suck in another packet */
1616 int ret=_fetch_and_process_packet(vf,NULL,1);
1617 if(ret==OV_EOF)return(0);
1618 if(ret<=0)return(ret);