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-2002 *
9 * by the XIPHOPHORUS Company 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){
66 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
67 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
68 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
69 if(bytes==0 && errno)return(-1);
75 /* save a tiny smidge of verbosity to make the code more readable */
76 static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
78 if((vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
81 ogg_sync_reset(&vf->oy);
83 /* shouldn't happen unless someone writes a broken callback */
89 /* The read/seek functions track absolute position within the stream */
91 /* from the head of the stream, get the next page. boundary specifies
92 if the function is allowed to fetch more data from the stream (and
93 how much) or only use internally buffered data.
95 boundary: -1) unbounded search
96 0) read no additional data; use cached only
97 n) search for a new page beginning for n bytes
99 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
100 n) found a page at absolute offset n */
102 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
103 ogg_int64_t boundary){
104 if(boundary>0)boundary+=vf->offset;
108 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
109 more=ogg_sync_pageseek(&vf->oy,og);
112 /* skipped n bytes */
116 /* send more paramedics */
117 if(!boundary)return(OV_FALSE);
119 long ret=_get_data(vf);
120 if(ret==0)return(OV_EOF);
121 if(ret<0)return(OV_EREAD);
124 /* got a page. Return the offset at the page beginning,
125 advance the internal offset past the page end */
126 ogg_int64_t ret=vf->offset;
135 /* find the latest page beginning before the current stream cursor
136 position. Much dirtier than the above as Ogg doesn't have any
137 backward search linkage. no 'readp' as it will certainly have to
139 /* returns offset or OV_EREAD, OV_FAULT */
140 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
141 ogg_int64_t begin=vf->offset;
142 ogg_int64_t end=begin;
144 ogg_int64_t offset=-1;
151 ret=_seek_helper(vf,begin);
154 while(vf->offset<end){
155 ret=_get_next_page(vf,og,end-vf->offset);
156 if(ret==OV_EREAD)return(OV_EREAD);
165 /* we have the offset. Actually snork and hold the page now */
166 ret=_seek_helper(vf,offset);
169 ret=_get_next_page(vf,og,CHUNKSIZE);
171 /* this shouldn't be possible */
177 static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
178 long s = ogg_page_serialno(og);
182 *serialno_list = _ogg_realloc(*serialno_list, sizeof(*serialno_list)*(*n));
184 *serialno_list = _ogg_malloc(sizeof(**serialno_list));
187 (*serialno_list)[(*n)-1] = s;
190 /* returns nonzero if found */
191 static int _lookup_serialno(ogg_page *og, long *serialno_list, int n){
192 long s = ogg_page_serialno(og);
196 if(*serialno_list == s) return 1;
203 /* start parsing pages at current offset, remembering all serial
204 numbers. Stop logging at first non-bos page */
205 static int _get_serialnos(OggVorbis_File *vf, long **s, int *n){
212 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
213 if(llret==OV_EOF)return(0);
214 if(llret<0)return(llret);
215 if(!ogg_page_bos(&og)) return 0;
217 /* look for duplicate serialnos; add this one if unique */
218 if(_lookup_serialno(&og,*s,*n)){
222 return(OV_EBADHEADER);
225 _add_serialno(&og,s,n);
229 /* finds each bitstream link one at a time using a bisection search
230 (has to begin by knowing the offset of the lb's initial page).
231 Recurses for each link so it can alloc the link storage after
232 finding them all, then unroll and fill the cache at the same time */
233 static int _bisect_forward_serialno(OggVorbis_File *vf,
235 ogg_int64_t searched,
237 long *currentno_list,
240 ogg_int64_t endsearched=end;
241 ogg_int64_t next=end;
245 /* the below guards against garbage seperating the last and
246 first pages of two links. */
247 while(searched<endsearched){
250 if(endsearched-searched<CHUNKSIZE){
253 bisect=(searched+endsearched)/2;
256 ret=_seek_helper(vf,bisect);
259 ret=_get_next_page(vf,&og,-1);
260 if(ret==OV_EREAD)return(OV_EREAD);
261 if(ret<0 || !_lookup_serialno(&og,currentno_list,currentnos)){
265 searched=ret+og.header_len+og.body_len;
270 long *next_serialno_list=NULL;
271 int next_serialnos=0;
273 ret=_seek_helper(vf,next);
275 ret=_get_serialnos(vf,&next_serialno_list,&next_serialnos);
278 if(searched>=end || next_serialnos==0){
280 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
281 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
282 vf->offsets[m+1]=searched;
284 ret=_bisect_forward_serialno(vf,next,vf->offset,
285 end,next_serialno_list,next_serialnos,m+1);
289 if(next_serialno_list)_ogg_free(next_serialno_list);
291 vf->offsets[m]=begin;
295 /* uses the local ogg_stream storage in vf; this is important for
296 non-streaming input sources */
297 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
298 long *serialno,ogg_page *og_ptr){
305 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
306 if(llret==OV_EREAD)return(OV_EREAD);
307 if(llret<0)return(OV_ENOTVORBIS);
311 vorbis_info_init(vi);
312 vorbis_comment_init(vc);
314 /* extract the first set of vorbis headers we see in the headerset */
318 /* if we're past the ID headers, we won't be finding a Vorbis
319 stream in this link */
320 if(!ogg_page_bos(og_ptr)){
325 /* prospective stream setup; we need a stream to get packets */
326 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
327 ogg_stream_pagein(&vf->os,og_ptr);
329 /* look for Vorbis ID header */
331 if(ogg_stream_packetout(&vf->os,&op) <= 0)
332 break; /* an error, yes, but try again */
334 if(!vorbis_synthesis_idheader(&op))
335 break; /* not a vorbis ID header; keep looking */
337 /* continue Vorbis header load; past this point, any error will
338 render this link useless (we won't continue looking for more
340 if(serialno)*serialno=vf->os.serialno;
341 vf->ready_state=STREAMSET;
342 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
346 while(i<2){ /* get a page loop */
348 while(i<2){ /* get a packet loop */
350 int result=ogg_stream_packetout(&vf->os,&op);
357 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
364 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
369 /* if this page belongs to the correct stream, go parse it */
370 if(vf->os.serialno == ogg_page_serialno(og_ptr)){
371 ogg_stream_pagein(&vf->os,og_ptr);
375 /* if we never see the final vorbis headers before the link
377 if(ogg_page_bos(og_ptr)){
385 /* otherwise, keep looking */
394 vorbis_info_clear(vi);
395 vorbis_comment_clear(vc);
396 vf->ready_state=OPENED;
401 /* last step of the OggVorbis_File initialization; get all the
402 vorbis_info structs and PCM positions. Only called by the seekable
403 initialization (local stream storage is hacked slightly; pay
404 attention to how that's done) */
406 /* this is void and does not propogate errors up because we want to be
407 able to open and use damaged bitstreams as well as we can. Just
408 watch out for missing information for links in the OggVorbis_File
410 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
415 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
416 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
417 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
418 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
420 for(i=0;i<vf->links;i++){
422 /* we already grabbed the initial header earlier. Just set the offset */
423 vf->dataoffsets[i]=dataoffset;
424 ret=_seek_helper(vf,dataoffset);
426 vf->dataoffsets[i]=-1;
430 /* seek to the location of the initial header */
432 ret=_seek_helper(vf,vf->offsets[i]);
434 vf->dataoffsets[i]=-1;
436 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,vf->serialnos+i,NULL)<0){
437 vf->dataoffsets[i]=-1;
439 vf->dataoffsets[i]=vf->offset;
444 /* fetch beginning PCM offset */
446 if(vf->dataoffsets[i]!=-1){
447 ogg_int64_t accumulated=0;
451 ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]);
456 ret=_get_next_page(vf,&og,-1);
458 /* this should not be possible unless the file is
462 if(ogg_page_serialno(&og)!=vf->serialnos[i])
465 /* count blocksizes of all frames in the page */
466 ogg_stream_pagein(&vf->os,&og);
467 while((result=ogg_stream_packetout(&vf->os,&op))){
468 if(result>0){ /* ignore holes */
469 long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
471 accumulated+=(lastblock+thisblock)>>2;
476 if(ogg_page_granulepos(&og)!=-1){
477 /* pcm offset of last packet on the first audio page */
478 accumulated= ogg_page_granulepos(&og)-accumulated;
483 /* less than zero? This is a stream with samples trimmed off
484 the beginning, a normal occurrence; set the offset to zero */
485 if(accumulated<0)accumulated=0;
487 vf->pcmlengths[i*2]=accumulated;
490 /* get the PCM length of this link. To do this,
491 get the last page of the stream */
493 ogg_int64_t end=vf->offsets[i+1];
494 ret=_seek_helper(vf,end);
496 /* this should not be possible */
497 vorbis_info_clear(vf->vi+i);
498 vorbis_comment_clear(vf->vc+i);
502 ret=_get_prev_page(vf,&og);
504 /* this should not be possible */
505 vorbis_info_clear(vf->vi+i);
506 vorbis_comment_clear(vf->vc+i);
509 if(ogg_page_granulepos(&og)!=-1){
510 vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
520 static int _make_decode_ready(OggVorbis_File *vf){
521 if(vf->ready_state>STREAMSET)return 0;
522 if(vf->ready_state<STREAMSET)return OV_EFAULT;
524 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
527 if(vorbis_synthesis_init(&vf->vd,vf->vi))
530 vorbis_block_init(&vf->vd,&vf->vb);
531 vf->ready_state=INITSET;
537 static int _open_seekable2(OggVorbis_File *vf){
538 ogg_int64_t dataoffset=vf->offset,end;
539 long *serialno_list=NULL;
543 /* we're partially open and have a first link header state in
545 /* we can seek, so set out learning all about this file */
546 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
547 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
549 /* If seek_func is implemented, tell_func must also be implemented */
550 if(vf->end==-1) return(OV_EINVAL);
552 /* back to beginning, learn all serialnos of first link */
553 ret=ov_raw_seek(vf,0);
555 ret=_get_serialnos(vf,&serialno_list,&serialnos);
558 /* now determine bitstream structure recursively */
559 if(_bisect_forward_serialno(vf,0,0,end+1,serialno_list,serialnos,0)<0)return(OV_EREAD);
560 if(serialno_list)_ogg_free(serialno_list);
562 /* the initial header memory is referenced by vf after; don't free it */
563 _prefetch_all_headers(vf,dataoffset);
564 return(ov_raw_seek(vf,0));
567 /* clear out the current logical bitstream decoder */
568 static void _decode_clear(OggVorbis_File *vf){
569 vorbis_dsp_clear(&vf->vd);
570 vorbis_block_clear(&vf->vb);
571 vf->ready_state=OPENED;
574 /* fetch and process a packet. Handles the case where we're at a
575 bitstream boundary and dumps the decoding machine. If the decoding
576 machine is unloaded, it loads it. It also keeps pcm_offset up to
577 date (seek and read both use this. seek uses a special hack with
580 return: <0) error, OV_HOLE (lost packet) or OV_EOF
581 0) need more data (only if readp==0)
585 static int _fetch_and_process_packet(OggVorbis_File *vf,
591 /* handle one packet. Try to fetch it from current stream state */
592 /* extract packets from page */
595 /* process a packet if we can. If the machine isn't loaded,
597 if(vf->ready_state==INITSET){
600 ogg_packet *op_ptr=(op_in?op_in:&op);
601 int result=ogg_stream_packetout(&vf->os,op_ptr);
602 ogg_int64_t granulepos;
605 if(result==-1)return(OV_HOLE); /* hole in the data. */
607 /* got a packet. process it */
608 granulepos=op_ptr->granulepos;
609 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
611 header packets aren't
614 vorbis_synthesis will
617 /* suck in the synthesis data and track bitrate */
619 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
620 /* for proper use of libvorbis within libvorbisfile,
621 oldsamples will always be zero. */
622 if(oldsamples)return(OV_EFAULT);
624 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
625 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
626 vf->bittrack+=op_ptr->bytes*8;
629 /* update the pcm offset. */
630 if(granulepos!=-1 && !op_ptr->e_o_s){
631 int link=(vf->seekable?vf->current_link:0);
634 /* this packet has a pcm_offset on it (the last packet
635 completed on a page carries the offset) After processing
636 (above), we know the pcm position of the *last* sample
637 ready to be returned. Find the offset of the *first*
639 As an aside, this trick is inaccurate if we begin
640 reading anew right at the last page; the end-of-stream
641 granulepos declares the last frame in the stream, and the
642 last packet of the last page may be a partial frame.
643 So, we need a previous granulepos from an in-sequence page
644 to have a reference point. Thus the !op_ptr->e_o_s clause
647 if(vf->seekable && link>0)
648 granulepos-=vf->pcmlengths[link*2];
649 if(granulepos<0)granulepos=0; /* actually, this
650 shouldn't be possible
651 here unless the stream
654 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
658 granulepos+=vf->pcmlengths[i*2+1];
659 vf->pcm_offset=granulepos;
669 if(vf->ready_state>=OPENED){
673 /* the loop is not strictly necessary, but there's no sense in
674 doing the extra checks of the larger loop for the common
675 case in a multiplexed bistream where the page is simply
676 part of a different logical bitstream; keep reading until
677 we get one with the correct serialno */
680 if((ret=_get_next_page(vf,&og,-1))<0){
681 return(OV_EOF); /* eof. leave unitialized */
684 /* bitrate tracking; add the header's bytes here, the body bytes
685 are done by packet above */
686 vf->bittrack+=og.header_len*8;
688 if(vf->ready_state==INITSET){
689 if(vf->current_serialno!=ogg_page_serialno(&og)){
691 /* two possibilities:
692 1) our decoding just traversed a bitstream boundary
693 2) another stream is multiplexed into this logical section? */
695 if(ogg_page_bos(&og)){
703 vorbis_info_clear(vf->vi);
704 vorbis_comment_clear(vf->vc);
709 continue; /* possibility #2 */
717 /* Do we need to load a new machine before submitting the page? */
718 /* This is different in the seekable and non-seekable cases.
720 In the seekable case, we already have all the header
721 information loaded and cached; we just initialize the machine
722 with it and continue on our merry way.
724 In the non-seekable (streaming) case, we'll only be at a
725 boundary if we just left the previous logical bitstream and
726 we're now nominally at the header of the next bitstream
729 if(vf->ready_state!=INITSET){
732 if(vf->ready_state<STREAMSET){
734 long serialno = ogg_page_serialno(&og);
736 /* match the serialno to bitstream section. We use this rather than
737 offset positions to avoid problems near logical bitstream
740 for(link=0;link<vf->links;link++)
741 if(vf->serialnos[link]==serialno)break;
743 if(link==vf->links) continue; /* not the desired Vorbis
744 bitstream section; keep
747 vf->current_serialno=serialno;
748 vf->current_link=link;
750 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
751 vf->ready_state=STREAMSET;
754 /* we're streaming */
755 /* fetch the three header packets, build the info struct */
757 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
765 int ret=_make_decode_ready(vf);
770 /* the buffered page is the data we want, and we're ready for it;
771 add it to the stream state */
772 ogg_stream_pagein(&vf->os,&og);
777 /* if, eg, 64 bit stdio is configured by default, this will build with
779 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
780 if(f==NULL)return(-1);
781 return fseek(f,off,whence);
784 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
785 long ibytes, ov_callbacks callbacks){
786 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
789 memset(vf,0,sizeof(*vf));
791 vf->callbacks = callbacks;
793 /* init the framing state */
794 ogg_sync_init(&vf->oy);
796 /* perhaps some data was previously read into a buffer for testing
797 against other stream types. Allow initialization from this
798 previously read data (as we may be reading from a non-seekable
801 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
802 memcpy(buffer,initial,ibytes);
803 ogg_sync_wrote(&vf->oy,ibytes);
806 /* can we seek? Stevens suggests the seek test was portable */
807 if(offsettest!=-1)vf->seekable=1;
809 /* No seeking yet; Set up a 'single' (current) logical bitstream
810 entry for partial open */
812 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
813 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
814 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
816 /* Try to fetch the headers, maintaining all the storage */
817 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
821 vf->ready_state=PARTOPEN;
825 static int _ov_open2(OggVorbis_File *vf){
826 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
827 vf->ready_state=OPENED;
829 int ret=_open_seekable2(vf);
836 vf->ready_state=STREAMSET;
842 /* clear out the OggVorbis_File struct */
843 int ov_clear(OggVorbis_File *vf){
845 vorbis_block_clear(&vf->vb);
846 vorbis_dsp_clear(&vf->vd);
847 ogg_stream_clear(&vf->os);
849 if(vf->vi && vf->links){
851 for(i=0;i<vf->links;i++){
852 vorbis_info_clear(vf->vi+i);
853 vorbis_comment_clear(vf->vc+i);
858 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
859 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
860 if(vf->serialnos)_ogg_free(vf->serialnos);
861 if(vf->offsets)_ogg_free(vf->offsets);
862 ogg_sync_clear(&vf->oy);
863 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
864 memset(vf,0,sizeof(*vf));
872 /* inspects the OggVorbis file and finds/documents all the logical
873 bitstreams contained in it. Tries to be tolerant of logical
874 bitstream sections that are truncated/woogie.
880 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
881 ov_callbacks callbacks){
882 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
884 return _ov_open2(vf);
887 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
888 ov_callbacks callbacks = {
889 (size_t (*)(void *, size_t, size_t, void *)) fread,
890 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
891 (int (*)(void *)) fclose,
892 (long (*)(void *)) ftell
895 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
898 /* cheap hack for game usage where downsampling is desirable; there's
899 no need for SRC as we can just do it cheaply in libvorbis. */
901 int ov_halfrate(OggVorbis_File *vf,int flag){
903 if(vf->vi==NULL)return OV_EINVAL;
904 if(!vf->seekable)return OV_EINVAL;
905 if(vf->ready_state>=STREAMSET)
906 _decode_clear(vf); /* clear out stream state; later on libvorbis
907 will be able to swap this on the fly, but
908 for now dumping the decode machine is needed
909 to reinit the MDCT lookups. 1.1 libvorbis
910 is planned to be able to switch on the fly */
912 for(i=0;i<vf->links;i++){
913 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
921 int ov_halfrate_p(OggVorbis_File *vf){
922 if(vf->vi==NULL)return OV_EINVAL;
923 return vorbis_synthesis_halfrate_p(vf->vi);
926 /* Only partially open the vorbis file; test for Vorbisness, and load
927 the headers for the first chain. Do not seek (although test for
928 seekability). Use ov_test_open to finish opening the file, else
929 ov_clear to close/free it. Same return codes as open. */
931 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
932 ov_callbacks callbacks)
934 return _ov_open1(f,vf,initial,ibytes,callbacks);
937 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
938 ov_callbacks callbacks = {
939 (size_t (*)(void *, size_t, size_t, void *)) fread,
940 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
941 (int (*)(void *)) fclose,
942 (long (*)(void *)) ftell
945 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
948 int ov_test_open(OggVorbis_File *vf){
949 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
950 return _ov_open2(vf);
953 /* How many logical bitstreams in this physical bitstream? */
954 long ov_streams(OggVorbis_File *vf){
958 /* Is the FILE * associated with vf seekable? */
959 long ov_seekable(OggVorbis_File *vf){
963 /* returns the bitrate for a given logical bitstream or the entire
964 physical bitstream. If the file is open for random access, it will
965 find the *actual* average bitrate. If the file is streaming, it
966 returns the nominal bitrate (if set) else the average of the
967 upper/lower bounds (if set) else -1 (unset).
969 If you want the actual bitrate field settings, get them from the
970 vorbis_info structs */
972 long ov_bitrate(OggVorbis_File *vf,int i){
973 if(vf->ready_state<OPENED)return(OV_EINVAL);
974 if(i>=vf->links)return(OV_EINVAL);
975 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
980 for(i=0;i<vf->links;i++)
981 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
982 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
983 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
984 * so this is slightly transformed to make it work.
986 br = bits/ov_time_total(vf,-1);
990 /* return the actual bitrate */
991 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
993 /* return nominal if set */
994 if(vf->vi[i].bitrate_nominal>0){
995 return vf->vi[i].bitrate_nominal;
997 if(vf->vi[i].bitrate_upper>0){
998 if(vf->vi[i].bitrate_lower>0){
999 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1001 return vf->vi[i].bitrate_upper;
1010 /* returns the actual bitrate since last call. returns -1 if no
1011 additional data to offer since last call (or at beginning of stream),
1012 EINVAL if stream is only partially open
1014 long ov_bitrate_instant(OggVorbis_File *vf){
1015 int link=(vf->seekable?vf->current_link:0);
1017 if(vf->ready_state<OPENED)return(OV_EINVAL);
1018 if(vf->samptrack==0)return(OV_FALSE);
1019 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1026 long ov_serialnumber(OggVorbis_File *vf,int i){
1027 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1028 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1030 return(vf->current_serialno);
1032 return(vf->serialnos[i]);
1036 /* returns: total raw (compressed) length of content if i==-1
1037 raw (compressed) length of that logical bitstream for i==0 to n
1038 OV_EINVAL if the stream is not seekable (we can't know the length)
1039 or if stream is only partially open
1041 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1042 if(vf->ready_state<OPENED)return(OV_EINVAL);
1043 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1047 for(i=0;i<vf->links;i++)
1048 acc+=ov_raw_total(vf,i);
1051 return(vf->offsets[i+1]-vf->offsets[i]);
1055 /* returns: total PCM length (samples) of content if i==-1 PCM length
1056 (samples) of that logical bitstream for i==0 to n
1057 OV_EINVAL if the stream is not seekable (we can't know the
1058 length) or only partially open
1060 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1061 if(vf->ready_state<OPENED)return(OV_EINVAL);
1062 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1066 for(i=0;i<vf->links;i++)
1067 acc+=ov_pcm_total(vf,i);
1070 return(vf->pcmlengths[i*2+1]);
1074 /* returns: total seconds of content if i==-1
1075 seconds in that logical bitstream for i==0 to n
1076 OV_EINVAL if the stream is not seekable (we can't know the
1077 length) or only partially open
1079 double ov_time_total(OggVorbis_File *vf,int i){
1080 if(vf->ready_state<OPENED)return(OV_EINVAL);
1081 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1085 for(i=0;i<vf->links;i++)
1086 acc+=ov_time_total(vf,i);
1089 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1093 /* seek to an offset relative to the *compressed* data. This also
1094 scans packets to update the PCM cursor. It will cross a logical
1095 bitstream boundary, but only if it can't get any packets out of the
1096 tail of the bitstream we seek to (so no surprises).
1098 returns zero on success, nonzero on failure */
1100 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1101 ogg_stream_state work_os;
1104 if(vf->ready_state<OPENED)return(OV_EINVAL);
1106 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1108 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1110 /* don't yet clear out decoding machine (if it's initialized), in
1111 the case we're in the same link. Restart the decode lapping, and
1112 let _fetch_and_process_packet deal with a potential bitstream
1115 ogg_stream_reset_serialno(&vf->os,
1116 vf->current_serialno); /* must set serialno */
1117 vorbis_synthesis_restart(&vf->vd);
1119 ret=_seek_helper(vf,pos);
1122 /* we need to make sure the pcm_offset is set, but we don't want to
1123 advance the raw cursor past good packets just to get to the first
1124 with a granulepos. That's not equivalent behavior to beginning
1125 decoding as immediately after the seek position as possible.
1127 So, a hack. We use two stream states; a local scratch state and
1128 the shared vf->os stream state. We use the local state to
1129 scan, and the shared state as a buffer for later decode.
1131 Unfortuantely, on the last page we still advance to last packet
1132 because the granulepos on the last page is not necessarily on a
1133 packet boundary, and we need to make sure the granpos is
1145 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1146 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1147 return from not necessarily
1148 starting from the beginning */
1151 if(vf->ready_state>=STREAMSET){
1152 /* snarf/scan a packet if we can */
1153 int result=ogg_stream_packetout(&work_os,&op);
1157 if(vf->vi[vf->current_link].codec_setup){
1158 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1160 ogg_stream_packetout(&vf->os,NULL);
1165 ogg_stream_packetout(&vf->os,NULL);
1167 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1170 if(op.granulepos!=-1){
1171 int i,link=vf->current_link;
1172 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1173 if(granulepos<0)granulepos=0;
1176 granulepos+=vf->pcmlengths[i*2+1];
1177 vf->pcm_offset=granulepos-accblock;
1180 lastblock=thisblock;
1183 ogg_stream_packetout(&vf->os,NULL);
1188 if(_get_next_page(vf,&og,-1)<0){
1189 vf->pcm_offset=ov_pcm_total(vf,-1);
1193 /* huh? Bogus stream with packets but no granulepos */
1198 /* has our decoding just traversed a bitstream boundary? */
1199 if(vf->ready_state>=STREAMSET)
1200 if(vf->current_serialno!=ogg_page_serialno(&og)){
1201 _decode_clear(vf); /* clear out stream state */
1202 ogg_stream_clear(&work_os);
1205 if(vf->ready_state<STREAMSET){
1208 vf->current_serialno=ogg_page_serialno(&og);
1209 for(link=0;link<vf->links;link++)
1210 if(vf->serialnos[link]==vf->current_serialno)break;
1211 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1213 machine uninitialized */
1214 vf->current_link=link;
1216 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1217 ogg_stream_reset_serialno(&work_os,vf->current_serialno);
1218 vf->ready_state=STREAMSET;
1222 ogg_stream_pagein(&vf->os,&og);
1223 ogg_stream_pagein(&work_os,&og);
1224 eosflag=ogg_page_eos(&og);
1228 ogg_stream_clear(&work_os);
1234 /* dump the machine so we're in a known state */
1236 ogg_stream_clear(&work_os);
1241 /* Page granularity seek (faster than sample granularity because we
1242 don't do the last bit of decode to find a specific sample).
1244 Seek to the last [granule marked] page preceeding the specified pos
1245 location, such that decoding past the returned point will quickly
1246 arrive at the requested position. */
1247 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1249 ogg_int64_t result=0;
1250 ogg_int64_t total=ov_pcm_total(vf,-1);
1252 if(vf->ready_state<OPENED)return(OV_EINVAL);
1253 if(!vf->seekable)return(OV_ENOSEEK);
1255 if(pos<0 || pos>total)return(OV_EINVAL);
1257 /* which bitstream section does this pcm offset occur in? */
1258 for(link=vf->links-1;link>=0;link--){
1259 total-=vf->pcmlengths[link*2+1];
1260 if(pos>=total)break;
1263 /* search within the logical bitstream for the page with the highest
1264 pcm_pos preceeding (or equal to) pos. There is a danger here;
1265 missing pages or incorrect frame number information in the
1266 bitstream could make our task impossible. Account for that (it
1267 would be an error condition) */
1269 /* new search algorithm by HB (Nicholas Vinen) */
1271 ogg_int64_t end=vf->offsets[link+1];
1272 ogg_int64_t begin=vf->offsets[link];
1273 ogg_int64_t begintime = vf->pcmlengths[link*2];
1274 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1275 ogg_int64_t target=pos-total+begintime;
1276 ogg_int64_t best=begin;
1282 if(end-begin<CHUNKSIZE){
1285 /* take a (pretty decent) guess. */
1287 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1292 result=_seek_helper(vf,bisect);
1293 if(result) goto seek_error;
1296 result=_get_next_page(vf,&og,end-vf->offset);
1297 if(result==OV_EREAD) goto seek_error;
1300 end=begin; /* found it */
1302 if(bisect==0) goto seek_error;
1304 if(bisect<=begin)bisect=begin+1;
1305 result=_seek_helper(vf,bisect);
1306 if(result) goto seek_error;
1309 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1310 if(granulepos==-1)continue;
1311 if(granulepos<target){
1312 best=result; /* raw offset of packet with granulepos */
1313 begin=vf->offset; /* raw offset of next page */
1314 begintime=granulepos;
1316 if(target-begintime>44100)break;
1317 bisect=begin; /* *not* begin + 1 */
1320 end=begin; /* found it */
1322 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1324 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1325 if(bisect<=begin)bisect=begin+1;
1326 result=_seek_helper(vf,bisect);
1327 if(result) goto seek_error;
1339 /* found our page. seek to it, update pcm offset. Easier case than
1340 raw_seek, don't keep packets preceeding granulepos. */
1346 result=_seek_helper(vf,best);
1348 if(result) goto seek_error;
1349 result=_get_next_page(vf,&og,-1);
1350 if(result<0) goto seek_error;
1352 if(link!=vf->current_link){
1353 /* Different link; dump entire decode machine */
1356 vf->current_link=link;
1357 vf->current_serialno=ogg_page_serialno(&og);
1358 vf->ready_state=STREAMSET;
1361 vorbis_synthesis_restart(&vf->vd);
1364 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1365 ogg_stream_pagein(&vf->os,&og);
1367 /* pull out all but last packet; the one with granulepos */
1369 result=ogg_stream_packetpeek(&vf->os,&op);
1371 /* !!! the packet finishing this page originated on a
1372 preceeding page. Keep fetching previous pages until we
1373 get one with a granulepos or without the 'continued' flag
1374 set. Then just use raw_seek for simplicity. */
1376 result=_seek_helper(vf,best);
1377 if(result<0) goto seek_error;
1380 result=_get_prev_page(vf,&og);
1381 if(result<0) goto seek_error;
1382 if(ogg_page_granulepos(&og)>-1 ||
1383 !ogg_page_continued(&og)){
1384 return ov_raw_seek(vf,result);
1390 result = OV_EBADPACKET;
1393 if(op.granulepos!=-1){
1394 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1395 if(vf->pcm_offset<0)vf->pcm_offset=0;
1396 vf->pcm_offset+=total;
1399 result=ogg_stream_packetout(&vf->os,NULL);
1405 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1414 /* dump machine so we're in a known state */
1420 /* seek to a sample offset relative to the decompressed pcm stream
1421 returns zero on success, nonzero on failure */
1423 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1424 int thisblock,lastblock=0;
1425 int ret=ov_pcm_seek_page(vf,pos);
1426 if(ret<0)return(ret);
1427 if((ret=_make_decode_ready(vf)))return ret;
1429 /* discard leading packets we don't need for the lapping of the
1430 position we want; don't decode them */
1436 int ret=ogg_stream_packetpeek(&vf->os,&op);
1438 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1440 ogg_stream_packetout(&vf->os,NULL);
1441 continue; /* non audio packet */
1443 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1445 if(vf->pcm_offset+((thisblock+
1446 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1448 /* remove the packet from packet queue and track its granulepos */
1449 ogg_stream_packetout(&vf->os,NULL);
1450 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1453 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1455 /* end of logical stream case is hard, especially with exact
1456 length positioning. */
1458 if(op.granulepos>-1){
1460 /* always believe the stream markers */
1461 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1462 if(vf->pcm_offset<0)vf->pcm_offset=0;
1463 for(i=0;i<vf->current_link;i++)
1464 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1467 lastblock=thisblock;
1470 if(ret<0 && ret!=OV_HOLE)break;
1472 /* suck in a new page */
1473 if(_get_next_page(vf,&og,-1)<0)break;
1474 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1476 if(vf->ready_state<STREAMSET){
1479 vf->current_serialno=ogg_page_serialno(&og);
1480 for(link=0;link<vf->links;link++)
1481 if(vf->serialnos[link]==vf->current_serialno)break;
1482 if(link==vf->links)return(OV_EBADLINK);
1483 vf->current_link=link;
1485 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1486 vf->ready_state=STREAMSET;
1487 ret=_make_decode_ready(vf);
1492 ogg_stream_pagein(&vf->os,&og);
1498 /* discard samples until we reach the desired position. Crossing a
1499 logical bitstream boundary with abandon is OK. */
1500 while(vf->pcm_offset<pos){
1501 ogg_int64_t target=pos-vf->pcm_offset;
1502 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1504 if(samples>target)samples=target;
1505 vorbis_synthesis_read(&vf->vd,samples);
1506 vf->pcm_offset+=samples;
1509 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1510 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1515 /* seek to a playback time relative to the decompressed pcm stream
1516 returns zero on success, nonzero on failure */
1517 int ov_time_seek(OggVorbis_File *vf,double seconds){
1518 /* translate time to PCM position and call ov_pcm_seek */
1521 ogg_int64_t pcm_total=0;
1522 double time_total=0.;
1524 if(vf->ready_state<OPENED)return(OV_EINVAL);
1525 if(!vf->seekable)return(OV_ENOSEEK);
1526 if(seconds<0)return(OV_EINVAL);
1528 /* which bitstream section does this time offset occur in? */
1529 for(link=0;link<vf->links;link++){
1530 double addsec = ov_time_total(vf,link);
1531 if(seconds<time_total+addsec)break;
1533 pcm_total+=vf->pcmlengths[link*2+1];
1536 if(link==vf->links)return(OV_EINVAL);
1538 /* enough information to convert time offset to pcm offset */
1540 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1541 return(ov_pcm_seek(vf,target));
1545 /* page-granularity version of ov_time_seek
1546 returns zero on success, nonzero on failure */
1547 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1548 /* translate time to PCM position and call ov_pcm_seek */
1551 ogg_int64_t pcm_total=0;
1552 double time_total=0.;
1554 if(vf->ready_state<OPENED)return(OV_EINVAL);
1555 if(!vf->seekable)return(OV_ENOSEEK);
1556 if(seconds<0)return(OV_EINVAL);
1558 /* which bitstream section does this time offset occur in? */
1559 for(link=0;link<vf->links;link++){
1560 double addsec = ov_time_total(vf,link);
1561 if(seconds<time_total+addsec)break;
1563 pcm_total+=vf->pcmlengths[link*2+1];
1566 if(link==vf->links)return(OV_EINVAL);
1568 /* enough information to convert time offset to pcm offset */
1570 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1571 return(ov_pcm_seek_page(vf,target));
1575 /* tell the current stream offset cursor. Note that seek followed by
1576 tell will likely not give the set offset due to caching */
1577 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1578 if(vf->ready_state<OPENED)return(OV_EINVAL);
1582 /* return PCM offset (sample) of next PCM sample to be read */
1583 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1584 if(vf->ready_state<OPENED)return(OV_EINVAL);
1585 return(vf->pcm_offset);
1588 /* return time offset (seconds) of next PCM sample to be read */
1589 double ov_time_tell(OggVorbis_File *vf){
1591 ogg_int64_t pcm_total=0;
1592 double time_total=0.f;
1594 if(vf->ready_state<OPENED)return(OV_EINVAL);
1596 pcm_total=ov_pcm_total(vf,-1);
1597 time_total=ov_time_total(vf,-1);
1599 /* which bitstream section does this time offset occur in? */
1600 for(link=vf->links-1;link>=0;link--){
1601 pcm_total-=vf->pcmlengths[link*2+1];
1602 time_total-=ov_time_total(vf,link);
1603 if(vf->pcm_offset>=pcm_total)break;
1607 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1610 /* link: -1) return the vorbis_info struct for the bitstream section
1611 currently being decoded
1612 0-n) to request information for a specific bitstream section
1614 In the case of a non-seekable bitstream, any call returns the
1615 current bitstream. NULL in the case that the machine is not
1618 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1621 if(vf->ready_state>=STREAMSET)
1622 return vf->vi+vf->current_link;
1635 /* grr, strong typing, grr, no templates/inheritence, grr */
1636 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1639 if(vf->ready_state>=STREAMSET)
1640 return vf->vc+vf->current_link;
1653 static int host_is_big_endian() {
1654 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1655 unsigned char *bytewise = (unsigned char *)&pattern;
1656 if (bytewise[0] == 0xfe) return 1;
1660 /* up to this point, everything could more or less hide the multiple
1661 logical bitstream nature of chaining from the toplevel application
1662 if the toplevel application didn't particularly care. However, at
1663 the point that we actually read audio back, the multiple-section
1664 nature must surface: Multiple bitstream sections do not necessarily
1665 have to have the same number of channels or sampling rate.
1667 ov_read returns the sequential logical bitstream number currently
1668 being decoded along with the PCM data in order that the toplevel
1669 application can take action on channel/sample rate changes. This
1670 number will be incremented even for streamed (non-seekable) streams
1671 (for seekable streams, it represents the actual logical bitstream
1672 index within the physical bitstream. Note that the accessor
1673 functions above are aware of this dichotomy).
1675 input values: buffer) a buffer to hold packed PCM data for return
1676 length) the byte length requested to be placed into buffer
1677 bigendianp) should the data be packed LSB first (0) or
1679 word) word size for output. currently 1 (byte) or
1682 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1684 n) number of bytes of PCM actually returned. The
1685 below works on a packet-by-packet basis, so the
1686 return length is not related to the 'length' passed
1687 in, just guaranteed to fit.
1689 *section) set to the logical bitstream number */
1691 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1692 int bigendianp,int word,int sgned,int *bitstream){
1694 int host_endian = host_is_big_endian();
1699 if(vf->ready_state<OPENED)return(OV_EINVAL);
1702 if(vf->ready_state==INITSET){
1703 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1707 /* suck in another packet */
1709 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1720 /* yay! proceed to pack data into the byte buffer */
1722 long channels=ov_info(vf,-1)->channels;
1723 long bytespersample=word * channels;
1724 vorbis_fpu_control fpu;
1725 if(samples>length/bytespersample)samples=length/bytespersample;
1730 /* a tight loop to pack each size */
1734 int off=(sgned?0:128);
1735 vorbis_fpu_setround(&fpu);
1736 for(j=0;j<samples;j++)
1737 for(i=0;i<channels;i++){
1738 val=vorbis_ftoi(pcm[i][j]*128.f);
1740 else if(val<-128)val=-128;
1743 vorbis_fpu_restore(fpu);
1745 int off=(sgned?0:32768);
1747 if(host_endian==bigendianp){
1750 vorbis_fpu_setround(&fpu);
1751 for(i=0;i<channels;i++) { /* It's faster in this order */
1753 short *dest=((short *)buffer)+i;
1754 for(j=0;j<samples;j++) {
1755 val=vorbis_ftoi(src[j]*32768.f);
1756 if(val>32767)val=32767;
1757 else if(val<-32768)val=-32768;
1762 vorbis_fpu_restore(fpu);
1766 vorbis_fpu_setround(&fpu);
1767 for(i=0;i<channels;i++) {
1769 short *dest=((short *)buffer)+i;
1770 for(j=0;j<samples;j++) {
1771 val=vorbis_ftoi(src[j]*32768.f);
1772 if(val>32767)val=32767;
1773 else if(val<-32768)val=-32768;
1778 vorbis_fpu_restore(fpu);
1781 }else if(bigendianp){
1783 vorbis_fpu_setround(&fpu);
1784 for(j=0;j<samples;j++)
1785 for(i=0;i<channels;i++){
1786 val=vorbis_ftoi(pcm[i][j]*32768.f);
1787 if(val>32767)val=32767;
1788 else if(val<-32768)val=-32768;
1791 *buffer++=(val&0xff);
1793 vorbis_fpu_restore(fpu);
1797 vorbis_fpu_setround(&fpu);
1798 for(j=0;j<samples;j++)
1799 for(i=0;i<channels;i++){
1800 val=vorbis_ftoi(pcm[i][j]*32768.f);
1801 if(val>32767)val=32767;
1802 else if(val<-32768)val=-32768;
1804 *buffer++=(val&0xff);
1807 vorbis_fpu_restore(fpu);
1813 vorbis_synthesis_read(&vf->vd,samples);
1814 vf->pcm_offset+=samples;
1815 if(bitstream)*bitstream=vf->current_link;
1816 return(samples*bytespersample);
1822 /* input values: pcm_channels) a float vector per channel of output
1823 length) the sample length being read by the app
1825 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1827 n) number of samples of PCM actually returned. The
1828 below works on a packet-by-packet basis, so the
1829 return length is not related to the 'length' passed
1830 in, just guaranteed to fit.
1832 *section) set to the logical bitstream number */
1836 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1839 if(vf->ready_state<OPENED)return(OV_EINVAL);
1842 if(vf->ready_state==INITSET){
1844 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1846 if(pcm_channels)*pcm_channels=pcm;
1847 if(samples>length)samples=length;
1848 vorbis_synthesis_read(&vf->vd,samples);
1849 vf->pcm_offset+=samples;
1850 if(bitstream)*bitstream=vf->current_link;
1856 /* suck in another packet */
1858 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1859 if(ret==OV_EOF)return(0);
1860 if(ret<=0)return(ret);
1866 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1867 extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
1870 static void _ov_splice(float **pcm,float **lappcm,
1873 float *w1, float *w2){
1884 for(j=0;j<ch1 && j<ch2;j++){
1891 d[i]=d[i]*wd + s[i]*ws;
1894 /* window from zero */
1905 /* make sure vf is INITSET */
1906 static int _ov_initset(OggVorbis_File *vf){
1908 if(vf->ready_state==INITSET)break;
1909 /* suck in another packet */
1911 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1912 if(ret<0 && ret!=OV_HOLE)return(ret);
1918 /* make sure vf is INITSET and that we have a primed buffer; if
1919 we're crosslapping at a stream section boundary, this also makes
1920 sure we're sanity checking against the right stream information */
1921 static int _ov_initprime(OggVorbis_File *vf){
1922 vorbis_dsp_state *vd=&vf->vd;
1924 if(vf->ready_state==INITSET)
1925 if(vorbis_synthesis_pcmout(vd,NULL))break;
1927 /* suck in another packet */
1929 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1930 if(ret<0 && ret!=OV_HOLE)return(ret);
1936 /* grab enough data for lapping from vf; this may be in the form of
1937 unreturned, already-decoded pcm, remaining PCM we will need to
1938 decode, or synthetic postextrapolation from last packets. */
1939 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1940 float **lappcm,int lapsize){
1944 /* try first to decode the lapping data */
1945 while(lapcount<lapsize){
1946 int samples=vorbis_synthesis_pcmout(vd,&pcm);
1948 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1949 for(i=0;i<vi->channels;i++)
1950 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1952 vorbis_synthesis_read(vd,samples);
1954 /* suck in another packet */
1955 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
1956 if(ret==OV_EOF)break;
1959 if(lapcount<lapsize){
1960 /* failed to get lapping data from normal decode; pry it from the
1961 postextrapolation buffering, or the second half of the MDCT
1962 from the last packet */
1963 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
1965 for(i=0;i<vi->channels;i++)
1966 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
1969 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1970 for(i=0;i<vi->channels;i++)
1971 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1977 /* this sets up crosslapping of a sample by using trailing data from
1978 sample 1 and lapping it into the windowing buffer of sample 2 */
1979 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
1980 vorbis_info *vi1,*vi2;
1984 int n1,n2,i,ret,hs1,hs2;
1986 if(vf1==vf2)return(0); /* degenerate case */
1987 if(vf1->ready_state<OPENED)return(OV_EINVAL);
1988 if(vf2->ready_state<OPENED)return(OV_EINVAL);
1990 /* the relevant overlap buffers must be pre-checked and pre-primed
1991 before looking at settings in the event that priming would cross
1992 a bitstream boundary. So, do it now */
1994 ret=_ov_initset(vf1);
1996 ret=_ov_initprime(vf2);
1999 vi1=ov_info(vf1,-1);
2000 vi2=ov_info(vf2,-1);
2001 hs1=ov_halfrate_p(vf1);
2002 hs2=ov_halfrate_p(vf2);
2004 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2005 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2006 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2007 w1=vorbis_window(&vf1->vd,0);
2008 w2=vorbis_window(&vf2->vd,0);
2010 for(i=0;i<vi1->channels;i++)
2011 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2013 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2015 /* have a lapping buffer from vf1; now to splice it into the lapping
2017 /* consolidate and expose the buffer. */
2018 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2019 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2020 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2023 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2029 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2030 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2035 int n1,n2,ch1,ch2,hs;
2038 if(vf->ready_state<OPENED)return(OV_EINVAL);
2039 ret=_ov_initset(vf);
2042 hs=ov_halfrate_p(vf);
2045 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2046 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2047 persistent; even if the decode state
2048 from this link gets dumped, this
2049 window array continues to exist */
2051 lappcm=alloca(sizeof(*lappcm)*ch1);
2053 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2054 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2056 /* have lapping data; seek and prime the buffer */
2057 ret=localseek(vf,pos);
2059 ret=_ov_initprime(vf);
2062 /* Guard against cross-link changes; they're perfectly legal */
2065 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2066 w2=vorbis_window(&vf->vd,0);
2068 /* consolidate and expose the buffer. */
2069 vorbis_synthesis_lapout(&vf->vd,&pcm);
2072 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2078 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2079 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2082 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2083 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2086 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2087 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2090 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2091 int (*localseek)(OggVorbis_File *,double)){
2096 int n1,n2,ch1,ch2,hs;
2099 if(vf->ready_state<OPENED)return(OV_EINVAL);
2100 ret=_ov_initset(vf);
2103 hs=ov_halfrate_p(vf);
2106 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2107 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2108 persistent; even if the decode state
2109 from this link gets dumped, this
2110 window array continues to exist */
2112 lappcm=alloca(sizeof(*lappcm)*ch1);
2114 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2115 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2117 /* have lapping data; seek and prime the buffer */
2118 ret=localseek(vf,pos);
2120 ret=_ov_initprime(vf);
2123 /* Guard against cross-link changes; they're perfectly legal */
2126 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2127 w2=vorbis_window(&vf->vd,0);
2129 /* consolidate and expose the buffer. */
2130 vorbis_synthesis_lapout(&vf->vd,&pcm);
2133 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2139 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2140 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2143 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2144 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);