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-2009 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: stdio-based convenience library for opening/seeking/decoding
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 65536
63 static long _get_data(OggVorbis_File *vf){
65 if(!(vf->callbacks.read_func))return(-1);
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 int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
79 if(!(vf->callbacks.seek_func)||
80 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
83 ogg_sync_reset(&vf->oy);
85 /* shouldn't happen unless someone writes a broken callback */
91 /* The read/seek functions track absolute position within the stream */
93 /* from the head of the stream, get the next page. boundary specifies
94 if the function is allowed to fetch more data from the stream (and
95 how much) or only use internally buffered data.
97 boundary: -1) unbounded search
98 0) read no additional data; use cached only
99 n) search for a new page beginning for n bytes
101 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
102 n) found a page at absolute offset n */
104 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
105 ogg_int64_t boundary){
106 if(boundary>0)boundary+=vf->offset;
110 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
111 more=ogg_sync_pageseek(&vf->oy,og);
114 /* skipped n bytes */
118 /* send more paramedics */
119 if(!boundary)return(OV_FALSE);
121 long ret=_get_data(vf);
122 if(ret==0)return(OV_EOF);
123 if(ret<0)return(OV_EREAD);
126 /* got a page. Return the offset at the page beginning,
127 advance the internal offset past the page end */
128 ogg_int64_t ret=vf->offset;
137 /* find the latest page beginning before the current stream cursor
138 position. Much dirtier than the above as Ogg doesn't have any
139 backward search linkage. no 'readp' as it will certainly have to
141 /* returns offset or OV_EREAD, OV_FAULT */
142 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
143 ogg_int64_t begin=vf->offset;
144 ogg_int64_t end=begin;
146 ogg_int64_t offset=-1;
153 ret=_seek_helper(vf,begin);
156 while(vf->offset<end){
157 memset(og,0,sizeof(*og));
158 ret=_get_next_page(vf,og,end-vf->offset);
159 if(ret==OV_EREAD)return(OV_EREAD);
168 /* In a fully compliant, non-multiplexed stream, we'll still be
169 holding the last page. In multiplexed (or noncompliant streams),
170 we will probably have to re-read the last page we saw */
171 if(og->header_len==0){
172 ret=_seek_helper(vf,offset);
175 ret=_get_next_page(vf,og,CHUNKSIZE);
177 /* this shouldn't be possible */
184 static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
185 long s = ogg_page_serialno(og);
189 *serialno_list = _ogg_realloc(*serialno_list, sizeof(**serialno_list)*(*n));
191 *serialno_list = _ogg_malloc(sizeof(**serialno_list));
194 (*serialno_list)[(*n)-1] = s;
197 /* returns nonzero if found */
198 static int _lookup_serialno(long s, long *serialno_list, int n){
201 if(*serialno_list == s) return 1;
208 static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
209 long s = ogg_page_serialno(og);
210 return _lookup_serialno(s,serialno_list,n);
213 /* performs the same search as _get_prev_page, but prefers pages of
214 the specified serial number. If a page of the specified serialno is
215 spotted during the seek-back-and-read-forward, it will return the
216 info of last page of the matching serial number instead of the very
217 last page. If no page of the specified serialno is seen, it will
218 return the info of last page and alter *serialno. */
219 static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
220 long *serial_list, int serial_n,
221 int *serialno, ogg_int64_t *granpos){
223 ogg_int64_t begin=vf->offset;
224 ogg_int64_t end=begin;
227 ogg_int64_t prefoffset=-1;
228 ogg_int64_t offset=-1;
229 ogg_int64_t ret_serialno;
230 ogg_int64_t ret_gran;
237 ret=_seek_helper(vf,begin);
240 while(vf->offset<end){
241 ret=_get_next_page(vf,&og,end-vf->offset);
242 if(ret==OV_EREAD)return(OV_EREAD);
246 ret_serialno=ogg_page_serialno(&og);
247 ret_gran=ogg_page_granulepos(&og);
250 if(ret_serialno == *serialno){
255 if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){
256 /* we fell off the end of the link, which means we seeked
257 back too far and shouldn't have been looking in that link
258 to begin with. If we found the preferred serial number,
259 forget that we saw it. */
266 /* we're not interested in the page... just the serialno and granpos. */
267 if(prefoffset>=0)return(prefoffset);
269 *serialno = ret_serialno;
275 /* uses the local ogg_stream storage in vf; this is important for
276 non-streaming input sources */
277 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
278 long **serialno_list, int *serialno_n,
286 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
287 if(llret==OV_EREAD)return(OV_EREAD);
288 if(llret<0)return(OV_ENOTVORBIS);
292 vorbis_info_init(vi);
293 vorbis_comment_init(vc);
294 vf->ready_state=OPENED;
296 /* extract the serialnos of all BOS pages + the first set of vorbis
297 headers we see in the link */
299 while(ogg_page_bos(og_ptr)){
301 if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
302 /* a dupe serialnumber in an initial header packet set == invalid stream */
303 if(*serialno_list)_ogg_free(*serialno_list);
310 _add_serialno(og_ptr,serialno_list,serialno_n);
313 if(vf->ready_state<STREAMSET){
314 /* we don't have a vorbis stream in this link yet, so begin
315 prospective stream setup. We need a stream to get packets */
316 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
317 ogg_stream_pagein(&vf->os,og_ptr);
319 if(ogg_stream_packetout(&vf->os,&op) > 0 &&
320 vorbis_synthesis_idheader(&op)){
321 /* vorbis header; continue setup */
322 vf->ready_state=STREAMSET;
323 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
332 ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
342 /* if this page also belongs to our vorbis stream, submit it and break */
343 if(vf->ready_state==STREAMSET &&
344 vf->os.serialno == ogg_page_serialno(og_ptr)){
345 ogg_stream_pagein(&vf->os,og_ptr);
351 if(vf->ready_state!=STREAMSET){
359 while(i<2){ /* get a page loop */
361 while(i<2){ /* get a packet loop */
363 int result=ogg_stream_packetout(&vf->os,&op);
370 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
377 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
382 /* if this page belongs to the correct stream, go parse it */
383 if(vf->os.serialno == ogg_page_serialno(og_ptr)){
384 ogg_stream_pagein(&vf->os,og_ptr);
388 /* if we never see the final vorbis headers before the link
390 if(ogg_page_bos(og_ptr)){
398 /* otherwise, keep looking */
406 vorbis_info_clear(vi);
407 vorbis_comment_clear(vc);
408 vf->ready_state=OPENED;
413 /* Starting from current cursor position, get initial PCM offset of
414 next page. Consumes the page in the process without decoding
415 audio, however this is only called during stream parsing upon
417 static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
419 ogg_int64_t accumulated=0;
422 int serialno = vf->os.serialno;
426 if(_get_next_page(vf,&og,-1)<0)
427 break; /* should not be possible unless the file is truncated/mangled */
429 if(ogg_page_bos(&og)) break;
430 if(ogg_page_serialno(&og)!=serialno) continue;
432 /* count blocksizes of all frames in the page */
433 ogg_stream_pagein(&vf->os,&og);
434 while((result=ogg_stream_packetout(&vf->os,&op))){
435 if(result>0){ /* ignore holes */
436 long thisblock=vorbis_packet_blocksize(vi,&op);
438 accumulated+=(lastblock+thisblock)>>2;
443 if(ogg_page_granulepos(&og)!=-1){
444 /* pcm offset of last packet on the first audio page */
445 accumulated= ogg_page_granulepos(&og)-accumulated;
450 /* less than zero? This is a stream with samples trimmed off
451 the beginning, a normal occurrence; set the offset to zero */
452 if(accumulated<0)accumulated=0;
457 /* finds each bitstream link one at a time using a bisection search
458 (has to begin by knowing the offset of the lb's initial page).
459 Recurses for each link so it can alloc the link storage after
460 finding them all, then unroll and fill the cache at the same time */
461 static int _bisect_forward_serialno(OggVorbis_File *vf,
463 ogg_int64_t searched,
467 long *currentno_list,
470 ogg_int64_t pcmoffset;
471 ogg_int64_t dataoffset=searched;
472 ogg_int64_t endsearched=end;
473 ogg_int64_t next=end;
474 ogg_int64_t searchgran=-1;
476 ogg_int64_t ret,last;
477 int serialno = vf->os.serialno;
480 we have the headers and serialnos for the link beginning at 'begin'
481 we have the offset and granpos of the last page in the file (potentially
482 not a page we care about)
485 /* Is the last page in our list of current serialnumbers? */
486 if(_lookup_serialno(endserial,currentno_list,currentnos)){
488 /* last page is in the starting serialno list, so we've bisected
489 down to (or just started with) a single link. Now we need to
490 find the last vorbis page belonging to the first vorbis stream
493 while(endserial != serialno){
494 endserial = serialno;
495 vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran);
499 if(vf->offsets)_ogg_free(vf->offsets);
500 if(vf->serialnos)_ogg_free(vf->serialnos);
501 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
503 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
504 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
505 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
506 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
507 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
508 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
510 vf->offsets[m+1]=end;
511 vf->offsets[m]=begin;
512 vf->pcmlengths[m*2+1]=endgran;
516 long *next_serialno_list=NULL;
517 int next_serialnos=0;
521 /* the below guards against garbage seperating the last and
522 first pages of two links. */
523 while(searched<endsearched){
526 if(endsearched-searched<CHUNKSIZE){
529 bisect=(searched+endsearched)/2;
532 ret=_seek_helper(vf,bisect);
535 last=_get_next_page(vf,&og,-1);
536 if(last==OV_EREAD)return(OV_EREAD);
537 if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
539 if(last>=0)next=last;
541 searched=last+og.header_len+og.body_len;
545 /* Bisection point found */
547 /* for the time being, fetch end PCM offset the simple way */
549 int testserial = serialno+1;
551 while(testserial != serialno){
552 testserial = serialno;
553 vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&testserial,&searchgran);
557 if(vf->offset!=next){
558 ret=_seek_helper(vf,next);
562 ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
564 serialno = vf->os.serialno;
565 dataoffset = vf->offset;
567 /* this will consume a page, however the next bistection always
568 starts with a raw seek */
569 pcmoffset = _initial_pcmoffset(vf,&vi);
571 ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
572 next_serialno_list,next_serialnos,m+1);
575 if(next_serialno_list)_ogg_free(next_serialno_list);
577 vf->offsets[m+1]=next;
578 vf->serialnos[m+1]=serialno;
579 vf->dataoffsets[m+1]=dataoffset;
584 vf->pcmlengths[m*2+1]=searchgran;
585 vf->pcmlengths[m*2+2]=pcmoffset;
586 vf->pcmlengths[m*2+3]-=pcmoffset;
592 static int _make_decode_ready(OggVorbis_File *vf){
593 if(vf->ready_state>STREAMSET)return 0;
594 if(vf->ready_state<STREAMSET)return OV_EFAULT;
596 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
599 if(vorbis_synthesis_init(&vf->vd,vf->vi))
602 vorbis_block_init(&vf->vd,&vf->vb);
603 vf->ready_state=INITSET;
609 static int _open_seekable2(OggVorbis_File *vf){
610 ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
611 int endserial=vf->os.serialno;
612 int serialno=vf->os.serialno;
614 /* we're partially open and have a first link header state in
617 /* fetch initial PCM offset */
618 ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
620 /* we can seek, so set out learning all about this file */
621 if(vf->callbacks.seek_func && vf->callbacks.tell_func){
622 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
623 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
625 vf->offset=vf->end=-1;
628 /* If seek_func is implemented, tell_func must also be implemented */
629 if(vf->end==-1) return(OV_EINVAL);
631 /* Get the offset of the last page of the physical bitstream, or, if
632 we're lucky the last vorbis page of this link as most OggVorbis
633 files will contain a single logical bitstream */
634 end=_get_prev_page_serial(vf,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
635 if(end<0)return(end);
637 /* now determine bitstream structure recursively */
638 if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial,
639 vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
642 vf->serialnos[0]=serialno;
643 vf->dataoffsets[0]=dataoffset;
644 vf->pcmlengths[0]=pcmoffset;
645 vf->pcmlengths[1]-=pcmoffset;
647 return(ov_raw_seek(vf,dataoffset));
650 /* clear out the current logical bitstream decoder */
651 static void _decode_clear(OggVorbis_File *vf){
652 vorbis_dsp_clear(&vf->vd);
653 vorbis_block_clear(&vf->vb);
654 vf->ready_state=OPENED;
657 /* fetch and process a packet. Handles the case where we're at a
658 bitstream boundary and dumps the decoding machine. If the decoding
659 machine is unloaded, it loads it. It also keeps pcm_offset up to
660 date (seek and read both use this. seek uses a special hack with
663 return: <0) error, OV_HOLE (lost packet) or OV_EOF
664 0) need more data (only if readp==0)
668 static int _fetch_and_process_packet(OggVorbis_File *vf,
674 /* handle one packet. Try to fetch it from current stream state */
675 /* extract packets from page */
678 /* process a packet if we can. If the machine isn't loaded,
680 if(vf->ready_state==INITSET){
683 ogg_packet *op_ptr=(op_in?op_in:&op);
684 int result=ogg_stream_packetout(&vf->os,op_ptr);
685 ogg_int64_t granulepos;
688 if(result==-1)return(OV_HOLE); /* hole in the data. */
690 /* got a packet. process it */
691 granulepos=op_ptr->granulepos;
692 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
694 header packets aren't
697 vorbis_synthesis will
700 /* suck in the synthesis data and track bitrate */
702 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
703 /* for proper use of libvorbis within libvorbisfile,
704 oldsamples will always be zero. */
705 if(oldsamples)return(OV_EFAULT);
707 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
708 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
709 vf->bittrack+=op_ptr->bytes*8;
712 /* update the pcm offset. */
713 if(granulepos!=-1 && !op_ptr->e_o_s){
714 int link=(vf->seekable?vf->current_link:0);
717 /* this packet has a pcm_offset on it (the last packet
718 completed on a page carries the offset) After processing
719 (above), we know the pcm position of the *last* sample
720 ready to be returned. Find the offset of the *first*
722 As an aside, this trick is inaccurate if we begin
723 reading anew right at the last page; the end-of-stream
724 granulepos declares the last frame in the stream, and the
725 last packet of the last page may be a partial frame.
726 So, we need a previous granulepos from an in-sequence page
727 to have a reference point. Thus the !op_ptr->e_o_s clause
730 if(vf->seekable && link>0)
731 granulepos-=vf->pcmlengths[link*2];
732 if(granulepos<0)granulepos=0; /* actually, this
733 shouldn't be possible
734 here unless the stream
737 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
741 granulepos+=vf->pcmlengths[i*2+1];
742 vf->pcm_offset=granulepos;
752 if(vf->ready_state>=OPENED){
756 /* the loop is not strictly necessary, but there's no sense in
757 doing the extra checks of the larger loop for the common
758 case in a multiplexed bistream where the page is simply
759 part of a different logical bitstream; keep reading until
760 we get one with the correct serialno */
763 if((ret=_get_next_page(vf,&og,-1))<0){
764 return(OV_EOF); /* eof. leave unitialized */
767 /* bitrate tracking; add the header's bytes here, the body bytes
768 are done by packet above */
769 vf->bittrack+=og.header_len*8;
771 if(vf->ready_state==INITSET){
772 if(vf->current_serialno!=ogg_page_serialno(&og)){
774 /* two possibilities:
775 1) our decoding just traversed a bitstream boundary
776 2) another stream is multiplexed into this logical section */
778 if(ogg_page_bos(&og)){
786 vorbis_info_clear(vf->vi);
787 vorbis_comment_clear(vf->vc);
792 continue; /* possibility #2 */
800 /* Do we need to load a new machine before submitting the page? */
801 /* This is different in the seekable and non-seekable cases.
803 In the seekable case, we already have all the header
804 information loaded and cached; we just initialize the machine
805 with it and continue on our merry way.
807 In the non-seekable (streaming) case, we'll only be at a
808 boundary if we just left the previous logical bitstream and
809 we're now nominally at the header of the next bitstream
812 if(vf->ready_state!=INITSET){
815 if(vf->ready_state<STREAMSET){
817 long serialno = ogg_page_serialno(&og);
819 /* match the serialno to bitstream section. We use this rather than
820 offset positions to avoid problems near logical bitstream
823 for(link=0;link<vf->links;link++)
824 if(vf->serialnos[link]==serialno)break;
826 if(link==vf->links) continue; /* not the desired Vorbis
827 bitstream section; keep
830 vf->current_serialno=serialno;
831 vf->current_link=link;
833 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
834 vf->ready_state=STREAMSET;
837 /* we're streaming */
838 /* fetch the three header packets, build the info struct */
840 int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
842 vf->current_serialno=vf->os.serialno;
849 int ret=_make_decode_ready(vf);
854 /* the buffered page is the data we want, and we're ready for it;
855 add it to the stream state */
856 ogg_stream_pagein(&vf->os,&og);
861 /* if, eg, 64 bit stdio is configured by default, this will build with
863 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
864 if(f==NULL)return(-1);
865 return fseek(f,off,whence);
868 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
869 long ibytes, ov_callbacks callbacks){
870 int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
871 long *serialno_list=NULL;
872 int serialno_list_size=0;
875 memset(vf,0,sizeof(*vf));
877 vf->callbacks = callbacks;
879 /* init the framing state */
880 ogg_sync_init(&vf->oy);
882 /* perhaps some data was previously read into a buffer for testing
883 against other stream types. Allow initialization from this
884 previously read data (especially as we may be reading from a
885 non-seekable stream) */
887 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
888 memcpy(buffer,initial,ibytes);
889 ogg_sync_wrote(&vf->oy,ibytes);
892 /* can we seek? Stevens suggests the seek test was portable */
893 if(offsettest!=-1)vf->seekable=1;
895 /* No seeking yet; Set up a 'single' (current) logical bitstream
896 entry for partial open */
898 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
899 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
900 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
902 /* Fetch all BOS pages, store the vorbis header and all seen serial
903 numbers, load subsequent vorbis setup headers */
904 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
908 /* serial number list for first link needs to be held somewhere
909 for second stage of seekable stream open; this saves having to
910 seek/reread first link's serialnumber data then. */
911 vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos));
912 vf->serialnos[0]=vf->current_serialno;
913 vf->serialnos[1]=serialno_list_size;
914 memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
916 vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
917 vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
919 vf->dataoffsets[0]=vf->offset;
920 vf->current_serialno=vf->os.serialno;
922 vf->ready_state=PARTOPEN;
924 if(serialno_list)_ogg_free(serialno_list);
928 static int _ov_open2(OggVorbis_File *vf){
929 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
930 vf->ready_state=OPENED;
932 int ret=_open_seekable2(vf);
939 vf->ready_state=STREAMSET;
945 /* clear out the OggVorbis_File struct */
946 int ov_clear(OggVorbis_File *vf){
948 vorbis_block_clear(&vf->vb);
949 vorbis_dsp_clear(&vf->vd);
950 ogg_stream_clear(&vf->os);
952 if(vf->vi && vf->links){
954 for(i=0;i<vf->links;i++){
955 vorbis_info_clear(vf->vi+i);
956 vorbis_comment_clear(vf->vc+i);
961 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
962 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
963 if(vf->serialnos)_ogg_free(vf->serialnos);
964 if(vf->offsets)_ogg_free(vf->offsets);
965 ogg_sync_clear(&vf->oy);
966 if(vf->datasource && vf->callbacks.close_func)
967 (vf->callbacks.close_func)(vf->datasource);
968 memset(vf,0,sizeof(*vf));
976 /* inspects the OggVorbis file and finds/documents all the logical
977 bitstreams contained in it. Tries to be tolerant of logical
978 bitstream sections that are truncated/woogie.
984 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
985 ov_callbacks callbacks){
986 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
988 return _ov_open2(vf);
991 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
992 ov_callbacks callbacks = {
993 (size_t (*)(void *, size_t, size_t, void *)) fread,
994 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
995 (int (*)(void *)) fclose,
996 (long (*)(void *)) ftell
999 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
1002 int ov_fopen(char *path,OggVorbis_File *vf){
1004 FILE *f = fopen(path,"rb");
1007 ret = ov_open(f,vf,NULL,0);
1013 /* cheap hack for game usage where downsampling is desirable; there's
1014 no need for SRC as we can just do it cheaply in libvorbis. */
1016 int ov_halfrate(OggVorbis_File *vf,int flag){
1018 if(vf->vi==NULL)return OV_EINVAL;
1019 if(!vf->seekable)return OV_EINVAL;
1020 if(vf->ready_state>=STREAMSET)
1021 _decode_clear(vf); /* clear out stream state; later on libvorbis
1022 will be able to swap this on the fly, but
1023 for now dumping the decode machine is needed
1024 to reinit the MDCT lookups. 1.1 libvorbis
1025 is planned to be able to switch on the fly */
1027 for(i=0;i<vf->links;i++){
1028 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
1036 int ov_halfrate_p(OggVorbis_File *vf){
1037 if(vf->vi==NULL)return OV_EINVAL;
1038 return vorbis_synthesis_halfrate_p(vf->vi);
1041 /* Only partially open the vorbis file; test for Vorbisness, and load
1042 the headers for the first chain. Do not seek (although test for
1043 seekability). Use ov_test_open to finish opening the file, else
1044 ov_clear to close/free it. Same return codes as open. */
1046 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
1047 ov_callbacks callbacks)
1049 return _ov_open1(f,vf,initial,ibytes,callbacks);
1052 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
1053 ov_callbacks callbacks = {
1054 (size_t (*)(void *, size_t, size_t, void *)) fread,
1055 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
1056 (int (*)(void *)) fclose,
1057 (long (*)(void *)) ftell
1060 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
1063 int ov_test_open(OggVorbis_File *vf){
1064 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
1065 return _ov_open2(vf);
1068 /* How many logical bitstreams in this physical bitstream? */
1069 long ov_streams(OggVorbis_File *vf){
1073 /* Is the FILE * associated with vf seekable? */
1074 long ov_seekable(OggVorbis_File *vf){
1075 return vf->seekable;
1078 /* returns the bitrate for a given logical bitstream or the entire
1079 physical bitstream. If the file is open for random access, it will
1080 find the *actual* average bitrate. If the file is streaming, it
1081 returns the nominal bitrate (if set) else the average of the
1082 upper/lower bounds (if set) else -1 (unset).
1084 If you want the actual bitrate field settings, get them from the
1085 vorbis_info structs */
1087 long ov_bitrate(OggVorbis_File *vf,int i){
1088 if(vf->ready_state<OPENED)return(OV_EINVAL);
1089 if(i>=vf->links)return(OV_EINVAL);
1090 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
1095 for(i=0;i<vf->links;i++)
1096 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
1097 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
1098 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
1099 * so this is slightly transformed to make it work.
1101 br = bits/ov_time_total(vf,-1);
1105 /* return the actual bitrate */
1106 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
1108 /* return nominal if set */
1109 if(vf->vi[i].bitrate_nominal>0){
1110 return vf->vi[i].bitrate_nominal;
1112 if(vf->vi[i].bitrate_upper>0){
1113 if(vf->vi[i].bitrate_lower>0){
1114 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1116 return vf->vi[i].bitrate_upper;
1125 /* returns the actual bitrate since last call. returns -1 if no
1126 additional data to offer since last call (or at beginning of stream),
1127 EINVAL if stream is only partially open
1129 long ov_bitrate_instant(OggVorbis_File *vf){
1130 int link=(vf->seekable?vf->current_link:0);
1132 if(vf->ready_state<OPENED)return(OV_EINVAL);
1133 if(vf->samptrack==0)return(OV_FALSE);
1134 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1141 long ov_serialnumber(OggVorbis_File *vf,int i){
1142 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1143 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1145 return(vf->current_serialno);
1147 return(vf->serialnos[i]);
1151 /* returns: total raw (compressed) length of content if i==-1
1152 raw (compressed) length of that logical bitstream for i==0 to n
1153 OV_EINVAL if the stream is not seekable (we can't know the length)
1154 or if stream is only partially open
1156 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1157 if(vf->ready_state<OPENED)return(OV_EINVAL);
1158 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1162 for(i=0;i<vf->links;i++)
1163 acc+=ov_raw_total(vf,i);
1166 return(vf->offsets[i+1]-vf->offsets[i]);
1170 /* returns: total PCM length (samples) of content if i==-1 PCM length
1171 (samples) of that logical bitstream for i==0 to n
1172 OV_EINVAL if the stream is not seekable (we can't know the
1173 length) or only partially open
1175 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1176 if(vf->ready_state<OPENED)return(OV_EINVAL);
1177 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1181 for(i=0;i<vf->links;i++)
1182 acc+=ov_pcm_total(vf,i);
1185 return(vf->pcmlengths[i*2+1]);
1189 /* returns: total seconds of content if i==-1
1190 seconds in that logical bitstream for i==0 to n
1191 OV_EINVAL if the stream is not seekable (we can't know the
1192 length) or only partially open
1194 double ov_time_total(OggVorbis_File *vf,int i){
1195 if(vf->ready_state<OPENED)return(OV_EINVAL);
1196 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1200 for(i=0;i<vf->links;i++)
1201 acc+=ov_time_total(vf,i);
1204 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1208 /* seek to an offset relative to the *compressed* data. This also
1209 scans packets to update the PCM cursor. It will cross a logical
1210 bitstream boundary, but only if it can't get any packets out of the
1211 tail of the bitstream we seek to (so no surprises).
1213 returns zero on success, nonzero on failure */
1215 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1216 ogg_stream_state work_os;
1219 if(vf->ready_state<OPENED)return(OV_EINVAL);
1221 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1223 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1225 /* don't yet clear out decoding machine (if it's initialized), in
1226 the case we're in the same link. Restart the decode lapping, and
1227 let _fetch_and_process_packet deal with a potential bitstream
1230 ogg_stream_reset_serialno(&vf->os,
1231 vf->current_serialno); /* must set serialno */
1232 vorbis_synthesis_restart(&vf->vd);
1234 ret=_seek_helper(vf,pos);
1235 if(ret)goto seek_error;
1237 /* we need to make sure the pcm_offset is set, but we don't want to
1238 advance the raw cursor past good packets just to get to the first
1239 with a granulepos. That's not equivalent behavior to beginning
1240 decoding as immediately after the seek position as possible.
1242 So, a hack. We use two stream states; a local scratch state and
1243 the shared vf->os stream state. We use the local state to
1244 scan, and the shared state as a buffer for later decode.
1246 Unfortuantely, on the last page we still advance to last packet
1247 because the granulepos on the last page is not necessarily on a
1248 packet boundary, and we need to make sure the granpos is
1260 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1261 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1262 return from not necessarily
1263 starting from the beginning */
1266 if(vf->ready_state>=STREAMSET){
1267 /* snarf/scan a packet if we can */
1268 int result=ogg_stream_packetout(&work_os,&op);
1272 if(vf->vi[vf->current_link].codec_setup){
1273 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1275 ogg_stream_packetout(&vf->os,NULL);
1280 ogg_stream_packetout(&vf->os,NULL);
1282 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1285 if(op.granulepos!=-1){
1286 int i,link=vf->current_link;
1287 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1288 if(granulepos<0)granulepos=0;
1291 granulepos+=vf->pcmlengths[i*2+1];
1292 vf->pcm_offset=granulepos-accblock;
1295 lastblock=thisblock;
1298 ogg_stream_packetout(&vf->os,NULL);
1303 if(_get_next_page(vf,&og,-1)<0){
1304 vf->pcm_offset=ov_pcm_total(vf,-1);
1308 /* huh? Bogus stream with packets but no granulepos */
1313 /* has our decoding just traversed a bitstream boundary? */
1314 if(vf->ready_state>=STREAMSET){
1315 if(vf->current_serialno!=ogg_page_serialno(&og)){
1317 /* two possibilities:
1318 1) our decoding just traversed a bitstream boundary
1319 2) another stream is multiplexed into this logical section? */
1321 if(ogg_page_bos(&og)){
1323 _decode_clear(vf); /* clear out stream state */
1324 ogg_stream_clear(&work_os);
1325 } /* else, do nothing; next loop will scoop another page */
1329 if(vf->ready_state<STREAMSET){
1331 long serialno = ogg_page_serialno(&og);
1333 for(link=0;link<vf->links;link++)
1334 if(vf->serialnos[link]==serialno)break;
1336 if(link==vf->links) continue; /* not the desired Vorbis
1337 bitstream section; keep
1339 vf->current_link=link;
1340 vf->current_serialno=serialno;
1341 ogg_stream_reset_serialno(&vf->os,serialno);
1342 ogg_stream_reset_serialno(&work_os,serialno);
1343 vf->ready_state=STREAMSET;
1347 ogg_stream_pagein(&vf->os,&og);
1348 ogg_stream_pagein(&work_os,&og);
1349 eosflag=ogg_page_eos(&og);
1353 ogg_stream_clear(&work_os);
1359 /* dump the machine so we're in a known state */
1361 ogg_stream_clear(&work_os);
1366 /* Page granularity seek (faster than sample granularity because we
1367 don't do the last bit of decode to find a specific sample).
1369 Seek to the last [granule marked] page preceeding the specified pos
1370 location, such that decoding past the returned point will quickly
1371 arrive at the requested position. */
1372 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1374 ogg_int64_t result=0;
1375 ogg_int64_t total=ov_pcm_total(vf,-1);
1377 if(vf->ready_state<OPENED)return(OV_EINVAL);
1378 if(!vf->seekable)return(OV_ENOSEEK);
1380 if(pos<0 || pos>total)return(OV_EINVAL);
1382 /* which bitstream section does this pcm offset occur in? */
1383 for(link=vf->links-1;link>=0;link--){
1384 total-=vf->pcmlengths[link*2+1];
1385 if(pos>=total)break;
1388 /* search within the logical bitstream for the page with the highest
1389 pcm_pos preceeding (or equal to) pos. There is a danger here;
1390 missing pages or incorrect frame number information in the
1391 bitstream could make our task impossible. Account for that (it
1392 would be an error condition) */
1394 /* new search algorithm by HB (Nicholas Vinen) */
1396 ogg_int64_t end=vf->offsets[link+1];
1397 ogg_int64_t begin=vf->offsets[link];
1398 ogg_int64_t begintime = vf->pcmlengths[link*2];
1399 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1400 ogg_int64_t target=pos-total+begintime;
1401 ogg_int64_t best=begin;
1407 if(end-begin<CHUNKSIZE){
1410 /* take a (pretty decent) guess. */
1412 (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime))
1418 result=_seek_helper(vf,bisect);
1419 if(result) goto seek_error;
1422 result=_get_next_page(vf,&og,end-vf->offset);
1423 if(result==OV_EREAD) goto seek_error;
1426 end=begin; /* found it */
1428 if(bisect==0) goto seek_error;
1430 if(bisect<=begin)bisect=begin+1;
1431 result=_seek_helper(vf,bisect);
1432 if(result) goto seek_error;
1435 ogg_int64_t granulepos;
1437 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1440 granulepos=ogg_page_granulepos(&og);
1441 if(granulepos==-1)continue;
1443 if(granulepos<target){
1444 best=result; /* raw offset of packet with granulepos */
1445 begin=vf->offset; /* raw offset of next page */
1446 begintime=granulepos;
1448 if(target-begintime>44100)break;
1449 bisect=begin; /* *not* begin + 1 */
1452 end=begin; /* found it */
1454 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1456 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1457 if(bisect<=begin)bisect=begin+1;
1458 result=_seek_helper(vf,bisect);
1459 if(result) goto seek_error;
1471 /* found our page. seek to it, update pcm offset. Easier case than
1472 raw_seek, don't keep packets preceeding granulepos. */
1478 result=_seek_helper(vf,best);
1480 if(result) goto seek_error;
1481 result=_get_next_page(vf,&og,-1);
1482 if(result<0) goto seek_error;
1484 if(link!=vf->current_link){
1485 /* Different link; dump entire decode machine */
1488 vf->current_link=link;
1489 vf->current_serialno=vf->serialnos[link];
1490 vf->ready_state=STREAMSET;
1493 vorbis_synthesis_restart(&vf->vd);
1496 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1497 ogg_stream_pagein(&vf->os,&og);
1499 /* pull out all but last packet; the one with granulepos */
1501 result=ogg_stream_packetpeek(&vf->os,&op);
1503 /* !!! the packet finishing this page originated on a
1504 preceeding page. Keep fetching previous pages until we
1505 get one with a granulepos or without the 'continued' flag
1506 set. Then just use raw_seek for simplicity. */
1508 result=_seek_helper(vf,best);
1509 if(result<0) goto seek_error;
1512 result=_get_prev_page(vf,&og);
1513 if(result<0) goto seek_error;
1514 if(ogg_page_serialno(&og)==vf->current_serialno &&
1515 (ogg_page_granulepos(&og)>-1 ||
1516 !ogg_page_continued(&og))){
1517 return ov_raw_seek(vf,result);
1523 result = OV_EBADPACKET;
1526 if(op.granulepos!=-1){
1527 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1528 if(vf->pcm_offset<0)vf->pcm_offset=0;
1529 vf->pcm_offset+=total;
1532 result=ogg_stream_packetout(&vf->os,NULL);
1538 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1547 /* dump machine so we're in a known state */
1553 /* seek to a sample offset relative to the decompressed pcm stream
1554 returns zero on success, nonzero on failure */
1556 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1557 int thisblock,lastblock=0;
1558 int ret=ov_pcm_seek_page(vf,pos);
1559 if(ret<0)return(ret);
1560 if((ret=_make_decode_ready(vf)))return ret;
1562 /* discard leading packets we don't need for the lapping of the
1563 position we want; don't decode them */
1569 int ret=ogg_stream_packetpeek(&vf->os,&op);
1571 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1573 ogg_stream_packetout(&vf->os,NULL);
1574 continue; /* non audio packet */
1576 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1578 if(vf->pcm_offset+((thisblock+
1579 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1581 /* remove the packet from packet queue and track its granulepos */
1582 ogg_stream_packetout(&vf->os,NULL);
1583 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1586 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1588 /* end of logical stream case is hard, especially with exact
1589 length positioning. */
1591 if(op.granulepos>-1){
1593 /* always believe the stream markers */
1594 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1595 if(vf->pcm_offset<0)vf->pcm_offset=0;
1596 for(i=0;i<vf->current_link;i++)
1597 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1600 lastblock=thisblock;
1603 if(ret<0 && ret!=OV_HOLE)break;
1605 /* suck in a new page */
1606 if(_get_next_page(vf,&og,-1)<0)break;
1607 if(ogg_page_bos(&og))_decode_clear(vf);
1609 if(vf->ready_state<STREAMSET){
1610 long serialno=ogg_page_serialno(&og);
1613 for(link=0;link<vf->links;link++)
1614 if(vf->serialnos[link]==serialno)break;
1615 if(link==vf->links) continue;
1616 vf->current_link=link;
1618 vf->ready_state=STREAMSET;
1619 vf->current_serialno=ogg_page_serialno(&og);
1620 ogg_stream_reset_serialno(&vf->os,serialno);
1621 ret=_make_decode_ready(vf);
1626 ogg_stream_pagein(&vf->os,&og);
1632 /* discard samples until we reach the desired position. Crossing a
1633 logical bitstream boundary with abandon is OK. */
1634 while(vf->pcm_offset<pos){
1635 ogg_int64_t target=pos-vf->pcm_offset;
1636 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1638 if(samples>target)samples=target;
1639 vorbis_synthesis_read(&vf->vd,samples);
1640 vf->pcm_offset+=samples;
1643 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1644 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1649 /* seek to a playback time relative to the decompressed pcm stream
1650 returns zero on success, nonzero on failure */
1651 int ov_time_seek(OggVorbis_File *vf,double seconds){
1652 /* translate time to PCM position and call ov_pcm_seek */
1655 ogg_int64_t pcm_total=0;
1656 double time_total=0.;
1658 if(vf->ready_state<OPENED)return(OV_EINVAL);
1659 if(!vf->seekable)return(OV_ENOSEEK);
1660 if(seconds<0)return(OV_EINVAL);
1662 /* which bitstream section does this time offset occur in? */
1663 for(link=0;link<vf->links;link++){
1664 double addsec = ov_time_total(vf,link);
1665 if(seconds<time_total+addsec)break;
1667 pcm_total+=vf->pcmlengths[link*2+1];
1670 if(link==vf->links)return(OV_EINVAL);
1672 /* enough information to convert time offset to pcm offset */
1674 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1675 return(ov_pcm_seek(vf,target));
1679 /* page-granularity version of ov_time_seek
1680 returns zero on success, nonzero on failure */
1681 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1682 /* translate time to PCM position and call ov_pcm_seek */
1685 ogg_int64_t pcm_total=0;
1686 double time_total=0.;
1688 if(vf->ready_state<OPENED)return(OV_EINVAL);
1689 if(!vf->seekable)return(OV_ENOSEEK);
1690 if(seconds<0)return(OV_EINVAL);
1692 /* which bitstream section does this time offset occur in? */
1693 for(link=0;link<vf->links;link++){
1694 double addsec = ov_time_total(vf,link);
1695 if(seconds<time_total+addsec)break;
1697 pcm_total+=vf->pcmlengths[link*2+1];
1700 if(link==vf->links)return(OV_EINVAL);
1702 /* enough information to convert time offset to pcm offset */
1704 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1705 return(ov_pcm_seek_page(vf,target));
1709 /* tell the current stream offset cursor. Note that seek followed by
1710 tell will likely not give the set offset due to caching */
1711 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1712 if(vf->ready_state<OPENED)return(OV_EINVAL);
1716 /* return PCM offset (sample) of next PCM sample to be read */
1717 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1718 if(vf->ready_state<OPENED)return(OV_EINVAL);
1719 return(vf->pcm_offset);
1722 /* return time offset (seconds) of next PCM sample to be read */
1723 double ov_time_tell(OggVorbis_File *vf){
1725 ogg_int64_t pcm_total=0;
1726 double time_total=0.f;
1728 if(vf->ready_state<OPENED)return(OV_EINVAL);
1730 pcm_total=ov_pcm_total(vf,-1);
1731 time_total=ov_time_total(vf,-1);
1733 /* which bitstream section does this time offset occur in? */
1734 for(link=vf->links-1;link>=0;link--){
1735 pcm_total-=vf->pcmlengths[link*2+1];
1736 time_total-=ov_time_total(vf,link);
1737 if(vf->pcm_offset>=pcm_total)break;
1741 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1744 /* link: -1) return the vorbis_info struct for the bitstream section
1745 currently being decoded
1746 0-n) to request information for a specific bitstream section
1748 In the case of a non-seekable bitstream, any call returns the
1749 current bitstream. NULL in the case that the machine is not
1752 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1755 if(vf->ready_state>=STREAMSET)
1756 return vf->vi+vf->current_link;
1769 /* grr, strong typing, grr, no templates/inheritence, grr */
1770 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1773 if(vf->ready_state>=STREAMSET)
1774 return vf->vc+vf->current_link;
1787 static int host_is_big_endian() {
1788 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1789 unsigned char *bytewise = (unsigned char *)&pattern;
1790 if (bytewise[0] == 0xfe) return 1;
1794 /* up to this point, everything could more or less hide the multiple
1795 logical bitstream nature of chaining from the toplevel application
1796 if the toplevel application didn't particularly care. However, at
1797 the point that we actually read audio back, the multiple-section
1798 nature must surface: Multiple bitstream sections do not necessarily
1799 have to have the same number of channels or sampling rate.
1801 ov_read returns the sequential logical bitstream number currently
1802 being decoded along with the PCM data in order that the toplevel
1803 application can take action on channel/sample rate changes. This
1804 number will be incremented even for streamed (non-seekable) streams
1805 (for seekable streams, it represents the actual logical bitstream
1806 index within the physical bitstream. Note that the accessor
1807 functions above are aware of this dichotomy).
1809 ov_read_filter is exactly the same as ov_read except that it processes
1810 the decoded audio data through a filter before packing it into the
1811 requested format. This gives greater accuracy than applying a filter
1812 after the audio has been converted into integral PCM.
1814 input values: buffer) a buffer to hold packed PCM data for return
1815 length) the byte length requested to be placed into buffer
1816 bigendianp) should the data be packed LSB first (0) or
1818 word) word size for output. currently 1 (byte) or
1821 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1823 n) number of bytes of PCM actually returned. The
1824 below works on a packet-by-packet basis, so the
1825 return length is not related to the 'length' passed
1826 in, just guaranteed to fit.
1828 *section) set to the logical bitstream number */
1830 long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
1831 int bigendianp,int word,int sgned,int *bitstream,
1832 void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
1834 int host_endian = host_is_big_endian();
1839 if(vf->ready_state<OPENED)return(OV_EINVAL);
1842 if(vf->ready_state==INITSET){
1843 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1847 /* suck in another packet */
1849 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1860 /* yay! proceed to pack data into the byte buffer */
1862 long channels=ov_info(vf,-1)->channels;
1863 long bytespersample=word * channels;
1864 vorbis_fpu_control fpu;
1865 if(samples>length/bytespersample)samples=length/bytespersample;
1872 filter(pcm,channels,samples,filter_param);
1874 /* a tight loop to pack each size */
1878 int off=(sgned?0:128);
1879 vorbis_fpu_setround(&fpu);
1880 for(j=0;j<samples;j++)
1881 for(i=0;i<channels;i++){
1882 val=vorbis_ftoi(pcm[i][j]*128.f);
1884 else if(val<-128)val=-128;
1887 vorbis_fpu_restore(fpu);
1889 int off=(sgned?0:32768);
1891 if(host_endian==bigendianp){
1894 vorbis_fpu_setround(&fpu);
1895 for(i=0;i<channels;i++) { /* It's faster in this order */
1897 short *dest=((short *)buffer)+i;
1898 for(j=0;j<samples;j++) {
1899 val=vorbis_ftoi(src[j]*32768.f);
1900 if(val>32767)val=32767;
1901 else if(val<-32768)val=-32768;
1906 vorbis_fpu_restore(fpu);
1910 vorbis_fpu_setround(&fpu);
1911 for(i=0;i<channels;i++) {
1913 short *dest=((short *)buffer)+i;
1914 for(j=0;j<samples;j++) {
1915 val=vorbis_ftoi(src[j]*32768.f);
1916 if(val>32767)val=32767;
1917 else if(val<-32768)val=-32768;
1922 vorbis_fpu_restore(fpu);
1925 }else if(bigendianp){
1927 vorbis_fpu_setround(&fpu);
1928 for(j=0;j<samples;j++)
1929 for(i=0;i<channels;i++){
1930 val=vorbis_ftoi(pcm[i][j]*32768.f);
1931 if(val>32767)val=32767;
1932 else if(val<-32768)val=-32768;
1935 *buffer++=(val&0xff);
1937 vorbis_fpu_restore(fpu);
1941 vorbis_fpu_setround(&fpu);
1942 for(j=0;j<samples;j++)
1943 for(i=0;i<channels;i++){
1944 val=vorbis_ftoi(pcm[i][j]*32768.f);
1945 if(val>32767)val=32767;
1946 else if(val<-32768)val=-32768;
1948 *buffer++=(val&0xff);
1951 vorbis_fpu_restore(fpu);
1957 vorbis_synthesis_read(&vf->vd,samples);
1958 vf->pcm_offset+=samples;
1959 if(bitstream)*bitstream=vf->current_link;
1960 return(samples*bytespersample);
1966 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1967 int bigendianp,int word,int sgned,int *bitstream){
1968 return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
1971 /* input values: pcm_channels) a float vector per channel of output
1972 length) the sample length being read by the app
1974 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1976 n) number of samples of PCM actually returned. The
1977 below works on a packet-by-packet basis, so the
1978 return length is not related to the 'length' passed
1979 in, just guaranteed to fit.
1981 *section) set to the logical bitstream number */
1985 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1988 if(vf->ready_state<OPENED)return(OV_EINVAL);
1991 if(vf->ready_state==INITSET){
1993 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1995 if(pcm_channels)*pcm_channels=pcm;
1996 if(samples>length)samples=length;
1997 vorbis_synthesis_read(&vf->vd,samples);
1998 vf->pcm_offset+=samples;
1999 if(bitstream)*bitstream=vf->current_link;
2005 /* suck in another packet */
2007 int ret=_fetch_and_process_packet(vf,NULL,1,1);
2008 if(ret==OV_EOF)return(0);
2009 if(ret<=0)return(ret);
2015 extern float *vorbis_window(vorbis_dsp_state *v,int W);
2017 static void _ov_splice(float **pcm,float **lappcm,
2020 float *w1, float *w2){
2031 for(j=0;j<ch1 && j<ch2;j++){
2038 d[i]=d[i]*wd + s[i]*ws;
2041 /* window from zero */
2052 /* make sure vf is INITSET */
2053 static int _ov_initset(OggVorbis_File *vf){
2055 if(vf->ready_state==INITSET)break;
2056 /* suck in another packet */
2058 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2059 if(ret<0 && ret!=OV_HOLE)return(ret);
2065 /* make sure vf is INITSET and that we have a primed buffer; if
2066 we're crosslapping at a stream section boundary, this also makes
2067 sure we're sanity checking against the right stream information */
2068 static int _ov_initprime(OggVorbis_File *vf){
2069 vorbis_dsp_state *vd=&vf->vd;
2071 if(vf->ready_state==INITSET)
2072 if(vorbis_synthesis_pcmout(vd,NULL))break;
2074 /* suck in another packet */
2076 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2077 if(ret<0 && ret!=OV_HOLE)return(ret);
2083 /* grab enough data for lapping from vf; this may be in the form of
2084 unreturned, already-decoded pcm, remaining PCM we will need to
2085 decode, or synthetic postextrapolation from last packets. */
2086 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
2087 float **lappcm,int lapsize){
2091 /* try first to decode the lapping data */
2092 while(lapcount<lapsize){
2093 int samples=vorbis_synthesis_pcmout(vd,&pcm);
2095 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2096 for(i=0;i<vi->channels;i++)
2097 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2099 vorbis_synthesis_read(vd,samples);
2101 /* suck in another packet */
2102 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
2103 if(ret==OV_EOF)break;
2106 if(lapcount<lapsize){
2107 /* failed to get lapping data from normal decode; pry it from the
2108 postextrapolation buffering, or the second half of the MDCT
2109 from the last packet */
2110 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
2112 for(i=0;i<vi->channels;i++)
2113 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2116 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2117 for(i=0;i<vi->channels;i++)
2118 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2124 /* this sets up crosslapping of a sample by using trailing data from
2125 sample 1 and lapping it into the windowing buffer of sample 2 */
2126 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2127 vorbis_info *vi1,*vi2;
2131 int n1,n2,i,ret,hs1,hs2;
2133 if(vf1==vf2)return(0); /* degenerate case */
2134 if(vf1->ready_state<OPENED)return(OV_EINVAL);
2135 if(vf2->ready_state<OPENED)return(OV_EINVAL);
2137 /* the relevant overlap buffers must be pre-checked and pre-primed
2138 before looking at settings in the event that priming would cross
2139 a bitstream boundary. So, do it now */
2141 ret=_ov_initset(vf1);
2143 ret=_ov_initprime(vf2);
2146 vi1=ov_info(vf1,-1);
2147 vi2=ov_info(vf2,-1);
2148 hs1=ov_halfrate_p(vf1);
2149 hs2=ov_halfrate_p(vf2);
2151 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2152 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2153 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2154 w1=vorbis_window(&vf1->vd,0);
2155 w2=vorbis_window(&vf2->vd,0);
2157 for(i=0;i<vi1->channels;i++)
2158 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2160 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2162 /* have a lapping buffer from vf1; now to splice it into the lapping
2164 /* consolidate and expose the buffer. */
2165 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2168 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2169 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2173 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2179 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2180 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2185 int n1,n2,ch1,ch2,hs;
2188 if(vf->ready_state<OPENED)return(OV_EINVAL);
2189 ret=_ov_initset(vf);
2192 hs=ov_halfrate_p(vf);
2195 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2196 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2197 persistent; even if the decode state
2198 from this link gets dumped, this
2199 window array continues to exist */
2201 lappcm=alloca(sizeof(*lappcm)*ch1);
2203 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2204 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2206 /* have lapping data; seek and prime the buffer */
2207 ret=localseek(vf,pos);
2209 ret=_ov_initprime(vf);
2212 /* Guard against cross-link changes; they're perfectly legal */
2215 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2216 w2=vorbis_window(&vf->vd,0);
2218 /* consolidate and expose the buffer. */
2219 vorbis_synthesis_lapout(&vf->vd,&pcm);
2222 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2228 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2229 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2232 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2233 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2236 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2237 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2240 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2241 int (*localseek)(OggVorbis_File *,double)){
2246 int n1,n2,ch1,ch2,hs;
2249 if(vf->ready_state<OPENED)return(OV_EINVAL);
2250 ret=_ov_initset(vf);
2253 hs=ov_halfrate_p(vf);
2256 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2257 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2258 persistent; even if the decode state
2259 from this link gets dumped, this
2260 window array continues to exist */
2262 lappcm=alloca(sizeof(*lappcm)*ch1);
2264 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2265 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2267 /* have lapping data; seek and prime the buffer */
2268 ret=localseek(vf,pos);
2270 ret=_ov_initprime(vf);
2273 /* Guard against cross-link changes; they're perfectly legal */
2276 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2277 w2=vorbis_window(&vf->vd,0);
2279 /* consolidate and expose the buffer. */
2280 vorbis_synthesis_lapout(&vf->vd,&pcm);
2283 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2289 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2290 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2293 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2294 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);