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.66 2003/03/02 21:32:00 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 /* fetch and process a packet. Handles the case where we're at a
448 bitstream boundary and dumps the decoding machine. If the decoding
449 machine is unloaded, it loads it. It also keeps pcm_offset up to
450 date (seek and read both use this. seek uses a special hack with
453 return: <0) error, OV_HOLE (lost packet) or OV_EOF
454 0) need more data (only if readp==0)
458 static int _fetch_and_process_packet(OggVorbis_File *vf,
464 /* handle one packet. Try to fetch it from current stream state */
465 /* extract packets from page */
468 /* process a packet if we can. If the machine isn't loaded,
470 if(vf->ready_state==INITSET){
473 ogg_packet *op_ptr=(op_in?op_in:&op);
474 int result=ogg_stream_packetout(&vf->os,op_ptr);
475 ogg_int64_t granulepos;
478 if(result==-1)return(OV_HOLE); /* hole in the data. */
480 /* got a packet. process it */
481 granulepos=op_ptr->granulepos;
482 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
484 header packets aren't
487 vorbis_synthesis will
490 /* suck in the synthesis data and track bitrate */
492 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
493 /* for proper use of libvorbis within libvorbisfile,
494 oldsamples will always be zero. */
495 if(oldsamples)return(OV_EFAULT);
497 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
498 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
499 vf->bittrack+=op_ptr->bytes*8;
502 /* update the pcm offset. */
503 if(granulepos!=-1 && !op_ptr->e_o_s){
504 int link=(vf->seekable?vf->current_link:0);
507 /* this packet has a pcm_offset on it (the last packet
508 completed on a page carries the offset) After processing
509 (above), we know the pcm position of the *last* sample
510 ready to be returned. Find the offset of the *first*
512 As an aside, this trick is inaccurate if we begin
513 reading anew right at the last page; the end-of-stream
514 granulepos declares the last frame in the stream, and the
515 last packet of the last page may be a partial frame.
516 So, we need a previous granulepos from an in-sequence page
517 to have a reference point. Thus the !op_ptr->e_o_s clause
520 if(vf->seekable && link>0)
521 granulepos-=vf->pcmlengths[link*2];
522 if(granulepos<0)granulepos=0; /* actually, this
523 shouldn't be possible
524 here unless the stream
527 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
531 granulepos+=vf->pcmlengths[i*2+1];
532 vf->pcm_offset=granulepos;
542 if(vf->ready_state>=OPENED){
544 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
546 /* bitrate tracking; add the header's bytes here, the body bytes
547 are done by packet above */
548 vf->bittrack+=og.header_len*8;
550 /* has our decoding just traversed a bitstream boundary? */
551 if(vf->ready_state==INITSET){
552 if(vf->current_serialno!=ogg_page_serialno(&og)){
553 if(!spanp)return(OV_EOF);
558 vorbis_info_clear(vf->vi);
559 vorbis_comment_clear(vf->vc);
565 /* Do we need to load a new machine before submitting the page? */
566 /* This is different in the seekable and non-seekable cases.
568 In the seekable case, we already have all the header
569 information loaded and cached; we just initialize the machine
570 with it and continue on our merry way.
572 In the non-seekable (streaming) case, we'll only be at a
573 boundary if we just left the previous logical bitstream and
574 we're now nominally at the header of the next bitstream
577 if(vf->ready_state!=INITSET){
580 if(vf->ready_state<STREAMSET){
582 vf->current_serialno=ogg_page_serialno(&og);
584 /* match the serialno to bitstream section. We use this rather than
585 offset positions to avoid problems near logical bitstream
587 for(link=0;link<vf->links;link++)
588 if(vf->serialnos[link]==vf->current_serialno)break;
589 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
594 vf->current_link=link;
596 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
597 vf->ready_state=STREAMSET;
600 /* we're streaming */
601 /* fetch the three header packets, build the info struct */
603 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
610 _make_decode_ready(vf);
612 ogg_stream_pagein(&vf->os,&og);
616 /* if, eg, 64 bit stdio is configured by default, this will build with
618 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
619 if(f==NULL)return(-1);
620 return fseek(f,off,whence);
623 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
624 long ibytes, ov_callbacks callbacks){
625 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
628 memset(vf,0,sizeof(*vf));
630 vf->callbacks = callbacks;
632 /* init the framing state */
633 ogg_sync_init(&vf->oy);
635 /* perhaps some data was previously read into a buffer for testing
636 against other stream types. Allow initialization from this
637 previously read data (as we may be reading from a non-seekable
640 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
641 memcpy(buffer,initial,ibytes);
642 ogg_sync_wrote(&vf->oy,ibytes);
645 /* can we seek? Stevens suggests the seek test was portable */
646 if(offsettest!=-1)vf->seekable=1;
648 /* No seeking yet; Set up a 'single' (current) logical bitstream
649 entry for partial open */
651 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
652 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
653 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
655 /* Try to fetch the headers, maintaining all the storage */
656 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
659 }else if(vf->ready_state < PARTOPEN)
660 vf->ready_state=PARTOPEN;
664 static int _ov_open2(OggVorbis_File *vf){
665 if(vf->ready_state < OPENED)
666 vf->ready_state=OPENED;
668 int ret=_open_seekable2(vf);
679 /* clear out the OggVorbis_File struct */
680 int ov_clear(OggVorbis_File *vf){
682 vorbis_block_clear(&vf->vb);
683 vorbis_dsp_clear(&vf->vd);
684 ogg_stream_clear(&vf->os);
686 if(vf->vi && vf->links){
688 for(i=0;i<vf->links;i++){
689 vorbis_info_clear(vf->vi+i);
690 vorbis_comment_clear(vf->vc+i);
695 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
696 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
697 if(vf->serialnos)_ogg_free(vf->serialnos);
698 if(vf->offsets)_ogg_free(vf->offsets);
699 ogg_sync_clear(&vf->oy);
700 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
701 memset(vf,0,sizeof(*vf));
709 /* inspects the OggVorbis file and finds/documents all the logical
710 bitstreams contained in it. Tries to be tolerant of logical
711 bitstream sections that are truncated/woogie.
717 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
718 ov_callbacks callbacks){
719 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
721 return _ov_open2(vf);
724 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
725 ov_callbacks callbacks = {
726 (size_t (*)(void *, size_t, size_t, void *)) fread,
727 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
728 (int (*)(void *)) fclose,
729 (long (*)(void *)) ftell
732 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
735 /* Only partially open the vorbis file; test for Vorbisness, and load
736 the headers for the first chain. Do not seek (although test for
737 seekability). Use ov_test_open to finish opening the file, else
738 ov_clear to close/free it. Same return codes as open. */
740 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
741 ov_callbacks callbacks)
743 return _ov_open1(f,vf,initial,ibytes,callbacks);
746 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
747 ov_callbacks callbacks = {
748 (size_t (*)(void *, size_t, size_t, void *)) fread,
749 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
750 (int (*)(void *)) fclose,
751 (long (*)(void *)) ftell
754 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
757 int ov_test_open(OggVorbis_File *vf){
758 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
759 return _ov_open2(vf);
762 /* How many logical bitstreams in this physical bitstream? */
763 long ov_streams(OggVorbis_File *vf){
767 /* Is the FILE * associated with vf seekable? */
768 long ov_seekable(OggVorbis_File *vf){
772 /* returns the bitrate for a given logical bitstream or the entire
773 physical bitstream. If the file is open for random access, it will
774 find the *actual* average bitrate. If the file is streaming, it
775 returns the nominal bitrate (if set) else the average of the
776 upper/lower bounds (if set) else -1 (unset).
778 If you want the actual bitrate field settings, get them from the
779 vorbis_info structs */
781 long ov_bitrate(OggVorbis_File *vf,int i){
782 if(vf->ready_state<OPENED)return(OV_EINVAL);
783 if(i>=vf->links)return(OV_EINVAL);
784 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
789 for(i=0;i<vf->links;i++)
790 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
791 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
792 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
793 * so this is slightly transformed to make it work.
795 br = bits/ov_time_total(vf,-1);
799 /* return the actual bitrate */
800 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
802 /* return nominal if set */
803 if(vf->vi[i].bitrate_nominal>0){
804 return vf->vi[i].bitrate_nominal;
806 if(vf->vi[i].bitrate_upper>0){
807 if(vf->vi[i].bitrate_lower>0){
808 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
810 return vf->vi[i].bitrate_upper;
819 /* returns the actual bitrate since last call. returns -1 if no
820 additional data to offer since last call (or at beginning of stream),
821 EINVAL if stream is only partially open
823 long ov_bitrate_instant(OggVorbis_File *vf){
824 int link=(vf->seekable?vf->current_link:0);
826 if(vf->ready_state<OPENED)return(OV_EINVAL);
827 if(vf->samptrack==0)return(OV_FALSE);
828 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
835 long ov_serialnumber(OggVorbis_File *vf,int i){
836 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
837 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
839 return(vf->current_serialno);
841 return(vf->serialnos[i]);
845 /* returns: total raw (compressed) length of content if i==-1
846 raw (compressed) length of that logical bitstream for i==0 to n
847 OV_EINVAL if the stream is not seekable (we can't know the length)
848 or if stream is only partially open
850 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
851 if(vf->ready_state<OPENED)return(OV_EINVAL);
852 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
856 for(i=0;i<vf->links;i++)
857 acc+=ov_raw_total(vf,i);
860 return(vf->offsets[i+1]-vf->offsets[i]);
864 /* returns: total PCM length (samples) of content if i==-1 PCM length
865 (samples) of that logical bitstream for i==0 to n
866 OV_EINVAL if the stream is not seekable (we can't know the
867 length) or only partially open
869 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
870 if(vf->ready_state<OPENED)return(OV_EINVAL);
871 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
875 for(i=0;i<vf->links;i++)
876 acc+=ov_pcm_total(vf,i);
879 return(vf->pcmlengths[i*2+1]);
883 /* returns: total seconds of content if i==-1
884 seconds in that logical bitstream for i==0 to n
885 OV_EINVAL if the stream is not seekable (we can't know the
886 length) or only partially open
888 double ov_time_total(OggVorbis_File *vf,int i){
889 if(vf->ready_state<OPENED)return(OV_EINVAL);
890 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
894 for(i=0;i<vf->links;i++)
895 acc+=ov_time_total(vf,i);
898 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
902 /* seek to an offset relative to the *compressed* data. This also
903 scans packets to update the PCM cursor. It will cross a logical
904 bitstream boundary, but only if it can't get any packets out of the
905 tail of the bitstream we seek to (so no surprises).
907 returns zero on success, nonzero on failure */
909 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
910 ogg_stream_state work_os;
912 if(vf->ready_state<OPENED)return(OV_EINVAL);
914 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
916 if(pos<0 || pos>vf->end)return(OV_EINVAL);
918 /* clear out decoding machine state */
922 _seek_helper(vf,pos);
924 /* we need to make sure the pcm_offset is set, but we don't want to
925 advance the raw cursor past good packets just to get to the first
926 with a granulepos. That's not equivalent behavior to beginning
927 decoding as immediately after the seek position as possible.
929 So, a hack. We use two stream states; a local scratch state and
930 the shared vf->os stream state. We use the local state to
931 scan, and the shared state as a buffer for later decode.
933 Unfortuantely, on the last page we still advance to last packet
934 because the granulepos on the last page is not necessarily on a
935 packet boundary, and we need to make sure the granpos is
947 ogg_stream_init(&work_os,-1); /* get the memory ready */
950 if(vf->ready_state==STREAMSET){
951 /* snarf/scan a packet if we can */
952 int result=ogg_stream_packetout(&work_os,&op);
956 if(vf->vi[vf->current_link].codec_setup)
957 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
959 ogg_stream_packetout(&vf->os,NULL);
961 if(lastblock)accblock+=(lastblock+thisblock)>>2;
963 if(op.granulepos!=-1){
964 int i,link=vf->current_link;
965 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
966 if(granulepos<0)granulepos=0;
969 granulepos+=vf->pcmlengths[i*2+1];
970 vf->pcm_offset=granulepos-accblock;
979 if(_get_next_page(vf,&og,-1)<0){
980 vf->pcm_offset=ov_pcm_total(vf,-1);
984 /* huh? Bogus stream with packets but no granulepos */
989 /* has our decoding just traversed a bitstream boundary? */
990 if(vf->ready_state==STREAMSET)
991 if(vf->current_serialno!=ogg_page_serialno(&og)){
992 _decode_clear(vf); /* clear out stream state */
993 ogg_stream_clear(&work_os);
996 if(vf->ready_state<STREAMSET){
999 vf->current_serialno=ogg_page_serialno(&og);
1000 for(link=0;link<vf->links;link++)
1001 if(vf->serialnos[link]==vf->current_serialno)break;
1002 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1004 machine uninitialized */
1005 vf->current_link=link;
1007 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1008 ogg_stream_reset_serialno(&work_os,vf->current_serialno);
1009 vf->ready_state=STREAMSET;
1013 ogg_stream_pagein(&vf->os,&og);
1014 ogg_stream_pagein(&work_os,&og);
1015 eosflag=ogg_page_eos(&og);
1019 ogg_stream_clear(&work_os);
1023 /* dump the machine so we're in a known state */
1025 ogg_stream_clear(&work_os);
1030 /* Page granularity seek (faster than sample granularity because we
1031 don't do the last bit of decode to find a specific sample).
1033 Seek to the last [granule marked] page preceeding the specified pos
1034 location, such that decoding past the returned point will quickly
1035 arrive at the requested position. */
1036 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1038 ogg_int64_t result=0;
1039 ogg_int64_t total=ov_pcm_total(vf,-1);
1041 if(vf->ready_state<OPENED)return(OV_EINVAL);
1042 if(!vf->seekable)return(OV_ENOSEEK);
1044 if(pos<0 || pos>total)return(OV_EINVAL);
1046 /* which bitstream section does this pcm offset occur in? */
1047 for(link=vf->links-1;link>=0;link--){
1048 total-=vf->pcmlengths[link*2+1];
1049 if(pos>=total)break;
1052 /* search within the logical bitstream for the page with the highest
1053 pcm_pos preceeding (or equal to) pos. There is a danger here;
1054 missing pages or incorrect frame number information in the
1055 bitstream could make our task impossible. Account for that (it
1056 would be an error condition) */
1058 /* new search algorithm by HB (Nicholas Vinen) */
1060 ogg_int64_t end=vf->offsets[link+1];
1061 ogg_int64_t begin=vf->offsets[link];
1062 ogg_int64_t begintime = vf->pcmlengths[link*2];
1063 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1064 ogg_int64_t target=pos-total+begintime;
1065 ogg_int64_t best=begin;
1071 if(end-begin<CHUNKSIZE){
1074 /* take a (pretty decent) guess. */
1076 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1081 _seek_helper(vf,bisect);
1084 result=_get_next_page(vf,&og,end-vf->offset);
1085 if(result==OV_EREAD) goto seek_error;
1088 end=begin; /* found it */
1090 if(bisect==0) goto seek_error;
1092 if(bisect<=begin)bisect=begin+1;
1093 _seek_helper(vf,bisect);
1096 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1097 if(granulepos==-1)continue;
1098 if(granulepos<target){
1099 best=result; /* raw offset of packet with granulepos */
1100 begin=vf->offset; /* raw offset of next page */
1101 begintime=granulepos;
1103 if(target-begintime>44100)break;
1104 bisect=begin; /* *not* begin + 1 */
1107 end=begin; /* found it */
1109 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1111 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1112 if(bisect<=begin)bisect=begin+1;
1113 _seek_helper(vf,bisect);
1125 /* found our page. seek to it, update pcm offset. Easier case than
1126 raw_seek, don't keep packets preceeding granulepos. */
1130 /* clear out decoding machine state */
1133 _seek_helper(vf,best);
1135 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1136 vf->current_serialno=ogg_page_serialno(&og);
1137 vf->current_link=link;
1139 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1140 vf->ready_state=STREAMSET;
1141 ogg_stream_pagein(&vf->os,&og);
1143 /* pull out all but last packet; the one with granulepos */
1145 result=ogg_stream_packetpeek(&vf->os,&op);
1147 /* !!! the packet finishing this page originated on a
1148 preceeding page. Keep fetching previous pages until we
1149 get one with a granulepos or without the 'continued' flag
1150 set. Then just use raw_seek for simplicity. */
1153 _seek_helper(vf,best);
1156 result=_get_prev_page(vf,&og);
1157 if(result<0) goto seek_error;
1158 if(ogg_page_granulepos(&og)>-1 ||
1159 !ogg_page_continued(&og)){
1160 return ov_raw_seek(vf,result);
1166 result = OV_EBADPACKET;
1169 if(op.granulepos!=-1){
1170 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1171 if(vf->pcm_offset<0)vf->pcm_offset=0;
1172 vf->pcm_offset+=total;
1175 result=ogg_stream_packetout(&vf->os,NULL);
1181 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1188 /* dump machine so we're in a known state */
1194 /* seek to a sample offset relative to the decompressed pcm stream
1195 returns zero on success, nonzero on failure */
1197 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1198 int thisblock,lastblock=0;
1199 int ret=ov_pcm_seek_page(vf,pos);
1200 if(ret<0)return(ret);
1201 _make_decode_ready(vf);
1203 /* discard leading packets we don't need for the lapping of the
1204 position we want; don't decode them */
1210 int ret=ogg_stream_packetpeek(&vf->os,&op);
1212 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1213 if(thisblock<0)thisblock=0; /* non audio packet */
1214 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1216 if(vf->pcm_offset+((thisblock+
1217 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1219 /* remove the packet from packet queue and track its granulepos */
1220 ogg_stream_packetout(&vf->os,NULL);
1221 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1224 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1226 /* end of logical stream case is hard, especially with exact
1227 length positioning. */
1229 if(op.granulepos>-1){
1231 /* always believe the stream markers */
1232 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1233 if(vf->pcm_offset<0)vf->pcm_offset=0;
1234 for(i=0;i<vf->current_link;i++)
1235 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1238 lastblock=thisblock;
1241 if(ret<0 && ret!=OV_HOLE)break;
1243 /* suck in a new page */
1244 if(_get_next_page(vf,&og,-1)<0)break;
1245 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1247 if(vf->ready_state<STREAMSET){
1250 vf->current_serialno=ogg_page_serialno(&og);
1251 for(link=0;link<vf->links;link++)
1252 if(vf->serialnos[link]==vf->current_serialno)break;
1253 if(link==vf->links)return(OV_EBADLINK);
1254 vf->current_link=link;
1256 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1257 vf->ready_state=STREAMSET;
1258 _make_decode_ready(vf);
1262 ogg_stream_pagein(&vf->os,&og);
1266 /* discard samples until we reach the desired position. Crossing a
1267 logical bitstream boundary with abandon is OK. */
1268 while(vf->pcm_offset<pos){
1269 ogg_int64_t target=pos-vf->pcm_offset;
1270 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1272 if(samples>target)samples=target;
1273 vorbis_synthesis_read(&vf->vd,samples);
1274 vf->pcm_offset+=samples;
1277 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1278 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1283 /* seek to a playback time relative to the decompressed pcm stream
1284 returns zero on success, nonzero on failure */
1285 int ov_time_seek(OggVorbis_File *vf,double seconds){
1286 /* translate time to PCM position and call ov_pcm_seek */
1289 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1290 double time_total=ov_time_total(vf,-1);
1292 if(vf->ready_state<OPENED)return(OV_EINVAL);
1293 if(!vf->seekable)return(OV_ENOSEEK);
1294 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1296 /* which bitstream section does this time offset occur in? */
1297 for(link=vf->links-1;link>=0;link--){
1298 pcm_total-=vf->pcmlengths[link*2+1];
1299 time_total-=ov_time_total(vf,link);
1300 if(seconds>=time_total)break;
1303 /* enough information to convert time offset to pcm offset */
1305 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1306 return(ov_pcm_seek(vf,target));
1310 /* page-granularity version of ov_time_seek
1311 returns zero on success, nonzero on failure */
1312 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1313 /* translate time to PCM position and call ov_pcm_seek */
1316 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1317 double time_total=ov_time_total(vf,-1);
1319 if(vf->ready_state<OPENED)return(OV_EINVAL);
1320 if(!vf->seekable)return(OV_ENOSEEK);
1321 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1323 /* which bitstream section does this time offset occur in? */
1324 for(link=vf->links-1;link>=0;link--){
1325 pcm_total-=vf->pcmlengths[link*2+1];
1326 time_total-=ov_time_total(vf,link);
1327 if(seconds>=time_total)break;
1330 /* enough information to convert time offset to pcm offset */
1332 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1333 return(ov_pcm_seek_page(vf,target));
1337 /* tell the current stream offset cursor. Note that seek followed by
1338 tell will likely not give the set offset due to caching */
1339 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1340 if(vf->ready_state<OPENED)return(OV_EINVAL);
1344 /* return PCM offset (sample) of next PCM sample to be read */
1345 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1346 if(vf->ready_state<OPENED)return(OV_EINVAL);
1347 return(vf->pcm_offset);
1350 /* return time offset (seconds) of next PCM sample to be read */
1351 double ov_time_tell(OggVorbis_File *vf){
1353 ogg_int64_t pcm_total=0;
1354 double time_total=0.f;
1356 if(vf->ready_state<OPENED)return(OV_EINVAL);
1358 pcm_total=ov_pcm_total(vf,-1);
1359 time_total=ov_time_total(vf,-1);
1361 /* which bitstream section does this time offset occur in? */
1362 for(link=vf->links-1;link>=0;link--){
1363 pcm_total-=vf->pcmlengths[link*2+1];
1364 time_total-=ov_time_total(vf,link);
1365 if(vf->pcm_offset>=pcm_total)break;
1369 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1372 /* link: -1) return the vorbis_info struct for the bitstream section
1373 currently being decoded
1374 0-n) to request information for a specific bitstream section
1376 In the case of a non-seekable bitstream, any call returns the
1377 current bitstream. NULL in the case that the machine is not
1380 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1383 if(vf->ready_state>=STREAMSET)
1384 return vf->vi+vf->current_link;
1397 /* grr, strong typing, grr, no templates/inheritence, grr */
1398 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1401 if(vf->ready_state>=STREAMSET)
1402 return vf->vc+vf->current_link;
1415 static int host_is_big_endian() {
1416 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1417 unsigned char *bytewise = (unsigned char *)&pattern;
1418 if (bytewise[0] == 0xfe) return 1;
1422 /* up to this point, everything could more or less hide the multiple
1423 logical bitstream nature of chaining from the toplevel application
1424 if the toplevel application didn't particularly care. However, at
1425 the point that we actually read audio back, the multiple-section
1426 nature must surface: Multiple bitstream sections do not necessarily
1427 have to have the same number of channels or sampling rate.
1429 ov_read returns the sequential logical bitstream number currently
1430 being decoded along with the PCM data in order that the toplevel
1431 application can take action on channel/sample rate changes. This
1432 number will be incremented even for streamed (non-seekable) streams
1433 (for seekable streams, it represents the actual logical bitstream
1434 index within the physical bitstream. Note that the accessor
1435 functions above are aware of this dichotomy).
1437 input values: buffer) a buffer to hold packed PCM data for return
1438 length) the byte length requested to be placed into buffer
1439 bigendianp) should the data be packed LSB first (0) or
1441 word) word size for output. currently 1 (byte) or
1444 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1446 n) number of bytes of PCM actually returned. The
1447 below works on a packet-by-packet basis, so the
1448 return length is not related to the 'length' passed
1449 in, just guaranteed to fit.
1451 *section) set to the logical bitstream number */
1453 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1454 int bigendianp,int word,int sgned,int *bitstream){
1456 int host_endian = host_is_big_endian();
1461 if(vf->ready_state<OPENED)return(OV_EINVAL);
1464 if(vf->ready_state==INITSET){
1465 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1469 /* suck in another packet */
1471 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1472 if(ret==OV_EOF)return(0);
1473 if(ret<=0)return(ret);
1480 /* yay! proceed to pack data into the byte buffer */
1482 long channels=ov_info(vf,-1)->channels;
1483 long bytespersample=word * channels;
1484 vorbis_fpu_control fpu;
1485 if(samples>length/bytespersample)samples=length/bytespersample;
1490 /* a tight loop to pack each size */
1494 int off=(sgned?0:128);
1495 vorbis_fpu_setround(&fpu);
1496 for(j=0;j<samples;j++)
1497 for(i=0;i<channels;i++){
1498 val=vorbis_ftoi(pcm[i][j]*128.f);
1500 else if(val<-128)val=-128;
1503 vorbis_fpu_restore(fpu);
1505 int off=(sgned?0:32768);
1507 if(host_endian==bigendianp){
1510 vorbis_fpu_setround(&fpu);
1511 for(i=0;i<channels;i++) { /* It's faster in this order */
1513 short *dest=((short *)buffer)+i;
1514 for(j=0;j<samples;j++) {
1515 val=vorbis_ftoi(src[j]*32768.f);
1516 if(val>32767)val=32767;
1517 else if(val<-32768)val=-32768;
1522 vorbis_fpu_restore(fpu);
1526 vorbis_fpu_setround(&fpu);
1527 for(i=0;i<channels;i++) {
1529 short *dest=((short *)buffer)+i;
1530 for(j=0;j<samples;j++) {
1531 val=vorbis_ftoi(src[j]*32768.f);
1532 if(val>32767)val=32767;
1533 else if(val<-32768)val=-32768;
1538 vorbis_fpu_restore(fpu);
1541 }else if(bigendianp){
1543 vorbis_fpu_setround(&fpu);
1544 for(j=0;j<samples;j++)
1545 for(i=0;i<channels;i++){
1546 val=vorbis_ftoi(pcm[i][j]*32768.f);
1547 if(val>32767)val=32767;
1548 else if(val<-32768)val=-32768;
1551 *buffer++=(val&0xff);
1553 vorbis_fpu_restore(fpu);
1557 vorbis_fpu_setround(&fpu);
1558 for(j=0;j<samples;j++)
1559 for(i=0;i<channels;i++){
1560 val=vorbis_ftoi(pcm[i][j]*32768.f);
1561 if(val>32767)val=32767;
1562 else if(val<-32768)val=-32768;
1564 *buffer++=(val&0xff);
1567 vorbis_fpu_restore(fpu);
1573 vorbis_synthesis_read(&vf->vd,samples);
1574 vf->pcm_offset+=samples;
1575 if(bitstream)*bitstream=vf->current_link;
1576 return(samples*bytespersample);
1582 /* input values: pcm_channels) a float vector per channel of output
1583 length) the sample length being read by the app
1585 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1587 n) number of samples of PCM actually returned. The
1588 below works on a packet-by-packet basis, so the
1589 return length is not related to the 'length' passed
1590 in, just guaranteed to fit.
1592 *section) set to the logical bitstream number */
1596 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1599 if(vf->ready_state<OPENED)return(OV_EINVAL);
1602 if(vf->ready_state==INITSET){
1604 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1606 if(pcm_channels)*pcm_channels=pcm;
1607 if(samples>length)samples=length;
1608 vorbis_synthesis_read(&vf->vd,samples);
1609 vf->pcm_offset+=samples;
1610 if(bitstream)*bitstream=vf->current_link;
1616 /* suck in another packet */
1618 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1619 if(ret==OV_EOF)return(0);
1620 if(ret<=0)return(ret);
1626 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1628 static void _vorbis_splice(float *d,float *s,
1629 vorbis_dsp_state *v,int W){
1631 vorbis_info *vi=v->vi;
1632 int n=vorbis_info_blocksize(vi,0)/2;
1633 float *w=vorbis_window(v,W);
1639 d[i]=d[i]*wd + s[i]*ws;
1645 /* this sets up crosslapping of a sample by using trailing data from
1646 sample 1 and lapping it into the windowing buffer of the second */
1648 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
1649 vorbis_info *vi1,*vi2;
1650 vorbis_dsp_state *vd1=&vf1->vd;
1651 vorbis_dsp_state *vd2=&vf2->vd;
1654 vorbis_dsp_state *winstate;
1655 int lapsize,lapcount=0,i,j;
1657 /* first enforce some level of sanity... */
1658 /* we need to know that sample rate & channels match. To do that,
1659 we need to verify the streams are actually initialized; the call
1660 is not just to be used for end-to-beginning lapping */
1662 if(vf1->ready_state<OPENED)return(OV_EINVAL);
1663 if(vf2->ready_state<OPENED)return(OV_EINVAL);
1665 /* make sure vf1 is INITSET */
1667 if(vf1->ready_state==INITSET)break;
1668 /* suck in another packet */
1670 int ret=_fetch_and_process_packet(vf1,NULL,1,0);
1671 if(ret<0)return(ret);
1675 /* make sure vf2 is INITSET and that we have a primed buffer; if
1676 we're crosslapping at a stream section boundary, this also makes
1677 sure we're sanity checking against the right stream information */
1680 if(vf2->ready_state==INITSET)
1681 if(vorbis_synthesis_pcmout(vd2,NULL))break;
1683 /* suck in another packet */
1685 int ret=_fetch_and_process_packet(vf2,NULL,1,0);
1686 if(ret<0)return(ret);
1690 /* sanity-check settings */
1691 vi1=ov_info(vf1,-1);
1692 vi2=ov_info(vf2,-1);
1693 if(vi1->channels != vi2->channels ||
1694 vi1->rate != vi2->rate) return OV_EINVAL;
1696 /* begin by grabbing enough data for lapping from vf1; this may be
1697 in the form of unreturned, already-decoded pcm, remaining PCM we
1698 will need to decode, or synthetic postextrapolation from last
1701 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
1702 lapsize=vorbis_info_blocksize(vi1,0);
1703 if(vorbis_info_blocksize(vi2,0)<lapsize){
1704 lapsize=vorbis_info_blocksize(vi2,0)/2;
1711 for(i=0;i<vi1->channels;i++)
1712 lappcm[i]=alloca(sizeof(**lappcm)*lapsize);
1714 /* try first to decode the lapping data */
1715 while(lapcount<lapsize){
1716 int samples=vorbis_synthesis_pcmout(vd1,&pcm);
1718 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1719 for(i=0;i<vi1->channels;i++)
1720 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1722 vorbis_synthesis_read(vd1,samples);
1724 /* suck in another packet */
1725 int ret=_fetch_and_process_packet(vf1,NULL,1,0); /* do *not* span */
1726 if(ret==OV_EOF)break;
1729 if(lapcount<lapsize){
1730 /* failed to get lapping data from normal decode; pry it from the
1731 postextrapolation buffering, or the second half of the MDCT
1732 from the last packet */
1733 int samples=vorbis_synthesis_lapout(&vf1->vd,&pcm);
1734 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1735 for(i=0;i<vi1->channels;i++)
1736 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1739 if(lapcount<lapsize)return OV_EFAULT;
1742 /* have a lapping buffer from vf1; now to splice it into the lapping
1745 /* consolidate and expose the buffer. */
1746 if(vorbis_synthesis_lapout(vd2,&pcm)<lapsize)return OV_EFAULT;
1749 for(j=0;j<vi1->channels;j++){
1752 _vorbis_splice(d,s,winstate,0);