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 if(vf->ready_state==STREAMSET){
679 int ret=_make_decode_ready(vf);
683 /* process a packet if we can. */
685 if(vf->ready_state==INITSET){
688 ogg_packet *op_ptr=(op_in?op_in:&op);
689 int result=ogg_stream_packetout(&vf->os,op_ptr);
690 ogg_int64_t granulepos;
693 if(result==-1)return(OV_HOLE); /* hole in the data. */
695 /* got a packet. process it */
696 granulepos=op_ptr->granulepos;
697 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
699 header packets aren't
702 vorbis_synthesis will
705 /* suck in the synthesis data and track bitrate */
707 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
708 /* for proper use of libvorbis within libvorbisfile,
709 oldsamples will always be zero. */
710 if(oldsamples)return(OV_EFAULT);
712 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
713 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
714 vf->bittrack+=op_ptr->bytes*8;
717 /* update the pcm offset. */
718 if(granulepos!=-1 && !op_ptr->e_o_s){
719 int link=(vf->seekable?vf->current_link:0);
722 /* this packet has a pcm_offset on it (the last packet
723 completed on a page carries the offset) After processing
724 (above), we know the pcm position of the *last* sample
725 ready to be returned. Find the offset of the *first*
727 As an aside, this trick is inaccurate if we begin
728 reading anew right at the last page; the end-of-stream
729 granulepos declares the last frame in the stream, and the
730 last packet of the last page may be a partial frame.
731 So, we need a previous granulepos from an in-sequence page
732 to have a reference point. Thus the !op_ptr->e_o_s clause
735 if(vf->seekable && link>0)
736 granulepos-=vf->pcmlengths[link*2];
737 if(granulepos<0)granulepos=0; /* actually, this
738 shouldn't be possible
739 here unless the stream
742 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
746 granulepos+=vf->pcmlengths[i*2+1];
747 vf->pcm_offset=granulepos;
757 if(vf->ready_state>=OPENED){
761 /* the loop is not strictly necessary, but there's no sense in
762 doing the extra checks of the larger loop for the common
763 case in a multiplexed bistream where the page is simply
764 part of a different logical bitstream; keep reading until
765 we get one with the correct serialno */
768 if((ret=_get_next_page(vf,&og,-1))<0){
769 return(OV_EOF); /* eof. leave unitialized */
772 /* bitrate tracking; add the header's bytes here, the body bytes
773 are done by packet above */
774 vf->bittrack+=og.header_len*8;
776 if(vf->ready_state==INITSET){
777 if(vf->current_serialno!=ogg_page_serialno(&og)){
779 /* two possibilities:
780 1) our decoding just traversed a bitstream boundary
781 2) another stream is multiplexed into this logical section */
783 if(ogg_page_bos(&og)){
791 vorbis_info_clear(vf->vi);
792 vorbis_comment_clear(vf->vc);
797 continue; /* possibility #2 */
805 /* Do we need to load a new machine before submitting the page? */
806 /* This is different in the seekable and non-seekable cases.
808 In the seekable case, we already have all the header
809 information loaded and cached; we just initialize the machine
810 with it and continue on our merry way.
812 In the non-seekable (streaming) case, we'll only be at a
813 boundary if we just left the previous logical bitstream and
814 we're now nominally at the header of the next bitstream
817 if(vf->ready_state!=INITSET){
820 if(vf->ready_state<STREAMSET){
822 long serialno = ogg_page_serialno(&og);
824 /* match the serialno to bitstream section. We use this rather than
825 offset positions to avoid problems near logical bitstream
828 for(link=0;link<vf->links;link++)
829 if(vf->serialnos[link]==serialno)break;
831 if(link==vf->links) continue; /* not the desired Vorbis
832 bitstream section; keep
835 vf->current_serialno=serialno;
836 vf->current_link=link;
838 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
839 vf->ready_state=STREAMSET;
842 /* we're streaming */
843 /* fetch the three header packets, build the info struct */
845 int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
847 vf->current_serialno=vf->os.serialno;
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_int64_t pagepos=-1;
1262 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1263 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1264 return from not necessarily
1265 starting from the beginning */
1268 if(vf->ready_state>=STREAMSET){
1269 /* snarf/scan a packet if we can */
1270 int result=ogg_stream_packetout(&work_os,&op);
1274 if(vf->vi[vf->current_link].codec_setup){
1275 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1277 ogg_stream_packetout(&vf->os,NULL);
1281 /* We can't get a guaranteed correct pcm position out of the
1282 last page in a stream because it might have a 'short'
1283 granpos, which can only be detected in the presence of a
1284 preceeding page. However, if the last page is also the first
1285 page, the granpos rules of a first page take precedence. Not
1286 only that, but for first==last, the EOS page must be treated
1287 as if its a normal first page for the stream to open/play. */
1288 if(lastflag && !firstflag)
1289 ogg_stream_packetout(&vf->os,NULL);
1291 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1294 if(op.granulepos!=-1){
1295 int i,link=vf->current_link;
1296 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1297 if(granulepos<0)granulepos=0;
1300 granulepos+=vf->pcmlengths[i*2+1];
1301 vf->pcm_offset=granulepos-accblock;
1302 if(vf->pcm_offset<0)vf->pcm_offset=0;
1305 lastblock=thisblock;
1308 ogg_stream_packetout(&vf->os,NULL);
1313 pagepos=_get_next_page(vf,&og,-1);
1315 vf->pcm_offset=ov_pcm_total(vf,-1);
1319 /* huh? Bogus stream with packets but no granulepos */
1324 /* has our decoding just traversed a bitstream boundary? */
1325 if(vf->ready_state>=STREAMSET){
1326 if(vf->current_serialno!=ogg_page_serialno(&og)){
1328 /* two possibilities:
1329 1) our decoding just traversed a bitstream boundary
1330 2) another stream is multiplexed into this logical section? */
1332 if(ogg_page_bos(&og)){
1334 _decode_clear(vf); /* clear out stream state */
1335 ogg_stream_clear(&work_os);
1336 } /* else, do nothing; next loop will scoop another page */
1340 if(vf->ready_state<STREAMSET){
1342 long serialno = ogg_page_serialno(&og);
1344 for(link=0;link<vf->links;link++)
1345 if(vf->serialnos[link]==serialno)break;
1347 if(link==vf->links) continue; /* not the desired Vorbis
1348 bitstream section; keep
1350 vf->current_link=link;
1351 vf->current_serialno=serialno;
1352 ogg_stream_reset_serialno(&vf->os,serialno);
1353 ogg_stream_reset_serialno(&work_os,serialno);
1354 vf->ready_state=STREAMSET;
1355 firstflag=(pagepos<=vf->dataoffsets[link]);
1358 ogg_stream_pagein(&vf->os,&og);
1359 ogg_stream_pagein(&work_os,&og);
1360 lastflag=ogg_page_eos(&og);
1365 ogg_stream_clear(&work_os);
1371 /* dump the machine so we're in a known state */
1373 ogg_stream_clear(&work_os);
1378 /* Page granularity seek (faster than sample granularity because we
1379 don't do the last bit of decode to find a specific sample).
1381 Seek to the last [granule marked] page preceeding the specified pos
1382 location, such that decoding past the returned point will quickly
1383 arrive at the requested position. */
1384 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1386 ogg_int64_t result=0;
1387 ogg_int64_t total=ov_pcm_total(vf,-1);
1389 if(vf->ready_state<OPENED)return(OV_EINVAL);
1390 if(!vf->seekable)return(OV_ENOSEEK);
1392 if(pos<0 || pos>total)return(OV_EINVAL);
1394 /* which bitstream section does this pcm offset occur in? */
1395 for(link=vf->links-1;link>=0;link--){
1396 total-=vf->pcmlengths[link*2+1];
1397 if(pos>=total)break;
1400 /* search within the logical bitstream for the page with the highest
1401 pcm_pos preceeding (or equal to) pos. There is a danger here;
1402 missing pages or incorrect frame number information in the
1403 bitstream could make our task impossible. Account for that (it
1404 would be an error condition) */
1406 /* new search algorithm by HB (Nicholas Vinen) */
1408 ogg_int64_t end=vf->offsets[link+1];
1409 ogg_int64_t begin=vf->offsets[link];
1410 ogg_int64_t begintime = vf->pcmlengths[link*2];
1411 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1412 ogg_int64_t target=pos-total+begintime;
1413 ogg_int64_t best=begin;
1419 if(end-begin<CHUNKSIZE){
1422 /* take a (pretty decent) guess. */
1424 (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime))
1430 result=_seek_helper(vf,bisect);
1431 if(result) goto seek_error;
1434 result=_get_next_page(vf,&og,end-vf->offset);
1435 if(result==OV_EREAD) goto seek_error;
1438 end=begin; /* found it */
1440 if(bisect==0) goto seek_error;
1442 if(bisect<=begin)bisect=begin+1;
1443 result=_seek_helper(vf,bisect);
1444 if(result) goto seek_error;
1447 ogg_int64_t granulepos;
1449 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1452 granulepos=ogg_page_granulepos(&og);
1453 if(granulepos==-1)continue;
1455 if(granulepos<target){
1456 best=result; /* raw offset of packet with granulepos */
1457 begin=vf->offset; /* raw offset of next page */
1458 begintime=granulepos;
1460 if(target-begintime>44100)break;
1461 bisect=begin; /* *not* begin + 1 */
1464 end=begin; /* found it */
1466 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1468 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1469 if(bisect<=begin)bisect=begin+1;
1470 result=_seek_helper(vf,bisect);
1471 if(result) goto seek_error;
1483 /* found our page. seek to it, update pcm offset. Easier case than
1484 raw_seek, don't keep packets preceeding granulepos. */
1490 result=_seek_helper(vf,best);
1492 if(result) goto seek_error;
1493 result=_get_next_page(vf,&og,-1);
1494 if(result<0) goto seek_error;
1496 if(link!=vf->current_link){
1497 /* Different link; dump entire decode machine */
1500 vf->current_link=link;
1501 vf->current_serialno=vf->serialnos[link];
1502 vf->ready_state=STREAMSET;
1505 vorbis_synthesis_restart(&vf->vd);
1508 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1509 ogg_stream_pagein(&vf->os,&og);
1511 /* pull out all but last packet; the one with granulepos */
1513 result=ogg_stream_packetpeek(&vf->os,&op);
1515 /* !!! the packet finishing this page originated on a
1516 preceeding page. Keep fetching previous pages until we
1517 get one with a granulepos or without the 'continued' flag
1518 set. Then just use raw_seek for simplicity. */
1520 result=_seek_helper(vf,best);
1521 if(result<0) goto seek_error;
1524 result=_get_prev_page(vf,&og);
1525 if(result<0) goto seek_error;
1526 if(ogg_page_serialno(&og)==vf->current_serialno &&
1527 (ogg_page_granulepos(&og)>-1 ||
1528 !ogg_page_continued(&og))){
1529 return ov_raw_seek(vf,result);
1535 result = OV_EBADPACKET;
1538 if(op.granulepos!=-1){
1539 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1540 if(vf->pcm_offset<0)vf->pcm_offset=0;
1541 vf->pcm_offset+=total;
1544 result=ogg_stream_packetout(&vf->os,NULL);
1550 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1559 /* dump machine so we're in a known state */
1565 /* seek to a sample offset relative to the decompressed pcm stream
1566 returns zero on success, nonzero on failure */
1568 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1569 int thisblock,lastblock=0;
1570 int ret=ov_pcm_seek_page(vf,pos);
1571 if(ret<0)return(ret);
1572 if((ret=_make_decode_ready(vf)))return ret;
1574 /* discard leading packets we don't need for the lapping of the
1575 position we want; don't decode them */
1581 int ret=ogg_stream_packetpeek(&vf->os,&op);
1583 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1585 ogg_stream_packetout(&vf->os,NULL);
1586 continue; /* non audio packet */
1588 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1590 if(vf->pcm_offset+((thisblock+
1591 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1593 /* remove the packet from packet queue and track its granulepos */
1594 ogg_stream_packetout(&vf->os,NULL);
1595 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1598 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1600 /* end of logical stream case is hard, especially with exact
1601 length positioning. */
1603 if(op.granulepos>-1){
1605 /* always believe the stream markers */
1606 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1607 if(vf->pcm_offset<0)vf->pcm_offset=0;
1608 for(i=0;i<vf->current_link;i++)
1609 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1612 lastblock=thisblock;
1615 if(ret<0 && ret!=OV_HOLE)break;
1617 /* suck in a new page */
1618 if(_get_next_page(vf,&og,-1)<0)break;
1619 if(ogg_page_bos(&og))_decode_clear(vf);
1621 if(vf->ready_state<STREAMSET){
1622 long serialno=ogg_page_serialno(&og);
1625 for(link=0;link<vf->links;link++)
1626 if(vf->serialnos[link]==serialno)break;
1627 if(link==vf->links) continue;
1628 vf->current_link=link;
1630 vf->ready_state=STREAMSET;
1631 vf->current_serialno=ogg_page_serialno(&og);
1632 ogg_stream_reset_serialno(&vf->os,serialno);
1633 ret=_make_decode_ready(vf);
1638 ogg_stream_pagein(&vf->os,&og);
1644 /* discard samples until we reach the desired position. Crossing a
1645 logical bitstream boundary with abandon is OK. */
1646 while(vf->pcm_offset<pos){
1647 ogg_int64_t target=pos-vf->pcm_offset;
1648 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1650 if(samples>target)samples=target;
1651 vorbis_synthesis_read(&vf->vd,samples);
1652 vf->pcm_offset+=samples;
1655 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1656 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1661 /* seek to a playback time relative to the decompressed pcm stream
1662 returns zero on success, nonzero on failure */
1663 int ov_time_seek(OggVorbis_File *vf,double seconds){
1664 /* translate time to PCM position and call ov_pcm_seek */
1667 ogg_int64_t pcm_total=0;
1668 double time_total=0.;
1670 if(vf->ready_state<OPENED)return(OV_EINVAL);
1671 if(!vf->seekable)return(OV_ENOSEEK);
1672 if(seconds<0)return(OV_EINVAL);
1674 /* which bitstream section does this time offset occur in? */
1675 for(link=0;link<vf->links;link++){
1676 double addsec = ov_time_total(vf,link);
1677 if(seconds<time_total+addsec)break;
1679 pcm_total+=vf->pcmlengths[link*2+1];
1682 if(link==vf->links)return(OV_EINVAL);
1684 /* enough information to convert time offset to pcm offset */
1686 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1687 return(ov_pcm_seek(vf,target));
1691 /* page-granularity version of ov_time_seek
1692 returns zero on success, nonzero on failure */
1693 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1694 /* translate time to PCM position and call ov_pcm_seek */
1697 ogg_int64_t pcm_total=0;
1698 double time_total=0.;
1700 if(vf->ready_state<OPENED)return(OV_EINVAL);
1701 if(!vf->seekable)return(OV_ENOSEEK);
1702 if(seconds<0)return(OV_EINVAL);
1704 /* which bitstream section does this time offset occur in? */
1705 for(link=0;link<vf->links;link++){
1706 double addsec = ov_time_total(vf,link);
1707 if(seconds<time_total+addsec)break;
1709 pcm_total+=vf->pcmlengths[link*2+1];
1712 if(link==vf->links)return(OV_EINVAL);
1714 /* enough information to convert time offset to pcm offset */
1716 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1717 return(ov_pcm_seek_page(vf,target));
1721 /* tell the current stream offset cursor. Note that seek followed by
1722 tell will likely not give the set offset due to caching */
1723 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1724 if(vf->ready_state<OPENED)return(OV_EINVAL);
1728 /* return PCM offset (sample) of next PCM sample to be read */
1729 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1730 if(vf->ready_state<OPENED)return(OV_EINVAL);
1731 return(vf->pcm_offset);
1734 /* return time offset (seconds) of next PCM sample to be read */
1735 double ov_time_tell(OggVorbis_File *vf){
1737 ogg_int64_t pcm_total=0;
1738 double time_total=0.f;
1740 if(vf->ready_state<OPENED)return(OV_EINVAL);
1742 pcm_total=ov_pcm_total(vf,-1);
1743 time_total=ov_time_total(vf,-1);
1745 /* which bitstream section does this time offset occur in? */
1746 for(link=vf->links-1;link>=0;link--){
1747 pcm_total-=vf->pcmlengths[link*2+1];
1748 time_total-=ov_time_total(vf,link);
1749 if(vf->pcm_offset>=pcm_total)break;
1753 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1756 /* link: -1) return the vorbis_info struct for the bitstream section
1757 currently being decoded
1758 0-n) to request information for a specific bitstream section
1760 In the case of a non-seekable bitstream, any call returns the
1761 current bitstream. NULL in the case that the machine is not
1764 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1767 if(vf->ready_state>=STREAMSET)
1768 return vf->vi+vf->current_link;
1781 /* grr, strong typing, grr, no templates/inheritence, grr */
1782 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1785 if(vf->ready_state>=STREAMSET)
1786 return vf->vc+vf->current_link;
1799 static int host_is_big_endian() {
1800 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1801 unsigned char *bytewise = (unsigned char *)&pattern;
1802 if (bytewise[0] == 0xfe) return 1;
1806 /* up to this point, everything could more or less hide the multiple
1807 logical bitstream nature of chaining from the toplevel application
1808 if the toplevel application didn't particularly care. However, at
1809 the point that we actually read audio back, the multiple-section
1810 nature must surface: Multiple bitstream sections do not necessarily
1811 have to have the same number of channels or sampling rate.
1813 ov_read returns the sequential logical bitstream number currently
1814 being decoded along with the PCM data in order that the toplevel
1815 application can take action on channel/sample rate changes. This
1816 number will be incremented even for streamed (non-seekable) streams
1817 (for seekable streams, it represents the actual logical bitstream
1818 index within the physical bitstream. Note that the accessor
1819 functions above are aware of this dichotomy).
1821 ov_read_filter is exactly the same as ov_read except that it processes
1822 the decoded audio data through a filter before packing it into the
1823 requested format. This gives greater accuracy than applying a filter
1824 after the audio has been converted into integral PCM.
1826 input values: buffer) a buffer to hold packed PCM data for return
1827 length) the byte length requested to be placed into buffer
1828 bigendianp) should the data be packed LSB first (0) or
1830 word) word size for output. currently 1 (byte) or
1833 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1835 n) number of bytes of PCM actually returned. The
1836 below works on a packet-by-packet basis, so the
1837 return length is not related to the 'length' passed
1838 in, just guaranteed to fit.
1840 *section) set to the logical bitstream number */
1842 long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
1843 int bigendianp,int word,int sgned,int *bitstream,
1844 void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
1846 int host_endian = host_is_big_endian();
1851 if(vf->ready_state<OPENED)return(OV_EINVAL);
1854 if(vf->ready_state==INITSET){
1855 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1859 /* suck in another packet */
1861 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1872 /* yay! proceed to pack data into the byte buffer */
1874 long channels=ov_info(vf,-1)->channels;
1875 long bytespersample=word * channels;
1876 vorbis_fpu_control fpu;
1877 if(samples>length/bytespersample)samples=length/bytespersample;
1884 filter(pcm,channels,samples,filter_param);
1886 /* a tight loop to pack each size */
1890 int off=(sgned?0:128);
1891 vorbis_fpu_setround(&fpu);
1892 for(j=0;j<samples;j++)
1893 for(i=0;i<channels;i++){
1894 val=vorbis_ftoi(pcm[i][j]*128.f);
1896 else if(val<-128)val=-128;
1899 vorbis_fpu_restore(fpu);
1901 int off=(sgned?0:32768);
1903 if(host_endian==bigendianp){
1906 vorbis_fpu_setround(&fpu);
1907 for(i=0;i<channels;i++) { /* It's faster in this order */
1909 short *dest=((short *)buffer)+i;
1910 for(j=0;j<samples;j++) {
1911 val=vorbis_ftoi(src[j]*32768.f);
1912 if(val>32767)val=32767;
1913 else if(val<-32768)val=-32768;
1918 vorbis_fpu_restore(fpu);
1922 vorbis_fpu_setround(&fpu);
1923 for(i=0;i<channels;i++) {
1925 short *dest=((short *)buffer)+i;
1926 for(j=0;j<samples;j++) {
1927 val=vorbis_ftoi(src[j]*32768.f);
1928 if(val>32767)val=32767;
1929 else if(val<-32768)val=-32768;
1934 vorbis_fpu_restore(fpu);
1937 }else if(bigendianp){
1939 vorbis_fpu_setround(&fpu);
1940 for(j=0;j<samples;j++)
1941 for(i=0;i<channels;i++){
1942 val=vorbis_ftoi(pcm[i][j]*32768.f);
1943 if(val>32767)val=32767;
1944 else if(val<-32768)val=-32768;
1947 *buffer++=(val&0xff);
1949 vorbis_fpu_restore(fpu);
1953 vorbis_fpu_setround(&fpu);
1954 for(j=0;j<samples;j++)
1955 for(i=0;i<channels;i++){
1956 val=vorbis_ftoi(pcm[i][j]*32768.f);
1957 if(val>32767)val=32767;
1958 else if(val<-32768)val=-32768;
1960 *buffer++=(val&0xff);
1963 vorbis_fpu_restore(fpu);
1969 vorbis_synthesis_read(&vf->vd,samples);
1970 vf->pcm_offset+=samples;
1971 if(bitstream)*bitstream=vf->current_link;
1972 return(samples*bytespersample);
1978 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1979 int bigendianp,int word,int sgned,int *bitstream){
1980 return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
1983 /* input values: pcm_channels) a float vector per channel of output
1984 length) the sample length being read by the app
1986 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1988 n) number of samples of PCM actually returned. The
1989 below works on a packet-by-packet basis, so the
1990 return length is not related to the 'length' passed
1991 in, just guaranteed to fit.
1993 *section) set to the logical bitstream number */
1997 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
2000 if(vf->ready_state<OPENED)return(OV_EINVAL);
2003 if(vf->ready_state==INITSET){
2005 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
2007 if(pcm_channels)*pcm_channels=pcm;
2008 if(samples>length)samples=length;
2009 vorbis_synthesis_read(&vf->vd,samples);
2010 vf->pcm_offset+=samples;
2011 if(bitstream)*bitstream=vf->current_link;
2017 /* suck in another packet */
2019 int ret=_fetch_and_process_packet(vf,NULL,1,1);
2020 if(ret==OV_EOF)return(0);
2021 if(ret<=0)return(ret);
2027 extern float *vorbis_window(vorbis_dsp_state *v,int W);
2029 static void _ov_splice(float **pcm,float **lappcm,
2032 float *w1, float *w2){
2043 for(j=0;j<ch1 && j<ch2;j++){
2050 d[i]=d[i]*wd + s[i]*ws;
2053 /* window from zero */
2064 /* make sure vf is INITSET */
2065 static int _ov_initset(OggVorbis_File *vf){
2067 if(vf->ready_state==INITSET)break;
2068 /* suck in another packet */
2070 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2071 if(ret<0 && ret!=OV_HOLE)return(ret);
2077 /* make sure vf is INITSET and that we have a primed buffer; if
2078 we're crosslapping at a stream section boundary, this also makes
2079 sure we're sanity checking against the right stream information */
2080 static int _ov_initprime(OggVorbis_File *vf){
2081 vorbis_dsp_state *vd=&vf->vd;
2083 if(vf->ready_state==INITSET)
2084 if(vorbis_synthesis_pcmout(vd,NULL))break;
2086 /* suck in another packet */
2088 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2089 if(ret<0 && ret!=OV_HOLE)return(ret);
2095 /* grab enough data for lapping from vf; this may be in the form of
2096 unreturned, already-decoded pcm, remaining PCM we will need to
2097 decode, or synthetic postextrapolation from last packets. */
2098 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
2099 float **lappcm,int lapsize){
2103 /* try first to decode the lapping data */
2104 while(lapcount<lapsize){
2105 int samples=vorbis_synthesis_pcmout(vd,&pcm);
2107 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2108 for(i=0;i<vi->channels;i++)
2109 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2111 vorbis_synthesis_read(vd,samples);
2113 /* suck in another packet */
2114 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
2115 if(ret==OV_EOF)break;
2118 if(lapcount<lapsize){
2119 /* failed to get lapping data from normal decode; pry it from the
2120 postextrapolation buffering, or the second half of the MDCT
2121 from the last packet */
2122 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
2124 for(i=0;i<vi->channels;i++)
2125 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2128 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2129 for(i=0;i<vi->channels;i++)
2130 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2136 /* this sets up crosslapping of a sample by using trailing data from
2137 sample 1 and lapping it into the windowing buffer of sample 2 */
2138 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2139 vorbis_info *vi1,*vi2;
2143 int n1,n2,i,ret,hs1,hs2;
2145 if(vf1==vf2)return(0); /* degenerate case */
2146 if(vf1->ready_state<OPENED)return(OV_EINVAL);
2147 if(vf2->ready_state<OPENED)return(OV_EINVAL);
2149 /* the relevant overlap buffers must be pre-checked and pre-primed
2150 before looking at settings in the event that priming would cross
2151 a bitstream boundary. So, do it now */
2153 ret=_ov_initset(vf1);
2155 ret=_ov_initprime(vf2);
2158 vi1=ov_info(vf1,-1);
2159 vi2=ov_info(vf2,-1);
2160 hs1=ov_halfrate_p(vf1);
2161 hs2=ov_halfrate_p(vf2);
2163 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2164 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2165 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2166 w1=vorbis_window(&vf1->vd,0);
2167 w2=vorbis_window(&vf2->vd,0);
2169 for(i=0;i<vi1->channels;i++)
2170 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2172 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2174 /* have a lapping buffer from vf1; now to splice it into the lapping
2176 /* consolidate and expose the buffer. */
2177 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2180 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2181 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2185 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2191 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2192 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2197 int n1,n2,ch1,ch2,hs;
2200 if(vf->ready_state<OPENED)return(OV_EINVAL);
2201 ret=_ov_initset(vf);
2204 hs=ov_halfrate_p(vf);
2207 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2208 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2209 persistent; even if the decode state
2210 from this link gets dumped, this
2211 window array continues to exist */
2213 lappcm=alloca(sizeof(*lappcm)*ch1);
2215 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2216 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2218 /* have lapping data; seek and prime the buffer */
2219 ret=localseek(vf,pos);
2221 ret=_ov_initprime(vf);
2224 /* Guard against cross-link changes; they're perfectly legal */
2227 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2228 w2=vorbis_window(&vf->vd,0);
2230 /* consolidate and expose the buffer. */
2231 vorbis_synthesis_lapout(&vf->vd,&pcm);
2234 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2240 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2241 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2244 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2245 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2248 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2249 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2252 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2253 int (*localseek)(OggVorbis_File *,double)){
2258 int n1,n2,ch1,ch2,hs;
2261 if(vf->ready_state<OPENED)return(OV_EINVAL);
2262 ret=_ov_initset(vf);
2265 hs=ov_halfrate_p(vf);
2268 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2269 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2270 persistent; even if the decode state
2271 from this link gets dumped, this
2272 window array continues to exist */
2274 lappcm=alloca(sizeof(*lappcm)*ch1);
2276 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2277 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2279 /* have lapping data; seek and prime the buffer */
2280 ret=localseek(vf,pos);
2282 ret=_ov_initprime(vf);
2285 /* Guard against cross-link changes; they're perfectly legal */
2288 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2289 w2=vorbis_window(&vf->vd,0);
2291 /* consolidate and expose the buffer. */
2292 vorbis_synthesis_lapout(&vf->vd,&pcm);
2295 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2301 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2302 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2305 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2306 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);