]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
stream-lined handling of ALEX attenuation/RX ant/TX ant
authorDL1YCF <dl1ycf@darc.de>
Sat, 23 May 2020 12:47:57 +0000 (14:47 +0200)
committerDL1YCF <dl1ycf@darc.de>
Sat, 23 May 2020 12:47:57 +0000 (14:47 +0200)
corrections to rigctl
minimize diffs to John's version

16 files changed:
ant_menu.c
discovery.c
ext.c
ext.h
freqent_menu.c
new_protocol.c
old_protocol.c
radio.c
radio.h
radio_menu.c
receiver.c
rigctl.c
rx_menu.c
rx_panadapter.c
sliders.c
vfo.c

index 07bbd4963c73bb794e5cd4c2315f21bfd170c381..05a929cafe753ecd0b8f8ef136becc7324dea15e 100644 (file)
@@ -28,7 +28,6 @@
 #include "ant_menu.h"
 #include "band.h"
 #include "radio.h"
-#include "vfo.h"
 #include "new_protocol.h"
 #ifdef SOAPYSDR
 #include "soapy_protocol.h"
@@ -66,12 +65,7 @@ static void rx_ant_cb(GtkToggleButton *widget, gpointer data) {
     int ant=(GPOINTER_TO_UINT(data))&0xF;
     BAND *band=band_get_band(b);
     band->alexRxAntenna=ant;
-    //
-    // Immediate switching if the VFO controlling the active receiver is on band b
-    //
-    if(vfo[active_receiver->id].band == b) {
-      set_alex_rx_antenna(ant);
-    }
+    set_alex_rx_antenna();
   }
 }
 
@@ -81,7 +75,7 @@ static void adc0_antenna_cb(GtkComboBox *widget,gpointer data) {
   if(radio->protocol==NEW_PROTOCOL) {
     schedule_high_priority();
 #ifdef SOAPYSDR
-  } else if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  } else if(radio->device==SOAPYSDR_USB_DEVICE) {
     soapy_protocol_set_rx_antenna(receiver[0],adc[0].antenna);
 #endif
   }
@@ -93,7 +87,7 @@ static void dac0_antenna_cb(GtkComboBox *widget,gpointer data) {
   if(radio->protocol==NEW_PROTOCOL) {
     schedule_high_priority();
 #ifdef SOAPYSDR
-  } else if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  } else if(radio->device==SOAPYSDR_USB_DEVICE) {
     soapy_protocol_set_tx_antenna(transmitter,dac->antenna);
 #endif
   }
@@ -105,12 +99,7 @@ static void tx_ant_cb(GtkToggleButton *widget, gpointer data) {
     int ant=(GPOINTER_TO_UINT(data))&0xF;
     BAND *band=band_get_band(b);
     band->alexTxAntenna=ant;
-    //
-    // Switch immediately if the VFO controlling the TX is on that band
-    //
-    if (vfo[get_tx_vfo()].band == b) {
-      set_alex_tx_antenna(ant);
-    }
+    set_alex_tx_antenna();
   }
 }
 
@@ -338,7 +327,7 @@ void ant_menu(GtkWidget *parent) {
   gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
 
 #ifdef SOAPYSDR
-  if(radio->protocol != SOAPYSDR_PROTOCOL || radio->device!=SOAPYSDR_USB_DEVICE) {
+  if(radio->device!=SOAPYSDR_USB_DEVICE) {
 #endif
     GtkWidget *hf_rb=gtk_radio_button_new_with_label(NULL,"HF");
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hf_rb),TRUE);
@@ -439,7 +428,7 @@ void ant_menu(GtkWidget *parent) {
   }
 
 #ifdef SOAPYSDR
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     int i;
 
 g_print("rx_antennas=%ld\n",radio->info.soapy.rx_antennas);
index c99e6ee3baeb3e74841598ae446aebdd2f631441..0ecb45e6ffc67c36ddfdaa38ed6dff3f0f2b00ed 100644 (file)
@@ -468,7 +468,7 @@ fprintf(stderr,"%p Protocol=%d name=%s\n",d,d->protocol,d->name);
         }
 
 #ifdef SOAPYSDR
-        if(d->protocol != SOAPYSDR_PROTOCOL || d->device!=SOAPYSDR_USB_DEVICE) {
+        if(d->device!=SOAPYSDR_USB_DEVICE) {
 #endif
           // if not on the same subnet then cannot start it
           if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) != (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) {
diff --git a/ext.c b/ext.c
index b3003f0fd46138151ce6db050e34065eaebf6a40..56b107efc6af85af5dc6185d17cf17d1fc96852c 100644 (file)
--- a/ext.c
+++ b/ext.c
@@ -309,7 +309,10 @@ int ext_update_att_preamp(void *data) {
 
 int ext_set_alex_attenuation(void *data) {
   int val=GPOINTER_TO_INT(data);
-  set_alex_attenuation(val);
+  BAND *band=band_get_band(vfo[VFO_A].band);
+  // store changed attenuation in "band" info
+  band->alexAttenuation=val;
+  set_alex_attenuation();
   return 0;
 }
 
@@ -569,18 +572,21 @@ int ext_agc_update(void *data) {
   return 0;
 }
 
+int ext_set_split(void *data) {
+  if(can_transmit) {
+    split=GPOINTER_TO_INT(data),
+    tx_set_mode(transmitter,get_tx_mode());
+    set_alex_tx_antenna();
+    g_idle_add(ext_vfo_update, NULL);
+  }
+  return 0;
+}
+
 int ext_split_toggle(void *data) {
-  BAND *band;
   if(can_transmit) {
     split=split==1?0:1;
     tx_set_mode(transmitter,get_tx_mode());
-    //
-    // Since the TX band possibly changed, we have to
-    // adjust the TX antenna
-    //
-    band=band_get_band(vfo[get_tx_vfo()].band);
-    set_alex_tx_antenna(band->alexTxAntenna);
-
+    set_alex_tx_antenna();
     g_idle_add(ext_vfo_update, NULL);
   }
   return 0;
diff --git a/ext.h b/ext.h
index 51f1bcc9c838daa9e6fe07fd9847a5d2f1263b5e..75f9d35d97c349e4d4f754e61376bd5e1fa354cc 100644 (file)
--- a/ext.h
+++ b/ext.h
@@ -77,6 +77,7 @@ extern void ctun_update(int id,int state);
 extern int ext_ctun_update(void *data);
 extern int ext_agc_update(void *data);
 extern int ext_split_toggle(void *data);
+extern int ext_set_split(void *data);
 
 
 extern int ext_cw_setup();
index 18803fa4e07fe004ede3c02d561377db19d9cf53..9de8a11f203ce2fea6afe2a2b8b8e04bcbbe1ff7 100644 (file)
@@ -130,13 +130,12 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) {
                 FILTER* band_filters=filters[entry->mode];
                 FILTER* band_filter=&band_filters[entry->filter];
                 set_filter(active_receiver,band_filter->low,band_filter->high);
-                if(active_receiver->id==0) {
-                  set_alex_rx_antenna(band->alexRxAntenna);
-                  set_alex_tx_antenna(band->alexTxAntenna);
-                  set_alex_attenuation(band->alexAttenuation);
-                }
               }
               setFrequency(f);
+             // defer set_alex.. until here since setFrequency sets the VFO.band
+              set_alex_rx_antenna();
+              set_alex_tx_antenna();
+              set_alex_attenuation();
               g_idle_add(ext_vfo_update,NULL);
             }
             set = 1;
index f2ad5f03f90409fb96cad38b6f4ceca71554609d..9ee12db024561711fa3bc6a3d1711369d4124ed8 100644 (file)
@@ -202,25 +202,20 @@ static socklen_t length=sizeof(addr);
 
 
 //
-// DL1YCF: note that we allocate and free the buffers for the
-// network traffic at a very high rate, and I observed certain
-// problems with this (possibly due to deficiencies in the
-// runtime system when firing malloc and free from different threads
-// at very high rate).
+// We used to allocate (malloc) and free (free) the buffers for the
+// network traffic at a very high rate, this may be a problem on
+// some systems. In fact, only a handful of buffers are actually used.
 //
 // Therefore we now allocate a pool of network buffers *once*, make 
-// them a linked list, and do our own memory managemant for these
+// them a linked list, and simply maintain a "free" flag.
 //
-//
-// This is ONLY MEANT for allocating buffers from within the
-// thread reading the buffers. Buffers for sending have a fixed
-// static allocation (e.g. high_priority_buffer_to_radio), so the
-// only "malloc" left is in the new_protocol_restart function where
-// a temporary buffer for draining the input queue is used.
+// This only applies to the network buffers filled with data in
+// new_protocol_thread(), so this need not be thread-safe.
 //
 
 //
-// one buffer
+// One buffer. The fences can be used to detect over-writing them
+// 
 //
 
 struct mybuffer_ {
@@ -234,7 +229,7 @@ struct mybuffer_ {
 typedef struct mybuffer_ mybuffer;
 
 //
-// number of buffers used (for statistics)
+// number of buffers allocated (for statistics)
 //
 static int num_buf = 0; 
 
@@ -243,10 +238,14 @@ static int num_buf = 0;
 //
 static mybuffer *buflist = NULL;
 
+//
+// The buffers used by new_protocol_thread
+//
 static mybuffer *iq_buffer[MAX_DDC];
 static mybuffer *command_response_buffer;
 static mybuffer *high_priority_buffer;
 static mybuffer *mic_line_buffer;
+
 static int mic_bytes_read;
 
 static unsigned char general_buffer[60];
@@ -254,11 +253,13 @@ static unsigned char high_priority_buffer_to_radio[1444];
 static unsigned char transmit_specific_buffer[60];
 static unsigned char receive_specific_buffer[1444];
 
-// DL1YCF
+//
 // new_protocol_receive_specific and friends are not thread-safe, but called
-// periodically from  timer thread and asynchronously from everywhere else
+// periodically from  timer thread *and* asynchronously from everywhere else
 // therefore we need to implement a critical section for each of these functions.
-// It seems that this is not necessary for the audio and TX-IQ buffers.
+// The audio buffer needs a mutex since both RX and TX threads may write to
+// this one (CW side tone).
+//
 
 static pthread_mutex_t rx_spec_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t tx_spec_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -296,7 +297,7 @@ static mybuffer *free_buffer() {
   mybuffer *bp=buflist;
   while (bp) {
     if (bp->free == 1) {
-      // found free buffer. Mark as used and return
+      // found free buffer. Mark as used and return that one.
       bp->free=0;
       return bp;
     }
@@ -1949,45 +1950,24 @@ static void process_mic_data(int bytes) {
   }
 }
 
-//
-// Pure DL1YCF paranoia:
 //
 // Note that new_protocol_cw_audio_samples() is called by the TX thread, while
 // new_protocol_audio_samples() is called by the RX thread.
 //
-// To make this bullet-proof, we need a mutex to ensure that only one of these
-// two functions is active at a given time.
 //
-// The problem is that upon a RX/TX transition, both functions may be called at
-// the same time, and the status if isTransmitting() may be changed at a moment
-// such that *both* functions proceed.
-//
-// So in 99% if the cases, the check on isTransmitting() controls that only one
-// of the two functions becomes active, but at the moment of a RX/TX transition
+// To avoid race conditions, we need a mutex covering these functions.
+// In 99% if the cases, the check on isTransmitting() controls that only one
+// of the functions becomes active, but at the moment of a RX/TX transition
 // this may fail.
 //
-// The same problem occured in the audio modules (audio_write vs. cw_audio_write)
-// and has been resolved with a mutex, and this we now also do here using
-// audio_mutex.
-//
-// Note that in almost all cases, no "blocking" occures, such that the lock/unlock
-// should cost only few CPU cycles. This may be different on systems with several
-// CPU sockets if "locking" the mutex causes cache in-coherency.
+// So "blocking" can only occur very rarely, such that the lock/unlock
+// should cost only few CPU cycles. 
 //
 
 void new_protocol_cw_audio_samples(short left_audio_sample,short right_audio_sample) {
   int rc;
   int txmode=get_tx_mode();
 
-  //
-  // The audio mutex has been introduced since it cannot be
-  // guaranteed that there is no race condition here: while
-  // new_protocol_audio_samples is called by the RX thread,
-  // the TX thread calls its sibling new_protocol_cw_audio_samples,
-  // and at the moment of a RX/TX transition, both threads may
-  // actually write into the audio buffer at the same time.
-  //
-
   if (isTransmitting() && (txmode==modeCWU || txmode==modeCWL)) {
     //
     // Only process samples if transmitting in CW
@@ -2027,14 +2007,6 @@ void new_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right
   //
   if (isTransmitting() && (txmode==modeCWU || txmode==modeCWL)) return;
 
-  //
-  // The audio mutex has been introduced since it cannot be
-  // guaranteed that there is no race condition here: while
-  // new_protocol_audio_samples is called by the RX thread,
-  // the TX thread calls its sibling new_protocol_cw_audio_samples,
-  // and at the moment of a RX/TX transition, both threads may
-  // actually write into the audio buffer at the same time.
-  //
   pthread_mutex_lock(&audio_mutex);
   // insert the samples
   audiobuffer[audioindex++]=left_audio_sample>>8;
@@ -2116,8 +2088,8 @@ void new_protocol_iq_samples(int isample,int qsample) {
 
 void* new_protocol_timer_thread(void* arg) {
   //
-  // We now sent HighPriority as well as General packets
-  // in addition. General packet re-sending is, for example,
+  // Periodically send HighPriority as well as General packets.
+  // A general packet is, for example,
   // required if the band changes (band->disblePA), and HighPrio
   // packets are necessary at very many instances when changing
   // something in the menus, and then a small delay does no harm
index 98ab7af8f40987625602f7de340e69ac9ab6faeb..b13bc4747aa36ca9407a6613fac207ab454e6070 100644 (file)
@@ -995,32 +995,16 @@ static void process_ozy_input_buffer(unsigned char  *buffer) {
 }
 
 //
-// Pure DL1YCF paranoia:
-//
-// To make this bullet-proof, we need a mutex covering the next three functions
+// To avoid race conditions, we need a mutex covering the next three functions
 // that are called both by the RX and TX thread, and are filling and sending the
 // output buffer.
 //
-// Note that old_protocol_iq_samples() and old_protocol_iq_samples_with_sidetone()
-// are mutually exclusive by design (the TX thread calls the latter one if doing
-// CW, the first one otherwise).
-//
-// The problem is that upon a RX/TX transition, old_protocol_audio_samples() and
-// old_protocol_iq_samples() may be called by the RX and TX thread at the same
-// time, and the status if isTransmitting() may be changed at a moment such that
-// *both* functions proceed.
-//
-// So in 99% if the cases, the check on isTransmitting() controls that only one
-// of the two functions becomes active, but at the moment of a RX/TX transition
+// In 99% if the cases, the check on isTransmitting() controls that only one
+// of the functions becomes active, but at the moment of a RX/TX transition
 // this may fail.
 //
-// The same problem occured in the audio modules (audio_write vs. cw_audio_write)
-// and has been resolved with a mutex, and this we now also do here using
-// send_buffer_mutex.
-//
-// Note that in almost all cases, no "blocking" occures, such that the lock/unlock
-// should cost only few CPU cycles. This may be different on systems with several
-// CPU sockets if "locking" the mutex causes cache in-coherency.
+// So "blocking" can only occur very rarely, such that the lock/unlock
+// should cost only few CPU cycles.
 //
 
 static pthread_mutex_t send_buffer_mutex   = PTHREAD_MUTEX_INITIALIZER;
diff --git a/radio.c b/radio.c
index 65140973b87dbe0e21198cd557702215e1d4481c..26e7bbe0b2e4a4b581b9a2cfa47d3d1f0b388d28 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -1083,7 +1083,7 @@ void start_radio() {
   iqswap=0;
 
 #ifdef SOAPYSDR
-  if(protocol == SOAPYSDR_PROTOCOL && device==SOAPYSDR_USB_DEVICE) {
+  if(device==SOAPYSDR_USB_DEVICE) {
     iqswap=1;
     receivers=1;
     filter_board=NONE;
@@ -1107,7 +1107,6 @@ void start_radio() {
   adc[0].preamp=FALSE;
   adc[0].attenuation=0;
 #ifdef SOAPYSDR
-  if (protocol == SOAPYSDR_PROTOCOL) {
   adc[0].antenna=0;
   if(device==SOAPYSDR_USB_DEVICE) {
     adc[0].rx_gain=malloc(radio->info.soapy.rx_gains*sizeof(gint));
@@ -1121,7 +1120,6 @@ void start_radio() {
       dac[0].tx_gain[i]=0;
     }
   }
-  }
 #endif
 
   adc[1].antenna=ANTENNA_1;
@@ -1133,7 +1131,6 @@ void start_radio() {
   adc[1].preamp=FALSE;
   adc[1].attenuation=0;
 #ifdef SOAPYSDR
-  if (protocol == SOAPYSDR_PROTOCOL) {
   adc[1].antenna=0;
   if(device==SOAPYSDR_USB_DEVICE) {
     adc[1].rx_gain=malloc(radio->info.soapy.rx_gains*sizeof(gint));
@@ -1149,7 +1146,6 @@ void start_radio() {
   }
 
   radio_sample_rate=radio->info.soapy.sample_rate;
-  }
 #endif
 
 //g_print("meter_calibration=%f display_calibration=%f\n", meter_calibration, display_calibration);
@@ -1806,43 +1802,68 @@ void set_attenuation(int value) {
     }
 }
 
-void set_alex_rx_antenna(int v) {
-    if(active_receiver->id==0) {
-      active_receiver->alex_antenna=v;
-      if(protocol==NEW_PROTOCOL) {
-          schedule_high_priority();
+//
+// For HPSDR, only receiver[0]->rx_antenna has an effect
+// The antenna is set according to what is stored in the "band" info
+// We have to call this routine in the HPSDR case each time a band is switched.
+//
+void set_alex_rx_antenna() {
+    BAND *band;
+    switch (protocol) {
+      case ORIGINAL_PROTOCOL:
+        band=band_get_band(vfo[VFO_A].band);
+        receiver[0]->alex_antenna=band->alexRxAntenna;
+        break;
+      case NEW_PROTOCOL:
+        band=band_get_band(vfo[VFO_A].band);
+        receiver[0]->alex_antenna=band->alexRxAntenna;
+        schedule_high_priority();
+        break;
       }
-    }
-#ifdef SOAPYSDR
-    if(protocol==SOAPYSDR_PROTOCOL) {
-        soapy_protocol_set_rx_antenna(active_receiver,v);
-    }
-#endif
 }
 
-void set_alex_tx_antenna(int v) {
-    transmitter->alex_antenna=v;
-    if(protocol==NEW_PROTOCOL) {
+//
+// For HPSDR, determine which band control the TX and
+// set TX antenna accordingly
+// We have to call this routine
+// in the HPSDR case each time the TX band is switched,
+// which is for each band switch, each time "split" is
+// changed, and in case of "split", each time the active
+// RX changes!
+//
+void set_alex_tx_antenna() {
+    BAND *band;
+    if (!can_transmit) return;
+    switch (protocol) {
+      case ORIGINAL_PROTOCOL:
+        band=band_get_band(vfo[get_tx_vfo()].band);
+        transmitter->alex_antenna=band->alexTxAntenna;
+       break;
+      case NEW_PROTOCOL:
+        band=band_get_band(vfo[get_tx_vfo()].band);
+        transmitter->alex_antenna=band->alexTxAntenna;
         schedule_high_priority();
+       break;
     }
 }
 
 //
-// There is an error here.
-// The alex att should not be associated with a receiver,
-// but with an ADC. *all* receivers bound to that ADC
-// will experience the same attenuation.
+// For HPSDR, only receiver[0]->alex_attenuation has an effect
+// Set this from the attenuation stored "per band"
 //
-// This means, alex_attenuation should not be stored in thre
-// receiver, but separately (as is the case with adc_attenuation).
-//
-void set_alex_attenuation(int v) {
-    if(active_receiver->id==0) {
-      active_receiver->alex_attenuation=v;
-      if(protocol==NEW_PROTOCOL) {
-          schedule_high_priority();
+void set_alex_attenuation() {
+    BAND *band;
+    switch (protocol) {
+      case ORIGINAL_PROTOCOL:
+        band=band_get_band(vfo[VFO_A].band);
+        receiver[0]->alex_attenuation=band->alexAttenuation;
+        break;
+      case NEW_PROTOCOL:
+        band=band_get_band(vfo[VFO_A].band);
+        receiver[0]->alex_attenuation=band->alexAttenuation;
+        schedule_high_priority();
+        break;
       }
-    }
 }
 
 void radioRestoreState() {
@@ -2085,7 +2106,7 @@ g_print("radioRestoreState: %s\n",property_path);
     if(value) mute_rx_while_transmitting=atoi(value);
 
 #ifdef SOAPYSDR
-    if(protocol == SOAPYSDR_PROTOCOL && device==SOAPYSDR_USB_DEVICE) {
+    if(device==SOAPYSDR_USB_DEVICE) {
       char name[128];
       for(int i=0;i<radio->info.soapy.rx_gains;i++) {
         sprintf(name,"radio.adc[0].rx_gain.%s",radio->info.soapy.rx_gain[i]) ;
@@ -2339,7 +2360,7 @@ g_print("radioSaveState: %s\n",property_path);
     setProperty("rx_gain_calibration",value);
 
 #ifdef SOAPYSDR
-    if(protocol == SOAPYSDR_PROTOCOL && device==SOAPYSDR_USB_DEVICE) {
+    if(device==SOAPYSDR_USB_DEVICE) {
       char name[128];
       for(int i=0;i<radio->info.soapy.rx_gains;i++) {
         sprintf(name,"radio.adc[0].rx_gain.%s",radio->info.soapy.rx_gain[i]);
diff --git a/radio.h b/radio.h
index e0b834f5d36b79bd1048313767da1603fc7717f8..b899aac55aef7c01acef1c9a532334958e86fca5 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -333,9 +333,9 @@ extern void calcTuneDriveLevel();
 extern void setSquelch(RECEIVER *rx);
 
 extern void set_attenuation(int value);
-extern void set_alex_rx_antenna(int v);
-extern void set_alex_tx_antenna(int v);
-extern void set_alex_attenuation(int v);
+extern void set_alex_rx_antenna(void);
+extern void set_alex_tx_antenna(void);
+extern void set_alex_attenuation(void);
 
 extern int isTransmitting();
 
index 881a7a3114b40f727344f77514e12f686906f82f..4d523cde496a32f417a5a454d174dacee3f03af9 100644 (file)
@@ -83,7 +83,7 @@ static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   ADC *adc=(ADC *)data;
   active_receiver->rf_gain=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
   
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     soapy_protocol_set_gain(receiver[0],active_receiver->rf_gain);
   }
 
@@ -99,7 +99,7 @@ static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
 static void rx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   ADC *adc=(ADC *)data;
   int gain;
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
     soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),gain);
 
@@ -117,7 +117,7 @@ static void rx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
 
 static void drive_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   DAC *dac=(DAC *)data;
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     transmitter->drive=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
     soapy_protocol_set_tx_gain(transmitter,(double)transmitter->drive);
 /*
@@ -132,7 +132,7 @@ static void drive_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
 static void tx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   DAC *dac=(DAC *)data;
   int gain;
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
     soapy_protocol_set_tx_gain_element(transmitter,(char *)gtk_widget_get_name(widget),gain);
 /*
@@ -157,7 +157,7 @@ static void agc_changed_cb(GtkWidget *widget, gpointer data) {
 static void dac0_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   DAC *dac=(DAC *)data;
   int gain;
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
     soapy_protocol_set_tx_gain_element(radio->transmitter,(char *)gtk_widget_get_name(widget),gain);
     for(int i=0;i<radio->discovered->info.soapy.tx_gains;i++) {
@@ -289,20 +289,9 @@ void load_filters(void) {
   }
 
   if(filter_board==ALEX || filter_board==APOLLO) {
-    BAND *band=band_get_current_band();
-    // mode and filters have nothing to do with the filter board
-    //BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
-    //setFrequency(entry->frequency);
-    //setMode(entry->mode);
-    //set_mode(active_receiver,entry->mode);
-    //FILTER* band_filters=filters[entry->mode];
-    //FILTER* band_filter=&band_filters[entry->filter];
-    //set_filter(active_receiver,band_filter->low,band_filter->high);
-    if(active_receiver->id==0) {
-      set_alex_rx_antenna(band->alexRxAntenna);
-      set_alex_tx_antenna(band->alexTxAntenna);
-      set_alex_attenuation(band->alexAttenuation);
-    }
+      set_alex_rx_antenna();
+      set_alex_tx_antenna();
+      set_alex_attenuation();
   }
   att_type_changed();
 }
@@ -799,7 +788,7 @@ void radio_menu(GtkWidget *parent) {
 
 #ifdef SOAPYSDR
   col=0;
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     int i;
 /*
     if(radio->info.soapy.rx_gains>0) {
index 417491b8798d26e1e5e2e82dd8218ea6e2b9f35c..e2a74b6ebd313938ded4db35a900602999ff33b2 100644 (file)
@@ -97,6 +97,7 @@ void receiver_set_active(RECEIVER *rx) {
   // setup the transmitter mode and filter
   if(can_transmit) {
     tx_set_mode(transmitter,get_tx_mode());
+    set_alex_tx_antenna();
   }
 }
 
@@ -113,19 +114,6 @@ gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton *event,
       if(event->button==3) {
         g_idle_add(ext_start_rx,NULL);
       }
-
-      //
-      // The RX/TX antenna may have been changed (in the ant menu) while
-      // this RX was inactive. In this case, ant switching  must be done now.
-      //
-      // set RX antenna
-      int id=active_receiver->id;
-      BAND *band=band_get_band(vfo[id].band);
-      set_alex_rx_antenna(band->alexRxAntenna);
-      // set TX antenna
-      band=band_get_band(vfo[get_tx_vfo()].band);
-      set_alex_tx_antenna(band->alexTxAntenna);
-
 #ifdef CLIENT_SERVER
    }
 #endif
@@ -985,7 +973,7 @@ fprintf(stderr,"create_receiver: id=%d buffer_size=%d fft_size=%d pixels=%d fps=
   }
 fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
 #ifdef SOAPYSDR
-  if(radio->protocol == SOAPYSDR_PROTOCOL && radio->device==SOAPYSDR_USB_DEVICE) {
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
     rx->sample_rate=radio->info.soapy.sample_rate;
     rx->resampler=NULL;
     rx->resample_buffer=NULL;
index 8607f7f2cdc6f779f185fc8821d6392f7d472cf8..27775ed0c1b195af26182e9ad1a2532634b52c55 100644 (file)
--- a/rigctl.c
+++ b/rigctl.c
@@ -2159,10 +2159,8 @@ gboolean parse_extended_cmd (char *command,CLIENT *client) {
             sprintf(reply,"ZZSP%d;",split);
             send_resp(client->fd,reply) ;
           } else if(command[5]==';') {
-           // use ext_set_split to take care of antenna switching
-            split=atoi(&command[4]);
-            tx_set_mode(transmitter,get_tx_mode());
-            vfo_update();
+           int val=atoi(&command[4]);
+           ext_set_split((gpointer) val);
           }
           break;
         case 'R': //ZZSR
@@ -2186,10 +2184,8 @@ gboolean parse_extended_cmd (char *command,CLIENT *client) {
             sprintf(reply,"ZZSW%d;",split);
             send_resp(client->fd,reply) ;
           } else if(command[5]==';') {
-           // use ext_set_split to take care of antenna switching
-            split=atoi(&command[4]);
-            tx_set_mode(transmitter,get_tx_mode());
-            vfo_update();
+            int val=atoi(&command[4]);
+            ext_set_split((gpointer) val);
           }
           break;
         case 'Y': //ZZSY
@@ -2746,10 +2742,8 @@ int parse_cmd(void *data) {
             sprintf(reply,"FT%d;",split);
             send_resp(client->fd,reply) ;
           } else if(command[3]==';') {
-           // use ext_set_split to take care of antenna switching
-            split=atoi(&command[2]);
-            tx_set_mode(transmitter,get_tx_mode());
-            vfo_update();
+            int val=atoi(&command[2]);
+            ext_set_split((gpointer) val);
           }
           break;
         case 'W': //FW
index 84e937f5556fb66e8580b427b56250b719c2dc60..4390f37b560243889ad1ac1117a1d0c8ce9f2255 100644 (file)
--- a/rx_menu.c
+++ b/rx_menu.c
@@ -33,6 +33,7 @@
 #include "receiver.h"
 #include "sliders.h"
 #include "new_protocol.h"
+#include "vfo.h"
 
 static GtkWidget *parent_window=NULL;
 static GtkWidget *menu_b=NULL;
@@ -80,8 +81,12 @@ static void preamp_cb(GtkWidget *widget, gpointer data) {
 }
 
 static void alex_att_cb(GtkWidget *widget, gpointer data) {
+  BAND *band;
   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
-    set_alex_attenuation((intptr_t) data);
+    // store value in the "band" info
+    band=band_get_band(vfo[VFO_A].band);
+    band->alexAttenuation=GPOINTER_TO_INT(data);
+    set_alex_attenuation();
     update_att_preamp();
   }
 }
index 56bee4952f17345e527229438d13cff13543333e..40f0ba50569a0416cf10ddfaea1ca8f42a7a7d8c 100644 (file)
@@ -489,7 +489,6 @@ void rx_panadapter_update(RECEIVER *rx) {
   } else {
     s1=(double)samples[pan]+(double)adc_attenuation[rx->adc];
   }
-  cairo_move_to(cr, 0.0, s1);
   if (filter_board == ALEX && rx->adc == 0) s1 += (double)(10*rx->alex_attenuation);
   if (filter_board == CHARLY25) {
     if (rx->preamp) s1 -= 18.0;
index 5fb8acf5a4a9d54f6ab9dc9eb20ab74b1e929978..07b55a4c3c64a99d6e5ead46a86177c544dcbd9a 100644 (file)
--- a/sliders.c
+++ b/sliders.c
@@ -246,11 +246,13 @@ static gboolean load_att_type_cb(gpointer data) {
 
 static void c25_att_combobox_changed(GtkWidget *widget, gpointer data) {
   int val = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)));
-  if (active_receiver->adc == 0) {
+  if (active_receiver->id == 0) {
     // this button is only valid for the first receiver
     // store attenuation, such that in meter.c the correct level is displayed
     adc_attenuation[active_receiver->adc] = 12*val;
-    set_alex_attenuation(val);
+    BAND* band = band_get_band(vfo[VFO_A].band);
+    band->alexAttenuation=val;
+    set_alex_attenuation();
   } else {
     // always show "0 dB" on the button if the second RX is active
     if (val != 0) {
diff --git a/vfo.c b/vfo.c
index 78fcd529a630e1220deb0ae602f57a503948317b..f985f9c64a08c5da8ef5258d678dcee70b7660d7 100644 (file)
--- a/vfo.c
+++ b/vfo.c
@@ -311,22 +311,20 @@ void vfo_band_changed(int id,int b) {
     case 0:
       bandstack->current_entry=vfo[id].bandstack;
       receiver_vfo_changed(receiver[id]);
-      BAND *band=band_get_band(vfo[id].band);
-      set_alex_rx_antenna(band->alexRxAntenna);
-      if(can_transmit) {
-        set_alex_tx_antenna(band->alexTxAntenna);
-      }
-      set_alex_attenuation(band->alexAttenuation);
       receiver_vfo_changed(receiver[0]);
       break;
    case 1:
+      // Split: RX1 controls TX frequency
       if(receivers==2) {
         receiver_vfo_changed(receiver[1]);
       }
       break;
   }
+  set_alex_attenuation();
+  set_alex_rx_antenna();
 
   if(can_transmit) {
+    set_alex_tx_antenna();
     tx_set_mode(transmitter,get_tx_mode());
     //
     // If the band has changed, it is necessary to re-calculate
@@ -365,13 +363,6 @@ void vfo_bandstack_changed(int b) {
   switch(id) {
     case 0:
       bandstack->current_entry=vfo[id].bandstack;
-      receiver_vfo_changed(receiver[id]);
-      BAND *band=band_get_band(vfo[id].band);
-      set_alex_rx_antenna(band->alexRxAntenna);
-      if(can_transmit) {
-        set_alex_tx_antenna(band->alexTxAntenna);
-      }
-      set_alex_attenuation(band->alexAttenuation);
       receiver_vfo_changed(receiver[0]);
       break;
    case 1:
@@ -381,7 +372,10 @@ void vfo_bandstack_changed(int b) {
       break;
   }
 
+  set_alex_rx_antenna();
+  set_alex_attenuation();
   if(can_transmit) {
+    set_alex_tx_antenna();
     tx_set_mode(transmitter,get_tx_mode());
     //
     // I do not think the band can change within this function.