From: Ramakrishnan Muthukrishnan Date: Fri, 23 Dec 2022 11:27:17 +0000 (+0530) Subject: NR4: libspecbleach based noise reduction X-Git-Url: https://git.rkrishnan.org/%5B/%5D%20/file/$top_link?a=commitdiff_plain;h=ccf0eb3b0cc2c58c893cb0f2206e824692d86014;p=pihpsdr.git NR4: libspecbleach based noise reduction --- diff --git a/Makefile b/Makefile index f1ccaec..09cda29 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,7 @@ ifeq ($(UNAME_S), Linux) RT_OPTION=-lrt endif -LIBS=$(RT_OPTION) -lm -lwdsp -lrnnoise -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(GTKLIBS) $(GPIO_LIBS) $(MIDI_LIBS) +LIBS=$(RT_OPTION) -lm -lwdsp -lrnnoise -lspecbleach -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(GTKLIBS) $(GPIO_LIBS) $(MIDI_LIBS) INCLUDES=$(GTKINCLUDES) COMPILE=$(CC) $(CFLAGS) $(OPTIONS) $(INCLUDES) diff --git a/dsp_menu.c b/dsp_menu.c index c02b631..26112df 100644 --- a/dsp_menu.c +++ b/dsp_menu.c @@ -63,6 +63,36 @@ static void agc_hang_threshold_value_changed_cb(GtkWidget *widget, gpointer data } } +static void nr4_reduction_amount_scale_changed_cb(GtkWidget *widget, gpointer data) { + active_receiver->nr4_reduction_amount=(int)gtk_range_get_value(GTK_RANGE(widget)); + + SetRXASBNRreductionAmount(active_receiver->id, (int)active_receiver->nr4_reduction_amount); +} + +static void nr4_smoothing_factor_scale_changed_cb(GtkWidget *widget, gpointer data) { + active_receiver->nr4_smoothing_factor=(int)gtk_range_get_value(GTK_RANGE(widget)); + + SetRXASBNRsmoothingFactor(active_receiver->id, (int)active_receiver->nr4_smoothing_factor); +} + +static void nr4_whitening_factor_scale_changed_cb(GtkWidget *widget, gpointer data) { + active_receiver->nr4_whitening_factor = (int)gtk_range_get_value(GTK_RANGE(widget)); + + SetRXASBNRwhiteningFactor(active_receiver->id, (int)active_receiver->nr4_whitening_factor); +} + +static void nr4_noise_rescale_scale_changed_cb(GtkWidget *widget, gpointer data) { + active_receiver->nr4_noise_rescale=(int)gtk_range_get_value(GTK_RANGE(widget)); + + SetRXASBNRnoiseRescale(active_receiver->id, (int)active_receiver->nr4_noise_rescale); +} + +static void nr4_post_filter_threshold_scale_changed_cb(GtkWidget *widget, gpointer data) { + active_receiver->nr4_post_filter_threshold=(int)gtk_range_get_value(GTK_RANGE(widget)); + + SetRXASBNRpostFilterThreshold(active_receiver->id, (int)active_receiver->nr4_post_filter_threshold); +} + static void pre_post_agc_cb(GtkToggleButton *widget, gpointer data) { if(gtk_toggle_button_get_active(widget)) { active_receiver->nr_agc=GPOINTER_TO_UINT(data); @@ -125,6 +155,7 @@ void dsp_menu(GtkWidget *parent) { gtk_label_set_markup(GTK_LABEL(agc_hang_threshold_label), "AGC Hang Threshold"); gtk_widget_show(agc_hang_threshold_label); gtk_grid_attach(GTK_GRID(grid),agc_hang_threshold_label,0,1,1,1); + GtkWidget *agc_hang_threshold_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.0, 100.0, 1.0); gtk_range_set_increments (GTK_RANGE(agc_hang_threshold_scale),1.0,1.0); gtk_range_set_value (GTK_RANGE(agc_hang_threshold_scale),active_receiver->agc_hang_threshold); @@ -199,6 +230,66 @@ void dsp_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),ae_b,0,5,1,1); g_signal_connect(ae_b,"toggled",G_CALLBACK(ae_cb),NULL); + GtkWidget *nr4_reduction_amount_label=gtk_label_new("NR4 Reduction Amount"); + gtk_label_set_markup(GTK_LABEL(nr4_reduction_amount_label), "NR4 Reduction Amount"); + gtk_widget_show(nr4_reduction_amount_label); + gtk_grid_attach(GTK_GRID(grid),nr4_reduction_amount_label,0,6,1,1); + + GtkWidget *nr4_reduction_amount_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.0, 20.0, 1.0); + gtk_range_set_increments (GTK_RANGE(nr4_reduction_amount_scale),1.0,1.0); + gtk_range_set_value (GTK_RANGE(nr4_reduction_amount_scale),active_receiver->nr4_reduction_amount); + gtk_widget_show(nr4_reduction_amount_scale); + gtk_grid_attach(GTK_GRID(grid),nr4_reduction_amount_scale,1,6,2,1); + g_signal_connect(G_OBJECT(nr4_reduction_amount_scale),"value_changed",G_CALLBACK(nr4_reduction_amount_scale_changed_cb),NULL); + + GtkWidget *nr4_smoothing_factor_label=gtk_label_new("NR4 Smoothing factor"); + gtk_label_set_markup(GTK_LABEL(nr4_smoothing_factor_label), "NR4 Smoothing factor"); + gtk_widget_show(nr4_smoothing_factor_label); + gtk_grid_attach(GTK_GRID(grid),nr4_smoothing_factor_label,0,7,1,1); + + GtkWidget *nr4_smoothing_factor_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.0, 100.0, 1.0); + gtk_range_set_increments (GTK_RANGE(nr4_smoothing_factor_scale),1.0,1.0); + gtk_range_set_value (GTK_RANGE(nr4_smoothing_factor_scale),active_receiver->nr4_smoothing_factor); + gtk_widget_show(nr4_smoothing_factor_scale); + gtk_grid_attach(GTK_GRID(grid),nr4_smoothing_factor_scale,1,7,2,1); + g_signal_connect(G_OBJECT(nr4_smoothing_factor_scale),"value_changed",G_CALLBACK(nr4_smoothing_factor_scale_changed_cb),NULL); + + GtkWidget *nr4_whitening_factor_label=gtk_label_new("NR4 Whitening factor"); + gtk_label_set_markup(GTK_LABEL(nr4_whitening_factor_label), "NR4 Whitening factor"); + gtk_widget_show(nr4_whitening_factor_label); + gtk_grid_attach(GTK_GRID(grid),nr4_whitening_factor_label,0,8,1,1); + + GtkWidget *nr4_whitening_factor_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.0, 100.0, 1.0); + gtk_range_set_increments (GTK_RANGE(nr4_whitening_factor_scale),1.0,1.0); + gtk_range_set_value (GTK_RANGE(nr4_whitening_factor_scale),active_receiver->nr4_whitening_factor); + gtk_widget_show(nr4_whitening_factor_scale); + gtk_grid_attach(GTK_GRID(grid),nr4_whitening_factor_scale,1,8,2,1); + g_signal_connect(G_OBJECT(nr4_whitening_factor_scale),"value_changed",G_CALLBACK(nr4_whitening_factor_scale_changed_cb),NULL); + + GtkWidget *nr4_noise_rescale_label=gtk_label_new("NR4 noise Rescale"); + gtk_label_set_markup(GTK_LABEL(nr4_noise_rescale_label), "NR4 noise rescale"); + gtk_widget_show(nr4_noise_rescale_label); + gtk_grid_attach(GTK_GRID(grid),nr4_noise_rescale_label,0,9,1,1); + + GtkWidget *nr4_noise_rescale_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.0, 12.0, 1.0); + gtk_range_set_increments (GTK_RANGE(nr4_noise_rescale_scale),1.0,1.0); + gtk_range_set_value (GTK_RANGE(nr4_noise_rescale_scale),active_receiver->nr4_noise_rescale); + gtk_widget_show(nr4_noise_rescale_scale); + gtk_grid_attach(GTK_GRID(grid),nr4_noise_rescale_scale,1,9,2,1); + g_signal_connect(G_OBJECT(nr4_noise_rescale_scale),"value_changed",G_CALLBACK(nr4_noise_rescale_scale_changed_cb),NULL); + + GtkWidget *nr4_post_filter_threshold_label=gtk_label_new("NR4 post filter threshold"); + gtk_label_set_markup(GTK_LABEL(nr4_post_filter_threshold_label), "NR4 post filter threshold"); + gtk_widget_show(nr4_post_filter_threshold_label); + gtk_grid_attach(GTK_GRID(grid),nr4_post_filter_threshold_label,0,10,1,1); + + GtkWidget *nr4_post_filter_threshold_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, -10.0, 10.0, 1.0); + gtk_range_set_increments (GTK_RANGE(nr4_post_filter_threshold_scale),1.0,1.0); + gtk_range_set_value (GTK_RANGE(nr4_post_filter_threshold_scale),active_receiver->nr4_post_filter_threshold); + gtk_widget_show(nr4_post_filter_threshold_scale); + gtk_grid_attach(GTK_GRID(grid),nr4_post_filter_threshold_scale,1,10,2,1); + g_signal_connect(G_OBJECT(nr4_post_filter_threshold_scale),"value_changed",G_CALLBACK(nr4_post_filter_threshold_scale_changed_cb),NULL); + gtk_container_add(GTK_CONTAINER(content),grid); sub_menu=dialog; diff --git a/noise_menu.c b/noise_menu.c index 05c4d40..deafed7 100644 --- a/noise_menu.c +++ b/noise_menu.c @@ -86,6 +86,7 @@ void set_noise() { SetRXAANRRun(active_receiver->id, active_receiver->nr); SetRXAEMNRRun(active_receiver->id, active_receiver->nr2); SetRXARNNRRun(active_receiver->id, active_receiver->nr3); + SetRXASBNRRun(active_receiver->id, active_receiver->nr4); SetRXAANFRun(active_receiver->id, active_receiver->anf); SetRXASNBARun(active_receiver->id, active_receiver->snb); g_idle_add(ext_vfo_update,NULL); @@ -128,9 +129,11 @@ static void nr_none_cb(GtkToggleButton *widget, gpointer data) { active_receiver->nr=0; active_receiver->nr2=0; active_receiver->nr3=0; + active_receiver->nr4=0; mode_settings[vfo[active_receiver->id].mode].nr=0; mode_settings[vfo[active_receiver->id].mode].nr2=0; mode_settings[vfo[active_receiver->id].mode].nr3=0; + mode_settings[vfo[active_receiver->id].mode].nr4=0; update_noise(); } } @@ -140,6 +143,7 @@ static void nr_cb(GtkToggleButton *widget, gpointer data) { active_receiver->nr=1; active_receiver->nr2=0; active_receiver->nr3=0; + active_receiver->nr4=0; mode_settings[vfo[active_receiver->id].mode].nr=1; mode_settings[vfo[active_receiver->id].mode].nr2=0; mode_settings[vfo[active_receiver->id].mode].nr3=0; @@ -162,9 +166,11 @@ static void nr2_cb(GtkToggleButton *widget, gpointer data) { active_receiver->nr=0; active_receiver->nr2=1; active_receiver->nr3=0; + active_receiver->nr4=0; mode_settings[vfo[active_receiver->id].mode].nr=0; mode_settings[vfo[active_receiver->id].mode].nr2=1; mode_settings[vfo[active_receiver->id].mode].nr3=0; + mode_settings[vfo[active_receiver->id].mode].nr4=0; update_noise(); } } @@ -174,9 +180,25 @@ static void nr3_cb(GtkToggleButton *widget, gpointer data) { active_receiver->nr=0; active_receiver->nr2=0; active_receiver->nr3=1; + active_receiver->nr4=0; mode_settings[vfo[active_receiver->id].mode].nr=0; mode_settings[vfo[active_receiver->id].mode].nr2=0; mode_settings[vfo[active_receiver->id].mode].nr3=1; + mode_settings[vfo[active_receiver->id].mode].nr4=0; + update_noise(); + } +} + +static void nr4_cb(GtkToggleButton *widget, gpointer data) { + if(gtk_toggle_button_get_active(widget)) { + active_receiver->nr=0; + active_receiver->nr2=0; + active_receiver->nr3=0; + active_receiver->nr4=1; + mode_settings[vfo[active_receiver->id].mode].nr=0; + mode_settings[vfo[active_receiver->id].mode].nr2=0; + mode_settings[vfo[active_receiver->id].mode].nr3=0; + mode_settings[vfo[active_receiver->id].mode].nr4=1; update_noise(); } } @@ -313,6 +335,14 @@ void noise_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),b_nr3,col,row,1,1); g_signal_connect(b_nr3,"toggled",G_CALLBACK(nr3_cb),NULL); + row++; + + GtkWidget *b_nr4=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr),"NR4"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr4), active_receiver->nr4); + gtk_widget_show(b_nr4); + gtk_grid_attach(GTK_GRID(grid),b_nr4,col,row,1,1); + g_signal_connect(b_nr4,"toggled",G_CALLBACK(nr4_cb),NULL); + gtk_container_add(GTK_CONTAINER(content),grid); sub_menu=dialog; diff --git a/receiver.c b/receiver.c index c8b56b5..29bf9ba 100644 --- a/receiver.c +++ b/receiver.c @@ -298,6 +298,10 @@ void receiver_save_state(RECEIVER *rx) { sprintf(value,"%d",rx->nr3); setProperty(name,value); + sprintf(name,"receiver.%d.nr4",rx->id); + sprintf(value,"%d",rx->nr4); + setProperty(name,value); + sprintf(name,"receiver.%d.anf",rx->id); sprintf(value,"%d",rx->anf); setProperty(name,value); @@ -519,6 +523,10 @@ g_print("%s: id=%d\n",__FUNCTION__,rx->id); value=getProperty(name); if(value) rx->nr3=atoi(value); + sprintf(name,"receiver.%d.nr4",rx->id); + value=getProperty(name); + if(value) rx->nr4=atoi(value); + sprintf(name,"receiver.%d.anf",rx->id); value=getProperty(name); if(value) rx->anf=atoi(value); @@ -933,6 +941,7 @@ g_print("%s: id=%d buffer_size=%d\n",__FUNCTION__,id,buffer_size); rx->nr=0; rx->nr2=0; rx->nr3=0; + rx->nr4=0; rx->anf=0; rx->snb=0; @@ -941,6 +950,12 @@ g_print("%s: id=%d buffer_size=%d\n",__FUNCTION__,id,buffer_size); rx->nr2_npe_method=0; rx->nr2_ae=1; + rx->nr4_reduction_amount = 10.F; + rx->nr4_smoothing_factor = 0.F; + rx->nr4_whitening_factor = 0.F; + rx->nr4_noise_rescale = 2.F; + rx->nr4_post_filter_threshold = -10.F; + rx->nb_lag_time = 0.0001; rx->nb_lead_time = 0.0001; rx->nb_transition_time = 0.0001; @@ -1063,6 +1078,7 @@ g_print("%s: id=%d default adc=%d\n",__FUNCTION__,rx->id, rx->adc); rx->nr=0; rx->nr2=0; rx->nr3=0; + rx->nr4=0; rx->anf=0; rx->snb=0; @@ -1071,6 +1087,12 @@ g_print("%s: id=%d default adc=%d\n",__FUNCTION__,rx->id, rx->adc); rx->nr2_npe_method=0; rx->nr2_ae=1; + rx->nr4_reduction_amount = 10.F; + rx->nr4_smoothing_factor = 0.F; + rx->nr4_whitening_factor = 0.F; + rx->nr4_noise_rescale = 2.F; + rx->nr4_post_filter_threshold = -10.F; + rx->nb_lag_time = 0.0001; rx->nb_lead_time = 0.0001; rx->nb_transition_time = 0.0001; @@ -1177,6 +1199,16 @@ g_print("%s: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d\n", SetRXARNNRRun(rx->id, rx->nr3); + // nr4 + SetRXASBNRreductionAmount(rx->id, rx->nr4_reduction_amount); + SetRXASBNRsmoothingFactor(rx->id, rx->nr4_smoothing_factor); + SetRXASBNRwhiteningFactor(rx->id, rx->nr4_whitening_factor); + SetRXASBNRnoiseRescale(rx->id, rx->nr4_noise_rescale); + SetRXASBNRpostFilterThreshold(rx->id, rx->nr4_post_filter_threshold); + + SetRXASBNRRun(rx->id, rx->nr4); + + SetEXTANBRun(rx->id, rx->nb); SetEXTNOBRun(rx->id, rx->nb2); diff --git a/receiver.h b/receiver.h index 6de1a1a..0749ac9 100644 --- a/receiver.h +++ b/receiver.h @@ -82,6 +82,7 @@ typedef struct _receiver { gint nr; gint nr2; gint nr3; + gint nr4; gint anf; gint snb; @@ -90,6 +91,12 @@ typedef struct _receiver { int nr2_npe_method; int nr2_ae; + float nr4_reduction_amount; + float nr4_smoothing_factor; + float nr4_whitening_factor; + float nr4_noise_rescale; + float nr4_post_filter_threshold; + double nb_lag_time; double nb_lead_time; double nb_transition_time; diff --git a/vfo.c b/vfo.c index 59ce9f9..713e86d 100644 --- a/vfo.c +++ b/vfo.c @@ -98,6 +98,10 @@ void modesettings_save_state() { sprintf(value,"%d", mode_settings[i].nr3); setProperty(name,value); + sprintf(name,"modeset.%d.nr4", i); + sprintf(value,"%d", mode_settings[i].nr4); + setProperty(name,value); + sprintf(name,"modeset.%d.nb", i); sprintf(value,"%d", mode_settings[i].nb); setProperty(name,value); @@ -125,6 +129,7 @@ void modesettings_restore_state() { mode_settings[i].nr=0; mode_settings[i].nr2=0; mode_settings[i].nr3=0; + mode_settings[i].nr4=0; mode_settings[i].nb=0; mode_settings[i].nb2=0; mode_settings[i].anf=0; @@ -145,6 +150,10 @@ void modesettings_restore_state() { value=getProperty(name); if(value) mode_settings[i].nr3=atoi(value); + sprintf(name,"modeset.%d.nr4",i); + value=getProperty(name); + if(value) mode_settings[i].nr4=atoi(value); + value=getProperty(name); if(value) mode_settings[i].nb=atoi(value); sprintf(name,"modeset.%d.nb2",i); @@ -411,6 +420,7 @@ void vfo_mode_changed(int m) { active_receiver->nr =mode_settings[m].nr; active_receiver->nr2=mode_settings[m].nr2; active_receiver->nr3=mode_settings[m].nr3; + active_receiver->nr4=mode_settings[m].nr4; active_receiver->nb =mode_settings[m].nb; active_receiver->nb2=mode_settings[m].nb2; active_receiver->anf=mode_settings[m].anf; @@ -1205,7 +1215,7 @@ void vfo_update() { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_show_text(cr, "NR"); } - // XXX need to have a button for NR3 + // XXX need to have a button for NR3 and NR4 cairo_move_to(cr, 70, 20); if(active_receiver->anf) { diff --git a/vfo.h b/vfo.h index 3fef3e1..ede8fd5 100644 --- a/vfo.h +++ b/vfo.h @@ -61,6 +61,7 @@ struct _mode_settings { int nr; int nr2; int nr3; + int nr4; int anf; int snb; };