Commit b9c4208c authored by Monty Montgomery's avatar Monty Montgomery

Engine for multiband compander panels for individial channels now active



git-svn-id: https://svn.xiph.org/trunk/postfish@6585 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent c14dabf8
......@@ -90,6 +90,7 @@ typedef struct multi_panel_state{
} multi_panel_state;
multi_panel_state *master_panel;
multi_panel_state **channel_panel;
static void compand_change(GtkWidget *w,gpointer in){
callback_arg_rv *ca=(callback_arg_rv *)in;
......@@ -490,9 +491,9 @@ static void mode_knee(GtkToggleButton *b,gpointer in){
*var=mode;
}
static void compandpanel_create(postfish_mainpanel *mp,
subpanel_generic *panel,
multicompand_settings *ms){
static multi_panel_state *compandpanel_create(postfish_mainpanel *mp,
subpanel_generic *panel,
multicompand_settings *ms){
int i;
char *labels[14]={"130","120","110","100","90","80","70",
"60","50","40","30","20","10","0"};
......@@ -508,7 +509,7 @@ static void compandpanel_create(postfish_mainpanel *mp,
float per_levels[9]={0,12.5,25,37.5,50,62.5,75,87.5,100};
char *per_labels[8]={"","25%","","50%","","75%","","100%"};
multi_panel_state *ps=master_panel=calloc(1,sizeof(multi_panel_state));
multi_panel_state *ps=calloc(1,sizeof(multi_panel_state));
ps->inactive_updatep=1;
ps->bank_active=2;
ps->ms=ms;
......@@ -912,8 +913,7 @@ static void compandpanel_create(postfish_mainpanel *mp,
ps->bars[multicomp_freqs_max].slider=multibar_slider_new(14,labels,levels,2);
multibar_callback(MULTIBAR(ps->bars[multicomp_freqs_max].slider),average_change,
master_panel);
multibar_callback(MULTIBAR(ps->bars[multicomp_freqs_max].slider),average_change,ps);
multibar_thumb_set(MULTIBAR(ps->bars[multicomp_freqs_max].slider),-140.,0);
multibar_thumb_set(MULTIBAR(ps->bars[multicomp_freqs_max].slider),0.,1);
......@@ -932,6 +932,7 @@ static void compandpanel_create(postfish_mainpanel *mp,
/* Now unmap the sliders we don't want */
static_octave(NULL,&ps->octave_full);
return ps;
}
void compandpanel_create_master(postfish_mainpanel *mp,
......@@ -944,13 +945,15 @@ void compandpanel_create_master(postfish_mainpanel *mp,
"_Multiband Compand (master)",shortcut,
0,1);
compandpanel_create(mp,panel,&multi_master_set);
master_panel=compandpanel_create(mp,panel,&multi_master_set);
}
void compandpanel_create_channel(postfish_mainpanel *mp,
GtkWidget **windowbutton,
GtkWidget **activebutton){
int i;
channel_panel=calloc(input_ch,sizeof(*channel_panel));
/* a panel for each channel */
for(i=0;i<input_ch;i++){
......@@ -964,7 +967,7 @@ void compandpanel_create_channel(postfish_mainpanel *mp,
buffer,NULL,
i,1);
compandpanel_create(mp,panel,multi_channel_set+1);
channel_panel[i]=compandpanel_create(mp,panel,multi_channel_set+i);
}
}
......@@ -973,7 +976,7 @@ static float **peakfeed=0;
static float **rmsfeed=0;
void compandpanel_feedback(int displayit){
int i,bands;
int i,j,bands;
if(!peakfeed){
peakfeed=malloc(sizeof(*peakfeed)*multicomp_freqs_max);
rmsfeed=malloc(sizeof(*rmsfeed)*multicomp_freqs_max);
......@@ -988,12 +991,34 @@ void compandpanel_feedback(int displayit){
for(i=0;i<bands;i++)
multibar_set(MULTIBAR(master_panel->bars[i].slider),rmsfeed[i],peakfeed[i],
input_ch,(displayit && multi_master_set.panel_visible));
/* channel panels are a bit different; we want each in its native color */
if(pull_multicompand_feedback_channel(peakfeed,rmsfeed,&bands)==1){
for(j=0;j<input_ch;j++){
for(i=0;i<bands;i++){
float rms[input_ch];
float peak[input_ch];
memset(rms,0,sizeof(rms));
memset(peak,0,sizeof(peak));
rms[j]=rmsfeed[i][j];
peak[j]=peakfeed[i][j];
multibar_set(MULTIBAR(channel_panel[j]->bars[i].slider),rms,peak,
input_ch,(displayit && multi_channel_set[j].panel_visible));
}
}
}
}
void compandpanel_reset(void){
int i;
int i,j;
for(i=0;i<multicomp_freqs_max;i++)
multibar_reset(MULTIBAR(master_panel->bars[i].slider));
for(i=0;i<multicomp_freqs_max;i++)
for(j=0;j<input_ch;j++)
multibar_reset(MULTIBAR(channel_panel[j]->bars[i].slider));
}
......@@ -49,7 +49,6 @@ typedef struct {
typedef struct {
feedback_generic_pool feedpool;
subband_state ss;
subband_window sw[multicomp_banks];
iir_filter *over_attack;
iir_filter *over_decay;
......@@ -76,7 +75,10 @@ typedef struct {
multicompand_settings multi_master_set;
multicompand_settings *multi_channel_set;
static multicompand_state ms;
static multicompand_state master_state;
static multicompand_state channel_state;
static subband_window sw[multicomp_banks];
static feedback_generic *new_multicompand_feedback(void){
int i;
......@@ -95,14 +97,14 @@ static feedback_generic *new_multicompand_feedback(void){
/* total, peak, rms are pulled in array[freqs][input_ch] order */
int pull_multicompand_feedback_master(float **peak,float **rms,int *b){
multicompand_feedback *f=(multicompand_feedback *)feedback_pull(&ms.feedpool);
static int pull_multicompand_feedback(multicompand_state *ms,float **peak,float **rms,int *b){
multicompand_feedback *f=(multicompand_feedback *)feedback_pull(&ms->feedpool);
int i;
if(!f)return 0;
if(f->bypass){
feedback_old(&ms.feedpool,(feedback_generic *)f);
feedback_old(&ms->feedpool,(feedback_generic *)f);
return 2;
}else{
if(peak)
......@@ -112,11 +114,19 @@ int pull_multicompand_feedback_master(float **peak,float **rms,int *b){
for(i=0;i<f->freq_bands;i++)
memcpy(rms[i],f->rms[i],sizeof(**rms)*input_ch);
if(b)*b=f->freq_bands;
feedback_old(&ms.feedpool,(feedback_generic *)f);
feedback_old(&ms->feedpool,(feedback_generic *)f);
return 1;
}
}
int pull_multicompand_feedback_master(float **peak,float **rms,int *b){
return pull_multicompand_feedback(&master_state,peak,rms,b);
}
int pull_multicompand_feedback_channel(float **peak,float **rms,int *b){
return pull_multicompand_feedback(&channel_state,peak,rms,b);
}
static void reset_filters(multicompand_state *ms){
int i,j;
for(i=0;i<multicomp_freqs_max;i++)
......@@ -132,61 +142,72 @@ static void reset_filters(multicompand_state *ms){
void multicompand_reset(){
subband_reset(&ms.ss);
subband_reset(&master_state.ss);
subband_reset(&channel_state.ss);
while(pull_multicompand_feedback_master(NULL,NULL,NULL));
reset_filters(&ms);
while(pull_multicompand_feedback_channel(NULL,NULL,NULL));
reset_filters(&master_state);
reset_filters(&channel_state);
}
int multicompand_load(void){
int h,i;
static int multicompand_load_helper(multicompand_state *ms){
int i;
int qblocksize=input_size/8;
memset(&ms,0,sizeof(ms));
multi_channel_set=calloc(input_ch,sizeof(*multi_channel_set));
memset(ms,0,sizeof(ms));
subband_load(&ms->ss,multicomp_freqs_max,qblocksize);
subband_load(&ms.ss,multicomp_freqs_max,qblocksize);
ms->over_attack=calloc(input_ch,sizeof(*ms->over_attack));
ms->over_decay=calloc(input_ch,sizeof(*ms->over_decay));
for(h=0;h<multicomp_banks;h++)
subband_load_freqs(&ms.ss,&ms.sw[h],multicomp_freq_list[h],
multicomp_freqs[h]);
ms.over_attack=calloc(input_ch,sizeof(*ms.over_attack));
ms.over_decay=calloc(input_ch,sizeof(*ms.over_decay));
ms->under_attack=calloc(input_ch,sizeof(*ms->under_attack));
ms->under_decay=calloc(input_ch,sizeof(*ms->under_decay));
ms.under_attack=calloc(input_ch,sizeof(*ms.under_attack));
ms.under_decay=calloc(input_ch,sizeof(*ms.under_decay));
ms.base_attack=calloc(input_ch,sizeof(*ms.base_attack));
ms.base_decay=calloc(input_ch,sizeof(*ms.base_decay));
ms->base_attack=calloc(input_ch,sizeof(*ms->base_attack));
ms->base_decay=calloc(input_ch,sizeof(*ms->base_decay));
for(i=0;i<multicomp_freqs_max;i++){
ms.over_peak[i]=calloc(input_ch,sizeof(peak_state));
ms.under_peak[i]=calloc(input_ch,sizeof(peak_state));
ms.base_peak[i]=calloc(input_ch,sizeof(peak_state));
ms.over_iir[i]=calloc(input_ch,sizeof(iir_state));
ms.under_iir[i]=calloc(input_ch,sizeof(iir_state));
ms.base_iir[i]=calloc(input_ch,sizeof(iir_state));
ms->over_peak[i]=calloc(input_ch,sizeof(peak_state));
ms->under_peak[i]=calloc(input_ch,sizeof(peak_state));
ms->base_peak[i]=calloc(input_ch,sizeof(peak_state));
ms->over_iir[i]=calloc(input_ch,sizeof(iir_state));
ms->under_iir[i]=calloc(input_ch,sizeof(iir_state));
ms->base_iir[i]=calloc(input_ch,sizeof(iir_state));
}
ms.peak=calloc(multicomp_freqs_max,sizeof(*ms.peak));
ms.rms=calloc(multicomp_freqs_max,sizeof(*ms.rms));
for(i=0;i<multicomp_freqs_max;i++)ms.peak[i]=malloc(input_ch*sizeof(**ms.peak));
for(i=0;i<multicomp_freqs_max;i++)ms.rms[i]=malloc(input_ch*sizeof(**ms.rms));
ms->peak=calloc(multicomp_freqs_max,sizeof(*ms->peak));
ms->rms=calloc(multicomp_freqs_max,sizeof(*ms->rms));
for(i=0;i<multicomp_freqs_max;i++)ms->peak[i]=malloc(input_ch*sizeof(**ms->peak));
for(i=0;i<multicomp_freqs_max;i++)ms->rms[i]=malloc(input_ch*sizeof(**ms->rms));
return 0;
}
static void filter_set(float msec,
iir_filter *filter,
int attackp){
int multicompand_load(void){
int i;
multi_channel_set=calloc(input_ch,sizeof(*multi_channel_set));
multicompand_load_helper(&master_state);
multicompand_load_helper(&channel_state);
for(i=0;i<multicomp_banks;i++)
subband_load_freqs(&master_state.ss,&sw[i],multicomp_freq_list[i],
multicomp_freqs[i]);
return 0;
}
static void filter_set(multicompand_state *ms,
float msec,
iir_filter *filter,
int attackp){
float alpha;
float corner_freq= 500./msec;
/* make sure the chosen frequency doesn't require a lookahead
greater than what's available */
if(step_freq(input_size*2-ms.ss.qblocksize*3)*1.01>corner_freq && attackp)
corner_freq=step_freq(input_size*2-ms.ss.qblocksize*3);
if(step_freq(input_size*2-ms->ss.qblocksize*3)*1.01>corner_freq && attackp)
corner_freq=step_freq(input_size*2-ms->ss.qblocksize*3);
alpha=corner_freq/input_rate;
filter->g=mkbessel(alpha,2,filter->c);
......@@ -195,12 +216,13 @@ static void filter_set(float msec,
}
static void filterbank_set(float msec,
iir_filter *filter,
int attackp){
static void filterbank_set(multicompand_state *ms,
float msec,
iir_filter *filter,
int attackp){
int i;
for(i=0;i<input_ch;i++)
filter_set(msec,filter+i,attackp);
filter_set(ms,msec,filter+i,attackp);
}
......@@ -356,7 +378,7 @@ static int find_maxbands(subband_state *ss,int channel){
return maxbands;
}
static int multicompand_work_channel(multicompand_state *ms,
static int multicompand_work_perchannel(multicompand_state *ms,
float **peakfeed,
float **rmsfeed,
int maxbands,
......@@ -373,9 +395,9 @@ static int multicompand_work_channel(multicompand_state *ms,
subband_window *wP=ss->wP[channel];
float adj[input_size];
if(w==&ms->sw[0]){
if(w==&sw[0]){
bank=0;
}else if(w==&ms->sw[1]){
}else if(w==&sw[1]){
bank=1;
}else bank=2;
......@@ -478,31 +500,10 @@ static int multicompand_work_channel(multicompand_state *ms,
return(feedback_p);
}
static void multicompand_work(void *vs){
multicompand_state *ms=(multicompand_state *)vs;
subband_state *ss=&ms->ss;
int i,j,bypass_visible=1;
int maxmaxbands=0;
float **peakfeed=ms->peak;
float **rmsfeed=ms->rms;
for(i=0;i<multicomp_freqs_max;i++){
memset(peakfeed[i],0,input_ch*sizeof(**peakfeed));
memset(rmsfeed[i],0,input_ch*sizeof(**rmsfeed));
}
for(j=0;j<input_ch;j++){
int maxbands=find_maxbands(ss,j);
if(maxbands>maxmaxbands)maxmaxbands=maxbands;
if(multicompand_work_channel(ms, peakfeed, rmsfeed, maxbands, j, &multi_master_set))
bypass_visible=0;
}
static void push_feedback(multicompand_state *ms,int bypass,int maxmaxbands){
int i;
/* finish up the state feedabck */
if(bypass_visible){
if(bypass){
multicompand_feedback *ff=
(multicompand_feedback *)
feedback_new(&ms->feedpool,new_multicompand_feedback);
......@@ -523,16 +524,56 @@ static void multicompand_work(void *vs){
}
}
static void multicompand_work_master(void *vs){
multicompand_state *ms=(multicompand_state *)vs;
int i,bypass_visible=1;
int maxmaxbands=0;
for(i=0;i<multicomp_freqs_max;i++){
memset(ms->peak[i],0,input_ch*sizeof(**ms->peak));
memset(ms->rms[i],0,input_ch*sizeof(**ms->rms));
}
for(i=0;i<input_ch;i++){
int maxbands=find_maxbands(&ms->ss,i);
if(maxbands>maxmaxbands)maxmaxbands=maxbands;
if(multicompand_work_perchannel(ms, ms->peak, ms->rms, maxbands, i, &multi_master_set))
bypass_visible=0;
}
push_feedback(ms,bypass_visible,maxmaxbands);
}
static void multicompand_work_channel(void *vs){
multicompand_state *ms=(multicompand_state *)vs;
int i,bypass_visible=1;
int maxmaxbands=0;
for(i=0;i<multicomp_freqs_max;i++){
memset(ms->peak[i],0,input_ch*sizeof(**ms->peak));
memset(ms->rms[i],0,input_ch*sizeof(**ms->rms));
}
for(i=0;i<input_ch;i++){
int maxbands=find_maxbands(&ms->ss,i);
if(maxbands>maxmaxbands)maxmaxbands=maxbands;
if(multicompand_work_perchannel(ms, ms->peak, ms->rms, maxbands, i, multi_channel_set+i))
bypass_visible=0;
}
push_feedback(ms,bypass_visible,maxmaxbands);
}
time_linkage *multicompand_read_master(time_linkage *in){
int visible[input_ch];
int active[input_ch];
subband_window *w[input_ch];
int i,ab=multi_master_set.active_bank;
for(i=0;i<input_ch;i++){
visible[i]=multi_master_set.panel_visible;
active[i]=multi_master_set.panel_active;
w[i]=&ms.sw[ab];
w[i]=&sw[ab];
}
/* do any filters need updated from UI changes? */
......@@ -544,17 +585,61 @@ time_linkage *multicompand_read_master(time_linkage *in){
float b_attackms=multi_master_set.base_attack*.1;
float b_decayms=multi_master_set.base_decay*.1;
if(o_attackms!=ms.over_attack[0].ms) filterbank_set(o_attackms,ms.over_attack,1);
if(o_decayms !=ms.over_decay[0].ms) filterbank_set(o_decayms,ms.over_decay,0);
if(u_attackms!=ms.under_attack[0].ms)filterbank_set(u_attackms,ms.under_attack,1);
if(u_decayms !=ms.under_decay[0].ms) filterbank_set(u_decayms,ms.under_decay,0);
if(b_attackms!=ms.base_attack[0].ms) filterbank_set(b_attackms,ms.base_attack,1);
if(b_decayms !=ms.base_decay[0].ms) filterbank_set(b_decayms,ms.base_decay,0);
if(o_attackms!=master_state.over_attack[0].ms)
filterbank_set(&master_state,o_attackms,master_state.over_attack,1);
if(o_decayms !=master_state.over_decay[0].ms)
filterbank_set(&master_state,o_decayms,master_state.over_decay,0);
if(u_attackms!=master_state.under_attack[0].ms)
filterbank_set(&master_state,u_attackms,master_state.under_attack,1);
if(u_decayms !=master_state.under_decay[0].ms)
filterbank_set(&master_state,u_decayms,master_state.under_decay,0);
if(b_attackms!=master_state.base_attack[0].ms)
filterbank_set(&master_state,b_attackms,master_state.base_attack,1);
if(b_decayms !=master_state.base_decay[0].ms)
filterbank_set(&master_state,b_decayms,master_state.base_decay,0);
}
return subband_read(in, &ms.ss, w,
visible,active,multicompand_work,&ms);
return subband_read(in, &master_state.ss, w, visible,active,
multicompand_work_master,&master_state);
}
time_linkage *multicompand_read_channel(time_linkage *in){
int visible[input_ch];
int active[input_ch];
subband_window *w[input_ch];
int i;
for(i=0;i<input_ch;i++){
/* do any filters need updated from UI changes? */
float o_attackms=multi_channel_set[i].over_attack*.1;
float o_decayms=multi_channel_set[i].over_decay*.1;
float u_attackms=multi_channel_set[i].under_attack*.1;
float u_decayms=multi_channel_set[i].under_decay*.1;
float b_attackms=multi_channel_set[i].base_attack*.1;
float b_decayms=multi_channel_set[i].base_decay*.1;
if(o_attackms!=channel_state.over_attack[i].ms)
filter_set(&master_state,o_attackms,channel_state.over_attack+i,1);
if(o_decayms !=channel_state.over_decay[i].ms)
filter_set(&master_state,o_decayms,channel_state.over_decay+i,0);
if(u_attackms!=channel_state.under_attack[i].ms)
filter_set(&master_state,u_attackms,channel_state.under_attack+i,1);
if(u_decayms !=channel_state.under_decay[i].ms)
filter_set(&master_state,u_decayms,channel_state.under_decay+i,0);
if(b_attackms!=channel_state.base_attack[i].ms)
filter_set(&master_state,b_attackms,channel_state.base_attack+i,1);
if(b_decayms !=channel_state.base_decay[i].ms)
filter_set(&master_state,b_decayms,channel_state.base_decay+i,0);
w[i]=&sw[multi_channel_set[i].active_bank];
visible[i]=multi_channel_set[i].panel_visible;
active[i]=multi_channel_set[i].panel_active;
}
return subband_read(in, &channel_state.ss, w, visible, active,
multicompand_work_channel,&channel_state);
}
......@@ -84,9 +84,10 @@ typedef struct {
extern void multicompand_reset();
extern int multicompand_load(void);
extern time_linkage *multicompand_read_channels(time_linkage *in);
extern time_linkage *multicompand_read_channel(time_linkage *in);
extern time_linkage *multicompand_read_master(time_linkage *in);
extern int pull_multicompand_feedback_channels(float **peak,float **rms,int *bands);
extern int pull_multicompand_feedback_channel(float **peak,float **rms,int *bands);
extern int pull_multicompand_feedback_master(float **peak,float **rms,int *bands);
......@@ -238,10 +238,8 @@ void *playback_thread(void *dummy){
link=declip_read(link);
result|=link->samples;
link=multicompand_read_channel(link);
result|=link->samples;
link=multicompand_read_master(link);
result|=link->samples;
......
#define VERSION "$Id$ "
/* DO NOT EDIT: Automated versioning hack [Fri Apr 23 02:21:55 EDT 2004] */
/* DO NOT EDIT: Automated versioning hack [Fri Apr 23 17:45:27 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