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.69 2003/03/11 23:52:02 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;
981 if(op.granulepos!=-1){
982 int i,link=vf->current_link;
983 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
984 if(granulepos<0)granulepos=0;
987 granulepos+=vf->pcmlengths[i*2+1];
988 vf->pcm_offset=granulepos-accblock;
994 ogg_stream_packetout(&vf->os,NULL);
999 if(_get_next_page(vf,&og,-1)<0){
1000 vf->pcm_offset=ov_pcm_total(vf,-1);
1004 /* huh? Bogus stream with packets but no granulepos */
1009 /* has our decoding just traversed a bitstream boundary? */
1010 if(vf->ready_state>=STREAMSET)
1011 if(vf->current_serialno!=ogg_page_serialno(&og)){
1012 _decode_clear(vf); /* clear out stream state */
1013 ogg_stream_clear(&work_os);
1016 if(vf->ready_state<STREAMSET){
1019 vf->current_serialno=ogg_page_serialno(&og);
1020 for(link=0;link<vf->links;link++)
1021 if(vf->serialnos[link]==vf->current_serialno)break;
1022 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1024 machine uninitialized */
1025 vf->current_link=link;
1027 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1028 ogg_stream_reset_serialno(&work_os,vf->current_serialno);
1029 vf->ready_state=STREAMSET;
1033 ogg_stream_pagein(&vf->os,&og);
1034 ogg_stream_pagein(&work_os,&og);
1035 eosflag=ogg_page_eos(&og);
1039 ogg_stream_clear(&work_os);
1045 /* dump the machine so we're in a known state */
1047 ogg_stream_clear(&work_os);
1052 /* Page granularity seek (faster than sample granularity because we
1053 don't do the last bit of decode to find a specific sample).
1055 Seek to the last [granule marked] page preceeding the specified pos
1056 location, such that decoding past the returned point will quickly
1057 arrive at the requested position. */
1058 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1060 ogg_int64_t result=0;
1061 ogg_int64_t total=ov_pcm_total(vf,-1);
1063 if(vf->ready_state<OPENED)return(OV_EINVAL);
1064 if(!vf->seekable)return(OV_ENOSEEK);
1066 if(pos<0 || pos>total)return(OV_EINVAL);
1068 /* which bitstream section does this pcm offset occur in? */
1069 for(link=vf->links-1;link>=0;link--){
1070 total-=vf->pcmlengths[link*2+1];
1071 if(pos>=total)break;
1074 /* search within the logical bitstream for the page with the highest
1075 pcm_pos preceeding (or equal to) pos. There is a danger here;
1076 missing pages or incorrect frame number information in the
1077 bitstream could make our task impossible. Account for that (it
1078 would be an error condition) */
1080 /* new search algorithm by HB (Nicholas Vinen) */
1082 ogg_int64_t end=vf->offsets[link+1];
1083 ogg_int64_t begin=vf->offsets[link];
1084 ogg_int64_t begintime = vf->pcmlengths[link*2];
1085 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1086 ogg_int64_t target=pos-total+begintime;
1087 ogg_int64_t best=begin;
1093 if(end-begin<CHUNKSIZE){
1096 /* take a (pretty decent) guess. */
1098 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1103 _seek_helper(vf,bisect);
1106 result=_get_next_page(vf,&og,end-vf->offset);
1107 if(result==OV_EREAD) goto seek_error;
1110 end=begin; /* found it */
1112 if(bisect==0) goto seek_error;
1114 if(bisect<=begin)bisect=begin+1;
1115 _seek_helper(vf,bisect);
1118 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1119 if(granulepos==-1)continue;
1120 if(granulepos<target){
1121 best=result; /* raw offset of packet with granulepos */
1122 begin=vf->offset; /* raw offset of next page */
1123 begintime=granulepos;
1125 if(target-begintime>44100)break;
1126 bisect=begin; /* *not* begin + 1 */
1129 end=begin; /* found it */
1131 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1133 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1134 if(bisect<=begin)bisect=begin+1;
1135 _seek_helper(vf,bisect);
1147 /* found our page. seek to it, update pcm offset. Easier case than
1148 raw_seek, don't keep packets preceeding granulepos. */
1154 _seek_helper(vf,best);
1157 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1159 if(link!=vf->current_link){
1160 /* Different link; dump entire decode machine */
1163 vf->current_link=link;
1164 vf->current_serialno=ogg_page_serialno(&og);
1165 vf->ready_state=STREAMSET;
1168 vorbis_synthesis_restart(&vf->vd);
1171 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1172 ogg_stream_pagein(&vf->os,&og);
1174 /* pull out all but last packet; the one with granulepos */
1176 result=ogg_stream_packetpeek(&vf->os,&op);
1178 /* !!! the packet finishing this page originated on a
1179 preceeding page. Keep fetching previous pages until we
1180 get one with a granulepos or without the 'continued' flag
1181 set. Then just use raw_seek for simplicity. */
1183 _seek_helper(vf,best);
1186 result=_get_prev_page(vf,&og);
1187 if(result<0) goto seek_error;
1188 if(ogg_page_granulepos(&og)>-1 ||
1189 !ogg_page_continued(&og)){
1190 return ov_raw_seek(vf,result);
1196 result = OV_EBADPACKET;
1199 if(op.granulepos!=-1){
1200 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1201 if(vf->pcm_offset<0)vf->pcm_offset=0;
1202 vf->pcm_offset+=total;
1205 result=ogg_stream_packetout(&vf->os,NULL);
1211 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1220 /* dump machine so we're in a known state */
1226 /* seek to a sample offset relative to the decompressed pcm stream
1227 returns zero on success, nonzero on failure */
1229 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1230 int thisblock,lastblock=0;
1231 int ret=ov_pcm_seek_page(vf,pos);
1232 if(ret<0)return(ret);
1233 _make_decode_ready(vf);
1235 /* discard leading packets we don't need for the lapping of the
1236 position we want; don't decode them */
1242 int ret=ogg_stream_packetpeek(&vf->os,&op);
1244 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1246 ogg_stream_packetout(&vf->os,NULL);
1247 continue; /* non audio packet */
1249 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1251 if(vf->pcm_offset+((thisblock+
1252 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1254 /* remove the packet from packet queue and track its granulepos */
1255 ogg_stream_packetout(&vf->os,NULL);
1256 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1259 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1261 /* end of logical stream case is hard, especially with exact
1262 length positioning. */
1264 if(op.granulepos>-1){
1266 /* always believe the stream markers */
1267 vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1268 if(vf->pcm_offset<0)vf->pcm_offset=0;
1269 for(i=0;i<vf->current_link;i++)
1270 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1273 lastblock=thisblock;
1276 if(ret<0 && ret!=OV_HOLE)break;
1278 /* suck in a new page */
1279 if(_get_next_page(vf,&og,-1)<0)break;
1280 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1282 if(vf->ready_state<STREAMSET){
1285 vf->current_serialno=ogg_page_serialno(&og);
1286 for(link=0;link<vf->links;link++)
1287 if(vf->serialnos[link]==vf->current_serialno)break;
1288 if(link==vf->links)return(OV_EBADLINK);
1289 vf->current_link=link;
1291 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1292 vf->ready_state=STREAMSET;
1293 _make_decode_ready(vf);
1297 ogg_stream_pagein(&vf->os,&og);
1303 /* discard samples until we reach the desired position. Crossing a
1304 logical bitstream boundary with abandon is OK. */
1305 while(vf->pcm_offset<pos){
1306 ogg_int64_t target=pos-vf->pcm_offset;
1307 long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1309 if(samples>target)samples=target;
1310 vorbis_synthesis_read(&vf->vd,samples);
1311 vf->pcm_offset+=samples;
1314 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1315 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1320 /* seek to a playback time relative to the decompressed pcm stream
1321 returns zero on success, nonzero on failure */
1322 int ov_time_seek(OggVorbis_File *vf,double seconds){
1323 /* translate time to PCM position and call ov_pcm_seek */
1326 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1327 double time_total=ov_time_total(vf,-1);
1329 if(vf->ready_state<OPENED)return(OV_EINVAL);
1330 if(!vf->seekable)return(OV_ENOSEEK);
1331 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1333 /* which bitstream section does this time offset occur in? */
1334 for(link=vf->links-1;link>=0;link--){
1335 pcm_total-=vf->pcmlengths[link*2+1];
1336 time_total-=ov_time_total(vf,link);
1337 if(seconds>=time_total)break;
1340 /* enough information to convert time offset to pcm offset */
1342 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1343 return(ov_pcm_seek(vf,target));
1347 /* page-granularity version of ov_time_seek
1348 returns zero on success, nonzero on failure */
1349 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1350 /* translate time to PCM position and call ov_pcm_seek */
1353 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1354 double time_total=ov_time_total(vf,-1);
1356 if(vf->ready_state<OPENED)return(OV_EINVAL);
1357 if(!vf->seekable)return(OV_ENOSEEK);
1358 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1360 /* which bitstream section does this time offset occur in? */
1361 for(link=vf->links-1;link>=0;link--){
1362 pcm_total-=vf->pcmlengths[link*2+1];
1363 time_total-=ov_time_total(vf,link);
1364 if(seconds>=time_total)break;
1367 /* enough information to convert time offset to pcm offset */
1369 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1370 return(ov_pcm_seek_page(vf,target));
1374 /* tell the current stream offset cursor. Note that seek followed by
1375 tell will likely not give the set offset due to caching */
1376 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1377 if(vf->ready_state<OPENED)return(OV_EINVAL);
1381 /* return PCM offset (sample) of next PCM sample to be read */
1382 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1383 if(vf->ready_state<OPENED)return(OV_EINVAL);
1384 return(vf->pcm_offset);
1387 /* return time offset (seconds) of next PCM sample to be read */
1388 double ov_time_tell(OggVorbis_File *vf){
1390 ogg_int64_t pcm_total=0;
1391 double time_total=0.f;
1393 if(vf->ready_state<OPENED)return(OV_EINVAL);
1395 pcm_total=ov_pcm_total(vf,-1);
1396 time_total=ov_time_total(vf,-1);
1398 /* which bitstream section does this time offset occur in? */
1399 for(link=vf->links-1;link>=0;link--){
1400 pcm_total-=vf->pcmlengths[link*2+1];
1401 time_total-=ov_time_total(vf,link);
1402 if(vf->pcm_offset>=pcm_total)break;
1406 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1409 /* link: -1) return the vorbis_info struct for the bitstream section
1410 currently being decoded
1411 0-n) to request information for a specific bitstream section
1413 In the case of a non-seekable bitstream, any call returns the
1414 current bitstream. NULL in the case that the machine is not
1417 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1420 if(vf->ready_state>=STREAMSET)
1421 return vf->vi+vf->current_link;
1434 /* grr, strong typing, grr, no templates/inheritence, grr */
1435 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1438 if(vf->ready_state>=STREAMSET)
1439 return vf->vc+vf->current_link;
1452 static int host_is_big_endian() {
1453 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1454 unsigned char *bytewise = (unsigned char *)&pattern;
1455 if (bytewise[0] == 0xfe) return 1;
1459 /* up to this point, everything could more or less hide the multiple
1460 logical bitstream nature of chaining from the toplevel application
1461 if the toplevel application didn't particularly care. However, at
1462 the point that we actually read audio back, the multiple-section
1463 nature must surface: Multiple bitstream sections do not necessarily
1464 have to have the same number of channels or sampling rate.
1466 ov_read returns the sequential logical bitstream number currently
1467 being decoded along with the PCM data in order that the toplevel
1468 application can take action on channel/sample rate changes. This
1469 number will be incremented even for streamed (non-seekable) streams
1470 (for seekable streams, it represents the actual logical bitstream
1471 index within the physical bitstream. Note that the accessor
1472 functions above are aware of this dichotomy).
1474 input values: buffer) a buffer to hold packed PCM data for return
1475 length) the byte length requested to be placed into buffer
1476 bigendianp) should the data be packed LSB first (0) or
1478 word) word size for output. currently 1 (byte) or
1481 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1483 n) number of bytes of PCM actually returned. The
1484 below works on a packet-by-packet basis, so the
1485 return length is not related to the 'length' passed
1486 in, just guaranteed to fit.
1488 *section) set to the logical bitstream number */
1490 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1491 int bigendianp,int word,int sgned,int *bitstream){
1493 int host_endian = host_is_big_endian();
1498 if(vf->ready_state<OPENED)return(OV_EINVAL);
1501 if(vf->ready_state==INITSET){
1502 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1506 /* suck in another packet */
1508 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1519 /* yay! proceed to pack data into the byte buffer */
1521 long channels=ov_info(vf,-1)->channels;
1522 long bytespersample=word * channels;
1523 vorbis_fpu_control fpu;
1524 if(samples>length/bytespersample)samples=length/bytespersample;
1529 /* a tight loop to pack each size */
1533 int off=(sgned?0:128);
1534 vorbis_fpu_setround(&fpu);
1535 for(j=0;j<samples;j++)
1536 for(i=0;i<channels;i++){
1537 val=vorbis_ftoi(pcm[i][j]*128.f);
1539 else if(val<-128)val=-128;
1542 vorbis_fpu_restore(fpu);
1544 int off=(sgned?0:32768);
1546 if(host_endian==bigendianp){
1549 vorbis_fpu_setround(&fpu);
1550 for(i=0;i<channels;i++) { /* It's faster in this order */
1552 short *dest=((short *)buffer)+i;
1553 for(j=0;j<samples;j++) {
1554 val=vorbis_ftoi(src[j]*32768.f);
1555 if(val>32767)val=32767;
1556 else if(val<-32768)val=-32768;
1561 vorbis_fpu_restore(fpu);
1565 vorbis_fpu_setround(&fpu);
1566 for(i=0;i<channels;i++) {
1568 short *dest=((short *)buffer)+i;
1569 for(j=0;j<samples;j++) {
1570 val=vorbis_ftoi(src[j]*32768.f);
1571 if(val>32767)val=32767;
1572 else if(val<-32768)val=-32768;
1577 vorbis_fpu_restore(fpu);
1580 }else if(bigendianp){
1582 vorbis_fpu_setround(&fpu);
1583 for(j=0;j<samples;j++)
1584 for(i=0;i<channels;i++){
1585 val=vorbis_ftoi(pcm[i][j]*32768.f);
1586 if(val>32767)val=32767;
1587 else if(val<-32768)val=-32768;
1590 *buffer++=(val&0xff);
1592 vorbis_fpu_restore(fpu);
1596 vorbis_fpu_setround(&fpu);
1597 for(j=0;j<samples;j++)
1598 for(i=0;i<channels;i++){
1599 val=vorbis_ftoi(pcm[i][j]*32768.f);
1600 if(val>32767)val=32767;
1601 else if(val<-32768)val=-32768;
1603 *buffer++=(val&0xff);
1606 vorbis_fpu_restore(fpu);
1612 vorbis_synthesis_read(&vf->vd,samples);
1613 vf->pcm_offset+=samples;
1614 if(bitstream)*bitstream=vf->current_link;
1615 return(samples*bytespersample);
1621 /* input values: pcm_channels) a float vector per channel of output
1622 length) the sample length being read by the app
1624 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1626 n) number of samples of PCM actually returned. The
1627 below works on a packet-by-packet basis, so the
1628 return length is not related to the 'length' passed
1629 in, just guaranteed to fit.
1631 *section) set to the logical bitstream number */
1635 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1638 if(vf->ready_state<OPENED)return(OV_EINVAL);
1641 if(vf->ready_state==INITSET){
1643 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1645 if(pcm_channels)*pcm_channels=pcm;
1646 if(samples>length)samples=length;
1647 vorbis_synthesis_read(&vf->vd,samples);
1648 vf->pcm_offset+=samples;
1649 if(bitstream)*bitstream=vf->current_link;
1655 /* suck in another packet */
1657 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1658 if(ret==OV_EOF)return(0);
1659 if(ret<=0)return(ret);
1665 extern float *vorbis_window(vorbis_dsp_state *v,int W);
1667 static void _ov_splice(float **pcm,float **lappcm,
1670 float *w1, float *w2){
1681 for(j=0;j<ch1 && j<ch2;j++){
1687 d[i]=d[i]*wd + s[i]*ws;
1690 /* window from zero */
1700 /* make sure vf is INITSET */
1701 static int _ov_initset(OggVorbis_File *vf){
1703 if(vf->ready_state==INITSET)break;
1704 /* suck in another packet */
1706 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1707 if(ret<0 && ret!=OV_HOLE)return(ret);
1713 /* make sure vf is INITSET and that we have a primed buffer; if
1714 we're crosslapping at a stream section boundary, this also makes
1715 sure we're sanity checking against the right stream information */
1716 static int _ov_initprime(OggVorbis_File *vf){
1717 vorbis_dsp_state *vd=&vf->vd;
1719 if(vf->ready_state==INITSET)
1720 if(vorbis_synthesis_pcmout(vd,NULL))break;
1722 /* suck in another packet */
1724 int ret=_fetch_and_process_packet(vf,NULL,1,0);
1725 if(ret<0 && ret!=OV_HOLE)return(ret);
1731 /* grab enough data for lapping from vf; this may be in the form of
1732 unreturned, already-decoded pcm, remaining PCM we will need to
1733 decode, or synthetic postextrapolation from last packets. */
1734 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
1735 float **lappcm,int lapsize){
1739 /* try first to decode the lapping data */
1740 while(lapcount<lapsize){
1741 int samples=vorbis_synthesis_pcmout(vd,&pcm);
1743 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1744 for(i=0;i<vi->channels;i++)
1745 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1747 vorbis_synthesis_read(vd,samples);
1749 /* suck in another packet */
1750 int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
1751 if(ret==OV_EOF)break;
1754 if(lapcount<lapsize){
1755 /* failed to get lapping data from normal decode; pry it from the
1756 postextrapolation buffering, or the second half of the MDCT
1757 from the last packet */
1758 int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
1759 if(samples>lapsize-lapcount)samples=lapsize-lapcount;
1760 for(i=0;i<vi->channels;i++)
1761 memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
1767 /* this sets up crosslapping of a sample by using trailing data from
1768 sample 1 and lapping it into the windowing buffer of sample 2 */
1769 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
1770 vorbis_info *vi1,*vi2;
1776 if(vf1==vf2)return(0); /* degenerate case */
1777 if(vf1->ready_state<OPENED)return(OV_EINVAL);
1778 if(vf2->ready_state<OPENED)return(OV_EINVAL);
1780 /* the relevant overlap buffers must be pre-checked and pre-primed
1781 before looking at settings in the event that priming would cross
1782 a bitstream boundary. So, do it now */
1784 ret=_ov_initset(vf1);
1786 ret=_ov_initprime(vf2);
1789 vi1=ov_info(vf1,-1);
1790 vi2=ov_info(vf2,-1);
1792 lappcm=alloca(sizeof(*lappcm)*vi1->channels);
1793 n1=vorbis_info_blocksize(vi1,0)/2;
1794 n2=vorbis_info_blocksize(vi2,0)/2;
1795 w1=vorbis_window(&vf1->vd,0);
1796 w2=vorbis_window(&vf2->vd,0);
1798 for(i=0;i<vi1->channels;i++)
1799 lappcm[i]=alloca(sizeof(**lappcm)*n1);
1801 _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
1803 /* have a lapping buffer from vf1; now to splice it into the lapping
1805 /* consolidate and expose the buffer. */
1806 vorbis_synthesis_lapout(&vf2->vd,&pcm);
1809 _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
1815 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
1816 int (*localseek)(OggVorbis_File *,ogg_int64_t)){
1824 if(vf->ready_state<OPENED)return(OV_EINVAL);
1825 ret=_ov_initset(vf);
1830 n1=vorbis_info_blocksize(vi,0)/2;
1831 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
1832 persistent; even if the decode state
1833 from this link gets dumped, this
1834 window array continues to exist */
1836 lappcm=alloca(sizeof(*lappcm)*ch1);
1838 lappcm[i]=alloca(sizeof(**lappcm)*n1);
1839 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1841 /* have lapping data; seek and prime the buffer */
1842 ret=localseek(vf,pos);
1844 ret=_ov_initprime(vf);
1847 /* Guard against cross-link changes; they're perfectly legal */
1850 n2=vorbis_info_blocksize(vi,0)/2;
1851 w2=vorbis_window(&vf->vd,0);
1853 /* consolidate and expose the buffer. */
1854 vorbis_synthesis_lapout(&vf->vd,&pcm);
1857 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1863 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
1864 return _ov_64_seek_lap(vf,pos,ov_raw_seek);
1867 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
1868 return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
1871 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
1872 return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
1875 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
1876 int (*localseek)(OggVorbis_File *,double)){
1884 if(vf->ready_state<OPENED)return(OV_EINVAL);
1885 ret=_ov_initset(vf);
1890 n1=vorbis_info_blocksize(vi,0)/2;
1891 w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are
1892 persistent; even if the decode state
1893 from this link gets dumped, this
1894 window array continues to exist */
1896 lappcm=alloca(sizeof(*lappcm)*ch1);
1898 lappcm[i]=alloca(sizeof(**lappcm)*n1);
1899 _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
1901 /* have lapping data; seek and prime the buffer */
1902 ret=localseek(vf,pos);
1904 ret=_ov_initprime(vf);
1907 /* Guard against cross-link changes; they're perfectly legal */
1910 n2=vorbis_info_blocksize(vi,0)/2;
1911 w2=vorbis_window(&vf->vd,0);
1913 /* consolidate and expose the buffer. */
1914 vorbis_synthesis_lapout(&vf->vd,&pcm);
1917 _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
1923 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
1924 return _ov_d_seek_lap(vf,pos,ov_time_seek);
1927 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
1928 return _ov_d_seek_lap(vf,pos,ov_time_seek_page);