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->offsets[m+1]=searched;
283 ret=_bisect_forward_serialno(vf,next,vf->offset,
284 end,next_serialno_list,next_serialnos,m+1);
288 if(next_serialno_list)_ogg_free(next_serialno_list);
290 vf->offsets[m]=begin;
294 /* uses the local ogg_stream storage in vf; this is important for
295 non-streaming input sources */
296 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
297 long *serialno,ogg_page *og_ptr){
304 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
305 if(llret==OV_EREAD)return(OV_EREAD);
306 if(llret<0)return(OV_ENOTVORBIS);
310 vorbis_info_init(vi);
311 vorbis_comment_init(vc);
313 /* extract the first set of vorbis headers we see in the headerset */
317 /* if we're past the ID headers, we won't be finding a Vorbis
318 stream in this link */
319 if(!ogg_page_bos(og_ptr)){
324 /* prospective stream setup; we need a stream to get packets */
325 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
326 ogg_stream_pagein(&vf->os,og_ptr);
328 if(ogg_stream_packetout(&vf->os,&op) > 0 &&
329 vorbis_synthesis_idheader(&op)){
331 /* continue Vorbis header load; past this point, any error will
332 render this link useless (we won't continue looking for more
334 if(serialno)*serialno=vf->os.serialno;
335 vf->ready_state=STREAMSET;
336 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
340 while(i<2){ /* get a page loop */
342 while(i<2){ /* get a packet loop */
344 int result=ogg_stream_packetout(&vf->os,&op);
351 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
358 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
363 /* if this page belongs to the correct stream, go parse it */
364 if(vf->os.serialno == ogg_page_serialno(og_ptr)){
365 ogg_stream_pagein(&vf->os,og_ptr);
369 /* if we never see the final vorbis headers before the link
371 if(ogg_page_bos(og_ptr)){
379 /* otherwise, keep looking */
386 /* this wasn't vorbis, get next page, try again */
388 ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
389 if(llret==OV_EREAD)return(OV_EREAD);
390 if(llret<0)return(OV_ENOTVORBIS);
395 vorbis_info_clear(vi);
396 vorbis_comment_clear(vc);
397 vf->ready_state=OPENED;
402 /* last step of the OggVorbis_File initialization; get all the
403 vorbis_info structs and PCM positions. Only called by the seekable
404 initialization (local stream storage is hacked slightly; pay
405 attention to how that's done) */
407 /* this is void and does not propogate errors up because we want to be
408 able to open and use damaged bitstreams as well as we can. Just
409 watch out for missing information for links in the OggVorbis_File
411 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
416 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
417 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
418 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
419 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
420 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
422 for(i=0;i<vf->links;i++){
424 /* we already grabbed the initial header earlier. Just set the offset */
425 vf->serialnos[i]=vf->current_serialno;
426 vf->dataoffsets[i]=dataoffset;
427 ret=_seek_helper(vf,dataoffset);
429 vf->dataoffsets[i]=-1;
433 /* seek to the location of the initial header */
435 ret=_seek_helper(vf,vf->offsets[i]);
437 vf->dataoffsets[i]=-1;
439 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,vf->serialnos+i,NULL)<0){
440 vf->dataoffsets[i]=-1;
442 vf->dataoffsets[i]=vf->offset;
447 /* fetch beginning PCM offset */
449 if(vf->dataoffsets[i]!=-1){
450 ogg_int64_t accumulated=0;
454 ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]);
459 ret=_get_next_page(vf,&og,-1);
461 /* this should not be possible unless the file is
465 if(ogg_page_bos(&og)) break;
467 if(ogg_page_serialno(&og)!=vf->serialnos[i])
470 /* count blocksizes of all frames in the page */
471 ogg_stream_pagein(&vf->os,&og);
472 while((result=ogg_stream_packetout(&vf->os,&op))){
473 if(result>0){ /* ignore holes */
474 long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
476 accumulated+=(lastblock+thisblock)>>2;
481 if(ogg_page_granulepos(&og)!=-1){
482 /* pcm offset of last packet on the first audio page */
483 accumulated= ogg_page_granulepos(&og)-accumulated;
488 /* less than zero? This is a stream with samples trimmed off
489 the beginning, a normal occurrence; set the offset to zero */
490 if(accumulated<0)accumulated=0;
492 vf->pcmlengths[i*2]=accumulated;
495 /* get the PCM length of this link. To do this,
496 get the last page of the stream */
498 ogg_int64_t end=vf->offsets[i+1];
499 ret=_seek_helper(vf,end);
501 /* this should not be possible */
502 vorbis_info_clear(vf->vi+i);
503 vorbis_comment_clear(vf->vc+i);
507 ret=_get_prev_page(vf,&og);
509 /* this should not be possible */
510 vorbis_info_clear(vf->vi+i);
511 vorbis_comment_clear(vf->vc+i);
514 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];
528 static int _make_decode_ready(OggVorbis_File *vf){
529 if(vf->ready_state>STREAMSET)return 0;
530 if(vf->ready_state<STREAMSET)return OV_EFAULT;
532 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
535 if(vorbis_synthesis_init(&vf->vd,vf->vi))
538 vorbis_block_init(&vf->vd,&vf->vb);
539 vf->ready_state=INITSET;
545 static int _open_seekable2(OggVorbis_File *vf){
546 ogg_int64_t dataoffset=vf->offset,end;
547 long *serialno_list=NULL;
552 /* we're partially open and have a first link header state in
554 /* we can seek, so set out learning all about this file */
555 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
556 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
558 /* If seek_func is implemented, tell_func must also be implemented */
559 if(vf->end==-1) return(OV_EINVAL);
561 /* We get the offset for the last page of the physical bitstream.
562 Most OggVorbis files will contain a single logical bitstream */
563 end=_get_prev_page(vf,&og);
564 if(end<0)return(end);
566 /* back to beginning, learn all serialnos of first link */
567 ret=_seek_helper(vf,0);
569 ret=_get_serialnos(vf,&serialno_list,&serialnos);
572 /* now determine bitstream structure recursively */
573 if(_bisect_forward_serialno(vf,0,0,end+1,serialno_list,serialnos,0)<0)return(OV_EREAD);
574 if(serialno_list)_ogg_free(serialno_list);
576 /* the initial header memory is referenced by vf after; don't free it */
577 _prefetch_all_headers(vf,dataoffset);
578 return(ov_raw_seek(vf,0));
581 /* clear out the current logical bitstream decoder */
582 static void _decode_clear(OggVorbis_File *vf){
583 vorbis_dsp_clear(&vf->vd);
584 vorbis_block_clear(&vf->vb);
585 vf->ready_state=OPENED;
588 /* fetch and process a packet. Handles the case where we're at a
589 bitstream boundary and dumps the decoding machine. If the decoding
590 machine is unloaded, it loads it. It also keeps pcm_offset up to
591 date (seek and read both use this. seek uses a special hack with
594 return: <0) error, OV_HOLE (lost packet) or OV_EOF
595 0) need more data (only if readp==0)
599 static int _fetch_and_process_packet(OggVorbis_File *vf,
605 /* handle one packet. Try to fetch it from current stream state */
606 /* extract packets from page */
609 /* process a packet if we can. If the machine isn't loaded,
611 if(vf->ready_state==INITSET){
614 ogg_packet *op_ptr=(op_in?op_in:&op);
615 int result=ogg_stream_packetout(&vf->os,op_ptr);
616 ogg_int64_t granulepos;
619 if(result==-1)return(OV_HOLE); /* hole in the data. */
621 /* got a packet. process it */
622 granulepos=op_ptr->granulepos;
623 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
625 header packets aren't
628 vorbis_synthesis will
631 /* suck in the synthesis data and track bitrate */
633 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
634 /* for proper use of libvorbis within libvorbisfile,
635 oldsamples will always be zero. */
636 if(oldsamples)return(OV_EFAULT);
638 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
639 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
640 vf->bittrack+=op_ptr->bytes*8;
643 /* update the pcm offset. */
644 if(granulepos!=-1 && !op_ptr->e_o_s){
645 int link=(vf->seekable?vf->current_link:0);
648 /* this packet has a pcm_offset on it (the last packet
649 completed on a page carries the offset) After processing
650 (above), we know the pcm position of the *last* sample
651 ready to be returned. Find the offset of the *first*
653 As an aside, this trick is inaccurate if we begin
654 reading anew right at the last page; the end-of-stream
655 granulepos declares the last frame in the stream, and the
656 last packet of the last page may be a partial frame.
657 So, we need a previous granulepos from an in-sequence page
658 to have a reference point. Thus the !op_ptr->e_o_s clause
661 if(vf->seekable && link>0)
662 granulepos-=vf->pcmlengths[link*2];
663 if(granulepos<0)granulepos=0; /* actually, this
664 shouldn't be possible
665 here unless the stream
668 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
672 granulepos+=vf->pcmlengths[i*2+1];
673 vf->pcm_offset=granulepos;
683 if(vf->ready_state>=OPENED){
687 /* the loop is not strictly necessary, but there's no sense in
688 doing the extra checks of the larger loop for the common
689 case in a multiplexed bistream where the page is simply
690 part of a different logical bitstream; keep reading until
691 we get one with the correct serialno */
694 if((ret=_get_next_page(vf,&og,-1))<0){
695 return(OV_EOF); /* eof. leave unitialized */
698 /* bitrate tracking; add the header's bytes here, the body bytes
699 are done by packet above */
700 vf->bittrack+=og.header_len*8;
702 if(vf->ready_state==INITSET){
703 if(vf->current_serialno!=ogg_page_serialno(&og)){
705 /* two possibilities:
706 1) our decoding just traversed a bitstream boundary
707 2) another stream is multiplexed into this logical section? */
709 if(ogg_page_bos(&og)){
717 vorbis_info_clear(vf->vi);
718 vorbis_comment_clear(vf->vc);
723 continue; /* possibility #2 */
731 /* Do we need to load a new machine before submitting the page? */
732 /* This is different in the seekable and non-seekable cases.
734 In the seekable case, we already have all the header
735 information loaded and cached; we just initialize the machine
736 with it and continue on our merry way.
738 In the non-seekable (streaming) case, we'll only be at a
739 boundary if we just left the previous logical bitstream and
740 we're now nominally at the header of the next bitstream
743 if(vf->ready_state!=INITSET){
746 if(vf->ready_state<STREAMSET){
748 long serialno = ogg_page_serialno(&og);
750 /* match the serialno to bitstream section. We use this rather than
751 offset positions to avoid problems near logical bitstream
754 for(link=0;link<vf->links;link++)
755 if(vf->serialnos[link]==serialno)break;
757 if(link==vf->links) continue; /* not the desired Vorbis
758 bitstream section; keep
761 vf->current_serialno=serialno;
762 vf->current_link=link;
764 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
765 vf->ready_state=STREAMSET;
768 /* we're streaming */
769 /* fetch the three header packets, build the info struct */
771 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
779 int ret=_make_decode_ready(vf);
784 /* the buffered page is the data we want, and we're ready for it;
785 add it to the stream state */
786 ogg_stream_pagein(&vf->os,&og);
791 /* if, eg, 64 bit stdio is configured by default, this will build with
793 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
794 if(f==NULL)return(-1);
795 return fseek(f,off,whence);
798 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
799 long ibytes, ov_callbacks callbacks){
800 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
803 memset(vf,0,sizeof(*vf));
805 vf->callbacks = callbacks;
807 /* init the framing state */
808 ogg_sync_init(&vf->oy);
810 /* perhaps some data was previously read into a buffer for testing
811 against other stream types. Allow initialization from this
812 previously read data (as we may be reading from a non-seekable
815 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
816 memcpy(buffer,initial,ibytes);
817 ogg_sync_wrote(&vf->oy,ibytes);
820 /* can we seek? Stevens suggests the seek test was portable */
821 if(offsettest!=-1)vf->seekable=1;
823 /* No seeking yet; Set up a 'single' (current) logical bitstream
824 entry for partial open */
826 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
827 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
828 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
830 /* Try to fetch the headers, maintaining all the storage */
831 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
835 vf->ready_state=PARTOPEN;
839 static int _ov_open2(OggVorbis_File *vf){
840 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
841 vf->ready_state=OPENED;
843 int ret=_open_seekable2(vf);
850 vf->ready_state=STREAMSET;
856 /* clear out the OggVorbis_File struct */
857 int ov_clear(OggVorbis_File *vf){
859 vorbis_block_clear(&vf->vb);
860 vorbis_dsp_clear(&vf->vd);
861 ogg_stream_clear(&vf->os);
863 if(vf->vi && vf->links){
865 for(i=0;i<vf->links;i++){
866 vorbis_info_clear(vf->vi+i);
867 vorbis_comment_clear(vf->vc+i);
872 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
873 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
874 if(vf->serialnos)_ogg_free(vf->serialnos);
875 if(vf->offsets)_ogg_free(vf->offsets);
876 ogg_sync_clear(&vf->oy);
877 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
878 memset(vf,0,sizeof(*vf));
886 /* inspects the OggVorbis file and finds/documents all the logical
887 bitstreams contained in it. Tries to be tolerant of logical
888 bitstream sections that are truncated/woogie.
894 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
895 ov_callbacks callbacks){
896 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
898 return _ov_open2(vf);
901 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
902 ov_callbacks callbacks = {
903 (size_t (*)(void *, size_t, size_t, void *)) fread,
904 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
905 (int (*)(void *)) fclose,
906 (long (*)(void *)) ftell
909 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
912 /* cheap hack for game usage where downsampling is desirable; there's
913 no need for SRC as we can just do it cheaply in libvorbis. */
915 int ov_halfrate(OggVorbis_File *vf,int flag){
917 if(vf->vi==NULL)return OV_EINVAL;
918 if(!vf->seekable)return OV_EINVAL;
919 if(vf->ready_state>=STREAMSET)
920 _decode_clear(vf); /* clear out stream state; later on libvorbis
921 will be able to swap this on the fly, but
922 for now dumping the decode machine is needed
923 to reinit the MDCT lookups. 1.1 libvorbis
924 is planned to be able to switch on the fly */
926 for(i=0;i<vf->links;i++){
927 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
935 int ov_halfrate_p(OggVorbis_File *vf){
936 if(vf->vi==NULL)return OV_EINVAL;
937 return vorbis_synthesis_halfrate_p(vf->vi);
940 /* Only partially open the vorbis file; test for Vorbisness, and load
941 the headers for the first chain. Do not seek (although test for
942 seekability). Use ov_test_open to finish opening the file, else
943 ov_clear to close/free it. Same return codes as open. */
945 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
946 ov_callbacks callbacks)
948 return _ov_open1(f,vf,initial,ibytes,callbacks);
951 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
952 ov_callbacks callbacks = {
953 (size_t (*)(void *, size_t, size_t, void *)) fread,
954 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
955 (int (*)(void *)) fclose,
956 (long (*)(void *)) ftell
959 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
962 int ov_test_open(OggVorbis_File *vf){
963 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
964 return _ov_open2(vf);
967 /* How many logical bitstreams in this physical bitstream? */
968 long ov_streams(OggVorbis_File *vf){
972 /* Is the FILE * associated with vf seekable? */
973 long ov_seekable(OggVorbis_File *vf){
977 /* returns the bitrate for a given logical bitstream or the entire
978 physical bitstream. If the file is open for random access, it will
979 find the *actual* average bitrate. If the file is streaming, it
980 returns the nominal bitrate (if set) else the average of the
981 upper/lower bounds (if set) else -1 (unset).
983 If you want the actual bitrate field settings, get them from the
984 vorbis_info structs */
986 long ov_bitrate(OggVorbis_File *vf,int i){
987 if(vf->ready_state<OPENED)return(OV_EINVAL);
988 if(i>=vf->links)return(OV_EINVAL);
989 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
994 for(i=0;i<vf->links;i++)
995 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
996 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
997 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
998 * so this is slightly transformed to make it work.
1000 br = bits/ov_time_total(vf,-1);
1004 /* return the actual bitrate */
1005 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
1007 /* return nominal if set */
1008 if(vf->vi[i].bitrate_nominal>0){
1009 return vf->vi[i].bitrate_nominal;
1011 if(vf->vi[i].bitrate_upper>0){
1012 if(vf->vi[i].bitrate_lower>0){
1013 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1015 return vf->vi[i].bitrate_upper;
1024 /* returns the actual bitrate since last call. returns -1 if no
1025 additional data to offer since last call (or at beginning of stream),
1026 EINVAL if stream is only partially open
1028 long ov_bitrate_instant(OggVorbis_File *vf){
1029 int link=(vf->seekable?vf->current_link:0);
1031 if(vf->ready_state<OPENED)return(OV_EINVAL);
1032 if(vf->samptrack==0)return(OV_FALSE);
1033 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1040 long ov_serialnumber(OggVorbis_File *vf,int i){
1041 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1042 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1044 return(vf->current_serialno);
1046 return(vf->serialnos[i]);
1050 /* returns: total raw (compressed) length of content if i==-1
1051 raw (compressed) length of that logical bitstream for i==0 to n
1052 OV_EINVAL if the stream is not seekable (we can't know the length)
1053 or if stream is only partially open
1055 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1056 if(vf->ready_state<OPENED)return(OV_EINVAL);
1057 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1061 for(i=0;i<vf->links;i++)
1062 acc+=ov_raw_total(vf,i);
1065 return(vf->offsets[i+1]-vf->offsets[i]);
1069 /* returns: total PCM length (samples) of content if i==-1 PCM length
1070 (samples) of that logical bitstream for i==0 to n
1071 OV_EINVAL if the stream is not seekable (we can't know the
1072 length) or only partially open
1074 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1075 if(vf->ready_state<OPENED)return(OV_EINVAL);
1076 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1080 for(i=0;i<vf->links;i++)
1081 acc+=ov_pcm_total(vf,i);
1084 return(vf->pcmlengths[i*2+1]);
1088 /* returns: total seconds of content if i==-1
1089 seconds in that logical bitstream for i==0 to n
1090 OV_EINVAL if the stream is not seekable (we can't know the
1091 length) or only partially open
1093 double ov_time_total(OggVorbis_File *vf,int i){
1094 if(vf->ready_state<OPENED)return(OV_EINVAL);
1095 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1099 for(i=0;i<vf->links;i++)
1100 acc+=ov_time_total(vf,i);
1103 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1107 /* seek to an offset relative to the *compressed* data. This also
1108 scans packets to update the PCM cursor. It will cross a logical
1109 bitstream boundary, but only if it can't get any packets out of the
1110 tail of the bitstream we seek to (so no surprises).
1112 returns zero on success, nonzero on failure */
1114 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1115 ogg_stream_state work_os;
1118 if(vf->ready_state<OPENED)return(OV_EINVAL);
1120 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1122 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1124 /* don't yet clear out decoding machine (if it's initialized), in
1125 the case we're in the same link. Restart the decode lapping, and
1126 let _fetch_and_process_packet deal with a potential bitstream
1129 ogg_stream_reset_serialno(&vf->os,
1130 vf->current_serialno); /* must set serialno */
1131 vorbis_synthesis_restart(&vf->vd);
1133 ret=_seek_helper(vf,pos);
1136 /* we need to make sure the pcm_offset is set, but we don't want to
1137 advance the raw cursor past good packets just to get to the first
1138 with a granulepos. That's not equivalent behavior to beginning
1139 decoding as immediately after the seek position as possible.
1141 So, a hack. We use two stream states; a local scratch state and
1142 the shared vf->os stream state. We use the local state to
1143 scan, and the shared state as a buffer for later decode.
1145 Unfortuantely, on the last page we still advance to last packet
1146 because the granulepos on the last page is not necessarily on a
1147 packet boundary, and we need to make sure the granpos is
1159 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1160 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1161 return from not necessarily
1162 starting from the beginning */
1165 if(vf->ready_state>=STREAMSET){
1166 /* snarf/scan a packet if we can */
1167 int result=ogg_stream_packetout(&work_os,&op);
1171 if(vf->vi[vf->current_link].codec_setup){
1172 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1174 ogg_stream_packetout(&vf->os,NULL);
1179 ogg_stream_packetout(&vf->os,NULL);
1181 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1184 if(op.granulepos!=-1){
1185 int i,link=vf->current_link;
1186 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1187 if(granulepos<0)granulepos=0;
1190 granulepos+=vf->pcmlengths[i*2+1];
1191 vf->pcm_offset=granulepos-accblock;
1194 lastblock=thisblock;
1197 ogg_stream_packetout(&vf->os,NULL);
1202 if(_get_next_page(vf,&og,-1)<0){
1203 vf->pcm_offset=ov_pcm_total(vf,-1);
1207 /* huh? Bogus stream with packets but no granulepos */
1212 /* has our decoding just traversed a bitstream boundary? */
1213 if(vf->ready_state>=STREAMSET){
1214 if(vf->current_serialno!=ogg_page_serialno(&og)){
1216 /* two possibilities:
1217 1) our decoding just traversed a bitstream boundary
1218 2) another stream is multiplexed into this logical section? */
1220 if(ogg_page_bos(&og)){
1222 _decode_clear(vf); /* clear out stream state */
1223 ogg_stream_clear(&work_os);
1224 } /* else, do nothing; next loop will scoop another page */
1228 if(vf->ready_state<STREAMSET){
1230 long serialno = ogg_page_serialno(&og);
1232 for(link=0;link<vf->links;link++)
1233 if(vf->serialnos[link]==serialno)break;
1235 if(link==vf->links) continue; /* not the desired Vorbis
1236 bitstream section; keep
1238 vf->current_link=link;
1239 vf->current_serialno=serialno;
1240 ogg_stream_reset_serialno(&vf->os,serialno);
1241 ogg_stream_reset_serialno(&work_os,serialno);
1242 vf->ready_state=STREAMSET;
1246 ogg_stream_pagein(&vf->os,&og);
1247 ogg_stream_pagein(&work_os,&og);
1248 eosflag=ogg_page_eos(&og);
1252 ogg_stream_clear(&work_os);
1258 /* dump the machine so we're in a known state */
1260 ogg_stream_clear(&work_os);
1265 /* Page granularity seek (faster than sample granularity because we
1266 don't do the last bit of decode to find a specific sample).
1268 Seek to the last [granule marked] page preceeding the specified pos
1269 location, such that decoding past the returned point will quickly
1270 arrive at the requested position. */
1271 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1273 ogg_int64_t result=0;
1274 ogg_int64_t total=ov_pcm_total(vf,-1);
1276 if(vf->ready_state<OPENED)return(OV_EINVAL);
1277 if(!vf->seekable)return(OV_ENOSEEK);
1279 if(pos<0 || pos>total)return(OV_EINVAL);
1281 /* which bitstream section does this pcm offset occur in? */
1282 for(link=vf->links-1;link>=0;link--){
1283 total-=vf->pcmlengths[link*2+1];
1284 if(pos>=total)break;
1287 /* search within the logical bitstream for the page with the highest
1288 pcm_pos preceeding (or equal to) pos. There is a danger here;
1289 missing pages or incorrect frame number information in the
1290 bitstream could make our task impossible. Account for that (it
1291 would be an error condition) */
1293 /* new search algorithm by HB (Nicholas Vinen) */
1295 ogg_int64_t end=vf->offsets[link+1];
1296 ogg_int64_t begin=vf->offsets[link];
1297 ogg_int64_t begintime = vf->pcmlengths[link*2];
1298 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1299 ogg_int64_t target=pos-total+begintime;
1300 ogg_int64_t best=begin;
1306 if(end-begin<CHUNKSIZE){
1309 /* take a (pretty decent) guess. */
1311 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1316 result=_seek_helper(vf,bisect);
1317 if(result) goto seek_error;
1320 result=_get_next_page(vf,&og,end-vf->offset);
1321 if(result==OV_EREAD) goto seek_error;
1324 end=begin; /* found it */
1326 if(bisect==0) goto seek_error;
1328 if(bisect<=begin)bisect=begin+1;
1329 result=_seek_helper(vf,bisect);
1330 if(result) goto seek_error;
1333 ogg_int64_t granulepos;
1335 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1338 granulepos=ogg_page_granulepos(&og);
1339 if(granulepos==-1)continue;
1341 if(granulepos<target){
1342 best=result; /* raw offset of packet with granulepos */
1343 begin=vf->offset; /* raw offset of next page */
1344 begintime=granulepos;
1346 if(target-begintime>44100)break;
1347 bisect=begin; /* *not* begin + 1 */
1350 end=begin; /* found it */
1352 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1354 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1355 if(bisect<=begin)bisect=begin+1;
1356 result=_seek_helper(vf,bisect);
1357 if(result) goto seek_error;
1369 /* found our page. seek to it, update pcm offset. Easier case than
1370 raw_seek, don't keep packets preceeding granulepos. */
1376 result=_seek_helper(vf,best);
1378 if(result) goto seek_error;
1379 result=_get_next_page(vf,&og,-1);
1380 if(result<0) goto seek_error;
1382 if(link!=vf->current_link){
1383 /* Different link; dump entire decode machine */
1386 vf->current_link=link;
1387 vf->current_serialno=vf->serialnos[link];
1388 vf->ready_state=STREAMSET;
1391 vorbis_synthesis_restart(&vf->vd);
1394 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1395 ogg_stream_pagein(&vf->os,&og);
1397 /* pull out all but last packet; the one with granulepos */
1399 result=ogg_stream_packetpeek(&vf->os,&op);
1401 /* !!! the packet finishing this page originated on a
1402 preceeding page. Keep fetching previous pages until we
1403 get one with a granulepos or without the 'continued' flag
1404 set. Then just use raw_seek for simplicity. */
1406 result=_seek_helper(vf,best);
1407 if(result<0) goto seek_error;
1410 result=_get_prev_page(vf,&og);
1411 if(result<0) goto seek_error;
1412 if(ogg_page_serialno(&og)==vf->current_serialno &&
1413 (ogg_page_granulepos(&og)>-1 ||
1414 !ogg_page_continued(&og))){
1415 return ov_raw_seek(vf,result);
1421 result = OV_EBADPACKET;
1424 if(op.granulepos!=-1){
1425 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1426 if(vf->pcm_offset<0)vf->pcm_offset=0;
1427 vf->pcm_offset+=total;
1430 result=ogg_stream_packetout(&vf->os,NULL);
1436 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1445 /* dump machine so we're in a known state */
1451 /* seek to a sample offset relative to the decompressed pcm stream
1452 returns zero on success, nonzero on failure */
1454 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1455 int thisblock,lastblock=0;
1456 int ret=ov_pcm_seek_page(vf,pos);
1457 if(ret<0)return(ret);
1458 if((ret=_make_decode_ready(vf)))return ret;
1460 /* discard leading packets we don't need for the lapping of the
1461 position we want; don't decode them */
1467 int ret=ogg_stream_packetpeek(&vf->os,&op);
1469 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1471 ogg_stream_packetout(&vf->os,NULL);
1472 continue; /* non audio packet */
1474 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1476 if(vf->pcm_offset+((thisblock+
1477 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1479 /* remove the packet from packet queue and track its granulepos */
1480 ogg_stream_packetout(&vf->os,NULL);
1481 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1484 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1486 /* end of logical stream case is hard, especially with exact
1487 length positioning. */
1489 if(op.granulepos>-1){
1491 /* always believe the stream markers */
1492 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1493 if(vf->pcm_offset<0)vf->pcm_offset=0;
1494 for(i=0;i<vf->current_link;i++)
1495 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1498 lastblock=thisblock;
1501 if(ret<0 && ret!=OV_HOLE)break;
1503 /* suck in a new page */
1504 if(_get_next_page(vf,&og,-1)<0)break;
1505 if(ogg_page_bos(&og))_decode_clear(vf);
1507 if(vf->ready_state<STREAMSET){
1508 long serialno=ogg_page_serialno(&og);
1511 for(link=0;link<vf->links;link++)
1512 if(vf->serialnos[link]==serialno)break;
1513 if(link==vf->links) continue;
1514 vf->current_link=link;
1516 vf->ready_state=STREAMSET;
1517 vf->current_serialno=ogg_page_serialno(&og);
1518 ogg_stream_reset_serialno(&vf->os,serialno);
1519 ret=_make_decode_ready(vf);
1524 ogg_stream_pagein(&vf->os,&og);
1530 /* discard samples until we reach the desired position. Crossing a
1531 logical bitstream boundary with abandon is OK. */
1532 while(vf->pcm_offset<pos){
1533 ogg_int64_t target=pos-vf->pcm_offset;
1534 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1536 if(samples>target)samples=target;
1537 vorbis_synthesis_read(&vf->vd,samples);
1538 vf->pcm_offset+=samples;
1541 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1542 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1547 /* seek to a playback time relative to the decompressed pcm stream
1548 returns zero on success, nonzero on failure */
1549 int ov_time_seek(OggVorbis_File *vf,double seconds){
1550 /* translate time to PCM position and call ov_pcm_seek */
1553 ogg_int64_t pcm_total=0;
1554 double time_total=0.;
1556 if(vf->ready_state<OPENED)return(OV_EINVAL);
1557 if(!vf->seekable)return(OV_ENOSEEK);
1558 if(seconds<0)return(OV_EINVAL);
1560 /* which bitstream section does this time offset occur in? */
1561 for(link=0;link<vf->links;link++){
1562 double addsec = ov_time_total(vf,link);
1563 if(seconds<time_total+addsec)break;
1565 pcm_total+=vf->pcmlengths[link*2+1];
1568 if(link==vf->links)return(OV_EINVAL);
1570 /* enough information to convert time offset to pcm offset */
1572 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1573 return(ov_pcm_seek(vf,target));
1577 /* page-granularity version of ov_time_seek
1578 returns zero on success, nonzero on failure */
1579 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1580 /* translate time to PCM position and call ov_pcm_seek */
1583 ogg_int64_t pcm_total=0;
1584 double time_total=0.;
1586 if(vf->ready_state<OPENED)return(OV_EINVAL);
1587 if(!vf->seekable)return(OV_ENOSEEK);
1588 if(seconds<0)return(OV_EINVAL);
1590 /* which bitstream section does this time offset occur in? */
1591 for(link=0;link<vf->links;link++){
1592 double addsec = ov_time_total(vf,link);
1593 if(seconds<time_total+addsec)break;
1595 pcm_total+=vf->pcmlengths[link*2+1];
1598 if(link==vf->links)return(OV_EINVAL);
1600 /* enough information to convert time offset to pcm offset */
1602 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1603 return(ov_pcm_seek_page(vf,target));
1607 /* tell the current stream offset cursor. Note that seek followed by
1608 tell will likely not give the set offset due to caching */
1609 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1610 if(vf->ready_state<OPENED)return(OV_EINVAL);
1614 /* return PCM offset (sample) of next PCM sample to be read */
1615 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1616 if(vf->ready_state<OPENED)return(OV_EINVAL);
1617 return(vf->pcm_offset);
1620 /* return time offset (seconds) of next PCM sample to be read */
1621 double ov_time_tell(OggVorbis_File *vf){
1623 ogg_int64_t pcm_total=0;
1624 double time_total=0.f;
1626 if(vf->ready_state<OPENED)return(OV_EINVAL);
1628 pcm_total=ov_pcm_total(vf,-1);
1629 time_total=ov_time_total(vf,-1);
1631 /* which bitstream section does this time offset occur in? */
1632 for(link=vf->links-1;link>=0;link--){
1633 pcm_total-=vf->pcmlengths[link*2+1];
1634 time_total-=ov_time_total(vf,link);
1635 if(vf->pcm_offset>=pcm_total)break;
1639 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1642 /* link: -1) return the vorbis_info struct for the bitstream section
1643 currently being decoded
1644 0-n) to request information for a specific bitstream section
1646 In the case of a non-seekable bitstream, any call returns the
1647 current bitstream. NULL in the case that the machine is not
1650 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1653 if(vf->ready_state>=STREAMSET)
1654 return vf->vi+vf->current_link;
1667 /* grr, strong typing, grr, no templates/inheritence, grr */
1668 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1671 if(vf->ready_state>=STREAMSET)
1672 return vf->vc+vf->current_link;
1685 static int host_is_big_endian() {
1686 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1687 unsigned char *bytewise = (unsigned char *)&pattern;
1688 if (bytewise[0] == 0xfe) return 1;
1692 /* up to this point, everything could more or less hide the multiple
1693 logical bitstream nature of chaining from the toplevel application
1694 if the toplevel application didn't particularly care. However, at
1695 the point that we actually read audio back, the multiple-section
1696 nature must surface: Multiple bitstream sections do not necessarily
1697 have to have the same number of channels or sampling rate.
1699 ov_read returns the sequential logical bitstream number currently
1700 being decoded along with the PCM data in order that the toplevel
1701 application can take action on channel/sample rate changes. This
1702 number will be incremented even for streamed (non-seekable) streams
1703 (for seekable streams, it represents the actual logical bitstream
1704 index within the physical bitstream. Note that the accessor
1705 functions above are aware of this dichotomy).
1707 input values: buffer) a buffer to hold packed PCM data for return
1708 length) the byte length requested to be placed into buffer
1709 bigendianp) should the data be packed LSB first (0) or
1711 word) word size for output. currently 1 (byte) or
1714 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1716 n) number of bytes of PCM actually returned. The
1717 below works on a packet-by-packet basis, so the
1718 return length is not related to the 'length' passed
1719 in, just guaranteed to fit.
1721 *section) set to the logical bitstream number */
1723 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1724 int bigendianp,int word,int sgned,int *bitstream){
1726 int host_endian = host_is_big_endian();
1731 if(vf->ready_state<OPENED)return(OV_EINVAL);
1734 if(vf->ready_state==INITSET){
1735 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1739 /* suck in another packet */
1741 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1752 /* yay! proceed to pack data into the byte buffer */
1754 long channels=ov_info(vf,-1)->channels;
1755 long bytespersample=word * channels;
1756 vorbis_fpu_control fpu;
1757 if(samples>length/bytespersample)samples=length/bytespersample;
1762 /* a tight loop to pack each size */
1766 int off=(sgned?0:128);
1767 vorbis_fpu_setround(&fpu);
1768 for(j=0;j<samples;j++)
1769 for(i=0;i<channels;i++){
1770 val=vorbis_ftoi(pcm[i][j]*128.f);
1772 else if(val<-128)val=-128;
1775 vorbis_fpu_restore(fpu);
1777 int off=(sgned?0:32768);
1779 if(host_endian==bigendianp){
1782 vorbis_fpu_setround(&fpu);
1783 for(i=0;i<channels;i++) { /* It's faster in this order */
1785 short *dest=((short *)buffer)+i;
1786 for(j=0;j<samples;j++) {
1787 val=vorbis_ftoi(src[j]*32768.f);
1788 if(val>32767)val=32767;
1789 else if(val<-32768)val=-32768;
1794 vorbis_fpu_restore(fpu);
1798 vorbis_fpu_setround(&fpu);
1799 for(i=0;i<channels;i++) {
1801 short *dest=((short *)buffer)+i;
1802 for(j=0;j<samples;j++) {
1803 val=vorbis_ftoi(src[j]*32768.f);
1804 if(val>32767)val=32767;
1805 else if(val<-32768)val=-32768;
1810 vorbis_fpu_restore(fpu);
1813 }else if(bigendianp){
1815 vorbis_fpu_setround(&fpu);
1816 for(j=0;j<samples;j++)
1817 for(i=0;i<channels;i++){
1818 val=vorbis_ftoi(pcm[i][j]*32768.f);
1819 if(val>32767)val=32767;
1820 else if(val<-32768)val=-32768;
1823 *buffer++=(val&0xff);
1825 vorbis_fpu_restore(fpu);
1829 vorbis_fpu_setround(&fpu);
1830 for(j=0;j<samples;j++)
1831 for(i=0;i<channels;i++){
1832 val=vorbis_ftoi(pcm[i][j]*32768.f);
1833 if(val>32767)val=32767;
1834 else if(val<-32768)val=-32768;
1836 *buffer++=(val&0xff);
1839 vorbis_fpu_restore(fpu);
1845 vorbis_synthesis_read(&vf->vd,samples);
1846 vf->pcm_offset+=samples;
1847 if(bitstream)*bitstream=vf->current_link;
1848 return(samples*bytespersample);
1854 /* input values: pcm_channels) a float vector per channel of output
1855 length) the sample length being read by the app
1857 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1859 n) number of samples of PCM actually returned. The
1860 below works on a packet-by-packet basis, so the
1861 return length is not related to the 'length' passed
1862 in, just guaranteed to fit.
1864 *section) set to the logical bitstream number */
1868 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1871 if(vf->ready_state<OPENED)return(OV_EINVAL);
1874 if(vf->ready_state==INITSET){
1876 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1878 if(pcm_channels)*pcm_channels=pcm;
1879 if(samples>length)samples=length;
1880 vorbis_synthesis_read(&vf->vd,samples);
1881 vf->pcm_offset+=samples;
1882 if(bitstream)*bitstream=vf->current_link;
1888 /* suck in another packet */
1890 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1891 if(ret==OV_EOF)return(0);
1892 if(ret<=0)return(ret);
1898 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1899 extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
1902 static void _ov_splice(float **pcm,float **lappcm,
1905 float *w1, float *w2){
1916 for(j=0;j<ch1 && j<ch2;j++){
1923 d[i]=d[i]*wd + s[i]*ws;
1926 /* window from zero */
1937 /* make sure vf is INITSET */
1938 static int _ov_initset(OggVorbis_File *vf){
1940 if(vf->ready_state==INITSET)break;
1941 /* suck in another packet */
1943 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1944 if(ret<0 && ret!=OV_HOLE)return(ret);
1950 /* make sure vf is INITSET and that we have a primed buffer; if
1951 we're crosslapping at a stream section boundary, this also makes
1952 sure we're sanity checking against the right stream information */
1953 static int _ov_initprime(OggVorbis_File *vf){
1954 vorbis_dsp_state *vd=&vf->vd;
1956 if(vf->ready_state==INITSET)
1957 if(vorbis_synthesis_pcmout(vd,NULL))break;
1959 /* suck in another packet */
1961 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1962 if(ret<0 && ret!=OV_HOLE)return(ret);
1968 /* grab enough data for lapping from vf; this may be in the form of
1969 unreturned, already-decoded pcm, remaining PCM we will need to
1970 decode, or synthetic postextrapolation from last packets. */
1971 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1972 float **lappcm,int lapsize){
1976 /* try first to decode the lapping data */
1977 while(lapcount<lapsize){
1978 int samples=vorbis_synthesis_pcmout(vd,&pcm);
1980 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1981 for(i=0;i<vi->channels;i++)
1982 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1984 vorbis_synthesis_read(vd,samples);
1986 /* suck in another packet */
1987 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
1988 if(ret==OV_EOF)break;
1991 if(lapcount<lapsize){
1992 /* failed to get lapping data from normal decode; pry it from the
1993 postextrapolation buffering, or the second half of the MDCT
1994 from the last packet */
1995 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
1997 for(i=0;i<vi->channels;i++)
1998 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2001 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2002 for(i=0;i<vi->channels;i++)
2003 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2009 /* this sets up crosslapping of a sample by using trailing data from
2010 sample 1 and lapping it into the windowing buffer of sample 2 */
2011 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2012 vorbis_info *vi1,*vi2;
2016 int n1,n2,i,ret,hs1,hs2;
2018 if(vf1==vf2)return(0); /* degenerate case */
2019 if(vf1->ready_state<OPENED)return(OV_EINVAL);
2020 if(vf2->ready_state<OPENED)return(OV_EINVAL);
2022 /* the relevant overlap buffers must be pre-checked and pre-primed
2023 before looking at settings in the event that priming would cross
2024 a bitstream boundary. So, do it now */
2026 ret=_ov_initset(vf1);
2028 ret=_ov_initprime(vf2);
2031 vi1=ov_info(vf1,-1);
2032 vi2=ov_info(vf2,-1);
2033 hs1=ov_halfrate_p(vf1);
2034 hs2=ov_halfrate_p(vf2);
2036 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2037 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2038 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2039 w1=vorbis_window(&vf1->vd,0);
2040 w2=vorbis_window(&vf2->vd,0);
2042 for(i=0;i<vi1->channels;i++)
2043 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2045 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2047 /* have a lapping buffer from vf1; now to splice it into the lapping
2049 /* consolidate and expose the buffer. */
2050 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2051 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2052 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2055 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2061 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2062 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2067 int n1,n2,ch1,ch2,hs;
2070 if(vf->ready_state<OPENED)return(OV_EINVAL);
2071 ret=_ov_initset(vf);
2074 hs=ov_halfrate_p(vf);
2077 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2078 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2079 persistent; even if the decode state
2080 from this link gets dumped, this
2081 window array continues to exist */
2083 lappcm=alloca(sizeof(*lappcm)*ch1);
2085 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2086 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2088 /* have lapping data; seek and prime the buffer */
2089 ret=localseek(vf,pos);
2091 ret=_ov_initprime(vf);
2094 /* Guard against cross-link changes; they're perfectly legal */
2097 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2098 w2=vorbis_window(&vf->vd,0);
2100 /* consolidate and expose the buffer. */
2101 vorbis_synthesis_lapout(&vf->vd,&pcm);
2104 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2110 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2111 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2114 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2115 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2118 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2119 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2122 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2123 int (*localseek)(OggVorbis_File *,double)){
2128 int n1,n2,ch1,ch2,hs;
2131 if(vf->ready_state<OPENED)return(OV_EINVAL);
2132 ret=_ov_initset(vf);
2135 hs=ov_halfrate_p(vf);
2138 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2139 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2140 persistent; even if the decode state
2141 from this link gets dumped, this
2142 window array continues to exist */
2144 lappcm=alloca(sizeof(*lappcm)*ch1);
2146 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2147 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2149 /* have lapping data; seek and prime the buffer */
2150 ret=localseek(vf,pos);
2152 ret=_ov_initprime(vf);
2155 /* Guard against cross-link changes; they're perfectly legal */
2158 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2159 w2=vorbis_window(&vf->vd,0);
2161 /* consolidate and expose the buffer. */
2162 vorbis_synthesis_lapout(&vf->vd,&pcm);
2165 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2171 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2172 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2175 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2176 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);