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-2007 *
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 /* performs the same search as _get_prev_page, but prefers pages of
185 the specified serial number. If a page of the specified serialno is
186 spotted during the seek-back-and-read-forward, it will return the
187 info of last page of the matching serial number instead of the very
188 last page. If no page of the specified serialno is seen, it will
189 return the info of last page and alter *serialno. */
190 static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,int *serialno, ogg_int64_t *granpos){
192 ogg_int64_t begin=vf->offset;
193 ogg_int64_t end=begin;
196 ogg_int64_t prefoffset=-1;
197 ogg_int64_t offset=-1;
198 ogg_int64_t ret_serialno;
199 ogg_int64_t ret_gran;
206 ret=_seek_helper(vf,begin);
209 while(vf->offset<end){
210 ret=_get_next_page(vf,&og,end-vf->offset);
211 if(ret==OV_EREAD)return(OV_EREAD);
215 ret_serialno=ogg_page_serialno(&og);
216 ret_gran=ogg_page_granulepos(&og);
219 if(ret_serialno == *serialno){
228 /* we're not interested in the page... just the serialno and granpos. */
229 if(prefoffset>=0)return(prefoffset);
231 *serialno = ret_serialno;
237 static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
238 long s = ogg_page_serialno(og);
242 *serialno_list = _ogg_realloc(*serialno_list, sizeof(*serialno_list)*(*n));
244 *serialno_list = _ogg_malloc(sizeof(**serialno_list));
247 (*serialno_list)[(*n)-1] = s;
250 /* returns nonzero if found */
251 static int _lookup_serialno(long s, long *serialno_list, int n){
254 if(*serialno_list == s) return 1;
261 static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
262 long s = ogg_page_serialno(og);
263 return _lookup_serialno(s,serialno_list,n);
266 /* uses the local ogg_stream storage in vf; this is important for
267 non-streaming input sources */
268 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
269 long **serialno_list, int *serialno_n,
277 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
278 if(llret==OV_EREAD)return(OV_EREAD);
279 if(llret<0)return(OV_ENOTVORBIS);
283 vorbis_info_init(vi);
284 vorbis_comment_init(vc);
285 vf->ready_state=OPENED;
287 /* extract the serialnos of all BOS pages + the first set of vorbis
288 headers we see in the link */
290 while(ogg_page_bos(og_ptr)){
292 if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
293 /* a dupe serialnumber in an initial header packet set == invalid stream */
294 if(*serialno_list)_ogg_free(*serialno_list);
301 _add_serialno(og_ptr,serialno_list,serialno_n);
304 if(vf->ready_state<STREAMSET){
305 /* we don't have a vorbis stream in this link yet, so begin
306 prospective stream setup. We need a stream to get packets */
307 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
308 ogg_stream_pagein(&vf->os,og_ptr);
310 if(ogg_stream_packetout(&vf->os,&op) > 0 &&
311 vorbis_synthesis_idheader(&op)){
312 /* vorbis header; continue setup */
313 vf->ready_state=STREAMSET;
314 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
323 ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
333 /* if this page also belongs to our vorbis stream, submit it and break */
334 if(vf->ready_state==STREAMSET &&
335 vf->os.serialno == ogg_page_serialno(og_ptr)){
336 ogg_stream_pagein(&vf->os,og_ptr);
342 if(vf->ready_state!=STREAMSET){
350 while(i<2){ /* get a page loop */
352 while(i<2){ /* get a packet loop */
354 int result=ogg_stream_packetout(&vf->os,&op);
361 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
368 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
373 /* if this page belongs to the correct stream, go parse it */
374 if(vf->os.serialno == ogg_page_serialno(og_ptr)){
375 ogg_stream_pagein(&vf->os,og_ptr);
379 /* if we never see the final vorbis headers before the link
381 if(ogg_page_bos(og_ptr)){
389 /* otherwise, keep looking */
397 vorbis_info_clear(vi);
398 vorbis_comment_clear(vc);
399 vf->ready_state=OPENED;
404 /* Starting from current cursor position, get initial PCM offset of
405 next page. Consumes the page in the process without decoding
406 audio, however this is only called during stream parsing upon
408 static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
410 ogg_int64_t accumulated=0;
413 int serialno = vf->os.serialno;
417 if(_get_next_page(vf,&og,-1)<0)
418 break; /* should not be possible unless the file is truncated/mangled */
420 if(ogg_page_bos(&og)) break;
421 if(ogg_page_serialno(&og)!=serialno) continue;
423 /* count blocksizes of all frames in the page */
424 ogg_stream_pagein(&vf->os,&og);
425 while((result=ogg_stream_packetout(&vf->os,&op))){
426 if(result>0){ /* ignore holes */
427 long thisblock=vorbis_packet_blocksize(vi,&op);
429 accumulated+=(lastblock+thisblock)>>2;
434 if(ogg_page_granulepos(&og)!=-1){
435 /* pcm offset of last packet on the first audio page */
436 accumulated= ogg_page_granulepos(&og)-accumulated;
441 /* less than zero? This is a stream with samples trimmed off
442 the beginning, a normal occurrence; set the offset to zero */
443 if(accumulated<0)accumulated=0;
448 /* finds each bitstream link one at a time using a bisection search
449 (has to begin by knowing the offset of the lb's initial page).
450 Recurses for each link so it can alloc the link storage after
451 finding them all, then unroll and fill the cache at the same time */
452 static int _bisect_forward_serialno(OggVorbis_File *vf,
454 ogg_int64_t searched,
458 long *currentno_list,
461 ogg_int64_t pcmoffset;
462 ogg_int64_t dataoffset=searched;
463 ogg_int64_t endsearched=end;
464 ogg_int64_t next=end;
465 ogg_int64_t searchgran=-1;
467 ogg_int64_t ret,last;
468 int serialno = vf->os.serialno;
471 we have the headers and serialnos for the link beginning at 'begin'
472 we have the offset and granpos of the last page in the file (potentially
473 not a page we care about)
476 /* Is the last page in our list of current serialnumbers? */
477 if(_lookup_serialno(endserial,currentno_list,currentnos)){
479 /* last page is in the starting serialno list, so we've bisected
480 down to (or just started with) a single link. Now we need to
481 find the last vorbis page belonging to the first vorbis stream
484 while(endserial != serialno){
485 endserial = serialno;
486 vf->offset=_get_prev_page_serial(vf,&endserial,&endgran);
490 if(vf->offsets)_ogg_free(vf->offsets);
491 if(vf->serialnos)_ogg_free(vf->serialnos);
492 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
494 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
495 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
496 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
497 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
498 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
499 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
501 vf->offsets[m+1]=end;
502 vf->offsets[m]=begin;
503 vf->pcmlengths[m*2+1]=endgran;
507 long *next_serialno_list=NULL;
508 int next_serialnos=0;
512 /* the below guards against garbage seperating the last and
513 first pages of two links. */
514 while(searched<endsearched){
517 if(endsearched-searched<CHUNKSIZE){
520 bisect=(searched+endsearched)/2;
523 ret=_seek_helper(vf,bisect);
526 last=_get_next_page(vf,&og,-1);
527 if(last==OV_EREAD)return(OV_EREAD);
528 if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
530 if(last>=0)next=last;
532 searched=last+og.header_len+og.body_len;
536 /* Bisection point found */
538 /* for the time being, fetch end PCM offset the simple way */
540 int testserial = serialno+1;
542 while(testserial != serialno){
543 testserial = serialno;
544 vf->offset=_get_prev_page_serial(vf,&testserial,&searchgran);
548 if(vf->offset!=next){
549 ret=_seek_helper(vf,next);
553 ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
555 serialno = vf->os.serialno;
556 dataoffset = vf->offset;
558 /* this will consume a page, however the next bistection always
559 starts with a raw seek */
560 pcmoffset = _initial_pcmoffset(vf,&vi);
562 ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
563 next_serialno_list,next_serialnos,m+1);
566 if(next_serialno_list)_ogg_free(next_serialno_list);
568 vf->offsets[m+1]=next;
569 vf->serialnos[m+1]=serialno;
570 vf->dataoffsets[m+1]=dataoffset;
575 vf->pcmlengths[m*2+1]=searchgran;
576 vf->pcmlengths[m*2+2]=pcmoffset;
577 vf->pcmlengths[m*2+3]-=pcmoffset;
583 static int _make_decode_ready(OggVorbis_File *vf){
584 if(vf->ready_state>STREAMSET)return 0;
585 if(vf->ready_state<STREAMSET)return OV_EFAULT;
587 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
590 if(vorbis_synthesis_init(&vf->vd,vf->vi))
593 vorbis_block_init(&vf->vd,&vf->vb);
594 vf->ready_state=INITSET;
600 static int _open_seekable2(OggVorbis_File *vf){
601 ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
602 int endserial=vf->os.serialno;
603 int serialno=vf->os.serialno;
605 /* we're partially open and have a first link header state in
608 /* fetch initial PCM offset */
609 ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
611 /* we can seek, so set out learning all about this file */
612 if(vf->callbacks.seek_func && vf->callbacks.tell_func){
613 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
614 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
616 vf->offset=vf->end=-1;
619 /* If seek_func is implemented, tell_func must also be implemented */
620 if(vf->end==-1) return(OV_EINVAL);
622 /* Get the offset of the last page of the physical bitstream, or, if
623 we're lucky the last vorbis page of this link as most OggVorbis
624 files will contain a single logical bitstream */
625 end=_get_prev_page_serial(vf,&endserial,&endgran);
626 if(end<0)return(end);
628 /* now determine bitstream structure recursively */
629 if(_bisect_forward_serialno(vf,0,dataoffset,end+1,endgran,endserial,
630 vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
633 vf->serialnos[0]=serialno;
634 vf->dataoffsets[0]=dataoffset;
635 vf->pcmlengths[0]=pcmoffset;
636 vf->pcmlengths[1]-=pcmoffset;
638 return(ov_raw_seek(vf,dataoffset));
641 /* clear out the current logical bitstream decoder */
642 static void _decode_clear(OggVorbis_File *vf){
643 vorbis_dsp_clear(&vf->vd);
644 vorbis_block_clear(&vf->vb);
645 vf->ready_state=OPENED;
648 /* fetch and process a packet. Handles the case where we're at a
649 bitstream boundary and dumps the decoding machine. If the decoding
650 machine is unloaded, it loads it. It also keeps pcm_offset up to
651 date (seek and read both use this. seek uses a special hack with
654 return: <0) error, OV_HOLE (lost packet) or OV_EOF
655 0) need more data (only if readp==0)
659 static int _fetch_and_process_packet(OggVorbis_File *vf,
665 /* handle one packet. Try to fetch it from current stream state */
666 /* extract packets from page */
669 /* process a packet if we can. If the machine isn't loaded,
671 if(vf->ready_state==INITSET){
674 ogg_packet *op_ptr=(op_in?op_in:&op);
675 int result=ogg_stream_packetout(&vf->os,op_ptr);
676 ogg_int64_t granulepos;
679 if(result==-1)return(OV_HOLE); /* hole in the data. */
681 /* got a packet. process it */
682 granulepos=op_ptr->granulepos;
683 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
685 header packets aren't
688 vorbis_synthesis will
691 /* suck in the synthesis data and track bitrate */
693 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
694 /* for proper use of libvorbis within libvorbisfile,
695 oldsamples will always be zero. */
696 if(oldsamples)return(OV_EFAULT);
698 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
699 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
700 vf->bittrack+=op_ptr->bytes*8;
703 /* update the pcm offset. */
704 if(granulepos!=-1 && !op_ptr->e_o_s){
705 int link=(vf->seekable?vf->current_link:0);
708 /* this packet has a pcm_offset on it (the last packet
709 completed on a page carries the offset) After processing
710 (above), we know the pcm position of the *last* sample
711 ready to be returned. Find the offset of the *first*
713 As an aside, this trick is inaccurate if we begin
714 reading anew right at the last page; the end-of-stream
715 granulepos declares the last frame in the stream, and the
716 last packet of the last page may be a partial frame.
717 So, we need a previous granulepos from an in-sequence page
718 to have a reference point. Thus the !op_ptr->e_o_s clause
721 if(vf->seekable && link>0)
722 granulepos-=vf->pcmlengths[link*2];
723 if(granulepos<0)granulepos=0; /* actually, this
724 shouldn't be possible
725 here unless the stream
728 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
732 granulepos+=vf->pcmlengths[i*2+1];
733 vf->pcm_offset=granulepos;
743 if(vf->ready_state>=OPENED){
747 /* the loop is not strictly necessary, but there's no sense in
748 doing the extra checks of the larger loop for the common
749 case in a multiplexed bistream where the page is simply
750 part of a different logical bitstream; keep reading until
751 we get one with the correct serialno */
754 if((ret=_get_next_page(vf,&og,-1))<0){
755 return(OV_EOF); /* eof. leave unitialized */
758 /* bitrate tracking; add the header's bytes here, the body bytes
759 are done by packet above */
760 vf->bittrack+=og.header_len*8;
762 if(vf->ready_state==INITSET){
763 if(vf->current_serialno!=ogg_page_serialno(&og)){
765 /* two possibilities:
766 1) our decoding just traversed a bitstream boundary
767 2) another stream is multiplexed into this logical section */
769 if(ogg_page_bos(&og)){
777 vorbis_info_clear(vf->vi);
778 vorbis_comment_clear(vf->vc);
783 continue; /* possibility #2 */
791 /* Do we need to load a new machine before submitting the page? */
792 /* This is different in the seekable and non-seekable cases.
794 In the seekable case, we already have all the header
795 information loaded and cached; we just initialize the machine
796 with it and continue on our merry way.
798 In the non-seekable (streaming) case, we'll only be at a
799 boundary if we just left the previous logical bitstream and
800 we're now nominally at the header of the next bitstream
803 if(vf->ready_state!=INITSET){
806 if(vf->ready_state<STREAMSET){
808 long serialno = ogg_page_serialno(&og);
810 /* match the serialno to bitstream section. We use this rather than
811 offset positions to avoid problems near logical bitstream
814 for(link=0;link<vf->links;link++)
815 if(vf->serialnos[link]==serialno)break;
817 if(link==vf->links) continue; /* not the desired Vorbis
818 bitstream section; keep
821 vf->current_serialno=serialno;
822 vf->current_link=link;
824 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
825 vf->ready_state=STREAMSET;
828 /* we're streaming */
829 /* fetch the three header packets, build the info struct */
831 int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
833 vf->current_serialno=vf->os.serialno;
840 int ret=_make_decode_ready(vf);
845 /* the buffered page is the data we want, and we're ready for it;
846 add it to the stream state */
847 ogg_stream_pagein(&vf->os,&og);
852 /* if, eg, 64 bit stdio is configured by default, this will build with
854 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
855 if(f==NULL)return(-1);
856 return fseek(f,off,whence);
859 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
860 long ibytes, ov_callbacks callbacks){
861 int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
862 long *serialno_list=NULL;
863 int serialno_list_size=0;
866 memset(vf,0,sizeof(*vf));
868 vf->callbacks = callbacks;
870 /* init the framing state */
871 ogg_sync_init(&vf->oy);
873 /* perhaps some data was previously read into a buffer for testing
874 against other stream types. Allow initialization from this
875 previously read data (especially as we may be reading from a
876 non-seekable stream) */
878 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
879 memcpy(buffer,initial,ibytes);
880 ogg_sync_wrote(&vf->oy,ibytes);
883 /* can we seek? Stevens suggests the seek test was portable */
884 if(offsettest!=-1)vf->seekable=1;
886 /* No seeking yet; Set up a 'single' (current) logical bitstream
887 entry for partial open */
889 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
890 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
891 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
893 /* Fetch all BOS pages, store the vorbis header and all seen serial
894 numbers, load subsequent vorbis setup headers */
895 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
899 /* serial number list for first link needs to be held somewhere
900 for second stage of seekable stream open; this saves having to
901 seek/reread first link's serialnumber data then. */
902 vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos));
903 vf->serialnos[0]=vf->current_serialno;
904 vf->serialnos[1]=serialno_list_size;
905 memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
907 vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
908 vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
910 vf->dataoffsets[0]=vf->offset;
911 vf->current_serialno=vf->os.serialno;
913 vf->ready_state=PARTOPEN;
915 if(serialno_list)_ogg_free(serialno_list);
919 static int _ov_open2(OggVorbis_File *vf){
920 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
921 vf->ready_state=OPENED;
923 int ret=_open_seekable2(vf);
930 vf->ready_state=STREAMSET;
936 /* clear out the OggVorbis_File struct */
937 int ov_clear(OggVorbis_File *vf){
939 vorbis_block_clear(&vf->vb);
940 vorbis_dsp_clear(&vf->vd);
941 ogg_stream_clear(&vf->os);
943 if(vf->vi && vf->links){
945 for(i=0;i<vf->links;i++){
946 vorbis_info_clear(vf->vi+i);
947 vorbis_comment_clear(vf->vc+i);
952 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
953 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
954 if(vf->serialnos)_ogg_free(vf->serialnos);
955 if(vf->offsets)_ogg_free(vf->offsets);
956 ogg_sync_clear(&vf->oy);
957 if(vf->datasource && vf->callbacks.close_func)
958 (vf->callbacks.close_func)(vf->datasource);
959 memset(vf,0,sizeof(*vf));
967 /* inspects the OggVorbis file and finds/documents all the logical
968 bitstreams contained in it. Tries to be tolerant of logical
969 bitstream sections that are truncated/woogie.
975 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
976 ov_callbacks callbacks){
977 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
979 return _ov_open2(vf);
982 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
983 ov_callbacks callbacks = {
984 (size_t (*)(void *, size_t, size_t, void *)) fread,
985 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
986 (int (*)(void *)) fclose,
987 (long (*)(void *)) ftell
990 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
993 int ov_fopen(char *path,OggVorbis_File *vf){
995 FILE *f = fopen(path,"rb");
998 ret = ov_open(f,vf,NULL,0);
1004 /* cheap hack for game usage where downsampling is desirable; there's
1005 no need for SRC as we can just do it cheaply in libvorbis. */
1007 int ov_halfrate(OggVorbis_File *vf,int flag){
1009 if(vf->vi==NULL)return OV_EINVAL;
1010 if(!vf->seekable)return OV_EINVAL;
1011 if(vf->ready_state>=STREAMSET)
1012 _decode_clear(vf); /* clear out stream state; later on libvorbis
1013 will be able to swap this on the fly, but
1014 for now dumping the decode machine is needed
1015 to reinit the MDCT lookups. 1.1 libvorbis
1016 is planned to be able to switch on the fly */
1018 for(i=0;i<vf->links;i++){
1019 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
1027 int ov_halfrate_p(OggVorbis_File *vf){
1028 if(vf->vi==NULL)return OV_EINVAL;
1029 return vorbis_synthesis_halfrate_p(vf->vi);
1032 /* Only partially open the vorbis file; test for Vorbisness, and load
1033 the headers for the first chain. Do not seek (although test for
1034 seekability). Use ov_test_open to finish opening the file, else
1035 ov_clear to close/free it. Same return codes as open. */
1037 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
1038 ov_callbacks callbacks)
1040 return _ov_open1(f,vf,initial,ibytes,callbacks);
1043 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
1044 ov_callbacks callbacks = {
1045 (size_t (*)(void *, size_t, size_t, void *)) fread,
1046 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
1047 (int (*)(void *)) fclose,
1048 (long (*)(void *)) ftell
1051 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
1054 int ov_test_open(OggVorbis_File *vf){
1055 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
1056 return _ov_open2(vf);
1059 /* How many logical bitstreams in this physical bitstream? */
1060 long ov_streams(OggVorbis_File *vf){
1064 /* Is the FILE * associated with vf seekable? */
1065 long ov_seekable(OggVorbis_File *vf){
1066 return vf->seekable;
1069 /* returns the bitrate for a given logical bitstream or the entire
1070 physical bitstream. If the file is open for random access, it will
1071 find the *actual* average bitrate. If the file is streaming, it
1072 returns the nominal bitrate (if set) else the average of the
1073 upper/lower bounds (if set) else -1 (unset).
1075 If you want the actual bitrate field settings, get them from the
1076 vorbis_info structs */
1078 long ov_bitrate(OggVorbis_File *vf,int i){
1079 if(vf->ready_state<OPENED)return(OV_EINVAL);
1080 if(i>=vf->links)return(OV_EINVAL);
1081 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
1086 for(i=0;i<vf->links;i++)
1087 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
1088 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
1089 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
1090 * so this is slightly transformed to make it work.
1092 br = bits/ov_time_total(vf,-1);
1096 /* return the actual bitrate */
1097 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
1099 /* return nominal if set */
1100 if(vf->vi[i].bitrate_nominal>0){
1101 return vf->vi[i].bitrate_nominal;
1103 if(vf->vi[i].bitrate_upper>0){
1104 if(vf->vi[i].bitrate_lower>0){
1105 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1107 return vf->vi[i].bitrate_upper;
1116 /* returns the actual bitrate since last call. returns -1 if no
1117 additional data to offer since last call (or at beginning of stream),
1118 EINVAL if stream is only partially open
1120 long ov_bitrate_instant(OggVorbis_File *vf){
1121 int link=(vf->seekable?vf->current_link:0);
1123 if(vf->ready_state<OPENED)return(OV_EINVAL);
1124 if(vf->samptrack==0)return(OV_FALSE);
1125 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1132 long ov_serialnumber(OggVorbis_File *vf,int i){
1133 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1134 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1136 return(vf->current_serialno);
1138 return(vf->serialnos[i]);
1142 /* returns: total raw (compressed) length of content if i==-1
1143 raw (compressed) length of that logical bitstream for i==0 to n
1144 OV_EINVAL if the stream is not seekable (we can't know the length)
1145 or if stream is only partially open
1147 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1148 if(vf->ready_state<OPENED)return(OV_EINVAL);
1149 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1153 for(i=0;i<vf->links;i++)
1154 acc+=ov_raw_total(vf,i);
1157 return(vf->offsets[i+1]-vf->offsets[i]);
1161 /* returns: total PCM length (samples) of content if i==-1 PCM length
1162 (samples) of that logical bitstream for i==0 to n
1163 OV_EINVAL if the stream is not seekable (we can't know the
1164 length) or only partially open
1166 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1167 if(vf->ready_state<OPENED)return(OV_EINVAL);
1168 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1172 for(i=0;i<vf->links;i++)
1173 acc+=ov_pcm_total(vf,i);
1176 return(vf->pcmlengths[i*2+1]);
1180 /* returns: total seconds of content if i==-1
1181 seconds in that logical bitstream for i==0 to n
1182 OV_EINVAL if the stream is not seekable (we can't know the
1183 length) or only partially open
1185 double ov_time_total(OggVorbis_File *vf,int i){
1186 if(vf->ready_state<OPENED)return(OV_EINVAL);
1187 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1191 for(i=0;i<vf->links;i++)
1192 acc+=ov_time_total(vf,i);
1195 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1199 /* seek to an offset relative to the *compressed* data. This also
1200 scans packets to update the PCM cursor. It will cross a logical
1201 bitstream boundary, but only if it can't get any packets out of the
1202 tail of the bitstream we seek to (so no surprises).
1204 returns zero on success, nonzero on failure */
1206 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1207 ogg_stream_state work_os;
1210 if(vf->ready_state<OPENED)return(OV_EINVAL);
1212 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1214 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1216 /* don't yet clear out decoding machine (if it's initialized), in
1217 the case we're in the same link. Restart the decode lapping, and
1218 let _fetch_and_process_packet deal with a potential bitstream
1221 ogg_stream_reset_serialno(&vf->os,
1222 vf->current_serialno); /* must set serialno */
1223 vorbis_synthesis_restart(&vf->vd);
1225 ret=_seek_helper(vf,pos);
1226 if(ret)goto seek_error;
1228 /* we need to make sure the pcm_offset is set, but we don't want to
1229 advance the raw cursor past good packets just to get to the first
1230 with a granulepos. That's not equivalent behavior to beginning
1231 decoding as immediately after the seek position as possible.
1233 So, a hack. We use two stream states; a local scratch state and
1234 the shared vf->os stream state. We use the local state to
1235 scan, and the shared state as a buffer for later decode.
1237 Unfortuantely, on the last page we still advance to last packet
1238 because the granulepos on the last page is not necessarily on a
1239 packet boundary, and we need to make sure the granpos is
1251 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1252 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1253 return from not necessarily
1254 starting from the beginning */
1257 if(vf->ready_state>=STREAMSET){
1258 /* snarf/scan a packet if we can */
1259 int result=ogg_stream_packetout(&work_os,&op);
1263 if(vf->vi[vf->current_link].codec_setup){
1264 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1266 ogg_stream_packetout(&vf->os,NULL);
1271 ogg_stream_packetout(&vf->os,NULL);
1273 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1276 if(op.granulepos!=-1){
1277 int i,link=vf->current_link;
1278 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1279 if(granulepos<0)granulepos=0;
1282 granulepos+=vf->pcmlengths[i*2+1];
1283 vf->pcm_offset=granulepos-accblock;
1286 lastblock=thisblock;
1289 ogg_stream_packetout(&vf->os,NULL);
1294 if(_get_next_page(vf,&og,-1)<0){
1295 vf->pcm_offset=ov_pcm_total(vf,-1);
1299 /* huh? Bogus stream with packets but no granulepos */
1304 /* has our decoding just traversed a bitstream boundary? */
1305 if(vf->ready_state>=STREAMSET){
1306 if(vf->current_serialno!=ogg_page_serialno(&og)){
1308 /* two possibilities:
1309 1) our decoding just traversed a bitstream boundary
1310 2) another stream is multiplexed into this logical section? */
1312 if(ogg_page_bos(&og)){
1314 _decode_clear(vf); /* clear out stream state */
1315 ogg_stream_clear(&work_os);
1316 } /* else, do nothing; next loop will scoop another page */
1320 if(vf->ready_state<STREAMSET){
1322 long serialno = ogg_page_serialno(&og);
1324 for(link=0;link<vf->links;link++)
1325 if(vf->serialnos[link]==serialno)break;
1327 if(link==vf->links) continue; /* not the desired Vorbis
1328 bitstream section; keep
1330 vf->current_link=link;
1331 vf->current_serialno=serialno;
1332 ogg_stream_reset_serialno(&vf->os,serialno);
1333 ogg_stream_reset_serialno(&work_os,serialno);
1334 vf->ready_state=STREAMSET;
1338 ogg_stream_pagein(&vf->os,&og);
1339 ogg_stream_pagein(&work_os,&og);
1340 eosflag=ogg_page_eos(&og);
1344 ogg_stream_clear(&work_os);
1350 /* dump the machine so we're in a known state */
1352 ogg_stream_clear(&work_os);
1357 /* Page granularity seek (faster than sample granularity because we
1358 don't do the last bit of decode to find a specific sample).
1360 Seek to the last [granule marked] page preceeding the specified pos
1361 location, such that decoding past the returned point will quickly
1362 arrive at the requested position. */
1363 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1365 ogg_int64_t result=0;
1366 ogg_int64_t total=ov_pcm_total(vf,-1);
1368 if(vf->ready_state<OPENED)return(OV_EINVAL);
1369 if(!vf->seekable)return(OV_ENOSEEK);
1371 if(pos<0 || pos>total)return(OV_EINVAL);
1373 /* which bitstream section does this pcm offset occur in? */
1374 for(link=vf->links-1;link>=0;link--){
1375 total-=vf->pcmlengths[link*2+1];
1376 if(pos>=total)break;
1379 /* search within the logical bitstream for the page with the highest
1380 pcm_pos preceeding (or equal to) pos. There is a danger here;
1381 missing pages or incorrect frame number information in the
1382 bitstream could make our task impossible. Account for that (it
1383 would be an error condition) */
1385 /* new search algorithm by HB (Nicholas Vinen) */
1387 ogg_int64_t end=vf->offsets[link+1];
1388 ogg_int64_t begin=vf->offsets[link];
1389 ogg_int64_t begintime = vf->pcmlengths[link*2];
1390 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1391 ogg_int64_t target=pos-total+begintime;
1392 ogg_int64_t best=begin;
1398 if(end-begin<CHUNKSIZE){
1401 /* take a (pretty decent) guess. */
1403 (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime))
1409 result=_seek_helper(vf,bisect);
1410 if(result) goto seek_error;
1413 result=_get_next_page(vf,&og,end-vf->offset);
1414 if(result==OV_EREAD) goto seek_error;
1417 end=begin; /* found it */
1419 if(bisect==0) goto seek_error;
1421 if(bisect<=begin)bisect=begin+1;
1422 result=_seek_helper(vf,bisect);
1423 if(result) goto seek_error;
1426 ogg_int64_t granulepos;
1428 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1431 granulepos=ogg_page_granulepos(&og);
1432 if(granulepos==-1)continue;
1434 if(granulepos<target){
1435 best=result; /* raw offset of packet with granulepos */
1436 begin=vf->offset; /* raw offset of next page */
1437 begintime=granulepos;
1439 if(target-begintime>44100)break;
1440 bisect=begin; /* *not* begin + 1 */
1443 end=begin; /* found it */
1445 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1447 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1448 if(bisect<=begin)bisect=begin+1;
1449 result=_seek_helper(vf,bisect);
1450 if(result) goto seek_error;
1462 /* found our page. seek to it, update pcm offset. Easier case than
1463 raw_seek, don't keep packets preceeding granulepos. */
1469 result=_seek_helper(vf,best);
1471 if(result) goto seek_error;
1472 result=_get_next_page(vf,&og,-1);
1473 if(result<0) goto seek_error;
1475 if(link!=vf->current_link){
1476 /* Different link; dump entire decode machine */
1479 vf->current_link=link;
1480 vf->current_serialno=vf->serialnos[link];
1481 vf->ready_state=STREAMSET;
1484 vorbis_synthesis_restart(&vf->vd);
1487 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1488 ogg_stream_pagein(&vf->os,&og);
1490 /* pull out all but last packet; the one with granulepos */
1492 result=ogg_stream_packetpeek(&vf->os,&op);
1494 /* !!! the packet finishing this page originated on a
1495 preceeding page. Keep fetching previous pages until we
1496 get one with a granulepos or without the 'continued' flag
1497 set. Then just use raw_seek for simplicity. */
1499 result=_seek_helper(vf,best);
1500 if(result<0) goto seek_error;
1503 result=_get_prev_page(vf,&og);
1504 if(result<0) goto seek_error;
1505 if(ogg_page_serialno(&og)==vf->current_serialno &&
1506 (ogg_page_granulepos(&og)>-1 ||
1507 !ogg_page_continued(&og))){
1508 return ov_raw_seek(vf,result);
1514 result = OV_EBADPACKET;
1517 if(op.granulepos!=-1){
1518 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1519 if(vf->pcm_offset<0)vf->pcm_offset=0;
1520 vf->pcm_offset+=total;
1523 result=ogg_stream_packetout(&vf->os,NULL);
1529 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1538 /* dump machine so we're in a known state */
1544 /* seek to a sample offset relative to the decompressed pcm stream
1545 returns zero on success, nonzero on failure */
1547 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1548 int thisblock,lastblock=0;
1549 int ret=ov_pcm_seek_page(vf,pos);
1550 if(ret<0)return(ret);
1551 if((ret=_make_decode_ready(vf)))return ret;
1553 /* discard leading packets we don't need for the lapping of the
1554 position we want; don't decode them */
1560 int ret=ogg_stream_packetpeek(&vf->os,&op);
1562 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1564 ogg_stream_packetout(&vf->os,NULL);
1565 continue; /* non audio packet */
1567 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1569 if(vf->pcm_offset+((thisblock+
1570 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1572 /* remove the packet from packet queue and track its granulepos */
1573 ogg_stream_packetout(&vf->os,NULL);
1574 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1577 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1579 /* end of logical stream case is hard, especially with exact
1580 length positioning. */
1582 if(op.granulepos>-1){
1584 /* always believe the stream markers */
1585 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1586 if(vf->pcm_offset<0)vf->pcm_offset=0;
1587 for(i=0;i<vf->current_link;i++)
1588 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1591 lastblock=thisblock;
1594 if(ret<0 && ret!=OV_HOLE)break;
1596 /* suck in a new page */
1597 if(_get_next_page(vf,&og,-1)<0)break;
1598 if(ogg_page_bos(&og))_decode_clear(vf);
1600 if(vf->ready_state<STREAMSET){
1601 long serialno=ogg_page_serialno(&og);
1604 for(link=0;link<vf->links;link++)
1605 if(vf->serialnos[link]==serialno)break;
1606 if(link==vf->links) continue;
1607 vf->current_link=link;
1609 vf->ready_state=STREAMSET;
1610 vf->current_serialno=ogg_page_serialno(&og);
1611 ogg_stream_reset_serialno(&vf->os,serialno);
1612 ret=_make_decode_ready(vf);
1617 ogg_stream_pagein(&vf->os,&og);
1623 /* discard samples until we reach the desired position. Crossing a
1624 logical bitstream boundary with abandon is OK. */
1625 while(vf->pcm_offset<pos){
1626 ogg_int64_t target=pos-vf->pcm_offset;
1627 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1629 if(samples>target)samples=target;
1630 vorbis_synthesis_read(&vf->vd,samples);
1631 vf->pcm_offset+=samples;
1634 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1635 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1640 /* seek to a playback time relative to the decompressed pcm stream
1641 returns zero on success, nonzero on failure */
1642 int ov_time_seek(OggVorbis_File *vf,double seconds){
1643 /* translate time to PCM position and call ov_pcm_seek */
1646 ogg_int64_t pcm_total=0;
1647 double time_total=0.;
1649 if(vf->ready_state<OPENED)return(OV_EINVAL);
1650 if(!vf->seekable)return(OV_ENOSEEK);
1651 if(seconds<0)return(OV_EINVAL);
1653 /* which bitstream section does this time offset occur in? */
1654 for(link=0;link<vf->links;link++){
1655 double addsec = ov_time_total(vf,link);
1656 if(seconds<time_total+addsec)break;
1658 pcm_total+=vf->pcmlengths[link*2+1];
1661 if(link==vf->links)return(OV_EINVAL);
1663 /* enough information to convert time offset to pcm offset */
1665 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1666 return(ov_pcm_seek(vf,target));
1670 /* page-granularity version of ov_time_seek
1671 returns zero on success, nonzero on failure */
1672 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1673 /* translate time to PCM position and call ov_pcm_seek */
1676 ogg_int64_t pcm_total=0;
1677 double time_total=0.;
1679 if(vf->ready_state<OPENED)return(OV_EINVAL);
1680 if(!vf->seekable)return(OV_ENOSEEK);
1681 if(seconds<0)return(OV_EINVAL);
1683 /* which bitstream section does this time offset occur in? */
1684 for(link=0;link<vf->links;link++){
1685 double addsec = ov_time_total(vf,link);
1686 if(seconds<time_total+addsec)break;
1688 pcm_total+=vf->pcmlengths[link*2+1];
1691 if(link==vf->links)return(OV_EINVAL);
1693 /* enough information to convert time offset to pcm offset */
1695 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1696 return(ov_pcm_seek_page(vf,target));
1700 /* tell the current stream offset cursor. Note that seek followed by
1701 tell will likely not give the set offset due to caching */
1702 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1703 if(vf->ready_state<OPENED)return(OV_EINVAL);
1707 /* return PCM offset (sample) of next PCM sample to be read */
1708 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1709 if(vf->ready_state<OPENED)return(OV_EINVAL);
1710 return(vf->pcm_offset);
1713 /* return time offset (seconds) of next PCM sample to be read */
1714 double ov_time_tell(OggVorbis_File *vf){
1716 ogg_int64_t pcm_total=0;
1717 double time_total=0.f;
1719 if(vf->ready_state<OPENED)return(OV_EINVAL);
1721 pcm_total=ov_pcm_total(vf,-1);
1722 time_total=ov_time_total(vf,-1);
1724 /* which bitstream section does this time offset occur in? */
1725 for(link=vf->links-1;link>=0;link--){
1726 pcm_total-=vf->pcmlengths[link*2+1];
1727 time_total-=ov_time_total(vf,link);
1728 if(vf->pcm_offset>=pcm_total)break;
1732 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1735 /* link: -1) return the vorbis_info struct for the bitstream section
1736 currently being decoded
1737 0-n) to request information for a specific bitstream section
1739 In the case of a non-seekable bitstream, any call returns the
1740 current bitstream. NULL in the case that the machine is not
1743 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1746 if(vf->ready_state>=STREAMSET)
1747 return vf->vi+vf->current_link;
1760 /* grr, strong typing, grr, no templates/inheritence, grr */
1761 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1764 if(vf->ready_state>=STREAMSET)
1765 return vf->vc+vf->current_link;
1778 static int host_is_big_endian() {
1779 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1780 unsigned char *bytewise = (unsigned char *)&pattern;
1781 if (bytewise[0] == 0xfe) return 1;
1785 /* up to this point, everything could more or less hide the multiple
1786 logical bitstream nature of chaining from the toplevel application
1787 if the toplevel application didn't particularly care. However, at
1788 the point that we actually read audio back, the multiple-section
1789 nature must surface: Multiple bitstream sections do not necessarily
1790 have to have the same number of channels or sampling rate.
1792 ov_read returns the sequential logical bitstream number currently
1793 being decoded along with the PCM data in order that the toplevel
1794 application can take action on channel/sample rate changes. This
1795 number will be incremented even for streamed (non-seekable) streams
1796 (for seekable streams, it represents the actual logical bitstream
1797 index within the physical bitstream. Note that the accessor
1798 functions above are aware of this dichotomy).
1800 ov_read_filter is exactly the same as ov_read except that it processes
1801 the decoded audio data through a filter before packing it into the
1802 requested format. This gives greater accuracy than applying a filter
1803 after the audio has been converted into integral PCM.
1805 input values: buffer) a buffer to hold packed PCM data for return
1806 length) the byte length requested to be placed into buffer
1807 bigendianp) should the data be packed LSB first (0) or
1809 word) word size for output. currently 1 (byte) or
1812 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1814 n) number of bytes of PCM actually returned. The
1815 below works on a packet-by-packet basis, so the
1816 return length is not related to the 'length' passed
1817 in, just guaranteed to fit.
1819 *section) set to the logical bitstream number */
1821 long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
1822 int bigendianp,int word,int sgned,int *bitstream,
1823 void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
1825 int host_endian = host_is_big_endian();
1830 if(vf->ready_state<OPENED)return(OV_EINVAL);
1833 if(vf->ready_state==INITSET){
1834 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1838 /* suck in another packet */
1840 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1851 /* yay! proceed to pack data into the byte buffer */
1853 long channels=ov_info(vf,-1)->channels;
1854 long bytespersample=word * channels;
1855 vorbis_fpu_control fpu;
1856 if(samples>length/bytespersample)samples=length/bytespersample;
1863 filter(pcm,channels,samples,filter_param);
1865 /* a tight loop to pack each size */
1869 int off=(sgned?0:128);
1870 vorbis_fpu_setround(&fpu);
1871 for(j=0;j<samples;j++)
1872 for(i=0;i<channels;i++){
1873 val=vorbis_ftoi(pcm[i][j]*128.f);
1875 else if(val<-128)val=-128;
1878 vorbis_fpu_restore(fpu);
1880 int off=(sgned?0:32768);
1882 if(host_endian==bigendianp){
1885 vorbis_fpu_setround(&fpu);
1886 for(i=0;i<channels;i++) { /* It's faster in this order */
1888 short *dest=((short *)buffer)+i;
1889 for(j=0;j<samples;j++) {
1890 val=vorbis_ftoi(src[j]*32768.f);
1891 if(val>32767)val=32767;
1892 else if(val<-32768)val=-32768;
1897 vorbis_fpu_restore(fpu);
1901 vorbis_fpu_setround(&fpu);
1902 for(i=0;i<channels;i++) {
1904 short *dest=((short *)buffer)+i;
1905 for(j=0;j<samples;j++) {
1906 val=vorbis_ftoi(src[j]*32768.f);
1907 if(val>32767)val=32767;
1908 else if(val<-32768)val=-32768;
1913 vorbis_fpu_restore(fpu);
1916 }else if(bigendianp){
1918 vorbis_fpu_setround(&fpu);
1919 for(j=0;j<samples;j++)
1920 for(i=0;i<channels;i++){
1921 val=vorbis_ftoi(pcm[i][j]*32768.f);
1922 if(val>32767)val=32767;
1923 else if(val<-32768)val=-32768;
1926 *buffer++=(val&0xff);
1928 vorbis_fpu_restore(fpu);
1932 vorbis_fpu_setround(&fpu);
1933 for(j=0;j<samples;j++)
1934 for(i=0;i<channels;i++){
1935 val=vorbis_ftoi(pcm[i][j]*32768.f);
1936 if(val>32767)val=32767;
1937 else if(val<-32768)val=-32768;
1939 *buffer++=(val&0xff);
1942 vorbis_fpu_restore(fpu);
1948 vorbis_synthesis_read(&vf->vd,samples);
1949 vf->pcm_offset+=samples;
1950 if(bitstream)*bitstream=vf->current_link;
1951 return(samples*bytespersample);
1957 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1958 int bigendianp,int word,int sgned,int *bitstream){
1959 return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
1962 /* input values: pcm_channels) a float vector per channel of output
1963 length) the sample length being read by the app
1965 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1967 n) number of samples of PCM actually returned. The
1968 below works on a packet-by-packet basis, so the
1969 return length is not related to the 'length' passed
1970 in, just guaranteed to fit.
1972 *section) set to the logical bitstream number */
1976 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1979 if(vf->ready_state<OPENED)return(OV_EINVAL);
1982 if(vf->ready_state==INITSET){
1984 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1986 if(pcm_channels)*pcm_channels=pcm;
1987 if(samples>length)samples=length;
1988 vorbis_synthesis_read(&vf->vd,samples);
1989 vf->pcm_offset+=samples;
1990 if(bitstream)*bitstream=vf->current_link;
1996 /* suck in another packet */
1998 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1999 if(ret==OV_EOF)return(0);
2000 if(ret<=0)return(ret);
2006 extern float *vorbis_window(vorbis_dsp_state *v,int W);
2007 extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
2010 static void _ov_splice(float **pcm,float **lappcm,
2013 float *w1, float *w2){
2024 for(j=0;j<ch1 && j<ch2;j++){
2031 d[i]=d[i]*wd + s[i]*ws;
2034 /* window from zero */
2045 /* make sure vf is INITSET */
2046 static int _ov_initset(OggVorbis_File *vf){
2048 if(vf->ready_state==INITSET)break;
2049 /* suck in another packet */
2051 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2052 if(ret<0 && ret!=OV_HOLE)return(ret);
2058 /* make sure vf is INITSET and that we have a primed buffer; if
2059 we're crosslapping at a stream section boundary, this also makes
2060 sure we're sanity checking against the right stream information */
2061 static int _ov_initprime(OggVorbis_File *vf){
2062 vorbis_dsp_state *vd=&vf->vd;
2064 if(vf->ready_state==INITSET)
2065 if(vorbis_synthesis_pcmout(vd,NULL))break;
2067 /* suck in another packet */
2069 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2070 if(ret<0 && ret!=OV_HOLE)return(ret);
2076 /* grab enough data for lapping from vf; this may be in the form of
2077 unreturned, already-decoded pcm, remaining PCM we will need to
2078 decode, or synthetic postextrapolation from last packets. */
2079 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
2080 float **lappcm,int lapsize){
2084 /* try first to decode the lapping data */
2085 while(lapcount<lapsize){
2086 int samples=vorbis_synthesis_pcmout(vd,&pcm);
2088 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2089 for(i=0;i<vi->channels;i++)
2090 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2092 vorbis_synthesis_read(vd,samples);
2094 /* suck in another packet */
2095 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
2096 if(ret==OV_EOF)break;
2099 if(lapcount<lapsize){
2100 /* failed to get lapping data from normal decode; pry it from the
2101 postextrapolation buffering, or the second half of the MDCT
2102 from the last packet */
2103 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
2105 for(i=0;i<vi->channels;i++)
2106 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2109 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2110 for(i=0;i<vi->channels;i++)
2111 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2117 /* this sets up crosslapping of a sample by using trailing data from
2118 sample 1 and lapping it into the windowing buffer of sample 2 */
2119 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2120 vorbis_info *vi1,*vi2;
2124 int n1,n2,i,ret,hs1,hs2;
2126 if(vf1==vf2)return(0); /* degenerate case */
2127 if(vf1->ready_state<OPENED)return(OV_EINVAL);
2128 if(vf2->ready_state<OPENED)return(OV_EINVAL);
2130 /* the relevant overlap buffers must be pre-checked and pre-primed
2131 before looking at settings in the event that priming would cross
2132 a bitstream boundary. So, do it now */
2134 ret=_ov_initset(vf1);
2136 ret=_ov_initprime(vf2);
2139 vi1=ov_info(vf1,-1);
2140 vi2=ov_info(vf2,-1);
2141 hs1=ov_halfrate_p(vf1);
2142 hs2=ov_halfrate_p(vf2);
2144 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2145 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2146 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2147 w1=vorbis_window(&vf1->vd,0);
2148 w2=vorbis_window(&vf2->vd,0);
2150 for(i=0;i<vi1->channels;i++)
2151 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2153 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2155 /* have a lapping buffer from vf1; now to splice it into the lapping
2157 /* consolidate and expose the buffer. */
2158 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2159 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2160 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2163 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2169 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2170 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2175 int n1,n2,ch1,ch2,hs;
2178 if(vf->ready_state<OPENED)return(OV_EINVAL);
2179 ret=_ov_initset(vf);
2182 hs=ov_halfrate_p(vf);
2185 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2186 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2187 persistent; even if the decode state
2188 from this link gets dumped, this
2189 window array continues to exist */
2191 lappcm=alloca(sizeof(*lappcm)*ch1);
2193 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2194 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2196 /* have lapping data; seek and prime the buffer */
2197 ret=localseek(vf,pos);
2199 ret=_ov_initprime(vf);
2202 /* Guard against cross-link changes; they're perfectly legal */
2205 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2206 w2=vorbis_window(&vf->vd,0);
2208 /* consolidate and expose the buffer. */
2209 vorbis_synthesis_lapout(&vf->vd,&pcm);
2212 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2218 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2219 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2222 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2223 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2226 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2227 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2230 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2231 int (*localseek)(OggVorbis_File *,double)){
2236 int n1,n2,ch1,ch2,hs;
2239 if(vf->ready_state<OPENED)return(OV_EINVAL);
2240 ret=_ov_initset(vf);
2243 hs=ov_halfrate_p(vf);
2246 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2247 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2248 persistent; even if the decode state
2249 from this link gets dumped, this
2250 window array continues to exist */
2252 lappcm=alloca(sizeof(*lappcm)*ch1);
2254 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2255 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2257 /* have lapping data; seek and prime the buffer */
2258 ret=localseek(vf,pos);
2260 ret=_ov_initprime(vf);
2263 /* Guard against cross-link changes; they're perfectly legal */
2266 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2267 w2=vorbis_window(&vf->vd,0);
2269 /* consolidate and expose the buffer. */
2270 vorbis_synthesis_lapout(&vf->vd,&pcm);
2273 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2279 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2280 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2283 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2284 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);