Commit ef30c244 authored by Monty Montgomery's avatar Monty Montgomery

Major signal path upgrade to subband.c:

  eliminate all clicks/thumps/dropouts on realtime interaction
  implement mute infrastructure
  active/visible by channel



git-svn-id: https://svn.xiph.org/trunk/postfish@6573 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 97a22680
......@@ -226,6 +226,7 @@ static void slider_change(GtkWidget *w,gpointer in){
cbar *b=(cbar *)in;
int o,u;
int i;
int adj;
u=multibar_get_value(MULTIBAR(b->slider),0);
sprintf(buffer,"%+4ddB",u);
......@@ -246,101 +247,98 @@ static void slider_change(GtkWidget *w,gpointer in){
bc[2].static_o[0]+=o-bc[2].static_o[1];
bc[2].static_u[0]+=u-bc[2].static_u[1];
}
if (b->number<9){
int adj;
/* convolutions for roundoff behavior */
if(b->number>0){
adj=(bc[1].static_o[b->number*2-1]*2 -
bc[1].static_o[b->number*2-2]-bc[1].static_o[b->number*2])/2;
bc[1].static_o[b->number*2-1]=
/* convolutions for roundoff behavior */
if(b->number>0){
adj=(bc[1].static_o[b->number*2-1]*2 -
bc[1].static_o[b->number*2-2]-bc[1].static_o[b->number*2])/2;
bc[1].static_o[b->number*2-1]=
(bc[1].static_o[b->number*2-2]+o)/2+adj;
adj=(bc[1].static_u[b->number*2-1]*2 -
bc[1].static_u[b->number*2-2]-bc[1].static_u[b->number*2])/2;
bc[1].static_u[b->number*2-1]=
(bc[1].static_u[b->number*2-2]+u)/2+adj;
adj=(bc[2].static_o[b->number*3-1]*3 -
bc[2].static_o[b->number*3-2] -
bc[2].static_o[b->number*3-2] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3-1]=
(bc[2].static_o[b->number*3-2]+
bc[2].static_o[b->number*3-2]+
o)/3+adj;
adj=(bc[2].static_o[b->number*3]*3 -
bc[2].static_o[b->number*3-2] -
bc[2].static_o[b->number*3+1] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3]=
(bc[2].static_o[b->number*3-2]+o+o)/3+adj;
adj=(bc[2].static_u[b->number*3-1]*3 -
bc[2].static_u[b->number*3-2] -
bc[2].static_u[b->number*3-2] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3-1]=
(bc[2].static_u[b->number*3-2]+
bc[2].static_u[b->number*3-2]+
u)/3+adj;
adj=(bc[2].static_u[b->number*3]*3 -
bc[2].static_u[b->number*3-2] -
bc[2].static_u[b->number*3+1] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3]=
(bc[2].static_u[b->number*3-2]+u+u)/3+adj;
}
if(b->number<9){
adj=(bc[1].static_o[b->number*2+1]*2-
bc[1].static_o[b->number*2+2]-bc[1].static_o[b->number*2])/2;
bc[1].static_o[b->number*2+1]=
(bc[1].static_o[b->number*2+2]+o)/2+adj;
adj=(bc[1].static_u[b->number*2+1]*2-
bc[1].static_u[b->number*2+2]-bc[1].static_u[b->number*2])/2;
bc[1].static_u[b->number*2+1]=
(bc[1].static_u[b->number*2+2]+u)/2+adj;
adj=(bc[2].static_o[b->number*3+3]*3 -
bc[2].static_o[b->number*3+4] -
bc[2].static_o[b->number*3+4] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3+3]=
(bc[2].static_o[b->number*3+4]+
bc[2].static_o[b->number*3+4]+
o)/3+adj;
adj=(bc[2].static_o[b->number*3+2]*3 -
bc[2].static_o[b->number*3+4] -
bc[2].static_o[b->number*3+1] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3+2]=
(bc[2].static_o[b->number*3+4]+o+o)/3+adj;
adj=(bc[2].static_u[b->number*3+3]*3 -
bc[2].static_u[b->number*3+4] -
bc[2].static_u[b->number*3+4] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3+3]=
(bc[2].static_u[b->number*3+4]+
bc[2].static_u[b->number*3+4]+
u)/3+adj;
adj=(bc[2].static_u[b->number*3+2]*3 -
bc[2].static_u[b->number*3+4] -
bc[2].static_u[b->number*3+1] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3+2]=
(bc[2].static_u[b->number*3+4]+u+u)/3+adj;
}
adj=(bc[1].static_u[b->number*2-1]*2 -
bc[1].static_u[b->number*2-2]-bc[1].static_u[b->number*2])/2;
bc[1].static_u[b->number*2-1]=
(bc[1].static_u[b->number*2-2]+u)/2+adj;
adj=(bc[2].static_o[b->number*3-1]*3 -
bc[2].static_o[b->number*3-2] -
bc[2].static_o[b->number*3-2] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3-1]=
(bc[2].static_o[b->number*3-2]+
bc[2].static_o[b->number*3-2]+
o)/3+adj;
adj=(bc[2].static_o[b->number*3]*3 -
bc[2].static_o[b->number*3-2] -
bc[2].static_o[b->number*3+1] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3]=
(bc[2].static_o[b->number*3-2]+o+o)/3+adj;
adj=(bc[2].static_u[b->number*3-1]*3 -
bc[2].static_u[b->number*3-2] -
bc[2].static_u[b->number*3-2] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3-1]=
(bc[2].static_u[b->number*3-2]+
bc[2].static_u[b->number*3-2]+
u)/3+adj;
adj=(bc[2].static_u[b->number*3]*3 -
bc[2].static_u[b->number*3-2] -
bc[2].static_u[b->number*3+1] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3]=
(bc[2].static_u[b->number*3-2]+u+u)/3+adj;
}
if(b->number<9){
adj=(bc[1].static_o[b->number*2+1]*2-
bc[1].static_o[b->number*2+2]-bc[1].static_o[b->number*2])/2;
bc[1].static_o[b->number*2+1]=
(bc[1].static_o[b->number*2+2]+o)/2+adj;
adj=(bc[1].static_u[b->number*2+1]*2-
bc[1].static_u[b->number*2+2]-bc[1].static_u[b->number*2])/2;
bc[1].static_u[b->number*2+1]=
(bc[1].static_u[b->number*2+2]+u)/2+adj;
adj=(bc[2].static_o[b->number*3+3]*3 -
bc[2].static_o[b->number*3+4] -
bc[2].static_o[b->number*3+4] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3+3]=
(bc[2].static_o[b->number*3+4]+
bc[2].static_o[b->number*3+4]+
o)/3+adj;
adj=(bc[2].static_o[b->number*3+2]*3 -
bc[2].static_o[b->number*3+4] -
bc[2].static_o[b->number*3+1] -
bc[2].static_o[b->number*3+1])/3;
bc[2].static_o[b->number*3+2]=
(bc[2].static_o[b->number*3+4]+o+o)/3+adj;
adj=(bc[2].static_u[b->number*3+3]*3 -
bc[2].static_u[b->number*3+4] -
bc[2].static_u[b->number*3+4] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3+3]=
(bc[2].static_u[b->number*3+4]+
bc[2].static_u[b->number*3+4]+
u)/3+adj;
adj=(bc[2].static_u[b->number*3+2]*3 -
bc[2].static_u[b->number*3+4] -
bc[2].static_u[b->number*3+1] -
bc[2].static_u[b->number*3+1])/3;
bc[2].static_u[b->number*3+2]=
(bc[2].static_u[b->number*3+4]+u+u)/3+adj;
}
if(b->number==9){
bc[1].static_o[19]+=o-bc[1].static_o[18];
bc[1].static_u[19]+=u-bc[1].static_u[18];
......@@ -461,7 +459,8 @@ static void static_octave(GtkWidget *w,gpointer in){
gtk_widget_hide(bars[i].readoutu);
}
}
multicompand_set_bank(bank_active);
c.active_bank=bank_active;
}
}
......
......@@ -476,6 +476,7 @@ time_linkage *freq_read(time_linkage *in, freq_state *f,
break;
case 3: /* we've pushed out EOF already */
f->out.samples=0;
return &f->out;
}
/* finish up the state feedabck */
......
This diff is collapsed.
......@@ -73,12 +73,12 @@ typedef struct {
sig_atomic_t under_lookahead;
sig_atomic_t under_trim;
sig_atomic_t active_bank;
} other_compand_settings;
extern void multicompand_reset();
extern int multicompand_load(void);
extern time_linkage *multicompand_read(time_linkage *in);
extern void multicompand_set_bank(int bank);
extern int pull_multicompand_feedback(float **peak,float **rms,int *bands);
extern int multicompand_over_attack_set(float msec);
......
......@@ -61,35 +61,13 @@ typedef struct{
float **cache;
int cache_samples;
u_int32_t mutemask0;
} singlecomp_state;
singlecomp_settings scset;
singlecomp_state scs;
static void _analysis(char *base,int i,float *v,int n,int dB,int offset){
int j;
FILE *of;
char buffer[80];
sprintf(buffer,"%s_%d.m",base,i);
of=fopen(buffer,"a");
if(!of)perror("failed to open data dump file");
for(j=0;j<n;j++){
fprintf(of,"%f ",(float)j+offset);
if(dB)
fprintf(of,"%f\n",todB(v[j]));
else
fprintf(of,"%f\n",(v[j]));
}
fprintf(of,"\n");
fclose(of);
}
static int offset=0;
/* feedback! */
typedef struct singlecomp_feedback{
feedback_generic parent_class;
......@@ -361,6 +339,8 @@ time_linkage *singlecomp_read(time_linkage *in){
scs.out.samples=0;
return &scs.out;
}
scs.mutemask0=in->active;
for(i=0;i<input_ch;i++){
float *temp=in->data[i];
float adj[input_size]; // under will set it
......@@ -514,8 +494,8 @@ time_linkage *singlecomp_read(time_linkage *in){
memset(scs.out.data[i]+scs.out.samples,0,sizeof(**scs.out.data)*tozero);
}
offset+=input_size;
scs.out.active=scs.mutemask0;
scs.mutemask0=in->active;
return &scs.out;
}
This diff is collapsed.
......@@ -23,9 +23,15 @@
#include "postfish.h"
typedef struct {
int freq_bands;
float **ho_window;
} subband_window;
typedef struct {
time_linkage out;
feedback_generic_pool feedpool;
float *fftwf_forward_out;
float *fftwf_backward_in;
......@@ -38,22 +44,39 @@ typedef struct {
float *window;
int bands;
float ***lap;
float **cache;
float **cache0;
float **cache1;
int *lap_activeC;
int *lap_active0;
int *lap_active1;
int *lap_activeP;
int *visibleC;
int *visible0;
int *visible1;
int *effect_activeC;
int *effect_active0;
int *effect_active1;
int *effect_activeP;
u_int32_t mutemaskC;
u_int32_t mutemask0;
u_int32_t mutemask1;
u_int32_t mutemaskP;
int lap_samples;
int fillstate; /* 0: uninitialized
1: partial prime
2: nominal
3: eof processed */
int lapbands[3];
} subband_state;
typedef struct {
subband_window *wP;
subband_window *w0;
subband_window *w1;
subband_window *wC;
int freq_bands;
float **ho_window;
float *ho_area;
} subband_window;
} subband_state;
......@@ -62,12 +85,9 @@ extern int subband_load_freqs(subband_state *f,subband_window *w,
const float *freq_list,int bands);
extern time_linkage *subband_read(time_linkage *in, subband_state *f,
subband_window *w,
void (*func)(float **, float **),
int bypass);
subband_window *w,int *visible, int *active,
void (*workfunc)(void *),void *arg);
extern int subband_reset(subband_state *f);
extern int pull_subband_feedback(subband_state *ff,
float **peak,float **rms,int *bands);
......@@ -115,14 +115,16 @@ int suppress_load(void){
return 0;
}
static void suppress_work(float **peakfeed,float **rmsfeed){
static void suppress_work(void *vs){
suppress_state *sss=(suppress_state *)vs;
subband_state *ss=&sss->ss;
int i,j,k,l;
float smoothms=sset.smooth*.1;
float triggerms=sset.trigger*.1;
float releasems=sset.release*.1;
iir_filter *trigger=&sss.trigger;
iir_filter *smooth=&sss.smooth;
iir_filter *release=&sss.release;
iir_filter *trigger=&sss->trigger;
iir_filter *smooth=&sss->smooth;
iir_filter *release=&sss->release;
int ahead;
if(smoothms!=smooth->ms)filter_set(smoothms,smooth,1,4);
......@@ -132,48 +134,52 @@ static void suppress_work(float **peakfeed,float **rmsfeed){
ahead=impulse_ahead4(smooth->alpha);
for(i=0;i<suppress_freqs;i++){
if(suppress_active){
float fast[input_size];
float slow[input_size];
float multiplier = 1.-1000./sset.ratio[i];
for(j=0;j<input_ch;j++){
int firstlink=0;
float fast[input_size];
float slow[input_size];
float multiplier = 1.-1000./sset.ratio[i];
for(j=0;j<input_ch;j++){
int active=(ss->effect_active1[j] ||
ss->effect_active0[j] ||
ss->effect_activeC[j]);
if(active){
if(sset.linkp){
if(j==0){
if(!firstlink){
firstlink++;
memset(fast,0,sizeof(fast));
float scale=1./input_ch;
for(l=0;l<input_ch;l++){
float *x=sss.ss.lap[i][l]+ahead;
float *x=sss->ss.lap[i][l]+ahead;
for(k=0;k<input_size;k++)
fast[k]+=x[k]*x[k];
}
for(k=0;k<input_size;k++)
fast[k]*=scale;
//_analysis("rms",i,fast,input_size,0,offset);
}
}else{
float *x=sss.ss.lap[i][j]+ahead;
float *x=sss->ss.lap[i][j]+ahead;
for(k=0;k<input_size;k++)
fast[k]=x[k]*x[k];
}
if(j==0 || sset.linkp==0){
compute_iir_symmetric4(fast, input_size, &sss.iirS[i][j],
smooth);
if(sset.linkp==0 || firstlink==1){
firstlink++;
compute_iir_symmetric4(fast, input_size, &sss->iirS[i][j],
smooth);
//_analysis("smooth",i,fast,input_size,1,offset);
compute_iir_freefall1(fast, input_size, &sss.iirT[i][j],
trigger);
compute_iir_freefall1(fast, input_size, &sss->iirT[i][j],
trigger);
memcpy(slow,fast,sizeof(slow));
compute_iir_freefall1(slow, input_size, &sss.iirR[i][j],
release);
compute_iir_freefall1(slow, input_size, &sss->iirR[i][j],
release);
//_analysis("fast",i,fast,input_size,1,offset);
//_analysis("slow",i,slow,input_size,1,offset);
......@@ -181,24 +187,35 @@ static void suppress_work(float **peakfeed,float **rmsfeed){
fast[k]=fromdB_a((todB_a(slow+k)-todB_a(fast+k))*.5*multiplier);
//_analysis("adj",i,fast,input_size,1,offset);
}
{
float *x=sss.ss.lap[i][j];
float *x=sss->ss.lap[i][j];
for(k=0;k<input_size;k++)
if(fast[k]<1.)
x[k]*=fast[k];
}
}else{
/* reset filters to sane inactive default */
memset(&sss->iirS[i][j],0,sizeof(iir_state));
memset(&sss->iirT[i][j],0,sizeof(iir_state));
memset(&sss->iirR[i][j],0,sizeof(iir_state));
}
}
}
}
time_linkage *suppress_read(time_linkage *in){
int bypass=!(suppress_active);
int visible[input_ch];
int active[input_ch];
int i;
for(i=0;i<input_ch;i++){
visible[i]=0;
active[i]=suppress_active;
}
return subband_read(in,&sss.ss,&sss.sw,
suppress_work,bypass);
return subband_read(in, &sss.ss, &sss.sw, visible, active, suppress_work, &sss);
}
#define VERSION "$Id$ "
/* DO NOT EDIT: Automated versioning hack [Sun Apr 18 22:28:48 EDT 2004] */
/* DO NOT EDIT: Automated versioning hack [Thu Apr 22 05:28:07 EDT 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