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.68 2003/03/06 22:05:26 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;
404 static int _open_seekable2(OggVorbis_File *vf){
405 long serialno=vf->current_serialno;
406 ogg_int64_t dataoffset=vf->offset, end;
409 /* we're partially open and have a first link header state in
411 /* we can seek, so set out learning all about this file */
412 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
413 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
415 /* We get the offset for the last page of the physical bitstream.
416 Most OggVorbis files will contain a single logical bitstream */
417 end=_get_prev_page(vf,&og);
418 if(end<0)return(end);
420 /* more than one logical bitstream? */
421 if(ogg_page_serialno(&og)!=serialno){
423 /* Chained bitstream. Bisect-search each logical bitstream
424 section. Do so based on serial number only */
425 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
429 /* Only one logical bitstream */
430 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
434 /* the initial header memory is referenced by vf after; don't free it */
435 _prefetch_all_headers(vf,dataoffset);
436 return(ov_raw_seek(vf,0));
439 /* clear out the current logical bitstream decoder */
440 static void _decode_clear(OggVorbis_File *vf){
441 vorbis_dsp_clear(&vf->vd);
442 vorbis_block_clear(&vf->vb);
443 vf->ready_state=OPENED;
446 /* fetch and process a packet. Handles the case where we're at a
447 bitstream boundary and dumps the decoding machine. If the decoding
448 machine is unloaded, it loads it. It also keeps pcm_offset up to
449 date (seek and read both use this. seek uses a special hack with
452 return: <0) error, OV_HOLE (lost packet) or OV_EOF
453 0) need more data (only if readp==0)
457 static int _fetch_and_process_packet(OggVorbis_File *vf,
463 /* handle one packet. Try to fetch it from current stream state */
464 /* extract packets from page */
467 /* process a packet if we can. If the machine isn't loaded,
469 if(vf->ready_state==INITSET){
472 ogg_packet *op_ptr=(op_in?op_in:&op);
473 int result=ogg_stream_packetout(&vf->os,op_ptr);
474 ogg_int64_t granulepos;
477 if(result==-1)return(OV_HOLE); /* hole in the data. */
479 /* got a packet. process it */
480 granulepos=op_ptr->granulepos;
481 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
483 header packets aren't
486 vorbis_synthesis will
489 /* suck in the synthesis data and track bitrate */
491 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
492 /* for proper use of libvorbis within libvorbisfile,
493 oldsamples will always be zero. */
494 if(oldsamples)return(OV_EFAULT);
496 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
497 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
498 vf->bittrack+=op_ptr->bytes*8;
501 /* update the pcm offset. */
502 if(granulepos!=-1 && !op_ptr->e_o_s){
503 int link=(vf->seekable?vf->current_link:0);
506 /* this packet has a pcm_offset on it (the last packet
507 completed on a page carries the offset) After processing
508 (above), we know the pcm position of the *last* sample
509 ready to be returned. Find the offset of the *first*
511 As an aside, this trick is inaccurate if we begin
512 reading anew right at the last page; the end-of-stream
513 granulepos declares the last frame in the stream, and the
514 last packet of the last page may be a partial frame.
515 So, we need a previous granulepos from an in-sequence page
516 to have a reference point. Thus the !op_ptr->e_o_s clause
519 if(vf->seekable && link>0)
520 granulepos-=vf->pcmlengths[link*2];
521 if(granulepos<0)granulepos=0; /* actually, this
522 shouldn't be possible
523 here unless the stream
526 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
530 granulepos+=vf->pcmlengths[i*2+1];
531 vf->pcm_offset=granulepos;
541 if(vf->ready_state>=OPENED){
544 if((ret=_get_next_page(vf,&og,-1))<0){
545 return(OV_EOF); /* eof.
549 /* bitrate tracking; add the header's bytes here, the body bytes
550 are done by packet above */
551 vf->bittrack+=og.header_len*8;
553 /* has our decoding just traversed a bitstream boundary? */
554 if(vf->ready_state==INITSET){
555 if(vf->current_serialno!=ogg_page_serialno(&og)){
562 vorbis_info_clear(vf->vi);
563 vorbis_comment_clear(vf->vc);
569 /* Do we need to load a new machine before submitting the page? */
570 /* This is different in the seekable and non-seekable cases.
572 In the seekable case, we already have all the header
573 information loaded and cached; we just initialize the machine
574 with it and continue on our merry way.
576 In the non-seekable (streaming) case, we'll only be at a
577 boundary if we just left the previous logical bitstream and
578 we're now nominally at the header of the next bitstream
581 if(vf->ready_state!=INITSET){
584 if(vf->ready_state<STREAMSET){
586 vf->current_serialno=ogg_page_serialno(&og);
588 /* match the serialno to bitstream section. We use this rather than
589 offset positions to avoid problems near logical bitstream
591 for(link=0;link<vf->links;link++)
592 if(vf->serialnos[link]==vf->current_serialno)break;
593 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
598 vf->current_link=link;
600 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
601 vf->ready_state=STREAMSET;
604 /* we're streaming */
605 /* fetch the three header packets, build the info struct */
607 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
614 _make_decode_ready(vf);
616 ogg_stream_pagein(&vf->os,&og);
620 /* if, eg, 64 bit stdio is configured by default, this will build with
622 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
623 if(f==NULL)return(-1);
624 return fseek(f,off,whence);
627 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
628 long ibytes, ov_callbacks callbacks){
629 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
632 memset(vf,0,sizeof(*vf));
634 vf->callbacks = callbacks;
636 /* init the framing state */
637 ogg_sync_init(&vf->oy);
639 /* perhaps some data was previously read into a buffer for testing
640 against other stream types. Allow initialization from this
641 previously read data (as we may be reading from a non-seekable
644 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
645 memcpy(buffer,initial,ibytes);
646 ogg_sync_wrote(&vf->oy,ibytes);
649 /* can we seek? Stevens suggests the seek test was portable */
650 if(offsettest!=-1)vf->seekable=1;
652 /* No seeking yet; Set up a 'single' (current) logical bitstream
653 entry for partial open */
655 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
656 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
657 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
659 /* Try to fetch the headers, maintaining all the storage */
660 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
663 }else if(vf->ready_state < PARTOPEN)
664 vf->ready_state=PARTOPEN;
668 static int _ov_open2(OggVorbis_File *vf){
669 if(vf->ready_state < OPENED)
670 vf->ready_state=OPENED;
672 int ret=_open_seekable2(vf);
683 /* clear out the OggVorbis_File struct */
684 int ov_clear(OggVorbis_File *vf){
686 vorbis_block_clear(&vf->vb);
687 vorbis_dsp_clear(&vf->vd);
688 ogg_stream_clear(&vf->os);
690 if(vf->vi && vf->links){
692 for(i=0;i<vf->links;i++){
693 vorbis_info_clear(vf->vi+i);
694 vorbis_comment_clear(vf->vc+i);
699 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
700 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
701 if(vf->serialnos)_ogg_free(vf->serialnos);
702 if(vf->offsets)_ogg_free(vf->offsets);
703 ogg_sync_clear(&vf->oy);
704 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
705 memset(vf,0,sizeof(*vf));
713 /* inspects the OggVorbis file and finds/documents all the logical
714 bitstreams contained in it. Tries to be tolerant of logical
715 bitstream sections that are truncated/woogie.
721 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
722 ov_callbacks callbacks){
723 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
725 return _ov_open2(vf);
728 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
729 ov_callbacks callbacks = {
730 (size_t (*)(void *, size_t, size_t, void *)) fread,
731 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
732 (int (*)(void *)) fclose,
733 (long (*)(void *)) ftell
736 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
739 /* Only partially open the vorbis file; test for Vorbisness, and load
740 the headers for the first chain. Do not seek (although test for
741 seekability). Use ov_test_open to finish opening the file, else
742 ov_clear to close/free it. Same return codes as open. */
744 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
745 ov_callbacks callbacks)
747 return _ov_open1(f,vf,initial,ibytes,callbacks);
750 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
751 ov_callbacks callbacks = {
752 (size_t (*)(void *, size_t, size_t, void *)) fread,
753 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
754 (int (*)(void *)) fclose,
755 (long (*)(void *)) ftell
758 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
761 int ov_test_open(OggVorbis_File *vf){
762 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
763 return _ov_open2(vf);
766 /* How many logical bitstreams in this physical bitstream? */
767 long ov_streams(OggVorbis_File *vf){
771 /* Is the FILE * associated with vf seekable? */
772 long ov_seekable(OggVorbis_File *vf){
776 /* returns the bitrate for a given logical bitstream or the entire
777 physical bitstream. If the file is open for random access, it will
778 find the *actual* average bitrate. If the file is streaming, it
779 returns the nominal bitrate (if set) else the average of the
780 upper/lower bounds (if set) else -1 (unset).
782 If you want the actual bitrate field settings, get them from the
783 vorbis_info structs */
785 long ov_bitrate(OggVorbis_File *vf,int i){
786 if(vf->ready_state<OPENED)return(OV_EINVAL);
787 if(i>=vf->links)return(OV_EINVAL);
788 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
793 for(i=0;i<vf->links;i++)
794 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
795 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
796 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
797 * so this is slightly transformed to make it work.
799 br = bits/ov_time_total(vf,-1);
803 /* return the actual bitrate */
804 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
806 /* return nominal if set */
807 if(vf->vi[i].bitrate_nominal>0){
808 return vf->vi[i].bitrate_nominal;
810 if(vf->vi[i].bitrate_upper>0){
811 if(vf->vi[i].bitrate_lower>0){
812 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
814 return vf->vi[i].bitrate_upper;
823 /* returns the actual bitrate since last call. returns -1 if no
824 additional data to offer since last call (or at beginning of stream),
825 EINVAL if stream is only partially open
827 long ov_bitrate_instant(OggVorbis_File *vf){
828 int link=(vf->seekable?vf->current_link:0);
830 if(vf->ready_state<OPENED)return(OV_EINVAL);
831 if(vf->samptrack==0)return(OV_FALSE);
832 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
839 long ov_serialnumber(OggVorbis_File *vf,int i){
840 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
841 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
843 return(vf->current_serialno);
845 return(vf->serialnos[i]);
849 /* returns: total raw (compressed) length of content if i==-1
850 raw (compressed) length of that logical bitstream for i==0 to n
851 OV_EINVAL if the stream is not seekable (we can't know the length)
852 or if stream is only partially open
854 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
855 if(vf->ready_state<OPENED)return(OV_EINVAL);
856 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
860 for(i=0;i<vf->links;i++)
861 acc+=ov_raw_total(vf,i);
864 return(vf->offsets[i+1]-vf->offsets[i]);
868 /* returns: total PCM length (samples) of content if i==-1 PCM length
869 (samples) of that logical bitstream for i==0 to n
870 OV_EINVAL if the stream is not seekable (we can't know the
871 length) or only partially open
873 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
874 if(vf->ready_state<OPENED)return(OV_EINVAL);
875 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
879 for(i=0;i<vf->links;i++)
880 acc+=ov_pcm_total(vf,i);
883 return(vf->pcmlengths[i*2+1]);
887 /* returns: total seconds of content if i==-1
888 seconds in that logical bitstream for i==0 to n
889 OV_EINVAL if the stream is not seekable (we can't know the
890 length) or only partially open
892 double ov_time_total(OggVorbis_File *vf,int i){
893 if(vf->ready_state<OPENED)return(OV_EINVAL);
894 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
898 for(i=0;i<vf->links;i++)
899 acc+=ov_time_total(vf,i);
902 return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
906 /* seek to an offset relative to the *compressed* data. This also
907 scans packets to update the PCM cursor. It will cross a logical
908 bitstream boundary, but only if it can't get any packets out of the
909 tail of the bitstream we seek to (so no surprises).
911 returns zero on success, nonzero on failure */
913 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
914 ogg_stream_state work_os;
916 if(vf->ready_state<OPENED)return(OV_EINVAL);
918 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
920 if(pos<0 || pos>vf->end)return(OV_EINVAL);
922 /* don't yet clear out decoding machine (if it's initialized), in
923 the case we're in the same link. Restart the decode lapping, and
924 let _fetch_and_process_packet deal with a potential bitstream
927 ogg_stream_reset_serialno(&vf->os,
928 vf->current_serialno); /* must set serialno */
929 vorbis_synthesis_restart(&vf->vd);
931 _seek_helper(vf,pos);
933 /* we need to make sure the pcm_offset is set, but we don't want to
934 advance the raw cursor past good packets just to get to the first
935 with a granulepos. That's not equivalent behavior to beginning
936 decoding as immediately after the seek position as possible.
938 So, a hack. We use two stream states; a local scratch state and
939 the shared vf->os stream state. We use the local state to
940 scan, and the shared state as a buffer for later decode.
942 Unfortuantely, on the last page we still advance to last packet
943 because the granulepos on the last page is not necessarily on a
944 packet boundary, and we need to make sure the granpos is
956 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
957 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
958 return from not necessarily
959 starting from the beginning */
962 if(vf->ready_state>=STREAMSET){
963 /* snarf/scan a packet if we can */
964 int result=ogg_stream_packetout(&work_os,&op);
968 if(vf->vi[vf->current_link].codec_setup){
969 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
971 ogg_stream_packetout(&vf->os,NULL);
976 ogg_stream_packetout(&vf->os,NULL);
978 if(lastblock)accblock+=(lastblock+thisblock)>>2;
980 if(op.granulepos!=-1){
981 int i,link=vf->current_link;
982 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
983 if(granulepos<0)granulepos=0;
986 granulepos+=vf->pcmlengths[i*2+1];
987 vf->pcm_offset=granulepos-accblock;
996 if(_get_next_page(vf,&og,-1)<0){
997 vf->pcm_offset=ov_pcm_total(vf,-1);
1001 /* huh? Bogus stream with packets but no granulepos */
1006 /* has our decoding just traversed a bitstream boundary? */
1007 if(vf->ready_state>=STREAMSET)
1008 if(vf->current_serialno!=ogg_page_serialno(&og)){
1009 _decode_clear(vf); /* clear out stream state */
1010 ogg_stream_clear(&work_os);
1013 if(vf->ready_state<STREAMSET){
1016 vf->current_serialno=ogg_page_serialno(&og);
1017 for(link=0;link<vf->links;link++)
1018 if(vf->serialnos[link]==vf->current_serialno)break;
1019 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1021 machine uninitialized */
1022 vf->current_link=link;
1024 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1025 ogg_stream_reset_serialno(&work_os,vf->current_serialno);
1026 vf->ready_state=STREAMSET;
1030 ogg_stream_pagein(&vf->os,&og);
1031 ogg_stream_pagein(&work_os,&og);
1032 eosflag=ogg_page_eos(&og);
1036 ogg_stream_clear(&work_os);
1042 /* dump the machine so we're in a known state */
1044 ogg_stream_clear(&work_os);
1049 /* Page granularity seek (faster than sample granularity because we
1050 don't do the last bit of decode to find a specific sample).
1052 Seek to the last [granule marked] page preceeding the specified pos
1053 location, such that decoding past the returned point will quickly
1054 arrive at the requested position. */
1055 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1057 ogg_int64_t result=0;
1058 ogg_int64_t total=ov_pcm_total(vf,-1);
1060 if(vf->ready_state<OPENED)return(OV_EINVAL);
1061 if(!vf->seekable)return(OV_ENOSEEK);
1063 if(pos<0 || pos>total)return(OV_EINVAL);
1065 /* which bitstream section does this pcm offset occur in? */
1066 for(link=vf->links-1;link>=0;link--){
1067 total-=vf->pcmlengths[link*2+1];
1068 if(pos>=total)break;
1071 /* search within the logical bitstream for the page with the highest
1072 pcm_pos preceeding (or equal to) pos. There is a danger here;
1073 missing pages or incorrect frame number information in the
1074 bitstream could make our task impossible. Account for that (it
1075 would be an error condition) */
1077 /* new search algorithm by HB (Nicholas Vinen) */
1079 ogg_int64_t end=vf->offsets[link+1];
1080 ogg_int64_t begin=vf->offsets[link];
1081 ogg_int64_t begintime = vf->pcmlengths[link*2];
1082 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1083 ogg_int64_t target=pos-total+begintime;
1084 ogg_int64_t best=begin;
1090 if(end-begin<CHUNKSIZE){
1093 /* take a (pretty decent) guess. */
1095 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1100 _seek_helper(vf,bisect);
1103 result=_get_next_page(vf,&og,end-vf->offset);
1104 if(result==OV_EREAD) goto seek_error;
1107 end=begin; /* found it */
1109 if(bisect==0) goto seek_error;
1111 if(bisect<=begin)bisect=begin+1;
1112 _seek_helper(vf,bisect);
1115 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1116 if(granulepos==-1)continue;
1117 if(granulepos<target){
1118 best=result; /* raw offset of packet with granulepos */
1119 begin=vf->offset; /* raw offset of next page */
1120 begintime=granulepos;
1122 if(target-begintime>44100)break;
1123 bisect=begin; /* *not* begin + 1 */
1126 end=begin; /* found it */
1128 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1130 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1131 if(bisect<=begin)bisect=begin+1;
1132 _seek_helper(vf,bisect);
1144 /* found our page. seek to it, update pcm offset. Easier case than
1145 raw_seek, don't keep packets preceeding granulepos. */
1151 _seek_helper(vf,best);
1154 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1156 if(link!=vf->current_link){
1157 /* Different link; dump entire decode machine */
1160 vf->current_link=link;
1161 vf->current_serialno=ogg_page_serialno(&og);
1162 vf->ready_state=STREAMSET;
1165 vorbis_synthesis_restart(&vf->vd);
1168 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1169 ogg_stream_pagein(&vf->os,&og);
1171 /* pull out all but last packet; the one with granulepos */
1173 result=ogg_stream_packetpeek(&vf->os,&op);
1175 /* !!! the packet finishing this page originated on a
1176 preceeding page. Keep fetching previous pages until we
1177 get one with a granulepos or without the 'continued' flag
1178 set. Then just use raw_seek for simplicity. */
1180 _seek_helper(vf,best);
1183 result=_get_prev_page(vf,&og);
1184 if(result<0) goto seek_error;
1185 if(ogg_page_granulepos(&og)>-1 ||
1186 !ogg_page_continued(&og)){
1187 return ov_raw_seek(vf,result);
1193 result = OV_EBADPACKET;
1196 if(op.granulepos!=-1){
1197 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1198 if(vf->pcm_offset<0)vf->pcm_offset=0;
1199 vf->pcm_offset+=total;
1202 result=ogg_stream_packetout(&vf->os,NULL);
1208 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1217 /* dump machine so we're in a known state */
1223 /* seek to a sample offset relative to the decompressed pcm stream
1224 returns zero on success, nonzero on failure */
1226 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1227 int thisblock,lastblock=0;
1228 int ret=ov_pcm_seek_page(vf,pos);
1229 if(ret<0)return(ret);
1230 _make_decode_ready(vf);
1232 /* discard leading packets we don't need for the lapping of the
1233 position we want; don't decode them */
1239 int ret=ogg_stream_packetpeek(&vf->os,&op);
1241 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1243 ogg_stream_packetout(&vf->os,NULL);
1244 continue; /* non audio packet */
1246 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1248 if(vf->pcm_offset+((thisblock+
1249 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1251 /* remove the packet from packet queue and track its granulepos */
1252 ogg_stream_packetout(&vf->os,NULL);
1253 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1256 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1258 /* end of logical stream case is hard, especially with exact
1259 length positioning. */
1261 if(op.granulepos>-1){
1263 /* always believe the stream markers */
1264 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1265 if(vf->pcm_offset<0)vf->pcm_offset=0;
1266 for(i=0;i<vf->current_link;i++)
1267 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1270 lastblock=thisblock;
1273 if(ret<0 && ret!=OV_HOLE)break;
1275 /* suck in a new page */
1276 if(_get_next_page(vf,&og,-1)<0)break;
1277 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1279 if(vf->ready_state<STREAMSET){
1282 vf->current_serialno=ogg_page_serialno(&og);
1283 for(link=0;link<vf->links;link++)
1284 if(vf->serialnos[link]==vf->current_serialno)break;
1285 if(link==vf->links)return(OV_EBADLINK);
1286 vf->current_link=link;
1288 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1289 vf->ready_state=STREAMSET;
1290 _make_decode_ready(vf);
1294 ogg_stream_pagein(&vf->os,&og);
1300 /* discard samples until we reach the desired position. Crossing a
1301 logical bitstream boundary with abandon is OK. */
1302 while(vf->pcm_offset<pos){
1303 ogg_int64_t target=pos-vf->pcm_offset;
1304 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1306 if(samples>target)samples=target;
1307 vorbis_synthesis_read(&vf->vd,samples);
1308 vf->pcm_offset+=samples;
1311 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1312 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1317 /* seek to a playback time relative to the decompressed pcm stream
1318 returns zero on success, nonzero on failure */
1319 int ov_time_seek(OggVorbis_File *vf,double seconds){
1320 /* translate time to PCM position and call ov_pcm_seek */
1323 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1324 double time_total=ov_time_total(vf,-1);
1326 if(vf->ready_state<OPENED)return(OV_EINVAL);
1327 if(!vf->seekable)return(OV_ENOSEEK);
1328 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1330 /* which bitstream section does this time offset occur in? */
1331 for(link=vf->links-1;link>=0;link--){
1332 pcm_total-=vf->pcmlengths[link*2+1];
1333 time_total-=ov_time_total(vf,link);
1334 if(seconds>=time_total)break;
1337 /* enough information to convert time offset to pcm offset */
1339 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1340 return(ov_pcm_seek(vf,target));
1344 /* page-granularity version of ov_time_seek
1345 returns zero on success, nonzero on failure */
1346 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1347 /* translate time to PCM position and call ov_pcm_seek */
1350 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1351 double time_total=ov_time_total(vf,-1);
1353 if(vf->ready_state<OPENED)return(OV_EINVAL);
1354 if(!vf->seekable)return(OV_ENOSEEK);
1355 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1357 /* which bitstream section does this time offset occur in? */
1358 for(link=vf->links-1;link>=0;link--){
1359 pcm_total-=vf->pcmlengths[link*2+1];
1360 time_total-=ov_time_total(vf,link);
1361 if(seconds>=time_total)break;
1364 /* enough information to convert time offset to pcm offset */
1366 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1367 return(ov_pcm_seek_page(vf,target));
1371 /* tell the current stream offset cursor. Note that seek followed by
1372 tell will likely not give the set offset due to caching */
1373 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1374 if(vf->ready_state<OPENED)return(OV_EINVAL);
1378 /* return PCM offset (sample) of next PCM sample to be read */
1379 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1380 if(vf->ready_state<OPENED)return(OV_EINVAL);
1381 return(vf->pcm_offset);
1384 /* return time offset (seconds) of next PCM sample to be read */
1385 double ov_time_tell(OggVorbis_File *vf){
1387 ogg_int64_t pcm_total=0;
1388 double time_total=0.f;
1390 if(vf->ready_state<OPENED)return(OV_EINVAL);
1392 pcm_total=ov_pcm_total(vf,-1);
1393 time_total=ov_time_total(vf,-1);
1395 /* which bitstream section does this time offset occur in? */
1396 for(link=vf->links-1;link>=0;link--){
1397 pcm_total-=vf->pcmlengths[link*2+1];
1398 time_total-=ov_time_total(vf,link);
1399 if(vf->pcm_offset>=pcm_total)break;
1403 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1406 /* link: -1) return the vorbis_info struct for the bitstream section
1407 currently being decoded
1408 0-n) to request information for a specific bitstream section
1410 In the case of a non-seekable bitstream, any call returns the
1411 current bitstream. NULL in the case that the machine is not
1414 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1417 if(vf->ready_state>=STREAMSET)
1418 return vf->vi+vf->current_link;
1431 /* grr, strong typing, grr, no templates/inheritence, grr */
1432 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1435 if(vf->ready_state>=STREAMSET)
1436 return vf->vc+vf->current_link;
1449 static int host_is_big_endian() {
1450 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1451 unsigned char *bytewise = (unsigned char *)&pattern;
1452 if (bytewise[0] == 0xfe) return 1;
1456 /* up to this point, everything could more or less hide the multiple
1457 logical bitstream nature of chaining from the toplevel application
1458 if the toplevel application didn't particularly care. However, at
1459 the point that we actually read audio back, the multiple-section
1460 nature must surface: Multiple bitstream sections do not necessarily
1461 have to have the same number of channels or sampling rate.
1463 ov_read returns the sequential logical bitstream number currently
1464 being decoded along with the PCM data in order that the toplevel
1465 application can take action on channel/sample rate changes. This
1466 number will be incremented even for streamed (non-seekable) streams
1467 (for seekable streams, it represents the actual logical bitstream
1468 index within the physical bitstream. Note that the accessor
1469 functions above are aware of this dichotomy).
1471 input values: buffer) a buffer to hold packed PCM data for return
1472 length) the byte length requested to be placed into buffer
1473 bigendianp) should the data be packed LSB first (0) or
1475 word) word size for output. currently 1 (byte) or
1478 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1480 n) number of bytes of PCM actually returned. The
1481 below works on a packet-by-packet basis, so the
1482 return length is not related to the 'length' passed
1483 in, just guaranteed to fit.
1485 *section) set to the logical bitstream number */
1487 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1488 int bigendianp,int word,int sgned,int *bitstream){
1490 int host_endian = host_is_big_endian();
1495 if(vf->ready_state<OPENED)return(OV_EINVAL);
1498 if(vf->ready_state==INITSET){
1499 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1503 /* suck in another packet */
1505 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1516 /* yay! proceed to pack data into the byte buffer */
1518 long channels=ov_info(vf,-1)->channels;
1519 long bytespersample=word * channels;
1520 vorbis_fpu_control fpu;
1521 if(samples>length/bytespersample)samples=length/bytespersample;
1526 /* a tight loop to pack each size */
1530 int off=(sgned?0:128);
1531 vorbis_fpu_setround(&fpu);
1532 for(j=0;j<samples;j++)
1533 for(i=0;i<channels;i++){
1534 val=vorbis_ftoi(pcm[i][j]*128.f);
1536 else if(val<-128)val=-128;
1539 vorbis_fpu_restore(fpu);
1541 int off=(sgned?0:32768);
1543 if(host_endian==bigendianp){
1546 vorbis_fpu_setround(&fpu);
1547 for(i=0;i<channels;i++) { /* It's faster in this order */
1549 short *dest=((short *)buffer)+i;
1550 for(j=0;j<samples;j++) {
1551 val=vorbis_ftoi(src[j]*32768.f);
1552 if(val>32767)val=32767;
1553 else if(val<-32768)val=-32768;
1558 vorbis_fpu_restore(fpu);
1562 vorbis_fpu_setround(&fpu);
1563 for(i=0;i<channels;i++) {
1565 short *dest=((short *)buffer)+i;
1566 for(j=0;j<samples;j++) {
1567 val=vorbis_ftoi(src[j]*32768.f);
1568 if(val>32767)val=32767;
1569 else if(val<-32768)val=-32768;
1574 vorbis_fpu_restore(fpu);
1577 }else if(bigendianp){
1579 vorbis_fpu_setround(&fpu);
1580 for(j=0;j<samples;j++)
1581 for(i=0;i<channels;i++){
1582 val=vorbis_ftoi(pcm[i][j]*32768.f);
1583 if(val>32767)val=32767;
1584 else if(val<-32768)val=-32768;
1587 *buffer++=(val&0xff);
1589 vorbis_fpu_restore(fpu);
1593 vorbis_fpu_setround(&fpu);
1594 for(j=0;j<samples;j++)
1595 for(i=0;i<channels;i++){
1596 val=vorbis_ftoi(pcm[i][j]*32768.f);
1597 if(val>32767)val=32767;
1598 else if(val<-32768)val=-32768;
1600 *buffer++=(val&0xff);
1603 vorbis_fpu_restore(fpu);
1609 vorbis_synthesis_read(&vf->vd,samples);
1610 vf->pcm_offset+=samples;
1611 if(bitstream)*bitstream=vf->current_link;
1612 return(samples*bytespersample);
1618 /* input values: pcm_channels) a float vector per channel of output
1619 length) the sample length being read by the app
1621 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1623 n) number of samples of PCM actually returned. The
1624 below works on a packet-by-packet basis, so the
1625 return length is not related to the 'length' passed
1626 in, just guaranteed to fit.
1628 *section) set to the logical bitstream number */
1632 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1635 if(vf->ready_state<OPENED)return(OV_EINVAL);
1638 if(vf->ready_state==INITSET){
1640 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1642 if(pcm_channels)*pcm_channels=pcm;
1643 if(samples>length)samples=length;
1644 vorbis_synthesis_read(&vf->vd,samples);
1645 vf->pcm_offset+=samples;
1646 if(bitstream)*bitstream=vf->current_link;
1652 /* suck in another packet */
1654 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1655 if(ret==OV_EOF)return(0);
1656 if(ret<=0)return(ret);
1662 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1664 static void _ov_splice(float **pcm,float **lappcm,
1667 float *w1, float *w2){
1678 for(j=0;j<ch1 && j<ch2;j++){
1684 d[i]=d[i]*wd + s[i]*ws;
1687 /* window from zero */
1697 /* make sure vf is INITSET */
1698 static int _ov_initset(OggVorbis_File *vf){
1700 if(vf->ready_state==INITSET)break;
1701 /* suck in another packet */
1703 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1704 if(ret<0 && ret!=OV_HOLE)return(ret);
1710 /* make sure vf is INITSET and that we have a primed buffer; if
1711 we're crosslapping at a stream section boundary, this also makes
1712 sure we're sanity checking against the right stream information */
1713 static int _ov_initprime(OggVorbis_File *vf){
1714 vorbis_dsp_state *vd=&vf->vd;
1716 if(vf->ready_state==INITSET)
1717 if(vorbis_synthesis_pcmout(vd,NULL))break;
1719 /* suck in another packet */
1721 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1722 if(ret<0 && ret!=OV_HOLE)return(ret);
1728 /* grab enough data for lapping from vf; this may be in the form of
1729 unreturned, already-decoded pcm, remaining PCM we will need to
1730 decode, or synthetic postextrapolation from last packets. */
1731 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1732 float **lappcm,int lapsize){
1736 /* try first to decode the lapping data */
1737 while(lapcount<lapsize){
1738 int samples=vorbis_synthesis_pcmout(vd,&pcm);
1740 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1741 for(i=0;i<vi->channels;i++)
1742 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1744 vorbis_synthesis_read(vd,samples);
1746 /* suck in another packet */
1747 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
1748 if(ret==OV_EOF)break;
1751 if(lapcount<lapsize){
1752 /* failed to get lapping data from normal decode; pry it from the
1753 postextrapolation buffering, or the second half of the MDCT
1754 from the last packet */
1755 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
1756 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1757 for(i=0;i<vi->channels;i++)
1758 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1764 /* this sets up crosslapping of a sample by using trailing data from
1765 sample 1 and lapping it into the windowing buffer of sample 2 */
1766 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
1767 vorbis_info *vi1,*vi2;
1773 if(vf1==vf2)return(0); /* degenerate case */
1774 if(vf1->ready_state<OPENED)return(OV_EINVAL);
1775 if(vf2->ready_state<OPENED)return(OV_EINVAL);
1777 /* the relevant overlap buffers must be pre-checked and pre-primed
1778 before looking at settings in the event that priming would cross
1779 a bitstream boundary. So, do it now */
1781 ret=_ov_initset(vf1);
1783 ret=_ov_initprime(vf2);
1786 vi1=ov_info(vf1,-1);
1787 vi2=ov_info(vf2,-1);
1789 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
1790 n1=vorbis_info_blocksize(vi1,0)/2;
1791 n2=vorbis_info_blocksize(vi2,0)/2;
1792 w1=vorbis_window(&vf1->vd,0);
1793 w2=vorbis_window(&vf2->vd,0);
1795 for(i=0;i<vi1->channels;i++)
1796 lappcm[i]=alloca(sizeof(**lappcm)*n1);
1798 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
1800 /* have a lapping buffer from vf1; now to splice it into the lapping
1802 /* consolidate and expose the buffer. */
1803 vorbis_synthesis_lapout(&vf2->vd,&pcm);
1806 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
1812 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
1813 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
1821 if(vf->ready_state<OPENED)return(OV_EINVAL);
1822 ret=_ov_initset(vf);
1827 n1=vorbis_info_blocksize(vi,0)/2;
1828 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
1829 persistent; even if the decode state
1830 from this link gets dumped, this
1831 window array continues to exist */
1833 lappcm=alloca(sizeof(*lappcm)*ch1);
1835 lappcm[i]=alloca(sizeof(**lappcm)*n1);
1836 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1838 /* have lapping data; seek and prime the buffer */
1839 ret=localseek(vf,pos);
1841 ret=_ov_initprime(vf);
1844 /* Guard against cross-link changes; they're perfectly legal */
1847 n2=vorbis_info_blocksize(vi,0)/2;
1848 w2=vorbis_window(&vf->vd,0);
1850 /* consolidate and expose the buffer. */
1851 vorbis_synthesis_lapout(&vf->vd,&pcm);
1854 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1860 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
1861 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
1864 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
1865 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
1868 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
1869 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
1872 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
1873 int (*localseek)(OggVorbis_File *,double)){
1881 if(vf->ready_state<OPENED)return(OV_EINVAL);
1882 ret=_ov_initset(vf);
1887 n1=vorbis_info_blocksize(vi,0)/2;
1888 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
1889 persistent; even if the decode state
1890 from this link gets dumped, this
1891 window array continues to exist */
1893 lappcm=alloca(sizeof(*lappcm)*ch1);
1895 lappcm[i]=alloca(sizeof(**lappcm)*n1);
1896 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1898 /* have lapping data; seek and prime the buffer */
1899 ret=localseek(vf,pos);
1901 ret=_ov_initprime(vf);
1904 /* Guard against cross-link changes; they're perfectly legal */
1907 n2=vorbis_info_blocksize(vi,0)/2;
1908 w2=vorbis_window(&vf->vd,0);
1910 /* consolidate and expose the buffer. */
1911 vorbis_synthesis_lapout(&vf->vd,&pcm);
1914 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1920 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
1921 return _ov_d_seek_lap(vf,pos,ov_time_seek);
1924 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
1925 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);