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
14 last mod: $Id: vorbisfile.c,v 1.67 2003/03/04 21:22:11 xiphmont Exp $
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 8500 /* a shade over 8k; anyone using pages well
62 over 8k gets what they deserve */
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 void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
78 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
80 ogg_sync_reset(&vf->oy);
82 /* shouldn't happen unless someone writes a broken callback */
87 /* The read/seek functions track absolute position within the stream */
89 /* from the head of the stream, get the next page. boundary specifies
90 if the function is allowed to fetch more data from the stream (and
91 how much) or only use internally buffered data.
93 boundary: -1) unbounded search
94 0) read no additional data; use cached only
95 n) search for a new page beginning for n bytes
97 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
98 n) found a page at absolute offset n */
100 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
101 ogg_int64_t boundary){
102 if(boundary>0)boundary+=vf->offset;
106 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
107 more=ogg_sync_pageseek(&vf->oy,og);
110 /* skipped n bytes */
114 /* send more paramedics */
115 if(!boundary)return(OV_FALSE);
117 long ret=_get_data(vf);
118 if(ret==0)return(OV_EOF);
119 if(ret<0)return(OV_EREAD);
122 /* got a page. Return the offset at the page beginning,
123 advance the internal offset past the page end */
124 ogg_int64_t ret=vf->offset;
133 /* find the latest page beginning before the current stream cursor
134 position. Much dirtier than the above as Ogg doesn't have any
135 backward search linkage. no 'readp' as it will certainly have to
137 /* returns offset or OV_EREAD, OV_FAULT */
138 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
139 ogg_int64_t begin=vf->offset;
140 ogg_int64_t end=begin;
142 ogg_int64_t offset=-1;
148 _seek_helper(vf,begin);
149 while(vf->offset<end){
150 ret=_get_next_page(vf,og,end-vf->offset);
151 if(ret==OV_EREAD)return(OV_EREAD);
160 /* we have the offset. Actually snork and hold the page now */
161 _seek_helper(vf,offset);
162 ret=_get_next_page(vf,og,CHUNKSIZE);
164 /* this shouldn't be possible */
170 /* finds each bitstream link one at a time using a bisection search
171 (has to begin by knowing the offset of the lb's initial page).
172 Recurses for each link so it can alloc the link storage after
173 finding them all, then unroll and fill the cache at the same time */
174 static int _bisect_forward_serialno(OggVorbis_File *vf,
176 ogg_int64_t searched,
180 ogg_int64_t endsearched=end;
181 ogg_int64_t next=end;
185 /* the below guards against garbage seperating the last and
186 first pages of two links. */
187 while(searched<endsearched){
190 if(endsearched-searched<CHUNKSIZE){
193 bisect=(searched+endsearched)/2;
196 _seek_helper(vf,bisect);
197 ret=_get_next_page(vf,&og,-1);
198 if(ret==OV_EREAD)return(OV_EREAD);
199 if(ret<0 || ogg_page_serialno(&og)!=currentno){
203 searched=ret+og.header_len+og.body_len;
207 _seek_helper(vf,next);
208 ret=_get_next_page(vf,&og,-1);
209 if(ret==OV_EREAD)return(OV_EREAD);
211 if(searched>=end || ret<0){
213 vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
214 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
215 vf->offsets[m+1]=searched;
217 ret=_bisect_forward_serialno(vf,next,vf->offset,
218 end,ogg_page_serialno(&og),m+1);
219 if(ret==OV_EREAD)return(OV_EREAD);
222 vf->offsets[m]=begin;
223 vf->serialnos[m]=currentno;
227 /* uses the local ogg_stream storage in vf; this is important for
228 non-streaming input sources */
229 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
230 long *serialno,ogg_page *og_ptr){
236 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
237 if(llret==OV_EREAD)return(OV_EREAD);
238 if(llret<0)return OV_ENOTVORBIS;
242 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
243 if(serialno)*serialno=vf->os.serialno;
244 vf->ready_state=STREAMSET;
246 /* extract the initial header from the first page and verify that the
247 Ogg bitstream is in fact Vorbis data */
249 vorbis_info_init(vi);
250 vorbis_comment_init(vc);
254 ogg_stream_pagein(&vf->os,og_ptr);
256 int result=ogg_stream_packetout(&vf->os,&op);
262 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
268 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
276 vorbis_info_clear(vi);
277 vorbis_comment_clear(vc);
278 vf->ready_state=OPENED;
283 /* last step of the OggVorbis_File initialization; get all the
284 vorbis_info structs and PCM positions. Only called by the seekable
285 initialization (local stream storage is hacked slightly; pay
286 attention to how that's done) */
288 /* this is void and does not propogate errors up because we want to be
289 able to open and use damaged bitstreams as well as we can. Just
290 watch out for missing information for links in the OggVorbis_File
292 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
297 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
298 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
299 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
300 vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
302 for(i=0;i<vf->links;i++){
304 /* we already grabbed the initial header earlier. Just set the offset */
305 vf->dataoffsets[i]=dataoffset;
306 _seek_helper(vf,dataoffset);
310 /* seek to the location of the initial header */
312 _seek_helper(vf,vf->offsets[i]);
313 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
314 vf->dataoffsets[i]=-1;
316 vf->dataoffsets[i]=vf->offset;
320 /* fetch beginning PCM offset */
322 if(vf->dataoffsets[i]!=-1){
323 ogg_int64_t accumulated=0;
327 ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]);
332 ret=_get_next_page(vf,&og,-1);
334 /* this should not be possible unless the file is
338 if(ogg_page_serialno(&og)!=vf->serialnos[i])
341 /* count blocksizes of all frames in the page */
342 ogg_stream_pagein(&vf->os,&og);
343 while((result=ogg_stream_packetout(&vf->os,&op))){
344 if(result>0){ /* ignore holes */
345 long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
347 accumulated+=(lastblock+thisblock)>>2;
352 if(ogg_page_granulepos(&og)!=-1){
353 /* pcm offset of last packet on the first audio page */
354 accumulated= ogg_page_granulepos(&og)-accumulated;
359 /* less than zero? This is a stream with samples trimmed off
360 the beginning, a normal occurrence; set the offset to zero */
361 if(accumulated<0)accumulated=0;
363 vf->pcmlengths[i*2]=accumulated;
366 /* get the PCM length of this link. To do this,
367 get the last page of the stream */
369 ogg_int64_t end=vf->offsets[i+1];
370 _seek_helper(vf,end);
373 ret=_get_prev_page(vf,&og);
375 /* this should not be possible */
376 vorbis_info_clear(vf->vi+i);
377 vorbis_comment_clear(vf->vc+i);
380 if(ogg_page_granulepos(&og)!=-1){
381 vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
390 static void _make_decode_ready(OggVorbis_File *vf){
391 if(vf->ready_state!=STREAMSET)return;
393 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
395 vorbis_synthesis_init(&vf->vd,vf->vi);
397 vorbis_block_init(&vf->vd,&vf->vb);
398 vf->ready_state=INITSET;
402 static int _open_seekable2(OggVorbis_File *vf){
403 long serialno=vf->current_serialno;
404 ogg_int64_t dataoffset=vf->offset, end;
407 /* we're partially open and have a first link header state in
409 /* we can seek, so set out learning all about this file */
410 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
411 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
413 /* We get the offset for the last page of the physical bitstream.
414 Most OggVorbis files will contain a single logical bitstream */
415 end=_get_prev_page(vf,&og);
416 if(end<0)return(end);
418 /* more than one logical bitstream? */
419 if(ogg_page_serialno(&og)!=serialno){
421 /* Chained bitstream. Bisect-search each logical bitstream
422 section. Do so based on serial number only */
423 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
427 /* Only one logical bitstream */
428 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
432 /* the initial header memory is referenced by vf after; don't free it */
433 _prefetch_all_headers(vf,dataoffset);
434 return(ov_raw_seek(vf,0));
437 /* clear out the current logical bitstream decoder */
438 static void _decode_clear(OggVorbis_File *vf){
439 vorbis_dsp_clear(&vf->vd);
440 vorbis_block_clear(&vf->vb);
441 vf->ready_state=OPENED;
447 /* restart the decoder, but don't clear out machine init */
448 static void _decode_restart(OggVorbis_File *vf){
449 vorbis_synthesis_restart(&vf->vd);
455 /* fetch and process a packet. Handles the case where we're at a
456 bitstream boundary and dumps the decoding machine. If the decoding
457 machine is unloaded, it loads it. It also keeps pcm_offset up to
458 date (seek and read both use this. seek uses a special hack with
461 return: <0) error, OV_HOLE (lost packet) or OV_EOF
462 0) need more data (only if readp==0)
466 static int _fetch_and_process_packet(OggVorbis_File *vf,
472 /* handle one packet. Try to fetch it from current stream state */
473 /* extract packets from page */
476 /* process a packet if we can. If the machine isn't loaded,
478 if(vf->ready_state==INITSET){
481 ogg_packet *op_ptr=(op_in?op_in:&op);
482 int result=ogg_stream_packetout(&vf->os,op_ptr);
483 ogg_int64_t granulepos;
486 if(result==-1)return(OV_HOLE); /* hole in the data. */
488 /* got a packet. process it */
489 granulepos=op_ptr->granulepos;
490 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
492 header packets aren't
495 vorbis_synthesis will
498 /* suck in the synthesis data and track bitrate */
500 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
501 /* for proper use of libvorbis within libvorbisfile,
502 oldsamples will always be zero. */
503 if(oldsamples)return(OV_EFAULT);
505 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
506 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
507 vf->bittrack+=op_ptr->bytes*8;
510 /* update the pcm offset. */
511 if(granulepos!=-1 && !op_ptr->e_o_s){
512 int link=(vf->seekable?vf->current_link:0);
515 /* this packet has a pcm_offset on it (the last packet
516 completed on a page carries the offset) After processing
517 (above), we know the pcm position of the *last* sample
518 ready to be returned. Find the offset of the *first*
520 As an aside, this trick is inaccurate if we begin
521 reading anew right at the last page; the end-of-stream
522 granulepos declares the last frame in the stream, and the
523 last packet of the last page may be a partial frame.
524 So, we need a previous granulepos from an in-sequence page
525 to have a reference point. Thus the !op_ptr->e_o_s clause
528 if(vf->seekable && link>0)
529 granulepos-=vf->pcmlengths[link*2];
530 if(granulepos<0)granulepos=0; /* actually, this
531 shouldn't be possible
532 here unless the stream
535 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
539 granulepos+=vf->pcmlengths[i*2+1];
540 vf->pcm_offset=granulepos;
550 if(vf->ready_state>=OPENED){
553 if((ret=_get_next_page(vf,&og,-1))<0){
554 return(OV_EOF); /* eof.
558 /* bitrate tracking; add the header's bytes here, the body bytes
559 are done by packet above */
560 vf->bittrack+=og.header_len*8;
562 /* has our decoding just traversed a bitstream boundary? */
563 if(vf->ready_state==INITSET){
564 if(vf->current_serialno!=ogg_page_serialno(&og)){
571 vorbis_info_clear(vf->vi);
572 vorbis_comment_clear(vf->vc);
578 /* Do we need to load a new machine before submitting the page? */
579 /* This is different in the seekable and non-seekable cases.
581 In the seekable case, we already have all the header
582 information loaded and cached; we just initialize the machine
583 with it and continue on our merry way.
585 In the non-seekable (streaming) case, we'll only be at a
586 boundary if we just left the previous logical bitstream and
587 we're now nominally at the header of the next bitstream
590 if(vf->ready_state!=INITSET){
593 if(vf->ready_state<STREAMSET){
595 vf->current_serialno=ogg_page_serialno(&og);
597 /* match the serialno to bitstream section. We use this rather than
598 offset positions to avoid problems near logical bitstream
600 for(link=0;link<vf->links;link++)
601 if(vf->serialnos[link]==vf->current_serialno)break;
602 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
607 vf->current_link=link;
609 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
610 vf->ready_state=STREAMSET;
613 /* we're streaming */
614 /* fetch the three header packets, build the info struct */
616 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
623 _make_decode_ready(vf);
625 ogg_stream_pagein(&vf->os,&og);
629 /* if, eg, 64 bit stdio is configured by default, this will build with
631 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
632 if(f==NULL)return(-1);
633 return fseek(f,off,whence);
636 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
637 long ibytes, ov_callbacks callbacks){
638 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
641 memset(vf,0,sizeof(*vf));
643 vf->callbacks = callbacks;
645 /* init the framing state */
646 ogg_sync_init(&vf->oy);
648 /* perhaps some data was previously read into a buffer for testing
649 against other stream types. Allow initialization from this
650 previously read data (as we may be reading from a non-seekable
653 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
654 memcpy(buffer,initial,ibytes);
655 ogg_sync_wrote(&vf->oy,ibytes);
658 /* can we seek? Stevens suggests the seek test was portable */
659 if(offsettest!=-1)vf->seekable=1;
661 /* No seeking yet; Set up a 'single' (current) logical bitstream
662 entry for partial open */
664 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
665 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
666 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
668 /* Try to fetch the headers, maintaining all the storage */
669 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
672 }else if(vf->ready_state < PARTOPEN)
673 vf->ready_state=PARTOPEN;
677 static int _ov_open2(OggVorbis_File *vf){
678 if(vf->ready_state < OPENED)
679 vf->ready_state=OPENED;
681 int ret=_open_seekable2(vf);
692 /* clear out the OggVorbis_File struct */
693 int ov_clear(OggVorbis_File *vf){
695 vorbis_block_clear(&vf->vb);
696 vorbis_dsp_clear(&vf->vd);
697 ogg_stream_clear(&vf->os);
699 if(vf->vi && vf->links){
701 for(i=0;i<vf->links;i++){
702 vorbis_info_clear(vf->vi+i);
703 vorbis_comment_clear(vf->vc+i);
708 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
709 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
710 if(vf->serialnos)_ogg_free(vf->serialnos);
711 if(vf->offsets)_ogg_free(vf->offsets);
712 ogg_sync_clear(&vf->oy);
713 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
714 memset(vf,0,sizeof(*vf));
722 /* inspects the OggVorbis file and finds/documents all the logical
723 bitstreams contained in it. Tries to be tolerant of logical
724 bitstream sections that are truncated/woogie.
730 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
731 ov_callbacks callbacks){
732 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
734 return _ov_open2(vf);
737 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
738 ov_callbacks callbacks = {
739 (size_t (*)(void *, size_t, size_t, void *)) fread,
740 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
741 (int (*)(void *)) fclose,
742 (long (*)(void *)) ftell
745 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
748 /* Only partially open the vorbis file; test for Vorbisness, and load
749 the headers for the first chain. Do not seek (although test for
750 seekability). Use ov_test_open to finish opening the file, else
751 ov_clear to close/free it. Same return codes as open. */
753 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
754 ov_callbacks callbacks)
756 return _ov_open1(f,vf,initial,ibytes,callbacks);
759 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
760 ov_callbacks callbacks = {
761 (size_t (*)(void *, size_t, size_t, void *)) fread,
762 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
763 (int (*)(void *)) fclose,
764 (long (*)(void *)) ftell
767 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
770 int ov_test_open(OggVorbis_File *vf){
771 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
772 return _ov_open2(vf);
775 /* How many logical bitstreams in this physical bitstream? */
776 long ov_streams(OggVorbis_File *vf){
780 /* Is the FILE * associated with vf seekable? */
781 long ov_seekable(OggVorbis_File *vf){
785 /* returns the bitrate for a given logical bitstream or the entire
786 physical bitstream. If the file is open for random access, it will
787 find the *actual* average bitrate. If the file is streaming, it
788 returns the nominal bitrate (if set) else the average of the
789 upper/lower bounds (if set) else -1 (unset).
791 If you want the actual bitrate field settings, get them from the
792 vorbis_info structs */
794 long ov_bitrate(OggVorbis_File *vf,int i){
795 if(vf->ready_state<OPENED)return(OV_EINVAL);
796 if(i>=vf->links)return(OV_EINVAL);
797 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
802 for(i=0;i<vf->links;i++)
803 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
804 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
805 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
806 * so this is slightly transformed to make it work.
808 br = bits/ov_time_total(vf,-1);
812 /* return the actual bitrate */
813 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
815 /* return nominal if set */
816 if(vf->vi[i].bitrate_nominal>0){
817 return vf->vi[i].bitrate_nominal;
819 if(vf->vi[i].bitrate_upper>0){
820 if(vf->vi[i].bitrate_lower>0){
821 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
823 return vf->vi[i].bitrate_upper;
832 /* returns the actual bitrate since last call. returns -1 if no
833 additional data to offer since last call (or at beginning of stream),
834 EINVAL if stream is only partially open
836 long ov_bitrate_instant(OggVorbis_File *vf){
837 int link=(vf->seekable?vf->current_link:0);
839 if(vf->ready_state<OPENED)return(OV_EINVAL);
840 if(vf->samptrack==0)return(OV_FALSE);
841 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
848 long ov_serialnumber(OggVorbis_File *vf,int i){
849 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
850 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
852 return(vf->current_serialno);
854 return(vf->serialnos[i]);
858 /* returns: total raw (compressed) length of content if i==-1
859 raw (compressed) length of that logical bitstream for i==0 to n
860 OV_EINVAL if the stream is not seekable (we can't know the length)
861 or if stream is only partially open
863 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
864 if(vf->ready_state<OPENED)return(OV_EINVAL);
865 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
869 for(i=0;i<vf->links;i++)
870 acc+=ov_raw_total(vf,i);
873 return(vf->offsets[i+1]-vf->offsets[i]);
877 /* returns: total PCM length (samples) of content if i==-1 PCM length
878 (samples) of that logical bitstream for i==0 to n
879 OV_EINVAL if the stream is not seekable (we can't know the
880 length) or only partially open
882 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
883 if(vf->ready_state<OPENED)return(OV_EINVAL);
884 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
888 for(i=0;i<vf->links;i++)
889 acc+=ov_pcm_total(vf,i);
892 return(vf->pcmlengths[i*2+1]);
896 /* returns: total seconds of content if i==-1
897 seconds in that logical bitstream for i==0 to n
898 OV_EINVAL if the stream is not seekable (we can't know the
899 length) or only partially open
901 double ov_time_total(OggVorbis_File *vf,int i){
902 if(vf->ready_state<OPENED)return(OV_EINVAL);
903 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
907 for(i=0;i<vf->links;i++)
908 acc+=ov_time_total(vf,i);
911 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
915 /* seek to an offset relative to the *compressed* data. This also
916 scans packets to update the PCM cursor. It will cross a logical
917 bitstream boundary, but only if it can't get any packets out of the
918 tail of the bitstream we seek to (so no surprises).
920 returns zero on success, nonzero on failure */
922 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
923 ogg_stream_state work_os;
927 if(vf->ready_state<OPENED)return(OV_EINVAL);
929 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
931 if(pos<0 || pos>vf->end)return(OV_EINVAL);
933 /* don't yet clear out decoding machine (if it's initialized), in
934 the case we're in the same link. Restart the decode lapping, and
935 let _fetch_and_process_packet deal with a potential bitstream
938 ogg_stream_reset_serialno(&vf->os,
939 vf->current_serialno); /* must set serialno */
943 _seek_helper(vf,pos);
945 /* we need to make sure the pcm_offset is set, but we don't want to
946 advance the raw cursor past good packets just to get to the first
947 with a granulepos. That's not equivalent behavior to beginning
948 decoding as immediately after the seek position as possible.
950 So, a hack. We use two stream states; a local scratch state and
951 the shared vf->os stream state. We use the local state to
952 scan, and the shared state as a buffer for later decode.
954 Unfortuantely, on the last page we still advance to last packet
955 because the granulepos on the last page is not necessarily on a
956 packet boundary, and we need to make sure the granpos is
968 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
969 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
970 return from not necessarily
971 starting from the beginning */
974 if(vf->ready_state>=STREAMSET){
975 /* snarf/scan a packet if we can */
976 int result=ogg_stream_packetout(&work_os,&op);
980 if(vf->vi[vf->current_link].codec_setup){
981 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
983 ogg_stream_packetout(&vf->os,NULL);
988 ogg_stream_packetout(&vf->os,NULL);
990 if(lastblock)accblock+=(lastblock+thisblock)>>2;
992 if(op.granulepos!=-1){
993 int i,link=vf->current_link;
994 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
995 if(granulepos<0)granulepos=0;
998 granulepos+=vf->pcmlengths[i*2+1];
999 vf->pcm_offset=granulepos-accblock;
1002 lastblock=thisblock;
1008 if(_get_next_page(vf,&og,-1)<0){
1009 vf->pcm_offset=ov_pcm_total(vf,-1);
1013 /* huh? Bogus stream with packets but no granulepos */
1018 /* has our decoding just traversed a bitstream boundary? */
1019 if(vf->ready_state>=STREAMSET)
1020 if(vf->current_serialno!=ogg_page_serialno(&og)){
1021 _decode_clear(vf); /* clear out stream state */
1022 ogg_stream_clear(&work_os);
1025 if(vf->ready_state<STREAMSET){
1028 vf->current_serialno=ogg_page_serialno(&og);
1029 for(link=0;link<vf->links;link++)
1030 if(vf->serialnos[link]==vf->current_serialno)break;
1031 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1033 machine uninitialized */
1034 vf->current_link=link;
1036 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1037 ogg_stream_reset_serialno(&work_os,vf->current_serialno);
1038 vf->ready_state=STREAMSET;
1042 ogg_stream_pagein(&vf->os,&og);
1043 ogg_stream_pagein(&work_os,&og);
1044 eosflag=ogg_page_eos(&og);
1048 ogg_stream_clear(&work_os);
1052 /* dump the machine so we're in a known state */
1054 ogg_stream_clear(&work_os);
1059 /* Page granularity seek (faster than sample granularity because we
1060 don't do the last bit of decode to find a specific sample).
1062 Seek to the last [granule marked] page preceeding the specified pos
1063 location, such that decoding past the returned point will quickly
1064 arrive at the requested position. */
1065 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1067 ogg_int64_t result=0;
1068 ogg_int64_t total=ov_pcm_total(vf,-1);
1070 if(vf->ready_state<OPENED)return(OV_EINVAL);
1071 if(!vf->seekable)return(OV_ENOSEEK);
1073 if(pos<0 || pos>total)return(OV_EINVAL);
1075 /* which bitstream section does this pcm offset occur in? */
1076 for(link=vf->links-1;link>=0;link--){
1077 total-=vf->pcmlengths[link*2+1];
1078 if(pos>=total)break;
1081 /* search within the logical bitstream for the page with the highest
1082 pcm_pos preceeding (or equal to) pos. There is a danger here;
1083 missing pages or incorrect frame number information in the
1084 bitstream could make our task impossible. Account for that (it
1085 would be an error condition) */
1087 /* new search algorithm by HB (Nicholas Vinen) */
1089 ogg_int64_t end=vf->offsets[link+1];
1090 ogg_int64_t begin=vf->offsets[link];
1091 ogg_int64_t begintime = vf->pcmlengths[link*2];
1092 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1093 ogg_int64_t target=pos-total+begintime;
1094 ogg_int64_t best=begin;
1100 if(end-begin<CHUNKSIZE){
1103 /* take a (pretty decent) guess. */
1105 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1110 _seek_helper(vf,bisect);
1113 result=_get_next_page(vf,&og,end-vf->offset);
1114 if(result==OV_EREAD) goto seek_error;
1117 end=begin; /* found it */
1119 if(bisect==0) goto seek_error;
1121 if(bisect<=begin)bisect=begin+1;
1122 _seek_helper(vf,bisect);
1125 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1126 if(granulepos==-1)continue;
1127 if(granulepos<target){
1128 best=result; /* raw offset of packet with granulepos */
1129 begin=vf->offset; /* raw offset of next page */
1130 begintime=granulepos;
1132 if(target-begintime>44100)break;
1133 bisect=begin; /* *not* begin + 1 */
1136 end=begin; /* found it */
1138 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1140 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1141 if(bisect<=begin)bisect=begin+1;
1142 _seek_helper(vf,bisect);
1154 /* found our page. seek to it, update pcm offset. Easier case than
1155 raw_seek, don't keep packets preceeding granulepos. */
1161 _seek_helper(vf,best);
1164 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1166 if(link!=vf->current_link){
1167 /* Different link; dump entire decode machine */
1170 vf->current_link=link;
1171 vf->current_serialno=ogg_page_serialno(&og);
1172 vf->ready_state=STREAMSET;
1175 _decode_restart(vf);
1178 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1179 ogg_stream_pagein(&vf->os,&og);
1181 /* pull out all but last packet; the one with granulepos */
1183 result=ogg_stream_packetpeek(&vf->os,&op);
1185 /* !!! the packet finishing this page originated on a
1186 preceeding page. Keep fetching previous pages until we
1187 get one with a granulepos or without the 'continued' flag
1188 set. Then just use raw_seek for simplicity. */
1190 //_decode_restart(vf);
1191 _seek_helper(vf,best);
1194 result=_get_prev_page(vf,&og);
1195 if(result<0) goto seek_error;
1196 if(ogg_page_granulepos(&og)>-1 ||
1197 !ogg_page_continued(&og)){
1198 return ov_raw_seek(vf,result);
1204 result = OV_EBADPACKET;
1207 if(op.granulepos!=-1){
1208 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1209 if(vf->pcm_offset<0)vf->pcm_offset=0;
1210 vf->pcm_offset+=total;
1213 result=ogg_stream_packetout(&vf->os,NULL);
1219 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1226 /* dump machine so we're in a known state */
1232 /* seek to a sample offset relative to the decompressed pcm stream
1233 returns zero on success, nonzero on failure */
1235 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1236 int thisblock,lastblock=0;
1237 int ret=ov_pcm_seek_page(vf,pos);
1238 if(ret<0)return(ret);
1239 _make_decode_ready(vf);
1241 /* discard leading packets we don't need for the lapping of the
1242 position we want; don't decode them */
1248 int ret=ogg_stream_packetpeek(&vf->os,&op);
1250 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1252 ogg_stream_packetout(&vf->os,NULL);
1253 continue; /* non audio packet */
1255 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1257 if(vf->pcm_offset+((thisblock+
1258 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1260 /* remove the packet from packet queue and track its granulepos */
1261 ogg_stream_packetout(&vf->os,NULL);
1262 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1265 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1267 /* end of logical stream case is hard, especially with exact
1268 length positioning. */
1270 if(op.granulepos>-1){
1272 /* always believe the stream markers */
1273 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1274 if(vf->pcm_offset<0)vf->pcm_offset=0;
1275 for(i=0;i<vf->current_link;i++)
1276 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1279 lastblock=thisblock;
1282 if(ret<0 && ret!=OV_HOLE)break;
1284 /* suck in a new page */
1285 if(_get_next_page(vf,&og,-1)<0)break;
1286 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1288 if(vf->ready_state<STREAMSET){
1291 vf->current_serialno=ogg_page_serialno(&og);
1292 for(link=0;link<vf->links;link++)
1293 if(vf->serialnos[link]==vf->current_serialno)break;
1294 if(link==vf->links)return(OV_EBADLINK);
1295 vf->current_link=link;
1297 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1298 vf->ready_state=STREAMSET;
1299 _make_decode_ready(vf);
1303 ogg_stream_pagein(&vf->os,&og);
1307 /* discard samples until we reach the desired position. Crossing a
1308 logical bitstream boundary with abandon is OK. */
1309 while(vf->pcm_offset<pos){
1310 ogg_int64_t target=pos-vf->pcm_offset;
1311 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1313 if(samples>target)samples=target;
1314 vorbis_synthesis_read(&vf->vd,samples);
1315 vf->pcm_offset+=samples;
1318 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1319 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1324 /* seek to a playback time relative to the decompressed pcm stream
1325 returns zero on success, nonzero on failure */
1326 int ov_time_seek(OggVorbis_File *vf,double seconds){
1327 /* translate time to PCM position and call ov_pcm_seek */
1330 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1331 double time_total=ov_time_total(vf,-1);
1333 if(vf->ready_state<OPENED)return(OV_EINVAL);
1334 if(!vf->seekable)return(OV_ENOSEEK);
1335 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1337 /* which bitstream section does this time offset occur in? */
1338 for(link=vf->links-1;link>=0;link--){
1339 pcm_total-=vf->pcmlengths[link*2+1];
1340 time_total-=ov_time_total(vf,link);
1341 if(seconds>=time_total)break;
1344 /* enough information to convert time offset to pcm offset */
1346 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1347 return(ov_pcm_seek(vf,target));
1351 /* page-granularity version of ov_time_seek
1352 returns zero on success, nonzero on failure */
1353 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1354 /* translate time to PCM position and call ov_pcm_seek */
1357 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1358 double time_total=ov_time_total(vf,-1);
1360 if(vf->ready_state<OPENED)return(OV_EINVAL);
1361 if(!vf->seekable)return(OV_ENOSEEK);
1362 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1364 /* which bitstream section does this time offset occur in? */
1365 for(link=vf->links-1;link>=0;link--){
1366 pcm_total-=vf->pcmlengths[link*2+1];
1367 time_total-=ov_time_total(vf,link);
1368 if(seconds>=time_total)break;
1371 /* enough information to convert time offset to pcm offset */
1373 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1374 return(ov_pcm_seek_page(vf,target));
1378 /* tell the current stream offset cursor. Note that seek followed by
1379 tell will likely not give the set offset due to caching */
1380 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1381 if(vf->ready_state<OPENED)return(OV_EINVAL);
1385 /* return PCM offset (sample) of next PCM sample to be read */
1386 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1387 if(vf->ready_state<OPENED)return(OV_EINVAL);
1388 return(vf->pcm_offset);
1391 /* return time offset (seconds) of next PCM sample to be read */
1392 double ov_time_tell(OggVorbis_File *vf){
1394 ogg_int64_t pcm_total=0;
1395 double time_total=0.f;
1397 if(vf->ready_state<OPENED)return(OV_EINVAL);
1399 pcm_total=ov_pcm_total(vf,-1);
1400 time_total=ov_time_total(vf,-1);
1402 /* which bitstream section does this time offset occur in? */
1403 for(link=vf->links-1;link>=0;link--){
1404 pcm_total-=vf->pcmlengths[link*2+1];
1405 time_total-=ov_time_total(vf,link);
1406 if(vf->pcm_offset>=pcm_total)break;
1410 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1413 /* link: -1) return the vorbis_info struct for the bitstream section
1414 currently being decoded
1415 0-n) to request information for a specific bitstream section
1417 In the case of a non-seekable bitstream, any call returns the
1418 current bitstream. NULL in the case that the machine is not
1421 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1424 if(vf->ready_state>=STREAMSET)
1425 return vf->vi+vf->current_link;
1438 /* grr, strong typing, grr, no templates/inheritence, grr */
1439 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1442 if(vf->ready_state>=STREAMSET)
1443 return vf->vc+vf->current_link;
1456 static int host_is_big_endian() {
1457 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1458 unsigned char *bytewise = (unsigned char *)&pattern;
1459 if (bytewise[0] == 0xfe) return 1;
1463 /* up to this point, everything could more or less hide the multiple
1464 logical bitstream nature of chaining from the toplevel application
1465 if the toplevel application didn't particularly care. However, at
1466 the point that we actually read audio back, the multiple-section
1467 nature must surface: Multiple bitstream sections do not necessarily
1468 have to have the same number of channels or sampling rate.
1470 ov_read returns the sequential logical bitstream number currently
1471 being decoded along with the PCM data in order that the toplevel
1472 application can take action on channel/sample rate changes. This
1473 number will be incremented even for streamed (non-seekable) streams
1474 (for seekable streams, it represents the actual logical bitstream
1475 index within the physical bitstream. Note that the accessor
1476 functions above are aware of this dichotomy).
1478 input values: buffer) a buffer to hold packed PCM data for return
1479 length) the byte length requested to be placed into buffer
1480 bigendianp) should the data be packed LSB first (0) or
1482 word) word size for output. currently 1 (byte) or
1485 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1487 n) number of bytes of PCM actually returned. The
1488 below works on a packet-by-packet basis, so the
1489 return length is not related to the 'length' passed
1490 in, just guaranteed to fit.
1492 *section) set to the logical bitstream number */
1494 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1495 int bigendianp,int word,int sgned,int *bitstream){
1497 int host_endian = host_is_big_endian();
1502 if(vf->ready_state<OPENED)return(OV_EINVAL);
1505 if(vf->ready_state==INITSET){
1506 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1510 /* suck in another packet */
1512 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1523 /* yay! proceed to pack data into the byte buffer */
1525 long channels=ov_info(vf,-1)->channels;
1526 long bytespersample=word * channels;
1527 vorbis_fpu_control fpu;
1528 if(samples>length/bytespersample)samples=length/bytespersample;
1533 /* a tight loop to pack each size */
1537 int off=(sgned?0:128);
1538 vorbis_fpu_setround(&fpu);
1539 for(j=0;j<samples;j++)
1540 for(i=0;i<channels;i++){
1541 val=vorbis_ftoi(pcm[i][j]*128.f);
1543 else if(val<-128)val=-128;
1546 vorbis_fpu_restore(fpu);
1548 int off=(sgned?0:32768);
1550 if(host_endian==bigendianp){
1553 vorbis_fpu_setround(&fpu);
1554 for(i=0;i<channels;i++) { /* It's faster in this order */
1556 short *dest=((short *)buffer)+i;
1557 for(j=0;j<samples;j++) {
1558 val=vorbis_ftoi(src[j]*32768.f);
1559 if(val>32767)val=32767;
1560 else if(val<-32768)val=-32768;
1565 vorbis_fpu_restore(fpu);
1569 vorbis_fpu_setround(&fpu);
1570 for(i=0;i<channels;i++) {
1572 short *dest=((short *)buffer)+i;
1573 for(j=0;j<samples;j++) {
1574 val=vorbis_ftoi(src[j]*32768.f);
1575 if(val>32767)val=32767;
1576 else if(val<-32768)val=-32768;
1581 vorbis_fpu_restore(fpu);
1584 }else if(bigendianp){
1586 vorbis_fpu_setround(&fpu);
1587 for(j=0;j<samples;j++)
1588 for(i=0;i<channels;i++){
1589 val=vorbis_ftoi(pcm[i][j]*32768.f);
1590 if(val>32767)val=32767;
1591 else if(val<-32768)val=-32768;
1594 *buffer++=(val&0xff);
1596 vorbis_fpu_restore(fpu);
1600 vorbis_fpu_setround(&fpu);
1601 for(j=0;j<samples;j++)
1602 for(i=0;i<channels;i++){
1603 val=vorbis_ftoi(pcm[i][j]*32768.f);
1604 if(val>32767)val=32767;
1605 else if(val<-32768)val=-32768;
1607 *buffer++=(val&0xff);
1610 vorbis_fpu_restore(fpu);
1616 vorbis_synthesis_read(&vf->vd,samples);
1617 vf->pcm_offset+=samples;
1618 if(bitstream)*bitstream=vf->current_link;
1619 return(samples*bytespersample);
1625 /* input values: pcm_channels) a float vector per channel of output
1626 length) the sample length being read by the app
1628 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1630 n) number of samples of PCM actually returned. The
1631 below works on a packet-by-packet basis, so the
1632 return length is not related to the 'length' passed
1633 in, just guaranteed to fit.
1635 *section) set to the logical bitstream number */
1639 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1642 if(vf->ready_state<OPENED)return(OV_EINVAL);
1645 if(vf->ready_state==INITSET){
1647 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1649 if(pcm_channels)*pcm_channels=pcm;
1650 if(samples>length)samples=length;
1651 vorbis_synthesis_read(&vf->vd,samples);
1652 vf->pcm_offset+=samples;
1653 if(bitstream)*bitstream=vf->current_link;
1659 /* suck in another packet */
1661 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1662 if(ret==OV_EOF)return(0);
1663 if(ret<=0)return(ret);
1669 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1671 static void _vorbis_splice(float *d,float *s,
1672 vorbis_dsp_state *v,int W){
1674 vorbis_info *vi=v->vi;
1675 int n=vorbis_info_blocksize(vi,0)/2;
1676 float *w=vorbis_window(v,W);
1682 d[i]=d[i]*wd + s[i]*ws;
1688 /* this sets up crosslapping of a sample by using trailing data from
1689 sample 1 and lapping it into the windowing buffer of the second */
1691 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
1692 vorbis_info *vi1,*vi2;
1693 vorbis_dsp_state *vd1=&vf1->vd;
1694 vorbis_dsp_state *vd2=&vf2->vd;
1697 vorbis_dsp_state *winstate;
1698 int lapsize,lapcount=0,i,j;
1700 /* first enforce some level of sanity... */
1701 /* we need to know that sample rate & channels match. To do that,
1702 we need to verify the streams are actually initialized; the call
1703 is not just to be used for end-to-beginning lapping */
1705 if(vf1->ready_state<OPENED)return(OV_EINVAL);
1706 if(vf2->ready_state<OPENED)return(OV_EINVAL);
1708 /* make sure vf1 is INITSET */
1710 if(vf1->ready_state==INITSET)break;
1711 /* suck in another packet */
1713 int ret=_fetch_and_process_packet(vf1,NULL,1,0);
1714 if(ret<0)return(ret);
1718 /* make sure vf2 is INITSET and that we have a primed buffer; if
1719 we're crosslapping at a stream section boundary, this also makes
1720 sure we're sanity checking against the right stream information */
1723 if(vf2->ready_state==INITSET)
1724 if(vorbis_synthesis_pcmout(vd2,NULL))break;
1726 /* suck in another packet */
1728 int ret=_fetch_and_process_packet(vf2,NULL,1,0);
1729 if(ret<0)return(ret);
1733 /* sanity-check settings */
1734 vi1=ov_info(vf1,-1);
1735 vi2=ov_info(vf2,-1);
1736 if(vi1->channels != vi2->channels ||
1737 vi1->rate != vi2->rate) return OV_EINVAL;
1739 /* begin by grabbing enough data for lapping from vf1; this may be
1740 in the form of unreturned, already-decoded pcm, remaining PCM we
1741 will need to decode, or synthetic postextrapolation from last
1744 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
1745 lapsize=vorbis_info_blocksize(vi1,0);
1746 if(vorbis_info_blocksize(vi2,0)<lapsize){
1747 lapsize=vorbis_info_blocksize(vi2,0)/2;
1754 for(i=0;i<vi1->channels;i++)
1755 lappcm[i]=alloca(sizeof(**lappcm)*lapsize);
1757 /* try first to decode the lapping data */
1758 while(lapcount<lapsize){
1759 int samples=vorbis_synthesis_pcmout(vd1,&pcm);
1761 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1762 for(i=0;i<vi1->channels;i++)
1763 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1765 vorbis_synthesis_read(vd1,samples);
1767 /* suck in another packet */
1768 int ret=_fetch_and_process_packet(vf1,NULL,1,0); /* do *not* span */
1769 if(ret==OV_EOF)break;
1772 if(lapcount<lapsize){
1773 /* failed to get lapping data from normal decode; pry it from the
1774 postextrapolation buffering, or the second half of the MDCT
1775 from the last packet */
1776 int samples=vorbis_synthesis_lapout(&vf1->vd,&pcm);
1777 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1778 for(i=0;i<vi1->channels;i++)
1779 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1782 if(lapcount<lapsize)return OV_EFAULT;
1785 /* have a lapping buffer from vf1; now to splice it into the lapping
1788 /* consolidate and expose the buffer. */
1789 if(vorbis_synthesis_lapout(vd2,&pcm)<lapsize)return OV_EFAULT;
1792 for(j=0;j<vi1->channels;j++){
1795 _vorbis_splice(d,s,winstate,0);