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.57 2002/02/28 07:12:20 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;
147 _seek_helper(vf,begin);
148 while(vf->offset<end){
149 ret=_get_next_page(vf,og,end-vf->offset);
150 if(ret==OV_EREAD)return(OV_EREAD);
159 /* we have the offset. Actually snork and hold the page now */
160 _seek_helper(vf,offset);
161 ret=_get_next_page(vf,og,CHUNKSIZE);
163 /* this shouldn't be possible */
169 /* finds each bitstream link one at a time using a bisection search
170 (has to begin by knowing the offset of the lb's initial page).
171 Recurses for each link so it can alloc the link storage after
172 finding them all, then unroll and fill the cache at the same time */
173 static int _bisect_forward_serialno(OggVorbis_File *vf,
179 long endsearched=end;
184 /* the below guards against garbage seperating the last and
185 first pages of two links. */
186 while(searched<endsearched){
189 if(endsearched-searched<CHUNKSIZE){
192 bisect=(searched+endsearched)/2;
195 _seek_helper(vf,bisect);
196 ret=_get_next_page(vf,&og,-1);
197 if(ret==OV_EREAD)return(OV_EREAD);
198 if(ret<0 || ogg_page_serialno(&og)!=currentno){
202 searched=ret+og.header_len+og.body_len;
206 _seek_helper(vf,next);
207 ret=_get_next_page(vf,&og,-1);
208 if(ret==OV_EREAD)return(OV_EREAD);
210 if(searched>=end || ret<0){
212 vf->offsets=_ogg_malloc((m+2)*sizeof(*vf->offsets));
213 vf->offsets[m+1]=searched;
215 ret=_bisect_forward_serialno(vf,next,vf->offset,
216 end,ogg_page_serialno(&og),m+1);
217 if(ret==OV_EREAD)return(OV_EREAD);
220 vf->offsets[m]=begin;
224 /* uses the local ogg_stream storage in vf; this is important for
225 non-streaming input sources */
226 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
227 long *serialno,ogg_page *og_ptr){
233 ret=_get_next_page(vf,&og,CHUNKSIZE);
234 if(ret==OV_EREAD)return(OV_EREAD);
235 if(ret<0)return OV_ENOTVORBIS;
239 if(serialno)*serialno=ogg_page_serialno(og_ptr);
240 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
241 vf->ready_state=STREAMSET;
243 /* extract the initial header from the first page and verify that the
244 Ogg bitstream is in fact Vorbis data */
246 vorbis_info_init(vi);
247 vorbis_comment_init(vc);
251 ogg_stream_pagein(&vf->os,og_ptr);
253 int result=ogg_stream_packetout(&vf->os,&op);
259 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
265 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
273 vorbis_info_clear(vi);
274 vorbis_comment_clear(vc);
275 ogg_stream_clear(&vf->os);
276 vf->ready_state=OPENED;
281 /* last step of the OggVorbis_File initialization; get all the
282 vorbis_info structs and PCM positions. Only called by the seekable
283 initialization (local stream storage is hacked slightly; pay
284 attention to how that's done) */
286 /* this is void and does not propogate errors up because we want to be
287 able to open and use damaged bitstreams as well as we can. Just
288 watch out for missing information for links in the OggVorbis_File
290 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
294 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
295 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
296 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
297 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(*vf->pcmlengths));
298 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
300 for(i=0;i<vf->links;i++){
302 /* we already grabbed the initial header earlier. Just set the offset */
303 vf->dataoffsets[i]=dataoffset;
306 /* seek to the location of the initial header */
308 _seek_helper(vf,vf->offsets[i]);
309 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
310 vf->dataoffsets[i]=-1;
312 vf->dataoffsets[i]=vf->offset;
313 ogg_stream_clear(&vf->os);
317 /* get the serial number and PCM length of this link. To do this,
318 get the last page of the stream */
320 long end=vf->offsets[i+1];
321 _seek_helper(vf,end);
324 ret=_get_prev_page(vf,&og);
326 /* this should not be possible */
327 vorbis_info_clear(vf->vi+i);
328 vorbis_comment_clear(vf->vc+i);
331 if(ogg_page_granulepos(&og)!=-1){
332 vf->serialnos[i]=ogg_page_serialno(&og);
333 vf->pcmlengths[i]=ogg_page_granulepos(&og);
342 static void _make_decode_ready(OggVorbis_File *vf){
343 if(vf->ready_state!=STREAMSET)return;
345 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
347 vorbis_synthesis_init(&vf->vd,vf->vi);
349 vorbis_block_init(&vf->vd,&vf->vb);
350 vf->ready_state=INITSET;
354 static int _open_seekable2(OggVorbis_File *vf){
355 long serialno=vf->current_serialno,end;
356 long dataoffset=vf->offset;
359 /* we're partially open and have a first link header state in
361 /* we can seek, so set out learning all about this file */
362 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
363 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
365 /* We get the offset for the last page of the physical bitstream.
366 Most OggVorbis files will contain a single logical bitstream */
367 end=_get_prev_page(vf,&og);
373 /* more than one logical bitstream? */
374 if(ogg_page_serialno(&og)!=serialno){
376 /* Chained bitstream. Bisect-search each logical bitstream
377 section. Do so based on serial number only */
378 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
385 /* Only one logical bitstream */
386 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
393 /* the initial header memory is referenced by vf after; don't free it */
394 _prefetch_all_headers(vf,dataoffset);
395 return(ov_raw_seek(vf,0));
398 /* clear out the current logical bitstream decoder */
399 static void _decode_clear(OggVorbis_File *vf){
400 ogg_stream_clear(&vf->os);
401 vorbis_dsp_clear(&vf->vd);
402 vorbis_block_clear(&vf->vb);
403 vf->ready_state=OPENED;
409 /* fetch and process a packet. Handles the case where we're at a
410 bitstream boundary and dumps the decoding machine. If the decoding
411 machine is unloaded, it loads it. It also keeps pcm_offset up to
412 date (seek and read both use this. seek uses a special hack with
415 return: <0) error, OV_HOLE (lost packet) or OV_EOF
416 0) need more data (only if readp==0)
420 static int _fetch_and_process_packet(OggVorbis_File *vf,
425 /* handle one packet. Try to fetch it from current stream state */
426 /* extract packets from page */
429 /* process a packet if we can. If the machine isn't loaded,
431 if(vf->ready_state==INITSET){
434 ogg_packet *op_ptr=(op_in?op_in:&op);
435 int result=ogg_stream_packetout(&vf->os,op_ptr);
436 ogg_int64_t granulepos;
439 if(result==-1)return(OV_HOLE); /* hole in the data. */
441 /* got a packet. process it */
442 granulepos=op_ptr->granulepos;
443 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
445 header packets aren't
448 vorbis_synthesis will
451 /* suck in the synthesis data and track bitrate */
453 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
454 /* for proper use of libvorbis within libvorbisfile,
455 oldsamples will always be zero. */
456 if(oldsamples)return(OV_EFAULT);
458 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
459 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
460 vf->bittrack+=op_ptr->bytes*8;
463 /* update the pcm offset. */
464 if(granulepos!=-1 && !op_ptr->e_o_s){
465 int link=(vf->seekable?vf->current_link:0);
468 /* this packet has a pcm_offset on it (the last packet
469 completed on a page carries the offset) After processing
470 (above), we know the pcm position of the *last* sample
471 ready to be returned. Find the offset of the *first*
473 As an aside, this trick is inaccurate if we begin
474 reading anew right at the last page; the end-of-stream
475 granulepos declares the last frame in the stream, and the
476 last packet of the last page may be a partial frame.
477 So, we need a previous granulepos from an in-sequence page
478 to have a reference point. Thus the !op_ptr->e_o_s clause
481 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
485 granulepos+=vf->pcmlengths[i];
486 vf->pcm_offset=granulepos;
496 if(vf->ready_state>=OPENED){
498 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
500 /* bitrate tracking; add the header's bytes here, the body bytes
501 are done by packet above */
502 vf->bittrack+=og.header_len*8;
504 /* has our decoding just traversed a bitstream boundary? */
505 if(vf->ready_state==INITSET){
506 if(vf->current_serialno!=ogg_page_serialno(&og)){
510 vorbis_info_clear(vf->vi);
511 vorbis_comment_clear(vf->vc);
517 /* Do we need to load a new machine before submitting the page? */
518 /* This is different in the seekable and non-seekable cases.
520 In the seekable case, we already have all the header
521 information loaded and cached; we just initialize the machine
522 with it and continue on our merry way.
524 In the non-seekable (streaming) case, we'll only be at a
525 boundary if we just left the previous logical bitstream and
526 we're now nominally at the header of the next bitstream
529 if(vf->ready_state!=INITSET){
532 if(vf->ready_state<STREAMSET){
534 vf->current_serialno=ogg_page_serialno(&og);
536 /* match the serialno to bitstream section. We use this rather than
537 offset positions to avoid problems near logical bitstream
539 for(link=0;link<vf->links;link++)
540 if(vf->serialnos[link]==vf->current_serialno)break;
541 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
546 vf->current_link=link;
548 ogg_stream_init(&vf->os,vf->current_serialno);
549 ogg_stream_reset(&vf->os);
550 vf->ready_state=STREAMSET;
553 /* we're streaming */
554 /* fetch the three header packets, build the info struct */
556 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
563 _make_decode_ready(vf);
565 ogg_stream_pagein(&vf->os,&og);
569 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
570 if(f==NULL)return(-1);
571 return fseek(f,(int)off,whence);
574 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
575 long ibytes, ov_callbacks callbacks){
576 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
579 memset(vf,0,sizeof(*vf));
581 vf->callbacks = callbacks;
583 /* init the framing state */
584 ogg_sync_init(&vf->oy);
586 /* perhaps some data was previously read into a buffer for testing
587 against other stream types. Allow initialization from this
588 previously read data (as we may be reading from a non-seekable
591 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
592 memcpy(buffer,initial,ibytes);
593 ogg_sync_wrote(&vf->oy,ibytes);
596 /* can we seek? Stevens suggests the seek test was portable */
597 if(offset!=-1)vf->seekable=1;
599 /* No seeking yet; Set up a 'single' (current) logical bitstream
600 entry for partial open */
602 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
603 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
605 /* Try to fetch the headers, maintaining all the storage */
606 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
609 }else if(vf->ready_state < PARTOPEN)
610 vf->ready_state=PARTOPEN;
614 static int _ov_open2(OggVorbis_File *vf){
615 if(vf->ready_state < OPENED)
616 vf->ready_state=OPENED;
618 int ret=_open_seekable2(vf);
629 /* clear out the OggVorbis_File struct */
630 int ov_clear(OggVorbis_File *vf){
632 vorbis_block_clear(&vf->vb);
633 vorbis_dsp_clear(&vf->vd);
634 ogg_stream_clear(&vf->os);
636 if(vf->vi && vf->links){
638 for(i=0;i<vf->links;i++){
639 vorbis_info_clear(vf->vi+i);
640 vorbis_comment_clear(vf->vc+i);
645 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
646 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
647 if(vf->serialnos)_ogg_free(vf->serialnos);
648 if(vf->offsets)_ogg_free(vf->offsets);
649 ogg_sync_clear(&vf->oy);
650 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
651 memset(vf,0,sizeof(*vf));
659 /* inspects the OggVorbis file and finds/documents all the logical
660 bitstreams contained in it. Tries to be tolerant of logical
661 bitstream sections that are truncated/woogie.
667 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
668 ov_callbacks callbacks){
669 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
671 return _ov_open2(vf);
674 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
675 ov_callbacks callbacks = {
676 (size_t (*)(void *, size_t, size_t, void *)) fread,
677 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
678 (int (*)(void *)) fclose,
679 (long (*)(void *)) ftell
682 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
685 /* Only partially open the vorbis file; test for Vorbisness, and load
686 the headers for the first chain. Do not seek (although test for
687 seekability). Use ov_test_open to finish opening the file, else
688 ov_clear to close/free it. Same return codes as open. */
690 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
691 ov_callbacks callbacks)
693 return _ov_open1(f,vf,initial,ibytes,callbacks);
696 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
697 ov_callbacks callbacks = {
698 (size_t (*)(void *, size_t, size_t, void *)) fread,
699 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
700 (int (*)(void *)) fclose,
701 (long (*)(void *)) ftell
704 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
707 int ov_test_open(OggVorbis_File *vf){
708 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
709 return _ov_open2(vf);
712 /* How many logical bitstreams in this physical bitstream? */
713 long ov_streams(OggVorbis_File *vf){
717 /* Is the FILE * associated with vf seekable? */
718 long ov_seekable(OggVorbis_File *vf){
722 /* returns the bitrate for a given logical bitstream or the entire
723 physical bitstream. If the file is open for random access, it will
724 find the *actual* average bitrate. If the file is streaming, it
725 returns the nominal bitrate (if set) else the average of the
726 upper/lower bounds (if set) else -1 (unset).
728 If you want the actual bitrate field settings, get them from the
729 vorbis_info structs */
731 long ov_bitrate(OggVorbis_File *vf,int i){
732 if(vf->ready_state<OPENED)return(OV_EINVAL);
733 if(i>=vf->links)return(OV_EINVAL);
734 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
738 for(i=0;i<vf->links;i++)
739 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
740 return(rint(bits/ov_time_total(vf,-1)));
743 /* return the actual bitrate */
744 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
746 /* return nominal if set */
747 if(vf->vi[i].bitrate_nominal>0){
748 return vf->vi[i].bitrate_nominal;
750 if(vf->vi[i].bitrate_upper>0){
751 if(vf->vi[i].bitrate_lower>0){
752 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
754 return vf->vi[i].bitrate_upper;
763 /* returns the actual bitrate since last call. returns -1 if no
764 additional data to offer since last call (or at beginning of stream),
765 EINVAL if stream is only partially open
767 long ov_bitrate_instant(OggVorbis_File *vf){
768 int link=(vf->seekable?vf->current_link:0);
770 if(vf->ready_state<OPENED)return(OV_EINVAL);
771 if(vf->samptrack==0)return(OV_FALSE);
772 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
779 long ov_serialnumber(OggVorbis_File *vf,int i){
780 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
781 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
783 return(vf->current_serialno);
785 return(vf->serialnos[i]);
789 /* returns: total raw (compressed) length of content if i==-1
790 raw (compressed) length of that logical bitstream for i==0 to n
791 OV_EINVAL if the stream is not seekable (we can't know the length)
792 or if stream is only partially open
794 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
795 if(vf->ready_state<OPENED)return(OV_EINVAL);
796 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
800 for(i=0;i<vf->links;i++)
801 acc+=ov_raw_total(vf,i);
804 return(vf->offsets[i+1]-vf->offsets[i]);
808 /* returns: total PCM length (samples) of content if i==-1 PCM length
809 (samples) of that logical bitstream for i==0 to n
810 OV_EINVAL if the stream is not seekable (we can't know the
811 length) or only partially open
813 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
814 if(vf->ready_state<OPENED)return(OV_EINVAL);
815 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
819 for(i=0;i<vf->links;i++)
820 acc+=ov_pcm_total(vf,i);
823 return(vf->pcmlengths[i]);
827 /* returns: total seconds of content if i==-1
828 seconds in that logical bitstream for i==0 to n
829 OV_EINVAL if the stream is not seekable (we can't know the
830 length) or only partially open
832 double ov_time_total(OggVorbis_File *vf,int i){
833 if(vf->ready_state<OPENED)return(OV_EINVAL);
834 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
838 for(i=0;i<vf->links;i++)
839 acc+=ov_time_total(vf,i);
842 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
846 /* seek to an offset relative to the *compressed* data. This also
847 scans packets to update the PCM cursor. It will cross a logical
848 bitstream boundary, but only if it can't get any packets out of the
849 tail of the bitstream we seek to (so no surprises).
851 returns zero on success, nonzero on failure */
853 int ov_raw_seek(OggVorbis_File *vf,long pos){
854 ogg_stream_state work_os;
856 if(vf->ready_state<OPENED)return(OV_EINVAL);
858 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
860 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
862 /* clear out decoding machine state */
866 _seek_helper(vf,pos);
868 /* we need to make sure the pcm_offset is set, but we don't want to
869 advance the raw cursor past good packets just to get to the first
870 with a granulepos. That's not equivalent behavior to beginning
871 decoding as immediately after the seek position as possible.
873 So, a hack. We use two stream states; a local scratch state and
874 a the shared vf->os stream state. We use the local state to
875 scan, and the shared state as a buffer for later decode.
877 Unfortuantely, on the last page we still advance to last packet
878 because the granulepos on the last page is not necessarily on a
879 packet boundary, and we need to make sure the granpos is
891 memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
892 it later even if we don't
896 if(vf->ready_state==STREAMSET){
897 /* snarf/scan a packet if we can */
898 int result=ogg_stream_packetout(&work_os,&op);
902 if(vf->vi[vf->current_link].codec_setup)
903 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
905 ogg_stream_packetout(&vf->os,NULL);
907 if(lastblock)accblock+=(lastblock+thisblock)>>2;
909 if(op.granulepos!=-1){
910 int i,link=vf->current_link;
911 ogg_int64_t granulepos=op.granulepos;
914 granulepos+=vf->pcmlengths[i];
915 vf->pcm_offset=granulepos-accblock;
924 if(_get_next_page(vf,&og,-1)<0){
925 vf->pcm_offset=ov_pcm_total(vf,-1);
929 /* huh? Bogus stream with packets but no granulepos */
934 /* has our decoding just traversed a bitstream boundary? */
935 if(vf->ready_state==STREAMSET)
936 if(vf->current_serialno!=ogg_page_serialno(&og)){
937 _decode_clear(vf); /* clear out stream state */
938 ogg_stream_clear(&work_os);
941 if(vf->ready_state<STREAMSET){
944 vf->current_serialno=ogg_page_serialno(&og);
945 for(link=0;link<vf->links;link++)
946 if(vf->serialnos[link]==vf->current_serialno)break;
947 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
949 machine uninitialized */
950 vf->current_link=link;
952 ogg_stream_init(&vf->os,vf->current_serialno);
953 ogg_stream_reset(&vf->os);
954 ogg_stream_init(&work_os,vf->current_serialno);
955 ogg_stream_reset(&work_os);
956 vf->ready_state=STREAMSET;
960 ogg_stream_pagein(&vf->os,&og);
961 ogg_stream_pagein(&work_os,&og);
962 eosflag=ogg_page_eos(&og);
966 ogg_stream_clear(&work_os);
970 /* dump the machine so we're in a known state */
972 ogg_stream_clear(&work_os);
977 /* Page granularity seek (faster than sample granularity because we
978 don't do the last bit of decode to find a specific sample).
980 Seek to the last [granule marked] page preceeding the specified pos
981 location, such that decoding past the returned point will quickly
982 arrive at the requested position. */
983 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
986 ogg_int64_t total=ov_pcm_total(vf,-1);
988 if(vf->ready_state<OPENED)return(OV_EINVAL);
989 if(!vf->seekable)return(OV_ENOSEEK);
990 if(pos<0 || pos>total)return(OV_EINVAL);
992 /* which bitstream section does this pcm offset occur in? */
993 for(link=vf->links-1;link>=0;link--){
994 total-=vf->pcmlengths[link];
998 /* search within the logical bitstream for the page with the highest
999 pcm_pos preceeding (or equal to) pos. There is a danger here;
1000 missing pages or incorrect frame number information in the
1001 bitstream could make our task impossible. Account for that (it
1002 would be an error condition) */
1004 /* new search algorithm by HB (Nicholas Vinen) */
1006 ogg_int64_t target=pos-total;
1007 long end=vf->offsets[link+1];
1008 long begin=vf->offsets[link];
1009 ogg_int64_t endtime = vf->pcmlengths[link];
1010 ogg_int64_t begintime = 0;
1017 if(end-begin<CHUNKSIZE){
1020 /* take a (pretty decent) guess. */
1022 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1026 _seek_helper(vf,bisect);
1029 ret=_get_next_page(vf,&og,end-bisect);
1030 if(ret==OV_EREAD) goto seek_error;
1033 end=begin; /* found it */
1035 if(bisect==0)goto seek_error;
1037 if(bisect<=begin)bisect=begin+1;
1038 _seek_helper(vf,bisect);
1041 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1042 if(granulepos<target){
1043 best=ret; /* raw offset of packet with granulepos */
1044 begin=vf->offset; /* raw offset of next page */
1045 begintime=granulepos;
1047 if(target-begin>44100)break;
1048 bisect=begin; /* *not* begin + 1 */
1051 end=begin; /* found it */
1053 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1055 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1056 if(bisect<=begin)bisect=begin+1;
1057 _seek_helper(vf,bisect);
1069 /* found our page. seek to it, update pcm offset. Easier case than
1070 raw_seek, don't keep packets preceeding granulepos. */
1074 /* clear out decoding machine state */
1077 _seek_helper(vf,best);
1079 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1080 vf->current_serialno=ogg_page_serialno(&og);
1081 vf->current_link=link;
1083 ogg_stream_init(&vf->os,vf->current_serialno);
1084 ogg_stream_reset(&vf->os);
1085 vf->ready_state=STREAMSET;
1086 ogg_stream_pagein(&vf->os,&og);
1088 /* pull out all but last packet; the one with granulepos */
1090 ret=ogg_stream_packetpeek(&vf->os,&op);
1092 /* !!! the packet finishing this page originated on a
1093 preceeding page. Keep fetching previous pages until we
1094 get one with a granulepos or without the 'continued' flag
1095 set. Then just use raw_seek for simplicity. */
1098 _seek_helper(vf,best);
1101 ret=_get_prev_page(vf,&og);
1102 if(ret<0)goto seek_error;
1103 if(ogg_page_granulepos(&og)>-1 ||
1104 !ogg_page_continued(&og)){
1105 return ov_raw_seek(vf,ret);
1110 if(ret<0)goto seek_error;
1111 if(op.granulepos!=-1){
1112 vf->pcm_offset=op.granulepos+total;
1115 ret=ogg_stream_packetout(&vf->os,NULL);
1121 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1128 /* dump machine so we're in a known state */
1134 /* seek to a sample offset relative to the decompressed pcm stream
1135 returns zero on success, nonzero on failure */
1137 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1138 int thisblock,lastblock=0;
1139 int ret=ov_pcm_seek_page(vf,pos);
1140 if(ret<0)return(ret);
1141 _make_decode_ready(vf);
1143 /* discard leading packets we don't need for the lapping of the
1144 position we want; don't decode them */
1150 int ret=ogg_stream_packetpeek(&vf->os,&op);
1152 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1153 if(thisblock<0)thisblock=0; /* non audio packet */
1154 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1156 if(vf->pcm_offset+((thisblock+
1157 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1159 /* remove the packet from packet queue and track its granulepos */
1160 ogg_stream_packetout(&vf->os,NULL);
1161 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1164 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1166 /* end of logical stream case is hard, especially with exact
1167 length positioning. */
1169 if(op.granulepos>-1){
1171 /* always believe the stream markers */
1172 vf->pcm_offset=op.granulepos;
1173 for(i=0;i<vf->current_link;i++)
1174 vf->pcm_offset+=vf->pcmlengths[i];
1177 lastblock=thisblock;
1180 if(ret<0 && ret!=OV_HOLE)break;
1182 /* suck in a new page */
1183 if(_get_next_page(vf,&og,-1)<0)break;
1184 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1186 if(vf->ready_state<STREAMSET){
1189 vf->current_serialno=ogg_page_serialno(&og);
1190 for(link=0;link<vf->links;link++)
1191 if(vf->serialnos[link]==vf->current_serialno)break;
1192 if(link==vf->links)return(OV_EBADLINK);
1193 vf->current_link=link;
1195 ogg_stream_init(&vf->os,vf->current_serialno);
1196 ogg_stream_reset(&vf->os);
1197 vf->ready_state=STREAMSET;
1198 _make_decode_ready(vf);
1202 ogg_stream_pagein(&vf->os,&og);
1206 /* discard samples until we reach the desired position. Crossing a
1207 logical bitstream boundary with abandon is OK. */
1208 while(vf->pcm_offset<pos){
1210 long target=pos-vf->pcm_offset;
1211 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1213 if(samples>target)samples=target;
1214 vorbis_synthesis_read(&vf->vd,samples);
1215 vf->pcm_offset+=samples;
1218 if(_fetch_and_process_packet(vf,NULL,1)<=0)
1219 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1224 /* seek to a playback time relative to the decompressed pcm stream
1225 returns zero on success, nonzero on failure */
1226 int ov_time_seek(OggVorbis_File *vf,double seconds){
1227 /* translate time to PCM position and call ov_pcm_seek */
1230 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1231 double time_total=ov_time_total(vf,-1);
1233 if(vf->ready_state<OPENED)return(OV_EINVAL);
1234 if(!vf->seekable)return(OV_ENOSEEK);
1235 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1237 /* which bitstream section does this time offset occur in? */
1238 for(link=vf->links-1;link>=0;link--){
1239 pcm_total-=vf->pcmlengths[link];
1240 time_total-=ov_time_total(vf,link);
1241 if(seconds>=time_total)break;
1244 /* enough information to convert time offset to pcm offset */
1246 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1247 return(ov_pcm_seek(vf,target));
1251 /* page-granularity version of ov_time_seek
1252 returns zero on success, nonzero on failure */
1253 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1254 /* translate time to PCM position and call ov_pcm_seek */
1257 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1258 double time_total=ov_time_total(vf,-1);
1260 if(vf->ready_state<OPENED)return(OV_EINVAL);
1261 if(!vf->seekable)return(OV_ENOSEEK);
1262 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1264 /* which bitstream section does this time offset occur in? */
1265 for(link=vf->links-1;link>=0;link--){
1266 pcm_total-=vf->pcmlengths[link];
1267 time_total-=ov_time_total(vf,link);
1268 if(seconds>=time_total)break;
1271 /* enough information to convert time offset to pcm offset */
1273 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1274 return(ov_pcm_seek_page(vf,target));
1278 /* tell the current stream offset cursor. Note that seek followed by
1279 tell will likely not give the set offset due to caching */
1280 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1281 if(vf->ready_state<OPENED)return(OV_EINVAL);
1285 /* return PCM offset (sample) of next PCM sample to be read */
1286 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1287 if(vf->ready_state<OPENED)return(OV_EINVAL);
1288 return(vf->pcm_offset);
1291 /* return time offset (seconds) of next PCM sample to be read */
1292 double ov_time_tell(OggVorbis_File *vf){
1293 /* translate time to PCM position and call ov_pcm_seek */
1296 ogg_int64_t pcm_total=0;
1297 double time_total=0.f;
1299 if(vf->ready_state<OPENED)return(OV_EINVAL);
1301 pcm_total=ov_pcm_total(vf,-1);
1302 time_total=ov_time_total(vf,-1);
1304 /* which bitstream section does this time offset occur in? */
1305 for(link=vf->links-1;link>=0;link--){
1306 pcm_total-=vf->pcmlengths[link];
1307 time_total-=ov_time_total(vf,link);
1308 if(vf->pcm_offset>=pcm_total)break;
1312 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1315 /* link: -1) return the vorbis_info struct for the bitstream section
1316 currently being decoded
1317 0-n) to request information for a specific bitstream section
1319 In the case of a non-seekable bitstream, any call returns the
1320 current bitstream. NULL in the case that the machine is not
1323 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1326 if(vf->ready_state>=STREAMSET)
1327 return vf->vi+vf->current_link;
1340 /* grr, strong typing, grr, no templates/inheritence, grr */
1341 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1344 if(vf->ready_state>=STREAMSET)
1345 return vf->vc+vf->current_link;
1358 static int host_is_big_endian() {
1359 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1360 unsigned char *bytewise = (unsigned char *)&pattern;
1361 if (bytewise[0] == 0xfe) return 1;
1365 /* up to this point, everything could more or less hide the multiple
1366 logical bitstream nature of chaining from the toplevel application
1367 if the toplevel application didn't particularly care. However, at
1368 the point that we actually read audio back, the multiple-section
1369 nature must surface: Multiple bitstream sections do not necessarily
1370 have to have the same number of channels or sampling rate.
1372 ov_read returns the sequential logical bitstream number currently
1373 being decoded along with the PCM data in order that the toplevel
1374 application can take action on channel/sample rate changes. This
1375 number will be incremented even for streamed (non-seekable) streams
1376 (for seekable streams, it represents the actual logical bitstream
1377 index within the physical bitstream. Note that the accessor
1378 functions above are aware of this dichotomy).
1380 input values: buffer) a buffer to hold packed PCM data for return
1381 length) the byte length requested to be placed into buffer
1382 bigendianp) should the data be packed LSB first (0) or
1384 word) word size for output. currently 1 (byte) or
1387 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1389 n) number of bytes of PCM actually returned. The
1390 below works on a packet-by-packet basis, so the
1391 return length is not related to the 'length' passed
1392 in, just guaranteed to fit.
1394 *section) set to the logical bitstream number */
1396 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int *bitstream){
1398 if(vf->ready_state<OPENED)return(OV_EINVAL);
1401 if(vf->ready_state>=STREAMSET){
1403 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1405 if(pcm_channels)*pcm_channels=pcm;
1406 vorbis_synthesis_read(&vf->vd,samples);
1407 vf->pcm_offset+=samples;
1408 if(bitstream)*bitstream=vf->current_link;
1414 /* suck in another packet */
1416 int ret=_fetch_and_process_packet(vf,NULL,1);
1417 if(ret==OV_EOF)return(0);
1418 if(ret<=0)return(ret);
1424 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1425 int bigendianp,int word,int sgned,int *bitstream){
1427 int host_endian = host_is_big_endian();
1432 if(vf->ready_state<OPENED)return(OV_EINVAL);
1435 if(vf->ready_state>=STREAMSET){
1436 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1440 /* suck in another packet */
1442 int ret=_fetch_and_process_packet(vf,NULL,1);
1443 if(ret==OV_EOF)return(0);
1444 if(ret<=0)return(ret);
1451 /* yay! proceed to pack data into the byte buffer */
1453 long channels=ov_info(vf,-1)->channels;
1454 long bytespersample=word * channels;
1455 vorbis_fpu_control fpu;
1456 if(samples>length/bytespersample)samples=length/bytespersample;
1458 /* a tight loop to pack each size */
1462 int off=(sgned?0:128);
1463 vorbis_fpu_setround(&fpu);
1464 for(j=0;j<samples;j++)
1465 for(i=0;i<channels;i++){
1466 val=vorbis_ftoi(pcm[i][j]*128.f);
1468 else if(val<-128)val=-128;
1471 vorbis_fpu_restore(fpu);
1473 int off=(sgned?0:32768);
1475 if(host_endian==bigendianp){
1478 vorbis_fpu_setround(&fpu);
1479 for(i=0;i<channels;i++) { /* It's faster in this order */
1481 short *dest=((short *)buffer)+i;
1482 for(j=0;j<samples;j++) {
1483 val=vorbis_ftoi(src[j]*32768.f);
1484 if(val>32767)val=32767;
1485 else if(val<-32768)val=-32768;
1490 vorbis_fpu_restore(fpu);
1494 vorbis_fpu_setround(&fpu);
1495 for(i=0;i<channels;i++) {
1497 short *dest=((short *)buffer)+i;
1498 for(j=0;j<samples;j++) {
1499 val=vorbis_ftoi(src[j]*32768.f);
1500 if(val>32767)val=32767;
1501 else if(val<-32768)val=-32768;
1506 vorbis_fpu_restore(fpu);
1509 }else if(bigendianp){
1511 vorbis_fpu_setround(&fpu);
1512 for(j=0;j<samples;j++)
1513 for(i=0;i<channels;i++){
1514 val=vorbis_ftoi(pcm[i][j]*32768.f);
1515 if(val>32767)val=32767;
1516 else if(val<-32768)val=-32768;
1519 *buffer++=(val&0xff);
1521 vorbis_fpu_restore(fpu);
1525 vorbis_fpu_setround(&fpu);
1526 for(j=0;j<samples;j++)
1527 for(i=0;i<channels;i++){
1528 val=vorbis_ftoi(pcm[i][j]*32768.f);
1529 if(val>32767)val=32767;
1530 else if(val<-32768)val=-32768;
1532 *buffer++=(val&0xff);
1535 vorbis_fpu_restore(fpu);
1541 vorbis_synthesis_read(&vf->vd,samples);
1542 vf->pcm_offset+=samples;
1543 if(bitstream)*bitstream=vf->current_link;
1544 return(samples*bytespersample);