ogg_int64_t val,ogg_int64_t pcmval,double timeval,
ogg_int64_t pcmlength,
char *bigassbuffer){
+ off_t i;
int j;
long bread;
char buffer[4096];
int dummy;
ogg_int64_t pos;
+ int hs = ov_halfrate_p(ov);
/* verify the raw position, the pcm position and position decode */
if(val!=-1 && ov_raw_tell(ov)<val){
}
bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
for(j=0;j<bread;j++){
- if(buffer[j]!=bigassbuffer[j+pos*2]){
- fprintf(stderr,"data position after seek doesn't match pcm position\n");
-
+ if(buffer[j]!=bigassbuffer[j+((pos>>hs)*2)]){
+ fprintf(stderr,"data after seek doesn't match declared pcm position %lld\n",pos);
+
+ for(i=0;i<(pcmlength>>hs)*2-bread;i++){
+ for(j=0;j<bread;j++)
+ if(buffer[j] != bigassbuffer[i+j])break;
+ if(j==bread){
+ fprintf(stderr,"data after seek appears to match position %lld\n",(i/2)<<hs);
+ }
+ }
{
FILE *f=fopen("a.m","w");
- for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)buffer[j]);
+ for(j=0;j<bread;j++)fprintf(f,"%d %d\n",j,(int)buffer[j]);
fclose(f);
f=fopen("b.m","w");
- for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)bigassbuffer[j+pos*2]);
+ for(j=-4096;j<bread+4096;j++)
+ if(j+((pos*2)>>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2)
+ fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]);
fclose(f);
}
double timelength;
char *bigassbuffer;
int dummy;
+ int hs=0;
#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
_setmode( _fileno( stdin ), _O_BINARY );
exit(1);
}
+#if 0 /*enable this code to test seeking with halfrate decode */
+ if(ov_halfrate(&ov,1)){
+ fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n");
+ exit(1);
+ }else
+ hs=1;
+#endif
+
if(ov_seekable(&ov)){
/* to simplify our own lives, we want to assume the whole file is
does what it claimed, decode the entire file into memory */
pcmlength=ov_pcm_total(&ov,-1);
timelength=ov_time_total(&ov,-1);
- bigassbuffer=malloc(pcmlength*2); /* w00t */
+ bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */
i=0;
- while(i<pcmlength*2){
- int ret=ov_read(&ov,bigassbuffer+i,pcmlength*2-i,1,1,1,&dummy);
+ while(i<(pcmlength>>hs)*2){
+ int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy);
if(ret<0){
fprintf(stderr,"Error reading file.\n");
exit(1);
if(ret){
i+=ret;
}else{
- pcmlength=i/2;
+ pcmlength=(i/2)<<hs;
}
fprintf(stderr,"\rloading.... [%ld left] ",
- (long)(pcmlength*2-i));
+ (long)((pcmlength>>hs)*2-i));
}
{
}
}
-
+
fprintf(stderr,"\r");
{
fprintf(stderr,"testing pcm exact seeking to random places in %ld samples....\n",
fprintf(stderr,"seek failed: %d\n",ret);
exit(1);
}
- if(ov_pcm_tell(&ov)!=val){
+ if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){
fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
(long)val,(long)ov_pcm_tell(&ov));
exit(1);
/* process a packet if we can. */
if(vf->ready_state==INITSET){
+ int hs=vorbis_synthesis_halfrate_p(vf->vi);
+
while(1) {
ogg_packet op;
ogg_packet *op_ptr=(op_in?op_in:&op);
if(oldsamples)return(OV_EFAULT);
vorbis_synthesis_blockin(&vf->vd,&vf->vb);
- vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
+ vf->samptrack+=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
vf->bittrack+=op_ptr->bytes*8;
}
here unless the stream
is very broken */
- samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
+ samples=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
granulepos-=samples;
for(i=0;i<link;i++)
int ov_halfrate(OggVorbis_File *vf,int flag){
int i;
if(vf->vi==NULL)return OV_EINVAL;
- if(!vf->seekable)return OV_EINVAL;
- if(vf->ready_state>=STREAMSET)
- _decode_clear(vf); /* clear out stream state; later on libvorbis
- will be able to swap this on the fly, but
- 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 */
+ if(vf->ready_state>STREAMSET){
+ /* clear out stream state; dumping the decode machine is needed to
+ reinit the MDCT lookups. */
+ vorbis_dsp_clear(&vf->vd);
+ vorbis_block_clear(&vf->vb);
+ vf->ready_state=STREAMSET;
+ if(vf->pcm_offset>=0){
+ ogg_int64_t pos=vf->pcm_offset;
+ vf->pcm_offset=-1; /* make sure the pos is dumped if unseekable */
+ ov_pcm_seek(vf,pos);
+ }
+ }
for(i=0;i<vf->links;i++){
if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
- ov_halfrate(vf,0);
+ if(flag) ov_halfrate(vf,0);
return OV_EINVAL;
}
}
vf->samptrack=0.f;
/* discard samples until we reach the desired position. Crossing a
logical bitstream boundary with abandon is OK. */
- while(vf->pcm_offset<pos){
- ogg_int64_t target=pos-vf->pcm_offset;
- long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
-
- 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 */
+ {
+ /* note that halfrate could be set differently in each link, but
+ vorbisfile encoforces all links are set or unset */
+ int hs=vorbis_synthesis_halfrate_p(vf->vi);
+ while(vf->pcm_offset<((pos>>hs)<<hs)){
+ ogg_int64_t target=(pos-vf->pcm_offset)>>hs;
+ long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
+
+ if(samples>target)samples=target;
+ vorbis_synthesis_read(&vf->vd,samples);
+ vf->pcm_offset+=samples<<hs;
+
+ if(samples<target)
+ if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
+ vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
+ }
}
return 0;
}
void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
int i,j;
int host_endian = host_is_big_endian();
+ int hs;
float **pcm;
long samples;
}
vorbis_synthesis_read(&vf->vd,samples);
- vf->pcm_offset+=samples;
+ hs=vorbis_synthesis_halfrate_p(vf->vi);
+ vf->pcm_offset+=(samples<<hs);
if(bitstream)*bitstream=vf->current_link;
return(samples*bytespersample);
}else{
float **pcm;
long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
if(samples){
+ int hs=vorbis_synthesis_halfrate_p(vf->vi);
if(pcm_channels)*pcm_channels=pcm;
if(samples>length)samples=length;
vorbis_synthesis_read(&vf->vd,samples);
- vf->pcm_offset+=samples;
+ vf->pcm_offset+=samples<<hs;
if(bitstream)*bitstream=vf->current_link;
return samples;