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-2001 *
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.49 2001/09/13 02:17:51 xiphmont Exp $
16 ********************************************************************/
24 #include "vorbis/codec.h"
25 #include "vorbis/vorbisfile.h"
28 #include "codec_internal.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 coarse 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
62 #define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
63 over 8k gets what they deserve */
64 static long _get_data(OggVorbis_File *vf){
67 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
68 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
69 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
70 if(bytes==0 && errno)return(-1);
76 /* save a tiny smidge of verbosity to make the code more readable */
77 static void _seek_helper(OggVorbis_File *vf,long offset){
79 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
81 ogg_sync_reset(&vf->oy);
83 /* shouldn't happen unless someone writes a broken callback */
88 /* The read/seek functions track absolute position within the stream */
90 /* from the head of the stream, get the next page. boundary specifies
91 if the function is allowed to fetch more data from the stream (and
92 how much) or only use internally buffered data.
94 boundary: -1) unbounded search
95 0) read no additional data; use cached only
96 n) search for a new page beginning for n bytes
98 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
99 n) found a page at absolute offset n */
101 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int 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 */
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 long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
139 long begin=vf->offset;
145 _seek_helper(vf,begin);
146 while(vf->offset<begin+CHUNKSIZE){
147 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
148 if(ret==OV_EREAD)return(OV_EREAD);
157 /* we have the offset. Actually snork and hold the page now */
158 _seek_helper(vf,offset);
159 ret=_get_next_page(vf,og,CHUNKSIZE);
161 /* this shouldn't be possible */
167 /* finds each bitstream link one at a time using a bisection search
168 (has to begin by knowing the offset of the lb's initial page).
169 Recurses for each link so it can alloc the link storage after
170 finding them all, then unroll and fill the cache at the same time */
171 static int _bisect_forward_serialno(OggVorbis_File *vf,
177 long endsearched=end;
182 /* the below guards against garbage seperating the last and
183 first pages of two links. */
184 while(searched<endsearched){
187 if(endsearched-searched<CHUNKSIZE){
190 bisect=(searched+endsearched)/2;
193 _seek_helper(vf,bisect);
194 ret=_get_next_page(vf,&og,-1);
195 if(ret==OV_EREAD)return(OV_EREAD);
196 if(ret<0 || ogg_page_serialno(&og)!=currentno){
200 searched=ret+og.header_len+og.body_len;
204 _seek_helper(vf,next);
205 ret=_get_next_page(vf,&og,-1);
206 if(ret==OV_EREAD)return(OV_EREAD);
208 if(searched>=end || ret<0){
210 vf->offsets=_ogg_malloc((m+2)*sizeof(ogg_int64_t));
211 vf->offsets[m+1]=searched;
213 ret=_bisect_forward_serialno(vf,next,vf->offset,
214 end,ogg_page_serialno(&og),m+1);
215 if(ret==OV_EREAD)return(OV_EREAD);
218 vf->offsets[m]=begin;
222 /* uses the local ogg_stream storage in vf; this is important for
223 non-streaming input sources */
224 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
225 long *serialno,ogg_page *og_ptr){
231 ret=_get_next_page(vf,&og,CHUNKSIZE);
232 if(ret==OV_EREAD)return(OV_EREAD);
233 if(ret<0)return OV_ENOTVORBIS;
237 if(serialno)*serialno=ogg_page_serialno(og_ptr);
238 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
239 vf->ready_state=STREAMSET;
241 /* extract the initial header from the first page and verify that the
242 Ogg bitstream is in fact Vorbis data */
244 vorbis_info_init(vi);
245 vorbis_comment_init(vc);
249 ogg_stream_pagein(&vf->os,og_ptr);
251 int result=ogg_stream_packetout(&vf->os,&op);
257 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
263 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
271 vorbis_info_clear(vi);
272 vorbis_comment_clear(vc);
273 ogg_stream_clear(&vf->os);
274 vf->ready_state=OPENED;
279 /* last step of the OggVorbis_File initialization; get all the
280 vorbis_info structs and PCM positions. Only called by the seekable
281 initialization (local stream storage is hacked slightly; pay
282 attention to how that's done) */
284 /* this is void and does not propogate errors up because we want to be
285 able to open and use damaged bitstreams as well as we can. Just
286 watch out for missing information for links in the OggVorbis_File
288 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
292 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(vorbis_info));
293 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(vorbis_info));
294 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
295 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
296 vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
298 for(i=0;i<vf->links;i++){
300 /* we already grabbed the initial header earlier. Just set the offset */
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 */
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);
340 static void _make_decode_ready(OggVorbis_File *vf){
341 if(vf->ready_state!=STREAMSET)return;
343 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
345 vorbis_synthesis_init(&vf->vd,vf->vi);
347 vorbis_block_init(&vf->vd,&vf->vb);
348 vf->ready_state=INITSET;
352 static int _open_seekable2(OggVorbis_File *vf){
353 long serialno=vf->current_serialno,end;
354 long dataoffset=vf->offset;
357 /* we're partially open and have a first link header state in
359 /* we can seek, so set out learning all about this file */
360 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
361 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
363 /* We get the offset for the last page of the physical bitstream.
364 Most OggVorbis files will contain a single logical bitstream */
365 end=_get_prev_page(vf,&og);
371 /* more than one logical bitstream? */
372 if(ogg_page_serialno(&og)!=serialno){
374 /* Chained bitstream. Bisect-search each logical bitstream
375 section. Do so based on serial number only */
376 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
383 /* Only one logical bitstream */
384 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
391 /* the initial header memory is referenced by vf after; don't free it */
392 _prefetch_all_headers(vf,dataoffset);
393 return(ov_raw_seek(vf,0));
396 /* clear out the current logical bitstream decoder */
397 static void _decode_clear(OggVorbis_File *vf){
398 ogg_stream_clear(&vf->os);
399 vorbis_dsp_clear(&vf->vd);
400 vorbis_block_clear(&vf->vb);
401 vf->ready_state=OPENED;
407 /* fetch and process a packet. Handles the case where we're at a
408 bitstream boundary and dumps the decoding machine. If the decoding
409 machine is unloaded, it loads it. It also keeps pcm_offset up to
410 date (seek and read both use this. seek uses a special hack with
413 return: <0) error, OV_HOLE (lost packet) or OV_EOF
414 0) need more data (only if readp==0)
418 static int _process_packet(OggVorbis_File *vf,int readp){
421 /* handle one packet. Try to fetch it from current stream state */
422 /* extract packets from page */
425 /* process a packet if we can. If the machine isn't loaded,
427 if(vf->ready_state==INITSET){
429 int result=ogg_stream_packetout(&vf->os,&op);
430 ogg_int64_t granulepos;
432 if(result==-1)return(OV_HOLE); /* hole in the data. */
434 /* got a packet. process it */
435 granulepos=op.granulepos;
436 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
438 header packets aren't
441 vorbis_synthesis will
444 /* suck in the synthesis data and track bitrate */
446 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
447 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
448 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
449 vf->bittrack+=op.bytes*8;
452 /* update the pcm offset. */
453 if(granulepos!=-1 && !op.e_o_s){
454 int link=(vf->seekable?vf->current_link:0);
457 /* this packet has a pcm_offset on it (the last packet
458 completed on a page carries the offset) After processing
459 (above), we know the pcm position of the *last* sample
460 ready to be returned. Find the offset of the *first*
462 As an aside, this trick is inaccurate if we begin
463 reading anew right at the last page; the end-of-stream
464 granulepos declares the last frame in the stream, and the
465 last packet of the last page may be a partial frame.
466 So, we need a previous granulepos from an in-sequence page
467 to have a reference point. Thus the !op.e_o_s clause
470 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
474 granulepos+=vf->pcmlengths[i];
475 vf->pcm_offset=granulepos;
482 if(vf->ready_state>=OPENED){
484 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
486 /* bitrate tracking; add the header's bytes here, the body bytes
487 are done by packet above */
488 vf->bittrack+=og.header_len*8;
490 /* has our decoding just traversed a bitstream boundary? */
491 if(vf->ready_state==INITSET){
492 if(vf->current_serialno!=ogg_page_serialno(&og)){
496 vorbis_info_clear(vf->vi);
497 vorbis_comment_clear(vf->vc);
503 /* Do we need to load a new machine before submitting the page? */
504 /* This is different in the seekable and non-seekable cases.
506 In the seekable case, we already have all the header
507 information loaded and cached; we just initialize the machine
508 with it and continue on our merry way.
510 In the non-seekable (streaming) case, we'll only be at a
511 boundary if we just left the previous logical bitstream and
512 we're now nominally at the header of the next bitstream
515 if(vf->ready_state!=INITSET){
518 if(vf->ready_state<STREAMSET){
520 vf->current_serialno=ogg_page_serialno(&og);
522 /* match the serialno to bitstream section. We use this rather than
523 offset positions to avoid problems near logical bitstream
525 for(link=0;link<vf->links;link++)
526 if(vf->serialnos[link]==vf->current_serialno)break;
527 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
532 vf->current_link=link;
534 ogg_stream_init(&vf->os,vf->current_serialno);
535 ogg_stream_reset(&vf->os);
536 vf->ready_state=STREAMSET;
539 /* we're streaming */
540 /* fetch the three header packets, build the info struct */
542 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
549 _make_decode_ready(vf);
551 ogg_stream_pagein(&vf->os,&og);
555 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
556 if(f==NULL)return(-1);
557 return fseek(f,(int)off,whence);
560 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
561 long ibytes, ov_callbacks callbacks){
562 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
565 memset(vf,0,sizeof(OggVorbis_File));
567 vf->callbacks = callbacks;
569 /* init the framing state */
570 ogg_sync_init(&vf->oy);
572 /* perhaps some data was previously read into a buffer for testing
573 against other stream types. Allow initialization from this
574 previously read data (as we may be reading from a non-seekable
577 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
578 memcpy(buffer,initial,ibytes);
579 ogg_sync_wrote(&vf->oy,ibytes);
582 /* can we seek? Stevens suggests the seek test was portable */
583 if(offset!=-1)vf->seekable=1;
585 /* No seeking yet; Set up a 'single' (current) logical bitstream
586 entry for partial open */
588 vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
589 vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
591 /* Try to fetch the headers, maintaining all the storage */
592 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
595 }else if(vf->ready_state < PARTOPEN)
596 vf->ready_state=PARTOPEN;
600 static int _ov_open2(OggVorbis_File *vf){
601 if(vf->ready_state < OPENED)
602 vf->ready_state=OPENED;
604 int ret=_open_seekable2(vf);
615 /* clear out the OggVorbis_File struct */
616 int ov_clear(OggVorbis_File *vf){
618 vorbis_block_clear(&vf->vb);
619 vorbis_dsp_clear(&vf->vd);
620 ogg_stream_clear(&vf->os);
622 if(vf->vi && vf->links){
624 for(i=0;i<vf->links;i++){
625 vorbis_info_clear(vf->vi+i);
626 vorbis_comment_clear(vf->vc+i);
631 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
632 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
633 if(vf->serialnos)_ogg_free(vf->serialnos);
634 if(vf->offsets)_ogg_free(vf->offsets);
635 ogg_sync_clear(&vf->oy);
636 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
637 memset(vf,0,sizeof(OggVorbis_File));
645 /* inspects the OggVorbis file and finds/documents all the logical
646 bitstreams contained in it. Tries to be tolerant of logical
647 bitstream sections that are truncated/woogie.
653 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
654 ov_callbacks callbacks){
655 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
657 return _ov_open2(vf);
660 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
661 ov_callbacks callbacks = {
662 (size_t (*)(void *, size_t, size_t, void *)) fread,
663 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
664 (int (*)(void *)) fclose,
665 (long (*)(void *)) ftell
668 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
671 /* Only partially open the vorbis file; test for Vorbisness, and load
672 the headers for the first chain. Do not seek (although test for
673 seekability). Use ov_test_open to finish opening the file, else
674 ov_clear to close/free it. Same return codes as open. */
676 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
677 ov_callbacks callbacks)
679 return _ov_open1(f,vf,initial,ibytes,callbacks);
682 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
683 ov_callbacks callbacks = {
684 (size_t (*)(void *, size_t, size_t, void *)) fread,
685 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
686 (int (*)(void *)) fclose,
687 (long (*)(void *)) ftell
690 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
693 int ov_test_open(OggVorbis_File *vf){
694 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
695 return _ov_open2(vf);
698 /* How many logical bitstreams in this physical bitstream? */
699 long ov_streams(OggVorbis_File *vf){
703 /* Is the FILE * associated with vf seekable? */
704 long ov_seekable(OggVorbis_File *vf){
708 /* returns the bitrate for a given logical bitstream or the entire
709 physical bitstream. If the file is open for random access, it will
710 find the *actual* average bitrate. If the file is streaming, it
711 returns the nominal bitrate (if set) else the average of the
712 upper/lower bounds (if set) else -1 (unset).
714 If you want the actual bitrate field settings, get them from the
715 vorbis_info structs */
717 long ov_bitrate(OggVorbis_File *vf,int i){
718 if(vf->ready_state<OPENED)return(OV_EINVAL);
719 if(i>=vf->links)return(OV_EINVAL);
720 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
724 for(i=0;i<vf->links;i++)
725 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
726 return(rint(bits/ov_time_total(vf,-1)));
729 /* return the actual bitrate */
730 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
732 /* return nominal if set */
733 if(vf->vi[i].bitrate_nominal>0){
734 return vf->vi[i].bitrate_nominal;
736 if(vf->vi[i].bitrate_upper>0){
737 if(vf->vi[i].bitrate_lower>0){
738 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
740 return vf->vi[i].bitrate_upper;
749 /* returns the actual bitrate since last call. returns -1 if no
750 additional data to offer since last call (or at beginning of stream),
751 EINVAL if stream is only partially open
753 long ov_bitrate_instant(OggVorbis_File *vf){
754 int link=(vf->seekable?vf->current_link:0);
756 if(vf->ready_state<OPENED)return(OV_EINVAL);
757 if(vf->samptrack==0)return(OV_FALSE);
758 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
765 long ov_serialnumber(OggVorbis_File *vf,int i){
766 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
767 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
769 return(vf->current_serialno);
771 return(vf->serialnos[i]);
775 /* returns: total raw (compressed) length of content if i==-1
776 raw (compressed) length of that logical bitstream for i==0 to n
777 OV_EINVAL if the stream is not seekable (we can't know the length)
778 or if stream is only partially open
780 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
781 if(vf->ready_state<OPENED)return(OV_EINVAL);
782 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
786 for(i=0;i<vf->links;i++)
787 acc+=ov_raw_total(vf,i);
790 return(vf->offsets[i+1]-vf->offsets[i]);
794 /* returns: total PCM length (samples) of content if i==-1 PCM length
795 (samples) of that logical bitstream for i==0 to n
796 OV_EINVAL if the stream is not seekable (we can't know the
797 length) or only partially open
799 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
800 if(vf->ready_state<OPENED)return(OV_EINVAL);
801 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
805 for(i=0;i<vf->links;i++)
806 acc+=ov_pcm_total(vf,i);
809 return(vf->pcmlengths[i]);
813 /* returns: total seconds of content if i==-1
814 seconds in that logical bitstream for i==0 to n
815 OV_EINVAL if the stream is not seekable (we can't know the
816 length) or only partially open
818 double ov_time_total(OggVorbis_File *vf,int i){
819 if(vf->ready_state<OPENED)return(OV_EINVAL);
820 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
824 for(i=0;i<vf->links;i++)
825 acc+=ov_time_total(vf,i);
828 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
832 /* seek to an offset relative to the *compressed* data. This also
833 scans packets to update the PCM cursor. It will cross a logical
834 bitstream boundary, but only if it can't get any packets out of the
835 tail of the bitstream we seek to (so no surprises).
837 returns zero on success, nonzero on failure */
839 int ov_raw_seek(OggVorbis_File *vf,long pos){
840 ogg_stream_state work_os;
842 if(vf->ready_state<OPENED)return(OV_EINVAL);
844 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
846 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
848 /* clear out decoding machine state */
852 _seek_helper(vf,pos);
854 /* we need to make sure the pcm_offset is set, but we don't want to
855 advance the raw cursor past good packets just to get to the first
856 with a granulepos. That's not equivalent behavior to beginning
857 decoding as immediately after the seek position as possible.
859 So, a hack. We use two stream states; a local scratch state and
860 a the shared vf->os stream state. We use the local state to
861 scan, and the shared state as a buffer for later decode.
863 Unfortuantely, on the last page we still advance to last packet
864 because the granulepos on the last page is not necessarily on a
865 packet boundary, and we need to make sure the granpos is
877 memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
878 it later even if we don't
882 if(vf->ready_state==STREAMSET){
883 /* snarf/scan a packet if we can */
884 int result=ogg_stream_packetout(&work_os,&op);
888 if(vf->vi[vf->current_link].codec_setup)
889 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
891 ogg_stream_packetout(&vf->os,NULL);
893 if(lastblock)accblock+=(lastblock+thisblock)>>2;
895 if(op.granulepos!=-1){
896 int i,link=vf->current_link;
897 ogg_int64_t granulepos=op.granulepos;
900 granulepos+=vf->pcmlengths[i];
901 vf->pcm_offset=granulepos-accblock;
910 if(_get_next_page(vf,&og,-1)<0){
911 vf->pcm_offset=ov_pcm_total(vf,-1);
915 /* huh? Bogus stream with packets but no granulepos */
920 /* has our decoding just traversed a bitstream boundary? */
921 if(vf->ready_state==STREAMSET)
922 if(vf->current_serialno!=ogg_page_serialno(&og)){
923 _decode_clear(vf); /* clear out stream state */
924 ogg_stream_clear(&work_os);
927 if(vf->ready_state<STREAMSET){
930 vf->current_serialno=ogg_page_serialno(&og);
931 for(link=0;link<vf->links;link++)
932 if(vf->serialnos[link]==vf->current_serialno)break;
933 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
935 machine uninitialized */
936 vf->current_link=link;
938 ogg_stream_init(&vf->os,vf->current_serialno);
939 ogg_stream_reset(&vf->os);
940 ogg_stream_init(&work_os,vf->current_serialno);
941 ogg_stream_reset(&work_os);
942 vf->ready_state=STREAMSET;
946 ogg_stream_pagein(&vf->os,&og);
947 ogg_stream_pagein(&work_os,&og);
948 eosflag=ogg_page_eos(&og);
952 ogg_stream_clear(&work_os);
956 /* dump the machine so we're in a known state */
958 ogg_stream_clear(&work_os);
963 /* Page granularity seek (faster than sample granularity because we
964 don't do the last bit of decode to find a specific sample).
966 Seek to the last [granule marked] page preceeding the specified pos
967 location, such that decoding past the returned point will quickly
968 arrive at the requested position. */
969 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
972 ogg_int64_t total=ov_pcm_total(vf,-1);
974 if(vf->ready_state<OPENED)return(OV_EINVAL);
975 if(!vf->seekable)return(OV_ENOSEEK);
976 if(pos<0 || pos>total)return(OV_EINVAL);
978 /* which bitstream section does this pcm offset occur in? */
979 for(link=vf->links-1;link>=0;link--){
980 total-=vf->pcmlengths[link];
984 /* search within the logical bitstream for the page with the highest
985 pcm_pos preceeding (or equal to) pos. There is a danger here;
986 missing pages or incorrect frame number information in the
987 bitstream could make our task impossible. Account for that (it
988 would be an error condition) */
990 /* new search algorithm by HB (Nicholas Vinen) */
992 ogg_int64_t target=pos-total;
993 long end=vf->offsets[link+1];
994 long begin=vf->offsets[link];
995 ogg_int64_t endtime = vf->pcmlengths[link];
996 ogg_int64_t begintime = 0;
1003 if(end-begin<CHUNKSIZE){
1006 /* take a (pretty decent) guess. */
1008 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1012 _seek_helper(vf,bisect);
1015 ret=_get_next_page(vf,&og,end-bisect);
1016 if(ret==OV_EREAD) goto seek_error;
1019 end=begin; /* found it */
1021 if(bisect==0)goto seek_error;
1023 if(bisect<=begin)bisect=begin+1;
1024 _seek_helper(vf,bisect);
1027 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1028 if(granulepos<target){
1029 best=ret; /* raw offset of packet with granulepos */
1030 begin=vf->offset; /* raw offset of next page */
1031 begintime=granulepos;
1033 if(target-begin>44100)break;
1034 bisect=begin; /* *not* begin + 1 */
1037 end=begin; /* found it */
1039 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1041 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1042 if(bisect<=begin)bisect=begin+1;
1043 _seek_helper(vf,bisect);
1055 /* found our page. seek to it, update pcm offset. Easier case than
1056 raw_seek, don't keep packets preceeding granulepos. */
1060 /* clear out decoding machine state */
1063 _seek_helper(vf,best);
1065 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1066 vf->current_serialno=ogg_page_serialno(&og);
1067 vf->current_link=link;
1069 ogg_stream_init(&vf->os,vf->current_serialno);
1070 ogg_stream_reset(&vf->os);
1071 vf->ready_state=STREAMSET;
1072 ogg_stream_pagein(&vf->os,&og);
1074 /* pull out all but last packet; the one with granulepos */
1076 ret=ogg_stream_packetpeek(&vf->os,&op);
1078 /* !!! the packet finishing this page originated on a
1079 preceeding page. Keep fetching previous pages until we
1080 get one with a granulepos or without the 'continued' flag
1081 set. Then just use raw_seek for simplicity. */
1083 ret=_get_prev_page(vf,&og);
1084 if(ret<0)goto seek_error;
1085 if(ogg_page_granulepos(&og)>-1 ||
1086 !ogg_page_continued(&og)){
1087 return ov_raw_seek(vf,ret);
1092 if(ret<0)goto seek_error;
1093 if(op.granulepos!=-1){
1094 vf->pcm_offset=op.granulepos+total;
1097 ret=ogg_stream_packetout(&vf->os,NULL);
1103 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1110 /* dump machine so we're in a known state */
1116 /* seek to a sample offset relative to the decompressed pcm stream
1117 returns zero on success, nonzero on failure */
1119 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1120 int thisblock,lastblock=0;
1121 int ret=ov_pcm_seek_page(vf,pos);
1122 codec_setup_info *ci=vf->vi->codec_setup;
1123 if(ret<0)return(ret);
1125 /* discard leading packets we don't need for the lapping of the
1126 position we want; don't decode them */
1132 int ret=ogg_stream_packetpeek(&vf->os,&op);
1134 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1135 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1137 if(vf->pcm_offset+((thisblock+ci->blocksizes[1])>>2)>=pos)break;
1139 ogg_stream_packetout(&vf->os,NULL);
1142 /* end of logical stream case is hard, especially with exact
1143 length positioning. */
1145 if(op.granulepos>-1){
1147 /* always believe the stream markers */
1148 vf->pcm_offset=op.granulepos;
1149 for(i=0;i<vf->current_link;i++)
1150 vf->pcm_offset+=vf->pcmlengths[i];
1153 lastblock=thisblock;
1156 if(ret<0 && ret!=OV_HOLE)break;
1158 /* suck in a new page */
1159 if(_get_next_page(vf,&og,-1)<0)break;
1160 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1162 if(vf->ready_state<STREAMSET){
1165 vf->current_serialno=ogg_page_serialno(&og);
1166 for(link=0;link<vf->links;link++)
1167 if(vf->serialnos[link]==vf->current_serialno)break;
1168 if(link==vf->links)return(OV_EBADLINK);
1169 vf->current_link=link;
1171 ogg_stream_init(&vf->os,vf->current_serialno);
1172 ogg_stream_reset(&vf->os);
1173 vf->ready_state=STREAMSET;
1176 ogg_stream_pagein(&vf->os,&og);
1180 /* discard samples until we reach the desired position. Crossing a
1181 logical bitstream boundary with abandon is OK. */
1182 _make_decode_ready(vf);
1183 while(vf->pcm_offset<pos){
1185 long target=pos-vf->pcm_offset;
1186 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1188 if(samples>target)samples=target;
1189 vorbis_synthesis_read(&vf->vd,samples);
1190 vf->pcm_offset+=samples;
1193 if(_process_packet(vf,1)<=0)
1194 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1199 /* seek to a playback time relative to the decompressed pcm stream
1200 returns zero on success, nonzero on failure */
1201 int ov_time_seek(OggVorbis_File *vf,double seconds){
1202 /* translate time to PCM position and call ov_pcm_seek */
1205 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1206 double time_total=ov_time_total(vf,-1);
1208 if(vf->ready_state<OPENED)return(OV_EINVAL);
1209 if(!vf->seekable)return(OV_ENOSEEK);
1210 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1212 /* which bitstream section does this time offset occur in? */
1213 for(link=vf->links-1;link>=0;link--){
1214 pcm_total-=vf->pcmlengths[link];
1215 time_total-=ov_time_total(vf,link);
1216 if(seconds>=time_total)break;
1219 /* enough information to convert time offset to pcm offset */
1221 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1222 return(ov_pcm_seek(vf,target));
1226 /* page-granularity version of ov_time_seek
1227 returns zero on success, nonzero on failure */
1228 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1229 /* translate time to PCM position and call ov_pcm_seek */
1232 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1233 double time_total=ov_time_total(vf,-1);
1235 if(vf->ready_state<OPENED)return(OV_EINVAL);
1236 if(!vf->seekable)return(OV_ENOSEEK);
1237 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1239 /* which bitstream section does this time offset occur in? */
1240 for(link=vf->links-1;link>=0;link--){
1241 pcm_total-=vf->pcmlengths[link];
1242 time_total-=ov_time_total(vf,link);
1243 if(seconds>=time_total)break;
1246 /* enough information to convert time offset to pcm offset */
1248 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1249 return(ov_pcm_seek_page(vf,target));
1253 /* tell the current stream offset cursor. Note that seek followed by
1254 tell will likely not give the set offset due to caching */
1255 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1256 if(vf->ready_state<OPENED)return(OV_EINVAL);
1260 /* return PCM offset (sample) of next PCM sample to be read */
1261 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1262 if(vf->ready_state<OPENED)return(OV_EINVAL);
1263 return(vf->pcm_offset);
1266 /* return time offset (seconds) of next PCM sample to be read */
1267 double ov_time_tell(OggVorbis_File *vf){
1268 /* translate time to PCM position and call ov_pcm_seek */
1271 ogg_int64_t pcm_total=0;
1272 double time_total=0.f;
1274 if(vf->ready_state<OPENED)return(OV_EINVAL);
1276 pcm_total=ov_pcm_total(vf,-1);
1277 time_total=ov_time_total(vf,-1);
1279 /* which bitstream section does this time offset occur in? */
1280 for(link=vf->links-1;link>=0;link--){
1281 pcm_total-=vf->pcmlengths[link];
1282 time_total-=ov_time_total(vf,link);
1283 if(vf->pcm_offset>=pcm_total)break;
1287 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1290 /* link: -1) return the vorbis_info struct for the bitstream section
1291 currently being decoded
1292 0-n) to request information for a specific bitstream section
1294 In the case of a non-seekable bitstream, any call returns the
1295 current bitstream. NULL in the case that the machine is not
1298 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1301 if(vf->ready_state>=STREAMSET)
1302 return vf->vi+vf->current_link;
1315 /* grr, strong typing, grr, no templates/inheritence, grr */
1316 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1319 if(vf->ready_state>=STREAMSET)
1320 return vf->vc+vf->current_link;
1333 int host_is_big_endian() {
1334 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1335 unsigned char *bytewise = (unsigned char *)&pattern;
1336 if (bytewise[0] == 0xfe) return 1;
1340 /* up to this point, everything could more or less hide the multiple
1341 logical bitstream nature of chaining from the toplevel application
1342 if the toplevel application didn't particularly care. However, at
1343 the point that we actually read audio back, the multiple-section
1344 nature must surface: Multiple bitstream sections do not necessarily
1345 have to have the same number of channels or sampling rate.
1347 ov_read returns the sequential logical bitstream number currently
1348 being decoded along with the PCM data in order that the toplevel
1349 application can take action on channel/sample rate changes. This
1350 number will be incremented even for streamed (non-seekable) streams
1351 (for seekable streams, it represents the actual logical bitstream
1352 index within the physical bitstream. Note that the accessor
1353 functions above are aware of this dichotomy).
1355 input values: buffer) a buffer to hold packed PCM data for return
1356 length) the byte length requested to be placed into buffer
1357 bigendianp) should the data be packed LSB first (0) or
1359 word) word size for output. currently 1 (byte) or
1362 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1364 n) number of bytes of PCM actually returned. The
1365 below works on a packet-by-packet basis, so the
1366 return length is not related to the 'length' passed
1367 in, just guaranteed to fit.
1369 *section) set to the logical bitstream number */
1371 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1372 int bigendianp,int word,int sgned,int *bitstream){
1374 int host_endian = host_is_big_endian();
1376 if(vf->ready_state<OPENED)return(OV_EINVAL);
1379 if(vf->ready_state>=STREAMSET){
1381 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1383 /* yay! proceed to pack data into the byte buffer */
1385 long channels=ov_info(vf,-1)->channels;
1386 long bytespersample=word * channels;
1387 vorbis_fpu_control fpu;
1388 if(samples>length/bytespersample)samples=length/bytespersample;
1390 /* a tight loop to pack each size */
1394 int off=(sgned?0:128);
1395 vorbis_fpu_setround(&fpu);
1396 for(j=0;j<samples;j++)
1397 for(i=0;i<channels;i++){
1398 val=vorbis_ftoi(pcm[i][j]*128.f);
1400 else if(val<-128)val=-128;
1403 vorbis_fpu_restore(fpu);
1405 int off=(sgned?0:32768);
1407 if(host_endian==bigendianp){
1410 vorbis_fpu_setround(&fpu);
1411 for(i=0;i<channels;i++) { /* It's faster in this order */
1413 short *dest=((short *)buffer)+i;
1414 for(j=0;j<samples;j++) {
1415 val=vorbis_ftoi(src[j]*32768.f);
1416 if(val>32767)val=32767;
1417 else if(val<-32768)val=-32768;
1422 vorbis_fpu_restore(fpu);
1426 vorbis_fpu_setround(&fpu);
1427 for(i=0;i<channels;i++) {
1429 short *dest=((short *)buffer)+i;
1430 for(j=0;j<samples;j++) {
1431 val=vorbis_ftoi(src[j]*32768.f);
1432 if(val>32767)val=32767;
1433 else if(val<-32768)val=-32768;
1438 vorbis_fpu_restore(fpu);
1441 }else if(bigendianp){
1443 vorbis_fpu_setround(&fpu);
1444 for(j=0;j<samples;j++)
1445 for(i=0;i<channels;i++){
1446 val=vorbis_ftoi(pcm[i][j]*32768.f);
1447 if(val>32767)val=32767;
1448 else if(val<-32768)val=-32768;
1451 *buffer++=(val&0xff);
1453 vorbis_fpu_restore(fpu);
1457 vorbis_fpu_setround(&fpu);
1458 for(j=0;j<samples;j++)
1459 for(i=0;i<channels;i++){
1460 val=vorbis_ftoi(pcm[i][j]*32768.f);
1461 if(val>32767)val=32767;
1462 else if(val<-32768)val=-32768;
1464 *buffer++=(val&0xff);
1467 vorbis_fpu_restore(fpu);
1473 vorbis_synthesis_read(&vf->vd,samples);
1474 vf->pcm_offset+=samples;
1475 if(bitstream)*bitstream=vf->current_link;
1476 return(samples*bytespersample);
1480 /* suck in another packet */
1482 int ret=_process_packet(vf,1);
1483 if(ret==OV_EOF)return(0);
1484 if(ret<=0)return(ret);