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]){
515 if(ogg_page_granulepos(&og)!=-1){
516 vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
527 static int _make_decode_ready(OggVorbis_File *vf){
528 if(vf->ready_state>STREAMSET)return 0;
529 if(vf->ready_state<STREAMSET)return OV_EFAULT;
531 if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
534 if(vorbis_synthesis_init(&vf->vd,vf->vi))
537 vorbis_block_init(&vf->vd,&vf->vb);
538 vf->ready_state=INITSET;
544 static int _open_seekable2(OggVorbis_File *vf){
545 ogg_int64_t dataoffset=vf->offset,end;
546 long *serialno_list=NULL;
551 /* we're partially open and have a first link header state in
553 /* we can seek, so set out learning all about this file */
554 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
555 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
557 /* If seek_func is implemented, tell_func must also be implemented */
558 if(vf->end==-1) return(OV_EINVAL);
560 /* We get the offset for the last page of the physical bitstream.
561 Most OggVorbis files will contain a single logical bitstream */
562 end=_get_prev_page(vf,&og);
563 if(end<0)return(end);
565 /* back to beginning, learn all serialnos of first link */
566 ret=_seek_helper(vf,0);
568 ret=_get_serialnos(vf,&serialno_list,&serialnos);
571 /* now determine bitstream structure recursively */
572 if(_bisect_forward_serialno(vf,0,0,end+1,serialno_list,serialnos,0)<0)return(OV_EREAD);
573 if(serialno_list)_ogg_free(serialno_list);
575 /* the initial header memory is referenced by vf after; don't free it */
576 _prefetch_all_headers(vf,dataoffset);
577 return(ov_raw_seek(vf,0));
580 /* clear out the current logical bitstream decoder */
581 static void _decode_clear(OggVorbis_File *vf){
582 vorbis_dsp_clear(&vf->vd);
583 vorbis_block_clear(&vf->vb);
584 vf->ready_state=OPENED;
587 /* fetch and process a packet. Handles the case where we're at a
588 bitstream boundary and dumps the decoding machine. If the decoding
589 machine is unloaded, it loads it. It also keeps pcm_offset up to
590 date (seek and read both use this. seek uses a special hack with
593 return: <0) error, OV_HOLE (lost packet) or OV_EOF
594 0) need more data (only if readp==0)
598 static int _fetch_and_process_packet(OggVorbis_File *vf,
604 /* handle one packet. Try to fetch it from current stream state */
605 /* extract packets from page */
608 /* process a packet if we can. If the machine isn't loaded,
610 if(vf->ready_state==INITSET){
613 ogg_packet *op_ptr=(op_in?op_in:&op);
614 int result=ogg_stream_packetout(&vf->os,op_ptr);
615 ogg_int64_t granulepos;
618 if(result==-1)return(OV_HOLE); /* hole in the data. */
620 /* got a packet. process it */
621 granulepos=op_ptr->granulepos;
622 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
624 header packets aren't
627 vorbis_synthesis will
630 /* suck in the synthesis data and track bitrate */
632 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
633 /* for proper use of libvorbis within libvorbisfile,
634 oldsamples will always be zero. */
635 if(oldsamples)return(OV_EFAULT);
637 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
638 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
639 vf->bittrack+=op_ptr->bytes*8;
642 /* update the pcm offset. */
643 if(granulepos!=-1 && !op_ptr->e_o_s){
644 int link=(vf->seekable?vf->current_link:0);
647 /* this packet has a pcm_offset on it (the last packet
648 completed on a page carries the offset) After processing
649 (above), we know the pcm position of the *last* sample
650 ready to be returned. Find the offset of the *first*
652 As an aside, this trick is inaccurate if we begin
653 reading anew right at the last page; the end-of-stream
654 granulepos declares the last frame in the stream, and the
655 last packet of the last page may be a partial frame.
656 So, we need a previous granulepos from an in-sequence page
657 to have a reference point. Thus the !op_ptr->e_o_s clause
660 if(vf->seekable && link>0)
661 granulepos-=vf->pcmlengths[link*2];
662 if(granulepos<0)granulepos=0; /* actually, this
663 shouldn't be possible
664 here unless the stream
667 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
671 granulepos+=vf->pcmlengths[i*2+1];
672 vf->pcm_offset=granulepos;
682 if(vf->ready_state>=OPENED){
686 /* the loop is not strictly necessary, but there's no sense in
687 doing the extra checks of the larger loop for the common
688 case in a multiplexed bistream where the page is simply
689 part of a different logical bitstream; keep reading until
690 we get one with the correct serialno */
693 if((ret=_get_next_page(vf,&og,-1))<0){
694 return(OV_EOF); /* eof. leave unitialized */
697 /* bitrate tracking; add the header's bytes here, the body bytes
698 are done by packet above */
699 vf->bittrack+=og.header_len*8;
701 if(vf->ready_state==INITSET){
702 if(vf->current_serialno!=ogg_page_serialno(&og)){
704 /* two possibilities:
705 1) our decoding just traversed a bitstream boundary
706 2) another stream is multiplexed into this logical section? */
708 if(ogg_page_bos(&og)){
716 vorbis_info_clear(vf->vi);
717 vorbis_comment_clear(vf->vc);
722 continue; /* possibility #2 */
730 /* Do we need to load a new machine before submitting the page? */
731 /* This is different in the seekable and non-seekable cases.
733 In the seekable case, we already have all the header
734 information loaded and cached; we just initialize the machine
735 with it and continue on our merry way.
737 In the non-seekable (streaming) case, we'll only be at a
738 boundary if we just left the previous logical bitstream and
739 we're now nominally at the header of the next bitstream
742 if(vf->ready_state!=INITSET){
745 if(vf->ready_state<STREAMSET){
747 long serialno = ogg_page_serialno(&og);
749 /* match the serialno to bitstream section. We use this rather than
750 offset positions to avoid problems near logical bitstream
753 for(link=0;link<vf->links;link++)
754 if(vf->serialnos[link]==serialno)break;
756 if(link==vf->links) continue; /* not the desired Vorbis
757 bitstream section; keep
760 vf->current_serialno=serialno;
761 vf->current_link=link;
763 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
764 vf->ready_state=STREAMSET;
767 /* we're streaming */
768 /* fetch the three header packets, build the info struct */
770 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
778 int ret=_make_decode_ready(vf);
783 /* the buffered page is the data we want, and we're ready for it;
784 add it to the stream state */
785 ogg_stream_pagein(&vf->os,&og);
790 /* if, eg, 64 bit stdio is configured by default, this will build with
792 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
793 if(f==NULL)return(-1);
794 return fseek(f,off,whence);
797 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
798 long ibytes, ov_callbacks callbacks){
799 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
802 memset(vf,0,sizeof(*vf));
804 vf->callbacks = callbacks;
806 /* init the framing state */
807 ogg_sync_init(&vf->oy);
809 /* perhaps some data was previously read into a buffer for testing
810 against other stream types. Allow initialization from this
811 previously read data (as we may be reading from a non-seekable
814 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
815 memcpy(buffer,initial,ibytes);
816 ogg_sync_wrote(&vf->oy,ibytes);
819 /* can we seek? Stevens suggests the seek test was portable */
820 if(offsettest!=-1)vf->seekable=1;
822 /* No seeking yet; Set up a 'single' (current) logical bitstream
823 entry for partial open */
825 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
826 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
827 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
829 /* Try to fetch the headers, maintaining all the storage */
830 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
834 vf->ready_state=PARTOPEN;
838 static int _ov_open2(OggVorbis_File *vf){
839 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
840 vf->ready_state=OPENED;
842 int ret=_open_seekable2(vf);
849 vf->ready_state=STREAMSET;
855 /* clear out the OggVorbis_File struct */
856 int ov_clear(OggVorbis_File *vf){
858 vorbis_block_clear(&vf->vb);
859 vorbis_dsp_clear(&vf->vd);
860 ogg_stream_clear(&vf->os);
862 if(vf->vi && vf->links){
864 for(i=0;i<vf->links;i++){
865 vorbis_info_clear(vf->vi+i);
866 vorbis_comment_clear(vf->vc+i);
871 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
872 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
873 if(vf->serialnos)_ogg_free(vf->serialnos);
874 if(vf->offsets)_ogg_free(vf->offsets);
875 ogg_sync_clear(&vf->oy);
876 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
877 memset(vf,0,sizeof(*vf));
885 /* inspects the OggVorbis file and finds/documents all the logical
886 bitstreams contained in it. Tries to be tolerant of logical
887 bitstream sections that are truncated/woogie.
893 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
894 ov_callbacks callbacks){
895 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
897 return _ov_open2(vf);
900 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
901 ov_callbacks callbacks = {
902 (size_t (*)(void *, size_t, size_t, void *)) fread,
903 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
904 (int (*)(void *)) fclose,
905 (long (*)(void *)) ftell
908 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
911 /* cheap hack for game usage where downsampling is desirable; there's
912 no need for SRC as we can just do it cheaply in libvorbis. */
914 int ov_halfrate(OggVorbis_File *vf,int flag){
916 if(vf->vi==NULL)return OV_EINVAL;
917 if(!vf->seekable)return OV_EINVAL;
918 if(vf->ready_state>=STREAMSET)
919 _decode_clear(vf); /* clear out stream state; later on libvorbis
920 will be able to swap this on the fly, but
921 for now dumping the decode machine is needed
922 to reinit the MDCT lookups. 1.1 libvorbis
923 is planned to be able to switch on the fly */
925 for(i=0;i<vf->links;i++){
926 if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
934 int ov_halfrate_p(OggVorbis_File *vf){
935 if(vf->vi==NULL)return OV_EINVAL;
936 return vorbis_synthesis_halfrate_p(vf->vi);
939 /* Only partially open the vorbis file; test for Vorbisness, and load
940 the headers for the first chain. Do not seek (although test for
941 seekability). Use ov_test_open to finish opening the file, else
942 ov_clear to close/free it. Same return codes as open. */
944 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
945 ov_callbacks callbacks)
947 return _ov_open1(f,vf,initial,ibytes,callbacks);
950 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
951 ov_callbacks callbacks = {
952 (size_t (*)(void *, size_t, size_t, void *)) fread,
953 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
954 (int (*)(void *)) fclose,
955 (long (*)(void *)) ftell
958 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
961 int ov_test_open(OggVorbis_File *vf){
962 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
963 return _ov_open2(vf);
966 /* How many logical bitstreams in this physical bitstream? */
967 long ov_streams(OggVorbis_File *vf){
971 /* Is the FILE * associated with vf seekable? */
972 long ov_seekable(OggVorbis_File *vf){
976 /* returns the bitrate for a given logical bitstream or the entire
977 physical bitstream. If the file is open for random access, it will
978 find the *actual* average bitrate. If the file is streaming, it
979 returns the nominal bitrate (if set) else the average of the
980 upper/lower bounds (if set) else -1 (unset).
982 If you want the actual bitrate field settings, get them from the
983 vorbis_info structs */
985 long ov_bitrate(OggVorbis_File *vf,int i){
986 if(vf->ready_state<OPENED)return(OV_EINVAL);
987 if(i>=vf->links)return(OV_EINVAL);
988 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
993 for(i=0;i<vf->links;i++)
994 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
995 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
996 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
997 * so this is slightly transformed to make it work.
999 br = bits/ov_time_total(vf,-1);
1003 /* return the actual bitrate */
1004 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
1006 /* return nominal if set */
1007 if(vf->vi[i].bitrate_nominal>0){
1008 return vf->vi[i].bitrate_nominal;
1010 if(vf->vi[i].bitrate_upper>0){
1011 if(vf->vi[i].bitrate_lower>0){
1012 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1014 return vf->vi[i].bitrate_upper;
1023 /* returns the actual bitrate since last call. returns -1 if no
1024 additional data to offer since last call (or at beginning of stream),
1025 EINVAL if stream is only partially open
1027 long ov_bitrate_instant(OggVorbis_File *vf){
1028 int link=(vf->seekable?vf->current_link:0);
1030 if(vf->ready_state<OPENED)return(OV_EINVAL);
1031 if(vf->samptrack==0)return(OV_FALSE);
1032 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1039 long ov_serialnumber(OggVorbis_File *vf,int i){
1040 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1041 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1043 return(vf->current_serialno);
1045 return(vf->serialnos[i]);
1049 /* returns: total raw (compressed) length of content if i==-1
1050 raw (compressed) length of that logical bitstream for i==0 to n
1051 OV_EINVAL if the stream is not seekable (we can't know the length)
1052 or if stream is only partially open
1054 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1055 if(vf->ready_state<OPENED)return(OV_EINVAL);
1056 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1060 for(i=0;i<vf->links;i++)
1061 acc+=ov_raw_total(vf,i);
1064 return(vf->offsets[i+1]-vf->offsets[i]);
1068 /* returns: total PCM length (samples) of content if i==-1 PCM length
1069 (samples) of that logical bitstream for i==0 to n
1070 OV_EINVAL if the stream is not seekable (we can't know the
1071 length) or only partially open
1073 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1074 if(vf->ready_state<OPENED)return(OV_EINVAL);
1075 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1079 for(i=0;i<vf->links;i++)
1080 acc+=ov_pcm_total(vf,i);
1083 return(vf->pcmlengths[i*2+1]);
1087 /* returns: total seconds of content if i==-1
1088 seconds in that logical bitstream for i==0 to n
1089 OV_EINVAL if the stream is not seekable (we can't know the
1090 length) or only partially open
1092 double ov_time_total(OggVorbis_File *vf,int i){
1093 if(vf->ready_state<OPENED)return(OV_EINVAL);
1094 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1098 for(i=0;i<vf->links;i++)
1099 acc+=ov_time_total(vf,i);
1102 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1106 /* seek to an offset relative to the *compressed* data. This also
1107 scans packets to update the PCM cursor. It will cross a logical
1108 bitstream boundary, but only if it can't get any packets out of the
1109 tail of the bitstream we seek to (so no surprises).
1111 returns zero on success, nonzero on failure */
1113 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1114 ogg_stream_state work_os;
1117 if(vf->ready_state<OPENED)return(OV_EINVAL);
1119 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1121 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1123 /* don't yet clear out decoding machine (if it's initialized), in
1124 the case we're in the same link. Restart the decode lapping, and
1125 let _fetch_and_process_packet deal with a potential bitstream
1128 ogg_stream_reset_serialno(&vf->os,
1129 vf->current_serialno); /* must set serialno */
1130 vorbis_synthesis_restart(&vf->vd);
1132 ret=_seek_helper(vf,pos);
1135 /* we need to make sure the pcm_offset is set, but we don't want to
1136 advance the raw cursor past good packets just to get to the first
1137 with a granulepos. That's not equivalent behavior to beginning
1138 decoding as immediately after the seek position as possible.
1140 So, a hack. We use two stream states; a local scratch state and
1141 the shared vf->os stream state. We use the local state to
1142 scan, and the shared state as a buffer for later decode.
1144 Unfortuantely, on the last page we still advance to last packet
1145 because the granulepos on the last page is not necessarily on a
1146 packet boundary, and we need to make sure the granpos is
1158 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1159 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1160 return from not necessarily
1161 starting from the beginning */
1164 if(vf->ready_state>=STREAMSET){
1165 /* snarf/scan a packet if we can */
1166 int result=ogg_stream_packetout(&work_os,&op);
1170 if(vf->vi[vf->current_link].codec_setup){
1171 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1173 ogg_stream_packetout(&vf->os,NULL);
1178 ogg_stream_packetout(&vf->os,NULL);
1180 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1183 if(op.granulepos!=-1){
1184 int i,link=vf->current_link;
1185 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1186 if(granulepos<0)granulepos=0;
1189 granulepos+=vf->pcmlengths[i*2+1];
1190 vf->pcm_offset=granulepos-accblock;
1193 lastblock=thisblock;
1196 ogg_stream_packetout(&vf->os,NULL);
1201 if(_get_next_page(vf,&og,-1)<0){
1202 vf->pcm_offset=ov_pcm_total(vf,-1);
1206 /* huh? Bogus stream with packets but no granulepos */
1211 /* has our decoding just traversed a bitstream boundary? */
1212 if(vf->ready_state>=STREAMSET){
1213 if(vf->current_serialno!=ogg_page_serialno(&og)){
1215 /* two possibilities:
1216 1) our decoding just traversed a bitstream boundary
1217 2) another stream is multiplexed into this logical section? */
1219 if(ogg_page_bos(&og)){
1221 _decode_clear(vf); /* clear out stream state */
1222 ogg_stream_clear(&work_os);
1223 } /* else, do nothing; next loop will scoop another page */
1227 if(vf->ready_state<STREAMSET){
1229 long serialno = ogg_page_serialno(&og);
1231 for(link=0;link<vf->links;link++)
1232 if(vf->serialnos[link]==serialno)break;
1234 if(link==vf->links) continue; /* not the desired Vorbis
1235 bitstream section; keep
1237 vf->current_link=link;
1238 vf->current_serialno=serialno;
1239 ogg_stream_reset_serialno(&vf->os,serialno);
1240 ogg_stream_reset_serialno(&work_os,serialno);
1241 vf->ready_state=STREAMSET;
1245 ogg_stream_pagein(&vf->os,&og);
1246 ogg_stream_pagein(&work_os,&og);
1247 eosflag=ogg_page_eos(&og);
1251 ogg_stream_clear(&work_os);
1257 /* dump the machine so we're in a known state */
1259 ogg_stream_clear(&work_os);
1264 /* Page granularity seek (faster than sample granularity because we
1265 don't do the last bit of decode to find a specific sample).
1267 Seek to the last [granule marked] page preceeding the specified pos
1268 location, such that decoding past the returned point will quickly
1269 arrive at the requested position. */
1270 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1272 ogg_int64_t result=0;
1273 ogg_int64_t total=ov_pcm_total(vf,-1);
1275 if(vf->ready_state<OPENED)return(OV_EINVAL);
1276 if(!vf->seekable)return(OV_ENOSEEK);
1278 if(pos<0 || pos>total)return(OV_EINVAL);
1280 /* which bitstream section does this pcm offset occur in? */
1281 for(link=vf->links-1;link>=0;link--){
1282 total-=vf->pcmlengths[link*2+1];
1283 if(pos>=total)break;
1286 /* search within the logical bitstream for the page with the highest
1287 pcm_pos preceeding (or equal to) pos. There is a danger here;
1288 missing pages or incorrect frame number information in the
1289 bitstream could make our task impossible. Account for that (it
1290 would be an error condition) */
1292 /* new search algorithm by HB (Nicholas Vinen) */
1294 ogg_int64_t end=vf->offsets[link+1];
1295 ogg_int64_t begin=vf->offsets[link];
1296 ogg_int64_t begintime = vf->pcmlengths[link*2];
1297 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1298 ogg_int64_t target=pos-total+begintime;
1299 ogg_int64_t best=begin;
1305 if(end-begin<CHUNKSIZE){
1308 /* take a (pretty decent) guess. */
1310 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1315 result=_seek_helper(vf,bisect);
1316 if(result) goto seek_error;
1319 result=_get_next_page(vf,&og,end-vf->offset);
1320 if(result==OV_EREAD) goto seek_error;
1323 end=begin; /* found it */
1325 if(bisect==0) goto seek_error;
1327 if(bisect<=begin)bisect=begin+1;
1328 result=_seek_helper(vf,bisect);
1329 if(result) goto seek_error;
1332 ogg_int64_t granulepos;
1334 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1337 granulepos=ogg_page_granulepos(&og);
1338 if(granulepos==-1)continue;
1340 if(granulepos<target){
1341 best=result; /* raw offset of packet with granulepos */
1342 begin=vf->offset; /* raw offset of next page */
1343 begintime=granulepos;
1345 if(target-begintime>44100)break;
1346 bisect=begin; /* *not* begin + 1 */
1349 end=begin; /* found it */
1351 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1353 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1354 if(bisect<=begin)bisect=begin+1;
1355 result=_seek_helper(vf,bisect);
1356 if(result) goto seek_error;
1368 /* found our page. seek to it, update pcm offset. Easier case than
1369 raw_seek, don't keep packets preceeding granulepos. */
1375 result=_seek_helper(vf,best);
1377 if(result) goto seek_error;
1378 result=_get_next_page(vf,&og,-1);
1379 if(result<0) goto seek_error;
1381 if(link!=vf->current_link){
1382 /* Different link; dump entire decode machine */
1385 vf->current_link=link;
1386 vf->current_serialno=vf->serialnos[link];
1387 vf->ready_state=STREAMSET;
1390 vorbis_synthesis_restart(&vf->vd);
1393 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1394 ogg_stream_pagein(&vf->os,&og);
1396 /* pull out all but last packet; the one with granulepos */
1398 result=ogg_stream_packetpeek(&vf->os,&op);
1400 /* !!! the packet finishing this page originated on a
1401 preceeding page. Keep fetching previous pages until we
1402 get one with a granulepos or without the 'continued' flag
1403 set. Then just use raw_seek for simplicity. */
1405 result=_seek_helper(vf,best);
1406 if(result<0) goto seek_error;
1409 result=_get_prev_page(vf,&og);
1410 if(result<0) goto seek_error;
1411 if(ogg_page_serialno(&og)==vf->current_serialno &&
1412 (ogg_page_granulepos(&og)>-1 ||
1413 !ogg_page_continued(&og))){
1414 return ov_raw_seek(vf,result);
1420 result = OV_EBADPACKET;
1423 if(op.granulepos!=-1){
1424 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1425 if(vf->pcm_offset<0)vf->pcm_offset=0;
1426 vf->pcm_offset+=total;
1429 result=ogg_stream_packetout(&vf->os,NULL);
1435 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1444 /* dump machine so we're in a known state */
1450 /* seek to a sample offset relative to the decompressed pcm stream
1451 returns zero on success, nonzero on failure */
1453 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1454 int thisblock,lastblock=0;
1455 int ret=ov_pcm_seek_page(vf,pos);
1456 if(ret<0)return(ret);
1457 if((ret=_make_decode_ready(vf)))return ret;
1459 /* discard leading packets we don't need for the lapping of the
1460 position we want; don't decode them */
1466 int ret=ogg_stream_packetpeek(&vf->os,&op);
1468 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1470 ogg_stream_packetout(&vf->os,NULL);
1471 continue; /* non audio packet */
1473 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1475 if(vf->pcm_offset+((thisblock+
1476 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1478 /* remove the packet from packet queue and track its granulepos */
1479 ogg_stream_packetout(&vf->os,NULL);
1480 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1483 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1485 /* end of logical stream case is hard, especially with exact
1486 length positioning. */
1488 if(op.granulepos>-1){
1490 /* always believe the stream markers */
1491 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1492 if(vf->pcm_offset<0)vf->pcm_offset=0;
1493 for(i=0;i<vf->current_link;i++)
1494 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1497 lastblock=thisblock;
1500 if(ret<0 && ret!=OV_HOLE)break;
1502 /* suck in a new page */
1503 if(_get_next_page(vf,&og,-1)<0)break;
1504 if(ogg_page_bos(&og))_decode_clear(vf);
1506 if(vf->ready_state<STREAMSET){
1507 long serialno=ogg_page_serialno(&og);
1510 for(link=0;link<vf->links;link++)
1511 if(vf->serialnos[link]==serialno)break;
1512 if(link==vf->links) continue;
1513 vf->current_link=link;
1515 vf->ready_state=STREAMSET;
1516 vf->current_serialno=ogg_page_serialno(&og);
1517 ogg_stream_reset_serialno(&vf->os,serialno);
1518 ret=_make_decode_ready(vf);
1523 ogg_stream_pagein(&vf->os,&og);
1529 /* discard samples until we reach the desired position. Crossing a
1530 logical bitstream boundary with abandon is OK. */
1531 while(vf->pcm_offset<pos){
1532 ogg_int64_t target=pos-vf->pcm_offset;
1533 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1535 if(samples>target)samples=target;
1536 vorbis_synthesis_read(&vf->vd,samples);
1537 vf->pcm_offset+=samples;
1540 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1541 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1546 /* seek to a playback time relative to the decompressed pcm stream
1547 returns zero on success, nonzero on failure */
1548 int ov_time_seek(OggVorbis_File *vf,double seconds){
1549 /* translate time to PCM position and call ov_pcm_seek */
1552 ogg_int64_t pcm_total=0;
1553 double time_total=0.;
1555 if(vf->ready_state<OPENED)return(OV_EINVAL);
1556 if(!vf->seekable)return(OV_ENOSEEK);
1557 if(seconds<0)return(OV_EINVAL);
1559 /* which bitstream section does this time offset occur in? */
1560 for(link=0;link<vf->links;link++){
1561 double addsec = ov_time_total(vf,link);
1562 if(seconds<time_total+addsec)break;
1564 pcm_total+=vf->pcmlengths[link*2+1];
1567 if(link==vf->links)return(OV_EINVAL);
1569 /* enough information to convert time offset to pcm offset */
1571 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1572 return(ov_pcm_seek(vf,target));
1576 /* page-granularity version of ov_time_seek
1577 returns zero on success, nonzero on failure */
1578 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1579 /* translate time to PCM position and call ov_pcm_seek */
1582 ogg_int64_t pcm_total=0;
1583 double time_total=0.;
1585 if(vf->ready_state<OPENED)return(OV_EINVAL);
1586 if(!vf->seekable)return(OV_ENOSEEK);
1587 if(seconds<0)return(OV_EINVAL);
1589 /* which bitstream section does this time offset occur in? */
1590 for(link=0;link<vf->links;link++){
1591 double addsec = ov_time_total(vf,link);
1592 if(seconds<time_total+addsec)break;
1594 pcm_total+=vf->pcmlengths[link*2+1];
1597 if(link==vf->links)return(OV_EINVAL);
1599 /* enough information to convert time offset to pcm offset */
1601 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1602 return(ov_pcm_seek_page(vf,target));
1606 /* tell the current stream offset cursor. Note that seek followed by
1607 tell will likely not give the set offset due to caching */
1608 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1609 if(vf->ready_state<OPENED)return(OV_EINVAL);
1613 /* return PCM offset (sample) of next PCM sample to be read */
1614 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1615 if(vf->ready_state<OPENED)return(OV_EINVAL);
1616 return(vf->pcm_offset);
1619 /* return time offset (seconds) of next PCM sample to be read */
1620 double ov_time_tell(OggVorbis_File *vf){
1622 ogg_int64_t pcm_total=0;
1623 double time_total=0.f;
1625 if(vf->ready_state<OPENED)return(OV_EINVAL);
1627 pcm_total=ov_pcm_total(vf,-1);
1628 time_total=ov_time_total(vf,-1);
1630 /* which bitstream section does this time offset occur in? */
1631 for(link=vf->links-1;link>=0;link--){
1632 pcm_total-=vf->pcmlengths[link*2+1];
1633 time_total-=ov_time_total(vf,link);
1634 if(vf->pcm_offset>=pcm_total)break;
1638 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1641 /* link: -1) return the vorbis_info struct for the bitstream section
1642 currently being decoded
1643 0-n) to request information for a specific bitstream section
1645 In the case of a non-seekable bitstream, any call returns the
1646 current bitstream. NULL in the case that the machine is not
1649 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1652 if(vf->ready_state>=STREAMSET)
1653 return vf->vi+vf->current_link;
1666 /* grr, strong typing, grr, no templates/inheritence, grr */
1667 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1670 if(vf->ready_state>=STREAMSET)
1671 return vf->vc+vf->current_link;
1684 static int host_is_big_endian() {
1685 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1686 unsigned char *bytewise = (unsigned char *)&pattern;
1687 if (bytewise[0] == 0xfe) return 1;
1691 /* up to this point, everything could more or less hide the multiple
1692 logical bitstream nature of chaining from the toplevel application
1693 if the toplevel application didn't particularly care. However, at
1694 the point that we actually read audio back, the multiple-section
1695 nature must surface: Multiple bitstream sections do not necessarily
1696 have to have the same number of channels or sampling rate.
1698 ov_read returns the sequential logical bitstream number currently
1699 being decoded along with the PCM data in order that the toplevel
1700 application can take action on channel/sample rate changes. This
1701 number will be incremented even for streamed (non-seekable) streams
1702 (for seekable streams, it represents the actual logical bitstream
1703 index within the physical bitstream. Note that the accessor
1704 functions above are aware of this dichotomy).
1706 input values: buffer) a buffer to hold packed PCM data for return
1707 length) the byte length requested to be placed into buffer
1708 bigendianp) should the data be packed LSB first (0) or
1710 word) word size for output. currently 1 (byte) or
1713 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1715 n) number of bytes of PCM actually returned. The
1716 below works on a packet-by-packet basis, so the
1717 return length is not related to the 'length' passed
1718 in, just guaranteed to fit.
1720 *section) set to the logical bitstream number */
1722 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1723 int bigendianp,int word,int sgned,int *bitstream){
1725 int host_endian = host_is_big_endian();
1730 if(vf->ready_state<OPENED)return(OV_EINVAL);
1733 if(vf->ready_state==INITSET){
1734 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1738 /* suck in another packet */
1740 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1751 /* yay! proceed to pack data into the byte buffer */
1753 long channels=ov_info(vf,-1)->channels;
1754 long bytespersample=word * channels;
1755 vorbis_fpu_control fpu;
1756 if(samples>length/bytespersample)samples=length/bytespersample;
1761 /* a tight loop to pack each size */
1765 int off=(sgned?0:128);
1766 vorbis_fpu_setround(&fpu);
1767 for(j=0;j<samples;j++)
1768 for(i=0;i<channels;i++){
1769 val=vorbis_ftoi(pcm[i][j]*128.f);
1771 else if(val<-128)val=-128;
1774 vorbis_fpu_restore(fpu);
1776 int off=(sgned?0:32768);
1778 if(host_endian==bigendianp){
1781 vorbis_fpu_setround(&fpu);
1782 for(i=0;i<channels;i++) { /* It's faster in this order */
1784 short *dest=((short *)buffer)+i;
1785 for(j=0;j<samples;j++) {
1786 val=vorbis_ftoi(src[j]*32768.f);
1787 if(val>32767)val=32767;
1788 else if(val<-32768)val=-32768;
1793 vorbis_fpu_restore(fpu);
1797 vorbis_fpu_setround(&fpu);
1798 for(i=0;i<channels;i++) {
1800 short *dest=((short *)buffer)+i;
1801 for(j=0;j<samples;j++) {
1802 val=vorbis_ftoi(src[j]*32768.f);
1803 if(val>32767)val=32767;
1804 else if(val<-32768)val=-32768;
1809 vorbis_fpu_restore(fpu);
1812 }else if(bigendianp){
1814 vorbis_fpu_setround(&fpu);
1815 for(j=0;j<samples;j++)
1816 for(i=0;i<channels;i++){
1817 val=vorbis_ftoi(pcm[i][j]*32768.f);
1818 if(val>32767)val=32767;
1819 else if(val<-32768)val=-32768;
1822 *buffer++=(val&0xff);
1824 vorbis_fpu_restore(fpu);
1828 vorbis_fpu_setround(&fpu);
1829 for(j=0;j<samples;j++)
1830 for(i=0;i<channels;i++){
1831 val=vorbis_ftoi(pcm[i][j]*32768.f);
1832 if(val>32767)val=32767;
1833 else if(val<-32768)val=-32768;
1835 *buffer++=(val&0xff);
1838 vorbis_fpu_restore(fpu);
1844 vorbis_synthesis_read(&vf->vd,samples);
1845 vf->pcm_offset+=samples;
1846 if(bitstream)*bitstream=vf->current_link;
1847 return(samples*bytespersample);
1853 /* input values: pcm_channels) a float vector per channel of output
1854 length) the sample length being read by the app
1856 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1858 n) number of samples of PCM actually returned. The
1859 below works on a packet-by-packet basis, so the
1860 return length is not related to the 'length' passed
1861 in, just guaranteed to fit.
1863 *section) set to the logical bitstream number */
1867 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1870 if(vf->ready_state<OPENED)return(OV_EINVAL);
1873 if(vf->ready_state==INITSET){
1875 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1877 if(pcm_channels)*pcm_channels=pcm;
1878 if(samples>length)samples=length;
1879 vorbis_synthesis_read(&vf->vd,samples);
1880 vf->pcm_offset+=samples;
1881 if(bitstream)*bitstream=vf->current_link;
1887 /* suck in another packet */
1889 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1890 if(ret==OV_EOF)return(0);
1891 if(ret<=0)return(ret);
1897 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1898 extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
1901 static void _ov_splice(float **pcm,float **lappcm,
1904 float *w1, float *w2){
1915 for(j=0;j<ch1 && j<ch2;j++){
1922 d[i]=d[i]*wd + s[i]*ws;
1925 /* window from zero */
1936 /* make sure vf is INITSET */
1937 static int _ov_initset(OggVorbis_File *vf){
1939 if(vf->ready_state==INITSET)break;
1940 /* suck in another packet */
1942 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1943 if(ret<0 && ret!=OV_HOLE)return(ret);
1949 /* make sure vf is INITSET and that we have a primed buffer; if
1950 we're crosslapping at a stream section boundary, this also makes
1951 sure we're sanity checking against the right stream information */
1952 static int _ov_initprime(OggVorbis_File *vf){
1953 vorbis_dsp_state *vd=&vf->vd;
1955 if(vf->ready_state==INITSET)
1956 if(vorbis_synthesis_pcmout(vd,NULL))break;
1958 /* suck in another packet */
1960 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1961 if(ret<0 && ret!=OV_HOLE)return(ret);
1967 /* grab enough data for lapping from vf; this may be in the form of
1968 unreturned, already-decoded pcm, remaining PCM we will need to
1969 decode, or synthetic postextrapolation from last packets. */
1970 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1971 float **lappcm,int lapsize){
1975 /* try first to decode the lapping data */
1976 while(lapcount<lapsize){
1977 int samples=vorbis_synthesis_pcmout(vd,&pcm);
1979 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1980 for(i=0;i<vi->channels;i++)
1981 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1983 vorbis_synthesis_read(vd,samples);
1985 /* suck in another packet */
1986 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
1987 if(ret==OV_EOF)break;
1990 if(lapcount<lapsize){
1991 /* failed to get lapping data from normal decode; pry it from the
1992 postextrapolation buffering, or the second half of the MDCT
1993 from the last packet */
1994 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
1996 for(i=0;i<vi->channels;i++)
1997 memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2000 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2001 for(i=0;i<vi->channels;i++)
2002 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2008 /* this sets up crosslapping of a sample by using trailing data from
2009 sample 1 and lapping it into the windowing buffer of sample 2 */
2010 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2011 vorbis_info *vi1,*vi2;
2015 int n1,n2,i,ret,hs1,hs2;
2017 if(vf1==vf2)return(0); /* degenerate case */
2018 if(vf1->ready_state<OPENED)return(OV_EINVAL);
2019 if(vf2->ready_state<OPENED)return(OV_EINVAL);
2021 /* the relevant overlap buffers must be pre-checked and pre-primed
2022 before looking at settings in the event that priming would cross
2023 a bitstream boundary. So, do it now */
2025 ret=_ov_initset(vf1);
2027 ret=_ov_initprime(vf2);
2030 vi1=ov_info(vf1,-1);
2031 vi2=ov_info(vf2,-1);
2032 hs1=ov_halfrate_p(vf1);
2033 hs2=ov_halfrate_p(vf2);
2035 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2036 n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2037 n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2038 w1=vorbis_window(&vf1->vd,0);
2039 w2=vorbis_window(&vf2->vd,0);
2041 for(i=0;i<vi1->channels;i++)
2042 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2044 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2046 /* have a lapping buffer from vf1; now to splice it into the lapping
2048 /* consolidate and expose the buffer. */
2049 vorbis_synthesis_lapout(&vf2->vd,&pcm);
2050 _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2051 _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2054 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2060 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2061 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2066 int n1,n2,ch1,ch2,hs;
2069 if(vf->ready_state<OPENED)return(OV_EINVAL);
2070 ret=_ov_initset(vf);
2073 hs=ov_halfrate_p(vf);
2076 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2077 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2078 persistent; even if the decode state
2079 from this link gets dumped, this
2080 window array continues to exist */
2082 lappcm=alloca(sizeof(*lappcm)*ch1);
2084 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2085 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2087 /* have lapping data; seek and prime the buffer */
2088 ret=localseek(vf,pos);
2090 ret=_ov_initprime(vf);
2093 /* Guard against cross-link changes; they're perfectly legal */
2096 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2097 w2=vorbis_window(&vf->vd,0);
2099 /* consolidate and expose the buffer. */
2100 vorbis_synthesis_lapout(&vf->vd,&pcm);
2103 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2109 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2110 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2113 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2114 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2117 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2118 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2121 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2122 int (*localseek)(OggVorbis_File *,double)){
2127 int n1,n2,ch1,ch2,hs;
2130 if(vf->ready_state<OPENED)return(OV_EINVAL);
2131 ret=_ov_initset(vf);
2134 hs=ov_halfrate_p(vf);
2137 n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2138 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
2139 persistent; even if the decode state
2140 from this link gets dumped, this
2141 window array continues to exist */
2143 lappcm=alloca(sizeof(*lappcm)*ch1);
2145 lappcm[i]=alloca(sizeof(**lappcm)*n1);
2146 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2148 /* have lapping data; seek and prime the buffer */
2149 ret=localseek(vf,pos);
2151 ret=_ov_initprime(vf);
2154 /* Guard against cross-link changes; they're perfectly legal */
2157 n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2158 w2=vorbis_window(&vf->vd,0);
2160 /* consolidate and expose the buffer. */
2161 vorbis_synthesis_lapout(&vf->vd,&pcm);
2164 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2170 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2171 return _ov_d_seek_lap(vf,pos,ov_time_seek);
2174 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2175 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);