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.56 2002/02/28 04:12:48 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,long 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 long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
101 if(boundary>0)boundary+=vf->offset;
105 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
106 more=ogg_sync_pageseek(&vf->oy,og);
109 /* skipped n bytes */
113 /* send more paramedics */
114 if(!boundary)return(OV_FALSE);
116 long ret=_get_data(vf);
117 if(ret==0)return(OV_EOF);
118 if(ret<0)return(OV_EREAD);
121 /* got a page. Return the offset at the page beginning,
122 advance the internal offset past the page end */
132 /* find the latest page beginning before the current stream cursor
133 position. Much dirtier than the above as Ogg doesn't have any
134 backward search linkage. no 'readp' as it will certainly have to
136 /* returns offset or OV_EREAD, OV_FAULT */
137 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
138 long begin=vf->offset;
146 _seek_helper(vf,begin);
147 while(vf->offset<begin+CHUNKSIZE){
148 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
149 if(ret==OV_EREAD)return(OV_EREAD);
158 /* we have the offset. Actually snork and hold the page now */
159 _seek_helper(vf,offset);
160 ret=_get_next_page(vf,og,CHUNKSIZE);
162 /* this shouldn't be possible */
168 /* finds each bitstream link one at a time using a bisection search
169 (has to begin by knowing the offset of the lb's initial page).
170 Recurses for each link so it can alloc the link storage after
171 finding them all, then unroll and fill the cache at the same time */
172 static int _bisect_forward_serialno(OggVorbis_File *vf,
178 long endsearched=end;
183 /* the below guards against garbage seperating the last and
184 first pages of two links. */
185 while(searched<endsearched){
188 if(endsearched-searched<CHUNKSIZE){
191 bisect=(searched+endsearched)/2;
194 _seek_helper(vf,bisect);
195 ret=_get_next_page(vf,&og,-1);
196 if(ret==OV_EREAD)return(OV_EREAD);
197 if(ret<0 || ogg_page_serialno(&og)!=currentno){
201 searched=ret+og.header_len+og.body_len;
205 _seek_helper(vf,next);
206 ret=_get_next_page(vf,&og,-1);
207 if(ret==OV_EREAD)return(OV_EREAD);
209 if(searched>=end || ret<0){
211 vf->offsets=_ogg_malloc((m+2)*sizeof(*vf->offsets));
212 vf->offsets[m+1]=searched;
214 ret=_bisect_forward_serialno(vf,next,vf->offset,
215 end,ogg_page_serialno(&og),m+1);
216 if(ret==OV_EREAD)return(OV_EREAD);
219 vf->offsets[m]=begin;
223 /* uses the local ogg_stream storage in vf; this is important for
224 non-streaming input sources */
225 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
226 long *serialno,ogg_page *og_ptr){
232 ret=_get_next_page(vf,&og,CHUNKSIZE);
233 if(ret==OV_EREAD)return(OV_EREAD);
234 if(ret<0)return OV_ENOTVORBIS;
238 if(serialno)*serialno=ogg_page_serialno(og_ptr);
239 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
240 vf->ready_state=STREAMSET;
242 /* extract the initial header from the first page and verify that the
243 Ogg bitstream is in fact Vorbis data */
245 vorbis_info_init(vi);
246 vorbis_comment_init(vc);
250 ogg_stream_pagein(&vf->os,og_ptr);
252 int result=ogg_stream_packetout(&vf->os,&op);
258 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
264 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
272 vorbis_info_clear(vi);
273 vorbis_comment_clear(vc);
274 ogg_stream_clear(&vf->os);
275 vf->ready_state=OPENED;
280 /* last step of the OggVorbis_File initialization; get all the
281 vorbis_info structs and PCM positions. Only called by the seekable
282 initialization (local stream storage is hacked slightly; pay
283 attention to how that's done) */
285 /* this is void and does not propogate errors up because we want to be
286 able to open and use damaged bitstreams as well as we can. Just
287 watch out for missing information for links in the OggVorbis_File
289 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
293 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
294 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
295 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
296 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(*vf->pcmlengths));
297 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
299 for(i=0;i<vf->links;i++){
301 /* we already grabbed the initial header earlier. Just set the offset */
302 vf->dataoffsets[i]=dataoffset;
305 /* seek to the location of the initial header */
307 _seek_helper(vf,vf->offsets[i]);
308 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
309 vf->dataoffsets[i]=-1;
311 vf->dataoffsets[i]=vf->offset;
312 ogg_stream_clear(&vf->os);
316 /* get the serial number and PCM length of this link. To do this,
317 get the last page of the stream */
319 long end=vf->offsets[i+1];
320 _seek_helper(vf,end);
323 ret=_get_prev_page(vf,&og);
325 /* this should not be possible */
326 vorbis_info_clear(vf->vi+i);
327 vorbis_comment_clear(vf->vc+i);
330 if(ogg_page_granulepos(&og)!=-1){
331 vf->serialnos[i]=ogg_page_serialno(&og);
332 vf->pcmlengths[i]=ogg_page_granulepos(&og);
341 static void _make_decode_ready(OggVorbis_File *vf){
342 if(vf->ready_state!=STREAMSET)return;
344 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
346 vorbis_synthesis_init(&vf->vd,vf->vi);
348 vorbis_block_init(&vf->vd,&vf->vb);
349 vf->ready_state=INITSET;
353 static int _open_seekable2(OggVorbis_File *vf){
354 long serialno=vf->current_serialno,end;
355 long dataoffset=vf->offset;
358 /* we're partially open and have a first link header state in
360 /* we can seek, so set out learning all about this file */
361 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
362 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
364 /* We get the offset for the last page of the physical bitstream.
365 Most OggVorbis files will contain a single logical bitstream */
366 end=_get_prev_page(vf,&og);
372 /* more than one logical bitstream? */
373 if(ogg_page_serialno(&og)!=serialno){
375 /* Chained bitstream. Bisect-search each logical bitstream
376 section. Do so based on serial number only */
377 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
384 /* Only one logical bitstream */
385 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
392 /* the initial header memory is referenced by vf after; don't free it */
393 _prefetch_all_headers(vf,dataoffset);
394 return(ov_raw_seek(vf,0));
397 /* clear out the current logical bitstream decoder */
398 static void _decode_clear(OggVorbis_File *vf){
399 ogg_stream_clear(&vf->os);
400 vorbis_dsp_clear(&vf->vd);
401 vorbis_block_clear(&vf->vb);
402 vf->ready_state=OPENED;
408 /* fetch and process a packet. Handles the case where we're at a
409 bitstream boundary and dumps the decoding machine. If the decoding
410 machine is unloaded, it loads it. It also keeps pcm_offset up to
411 date (seek and read both use this. seek uses a special hack with
414 return: <0) error, OV_HOLE (lost packet) or OV_EOF
415 0) need more data (only if readp==0)
419 static int _fetch_and_process_packet(OggVorbis_File *vf,
424 /* handle one packet. Try to fetch it from current stream state */
425 /* extract packets from page */
428 /* process a packet if we can. If the machine isn't loaded,
430 if(vf->ready_state==INITSET){
433 ogg_packet *op_ptr=(op_in?op_in:&op);
434 int result=ogg_stream_packetout(&vf->os,op_ptr);
435 ogg_int64_t granulepos;
438 if(result==-1)return(OV_HOLE); /* hole in the data. */
440 /* got a packet. process it */
441 granulepos=op_ptr->granulepos;
442 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
444 header packets aren't
447 vorbis_synthesis will
450 /* suck in the synthesis data and track bitrate */
452 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
453 /* for proper use of libvorbis within libvorbisfile,
454 oldsamples will always be zero. */
455 if(oldsamples)return(OV_EFAULT);
457 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
458 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
459 vf->bittrack+=op_ptr->bytes*8;
462 /* update the pcm offset. */
463 if(granulepos!=-1 && !op_ptr->e_o_s){
464 int link=(vf->seekable?vf->current_link:0);
467 /* this packet has a pcm_offset on it (the last packet
468 completed on a page carries the offset) After processing
469 (above), we know the pcm position of the *last* sample
470 ready to be returned. Find the offset of the *first*
472 As an aside, this trick is inaccurate if we begin
473 reading anew right at the last page; the end-of-stream
474 granulepos declares the last frame in the stream, and the
475 last packet of the last page may be a partial frame.
476 So, we need a previous granulepos from an in-sequence page
477 to have a reference point. Thus the !op_ptr->e_o_s clause
480 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
484 granulepos+=vf->pcmlengths[i];
485 vf->pcm_offset=granulepos;
495 if(vf->ready_state>=OPENED){
497 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
499 /* bitrate tracking; add the header's bytes here, the body bytes
500 are done by packet above */
501 vf->bittrack+=og.header_len*8;
503 /* has our decoding just traversed a bitstream boundary? */
504 if(vf->ready_state==INITSET){
505 if(vf->current_serialno!=ogg_page_serialno(&og)){
509 vorbis_info_clear(vf->vi);
510 vorbis_comment_clear(vf->vc);
516 /* Do we need to load a new machine before submitting the page? */
517 /* This is different in the seekable and non-seekable cases.
519 In the seekable case, we already have all the header
520 information loaded and cached; we just initialize the machine
521 with it and continue on our merry way.
523 In the non-seekable (streaming) case, we'll only be at a
524 boundary if we just left the previous logical bitstream and
525 we're now nominally at the header of the next bitstream
528 if(vf->ready_state!=INITSET){
531 if(vf->ready_state<STREAMSET){
533 vf->current_serialno=ogg_page_serialno(&og);
535 /* match the serialno to bitstream section. We use this rather than
536 offset positions to avoid problems near logical bitstream
538 for(link=0;link<vf->links;link++)
539 if(vf->serialnos[link]==vf->current_serialno)break;
540 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
545 vf->current_link=link;
547 ogg_stream_init(&vf->os,vf->current_serialno);
548 ogg_stream_reset(&vf->os);
549 vf->ready_state=STREAMSET;
552 /* we're streaming */
553 /* fetch the three header packets, build the info struct */
555 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
562 _make_decode_ready(vf);
564 ogg_stream_pagein(&vf->os,&og);
568 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
569 if(f==NULL)return(-1);
570 return fseek(f,(int)off,whence);
573 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
574 long ibytes, ov_callbacks callbacks){
575 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
578 memset(vf,0,sizeof(*vf));
580 vf->callbacks = callbacks;
582 /* init the framing state */
583 ogg_sync_init(&vf->oy);
585 /* perhaps some data was previously read into a buffer for testing
586 against other stream types. Allow initialization from this
587 previously read data (as we may be reading from a non-seekable
590 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
591 memcpy(buffer,initial,ibytes);
592 ogg_sync_wrote(&vf->oy,ibytes);
595 /* can we seek? Stevens suggests the seek test was portable */
596 if(offset!=-1)vf->seekable=1;
598 /* No seeking yet; Set up a 'single' (current) logical bitstream
599 entry for partial open */
601 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
602 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
604 /* Try to fetch the headers, maintaining all the storage */
605 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
608 }else if(vf->ready_state < PARTOPEN)
609 vf->ready_state=PARTOPEN;
613 static int _ov_open2(OggVorbis_File *vf){
614 if(vf->ready_state < OPENED)
615 vf->ready_state=OPENED;
617 int ret=_open_seekable2(vf);
628 /* clear out the OggVorbis_File struct */
629 int ov_clear(OggVorbis_File *vf){
631 vorbis_block_clear(&vf->vb);
632 vorbis_dsp_clear(&vf->vd);
633 ogg_stream_clear(&vf->os);
635 if(vf->vi && vf->links){
637 for(i=0;i<vf->links;i++){
638 vorbis_info_clear(vf->vi+i);
639 vorbis_comment_clear(vf->vc+i);
644 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
645 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
646 if(vf->serialnos)_ogg_free(vf->serialnos);
647 if(vf->offsets)_ogg_free(vf->offsets);
648 ogg_sync_clear(&vf->oy);
649 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
650 memset(vf,0,sizeof(*vf));
658 /* inspects the OggVorbis file and finds/documents all the logical
659 bitstreams contained in it. Tries to be tolerant of logical
660 bitstream sections that are truncated/woogie.
666 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
667 ov_callbacks callbacks){
668 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
670 return _ov_open2(vf);
673 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
674 ov_callbacks callbacks = {
675 (size_t (*)(void *, size_t, size_t, void *)) fread,
676 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
677 (int (*)(void *)) fclose,
678 (long (*)(void *)) ftell
681 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
684 /* Only partially open the vorbis file; test for Vorbisness, and load
685 the headers for the first chain. Do not seek (although test for
686 seekability). Use ov_test_open to finish opening the file, else
687 ov_clear to close/free it. Same return codes as open. */
689 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
690 ov_callbacks callbacks)
692 return _ov_open1(f,vf,initial,ibytes,callbacks);
695 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
696 ov_callbacks callbacks = {
697 (size_t (*)(void *, size_t, size_t, void *)) fread,
698 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
699 (int (*)(void *)) fclose,
700 (long (*)(void *)) ftell
703 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
706 int ov_test_open(OggVorbis_File *vf){
707 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
708 return _ov_open2(vf);
711 /* How many logical bitstreams in this physical bitstream? */
712 long ov_streams(OggVorbis_File *vf){
716 /* Is the FILE * associated with vf seekable? */
717 long ov_seekable(OggVorbis_File *vf){
721 /* returns the bitrate for a given logical bitstream or the entire
722 physical bitstream. If the file is open for random access, it will
723 find the *actual* average bitrate. If the file is streaming, it
724 returns the nominal bitrate (if set) else the average of the
725 upper/lower bounds (if set) else -1 (unset).
727 If you want the actual bitrate field settings, get them from the
728 vorbis_info structs */
730 long ov_bitrate(OggVorbis_File *vf,int i){
731 if(vf->ready_state<OPENED)return(OV_EINVAL);
732 if(i>=vf->links)return(OV_EINVAL);
733 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
737 for(i=0;i<vf->links;i++)
738 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
739 return(rint(bits/ov_time_total(vf,-1)));
742 /* return the actual bitrate */
743 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
745 /* return nominal if set */
746 if(vf->vi[i].bitrate_nominal>0){
747 return vf->vi[i].bitrate_nominal;
749 if(vf->vi[i].bitrate_upper>0){
750 if(vf->vi[i].bitrate_lower>0){
751 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
753 return vf->vi[i].bitrate_upper;
762 /* returns the actual bitrate since last call. returns -1 if no
763 additional data to offer since last call (or at beginning of stream),
764 EINVAL if stream is only partially open
766 long ov_bitrate_instant(OggVorbis_File *vf){
767 int link=(vf->seekable?vf->current_link:0);
769 if(vf->ready_state<OPENED)return(OV_EINVAL);
770 if(vf->samptrack==0)return(OV_FALSE);
771 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
778 long ov_serialnumber(OggVorbis_File *vf,int i){
779 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
780 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
782 return(vf->current_serialno);
784 return(vf->serialnos[i]);
788 /* returns: total raw (compressed) length of content if i==-1
789 raw (compressed) length of that logical bitstream for i==0 to n
790 OV_EINVAL if the stream is not seekable (we can't know the length)
791 or if stream is only partially open
793 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
794 if(vf->ready_state<OPENED)return(OV_EINVAL);
795 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
799 for(i=0;i<vf->links;i++)
800 acc+=ov_raw_total(vf,i);
803 return(vf->offsets[i+1]-vf->offsets[i]);
807 /* returns: total PCM length (samples) of content if i==-1 PCM length
808 (samples) of that logical bitstream for i==0 to n
809 OV_EINVAL if the stream is not seekable (we can't know the
810 length) or only partially open
812 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
813 if(vf->ready_state<OPENED)return(OV_EINVAL);
814 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
818 for(i=0;i<vf->links;i++)
819 acc+=ov_pcm_total(vf,i);
822 return(vf->pcmlengths[i]);
826 /* returns: total seconds of content if i==-1
827 seconds in that logical bitstream for i==0 to n
828 OV_EINVAL if the stream is not seekable (we can't know the
829 length) or only partially open
831 double ov_time_total(OggVorbis_File *vf,int i){
832 if(vf->ready_state<OPENED)return(OV_EINVAL);
833 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
837 for(i=0;i<vf->links;i++)
838 acc+=ov_time_total(vf,i);
841 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
845 /* seek to an offset relative to the *compressed* data. This also
846 scans packets to update the PCM cursor. It will cross a logical
847 bitstream boundary, but only if it can't get any packets out of the
848 tail of the bitstream we seek to (so no surprises).
850 returns zero on success, nonzero on failure */
852 int ov_raw_seek(OggVorbis_File *vf,long pos){
853 ogg_stream_state work_os;
855 if(vf->ready_state<OPENED)return(OV_EINVAL);
857 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
859 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
861 /* clear out decoding machine state */
865 _seek_helper(vf,pos);
867 /* we need to make sure the pcm_offset is set, but we don't want to
868 advance the raw cursor past good packets just to get to the first
869 with a granulepos. That's not equivalent behavior to beginning
870 decoding as immediately after the seek position as possible.
872 So, a hack. We use two stream states; a local scratch state and
873 a the shared vf->os stream state. We use the local state to
874 scan, and the shared state as a buffer for later decode.
876 Unfortuantely, on the last page we still advance to last packet
877 because the granulepos on the last page is not necessarily on a
878 packet boundary, and we need to make sure the granpos is
890 memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
891 it later even if we don't
895 if(vf->ready_state==STREAMSET){
896 /* snarf/scan a packet if we can */
897 int result=ogg_stream_packetout(&work_os,&op);
901 if(vf->vi[vf->current_link].codec_setup)
902 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
904 ogg_stream_packetout(&vf->os,NULL);
906 if(lastblock)accblock+=(lastblock+thisblock)>>2;
908 if(op.granulepos!=-1){
909 int i,link=vf->current_link;
910 ogg_int64_t granulepos=op.granulepos;
913 granulepos+=vf->pcmlengths[i];
914 vf->pcm_offset=granulepos-accblock;
923 if(_get_next_page(vf,&og,-1)<0){
924 vf->pcm_offset=ov_pcm_total(vf,-1);
928 /* huh? Bogus stream with packets but no granulepos */
933 /* has our decoding just traversed a bitstream boundary? */
934 if(vf->ready_state==STREAMSET)
935 if(vf->current_serialno!=ogg_page_serialno(&og)){
936 _decode_clear(vf); /* clear out stream state */
937 ogg_stream_clear(&work_os);
940 if(vf->ready_state<STREAMSET){
943 vf->current_serialno=ogg_page_serialno(&og);
944 for(link=0;link<vf->links;link++)
945 if(vf->serialnos[link]==vf->current_serialno)break;
946 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
948 machine uninitialized */
949 vf->current_link=link;
951 ogg_stream_init(&vf->os,vf->current_serialno);
952 ogg_stream_reset(&vf->os);
953 ogg_stream_init(&work_os,vf->current_serialno);
954 ogg_stream_reset(&work_os);
955 vf->ready_state=STREAMSET;
959 ogg_stream_pagein(&vf->os,&og);
960 ogg_stream_pagein(&work_os,&og);
961 eosflag=ogg_page_eos(&og);
965 ogg_stream_clear(&work_os);
969 /* dump the machine so we're in a known state */
971 ogg_stream_clear(&work_os);
976 /* Page granularity seek (faster than sample granularity because we
977 don't do the last bit of decode to find a specific sample).
979 Seek to the last [granule marked] page preceeding the specified pos
980 location, such that decoding past the returned point will quickly
981 arrive at the requested position. */
982 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
985 ogg_int64_t total=ov_pcm_total(vf,-1);
987 if(vf->ready_state<OPENED)return(OV_EINVAL);
988 if(!vf->seekable)return(OV_ENOSEEK);
989 if(pos<0 || pos>total)return(OV_EINVAL);
991 /* which bitstream section does this pcm offset occur in? */
992 for(link=vf->links-1;link>=0;link--){
993 total-=vf->pcmlengths[link];
997 /* search within the logical bitstream for the page with the highest
998 pcm_pos preceeding (or equal to) pos. There is a danger here;
999 missing pages or incorrect frame number information in the
1000 bitstream could make our task impossible. Account for that (it
1001 would be an error condition) */
1003 /* new search algorithm by HB (Nicholas Vinen) */
1005 ogg_int64_t target=pos-total;
1006 long end=vf->offsets[link+1];
1007 long begin=vf->offsets[link];
1008 ogg_int64_t endtime = vf->pcmlengths[link];
1009 ogg_int64_t begintime = 0;
1016 if(end-begin<CHUNKSIZE){
1019 /* take a (pretty decent) guess. */
1021 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1025 _seek_helper(vf,bisect);
1028 ret=_get_next_page(vf,&og,end-bisect);
1029 if(ret==OV_EREAD) goto seek_error;
1032 end=begin; /* found it */
1034 if(bisect==0)goto seek_error;
1036 if(bisect<=begin)bisect=begin+1;
1037 _seek_helper(vf,bisect);
1040 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1041 if(granulepos<target){
1042 best=ret; /* raw offset of packet with granulepos */
1043 begin=vf->offset; /* raw offset of next page */
1044 begintime=granulepos;
1046 if(target-begin>44100)break;
1047 bisect=begin; /* *not* begin + 1 */
1050 end=begin; /* found it */
1052 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1054 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1055 if(bisect<=begin)bisect=begin+1;
1056 _seek_helper(vf,bisect);
1068 /* found our page. seek to it, update pcm offset. Easier case than
1069 raw_seek, don't keep packets preceeding granulepos. */
1073 /* clear out decoding machine state */
1076 _seek_helper(vf,best);
1078 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1079 vf->current_serialno=ogg_page_serialno(&og);
1080 vf->current_link=link;
1082 ogg_stream_init(&vf->os,vf->current_serialno);
1083 ogg_stream_reset(&vf->os);
1084 vf->ready_state=STREAMSET;
1085 ogg_stream_pagein(&vf->os,&og);
1087 /* pull out all but last packet; the one with granulepos */
1089 ret=ogg_stream_packetpeek(&vf->os,&op);
1091 /* !!! the packet finishing this page originated on a
1092 preceeding page. Keep fetching previous pages until we
1093 get one with a granulepos or without the 'continued' flag
1094 set. Then just use raw_seek for simplicity. */
1096 ret=_get_prev_page(vf,&og);
1097 if(ret<0)goto seek_error;
1098 if(ogg_page_granulepos(&og)>-1 ||
1099 !ogg_page_continued(&og)){
1100 return ov_raw_seek(vf,ret);
1105 if(ret<0)goto seek_error;
1106 if(op.granulepos!=-1){
1107 vf->pcm_offset=op.granulepos+total;
1110 ret=ogg_stream_packetout(&vf->os,NULL);
1116 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1123 /* dump machine so we're in a known state */
1129 /* seek to a sample offset relative to the decompressed pcm stream
1130 returns zero on success, nonzero on failure */
1132 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1133 int thisblock,lastblock=0;
1134 int ret=ov_pcm_seek_page(vf,pos);
1135 if(ret<0)return(ret);
1136 _make_decode_ready(vf);
1138 /* discard leading packets we don't need for the lapping of the
1139 position we want; don't decode them */
1145 int ret=ogg_stream_packetpeek(&vf->os,&op);
1147 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1148 if(thisblock<0)thisblock=0; /* non audio packet */
1149 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1151 if(vf->pcm_offset+((thisblock+
1152 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1154 /* remove the packet from packet queue and track its granulepos */
1155 ogg_stream_packetout(&vf->os,NULL);
1156 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1159 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1161 /* end of logical stream case is hard, especially with exact
1162 length positioning. */
1164 if(op.granulepos>-1){
1166 /* always believe the stream markers */
1167 vf->pcm_offset=op.granulepos;
1168 for(i=0;i<vf->current_link;i++)
1169 vf->pcm_offset+=vf->pcmlengths[i];
1172 lastblock=thisblock;
1175 if(ret<0 && ret!=OV_HOLE)break;
1177 /* suck in a new page */
1178 if(_get_next_page(vf,&og,-1)<0)break;
1179 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1181 if(vf->ready_state<STREAMSET){
1184 vf->current_serialno=ogg_page_serialno(&og);
1185 for(link=0;link<vf->links;link++)
1186 if(vf->serialnos[link]==vf->current_serialno)break;
1187 if(link==vf->links)return(OV_EBADLINK);
1188 vf->current_link=link;
1190 ogg_stream_init(&vf->os,vf->current_serialno);
1191 ogg_stream_reset(&vf->os);
1192 vf->ready_state=STREAMSET;
1193 _make_decode_ready(vf);
1197 ogg_stream_pagein(&vf->os,&og);
1201 /* discard samples until we reach the desired position. Crossing a
1202 logical bitstream boundary with abandon is OK. */
1203 while(vf->pcm_offset<pos){
1205 long target=pos-vf->pcm_offset;
1206 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1208 if(samples>target)samples=target;
1209 vorbis_synthesis_read(&vf->vd,samples);
1210 vf->pcm_offset+=samples;
1213 if(_fetch_and_process_packet(vf,NULL,1)<=0)
1214 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1219 /* seek to a playback time relative to the decompressed pcm stream
1220 returns zero on success, nonzero on failure */
1221 int ov_time_seek(OggVorbis_File *vf,double seconds){
1222 /* translate time to PCM position and call ov_pcm_seek */
1225 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1226 double time_total=ov_time_total(vf,-1);
1228 if(vf->ready_state<OPENED)return(OV_EINVAL);
1229 if(!vf->seekable)return(OV_ENOSEEK);
1230 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1232 /* which bitstream section does this time offset occur in? */
1233 for(link=vf->links-1;link>=0;link--){
1234 pcm_total-=vf->pcmlengths[link];
1235 time_total-=ov_time_total(vf,link);
1236 if(seconds>=time_total)break;
1239 /* enough information to convert time offset to pcm offset */
1241 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1242 return(ov_pcm_seek(vf,target));
1246 /* page-granularity version of ov_time_seek
1247 returns zero on success, nonzero on failure */
1248 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1249 /* translate time to PCM position and call ov_pcm_seek */
1252 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1253 double time_total=ov_time_total(vf,-1);
1255 if(vf->ready_state<OPENED)return(OV_EINVAL);
1256 if(!vf->seekable)return(OV_ENOSEEK);
1257 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1259 /* which bitstream section does this time offset occur in? */
1260 for(link=vf->links-1;link>=0;link--){
1261 pcm_total-=vf->pcmlengths[link];
1262 time_total-=ov_time_total(vf,link);
1263 if(seconds>=time_total)break;
1266 /* enough information to convert time offset to pcm offset */
1268 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1269 return(ov_pcm_seek_page(vf,target));
1273 /* tell the current stream offset cursor. Note that seek followed by
1274 tell will likely not give the set offset due to caching */
1275 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1276 if(vf->ready_state<OPENED)return(OV_EINVAL);
1280 /* return PCM offset (sample) of next PCM sample to be read */
1281 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1282 if(vf->ready_state<OPENED)return(OV_EINVAL);
1283 return(vf->pcm_offset);
1286 /* return time offset (seconds) of next PCM sample to be read */
1287 double ov_time_tell(OggVorbis_File *vf){
1288 /* translate time to PCM position and call ov_pcm_seek */
1291 ogg_int64_t pcm_total=0;
1292 double time_total=0.f;
1294 if(vf->ready_state<OPENED)return(OV_EINVAL);
1296 pcm_total=ov_pcm_total(vf,-1);
1297 time_total=ov_time_total(vf,-1);
1299 /* which bitstream section does this time offset occur in? */
1300 for(link=vf->links-1;link>=0;link--){
1301 pcm_total-=vf->pcmlengths[link];
1302 time_total-=ov_time_total(vf,link);
1303 if(vf->pcm_offset>=pcm_total)break;
1307 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1310 /* link: -1) return the vorbis_info struct for the bitstream section
1311 currently being decoded
1312 0-n) to request information for a specific bitstream section
1314 In the case of a non-seekable bitstream, any call returns the
1315 current bitstream. NULL in the case that the machine is not
1318 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1321 if(vf->ready_state>=STREAMSET)
1322 return vf->vi+vf->current_link;
1335 /* grr, strong typing, grr, no templates/inheritence, grr */
1336 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1339 if(vf->ready_state>=STREAMSET)
1340 return vf->vc+vf->current_link;
1353 static int host_is_big_endian() {
1354 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1355 unsigned char *bytewise = (unsigned char *)&pattern;
1356 if (bytewise[0] == 0xfe) return 1;
1360 /* up to this point, everything could more or less hide the multiple
1361 logical bitstream nature of chaining from the toplevel application
1362 if the toplevel application didn't particularly care. However, at
1363 the point that we actually read audio back, the multiple-section
1364 nature must surface: Multiple bitstream sections do not necessarily
1365 have to have the same number of channels or sampling rate.
1367 ov_read returns the sequential logical bitstream number currently
1368 being decoded along with the PCM data in order that the toplevel
1369 application can take action on channel/sample rate changes. This
1370 number will be incremented even for streamed (non-seekable) streams
1371 (for seekable streams, it represents the actual logical bitstream
1372 index within the physical bitstream. Note that the accessor
1373 functions above are aware of this dichotomy).
1375 input values: buffer) a buffer to hold packed PCM data for return
1376 length) the byte length requested to be placed into buffer
1377 bigendianp) should the data be packed LSB first (0) or
1379 word) word size for output. currently 1 (byte) or
1382 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1384 n) number of bytes of PCM actually returned. The
1385 below works on a packet-by-packet basis, so the
1386 return length is not related to the 'length' passed
1387 in, just guaranteed to fit.
1389 *section) set to the logical bitstream number */
1391 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int *bitstream){
1393 if(vf->ready_state<OPENED)return(OV_EINVAL);
1396 if(vf->ready_state>=STREAMSET){
1398 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1400 if(pcm_channels)*pcm_channels=pcm;
1401 vorbis_synthesis_read(&vf->vd,samples);
1402 vf->pcm_offset+=samples;
1403 if(bitstream)*bitstream=vf->current_link;
1409 /* suck in another packet */
1411 int ret=_fetch_and_process_packet(vf,NULL,1);
1412 if(ret==OV_EOF)return(0);
1413 if(ret<=0)return(ret);
1419 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1420 int bigendianp,int word,int sgned,int *bitstream){
1422 int host_endian = host_is_big_endian();
1427 if(vf->ready_state<OPENED)return(OV_EINVAL);
1430 if(vf->ready_state>=STREAMSET){
1431 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1435 /* suck in another packet */
1437 int ret=_fetch_and_process_packet(vf,NULL,1);
1438 if(ret==OV_EOF)return(0);
1439 if(ret<=0)return(ret);
1446 /* yay! proceed to pack data into the byte buffer */
1448 long channels=ov_info(vf,-1)->channels;
1449 long bytespersample=word * channels;
1450 vorbis_fpu_control fpu;
1451 if(samples>length/bytespersample)samples=length/bytespersample;
1453 /* a tight loop to pack each size */
1457 int off=(sgned?0:128);
1458 vorbis_fpu_setround(&fpu);
1459 for(j=0;j<samples;j++)
1460 for(i=0;i<channels;i++){
1461 val=vorbis_ftoi(pcm[i][j]*128.f);
1463 else if(val<-128)val=-128;
1466 vorbis_fpu_restore(fpu);
1468 int off=(sgned?0:32768);
1470 if(host_endian==bigendianp){
1473 vorbis_fpu_setround(&fpu);
1474 for(i=0;i<channels;i++) { /* It's faster in this order */
1476 short *dest=((short *)buffer)+i;
1477 for(j=0;j<samples;j++) {
1478 val=vorbis_ftoi(src[j]*32768.f);
1479 if(val>32767)val=32767;
1480 else if(val<-32768)val=-32768;
1485 vorbis_fpu_restore(fpu);
1489 vorbis_fpu_setround(&fpu);
1490 for(i=0;i<channels;i++) {
1492 short *dest=((short *)buffer)+i;
1493 for(j=0;j<samples;j++) {
1494 val=vorbis_ftoi(src[j]*32768.f);
1495 if(val>32767)val=32767;
1496 else if(val<-32768)val=-32768;
1501 vorbis_fpu_restore(fpu);
1504 }else if(bigendianp){
1506 vorbis_fpu_setround(&fpu);
1507 for(j=0;j<samples;j++)
1508 for(i=0;i<channels;i++){
1509 val=vorbis_ftoi(pcm[i][j]*32768.f);
1510 if(val>32767)val=32767;
1511 else if(val<-32768)val=-32768;
1514 *buffer++=(val&0xff);
1516 vorbis_fpu_restore(fpu);
1520 vorbis_fpu_setround(&fpu);
1521 for(j=0;j<samples;j++)
1522 for(i=0;i<channels;i++){
1523 val=vorbis_ftoi(pcm[i][j]*32768.f);
1524 if(val>32767)val=32767;
1525 else if(val<-32768)val=-32768;
1527 *buffer++=(val&0xff);
1530 vorbis_fpu_restore(fpu);
1536 vorbis_synthesis_read(&vf->vd,samples);
1537 vf->pcm_offset+=samples;
1538 if(bitstream)*bitstream=vf->current_link;
1539 return(samples*bytespersample);