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-2015 *
9 * by the Xiph.Org Foundation https://xiph.org/ *
11 ********************************************************************
13 function: stdio-based convenience library for opening/seeking/decoding
15 ********************************************************************/
23 #include "vorbis/codec.h"
25 /* we don't need or want the static callback symbols here */
26 #define OV_EXCLUDE_STATIC_CALLBACKS
27 #include "vorbis/vorbisfile.h"
32 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
33 one logical bitstream arranged end to end (the only form of Ogg
34 multiplexing allowed in a Vorbis bitstream; grouping [parallel
35 multiplexing] is not allowed in Vorbis) */
37 /* A Vorbis file can be played beginning to end (streamed) without
38 worrying ahead of time about chaining (see decoder_example.c). If
39 we have the whole file, however, and want random access
40 (seeking/scrubbing) or desire to know the total length/time of a
41 file, we need to account for the possibility of chaining. */
43 /* We can handle things a number of ways; we can determine the entire
44 bitstream structure right off the bat, or find pieces on demand.
45 This example determines and caches structure for the entire
46 bitstream, but builds a virtual decoder on the fly when moving
47 between links in the chain. */
49 /* There are also different ways to implement seeking. Enough
50 information exists in an Ogg bitstream to seek to
51 sample-granularity positions in the output. Or, one can seek by
52 picking some portion of the stream roughly in the desired area if
53 we only want coarse navigation through the stream. */
55 /*************************************************************************
56 * Many, many internal helpers. The intention is not to be confusing;
57 * rampant duplication and monolithic function implementation would be
58 * harder to understand anyway. The high level functions are last. Begin
59 * grokking near the end of the file */
61 /* read a little more data from the file/pipe into the ogg_sync framer
63 #define CHUNKSIZE 65536 /* greater-than-page-size granularity seeking */
64 #define READSIZE 2048 /* a smaller read size is needed for low-rate streaming. */
66 static long _get_data(OggVorbis_File *vf){
68 if(!(vf->callbacks.read_func))return(-1);
70 char *buffer=ogg_sync_buffer(&vf->oy,READSIZE);
71 long bytes=(vf->callbacks.read_func)(buffer,1,READSIZE,vf->datasource);
72 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
73 if(bytes==0 && errno)return(-1);
79 /* save a tiny smidge of verbosity to make the code more readable */
80 static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
82 /* only seek if the file position isn't already there */
83 if(vf->offset != offset){
84 if(!(vf->callbacks.seek_func)||
85 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
88 ogg_sync_reset(&vf->oy);
91 /* shouldn't happen unless someone writes a broken callback */
97 /* The read/seek functions track absolute position within the stream */
99 /* from the head of the stream, get the next page. boundary specifies
100 if the function is allowed to fetch more data from the stream (and
101 how much) or only use internally buffered data.
103 boundary: -1) unbounded search
104 0) read no additional data; use cached only
105 n) search for a new page beginning for n bytes
107 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
108 n) found a page at absolute offset n */
110 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
111 ogg_int64_t boundary){
112 if(boundary>0)boundary+=vf->offset;
116 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
117 more=ogg_sync_pageseek(&vf->oy,og);
120 /* skipped n bytes */
124 /* send more paramedics */
125 if(!boundary)return(OV_FALSE);
127 long ret=_get_data(vf);
128 if(ret==0)return(OV_EOF);
129 if(ret<0)return(OV_EREAD);
132 /* got a page. Return the offset at the page beginning,
133 advance the internal offset past the page end */
134 ogg_int64_t ret=vf->offset;
143 /* find the latest page beginning before the passed in position. Much
144 dirtier than the above as Ogg doesn't have any backward search
145 linkage. no 'readp' as it will certainly have to read. */
146 /* returns offset or OV_EREAD, OV_FAULT */
147 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_int64_t begin,ogg_page *og){
148 ogg_int64_t end = begin;
150 ogg_int64_t offset=-1;
157 ret=_seek_helper(vf,begin);
160 while(vf->offset<end){
161 memset(og,0,sizeof(*og));
162 ret=_get_next_page(vf,og,end-vf->offset);
163 if(ret==OV_EREAD)return(OV_EREAD);
172 /* In a fully compliant, non-multiplexed stream, we'll still be
173 holding the last page. In multiplexed (or noncompliant streams),
174 we will probably have to re-read the last page we saw */
175 if(og->header_len==0){
176 ret=_seek_helper(vf,offset);
179 ret=_get_next_page(vf,og,CHUNKSIZE);
181 /* this shouldn't be possible */
188 static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
189 long s = ogg_page_serialno(og);
193 *serialno_list = _ogg_realloc(*serialno_list, sizeof(**serialno_list)*(*n));
195 *serialno_list = _ogg_malloc(sizeof(**serialno_list));
198 (*serialno_list)[(*n)-1] = s;
201 /* returns nonzero if found */
202 static int _lookup_serialno(long s, long *serialno_list, int n){
205 if(*serialno_list == s) return 1;
212 static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
213 long s = ogg_page_serialno(og);
214 return _lookup_serialno(s,serialno_list,n);
217 /* performs the same search as _get_prev_page, but prefers pages of
218 the specified serial number. If a page of the specified serialno is
219 spotted during the seek-back-and-read-forward, it will return the
220 info of last page of the matching serial number instead of the very
221 last page. If no page of the specified serialno is seen, it will
222 return the info of last page and alter *serialno. */
223 static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, ogg_int64_t begin,
224 long *serial_list, int serial_n,
225 int *serialno, ogg_int64_t *granpos){
227 ogg_int64_t end=begin;
230 ogg_int64_t prefoffset=-1;
231 ogg_int64_t offset=-1;
232 ogg_int64_t ret_serialno=-1;
233 ogg_int64_t ret_gran=-1;
240 ret=_seek_helper(vf,begin);
243 while(vf->offset<end){
244 ret=_get_next_page(vf,&og,end-vf->offset);
245 if(ret==OV_EREAD)return(OV_EREAD);
249 ret_serialno=ogg_page_serialno(&og);
250 ret_gran=ogg_page_granulepos(&og);
253 if(ret_serialno == *serialno){
258 if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){
259 /* we fell off the end of the link, which means we seeked
260 back too far and shouldn't have been looking in that link
261 to begin with. If we found the preferred serial number,
262 forget that we saw it. */
267 /*We started from the beginning of the stream and found nothing.
268 This should be impossible unless the contents of the stream changed out
269 from under us after we read from it.*/
270 if(!begin&&vf->offset<0)return OV_EBADLINK;
273 /* we're not interested in the page... just the serialno and granpos. */
274 if(prefoffset>=0)return(prefoffset);
276 *serialno = ret_serialno;
282 /* uses the local ogg_stream storage in vf; this is important for
283 non-streaming input sources */
284 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
285 long **serialno_list, int *serialno_n,
293 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
294 if(llret==OV_EREAD)return(OV_EREAD);
295 if(llret<0)return(OV_ENOTVORBIS);
299 vorbis_info_init(vi);
300 vorbis_comment_init(vc);
301 vf->ready_state=OPENED;
303 /* extract the serialnos of all BOS pages + the first set of vorbis
304 headers we see in the link */
306 while(ogg_page_bos(og_ptr)){
308 if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
309 /* a dupe serialnumber in an initial header packet set == invalid stream */
310 if(*serialno_list)_ogg_free(*serialno_list);
317 _add_serialno(og_ptr,serialno_list,serialno_n);
320 if(vf->ready_state<STREAMSET){
321 /* we don't have a vorbis stream in this link yet, so begin
322 prospective stream setup. We need a stream to get packets */
323 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
324 ogg_stream_pagein(&vf->os,og_ptr);
326 if(ogg_stream_packetout(&vf->os,&op) > 0 &&
327 vorbis_synthesis_idheader(&op)){
328 /* vorbis header; continue setup */
329 vf->ready_state=STREAMSET;
330 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
339 ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
349 /* if this page also belongs to our vorbis stream, submit it and break */
350 if(vf->ready_state==STREAMSET &&
351 vf->os.serialno == ogg_page_serialno(og_ptr)){
352 ogg_stream_pagein(&vf->os,og_ptr);
358 if(vf->ready_state!=STREAMSET){
366 while(i<2){ /* get a page loop */
368 while(i<2){ /* get a packet loop */
370 int result=ogg_stream_packetout(&vf->os,&op);
377 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
384 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
389 /* if this page belongs to the correct stream, go parse it */
390 if(vf->os.serialno == ogg_page_serialno(og_ptr)){
391 ogg_stream_pagein(&vf->os,og_ptr);
395 /* if we never see the final vorbis headers before the link
397 if(ogg_page_bos(og_ptr)){
405 /* otherwise, keep looking */
413 vorbis_info_clear(vi);
414 vorbis_comment_clear(vc);
415 vf->ready_state=OPENED;
420 /* Starting from current cursor position, get initial PCM offset of
421 next page. Consumes the page in the process without decoding
422 audio, however this is only called during stream parsing upon
424 static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
426 ogg_int64_t accumulated=0;
429 int serialno = vf->os.serialno;
433 if(_get_next_page(vf,&og,-1)<0)
434 break; /* should not be possible unless the file is truncated/mangled */
436 if(ogg_page_bos(&og)) break;
437 if(ogg_page_serialno(&og)!=serialno) continue;
439 /* count blocksizes of all frames in the page */
440 ogg_stream_pagein(&vf->os,&og);
441 while((result=ogg_stream_packetout(&vf->os,&op))){
442 if(result>0){ /* ignore holes */
443 long thisblock=vorbis_packet_blocksize(vi,&op);
446 accumulated+=(lastblock+thisblock)>>2;
452 if(ogg_page_granulepos(&og)!=-1){
453 /* pcm offset of last packet on the first audio page */
454 accumulated= ogg_page_granulepos(&og)-accumulated;
459 /* less than zero? Either a corrupt file or a stream with samples
460 trimmed off the beginning, a normal occurrence; in both cases set
461 the offset to zero */
462 if(accumulated<0)accumulated=0;
467 /* finds each bitstream link one at a time using a bisection search
468 (has to begin by knowing the offset of the lb's initial page).
469 Recurses for each link so it can alloc the link storage after
470 finding them all, then unroll and fill the cache at the same time */
471 static int _bisect_forward_serialno(OggVorbis_File *vf,
473 ogg_int64_t searched,
477 long *currentno_list,
480 ogg_int64_t pcmoffset;
481 ogg_int64_t dataoffset=searched;
482 ogg_int64_t endsearched=end;
483 ogg_int64_t next=end;
484 ogg_int64_t searchgran=-1;
486 ogg_int64_t ret,last;
487 int serialno = vf->os.serialno;
490 we have the headers and serialnos for the link beginning at 'begin'
491 we have the offset and granpos of the last page in the file (potentially
492 not a page we care about)
495 /* Is the last page in our list of current serialnumbers? */
496 if(_lookup_serialno(endserial,currentno_list,currentnos)){
498 /* last page is in the starting serialno list, so we've bisected
499 down to (or just started with) a single link. Now we need to
500 find the last vorbis page belonging to the first vorbis stream
503 while(endserial != serialno){
504 endserial = serialno;
505 searched=_get_prev_page_serial(vf,searched,currentno_list,currentnos,&endserial,&endgran);
509 if(vf->offsets)_ogg_free(vf->offsets);
510 if(vf->serialnos)_ogg_free(vf->serialnos);
511 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
513 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
514 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
515 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
516 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
517 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
518 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
520 vf->offsets[m+1]=end;
521 vf->offsets[m]=begin;
522 vf->pcmlengths[m*2+1]=(endgran<0?0:endgran);
526 /* last page is not in the starting stream's serial number list,
527 so we have multiple links. Find where the stream that begins
528 our bisection ends. */
530 long *next_serialno_list=NULL;
531 int next_serialnos=0;
534 int testserial = serialno+1;
536 /* the below guards against garbage seperating the last and
537 first pages of two links. */
538 while(searched<endsearched){
541 if(endsearched-searched<CHUNKSIZE){
544 bisect=(searched+endsearched)/2;
547 ret=_seek_helper(vf,bisect);
550 last=_get_next_page(vf,&og,-1);
551 if(last==OV_EREAD)return(OV_EREAD);
552 if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
554 if(last>=0)next=last;
560 /* Bisection point found */
561 /* for the time being, fetch end PCM offset the simple way */
563 while(testserial != serialno){
564 testserial = serialno;
565 searched = _get_prev_page_serial(vf,searched,currentno_list,currentnos,&testserial,&searchgran);
568 ret=_seek_helper(vf,next);
571 ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
573 serialno = vf->os.serialno;
574 dataoffset = vf->offset;
576 /* this will consume a page, however the next bisection always
577 starts with a raw seek */
578 pcmoffset = _initial_pcmoffset(vf,&vi);
580 ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
581 next_serialno_list,next_serialnos,m+1);
584 if(next_serialno_list)_ogg_free(next_serialno_list);
586 vf->offsets[m+1]=next;
587 vf->serialnos[m+1]=serialno;
588 vf->dataoffsets[m+1]=dataoffset;
593 vf->pcmlengths[m*2+1]=searchgran;
594 vf->pcmlengths[m*2+2]=pcmoffset;
595 vf->pcmlengths[m*2+3]-=pcmoffset;
596 if(vf->pcmlengths[m*2+3]<0)vf->pcmlengths[m*2+3]=0;
601 static int _make_decode_ready(OggVorbis_File *vf){
602 if(vf->ready_state>STREAMSET)return 0;
603 if(vf->ready_state<STREAMSET)return OV_EFAULT;
605 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
608 if(vorbis_synthesis_init(&vf->vd,vf->vi))
611 vorbis_block_init(&vf->vd,&vf->vb);
612 vf->ready_state=INITSET;
618 static int _open_seekable2(OggVorbis_File *vf){
619 ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
620 int endserial=vf->os.serialno;
621 int serialno=vf->os.serialno;
623 /* we're partially open and have a first link header state in
626 /* fetch initial PCM offset */
627 ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
629 /* we can seek, so set out learning all about this file */
630 if(vf->callbacks.seek_func && vf->callbacks.tell_func){
631 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
632 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
634 vf->offset=vf->end=-1;
637 /* If seek_func is implemented, tell_func must also be implemented */
638 if(vf->end==-1) return(OV_EINVAL);
640 /* Get the offset of the last page of the physical bitstream, or, if
641 we're lucky the last vorbis page of this link as most OggVorbis
642 files will contain a single logical bitstream */
643 end=_get_prev_page_serial(vf,vf->end,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
644 if(end<0)return(end);
646 /* now determine bitstream structure recursively */
647 if(_bisect_forward_serialno(vf,0,dataoffset,end,endgran,endserial,
648 vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
651 vf->serialnos[0]=serialno;
652 vf->dataoffsets[0]=dataoffset;
653 vf->pcmlengths[0]=pcmoffset;
654 vf->pcmlengths[1]-=pcmoffset;
655 if(vf->pcmlengths[1]<0)vf->pcmlengths[1]=0;
657 return(ov_raw_seek(vf,dataoffset));
660 /* clear out the current logical bitstream decoder */
661 static void _decode_clear(OggVorbis_File *vf){
662 vorbis_dsp_clear(&vf->vd);
663 vorbis_block_clear(&vf->vb);
664 vf->ready_state=OPENED;
667 /* fetch and process a packet. Handles the case where we're at a
668 bitstream boundary and dumps the decoding machine. If the decoding
669 machine is unloaded, it loads it. It also keeps pcm_offset up to
670 date (seek and read both use this. seek uses a special hack with
673 return: <0) error, OV_HOLE (lost packet) or OV_EOF
674 0) need more data (only if readp==0)
678 static int _fetch_and_process_packet(OggVorbis_File *vf,
684 /* handle one packet. Try to fetch it from current stream state */
685 /* extract packets from page */
688 if(vf->ready_state==STREAMSET){
689 int ret=_make_decode_ready(vf);
693 /* process a packet if we can. */
695 if(vf->ready_state==INITSET){
696 int hs=vorbis_synthesis_halfrate_p(vf->vi);
700 ogg_packet *op_ptr=(op_in?op_in:&op);
701 int result=ogg_stream_packetout(&vf->os,op_ptr);
702 ogg_int64_t granulepos;
705 if(result==-1)return(OV_HOLE); /* hole in the data. */
707 /* got a packet. process it */
708 granulepos=op_ptr->granulepos;
709 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
711 header packets aren't
714 vorbis_synthesis will
717 /* suck in the synthesis data and track bitrate */
719 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
720 /* for proper use of libvorbis within libvorbisfile,
721 oldsamples will always be zero. */
722 if(oldsamples)return(OV_EFAULT);
724 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
725 vf->samptrack+=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
726 vf->bittrack+=op_ptr->bytes*8;
729 /* update the pcm offset. */
730 if(granulepos!=-1 && !op_ptr->e_o_s){
731 int link=(vf->seekable?vf->current_link:0);
734 /* this packet has a pcm_offset on it (the last packet
735 completed on a page carries the offset) After processing
736 (above), we know the pcm position of the *last* sample
737 ready to be returned. Find the offset of the *first*
739 As an aside, this trick is inaccurate if we begin
740 reading anew right at the last page; the end-of-stream
741 granulepos declares the last frame in the stream, and the
742 last packet of the last page may be a partial frame.
743 So, we need a previous granulepos from an in-sequence page
744 to have a reference point. Thus the !op_ptr->e_o_s clause
747 if(vf->seekable && link>0)
748 granulepos-=vf->pcmlengths[link*2];
749 if(granulepos<0)granulepos=0; /* actually, this
750 shouldn't be possible
751 here unless the stream
754 samples=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
758 granulepos+=vf->pcmlengths[i*2+1];
759 vf->pcm_offset=granulepos;
769 if(vf->ready_state>=OPENED){
773 /* the loop is not strictly necessary, but there's no sense in
774 doing the extra checks of the larger loop for the common
775 case in a multiplexed bistream where the page is simply
776 part of a different logical bitstream; keep reading until
777 we get one with the correct serialno */
780 if((ret=_get_next_page(vf,&og,-1))<0){
781 return(OV_EOF); /* eof. leave unitialized */
784 /* bitrate tracking; add the header's bytes here, the body bytes
785 are done by packet above */
786 vf->bittrack+=og.header_len*8;
788 if(vf->ready_state==INITSET){
789 if(vf->current_serialno!=ogg_page_serialno(&og)){
791 /* two possibilities:
792 1) our decoding just traversed a bitstream boundary
793 2) another stream is multiplexed into this logical section */
795 if(ogg_page_bos(&og)){
803 vorbis_info_clear(vf->vi);
804 vorbis_comment_clear(vf->vc);
809 continue; /* possibility #2 */
817 /* Do we need to load a new machine before submitting the page? */
818 /* This is different in the seekable and non-seekable cases.
820 In the seekable case, we already have all the header
821 information loaded and cached; we just initialize the machine
822 with it and continue on our merry way.
824 In the non-seekable (streaming) case, we'll only be at a
825 boundary if we just left the previous logical bitstream and
826 we're now nominally at the header of the next bitstream
829 if(vf->ready_state!=INITSET){
832 if(vf->ready_state<STREAMSET){
834 long serialno = ogg_page_serialno(&og);
836 /* match the serialno to bitstream section. We use this rather than
837 offset positions to avoid problems near logical bitstream
840 for(link=0;link<vf->links;link++)
841 if(vf->serialnos[link]==serialno)break;
843 if(link==vf->links) continue; /* not the desired Vorbis
844 bitstream section; keep
847 vf->current_serialno=serialno;
848 vf->current_link=link;
850 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
851 vf->ready_state=STREAMSET;
854 /* we're streaming */
855 /* fetch the three header packets, build the info struct */
857 int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
859 vf->current_serialno=vf->os.serialno;
866 /* the buffered page is the data we want, and we're ready for it;
867 add it to the stream state */
868 ogg_stream_pagein(&vf->os,&og);
873 /* if, eg, 64 bit stdio is configured by default, this will build with
875 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
876 if(f==NULL)return(-1);
877 return fseek(f,off,whence);
880 static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial,
881 long ibytes, ov_callbacks callbacks){
882 int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
883 long *serialno_list=NULL;
884 int serialno_list_size=0;
887 memset(vf,0,sizeof(*vf));
889 vf->callbacks = callbacks;
891 /* init the framing state */
892 ogg_sync_init(&vf->oy);
894 /* perhaps some data was previously read into a buffer for testing
895 against other stream types. Allow initialization from this
896 previously read data (especially as we may be reading from a
897 non-seekable stream) */
899 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
900 memcpy(buffer,initial,ibytes);
901 ogg_sync_wrote(&vf->oy,ibytes);
904 /* can we seek? Stevens suggests the seek test was portable */
905 if(offsettest!=-1)vf->seekable=1;
907 /* No seeking yet; Set up a 'single' (current) logical bitstream
908 entry for partial open */
910 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
911 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
912 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
914 /* Fetch all BOS pages, store the vorbis header and all seen serial
915 numbers, load subsequent vorbis setup headers */
916 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
920 /* serial number list for first link needs to be held somewhere
921 for second stage of seekable stream open; this saves having to
922 seek/reread first link's serialnumber data then. */
923 vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos));
924 vf->serialnos[0]=vf->current_serialno=vf->os.serialno;
925 vf->serialnos[1]=serialno_list_size;
926 memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
928 vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
929 vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
931 vf->dataoffsets[0]=vf->offset;
933 vf->ready_state=PARTOPEN;
935 if(serialno_list)_ogg_free(serialno_list);
939 static int _ov_open2(OggVorbis_File *vf){
940 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
941 vf->ready_state=OPENED;
943 int ret=_open_seekable2(vf);
950 vf->ready_state=STREAMSET;
956 /* clear out the OggVorbis_File struct */
957 int ov_clear(OggVorbis_File *vf){
959 vorbis_block_clear(&vf->vb);
960 vorbis_dsp_clear(&vf->vd);
961 ogg_stream_clear(&vf->os);
963 if(vf->vi && vf->links){
965 for(i=0;i<vf->links;i++){
966 vorbis_info_clear(vf->vi+i);
967 vorbis_comment_clear(vf->vc+i);
972 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
973 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
974 if(vf->serialnos)_ogg_free(vf->serialnos);
975 if(vf->offsets)_ogg_free(vf->offsets);
976 ogg_sync_clear(&vf->oy);
977 if(vf->datasource && vf->callbacks.close_func)
978 (vf->callbacks.close_func)(vf->datasource);
979 memset(vf,0,sizeof(*vf));
987 /* inspects the OggVorbis file and finds/documents all the logical
988 bitstreams contained in it. Tries to be tolerant of logical
989 bitstream sections that are truncated/woogie.
995 int ov_open_callbacks(void *f,OggVorbis_File *vf,
996 const char *initial,long ibytes,ov_callbacks callbacks){
997 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
999 return _ov_open2(vf);
1002 int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
1003 ov_callbacks callbacks = {
1004 (size_t (*)(void *, size_t, size_t, void *)) fread,
1005 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
1006 (int (*)(void *)) fclose,
1007 (long (*)(void *)) ftell
1010 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
1013 int ov_fopen(const char *path,OggVorbis_File *vf){
1015 FILE *f = fopen(path,"rb");
1018 ret = ov_open(f,vf,NULL,0);
1024 /* cheap hack for game usage where downsampling is desirable; there's
1025 no need for SRC as we can just do it cheaply in libvorbis. */
1027 int ov_halfrate(OggVorbis_File *vf,int flag){
1029 if(vf->vi==NULL)return OV_EINVAL;
1030 if(vf->ready_state>STREAMSET){
1031 /* clear out stream state; dumping the decode machine is needed to
1032 reinit the MDCT lookups. */
1033 vorbis_dsp_clear(&vf->vd);
1034 vorbis_block_clear(&vf->vb);
1035 vf->ready_state=STREAMSET;
1036 if(vf->pcm_offset>=0){
1037 ogg_int64_t pos=vf->pcm_offset;
1038 vf->pcm_offset=-1; /* make sure the pos is dumped if unseekable */
1039 ov_pcm_seek(vf,pos);
1043 for(i=0;i<vf->links;i++){
1044 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
1045 if(flag) ov_halfrate(vf,0);
1052 int ov_halfrate_p(OggVorbis_File *vf){
1053 if(vf->vi==NULL)return OV_EINVAL;
1054 return vorbis_synthesis_halfrate_p(vf->vi);
1057 /* Only partially open the vorbis file; test for Vorbisness, and load
1058 the headers for the first chain. Do not seek (although test for
1059 seekability). Use ov_test_open to finish opening the file, else
1060 ov_clear to close/free it. Same return codes as open.
1062 Note that vorbisfile does _not_ take ownership of the file if the
1063 call fails; the calling applicaiton is responsible for closing the file
1064 if this call returns an error. */
1066 int ov_test_callbacks(void *f,OggVorbis_File *vf,
1067 const char *initial,long ibytes,ov_callbacks callbacks)
1069 return _ov_open1(f,vf,initial,ibytes,callbacks);
1072 int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
1073 ov_callbacks callbacks = {
1074 (size_t (*)(void *, size_t, size_t, void *)) fread,
1075 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
1076 (int (*)(void *)) fclose,
1077 (long (*)(void *)) ftell
1080 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
1083 int ov_test_open(OggVorbis_File *vf){
1084 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
1085 return _ov_open2(vf);
1088 /* How many logical bitstreams in this physical bitstream? */
1089 long ov_streams(OggVorbis_File *vf){
1093 /* Is the FILE * associated with vf seekable? */
1094 long ov_seekable(OggVorbis_File *vf){
1095 return vf->seekable;
1098 /* returns the bitrate for a given logical bitstream or the entire
1099 physical bitstream. If the file is open for random access, it will
1100 find the *actual* average bitrate. If the file is streaming, it
1101 returns the nominal bitrate (if set) else the average of the
1102 upper/lower bounds (if set) else -1 (unset).
1104 If you want the actual bitrate field settings, get them from the
1105 vorbis_info structs */
1107 long ov_bitrate(OggVorbis_File *vf,int i){
1108 if(vf->ready_state<OPENED)return(OV_EINVAL);
1109 if(i>=vf->links)return(OV_EINVAL);
1110 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
1115 for(i=0;i<vf->links;i++)
1116 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
1117 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
1118 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
1119 * so this is slightly transformed to make it work.
1121 br = bits/ov_time_total(vf,-1);
1125 /* return the actual bitrate */
1126 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
1128 /* return nominal if set */
1129 if(vf->vi[i].bitrate_nominal>0){
1130 return vf->vi[i].bitrate_nominal;
1132 if(vf->vi[i].bitrate_upper>0){
1133 if(vf->vi[i].bitrate_lower>0){
1134 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1136 return vf->vi[i].bitrate_upper;
1145 /* returns the actual bitrate since last call. returns -1 if no
1146 additional data to offer since last call (or at beginning of stream),
1147 EINVAL if stream is only partially open
1149 long ov_bitrate_instant(OggVorbis_File *vf){
1150 int link=(vf->seekable?vf->current_link:0);
1152 if(vf->ready_state<OPENED)return(OV_EINVAL);
1153 if(vf->samptrack==0)return(OV_FALSE);
1154 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1161 long ov_serialnumber(OggVorbis_File *vf,int i){
1162 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1163 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1165 return(vf->current_serialno);
1167 return(vf->serialnos[i]);
1171 /* returns: total raw (compressed) length of content if i==-1
1172 raw (compressed) length of that logical bitstream for i==0 to n
1173 OV_EINVAL if the stream is not seekable (we can't know the length)
1174 or if stream is only partially open
1176 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1177 if(vf->ready_state<OPENED)return(OV_EINVAL);
1178 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1182 for(i=0;i<vf->links;i++)
1183 acc+=ov_raw_total(vf,i);
1186 return(vf->offsets[i+1]-vf->offsets[i]);
1190 /* returns: total PCM length (samples) of content if i==-1 PCM length
1191 (samples) of that logical bitstream for i==0 to n
1192 OV_EINVAL if the stream is not seekable (we can't know the
1193 length) or only partially open
1195 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1196 if(vf->ready_state<OPENED)return(OV_EINVAL);
1197 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1201 for(i=0;i<vf->links;i++)
1202 acc+=ov_pcm_total(vf,i);
1205 return(vf->pcmlengths[i*2+1]);
1209 /* returns: total seconds of content if i==-1
1210 seconds in that logical bitstream for i==0 to n
1211 OV_EINVAL if the stream is not seekable (we can't know the
1212 length) or only partially open
1214 double ov_time_total(OggVorbis_File *vf,int i){
1215 if(vf->ready_state<OPENED)return(OV_EINVAL);
1216 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1220 for(i=0;i<vf->links;i++)
1221 acc+=ov_time_total(vf,i);
1224 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1228 /* seek to an offset relative to the *compressed* data. This also
1229 scans packets to update the PCM cursor. It will cross a logical
1230 bitstream boundary, but only if it can't get any packets out of the
1231 tail of the bitstream we seek to (so no surprises).
1233 returns zero on success, nonzero on failure */
1235 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1236 ogg_stream_state work_os;
1238 if(vf->ready_state<OPENED)return(OV_EINVAL);
1240 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1242 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1244 /* is the seek position outside our current link [if any]? */
1245 if(vf->ready_state>=STREAMSET){
1246 if(pos<vf->offsets[vf->current_link] || pos>=vf->offsets[vf->current_link+1])
1247 _decode_clear(vf); /* clear out stream state */
1250 /* don't yet clear out decoding machine (if it's initialized), in
1251 the case we're in the same link. Restart the decode lapping, and
1252 let _fetch_and_process_packet deal with a potential bitstream
1255 ogg_stream_reset_serialno(&vf->os,
1256 vf->current_serialno); /* must set serialno */
1257 vorbis_synthesis_restart(&vf->vd);
1259 if(_seek_helper(vf,pos)) {
1260 /* dump the machine so we're in a known state */
1266 /* we need to make sure the pcm_offset is set, but we don't want to
1267 advance the raw cursor past good packets just to get to the first
1268 with a granulepos. That's not equivalent behavior to beginning
1269 decoding as immediately after the seek position as possible.
1271 So, a hack. We use two stream states; a local scratch state and
1272 the shared vf->os stream state. We use the local state to
1273 scan, and the shared state as a buffer for later decode.
1275 Unfortuantely, on the last page we still advance to last packet
1276 because the granulepos on the last page is not necessarily on a
1277 packet boundary, and we need to make sure the granpos is
1289 ogg_int64_t pagepos=-1;
1291 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1292 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1293 return from not necessarily
1294 starting from the beginning */
1297 if(vf->ready_state>=STREAMSET){
1298 /* snarf/scan a packet if we can */
1299 int result=ogg_stream_packetout(&work_os,&op);
1303 if(vf->vi[vf->current_link].codec_setup){
1304 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1306 ogg_stream_packetout(&vf->os,NULL);
1310 /* We can't get a guaranteed correct pcm position out of the
1311 last page in a stream because it might have a 'short'
1312 granpos, which can only be detected in the presence of a
1313 preceding page. However, if the last page is also the first
1314 page, the granpos rules of a first page take precedence. Not
1315 only that, but for first==last, the EOS page must be treated
1316 as if its a normal first page for the stream to open/play. */
1317 if(lastflag && !firstflag)
1318 ogg_stream_packetout(&vf->os,NULL);
1320 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1323 if(op.granulepos!=-1){
1324 int i,link=vf->current_link;
1325 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1326 if(granulepos<0)granulepos=0;
1329 granulepos+=vf->pcmlengths[i*2+1];
1330 vf->pcm_offset=granulepos-accblock;
1331 if(vf->pcm_offset<0)vf->pcm_offset=0;
1334 lastblock=thisblock;
1337 ogg_stream_packetout(&vf->os,NULL);
1342 pagepos=_get_next_page(vf,&og,-1);
1344 vf->pcm_offset=ov_pcm_total(vf,-1);
1348 /* huh? Bogus stream with packets but no granulepos */
1353 /* has our decoding just traversed a bitstream boundary? */
1354 if(vf->ready_state>=STREAMSET){
1355 if(vf->current_serialno!=ogg_page_serialno(&og)){
1357 /* two possibilities:
1358 1) our decoding just traversed a bitstream boundary
1359 2) another stream is multiplexed into this logical section? */
1361 if(ogg_page_bos(&og)){
1363 _decode_clear(vf); /* clear out stream state */
1364 ogg_stream_clear(&work_os);
1365 } /* else, do nothing; next loop will scoop another page */
1369 if(vf->ready_state<STREAMSET){
1371 long serialno = ogg_page_serialno(&og);
1373 for(link=0;link<vf->links;link++)
1374 if(vf->serialnos[link]==serialno)break;
1376 if(link==vf->links) continue; /* not the desired Vorbis
1377 bitstream section; keep
1379 vf->current_link=link;
1380 vf->current_serialno=serialno;
1381 ogg_stream_reset_serialno(&vf->os,serialno);
1382 ogg_stream_reset_serialno(&work_os,serialno);
1383 vf->ready_state=STREAMSET;
1384 firstflag=(pagepos<=vf->dataoffsets[link]);
1387 ogg_stream_pagein(&vf->os,&og);
1388 ogg_stream_pagein(&work_os,&og);
1389 lastflag=ogg_page_eos(&og);
1394 ogg_stream_clear(&work_os);
1400 /* Page granularity seek (faster than sample granularity because we
1401 don't do the last bit of decode to find a specific sample).
1403 Seek to the last [granule marked] page preceding the specified pos
1404 location, such that decoding past the returned point will quickly
1405 arrive at the requested position. */
1406 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1408 ogg_int64_t result=0;
1409 ogg_int64_t total=ov_pcm_total(vf,-1);
1411 if(vf->ready_state<OPENED)return(OV_EINVAL);
1412 if(!vf->seekable)return(OV_ENOSEEK);
1414 if(pos<0 || pos>total)return(OV_EINVAL);
1416 /* which bitstream section does this pcm offset occur in? */
1417 for(link=vf->links-1;link>=0;link--){
1418 total-=vf->pcmlengths[link*2+1];
1419 if(pos>=total)break;
1422 /* Search within the logical bitstream for the page with the highest
1423 pcm_pos preceding pos. If we're looking for a position on the
1424 first page, bisection will halt without finding our position as
1425 it's before the first explicit granulepos fencepost. That case is
1426 handled separately below.
1428 There is a danger here; missing pages or incorrect frame number
1429 information in the bitstream could make our task impossible.
1430 Account for that (it would be an error condition) */
1432 /* new search algorithm originally by HB (Nicholas Vinen) */
1435 ogg_int64_t end=vf->offsets[link+1];
1436 ogg_int64_t begin=vf->dataoffsets[link];
1437 ogg_int64_t begintime = vf->pcmlengths[link*2];
1438 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1439 ogg_int64_t target=pos-total+begintime;
1440 ogg_int64_t best=-1;
1445 /* if we have only one page, there will be no bisection. Grab the page here */
1447 result=_seek_helper(vf,begin);
1448 if(result) goto seek_error;
1450 result=_get_next_page(vf,&og,1);
1451 if(result<0) goto seek_error;
1456 /* bisection loop */
1460 if(end-begin<CHUNKSIZE){
1463 /* take a (pretty decent) guess. */
1465 (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime))
1467 if(bisect<begin+CHUNKSIZE)
1471 result=_seek_helper(vf,bisect);
1472 if(result) goto seek_error;
1474 /* read loop within the bisection loop */
1476 result=_get_next_page(vf,&og,end-vf->offset);
1477 if(result==OV_EREAD) goto seek_error;
1479 /* there is no next page! */
1481 /* No bisection left to perform. We've either found the
1482 best candidate already or failed. Exit loop. */
1485 /* We tried to load a fraction of the last page; back up a
1486 bit and try to get the whole last page */
1487 if(bisect==0) goto seek_error;
1490 /* don't repeat/loop on a read we've already performed */
1491 if(bisect<=begin)bisect=begin+1;
1493 /* seek and cntinue bisection */
1494 result=_seek_helper(vf,bisect);
1495 if(result) goto seek_error;
1498 ogg_int64_t granulepos;
1501 /* got a page. analyze it */
1502 /* only consider pages from primary vorbis stream */
1503 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1506 /* only consider pages with the granulepos set */
1507 granulepos=ogg_page_granulepos(&og);
1508 if(granulepos==-1)continue;
1510 if(granulepos<target){
1511 /* this page is a successful candidate! Set state */
1513 best=result; /* raw offset of packet with granulepos */
1514 begin=vf->offset; /* raw offset of next page */
1515 begintime=granulepos;
1517 /* if we're before our target but within a short distance,
1518 don't bisect; read forward */
1519 if(target-begintime>44100)break;
1521 bisect=begin; /* *not* begin + 1 as above */
1524 /* This is one of our pages, but the granpos is
1525 post-target; it is not a bisection return
1526 candidate. (The only way we'd use it is if it's the
1527 first page in the stream; we handle that case later
1528 outside the bisection) */
1529 if(bisect<=begin+1){
1530 /* No bisection left to perform. We've either found the
1531 best candidate already or failed. Exit loop. */
1534 if(end==vf->offset){
1535 /* bisection read to the end; use the known page
1536 boundary (result) to update bisection, back up a
1537 little bit, and try again */
1540 if(bisect<=begin)bisect=begin+1;
1541 result=_seek_helper(vf,bisect);
1542 if(result) goto seek_error;
1544 /* Normal bisection */
1555 /* Out of bisection: did it 'fail?' */
1558 /* Check the 'looking for data in first page' special case;
1559 bisection would 'fail' because our search target was before the
1560 first PCM granule position fencepost. */
1563 begin == vf->dataoffsets[link] &&
1564 ogg_page_serialno(&og)==vf->serialnos[link]){
1566 /* Yes, this is the beginning-of-stream case. We already have
1567 our page, right at the beginning of PCM data. Set state
1570 vf->pcm_offset=total;
1572 if(link!=vf->current_link){
1573 /* Different link; dump entire decode machine */
1576 vf->current_link=link;
1577 vf->current_serialno=vf->serialnos[link];
1578 vf->ready_state=STREAMSET;
1581 vorbis_synthesis_restart(&vf->vd);
1584 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1585 ogg_stream_pagein(&vf->os,&og);
1592 /* Bisection found our page. seek to it, update pcm offset. Easier case than
1593 raw_seek, don't keep packets preceding granulepos. */
1599 result=_seek_helper(vf,best);
1601 if(result) goto seek_error;
1602 result=_get_next_page(vf,&og,-1);
1603 if(result<0) goto seek_error;
1605 if(link!=vf->current_link){
1606 /* Different link; dump entire decode machine */
1609 vf->current_link=link;
1610 vf->current_serialno=vf->serialnos[link];
1611 vf->ready_state=STREAMSET;
1614 vorbis_synthesis_restart(&vf->vd);
1617 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1618 ogg_stream_pagein(&vf->os,&og);
1620 /* pull out all but last packet; the one with granulepos */
1622 result=ogg_stream_packetpeek(&vf->os,&op);
1624 /* No packet returned; we exited the bisection with 'best'
1625 pointing to a page with a granule position, so the packet
1626 finishing this page ('best') originated on a preceding
1627 page. Keep fetching previous pages until we get one with
1628 a granulepos or without the 'continued' flag set. Then
1629 just use raw_seek for simplicity. */
1630 /* Do not rewind past the beginning of link data; if we do,
1631 it's either a bug or a broken stream */
1633 while(result>vf->dataoffsets[link]){
1634 result=_get_prev_page(vf,result,&og);
1635 if(result<0) goto seek_error;
1636 if(ogg_page_serialno(&og)==vf->current_serialno &&
1637 (ogg_page_granulepos(&og)>-1 ||
1638 !ogg_page_continued(&og))){
1639 return ov_raw_seek(vf,result);
1644 result = OV_EBADPACKET;
1647 if(op.granulepos!=-1){
1648 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1649 if(vf->pcm_offset<0)vf->pcm_offset=0;
1650 vf->pcm_offset+=total;
1653 result=ogg_stream_packetout(&vf->os,NULL);
1659 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1668 /* dump machine so we're in a known state */
1674 /* seek to a sample offset relative to the decompressed pcm stream
1675 returns zero on success, nonzero on failure */
1677 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1678 int thisblock,lastblock=0;
1679 int ret=ov_pcm_seek_page(vf,pos);
1680 if(ret<0)return(ret);
1681 if((ret=_make_decode_ready(vf)))return ret;
1683 /* discard leading packets we don't need for the lapping of the
1684 position we want; don't decode them */
1690 int ret=ogg_stream_packetpeek(&vf->os,&op);
1692 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1694 ogg_stream_packetout(&vf->os,NULL);
1695 continue; /* non audio packet */
1697 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1699 if(vf->pcm_offset+((thisblock+
1700 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1702 /* remove the packet from packet queue and track its granulepos */
1703 ogg_stream_packetout(&vf->os,NULL);
1704 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1707 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1709 /* end of logical stream case is hard, especially with exact
1710 length positioning. */
1712 if(op.granulepos>-1){
1714 /* always believe the stream markers */
1715 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1716 if(vf->pcm_offset<0)vf->pcm_offset=0;
1717 for(i=0;i<vf->current_link;i++)
1718 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1721 lastblock=thisblock;
1724 if(ret<0 && ret!=OV_HOLE)break;
1726 /* suck in a new page */
1727 if(_get_next_page(vf,&og,-1)<0)break;
1728 if(ogg_page_bos(&og))_decode_clear(vf);
1730 if(vf->ready_state<STREAMSET){
1731 long serialno=ogg_page_serialno(&og);
1734 for(link=0;link<vf->links;link++)
1735 if(vf->serialnos[link]==serialno)break;
1736 if(link==vf->links) continue;
1737 vf->current_link=link;
1739 vf->ready_state=STREAMSET;
1740 vf->current_serialno=ogg_page_serialno(&og);
1741 ogg_stream_reset_serialno(&vf->os,serialno);
1742 ret=_make_decode_ready(vf);
1747 ogg_stream_pagein(&vf->os,&og);
1753 /* discard samples until we reach the desired position. Crossing a
1754 logical bitstream boundary with abandon is OK. */
1756 /* note that halfrate could be set differently in each link, but
1757 vorbisfile encoforces all links are set or unset */
1758 int hs=vorbis_synthesis_halfrate_p(vf->vi);
1759 while(vf->pcm_offset<((pos>>hs)<<hs)){
1760 ogg_int64_t target=(pos-vf->pcm_offset)>>hs;
1761 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1763 if(samples>target)samples=target;
1764 vorbis_synthesis_read(&vf->vd,samples);
1765 vf->pcm_offset+=samples<<hs;
1768 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1769 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1775 /* seek to a playback time relative to the decompressed pcm stream
1776 returns zero on success, nonzero on failure */
1777 int ov_time_seek(OggVorbis_File *vf,double seconds){
1778 /* translate time to PCM position and call ov_pcm_seek */
1781 ogg_int64_t pcm_total=0;
1782 double time_total=0.;
1784 if(vf->ready_state<OPENED)return(OV_EINVAL);
1785 if(!vf->seekable)return(OV_ENOSEEK);
1786 if(seconds<0)return(OV_EINVAL);
1788 /* which bitstream section does this time offset occur in? */
1789 for(link=0;link<vf->links;link++){
1790 double addsec = ov_time_total(vf,link);
1791 if(seconds<time_total+addsec)break;
1793 pcm_total+=vf->pcmlengths[link*2+1];
1796 if(link==vf->links)return(OV_EINVAL);
1798 /* enough information to convert time offset to pcm offset */
1800 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1801 return(ov_pcm_seek(vf,target));
1805 /* page-granularity version of ov_time_seek
1806 returns zero on success, nonzero on failure */
1807 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1808 /* translate time to PCM position and call ov_pcm_seek */
1811 ogg_int64_t pcm_total=0;
1812 double time_total=0.;
1814 if(vf->ready_state<OPENED)return(OV_EINVAL);
1815 if(!vf->seekable)return(OV_ENOSEEK);
1816 if(seconds<0)return(OV_EINVAL);
1818 /* which bitstream section does this time offset occur in? */
1819 for(link=0;link<vf->links;link++){
1820 double addsec = ov_time_total(vf,link);
1821 if(seconds<time_total+addsec)break;
1823 pcm_total+=vf->pcmlengths[link*2+1];
1826 if(link==vf->links)return(OV_EINVAL);
1828 /* enough information to convert time offset to pcm offset */
1830 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1831 return(ov_pcm_seek_page(vf,target));
1835 /* tell the current stream offset cursor. Note that seek followed by
1836 tell will likely not give the set offset due to caching */
1837 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1838 if(vf->ready_state<OPENED)return(OV_EINVAL);
1842 /* return PCM offset (sample) of next PCM sample to be read */
1843 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1844 if(vf->ready_state<OPENED)return(OV_EINVAL);
1845 return(vf->pcm_offset);
1848 /* return time offset (seconds) of next PCM sample to be read */
1849 double ov_time_tell(OggVorbis_File *vf){
1851 ogg_int64_t pcm_total=0;
1852 double time_total=0.f;
1854 if(vf->ready_state<OPENED)return(OV_EINVAL);
1856 pcm_total=ov_pcm_total(vf,-1);
1857 time_total=ov_time_total(vf,-1);
1859 /* which bitstream section does this time offset occur in? */
1860 for(link=vf->links-1;link>=0;link--){
1861 pcm_total-=vf->pcmlengths[link*2+1];
1862 time_total-=ov_time_total(vf,link);
1863 if(vf->pcm_offset>=pcm_total)break;
1867 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1870 /* link: -1) return the vorbis_info struct for the bitstream section
1871 currently being decoded
1872 0-n) to request information for a specific bitstream section
1874 In the case of a non-seekable bitstream, any call returns the
1875 current bitstream. NULL in the case that the machine is not
1878 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1881 if(vf->ready_state>=STREAMSET)
1882 return vf->vi+vf->current_link;
1895 /* grr, strong typing, grr, no templates/inheritence, grr */
1896 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1899 if(vf->ready_state>=STREAMSET)
1900 return vf->vc+vf->current_link;
1913 static int host_is_big_endian() {
1914 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1915 unsigned char *bytewise = (unsigned char *)&pattern;
1916 if (bytewise[0] == 0xfe) return 1;
1920 /* up to this point, everything could more or less hide the multiple
1921 logical bitstream nature of chaining from the toplevel application
1922 if the toplevel application didn't particularly care. However, at
1923 the point that we actually read audio back, the multiple-section
1924 nature must surface: Multiple bitstream sections do not necessarily
1925 have to have the same number of channels or sampling rate.
1927 ov_read returns the sequential logical bitstream number currently
1928 being decoded along with the PCM data in order that the toplevel
1929 application can take action on channel/sample rate changes. This
1930 number will be incremented even for streamed (non-seekable) streams
1931 (for seekable streams, it represents the actual logical bitstream
1932 index within the physical bitstream. Note that the accessor
1933 functions above are aware of this dichotomy).
1935 ov_read_filter is exactly the same as ov_read except that it processes
1936 the decoded audio data through a filter before packing it into the
1937 requested format. This gives greater accuracy than applying a filter
1938 after the audio has been converted into integral PCM.
1940 input values: buffer) a buffer to hold packed PCM data for return
1941 length) the byte length requested to be placed into buffer
1942 bigendianp) should the data be packed LSB first (0) or
1944 word) word size for output. currently 1 (byte) or
1947 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1949 n) number of bytes of PCM actually returned. The
1950 below works on a packet-by-packet basis, so the
1951 return length is not related to the 'length' passed
1952 in, just guaranteed to fit.
1954 *section) set to the logical bitstream number */
1956 long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
1957 int bigendianp,int word,int sgned,int *bitstream,
1958 void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
1960 int host_endian = host_is_big_endian();
1966 if(vf->ready_state<OPENED)return(OV_EINVAL);
1967 if(word<=0)return(OV_EINVAL);
1970 if(vf->ready_state==INITSET){
1971 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1975 /* suck in another packet */
1977 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1988 /* yay! proceed to pack data into the byte buffer */
1990 long channels=ov_info(vf,-1)->channels;
1991 long bytespersample=word * channels;
1992 vorbis_fpu_control fpu;
1994 if(channels<1||channels>255)return(OV_EINVAL);
1995 if(samples>length/bytespersample)samples=length/bytespersample;
2002 filter(pcm,channels,samples,filter_param);
2004 /* a tight loop to pack each size */
2008 int off=(sgned?0:128);
2009 vorbis_fpu_setround(&fpu);
2010 for(j=0;j<samples;j++)
2011 for(i=0;i<channels;i++){
2012 val=vorbis_ftoi(pcm[i][j]*128.f);
2014 else if(val<-128)val=-128;
2017 vorbis_fpu_restore(fpu);
2019 int off=(sgned?0:32768);
2021 if(host_endian==bigendianp){
2024 vorbis_fpu_setround(&fpu);
2025 for(i=0;i<channels;i++) { /* It's faster in this order */
2027 short *dest=((short *)buffer)+i;
2028 for(j=0;j<samples;j++) {
2029 val=vorbis_ftoi(src[j]*32768.f);
2030 if(val>32767)val=32767;
2031 else if(val<-32768)val=-32768;
2036 vorbis_fpu_restore(fpu);
2040 vorbis_fpu_setround(&fpu);
2041 for(i=0;i<channels;i++) {
2043 short *dest=((short *)buffer)+i;
2044 for(j=0;j<samples;j++) {
2045 val=vorbis_ftoi(src[j]*32768.f);
2046 if(val>32767)val=32767;
2047 else if(val<-32768)val=-32768;
2052 vorbis_fpu_restore(fpu);
2055 }else if(bigendianp){
2057 vorbis_fpu_setround(&fpu);
2058 for(j=0;j<samples;j++)
2059 for(i=0;i<channels;i++){
2060 val=vorbis_ftoi(pcm[i][j]*32768.f);
2061 if(val>32767)val=32767;
2062 else if(val<-32768)val=-32768;
2065 *buffer++=(val&0xff);
2067 vorbis_fpu_restore(fpu);
2071 vorbis_fpu_setround(&fpu);
2072 for(j=0;j<samples;j++)
2073 for(i=0;i<channels;i++){
2074 val=vorbis_ftoi(pcm[i][j]*32768.f);
2075 if(val>32767)val=32767;
2076 else if(val<-32768)val=-32768;
2078 *buffer++=(val&0xff);
2081 vorbis_fpu_restore(fpu);
2087 vorbis_synthesis_read(&vf->vd,samples);
2088 hs=vorbis_synthesis_halfrate_p(vf->vi);
2089 vf->pcm_offset+=(samples<<hs);
2090 if(bitstream)*bitstream=vf->current_link;
2091 return(samples*bytespersample);
2097 long ov_read(OggVorbis_File *vf,char *buffer,int length,
2098 int bigendianp,int word,int sgned,int *bitstream){
2099 return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
2102 /* input values: pcm_channels) a float vector per channel of output
2103 length) the sample length being read by the app
2105 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
2107 n) number of samples of PCM actually returned. The
2108 below works on a packet-by-packet basis, so the
2109 return length is not related to the 'length' passed
2110 in, just guaranteed to fit.
2112 *section) set to the logical bitstream number */
2116 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
2119 if(vf->ready_state<OPENED)return(OV_EINVAL);
2122 if(vf->ready_state==INITSET){
2124 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
2126 int hs=vorbis_synthesis_halfrate_p(vf->vi);
2127 if(pcm_channels)*pcm_channels=pcm;
2128 if(samples>length)samples=length;
2129 vorbis_synthesis_read(&vf->vd,samples);
2130 vf->pcm_offset+=samples<<hs;
2131 if(bitstream)*bitstream=vf->current_link;
2137 /* suck in another packet */
2139 int ret=_fetch_and_process_packet(vf,NULL,1,1);
2140 if(ret==OV_EOF)return(0);
2141 if(ret<=0)return(ret);
2147 extern const float *vorbis_window(vorbis_dsp_state *v,int W);
2149 static void _ov_splice(float **pcm,float **lappcm,
2152 const float *w1, const float *w2){
2163 for(j=0;j<ch1 && j<ch2;j++){
2170 d[i]=d[i]*wd + s[i]*ws;
2173 /* window from zero */
2184 /* make sure vf is INITSET */
2185 static int _ov_initset(OggVorbis_File *vf){
2187 if(vf->ready_state==INITSET)break;
2188 /* suck in another packet */
2190 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2191 if(ret<0 && ret!=OV_HOLE)return(ret);
2197 /* make sure vf is INITSET and that we have a primed buffer; if
2198 we're crosslapping at a stream section boundary, this also makes
2199 sure we're sanity checking against the right stream information */
2200 static int _ov_initprime(OggVorbis_File *vf){
2201 vorbis_dsp_state *vd=&vf->vd;
2203 if(vf->ready_state==INITSET)
2204 if(vorbis_synthesis_pcmout(vd,NULL))break;
2206 /* suck in another packet */
2208 int ret=_fetch_and_process_packet(vf,NULL,1,0);
2209 if(ret<0 && ret!=OV_HOLE)return(ret);
2215 /* grab enough data for lapping from vf; this may be in the form of
2216 unreturned, already-decoded pcm, remaining PCM we will need to
2217 decode, or synthetic postextrapolation from last packets. */
2218 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
2219 float **lappcm,int lapsize){
2223 /* try first to decode the lapping data */
2224 while(lapcount<lapsize){
2225 int samples=vorbis_synthesis_pcmout(vd,&pcm);
2227 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2228 for(i=0;i<vi->channels;i++)
2229 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2231 vorbis_synthesis_read(vd,samples);
2233 /* suck in another packet */
2234 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
2235 if(ret==OV_EOF)break;
2238 if(lapcount<lapsize){
2239 /* failed to get lapping data from normal decode; pry it from the
2240 postextrapolation buffering, or the second half of the MDCT
2241 from the last packet */
2242 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
2244 for(i=0;i<vi->channels;i++)
2245 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2248 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2249 for(i=0;i<vi->channels;i++)
2250 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2256 /* this sets up crosslapping of a sample by using trailing data from
2257 sample 1 and lapping it into the windowing buffer of sample 2 */
2258 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2259 vorbis_info *vi1,*vi2;
2262 const float *w1,*w2;
2263 int n1,n2,i,ret,hs1,hs2;
2265 if(vf1==vf2)return(0); /* degenerate case */
2266 if(vf1->ready_state<OPENED)return(OV_EINVAL);
2267 if(vf2->ready_state<OPENED)return(OV_EINVAL);
2269 /* the relevant overlap buffers must be pre-checked and pre-primed
2270 before looking at settings in the event that priming would cross
2271 a bitstream boundary. So, do it now */
2273 ret=_ov_initset(vf1);
2275 ret=_ov_initprime(vf2);
2278 vi1=ov_info(vf1,-1);
2279 vi2=ov_info(vf2,-1);
2280 hs1=ov_halfrate_p(vf1);
2281 hs2=ov_halfrate_p(vf2);
2283 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2284 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2285 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2286 w1=vorbis_window(&vf1->vd,0);
2287 w2=vorbis_window(&vf2->vd,0);
2289 for(i=0;i<vi1->channels;i++)
2290 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2292 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2294 /* have a lapping buffer from vf1; now to splice it into the lapping
2296 /* consolidate and expose the buffer. */
2297 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2300 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2301 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2305 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2311 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2312 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2316 const float *w1,*w2;
2317 int n1,n2,ch1,ch2,hs;
2320 if(vf->ready_state<OPENED)return(OV_EINVAL);
2321 ret=_ov_initset(vf);
2324 hs=ov_halfrate_p(vf);
2327 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2328 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2329 persistent; even if the decode state
2330 from this link gets dumped, this
2331 window array continues to exist */
2333 lappcm=alloca(sizeof(*lappcm)*ch1);
2335 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2336 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2338 /* have lapping data; seek and prime the buffer */
2339 ret=localseek(vf,pos);
2341 ret=_ov_initprime(vf);
2344 /* Guard against cross-link changes; they're perfectly legal */
2347 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2348 w2=vorbis_window(&vf->vd,0);
2350 /* consolidate and expose the buffer. */
2351 vorbis_synthesis_lapout(&vf->vd,&pcm);
2354 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2360 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2361 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2364 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2365 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2368 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2369 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2372 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2373 int (*localseek)(OggVorbis_File *,double)){
2377 const float *w1,*w2;
2378 int n1,n2,ch1,ch2,hs;
2381 if(vf->ready_state<OPENED)return(OV_EINVAL);
2382 ret=_ov_initset(vf);
2385 hs=ov_halfrate_p(vf);
2388 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2389 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2390 persistent; even if the decode state
2391 from this link gets dumped, this
2392 window array continues to exist */
2394 lappcm=alloca(sizeof(*lappcm)*ch1);
2396 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2397 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2399 /* have lapping data; seek and prime the buffer */
2400 ret=localseek(vf,pos);
2402 ret=_ov_initprime(vf);
2405 /* Guard against cross-link changes; they're perfectly legal */
2408 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2409 w2=vorbis_window(&vf->vd,0);
2411 /* consolidate and expose the buffer. */
2412 vorbis_synthesis_lapout(&vf->vd,&pcm);
2415 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2421 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2422 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2425 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2426 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);