1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: stdio-based convenience library for opening/seeking/decoding
16 ********************************************************************/
24 #include "vorbis/codec.h"
25 #include "vorbis/vorbisfile.h"
30 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
31 one logical bitstream arranged end to end (the only form of Ogg
32 multiplexing allowed in a Vorbis bitstream; grouping [parallel
33 multiplexing] is not allowed in Vorbis) */
35 /* A Vorbis file can be played beginning to end (streamed) without
36 worrying ahead of time about chaining (see decoder_example.c). If
37 we have the whole file, however, and want random access
38 (seeking/scrubbing) or desire to know the total length/time of a
39 file, we need to account for the possibility of chaining. */
41 /* We can handle things a number of ways; we can determine the entire
42 bitstream structure right off the bat, or find pieces on demand.
43 This example determines and caches structure for the entire
44 bitstream, but builds a virtual decoder on the fly when moving
45 between links in the chain. */
47 /* There are also different ways to implement seeking. Enough
48 information exists in an Ogg bitstream to seek to
49 sample-granularity positions in the output. Or, one can seek by
50 picking some portion of the stream roughly in the desired area if
51 we only want coarse navigation through the stream. */
53 /*************************************************************************
54 * Many, many internal helpers. The intention is not to be confusing;
55 * rampant duplication and monolithic function implementation would be
56 * harder to understand anyway. The high level functions are last. Begin
57 * grokking near the end of the file */
59 /* read a little more data from the file/pipe into the ogg_sync framer
61 #define CHUNKSIZE 65536
63 static long _get_data(OggVorbis_File *vf){
65 if(!(vf->callbacks.read_func))return(-1);
67 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
68 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
69 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
70 if(bytes==0 && errno)return(-1);
76 /* save a tiny smidge of verbosity to make the code more readable */
77 static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
79 if(!(vf->callbacks.seek_func)||
80 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
83 ogg_sync_reset(&vf->oy);
85 /* shouldn't happen unless someone writes a broken callback */
91 /* The read/seek functions track absolute position within the stream */
93 /* from the head of the stream, get the next page. boundary specifies
94 if the function is allowed to fetch more data from the stream (and
95 how much) or only use internally buffered data.
97 boundary: -1) unbounded search
98 0) read no additional data; use cached only
99 n) search for a new page beginning for n bytes
101 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
102 n) found a page at absolute offset n */
104 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
105 ogg_int64_t boundary){
106 if(boundary>0)boundary+=vf->offset;
110 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
111 more=ogg_sync_pageseek(&vf->oy,og);
114 /* skipped n bytes */
118 /* send more paramedics */
119 if(!boundary)return(OV_FALSE);
121 long ret=_get_data(vf);
122 if(ret==0)return(OV_EOF);
123 if(ret<0)return(OV_EREAD);
126 /* got a page. Return the offset at the page beginning,
127 advance the internal offset past the page end */
128 ogg_int64_t ret=vf->offset;
137 /* find the latest page beginning before the current stream cursor
138 position. Much dirtier than the above as Ogg doesn't have any
139 backward search linkage. no 'readp' as it will certainly have to
141 /* returns offset or OV_EREAD, OV_FAULT */
142 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
143 ogg_int64_t begin=vf->offset;
144 ogg_int64_t end=begin;
146 ogg_int64_t offset=-1;
153 ret=_seek_helper(vf,begin);
156 while(vf->offset<end){
157 ret=_get_next_page(vf,og,end-vf->offset);
158 if(ret==OV_EREAD)return(OV_EREAD);
167 /* we have the offset. Actually snork and hold the page now */
168 ret=_seek_helper(vf,offset);
171 ret=_get_next_page(vf,og,CHUNKSIZE);
173 /* this shouldn't be possible */
179 static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
180 long s = ogg_page_serialno(og);
184 *serialno_list = _ogg_realloc(*serialno_list, sizeof(*serialno_list)*(*n));
186 *serialno_list = _ogg_malloc(sizeof(**serialno_list));
189 (*serialno_list)[(*n)-1] = s;
192 /* returns nonzero if found */
193 static int _lookup_serialno(ogg_page *og, long *serialno_list, int n){
194 long s = ogg_page_serialno(og);
198 if(*serialno_list == s) return 1;
205 /* start parsing pages at current offset, remembering all serial
206 numbers. Stop logging at first non-bos page */
207 static int _get_serialnos(OggVorbis_File *vf, long **s, int *n){
214 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
215 if(llret==OV_EOF)return(0);
216 if(llret<0)return(llret);
217 if(!ogg_page_bos(&og)) return 0;
219 /* look for duplicate serialnos; add this one if unique */
220 if(_lookup_serialno(&og,*s,*n)){
224 return(OV_EBADHEADER);
227 _add_serialno(&og,s,n);
231 /* finds each bitstream link one at a time using a bisection search
232 (has to begin by knowing the offset of the lb's initial page).
233 Recurses for each link so it can alloc the link storage after
234 finding them all, then unroll and fill the cache at the same time */
235 static int _bisect_forward_serialno(OggVorbis_File *vf,
237 ogg_int64_t searched,
239 long *currentno_list,
242 ogg_int64_t endsearched=end;
243 ogg_int64_t next=end;
247 /* the below guards against garbage seperating the last and
248 first pages of two links. */
249 while(searched<endsearched){
252 if(endsearched-searched<CHUNKSIZE){
255 bisect=(searched+endsearched)/2;
258 ret=_seek_helper(vf,bisect);
261 ret=_get_next_page(vf,&og,-1);
262 if(ret==OV_EREAD)return(OV_EREAD);
263 if(ret<0 || !_lookup_serialno(&og,currentno_list,currentnos)){
267 searched=ret+og.header_len+og.body_len;
272 long *next_serialno_list=NULL;
273 int next_serialnos=0;
275 ret=_seek_helper(vf,next);
277 ret=_get_serialnos(vf,&next_serialno_list,&next_serialnos);
280 if(searched>=end || next_serialnos==0){
282 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
283 vf->offsets[m+1]=searched;
285 ret=_bisect_forward_serialno(vf,next,vf->offset,
286 end,next_serialno_list,next_serialnos,m+1);
290 if(next_serialno_list)_ogg_free(next_serialno_list);
292 vf->offsets[m]=begin;
296 /* uses the local ogg_stream storage in vf; this is important for
297 non-streaming input sources */
298 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
299 long *serialno,ogg_page *og_ptr){
306 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
307 if(llret==OV_EREAD)return(OV_EREAD);
308 if(llret<0)return(OV_ENOTVORBIS);
312 vorbis_info_init(vi);
313 vorbis_comment_init(vc);
315 /* extract the first set of vorbis headers we see in the headerset */
319 /* if we're past the ID headers, we won't be finding a Vorbis
320 stream in this link */
321 if(!ogg_page_bos(og_ptr)){
326 /* prospective stream setup; we need a stream to get packets */
327 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
328 ogg_stream_pagein(&vf->os,og_ptr);
330 if(ogg_stream_packetout(&vf->os,&op) > 0 &&
331 vorbis_synthesis_idheader(&op)){
333 /* continue Vorbis header load; past this point, any error will
334 render this link useless (we won't continue looking for more
336 if(serialno)*serialno=vf->os.serialno;
337 vf->ready_state=STREAMSET;
338 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
342 while(i<2){ /* get a page loop */
344 while(i<2){ /* get a packet loop */
346 int result=ogg_stream_packetout(&vf->os,&op);
353 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
360 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
365 /* if this page belongs to the correct stream, go parse it */
366 if(vf->os.serialno == ogg_page_serialno(og_ptr)){
367 ogg_stream_pagein(&vf->os,og_ptr);
371 /* if we never see the final vorbis headers before the link
373 if(ogg_page_bos(og_ptr)){
381 /* otherwise, keep looking */
388 /* this wasn't vorbis, get next page, try again */
390 ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
391 if(llret==OV_EREAD)return(OV_EREAD);
392 if(llret<0)return(OV_ENOTVORBIS);
397 vorbis_info_clear(vi);
398 vorbis_comment_clear(vc);
399 vf->ready_state=OPENED;
404 /* last step of the OggVorbis_File initialization; get all the
405 vorbis_info structs and PCM positions. Only called by the seekable
406 initialization (local stream storage is hacked slightly; pay
407 attention to how that's done) */
409 /* this is void and does not propogate errors up because we want to be
410 able to open and use damaged bitstreams as well as we can. Just
411 watch out for missing information for links in the OggVorbis_File
413 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
418 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
419 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
420 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
421 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
422 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
424 for(i=0;i<vf->links;i++){
426 /* we already grabbed the initial header earlier. Just set the offset */
427 vf->serialnos[i]=vf->current_serialno;
428 vf->dataoffsets[i]=dataoffset;
429 ret=_seek_helper(vf,dataoffset);
431 vf->dataoffsets[i]=-1;
435 /* seek to the location of the initial header */
437 ret=_seek_helper(vf,vf->offsets[i]);
439 vf->dataoffsets[i]=-1;
441 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,vf->serialnos+i,NULL)<0){
442 vf->dataoffsets[i]=-1;
444 vf->dataoffsets[i]=vf->offset;
449 /* fetch beginning PCM offset */
451 if(vf->dataoffsets[i]!=-1){
452 ogg_int64_t accumulated=0;
456 ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]);
461 ret=_get_next_page(vf,&og,-1);
463 /* this should not be possible unless the file is
467 if(ogg_page_bos(&og)) break;
469 if(ogg_page_serialno(&og)!=vf->serialnos[i])
472 /* count blocksizes of all frames in the page */
473 ogg_stream_pagein(&vf->os,&og);
474 while((result=ogg_stream_packetout(&vf->os,&op))){
475 if(result>0){ /* ignore holes */
476 long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
478 accumulated+=(lastblock+thisblock)>>2;
483 if(ogg_page_granulepos(&og)!=-1){
484 /* pcm offset of last packet on the first audio page */
485 accumulated= ogg_page_granulepos(&og)-accumulated;
490 /* less than zero? This is a stream with samples trimmed off
491 the beginning, a normal occurrence; set the offset to zero */
492 if(accumulated<0)accumulated=0;
494 vf->pcmlengths[i*2]=accumulated;
497 /* get the PCM length of this link. To do this,
498 get the last page of the stream */
500 ogg_int64_t end=vf->offsets[i+1];
501 ret=_seek_helper(vf,end);
503 /* this should not be possible */
504 vorbis_info_clear(vf->vi+i);
505 vorbis_comment_clear(vf->vc+i);
509 ret=_get_prev_page(vf,&og);
511 /* this should not be possible */
512 vorbis_info_clear(vf->vi+i);
513 vorbis_comment_clear(vf->vc+i);
516 if(ogg_page_serialno(&og)==vf->serialnos[i]){
517 if(ogg_page_granulepos(&og)!=-1){
518 vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
529 static int _make_decode_ready(OggVorbis_File *vf){
530 if(vf->ready_state>STREAMSET)return 0;
531 if(vf->ready_state<STREAMSET)return OV_EFAULT;
533 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
536 if(vorbis_synthesis_init(&vf->vd,vf->vi))
539 vorbis_block_init(&vf->vd,&vf->vb);
540 vf->ready_state=INITSET;
546 static int _open_seekable2(OggVorbis_File *vf){
547 ogg_int64_t dataoffset=vf->offset,end;
548 long *serialno_list=NULL;
553 /* we're partially open and have a first link header state in
555 /* we can seek, so set out learning all about this file */
556 if(vf->callbacks.seek_func && vf->callbacks.tell_func){
557 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
558 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
560 vf->offset=vf->end=-1;
563 /* If seek_func is implemented, tell_func must also be implemented */
564 if(vf->end==-1) return(OV_EINVAL);
566 /* We get the offset for the last page of the physical bitstream.
567 Most OggVorbis files will contain a single logical bitstream */
568 end=_get_prev_page(vf,&og);
569 if(end<0)return(end);
571 /* back to beginning, learn all serialnos of first link */
572 ret=_seek_helper(vf,0);
574 ret=_get_serialnos(vf,&serialno_list,&serialnos);
577 /* now determine bitstream structure recursively */
578 if(_bisect_forward_serialno(vf,0,0,end+1,serialno_list,serialnos,0)<0)return(OV_EREAD);
579 if(serialno_list)_ogg_free(serialno_list);
581 /* the initial header memory is referenced by vf after; don't free it */
582 _prefetch_all_headers(vf,dataoffset);
583 return(ov_raw_seek(vf,0));
586 /* clear out the current logical bitstream decoder */
587 static void _decode_clear(OggVorbis_File *vf){
588 vorbis_dsp_clear(&vf->vd);
589 vorbis_block_clear(&vf->vb);
590 vf->ready_state=OPENED;
593 /* fetch and process a packet. Handles the case where we're at a
594 bitstream boundary and dumps the decoding machine. If the decoding
595 machine is unloaded, it loads it. It also keeps pcm_offset up to
596 date (seek and read both use this. seek uses a special hack with
599 return: <0) error, OV_HOLE (lost packet) or OV_EOF
600 0) need more data (only if readp==0)
604 static int _fetch_and_process_packet(OggVorbis_File *vf,
610 /* handle one packet. Try to fetch it from current stream state */
611 /* extract packets from page */
614 /* process a packet if we can. If the machine isn't loaded,
616 if(vf->ready_state==INITSET){
619 ogg_packet *op_ptr=(op_in?op_in:&op);
620 int result=ogg_stream_packetout(&vf->os,op_ptr);
621 ogg_int64_t granulepos;
624 if(result==-1)return(OV_HOLE); /* hole in the data. */
626 /* got a packet. process it */
627 granulepos=op_ptr->granulepos;
628 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
630 header packets aren't
633 vorbis_synthesis will
636 /* suck in the synthesis data and track bitrate */
638 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
639 /* for proper use of libvorbis within libvorbisfile,
640 oldsamples will always be zero. */
641 if(oldsamples)return(OV_EFAULT);
643 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
644 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
645 vf->bittrack+=op_ptr->bytes*8;
648 /* update the pcm offset. */
649 if(granulepos!=-1 && !op_ptr->e_o_s){
650 int link=(vf->seekable?vf->current_link:0);
653 /* this packet has a pcm_offset on it (the last packet
654 completed on a page carries the offset) After processing
655 (above), we know the pcm position of the *last* sample
656 ready to be returned. Find the offset of the *first*
658 As an aside, this trick is inaccurate if we begin
659 reading anew right at the last page; the end-of-stream
660 granulepos declares the last frame in the stream, and the
661 last packet of the last page may be a partial frame.
662 So, we need a previous granulepos from an in-sequence page
663 to have a reference point. Thus the !op_ptr->e_o_s clause
666 if(vf->seekable && link>0)
667 granulepos-=vf->pcmlengths[link*2];
668 if(granulepos<0)granulepos=0; /* actually, this
669 shouldn't be possible
670 here unless the stream
673 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
677 granulepos+=vf->pcmlengths[i*2+1];
678 vf->pcm_offset=granulepos;
688 if(vf->ready_state>=OPENED){
692 /* the loop is not strictly necessary, but there's no sense in
693 doing the extra checks of the larger loop for the common
694 case in a multiplexed bistream where the page is simply
695 part of a different logical bitstream; keep reading until
696 we get one with the correct serialno */
699 if((ret=_get_next_page(vf,&og,-1))<0){
700 return(OV_EOF); /* eof. leave unitialized */
703 /* bitrate tracking; add the header's bytes here, the body bytes
704 are done by packet above */
705 vf->bittrack+=og.header_len*8;
707 if(vf->ready_state==INITSET){
708 if(vf->current_serialno!=ogg_page_serialno(&og)){
710 /* two possibilities:
711 1) our decoding just traversed a bitstream boundary
712 2) another stream is multiplexed into this logical section? */
714 if(ogg_page_bos(&og)){
722 vorbis_info_clear(vf->vi);
723 vorbis_comment_clear(vf->vc);
728 continue; /* possibility #2 */
736 /* Do we need to load a new machine before submitting the page? */
737 /* This is different in the seekable and non-seekable cases.
739 In the seekable case, we already have all the header
740 information loaded and cached; we just initialize the machine
741 with it and continue on our merry way.
743 In the non-seekable (streaming) case, we'll only be at a
744 boundary if we just left the previous logical bitstream and
745 we're now nominally at the header of the next bitstream
748 if(vf->ready_state!=INITSET){
751 if(vf->ready_state<STREAMSET){
753 long serialno = ogg_page_serialno(&og);
755 /* match the serialno to bitstream section. We use this rather than
756 offset positions to avoid problems near logical bitstream
759 for(link=0;link<vf->links;link++)
760 if(vf->serialnos[link]==serialno)break;
762 if(link==vf->links) continue; /* not the desired Vorbis
763 bitstream section; keep
766 vf->current_serialno=serialno;
767 vf->current_link=link;
769 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
770 vf->ready_state=STREAMSET;
773 /* we're streaming */
774 /* fetch the three header packets, build the info struct */
776 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
784 int ret=_make_decode_ready(vf);
789 /* the buffered page is the data we want, and we're ready for it;
790 add it to the stream state */
791 ogg_stream_pagein(&vf->os,&og);
796 /* if, eg, 64 bit stdio is configured by default, this will build with
798 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
799 if(f==NULL)return(-1);
800 return fseek(f,off,whence);
803 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
804 long ibytes, ov_callbacks callbacks){
805 int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
808 memset(vf,0,sizeof(*vf));
810 vf->callbacks = callbacks;
812 /* init the framing state */
813 ogg_sync_init(&vf->oy);
815 /* perhaps some data was previously read into a buffer for testing
816 against other stream types. Allow initialization from this
817 previously read data (as we may be reading from a non-seekable
820 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
821 memcpy(buffer,initial,ibytes);
822 ogg_sync_wrote(&vf->oy,ibytes);
825 /* can we seek? Stevens suggests the seek test was portable */
826 if(offsettest!=-1)vf->seekable=1;
828 /* No seeking yet; Set up a 'single' (current) logical bitstream
829 entry for partial open */
831 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
832 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
833 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
835 /* Try to fetch the headers, maintaining all the storage */
836 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
840 vf->ready_state=PARTOPEN;
844 static int _ov_open2(OggVorbis_File *vf){
845 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
846 vf->ready_state=OPENED;
848 int ret=_open_seekable2(vf);
855 vf->ready_state=STREAMSET;
861 /* clear out the OggVorbis_File struct */
862 int ov_clear(OggVorbis_File *vf){
864 vorbis_block_clear(&vf->vb);
865 vorbis_dsp_clear(&vf->vd);
866 ogg_stream_clear(&vf->os);
868 if(vf->vi && vf->links){
870 for(i=0;i<vf->links;i++){
871 vorbis_info_clear(vf->vi+i);
872 vorbis_comment_clear(vf->vc+i);
877 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
878 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
879 if(vf->serialnos)_ogg_free(vf->serialnos);
880 if(vf->offsets)_ogg_free(vf->offsets);
881 ogg_sync_clear(&vf->oy);
882 if(vf->datasource && vf->callbacks.close_func)
883 (vf->callbacks.close_func)(vf->datasource);
884 memset(vf,0,sizeof(*vf));
892 /* inspects the OggVorbis file and finds/documents all the logical
893 bitstreams contained in it. Tries to be tolerant of logical
894 bitstream sections that are truncated/woogie.
900 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
901 ov_callbacks callbacks){
902 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
904 return _ov_open2(vf);
907 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
908 ov_callbacks callbacks = {
909 (size_t (*)(void *, size_t, size_t, void *)) fread,
910 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
911 (int (*)(void *)) fclose,
912 (long (*)(void *)) ftell
915 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
918 int ov_fopen(char *path,OggVorbis_File *vf){
920 FILE *f = fopen(path,"rb");
923 ret = ov_open(f,vf,NULL,0);
929 /* cheap hack for game usage where downsampling is desirable; there's
930 no need for SRC as we can just do it cheaply in libvorbis. */
932 int ov_halfrate(OggVorbis_File *vf,int flag){
934 if(vf->vi==NULL)return OV_EINVAL;
935 if(!vf->seekable)return OV_EINVAL;
936 if(vf->ready_state>=STREAMSET)
937 _decode_clear(vf); /* clear out stream state; later on libvorbis
938 will be able to swap this on the fly, but
939 for now dumping the decode machine is needed
940 to reinit the MDCT lookups. 1.1 libvorbis
941 is planned to be able to switch on the fly */
943 for(i=0;i<vf->links;i++){
944 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
952 int ov_halfrate_p(OggVorbis_File *vf){
953 if(vf->vi==NULL)return OV_EINVAL;
954 return vorbis_synthesis_halfrate_p(vf->vi);
957 /* Only partially open the vorbis file; test for Vorbisness, and load
958 the headers for the first chain. Do not seek (although test for
959 seekability). Use ov_test_open to finish opening the file, else
960 ov_clear to close/free it. Same return codes as open. */
962 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
963 ov_callbacks callbacks)
965 return _ov_open1(f,vf,initial,ibytes,callbacks);
968 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
969 ov_callbacks callbacks = {
970 (size_t (*)(void *, size_t, size_t, void *)) fread,
971 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
972 (int (*)(void *)) fclose,
973 (long (*)(void *)) ftell
976 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
979 int ov_test_open(OggVorbis_File *vf){
980 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
981 return _ov_open2(vf);
984 /* How many logical bitstreams in this physical bitstream? */
985 long ov_streams(OggVorbis_File *vf){
989 /* Is the FILE * associated with vf seekable? */
990 long ov_seekable(OggVorbis_File *vf){
994 /* returns the bitrate for a given logical bitstream or the entire
995 physical bitstream. If the file is open for random access, it will
996 find the *actual* average bitrate. If the file is streaming, it
997 returns the nominal bitrate (if set) else the average of the
998 upper/lower bounds (if set) else -1 (unset).
1000 If you want the actual bitrate field settings, get them from the
1001 vorbis_info structs */
1003 long ov_bitrate(OggVorbis_File *vf,int i){
1004 if(vf->ready_state<OPENED)return(OV_EINVAL);
1005 if(i>=vf->links)return(OV_EINVAL);
1006 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
1011 for(i=0;i<vf->links;i++)
1012 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
1013 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
1014 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
1015 * so this is slightly transformed to make it work.
1017 br = bits/ov_time_total(vf,-1);
1021 /* return the actual bitrate */
1022 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
1024 /* return nominal if set */
1025 if(vf->vi[i].bitrate_nominal>0){
1026 return vf->vi[i].bitrate_nominal;
1028 if(vf->vi[i].bitrate_upper>0){
1029 if(vf->vi[i].bitrate_lower>0){
1030 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1032 return vf->vi[i].bitrate_upper;
1041 /* returns the actual bitrate since last call. returns -1 if no
1042 additional data to offer since last call (or at beginning of stream),
1043 EINVAL if stream is only partially open
1045 long ov_bitrate_instant(OggVorbis_File *vf){
1046 int link=(vf->seekable?vf->current_link:0);
1048 if(vf->ready_state<OPENED)return(OV_EINVAL);
1049 if(vf->samptrack==0)return(OV_FALSE);
1050 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1057 long ov_serialnumber(OggVorbis_File *vf,int i){
1058 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1059 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1061 return(vf->current_serialno);
1063 return(vf->serialnos[i]);
1067 /* returns: total raw (compressed) length of content if i==-1
1068 raw (compressed) length of that logical bitstream for i==0 to n
1069 OV_EINVAL if the stream is not seekable (we can't know the length)
1070 or if stream is only partially open
1072 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1073 if(vf->ready_state<OPENED)return(OV_EINVAL);
1074 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1078 for(i=0;i<vf->links;i++)
1079 acc+=ov_raw_total(vf,i);
1082 return(vf->offsets[i+1]-vf->offsets[i]);
1086 /* returns: total PCM length (samples) of content if i==-1 PCM length
1087 (samples) of that logical bitstream for i==0 to n
1088 OV_EINVAL if the stream is not seekable (we can't know the
1089 length) or only partially open
1091 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1092 if(vf->ready_state<OPENED)return(OV_EINVAL);
1093 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1097 for(i=0;i<vf->links;i++)
1098 acc+=ov_pcm_total(vf,i);
1101 return(vf->pcmlengths[i*2+1]);
1105 /* returns: total seconds of content if i==-1
1106 seconds in that logical bitstream for i==0 to n
1107 OV_EINVAL if the stream is not seekable (we can't know the
1108 length) or only partially open
1110 double ov_time_total(OggVorbis_File *vf,int i){
1111 if(vf->ready_state<OPENED)return(OV_EINVAL);
1112 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1116 for(i=0;i<vf->links;i++)
1117 acc+=ov_time_total(vf,i);
1120 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1124 /* seek to an offset relative to the *compressed* data. This also
1125 scans packets to update the PCM cursor. It will cross a logical
1126 bitstream boundary, but only if it can't get any packets out of the
1127 tail of the bitstream we seek to (so no surprises).
1129 returns zero on success, nonzero on failure */
1131 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1132 ogg_stream_state work_os;
1135 if(vf->ready_state<OPENED)return(OV_EINVAL);
1137 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1139 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1141 /* don't yet clear out decoding machine (if it's initialized), in
1142 the case we're in the same link. Restart the decode lapping, and
1143 let _fetch_and_process_packet deal with a potential bitstream
1146 ogg_stream_reset_serialno(&vf->os,
1147 vf->current_serialno); /* must set serialno */
1148 vorbis_synthesis_restart(&vf->vd);
1150 ret=_seek_helper(vf,pos);
1151 if(ret)goto seek_error;
1153 /* we need to make sure the pcm_offset is set, but we don't want to
1154 advance the raw cursor past good packets just to get to the first
1155 with a granulepos. That's not equivalent behavior to beginning
1156 decoding as immediately after the seek position as possible.
1158 So, a hack. We use two stream states; a local scratch state and
1159 the shared vf->os stream state. We use the local state to
1160 scan, and the shared state as a buffer for later decode.
1162 Unfortuantely, on the last page we still advance to last packet
1163 because the granulepos on the last page is not necessarily on a
1164 packet boundary, and we need to make sure the granpos is
1176 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1177 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1178 return from not necessarily
1179 starting from the beginning */
1182 if(vf->ready_state>=STREAMSET){
1183 /* snarf/scan a packet if we can */
1184 int result=ogg_stream_packetout(&work_os,&op);
1188 if(vf->vi[vf->current_link].codec_setup){
1189 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1191 ogg_stream_packetout(&vf->os,NULL);
1196 ogg_stream_packetout(&vf->os,NULL);
1198 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1201 if(op.granulepos!=-1){
1202 int i,link=vf->current_link;
1203 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1204 if(granulepos<0)granulepos=0;
1207 granulepos+=vf->pcmlengths[i*2+1];
1208 vf->pcm_offset=granulepos-accblock;
1211 lastblock=thisblock;
1214 ogg_stream_packetout(&vf->os,NULL);
1219 if(_get_next_page(vf,&og,-1)<0){
1220 vf->pcm_offset=ov_pcm_total(vf,-1);
1224 /* huh? Bogus stream with packets but no granulepos */
1229 /* has our decoding just traversed a bitstream boundary? */
1230 if(vf->ready_state>=STREAMSET){
1231 if(vf->current_serialno!=ogg_page_serialno(&og)){
1233 /* two possibilities:
1234 1) our decoding just traversed a bitstream boundary
1235 2) another stream is multiplexed into this logical section? */
1237 if(ogg_page_bos(&og)){
1239 _decode_clear(vf); /* clear out stream state */
1240 ogg_stream_clear(&work_os);
1241 } /* else, do nothing; next loop will scoop another page */
1245 if(vf->ready_state<STREAMSET){
1247 long serialno = ogg_page_serialno(&og);
1249 for(link=0;link<vf->links;link++)
1250 if(vf->serialnos[link]==serialno)break;
1252 if(link==vf->links) continue; /* not the desired Vorbis
1253 bitstream section; keep
1255 vf->current_link=link;
1256 vf->current_serialno=serialno;
1257 ogg_stream_reset_serialno(&vf->os,serialno);
1258 ogg_stream_reset_serialno(&work_os,serialno);
1259 vf->ready_state=STREAMSET;
1263 ogg_stream_pagein(&vf->os,&og);
1264 ogg_stream_pagein(&work_os,&og);
1265 eosflag=ogg_page_eos(&og);
1269 ogg_stream_clear(&work_os);
1275 /* dump the machine so we're in a known state */
1277 ogg_stream_clear(&work_os);
1282 /* Page granularity seek (faster than sample granularity because we
1283 don't do the last bit of decode to find a specific sample).
1285 Seek to the last [granule marked] page preceeding the specified pos
1286 location, such that decoding past the returned point will quickly
1287 arrive at the requested position. */
1288 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1290 ogg_int64_t result=0;
1291 ogg_int64_t total=ov_pcm_total(vf,-1);
1293 if(vf->ready_state<OPENED)return(OV_EINVAL);
1294 if(!vf->seekable)return(OV_ENOSEEK);
1296 if(pos<0 || pos>total)return(OV_EINVAL);
1298 /* which bitstream section does this pcm offset occur in? */
1299 for(link=vf->links-1;link>=0;link--){
1300 total-=vf->pcmlengths[link*2+1];
1301 if(pos>=total)break;
1304 /* search within the logical bitstream for the page with the highest
1305 pcm_pos preceeding (or equal to) pos. There is a danger here;
1306 missing pages or incorrect frame number information in the
1307 bitstream could make our task impossible. Account for that (it
1308 would be an error condition) */
1310 /* new search algorithm by HB (Nicholas Vinen) */
1312 ogg_int64_t end=vf->offsets[link+1];
1313 ogg_int64_t begin=vf->offsets[link];
1314 ogg_int64_t begintime = vf->pcmlengths[link*2];
1315 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1316 ogg_int64_t target=pos-total+begintime;
1317 ogg_int64_t best=begin;
1323 if(end-begin<CHUNKSIZE){
1326 /* take a (pretty decent) guess. */
1328 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1333 result=_seek_helper(vf,bisect);
1334 if(result) goto seek_error;
1337 result=_get_next_page(vf,&og,end-vf->offset);
1338 if(result==OV_EREAD) goto seek_error;
1341 end=begin; /* found it */
1343 if(bisect==0) goto seek_error;
1345 if(bisect<=begin)bisect=begin+1;
1346 result=_seek_helper(vf,bisect);
1347 if(result) goto seek_error;
1350 ogg_int64_t granulepos;
1352 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1355 granulepos=ogg_page_granulepos(&og);
1356 if(granulepos==-1)continue;
1358 if(granulepos<target){
1359 best=result; /* raw offset of packet with granulepos */
1360 begin=vf->offset; /* raw offset of next page */
1361 begintime=granulepos;
1363 if(target-begintime>44100)break;
1364 bisect=begin; /* *not* begin + 1 */
1367 end=begin; /* found it */
1369 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1371 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1372 if(bisect<=begin)bisect=begin+1;
1373 result=_seek_helper(vf,bisect);
1374 if(result) goto seek_error;
1386 /* found our page. seek to it, update pcm offset. Easier case than
1387 raw_seek, don't keep packets preceeding granulepos. */
1393 result=_seek_helper(vf,best);
1395 if(result) goto seek_error;
1396 result=_get_next_page(vf,&og,-1);
1397 if(result<0) goto seek_error;
1399 if(link!=vf->current_link){
1400 /* Different link; dump entire decode machine */
1403 vf->current_link=link;
1404 vf->current_serialno=vf->serialnos[link];
1405 vf->ready_state=STREAMSET;
1408 vorbis_synthesis_restart(&vf->vd);
1411 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1412 ogg_stream_pagein(&vf->os,&og);
1414 /* pull out all but last packet; the one with granulepos */
1416 result=ogg_stream_packetpeek(&vf->os,&op);
1418 /* !!! the packet finishing this page originated on a
1419 preceeding page. Keep fetching previous pages until we
1420 get one with a granulepos or without the 'continued' flag
1421 set. Then just use raw_seek for simplicity. */
1423 result=_seek_helper(vf,best);
1424 if(result<0) goto seek_error;
1427 result=_get_prev_page(vf,&og);
1428 if(result<0) goto seek_error;
1429 if(ogg_page_serialno(&og)==vf->current_serialno &&
1430 (ogg_page_granulepos(&og)>-1 ||
1431 !ogg_page_continued(&og))){
1432 return ov_raw_seek(vf,result);
1438 result = OV_EBADPACKET;
1441 if(op.granulepos!=-1){
1442 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1443 if(vf->pcm_offset<0)vf->pcm_offset=0;
1444 vf->pcm_offset+=total;
1447 result=ogg_stream_packetout(&vf->os,NULL);
1453 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1462 /* dump machine so we're in a known state */
1468 /* seek to a sample offset relative to the decompressed pcm stream
1469 returns zero on success, nonzero on failure */
1471 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1472 int thisblock,lastblock=0;
1473 int ret=ov_pcm_seek_page(vf,pos);
1474 if(ret<0)return(ret);
1475 if((ret=_make_decode_ready(vf)))return ret;
1477 /* discard leading packets we don't need for the lapping of the
1478 position we want; don't decode them */
1484 int ret=ogg_stream_packetpeek(&vf->os,&op);
1486 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1488 ogg_stream_packetout(&vf->os,NULL);
1489 continue; /* non audio packet */
1491 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1493 if(vf->pcm_offset+((thisblock+
1494 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1496 /* remove the packet from packet queue and track its granulepos */
1497 ogg_stream_packetout(&vf->os,NULL);
1498 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1501 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1503 /* end of logical stream case is hard, especially with exact
1504 length positioning. */
1506 if(op.granulepos>-1){
1508 /* always believe the stream markers */
1509 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1510 if(vf->pcm_offset<0)vf->pcm_offset=0;
1511 for(i=0;i<vf->current_link;i++)
1512 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1515 lastblock=thisblock;
1518 if(ret<0 && ret!=OV_HOLE)break;
1520 /* suck in a new page */
1521 if(_get_next_page(vf,&og,-1)<0)break;
1522 if(ogg_page_bos(&og))_decode_clear(vf);
1524 if(vf->ready_state<STREAMSET){
1525 long serialno=ogg_page_serialno(&og);
1528 for(link=0;link<vf->links;link++)
1529 if(vf->serialnos[link]==serialno)break;
1530 if(link==vf->links) continue;
1531 vf->current_link=link;
1533 vf->ready_state=STREAMSET;
1534 vf->current_serialno=ogg_page_serialno(&og);
1535 ogg_stream_reset_serialno(&vf->os,serialno);
1536 ret=_make_decode_ready(vf);
1541 ogg_stream_pagein(&vf->os,&og);
1547 /* discard samples until we reach the desired position. Crossing a
1548 logical bitstream boundary with abandon is OK. */
1549 while(vf->pcm_offset<pos){
1550 ogg_int64_t target=pos-vf->pcm_offset;
1551 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1553 if(samples>target)samples=target;
1554 vorbis_synthesis_read(&vf->vd,samples);
1555 vf->pcm_offset+=samples;
1558 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1559 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1564 /* seek to a playback time relative to the decompressed pcm stream
1565 returns zero on success, nonzero on failure */
1566 int ov_time_seek(OggVorbis_File *vf,double seconds){
1567 /* translate time to PCM position and call ov_pcm_seek */
1570 ogg_int64_t pcm_total=0;
1571 double time_total=0.;
1573 if(vf->ready_state<OPENED)return(OV_EINVAL);
1574 if(!vf->seekable)return(OV_ENOSEEK);
1575 if(seconds<0)return(OV_EINVAL);
1577 /* which bitstream section does this time offset occur in? */
1578 for(link=0;link<vf->links;link++){
1579 double addsec = ov_time_total(vf,link);
1580 if(seconds<time_total+addsec)break;
1582 pcm_total+=vf->pcmlengths[link*2+1];
1585 if(link==vf->links)return(OV_EINVAL);
1587 /* enough information to convert time offset to pcm offset */
1589 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1590 return(ov_pcm_seek(vf,target));
1594 /* page-granularity version of ov_time_seek
1595 returns zero on success, nonzero on failure */
1596 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1597 /* translate time to PCM position and call ov_pcm_seek */
1600 ogg_int64_t pcm_total=0;
1601 double time_total=0.;
1603 if(vf->ready_state<OPENED)return(OV_EINVAL);
1604 if(!vf->seekable)return(OV_ENOSEEK);
1605 if(seconds<0)return(OV_EINVAL);
1607 /* which bitstream section does this time offset occur in? */
1608 for(link=0;link<vf->links;link++){
1609 double addsec = ov_time_total(vf,link);
1610 if(seconds<time_total+addsec)break;
1612 pcm_total+=vf->pcmlengths[link*2+1];
1615 if(link==vf->links)return(OV_EINVAL);
1617 /* enough information to convert time offset to pcm offset */
1619 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1620 return(ov_pcm_seek_page(vf,target));
1624 /* tell the current stream offset cursor. Note that seek followed by
1625 tell will likely not give the set offset due to caching */
1626 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1627 if(vf->ready_state<OPENED)return(OV_EINVAL);
1631 /* return PCM offset (sample) of next PCM sample to be read */
1632 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1633 if(vf->ready_state<OPENED)return(OV_EINVAL);
1634 return(vf->pcm_offset);
1637 /* return time offset (seconds) of next PCM sample to be read */
1638 double ov_time_tell(OggVorbis_File *vf){
1640 ogg_int64_t pcm_total=0;
1641 double time_total=0.f;
1643 if(vf->ready_state<OPENED)return(OV_EINVAL);
1645 pcm_total=ov_pcm_total(vf,-1);
1646 time_total=ov_time_total(vf,-1);
1648 /* which bitstream section does this time offset occur in? */
1649 for(link=vf->links-1;link>=0;link--){
1650 pcm_total-=vf->pcmlengths[link*2+1];
1651 time_total-=ov_time_total(vf,link);
1652 if(vf->pcm_offset>=pcm_total)break;
1656 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1659 /* link: -1) return the vorbis_info struct for the bitstream section
1660 currently being decoded
1661 0-n) to request information for a specific bitstream section
1663 In the case of a non-seekable bitstream, any call returns the
1664 current bitstream. NULL in the case that the machine is not
1667 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1670 if(vf->ready_state>=STREAMSET)
1671 return vf->vi+vf->current_link;
1684 /* grr, strong typing, grr, no templates/inheritence, grr */
1685 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1688 if(vf->ready_state>=STREAMSET)
1689 return vf->vc+vf->current_link;
1702 static int host_is_big_endian() {
1703 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1704 unsigned char *bytewise = (unsigned char *)&pattern;
1705 if (bytewise[0] == 0xfe) return 1;
1709 /* up to this point, everything could more or less hide the multiple
1710 logical bitstream nature of chaining from the toplevel application
1711 if the toplevel application didn't particularly care. However, at
1712 the point that we actually read audio back, the multiple-section
1713 nature must surface: Multiple bitstream sections do not necessarily
1714 have to have the same number of channels or sampling rate.
1716 ov_read returns the sequential logical bitstream number currently
1717 being decoded along with the PCM data in order that the toplevel
1718 application can take action on channel/sample rate changes. This
1719 number will be incremented even for streamed (non-seekable) streams
1720 (for seekable streams, it represents the actual logical bitstream
1721 index within the physical bitstream. Note that the accessor
1722 functions above are aware of this dichotomy).
1724 input values: buffer) a buffer to hold packed PCM data for return
1725 length) the byte length requested to be placed into buffer
1726 bigendianp) should the data be packed LSB first (0) or
1728 word) word size for output. currently 1 (byte) or
1731 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1733 n) number of bytes of PCM actually returned. The
1734 below works on a packet-by-packet basis, so the
1735 return length is not related to the 'length' passed
1736 in, just guaranteed to fit.
1738 *section) set to the logical bitstream number */
1740 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1741 int bigendianp,int word,int sgned,int *bitstream){
1743 int host_endian = host_is_big_endian();
1748 if(vf->ready_state<OPENED)return(OV_EINVAL);
1751 if(vf->ready_state==INITSET){
1752 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1756 /* suck in another packet */
1758 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1769 /* yay! proceed to pack data into the byte buffer */
1771 long channels=ov_info(vf,-1)->channels;
1772 long bytespersample=word * channels;
1773 vorbis_fpu_control fpu;
1774 if(samples>length/bytespersample)samples=length/bytespersample;
1779 /* a tight loop to pack each size */
1783 int off=(sgned?0:128);
1784 vorbis_fpu_setround(&fpu);
1785 for(j=0;j<samples;j++)
1786 for(i=0;i<channels;i++){
1787 val=vorbis_ftoi(pcm[i][j]*128.f);
1789 else if(val<-128)val=-128;
1792 vorbis_fpu_restore(fpu);
1794 int off=(sgned?0:32768);
1796 if(host_endian==bigendianp){
1799 vorbis_fpu_setround(&fpu);
1800 for(i=0;i<channels;i++) { /* It's faster in this order */
1802 short *dest=((short *)buffer)+i;
1803 for(j=0;j<samples;j++) {
1804 val=vorbis_ftoi(src[j]*32768.f);
1805 if(val>32767)val=32767;
1806 else if(val<-32768)val=-32768;
1811 vorbis_fpu_restore(fpu);
1815 vorbis_fpu_setround(&fpu);
1816 for(i=0;i<channels;i++) {
1818 short *dest=((short *)buffer)+i;
1819 for(j=0;j<samples;j++) {
1820 val=vorbis_ftoi(src[j]*32768.f);
1821 if(val>32767)val=32767;
1822 else if(val<-32768)val=-32768;
1827 vorbis_fpu_restore(fpu);
1830 }else if(bigendianp){
1832 vorbis_fpu_setround(&fpu);
1833 for(j=0;j<samples;j++)
1834 for(i=0;i<channels;i++){
1835 val=vorbis_ftoi(pcm[i][j]*32768.f);
1836 if(val>32767)val=32767;
1837 else if(val<-32768)val=-32768;
1840 *buffer++=(val&0xff);
1842 vorbis_fpu_restore(fpu);
1846 vorbis_fpu_setround(&fpu);
1847 for(j=0;j<samples;j++)
1848 for(i=0;i<channels;i++){
1849 val=vorbis_ftoi(pcm[i][j]*32768.f);
1850 if(val>32767)val=32767;
1851 else if(val<-32768)val=-32768;
1853 *buffer++=(val&0xff);
1856 vorbis_fpu_restore(fpu);
1862 vorbis_synthesis_read(&vf->vd,samples);
1863 vf->pcm_offset+=samples;
1864 if(bitstream)*bitstream=vf->current_link;
1865 return(samples*bytespersample);
1871 /* input values: pcm_channels) a float vector per channel of output
1872 length) the sample length being read by the app
1874 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1876 n) number of samples of PCM actually returned. The
1877 below works on a packet-by-packet basis, so the
1878 return length is not related to the 'length' passed
1879 in, just guaranteed to fit.
1881 *section) set to the logical bitstream number */
1885 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1888 if(vf->ready_state<OPENED)return(OV_EINVAL);
1891 if(vf->ready_state==INITSET){
1893 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1895 if(pcm_channels)*pcm_channels=pcm;
1896 if(samples>length)samples=length;
1897 vorbis_synthesis_read(&vf->vd,samples);
1898 vf->pcm_offset+=samples;
1899 if(bitstream)*bitstream=vf->current_link;
1905 /* suck in another packet */
1907 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1908 if(ret==OV_EOF)return(0);
1909 if(ret<=0)return(ret);
1915 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1916 extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
1919 static void _ov_splice(float **pcm,float **lappcm,
1922 float *w1, float *w2){
1933 for(j=0;j<ch1 && j<ch2;j++){
1940 d[i]=d[i]*wd + s[i]*ws;
1943 /* window from zero */
1954 /* make sure vf is INITSET */
1955 static int _ov_initset(OggVorbis_File *vf){
1957 if(vf->ready_state==INITSET)break;
1958 /* suck in another packet */
1960 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1961 if(ret<0 && ret!=OV_HOLE)return(ret);
1967 /* make sure vf is INITSET and that we have a primed buffer; if
1968 we're crosslapping at a stream section boundary, this also makes
1969 sure we're sanity checking against the right stream information */
1970 static int _ov_initprime(OggVorbis_File *vf){
1971 vorbis_dsp_state *vd=&vf->vd;
1973 if(vf->ready_state==INITSET)
1974 if(vorbis_synthesis_pcmout(vd,NULL))break;
1976 /* suck in another packet */
1978 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1979 if(ret<0 && ret!=OV_HOLE)return(ret);
1985 /* grab enough data for lapping from vf; this may be in the form of
1986 unreturned, already-decoded pcm, remaining PCM we will need to
1987 decode, or synthetic postextrapolation from last packets. */
1988 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1989 float **lappcm,int lapsize){
1993 /* try first to decode the lapping data */
1994 while(lapcount<lapsize){
1995 int samples=vorbis_synthesis_pcmout(vd,&pcm);
1997 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1998 for(i=0;i<vi->channels;i++)
1999 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2001 vorbis_synthesis_read(vd,samples);
2003 /* suck in another packet */
2004 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
2005 if(ret==OV_EOF)break;
2008 if(lapcount<lapsize){
2009 /* failed to get lapping data from normal decode; pry it from the
2010 postextrapolation buffering, or the second half of the MDCT
2011 from the last packet */
2012 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
2014 for(i=0;i<vi->channels;i++)
2015 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2018 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2019 for(i=0;i<vi->channels;i++)
2020 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2026 /* this sets up crosslapping of a sample by using trailing data from
2027 sample 1 and lapping it into the windowing buffer of sample 2 */
2028 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2029 vorbis_info *vi1,*vi2;
2033 int n1,n2,i,ret,hs1,hs2;
2035 if(vf1==vf2)return(0); /* degenerate case */
2036 if(vf1->ready_state<OPENED)return(OV_EINVAL);
2037 if(vf2->ready_state<OPENED)return(OV_EINVAL);
2039 /* the relevant overlap buffers must be pre-checked and pre-primed
2040 before looking at settings in the event that priming would cross
2041 a bitstream boundary. So, do it now */
2043 ret=_ov_initset(vf1);
2045 ret=_ov_initprime(vf2);
2048 vi1=ov_info(vf1,-1);
2049 vi2=ov_info(vf2,-1);
2050 hs1=ov_halfrate_p(vf1);
2051 hs2=ov_halfrate_p(vf2);
2053 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2054 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2055 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2056 w1=vorbis_window(&vf1->vd,0);
2057 w2=vorbis_window(&vf2->vd,0);
2059 for(i=0;i<vi1->channels;i++)
2060 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2062 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2064 /* have a lapping buffer from vf1; now to splice it into the lapping
2066 /* consolidate and expose the buffer. */
2067 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2068 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2069 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2072 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2078 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2079 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2084 int n1,n2,ch1,ch2,hs;
2087 if(vf->ready_state<OPENED)return(OV_EINVAL);
2088 ret=_ov_initset(vf);
2091 hs=ov_halfrate_p(vf);
2094 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2095 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2096 persistent; even if the decode state
2097 from this link gets dumped, this
2098 window array continues to exist */
2100 lappcm=alloca(sizeof(*lappcm)*ch1);
2102 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2103 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2105 /* have lapping data; seek and prime the buffer */
2106 ret=localseek(vf,pos);
2108 ret=_ov_initprime(vf);
2111 /* Guard against cross-link changes; they're perfectly legal */
2114 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2115 w2=vorbis_window(&vf->vd,0);
2117 /* consolidate and expose the buffer. */
2118 vorbis_synthesis_lapout(&vf->vd,&pcm);
2121 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2127 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2128 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2131 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2132 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2135 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2136 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2139 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2140 int (*localseek)(OggVorbis_File *,double)){
2145 int n1,n2,ch1,ch2,hs;
2148 if(vf->ready_state<OPENED)return(OV_EINVAL);
2149 ret=_ov_initset(vf);
2152 hs=ov_halfrate_p(vf);
2155 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2156 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2157 persistent; even if the decode state
2158 from this link gets dumped, this
2159 window array continues to exist */
2161 lappcm=alloca(sizeof(*lappcm)*ch1);
2163 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2164 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2166 /* have lapping data; seek and prime the buffer */
2167 ret=localseek(vf,pos);
2169 ret=_ov_initprime(vf);
2172 /* Guard against cross-link changes; they're perfectly legal */
2175 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2176 w2=vorbis_window(&vf->vd,0);
2178 /* consolidate and expose the buffer. */
2179 vorbis_synthesis_lapout(&vf->vd,&pcm);
2182 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2188 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2189 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2192 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2193 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);