Commit 55e2d3a7 authored by Monty Montgomery's avatar Monty Montgomery

We really do need padded fourier blocks to avoid time-aliasing.
Implement that in the declipper and make sure to use it in later
filters.

Monty


git-svn-id: https://svn.xiph.org/trunk/postfish@5824 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent a99f7874
......@@ -73,10 +73,10 @@ static void blocksize_slider_change(GtkWidget *w,gpointer in){
int choice=rint(gtk_range_get_value(GTK_RANGE(w)));
int blocksize=64<<choice;
sprintf(buffer,"%5d ",blocksize*3/4);
sprintf(buffer,"%5d ",blocksize);
readout_set(READOUT(samplereadout),buffer);
sprintf(buffer,"%3.1f ms",blocksize*3000./4/input_rate);
sprintf(buffer,"%3.1f ms",blocksize*1000./input_rate);
readout_set(READOUT(msreadout),buffer);
sprintf(buffer,"%5d Hz",(int)rint(input_rate*2./blocksize));
......
......@@ -129,7 +129,7 @@ int declip_setblock(int n){
int declip_settrigger(double trigger,int ch){
if(ch<0 || ch>=input_ch)return -1;
pthread_mutex_lock(&master_mutex);
chtrigger[ch]=trigger;
chtrigger[ch]=trigger-(1./32768);
pthread_mutex_unlock(&master_mutex);
return 0;
}
......@@ -216,12 +216,11 @@ static void declip(double *data,double *lap,double *out,
int blocksize,double trigger,
double epsilon, double iteration,
int *runningtotal, int *runningcount){
double freq[blocksize];
double flag[blocksize];
double freq[blocksize*2];
double flag[blocksize*2];
int iterbound,i,j,count=0;
for(i=0;i<blocksize/8;i++)flag[i]=0.;
for(;i<blocksize*7/8;i++){
for(i=blocksize/2;i<blocksize*3/2;i++){
flag[i]=0.;
if(data[i]>=trigger || data[i]<=-trigger){
flag[i]=1.;
......@@ -229,36 +228,41 @@ static void declip(double *data,double *lap,double *out,
}
}
*runningtotal+=blocksize*3/4;
*runningtotal+=blocksize;
*runningcount+=count;
if(declip_active){
for(;i<blocksize;i++)flag[i]=0.;
for(i=0;i<blocksize;i++)data[i]*=window[i];
for(i=0;i<blocksize/2;i++)flag[i]=0.;
for(i=blocksize*3/2;i<blocksize*2;i++)flag[i]=0.;
for(i=0;i<blocksize/2;i++)data[i]=0.;
for(i=0;i<blocksize;i++)data[i+blocksize/2]*=window[i];
for(i=blocksize*3/2;i<blocksize*2;i++)data[i]=0.;
memcpy(freq,data,sizeof(freq));
drft_forward(&fft,freq);
sliding_bark_average(freq,freq,blocksize,width);
sliding_bark_average(freq,freq,blocksize*2,width);
iterbound=count*iteration;
if(iterbound<10)iterbound=10;
if(count)reconstruct(&fft,data,freq,flag,epsilon,iterbound,blocksize);
if(count)reconstruct(&fft,data,freq,flag,epsilon,iterbound,blocksize*2);
if(out)
for(i=0;i<blocksize/2;i++)
out[i]=lap[i]+data[i]*window[i];
out[i]=lap[i]+data[i+blocksize/2]*window[i];
for(i=blocksize/2,j=0;i<blocksize;i++)
lap[j++]=data[i]*window[i];
lap[j++]=data[i+blocksize/2]*window[i];
}else{
if(out)
for(i=0;i<blocksize/2;i++)
out[i]=data[i];
out[i]=data[i+blocksize/2];
for(i=blocksize/2,j=0;i<blocksize;i++)
lap[j++]=data[i]*window[i]*window[i];
lap[j++]=data[i+blocksize/2]*window[i]*window[i];
}
for(i=blocksize/2;i<input_size;i++)
lap[i]=0.;
......@@ -291,31 +295,27 @@ time_linkage *declip_read(time_linkage *in){
}
blocksize=pending_blocksize;
lopad=1-rint(fromBark(toBark(0.)-width)*blocksize/input_rate);
hipad=rint(fromBark(toBark(input_rate*.5)+width)*blocksize/input_rate)+lopad;
lopad=1-rint(fromBark(toBark(0.)-width)*blocksize*2/input_rate);
hipad=rint(fromBark(toBark(input_rate*.5)+width)*blocksize*2/input_rate)+lopad;
widthlookup=malloc((hipad+1)*sizeof(*widthlookup));
for(i=0;i<blocksize/2;i++){
double bark=toBark(input_rate*i/blocksize);
int hi=rint(fromBark(bark-width)*blocksize/input_rate)-1+lopad;
int lo=rint(fromBark(bark+width)*blocksize/input_rate)+1+lopad;
for(i=0;i<blocksize;i++){
double bark=toBark(input_rate*i/(blocksize*2));
int hi=rint(fromBark(bark-width)*(blocksize*2)/input_rate)-1+lopad;
int lo=rint(fromBark(bark+width)*(blocksize*2)/input_rate)+1+lopad;
widthlookup[i]=(hi<<16)+lo;
}
drft_init(&fft,blocksize);
drft_init(&fft,blocksize*2);
window=malloc(blocksize*sizeof(*window));
for(i=0;i<blocksize/8;i++) window[i]=0.;
for(;i<blocksize*3/8;i++) window[i]=sin( (double)(i-blocksize/8)/blocksize*M_PIl*2. );
for(;i<blocksize*5/8;i++) window[i]=1.;
for(;i<blocksize*7/8;i++) window[i]=sin( (double)(blocksize*7/8-i)/blocksize*M_PIl*2. );
for(;i<blocksize;i++) window[i]=0.;
for(i=0;i<blocksize;i++) window[i]=sin( M_PIl*i/blocksize );
for(i=0;i<blocksize;i++) window[i]*=window[i];
for(i=0;i<blocksize;i++) window[i]=sin(window[i]*M_PIl*.5);
}
{
double work[blocksize];
double work[blocksize*2];
switch(fillstate){
case 0: /* prime the lapping and cache */
......@@ -323,8 +323,8 @@ time_linkage *declip_read(time_linkage *in){
int j;
double *temp=in->data[i];
total=0;
memset(work,0,sizeof(*work)*blocksize/2);
memcpy(work+blocksize/2,temp,sizeof(*work)*blocksize/2);
memset(work+blocksize/2,0,sizeof(*work)*blocksize/2);
memcpy(work+blocksize,temp,sizeof(*work)*blocksize/2);
declip(work,lap[i],0,blocksize,
local_trigger[i],local_convergence,local_iterations,
&total,count+i);
......@@ -348,13 +348,13 @@ time_linkage *declip_read(time_linkage *in){
int j;
total=0;
for(j=0;j+blocksize<=out.size;j+=blocksize/2){
memcpy(work,temp+j,sizeof(*work)*blocksize);
memcpy(work+blocksize/2,temp+j,sizeof(*work)*blocksize);
declip(work,lap[i],out.data[i]+j,blocksize,
local_trigger[i],local_convergence,local_iterations,
&total,count+i);
}
memcpy(work,temp+j,sizeof(*work)*blocksize/2);
memcpy(work+blocksize/2,in->data[i],sizeof(*work)*blocksize/2);
memcpy(work+blocksize/2,temp+j,sizeof(*work)*blocksize/2);
memcpy(work+blocksize,in->data[i],sizeof(*work)*blocksize/2);
declip(work,lap[i],out.data[i]+j,blocksize,
local_trigger[i],local_convergence,local_iterations,
......
......@@ -517,9 +517,9 @@ time_linkage *input_read(void){
break;
}
if(signp)
dval=out.data[j][i]=val/2147483647.;
dval=out.data[j][i]=val/2147483648.;
else
dval=out.data[j][i]=(val^0x80000000UL)/2147483647.;
dval=out.data[j][i]=(val^0x80000000UL)/2147483648.;
if(fabs(dval)>peak[j])peak[j]=fabs(dval);
rms[j]+= dval*dval;
......
......@@ -862,7 +862,7 @@ static gboolean feedback_process(postfish_mainpanel *panel){
available and not dirtied by a seek */
if(!playback_seeking){
off_t time_cursor;
int n=input_ch+2;
int n=(input_ch>1?input_ch+2:input_ch);
double *rms=alloca(sizeof(*rms)*(input_ch+2));
double *peak=alloca(sizeof(*peak)*(input_ch+2));
......
......@@ -124,9 +124,9 @@ static int isachr(FILE *f){
return 0;
}
static int outbytes;
static FILE *playback_startup(int outfileno, int ch, int r, int *bep){
FILE *playback_fd=NULL;
int format=AFMT_S16_NE;
int rate=r,channels=ch,ret;
if(outfileno==-1){
......@@ -144,6 +144,8 @@ static FILE *playback_startup(int outfileno, int ch, int r, int *bep){
if(isachr(playback_fd)){
int fragment=0x0004000d;
int fd=fileno(playback_fd);
int format=AFMT_S16_NE;
outbytes=2;
/* try to lower the DSP delay; this ioctl may fail gracefully */
ret=ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&fragment);
......@@ -167,7 +169,8 @@ static FILE *playback_startup(int outfileno, int ch, int r, int *bep){
exit(1);
}
}else{
WriteWav(playback_fd,ch,r,16,-1);
outbytes=3;
WriteWav(playback_fd,ch,r,24,-1);
*bep=0;
}
......@@ -176,8 +179,8 @@ static FILE *playback_startup(int outfileno, int ch, int r, int *bep){
/* playback must be halted to change blocksize. */
void *playback_thread(void *dummy){
int audiobufsize=8192,i,j,k;
unsigned char *audiobuf=malloc(audiobufsize);
int audiobufsize=0,i,j,k;
unsigned char *audiobuf=NULL;
int bigendianp=(AFMT_S16_NE==AFMT_S16_BE?1:0);
FILE *playback_fd=NULL;
int setupp=0;
......@@ -241,13 +244,16 @@ void *playback_thread(void *dummy){
setupp=1;
}
if(audiobufsize<link->channels*link->samples*2){
audiobufsize=link->channels*link->samples*2;
audiobuf=realloc(audiobuf,sizeof(*audiobuf)*audiobufsize);
if(audiobufsize<link->channels*link->samples*outbytes){
audiobufsize=link->channels*link->samples*outbytes;
if(audiobuf)
audiobuf=realloc(audiobuf,sizeof(*audiobuf)*audiobufsize);
else
audiobuf=malloc(sizeof(*audiobuf)*audiobufsize);
}
/* final limiting and conversion */
for(k=0,i=0;i<link->samples;i++){
double mean=0.;
double div=0.;
......@@ -255,17 +261,41 @@ void *playback_thread(void *dummy){
for(j=0;j<link->channels;j++){
double dval=link->data[j][i];
int val=rint(dval*32767.);
if(val>32767)val=32767;
if(val<-32768)val=-32768;
if(bigendianp){
audiobuf[k++]=val>>8;
audiobuf[k++]=val;
}else{
audiobuf[k++]=val;
audiobuf[k++]=val>>8;
}
switch(outbytes){
case 3:
{
int32_t val=rint(dval*8388608.);
if(val>8388607)val=8388607;
if(val<-8388608)val=-8388608;
if(bigendianp){
audiobuf[k++]=val>>16;
audiobuf[k++]=val>>8;
audiobuf[k++]=val;
}else{
audiobuf[k++]=val;
audiobuf[k++]=val>>8;
audiobuf[k++]=val>>16;
}
}
break;
case 2:
{
int32_t val=rint(dval*32768.);
if(val>32767)val=32767;
if(val<-32768)val=-32768;
if(bigendianp){
audiobuf[k++]=val>>8;
audiobuf[k++]=val;
}else{
audiobuf[k++]=val;
audiobuf[k++]=val>>8;
}
}
break;
}
if(fabs(dval)>peak[j])peak[j]=fabs(dval);
rms[j]+= dval*dval;
mean+=dval;
......@@ -292,7 +322,7 @@ void *playback_thread(void *dummy){
rms[j]=sqrt(rms[j]);
}
count+=fwrite(audiobuf,1,link->channels*link->samples*2,playback_fd);
count+=fwrite(audiobuf,1,link->channels*link->samples*outbytes,playback_fd);
/* inform Lord Vader his shuttle is ready */
push_output_feedback(peak,rms);
......@@ -307,7 +337,7 @@ void *playback_thread(void *dummy){
ioctl(fd,SNDCTL_DSP_RESET);
}else{
if(ch>-1)
WriteWav(playback_fd,ch,rate,16,count);
WriteWav(playback_fd,ch,rate,24,count);
}
fclose(playback_fd);
}
......
......@@ -122,7 +122,5 @@ void reconstruct(drft_lookup *fft,
}
fprintf(stderr,"converged in %d with res=%f\n",i,sqrt(res_new)/sqrt(res_0));
}
#define VERSION "$Id: version.h,v 1.24 2004/01/14 16:03:34 xiphmont Exp $ "
/* DO NOT EDIT: Automated versioning hack [Mon Jan 12 14:46:49 EST 2004] */
#define VERSION "$Id: version.h,v 1.25 2004/02/13 18:11:35 xiphmont Exp $ "
/* DO NOT EDIT: Automated versioning hack [Fri Feb 13 13:08:35 EST 2004] */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment