]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
DIVERSITY corrections (user interface: gain+phase rather than I+Q)
authorc vw <dl1ycf@darc.de>
Thu, 25 Jul 2019 08:00:48 +0000 (10:00 +0200)
committerc vw <dl1ycf@darc.de>
Thu, 25 Jul 2019 08:00:48 +0000 (10:00 +0200)
diversity_menu.c
radio.c
radio.h
receiver.c

index 458143aa4f705be0d912d04c5655e4bb2324c004..4e084f161b43d90377503934b508695bd492e387 100644 (file)
@@ -29,6 +29,8 @@
 #include "radio.h"
 #include "new_protocol.h"
 
+#include <math.h> 
+
 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 833f8fbd4298a934905347034058a319b36aa8e2..c719191ec15ba9cf083fab18294aaf89e0c45bfe 100644 (file)
--- 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 3575709c2d87a0b726d6fb7d087bdf445e1112ee..211540c4ed060174c649949c2e872123a2c6c617 100644 (file)
--- 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;
index 46f0e71e0aaf4aea91c943945acce13415cd785c..41a8664fc07a96d326bc2f55ceb4527b462bd20c 100644 (file)
@@ -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);