we only want coarse navigation through the stream. */
/*************************************************************************
- * Many, many internal helpers. The intention is not to be confusing;
- * rampant duplication and monolithic function implementation would be
+ * Many, many internal helpers. The intention is not to be confusing;
+ * rampant duplication and monolithic function implementation would be
* harder to understand anyway. The high level functions are last. Begin
* grokking near the end of the file */
/* save a tiny smidge of verbosity to make the code more readable */
static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
- if(vf->datasource){
+ if(vf->datasource){
if(!(vf->callbacks.seek_func)||
(vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
return OV_EREAD;
if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
more=ogg_sync_pageseek(&vf->oy,og);
-
+
if(more<0){
/* skipped n bytes */
vf->offset-=more;
ogg_int64_t ret=vf->offset;
vf->offset+=more;
return(ret);
-
+
}
}
}
}else{
*serialno_list = _ogg_malloc(sizeof(**serialno_list));
}
-
+
(*serialno_list)[(*n)-1] = s;
}
if(ret_serialno == *serialno){
prefoffset=ret;
*granpos=ret_gran;
- }
+ }
if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){
/* we fell off the end of the link, which means we seeked
ret=OV_EBADHEADER;
goto bail_header;
}
-
+
_add_serialno(og_ptr,serialno_list,serialno_n);
}
}
/* if this page also belongs to our vorbis stream, submit it and break */
- if(vf->ready_state==STREAMSET &&
+ if(vf->ready_state==STREAMSET &&
vf->os.serialno == ogg_page_serialno(og_ptr)){
ogg_stream_pagein(&vf->os,og_ptr);
break;
- }
- }
+ }
+ }
}
if(vf->ready_state!=STREAMSET){
}
while(1){
-
+
i=0;
while(i<2){ /* get a page loop */
-
+
while(i<2){ /* get a packet loop */
-
+
int result=ogg_stream_packetout(&vf->os,&op);
if(result==0)break;
if(result==-1){
ret=OV_EBADHEADER;
goto bail_header;
}
-
+
if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
goto bail_header;
-
+
i++;
}
-
+
while(i<2){
if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
ret=OV_EBADHEADER;
goto bail_header;
}
-
+
/* if this page belongs to the correct stream, go parse it */
if(vf->os.serialno == ogg_page_serialno(og_ptr)){
ogg_stream_pagein(&vf->os,og_ptr);
break;
}
-
+
/* if we never see the final vorbis headers before the link
ends, abort */
if(ogg_page_bos(og_ptr)){
}else
allbos=1;
}
-
+
/* otherwise, keep looking */
}
}
-
- return 0;
+
+ return 0;
}
bail_header:
ogg_packet op;
if(_get_next_page(vf,&og,-1)<0)
break; /* should not be possible unless the file is truncated/mangled */
-
+
if(ogg_page_bos(&og)) break;
if(ogg_page_serialno(&og)!=serialno) continue;
-
+
/* count blocksizes of all frames in the page */
ogg_stream_pagein(&vf->os,&og);
while((result=ogg_stream_packetout(&vf->os,&op))){
/* less than zero? This is a stream with samples trimmed off
the beginning, a normal occurrence; set the offset to zero */
if(accumulated<0)accumulated=0;
-
+
return accumulated;
}
ogg_int64_t ret,last;
int serialno = vf->os.serialno;
- /* invariants:
+ /* invariants:
we have the headers and serialnos for the link beginning at 'begin'
- we have the offset and granpos of the last page in the file (potentially
+ we have the offset and granpos of the last page in the file (potentially
not a page we care about)
*/
down to (or just started with) a single link. Now we need to
find the last vorbis page belonging to the first vorbis stream
for this link. */
-
+
while(endserial != serialno){
endserial = serialno;
vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran);
vf->offsets[m+1]=end;
vf->offsets[m]=begin;
- vf->pcmlengths[m*2+1]=endgran;
+ vf->pcmlengths[m*2+1]=endgran;
}else{
-
+
long *next_serialno_list=NULL;
int next_serialnos=0;
vorbis_info vi;
first pages of two links. */
while(searched<endsearched){
ogg_int64_t bisect;
-
+
if(endsearched-searched<CHUNKSIZE){
bisect=searched;
}else{
bisect=(searched+endsearched)/2;
}
-
+
ret=_seek_helper(vf,bisect);
if(ret)return(ret);
ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
next_serialno_list,next_serialnos,m+1);
if(ret)return(ret);
-
+
if(next_serialno_list)_ogg_free(next_serialno_list);
-
+
vf->offsets[m+1]=next;
vf->serialnos[m+1]=serialno;
vf->dataoffsets[m+1]=dataoffset;
}else{
if(vorbis_synthesis_init(&vf->vd,vf->vi))
return OV_EBADLINK;
- }
+ }
vorbis_block_init(&vf->vd,&vf->vb);
vf->ready_state=INITSET;
vf->bittrack=0.f;
/* now determine bitstream structure recursively */
if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial,
- vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
+ vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
vf->offsets[0]=0;
vf->serialnos[0]=serialno;
return(ov_raw_seek(vf,dataoffset));
}
-/* clear out the current logical bitstream decoder */
+/* clear out the current logical bitstream decoder */
static void _decode_clear(OggVorbis_File *vf){
vorbis_dsp_clear(&vf->vd);
vorbis_block_clear(&vf->vb);
bitstream boundary and dumps the decoding machine. If the decoding
machine is unloaded, it loads it. It also keeps pcm_offset up to
date (seek and read both use this. seek uses a special hack with
- readp).
+ readp).
return: <0) error, OV_HOLE (lost packet) or OV_EOF
0) need more data (only if readp==0)
- 1) got a packet
+ 1) got a packet
*/
static int _fetch_and_process_packet(OggVorbis_File *vf,
/* handle one packet. Try to fetch it from current stream state */
/* extract packets from page */
while(1){
-
+
/* process a packet if we can. If the machine isn't loaded,
neither is a page */
if(vf->ready_state==INITSET){
/* for proper use of libvorbis within libvorbisfile,
oldsamples will always be zero. */
if(oldsamples)return(OV_EFAULT);
-
+
vorbis_synthesis_blockin(&vf->vd,&vf->vb);
vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
vf->bittrack+=op_ptr->bytes*8;
}
-
+
/* update the pcm offset. */
if(granulepos!=-1 && !op_ptr->e_o_s){
int link=(vf->seekable?vf->current_link:0);
int i,samples;
-
+
/* this packet has a pcm_offset on it (the last packet
completed on a page carries the offset) After processing
(above), we know the pcm position of the *last* sample
is very broken */
samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
-
+
granulepos-=samples;
for(i=0;i<link;i++)
granulepos+=vf->pcmlengths[i*2+1];
return(1);
}
}
- else
+ else
break;
}
}
if(vf->ready_state>=OPENED){
ogg_int64_t ret;
-
- while(1){
+
+ while(1){
/* the loop is not strictly necessary, but there's no sense in
doing the extra checks of the larger loop for the common
case in a multiplexed bistream where the page is simply
part of a different logical bitstream; keep reading until
we get one with the correct serialno */
-
+
if(!readp)return(0);
if((ret=_get_next_page(vf,&og,-1))<0){
return(OV_EOF); /* eof. leave unitialized */
/* bitrate tracking; add the header's bytes here, the body bytes
are done by packet above */
vf->bittrack+=og.header_len*8;
-
+
if(vf->ready_state==INITSET){
if(vf->current_serialno!=ogg_page_serialno(&og)){
-
- /* two possibilities:
+
+ /* two possibilities:
1) our decoding just traversed a bitstream boundary
2) another stream is multiplexed into this logical section */
-
+
if(ogg_page_bos(&og)){
/* boundary case */
if(!spanp)
return(OV_EOF);
-
+
_decode_clear(vf);
-
+
if(!vf->seekable){
vorbis_info_clear(vf->vi);
vorbis_comment_clear(vf->vc);
}
/* Do we need to load a new machine before submitting the page? */
- /* This is different in the seekable and non-seekable cases.
+ /* This is different in the seekable and non-seekable cases.
In the seekable case, we already have all the header
information loaded and cached; we just initialize the machine
we're now nominally at the header of the next bitstream
*/
- if(vf->ready_state!=INITSET){
+ if(vf->ready_state!=INITSET){
int link;
if(vf->ready_state<STREAMSET){
vf->current_serialno=serialno;
vf->current_link=link;
-
+
ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
vf->ready_state=STREAMSET;
-
+
}else{
/* we're streaming */
/* fetch the three header packets, build the info struct */
-
+
int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
if(ret)return(ret);
vf->current_serialno=vf->os.serialno;
link=0;
}
}
-
+
{
int ret=_make_decode_ready(vf);
if(ret<0)return ret;
long *serialno_list=NULL;
int serialno_list_size=0;
int ret;
-
+
memset(vf,0,sizeof(*vf));
vf->datasource=f;
vf->callbacks = callbacks;
vf->serialnos[0]=vf->current_serialno;
vf->serialnos[1]=serialno_list_size;
memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
-
+
vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
vf->offsets[0]=0;
vorbis_block_clear(&vf->vb);
vorbis_dsp_clear(&vf->vd);
ogg_stream_clear(&vf->os);
-
+
if(vf->vi && vf->links){
int i;
for(i=0;i<vf->links;i++){
/* inspects the OggVorbis file and finds/documents all the logical
bitstreams contained in it. Tries to be tolerant of logical
- bitstream sections that are truncated/woogie.
+ bitstream sections that are truncated/woogie.
return: -1) error
0) OK
return ret;
}
-
+
/* cheap hack for game usage where downsampling is desirable; there's
no need for SRC as we can just do it cheaply in libvorbis. */
-
+
int ov_halfrate(OggVorbis_File *vf,int flag){
int i;
if(vf->vi==NULL)return OV_EINVAL;
for now dumping the decode machine is needed
to reinit the MDCT lookups. 1.1 libvorbis
is planned to be able to switch on the fly */
-
+
for(i=0;i<vf->links;i++){
if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
ov_halfrate(vf,0);
return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
-
+
int ov_test_open(OggVorbis_File *vf){
if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
return _ov_open2(vf);
/* returns the actual bitrate since last call. returns -1 if no
additional data to offer since last call (or at beginning of stream),
- EINVAL if stream is only partially open
+ EINVAL if stream is only partially open
*/
long ov_bitrate_instant(OggVorbis_File *vf){
int link=(vf->seekable?vf->current_link:0);
/* returns: total PCM length (samples) of content if i==-1 PCM length
(samples) of that logical bitstream for i==0 to n
OV_EINVAL if the stream is not seekable (we can't know the
- length) or only partially open
+ length) or only partially open
*/
ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
if(vf->ready_state<OPENED)return(OV_EINVAL);
/* returns: total seconds of content if i==-1
seconds in that logical bitstream for i==0 to n
OV_EINVAL if the stream is not seekable (we can't know the
- length) or only partially open
+ length) or only partially open
*/
double ov_time_total(OggVorbis_File *vf,int i){
if(vf->ready_state<OPENED)return(OV_EINVAL);
ogg_stream_reset_serialno(&vf->os,
vf->current_serialno); /* must set serialno */
vorbis_synthesis_restart(&vf->vd);
-
+
ret=_seek_helper(vf,pos);
if(ret)goto seek_error;
So, a hack. We use two stream states; a local scratch state and
the shared vf->os stream state. We use the local state to
- scan, and the shared state as a buffer for later decode.
+ scan, and the shared state as a buffer for later decode.
Unfortuantely, on the last page we still advance to last packet
because the granulepos on the last page is not necessarily on a
packet boundary, and we need to make sure the granpos is
- correct.
+ correct.
*/
{
int lastblock=0;
int accblock=0;
int thisblock=0;
- int eosflag=0;
+ int eosflag=0;
ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
if(vf->ready_state>=STREAMSET){
/* snarf/scan a packet if we can */
int result=ogg_stream_packetout(&work_os,&op);
-
+
if(result>0){
if(vf->vi[vf->current_link].codec_setup){
ogg_stream_packetout(&vf->os,NULL);
thisblock=0;
}else{
-
+
if(eosflag)
ogg_stream_packetout(&vf->os,NULL);
else
if(lastblock)accblock+=(lastblock+thisblock)>>2;
- }
+ }
if(op.granulepos!=-1){
int i,link=vf->current_link;
ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
if(granulepos<0)granulepos=0;
-
+
for(i=0;i<link;i++)
granulepos+=vf->pcmlengths[i*2+1];
vf->pcm_offset=granulepos-accblock;
ogg_stream_packetout(&vf->os,NULL);
}
}
-
+
if(!lastblock){
if(_get_next_page(vf,&og,-1)<0){
vf->pcm_offset=ov_pcm_total(vf,-1);
vf->pcm_offset=-1;
break;
}
-
+
/* has our decoding just traversed a bitstream boundary? */
if(vf->ready_state>=STREAMSET){
if(vf->current_serialno!=ogg_page_serialno(&og)){
-
- /* two possibilities:
+
+ /* two possibilities:
1) our decoding just traversed a bitstream boundary
2) another stream is multiplexed into this logical section? */
-
+
if(ogg_page_bos(&og)){
/* we traversed */
_decode_clear(vf); /* clear out stream state */
vf->current_link=link;
vf->current_serialno=serialno;
ogg_stream_reset_serialno(&vf->os,serialno);
- ogg_stream_reset_serialno(&work_os,serialno);
+ ogg_stream_reset_serialno(&work_os,serialno);
vf->ready_state=STREAMSET;
-
+
}
-
+
ogg_stream_pagein(&vf->os,&og);
ogg_stream_pagein(&work_os,&og);
eosflag=ogg_page_eos(&og);
int link=-1;
ogg_int64_t result=0;
ogg_int64_t total=ov_pcm_total(vf,-1);
-
+
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(pos<0 || pos>total)return(OV_EINVAL);
-
+
/* which bitstream section does this pcm offset occur in? */
for(link=vf->links-1;link>=0;link--){
total-=vf->pcmlengths[link*2+1];
ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
ogg_int64_t target=pos-total+begintime;
ogg_int64_t best=begin;
-
+
ogg_page og;
while(begin<end){
ogg_int64_t bisect;
-
+
if(end-begin<CHUNKSIZE){
bisect=begin;
}else{
if(bisect<=begin)
bisect=begin+1;
}
-
+
result=_seek_helper(vf,bisect);
if(result) goto seek_error;
-
+
while(begin<end){
result=_get_next_page(vf,&og,end-vf->offset);
if(result==OV_EREAD) goto seek_error;
granulepos=ogg_page_granulepos(&og);
if(granulepos==-1)continue;
-
+
if(granulepos<target){
- best=result; /* raw offset of packet with granulepos */
+ best=result; /* raw offset of packet with granulepos */
begin=vf->offset; /* raw offset of next page */
begintime=granulepos;
-
+
if(target-begintime>44100)break;
bisect=begin; /* *not* begin + 1 */
}else{
{
ogg_page og;
ogg_packet op;
-
+
/* seek */
result=_seek_helper(vf,best);
vf->pcm_offset=-1;
if(result) goto seek_error;
result=_get_next_page(vf,&og,-1);
if(result<0) goto seek_error;
-
+
if(link!=vf->current_link){
/* Different link; dump entire decode machine */
- _decode_clear(vf);
-
+ _decode_clear(vf);
+
vf->current_link=link;
vf->current_serialno=vf->serialnos[link];
vf->ready_state=STREAMSET;
-
+
}else{
vorbis_synthesis_restart(&vf->vd);
}
preceeding page. Keep fetching previous pages until we
get one with a granulepos or without the 'continued' flag
set. Then just use raw_seek for simplicity. */
-
+
result=_seek_helper(vf,best);
if(result<0) goto seek_error;
-
+
while(1){
result=_get_prev_page(vf,&og);
if(result<0) goto seek_error;
}
}
if(result<0){
- result = OV_EBADPACKET;
+ result = OV_EBADPACKET;
goto seek_error;
}
if(op.granulepos!=-1){
}
}
}
-
+
/* verify result */
if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
result=OV_EFAULT;
vf->bittrack=0.f;
vf->samptrack=0.f;
return(0);
-
+
seek_error:
/* dump machine so we're in a known state */
vf->pcm_offset=-1;
return (int)result;
}
-/* seek to a sample offset relative to the decompressed pcm stream
+/* seek to a sample offset relative to the decompressed pcm stream
returns zero on success, nonzero on failure */
int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
continue; /* non audio packet */
}
if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
-
+
if(vf->pcm_offset+((thisblock+
vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
-
+
/* remove the packet from packet queue and track its granulepos */
ogg_stream_packetout(&vf->os,NULL);
vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
only tracking, no
pcm_decode */
- vorbis_synthesis_blockin(&vf->vd,&vf->vb);
-
+ vorbis_synthesis_blockin(&vf->vd,&vf->vb);
+
/* end of logical stream case is hard, especially with exact
length positioning. */
-
+
if(op.granulepos>-1){
int i;
/* always believe the stream markers */
for(i=0;i<vf->current_link;i++)
vf->pcm_offset+=vf->pcmlengths[i*2+1];
}
-
+
lastblock=thisblock;
-
+
}else{
if(ret<0 && ret!=OV_HOLE)break;
-
+
/* suck in a new page */
if(_get_next_page(vf,&og,-1)<0)break;
if(ogg_page_bos(&og))_decode_clear(vf);
-
+
if(vf->ready_state<STREAMSET){
long serialno=ogg_page_serialno(&og);
int link;
-
+
for(link=0;link<vf->links;link++)
if(vf->serialnos[link]==serialno)break;
- if(link==vf->links) continue;
+ if(link==vf->links) continue;
vf->current_link=link;
-
- vf->ready_state=STREAMSET;
+
+ vf->ready_state=STREAMSET;
vf->current_serialno=ogg_page_serialno(&og);
- ogg_stream_reset_serialno(&vf->os,serialno);
+ ogg_stream_reset_serialno(&vf->os,serialno);
ret=_make_decode_ready(vf);
if(ret)return ret;
lastblock=0;
if(samples>target)samples=target;
vorbis_synthesis_read(&vf->vd,samples);
vf->pcm_offset+=samples;
-
+
if(samples<target)
if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
return 0;
}
-/* seek to a playback time relative to the decompressed pcm stream
+/* seek to a playback time relative to the decompressed pcm stream
returns zero on success, nonzero on failure */
int ov_time_seek(OggVorbis_File *vf,double seconds){
/* translate time to PCM position and call ov_pcm_seek */
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(seconds<0)return(OV_EINVAL);
-
+
/* which bitstream section does this time offset occur in? */
for(link=0;link<vf->links;link++){
double addsec = ov_time_total(vf,link);
}
}
-/* page-granularity version of ov_time_seek
+/* page-granularity version of ov_time_seek
returns zero on success, nonzero on failure */
int ov_time_seek_page(OggVorbis_File *vf,double seconds){
/* translate time to PCM position and call ov_pcm_seek */
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(seconds<0)return(OV_EINVAL);
-
+
/* which bitstream section does this time offset occur in? */
for(link=0;link<vf->links;link++){
double addsec = ov_time_total(vf,link);
int link=0;
ogg_int64_t pcm_total=0;
double time_total=0.f;
-
+
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(vf->seekable){
pcm_total=ov_pcm_total(vf,-1);
time_total=ov_time_total(vf,-1);
-
+
/* which bitstream section does this time offset occur in? */
for(link=vf->links-1;link>=0;link--){
pcm_total-=vf->pcmlengths[link*2+1];
/* link: -1) return the vorbis_info struct for the bitstream section
currently being decoded
0-n) to request information for a specific bitstream section
-
+
In the case of a non-seekable bitstream, any call returns the
current bitstream. NULL in the case that the machine is not
initialized */
length) the byte length requested to be placed into buffer
bigendianp) should the data be packed LSB first (0) or
MSB first (1)
- word) word size for output. currently 1 (byte) or
+ word) word size for output. currently 1 (byte) or
2 (16 bit short)
return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
}
if(samples>0){
-
+
/* yay! proceed to pack data into the byte buffer */
-
+
long channels=ov_info(vf,-1)->channels;
long bytespersample=word * channels;
vorbis_fpu_control fpu;
if(samples <= 0)
return OV_EINVAL;
-
+
/* Here. */
if(filter)
filter(pcm,channels,samples,filter_param);
vorbis_fpu_restore(fpu);
}else{
int off=(sgned?0:32768);
-
+
if(host_endian==bigendianp){
if(sgned){
-
+
vorbis_fpu_setround(&fpu);
for(i=0;i<channels;i++) { /* It's faster in this order */
float *src=pcm[i];
}
}
vorbis_fpu_restore(fpu);
-
+
}else{
-
+
vorbis_fpu_setround(&fpu);
for(i=0;i<channels;i++) {
float *src=pcm[i];
}
}
vorbis_fpu_restore(fpu);
-
+
}
}else if(bigendianp){
-
+
vorbis_fpu_setround(&fpu);
for(j=0;j<samples;j++)
for(i=0;i<channels;i++){
*buffer++=(val&0xff);
}
vorbis_fpu_restore(fpu);
-
+
}else{
int val;
vorbis_fpu_setround(&fpu);
*buffer++=(val&0xff);
*buffer++=(val>>8);
}
- vorbis_fpu_restore(fpu);
-
+ vorbis_fpu_restore(fpu);
+
}
}
}
-
+
vorbis_synthesis_read(&vf->vd,samples);
vf->pcm_offset+=samples;
if(bitstream)*bitstream=vf->current_link;
}
extern float *vorbis_window(vorbis_dsp_state *v,int W);
-extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
- ogg_int64_t off);
static void _ov_splice(float **pcm,float **lappcm,
int n1, int n2,
}
}
-
+
/* make sure vf is INITSET */
static int _ov_initset(OggVorbis_File *vf){
while(1){
while(1){
if(vf->ready_state==INITSET)
if(vorbis_synthesis_pcmout(vd,NULL))break;
-
+
/* suck in another packet */
{
int ret=_fetch_and_process_packet(vf,NULL,1,0);
if(ret<0 && ret!=OV_HOLE)return(ret);
}
- }
+ }
return 0;
}
buffer of vf2 */
/* consolidate and expose the buffer. */
vorbis_synthesis_lapout(&vf2->vd,&pcm);
+
+#if 0
_analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
_analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
+#endif
/* splice */
_ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
-
+
/* done */
return(0);
}
if(ret)return(ret);
vi=ov_info(vf,-1);
hs=ov_halfrate_p(vf);
-
+
ch1=vi->channels;
n1=vorbis_info_blocksize(vi,0)>>(1+hs);
w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are