From: c vw Date: Thu, 25 Jul 2019 08:00:48 +0000 (+0200) Subject: DIVERSITY corrections (user interface: gain+phase rather than I+Q) X-Git-Url: https://git.rkrishnan.org/%5B/listings/flags/status?a=commitdiff_plain;h=2d4b6cf4fcd3bc06d835350af8a09693e39e2782;p=pihpsdr.git DIVERSITY corrections (user interface: gain+phase rather than I+Q) --- diff --git a/diversity_menu.c b/diversity_menu.c index 458143a..4e084f1 100644 --- a/diversity_menu.c +++ b/diversity_menu.c @@ -29,6 +29,8 @@ #include "radio.h" #include "new_protocol.h" +#include + static GtkWidget *parent_window=NULL; static GtkWidget *dialog=NULL; @@ -61,12 +63,27 @@ static void diversity_cb(GtkWidget *widget, gpointer data) { } } -static void i_rotate_value_changed_cb(GtkWidget *widget, gpointer data) { - i_rotate[1]=gtk_range_get_value(GTK_RANGE(widget)); +// +// the magic constant 0.017... is Pi/180 +// The DIVERSITY rotation parameters must be re-calculated +// each time the gain or the phase changes. +// +static void gain_value_changed_cb(GtkWidget *widget, gpointer data) { + double amplitude,arg; + div_gain=gtk_range_get_value(GTK_RANGE(widget)); + amplitude=pow(10.0, 0.05*div_gain); + arg=div_phase*0.017453292519943295769236907684886; + div_cos=amplitude*cos(arg); + div_sin=amplitude*sin(arg); } -static void q_rotate_value_changed_cb(GtkWidget *widget, gpointer data) { - q_rotate[1]=gtk_range_get_value(GTK_RANGE(widget)); +static void phase_value_changed_cb(GtkWidget *widget, gpointer data) { + double amplitude,arg; + div_phase=gtk_range_get_value(GTK_RANGE(widget)); + amplitude=pow(10.0, 0.05*div_gain); + arg=div_phase*0.017453292519943295769236907684886; + div_cos=amplitude*cos(arg); + div_sin=amplitude*sin(arg); } void diversity_menu(GtkWidget *parent) { @@ -106,29 +123,29 @@ void diversity_menu(GtkWidget *parent) { g_signal_connect(diversity_b,"toggled",G_CALLBACK(diversity_cb),NULL); - GtkWidget *i_rotate_label=gtk_label_new("I Rotate:"); - gtk_misc_set_alignment (GTK_MISC(i_rotate_label), 0, 0); - gtk_widget_show(i_rotate_label); - gtk_grid_attach(GTK_GRID(grid),i_rotate_label,0,2,1,1); - - GtkWidget *i_rotate_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0,1.0,0.01); - gtk_widget_set_size_request (i_rotate_scale, 300, 25); - gtk_range_set_value(GTK_RANGE(i_rotate_scale),i_rotate[1]); - gtk_widget_show(i_rotate_scale); - gtk_grid_attach(GTK_GRID(grid),i_rotate_scale,1,2,1,1); - g_signal_connect(G_OBJECT(i_rotate_scale),"value_changed",G_CALLBACK(i_rotate_value_changed_cb),NULL); - - GtkWidget *q_rotate_label=gtk_label_new("Q Rotate:"); - gtk_misc_set_alignment (GTK_MISC(q_rotate_label), 0, 0); - gtk_widget_show(q_rotate_label); - gtk_grid_attach(GTK_GRID(grid),q_rotate_label,0,3,1,1); - - GtkWidget *q_rotate_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0,1.0,0.01); - gtk_widget_set_size_request (q_rotate_scale, 300, 25); - gtk_range_set_value(GTK_RANGE(q_rotate_scale),q_rotate[1]); - gtk_widget_show(q_rotate_scale); - gtk_grid_attach(GTK_GRID(grid),q_rotate_scale,1,3,1,1); - g_signal_connect(G_OBJECT(q_rotate_scale),"value_changed",G_CALLBACK(q_rotate_value_changed_cb),NULL); + GtkWidget *gain_label=gtk_label_new("Gain:"); + gtk_misc_set_alignment (GTK_MISC(gain_label), 0, 0); + gtk_widget_show(gain_label); + gtk_grid_attach(GTK_GRID(grid),gain_label,0,2,1,1); + + GtkWidget *gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-12.0,+12.0,0.1); + gtk_widget_set_size_request (gain_scale, 300, 25); + gtk_range_set_value(GTK_RANGE(gain_scale),div_gain); + gtk_widget_show(gain_scale); + gtk_grid_attach(GTK_GRID(grid),gain_scale,1,2,1,1); + g_signal_connect(G_OBJECT(gain_scale),"value_changed",G_CALLBACK(gain_value_changed_cb),NULL); + + GtkWidget *phase_label=gtk_label_new("Phase:"); + gtk_misc_set_alignment (GTK_MISC(phase_label), 0, 0); + gtk_widget_show(phase_label); + gtk_grid_attach(GTK_GRID(grid),phase_label,0,3,1,1); + + GtkWidget *phase_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0,360.0,1.0); + gtk_widget_set_size_request (phase_scale, 300, 25); + gtk_range_set_value(GTK_RANGE(phase_scale),div_phase); + gtk_widget_show(phase_scale); + gtk_grid_attach(GTK_GRID(grid),phase_scale,1,3,1,1); + g_signal_connect(G_OBJECT(phase_scale),"value_changed",G_CALLBACK(phase_value_changed_cb),NULL); gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/radio.c b/radio.c index 833f8fb..c719191 100644 --- a/radio.c +++ b/radio.c @@ -298,8 +298,10 @@ int cw_key_state=0; int n_adc=1; int diversity_enabled=0; -double i_rotate[2]={1.0,1.0}; -double q_rotate[2]={0.0,0.0}; +double div_cos=1.0; // I factor for diversity +double div_sin=1.0; // Q factor for diversity +double div_gain=0.0; // gain for diversity (in dB) +double div_phase=0.0; // phase for diversity (in degrees, 0 ... 360) double meter_calibration=0.0; double display_calibration=0.0; diff --git a/radio.h b/radio.h index 3575709..211540c 100644 --- a/radio.h +++ b/radio.h @@ -251,8 +251,8 @@ extern int cw_key_state; extern int n_adc; extern int diversity_enabled; -extern double i_rotate[2]; -extern double q_rotate[2]; +extern double div_cos, div_sin; +extern double div_gain, div_phase; extern double meter_calibration; extern double display_calibration; diff --git a/receiver.c b/receiver.c index 46f0e71..41a8664 100644 --- a/receiver.c +++ b/receiver.c @@ -908,7 +908,6 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc); rx->height=height; // allocate buffers - rx->iq_sequence=0; rx->iq_input_buffer=malloc(sizeof(double)*2*rx->buffer_size); rx->audio_buffer=malloc(AUDIO_BUFFER_SIZE); rx->audio_sequence=0L; @@ -1387,16 +1386,11 @@ void add_iq_samples(RECEIVER *rx, double i_sample,double q_sample) { } // -// Note that we sum such that the first channel has a factor of 1, -// so we do not use but rather hard-code the values -// i_rotate[0]=1 and q_rotate[0]=0. +// Note that we sum the second channel onto the first one. // void add_div_iq_samples(RECEIVER *rx, double i0, double q0, double i1, double q1) { - double i_sample, q_sample; - i_sample = i0 + i_rotate[1]*i1 - q_rotate[1]*q1; - q_sample = q0 + q_rotate[1]*i1 + i_rotate[1]*q1; - rx->iq_input_buffer[rx->samples*2]=i_sample; - rx->iq_input_buffer[(rx->samples*2)+1]=q_sample; + rx->iq_input_buffer[rx->samples*2] = i0 + (div_cos*i1 - div_sin*q1); + rx->iq_input_buffer[(rx->samples*2)+1]= q0 + (div_sin*i1 + div_cos*q1); rx->samples=rx->samples+1; if(rx->samples>=rx->buffer_size) { full_rx_buffer(rx);