]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Changed audio to use audio device name. Added XIT. Added Duplex. Addes SAT and RSAT...
authorJohn Melton G0ORX <john.d.melton@googlemail.com>
Thu, 7 Nov 2019 16:20:53 +0000 (16:20 +0000)
committerJohn Melton G0ORX <john.d.melton@googlemail.com>
Thu, 7 Nov 2019 16:20:53 +0000 (16:20 +0000)
42 files changed:
ant_menu.c
audio.c
audio.h
encoder_menu.c
exit_menu.c
ext.c
ext.h
gpio.c
gpio.h
i2c.c
midi3.c
new_protocol.c
new_protocol.h
old_protocol.c
old_protocol.h
radio.c
radio.h
radio_menu.c
receiver.c
receiver.h
release/pihpsdr-controller1.v2.0.1-beta.tar [new file with mode: 0644]
release/pihpsdr-controller2-v1.v2.0.1-beta.tar [new file with mode: 0644]
release/pihpsdr-controller2-v2.v2.0.1-beta.tar [new file with mode: 0644]
release/pihpsdr-nocontroller.v2.0.1-beta.tar [new file with mode: 0644]
release/pihpsdr/pihpsdr
rx_menu.c
rx_panadapter.c
sliders.c
sliders.h
soapy_protocol.c
soapy_protocol.h
toolbar.c
toolbar.h
transmitter.c
transmitter.h
tx_menu.c
tx_panadapter.c
version.c
vfo.c
vfo.h
vfo_menu.c
xvtr_menu.c

index d7ac9f796c16ed4a9af49981e005f6159d619d96..a23c6bbd6e21fecf6ac01d97b0b45a222ef930c6 100644 (file)
@@ -88,7 +88,7 @@ static void dac0_antenna_cb(GtkComboBox *widget,gpointer data) {
     schedule_high_priority();
 #ifdef SOAPYSDR
   } else if(radio->device==SOAPYSDR_USB_DEVICE) {
-    soapy_protocol_set_tx_antenna(transmitter,dac[0].antenna);
+    soapy_protocol_set_tx_antenna(transmitter,dac->antenna);
 #endif
   }
 }
diff --git a/audio.c b/audio.c
index c54facbeea8d0b02665b3737b8f13d92e1de4306..a942201ff46ae7e8178ee513bcf3857557dd7280 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -66,7 +66,7 @@ static snd_pcm_t *record_handle=NULL;
 //static unsigned char *audio_buffer=NULL;
 //static int audio_offset=0;
 
-static unsigned char *mic_buffer=NULL;
+static float *mic_buffer=NULL;
 
 static GThread *mic_read_thread_id;
 
@@ -74,13 +74,11 @@ static int running=FALSE;
 
 static void *mic_read_thread(void *arg);
 
-char *input_devices[32];
-int n_input_devices=0;
-//int n_selected_input_device=-1;
 
-char *output_devices[32];
-int n_output_devices=0;
-//int n_selected_output_device=-1;
+int n_input_devices;
+AUDIO_DEVICE input_devices[MAX_AUDIO_DEVICES];
+int n_output_devices;
+AUDIO_DEVICE output_devices[MAX_AUDIO_DEVICES];
 
 int audio_open_output(RECEIVER *rx) {
   int err;
@@ -88,22 +86,21 @@ int audio_open_output(RECEIVER *rx) {
   int rate=48000;
   int dir=0;
 
-
-fprintf(stderr,"audio_open_output: rx=%d audio_device=%d\n",rx->id,rx->audio_device);
-  if(rx->audio_device<0 || rx->audio_device>=n_output_devices) {
-    rx->audio_device=-1;
+  if(rx->audio_name==NULL) {
+    rx->local_audio=0;
     return -1;
   }
 
+fprintf(stderr,"audio_open_output: rx=%d %s\n",rx->id,rx->audio_name);
+
   int i;
-  char hw[64];
-  char *selected=output_devices[rx->audio_device];
+  char hw[128];
  
-fprintf(stderr,"audio_open_output: selected=%d:%s\n",rx->audio_device,selected);
+fprintf(stderr,"audio_open_output: selected=%s\n",rx->audio_name);
 
   i=0;
-  while(selected[i]!=' ') {
-    hw[i]=selected[i];
+  while(rx->audio_name[i]!=' ') {
+    hw[i]=rx->audio_name[i];
     i++;
   }
   hw[i]='\0';
@@ -182,16 +179,14 @@ int audio_open_input() {
   int rate=48000;
   int dir=0;
 
-fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device);
-  if(transmitter->input_device<0 || transmitter->input_device>=n_input_devices) {
-    transmitter->input_device=0;
+  if(transmitter->microphone_name==NULL) {
+    transmitter->local_microphone=0;
     return -1;
   }
+fprintf(stderr,"audio_open_input: %s\n",transmitter->microphone_name);
 
   int i;
   char hw[64];
-  char *selected=input_devices[transmitter->input_device];
-  fprintf(stderr,"audio_open_input: selected=%d:%s\n",transmitter->input_device,selected);
   
   switch(protocol) {
     case ORIGINAL_PROTOCOL:
@@ -211,12 +206,13 @@ fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device);
   
   fprintf(stderr,"audio_open_input: mic_buffer_size=%d\n",mic_buffer_size);
   i=0;
-  while(selected[i]!=' ') {
-    hw[i]=selected[i];
+  while(transmitter->microphone_name[i]!=' ') {
+    hw[i]=transmitter->microphone_name[i];
     i++;
   }
   hw[i]='\0';
 
+
   fprintf(stderr,"audio_open_input: hw=%s\n",hw);
 
   if ((err = snd_pcm_open (&record_handle, hw, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
@@ -247,7 +243,7 @@ fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device);
     return -1;
 }
 
-  if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+  if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_FLOAT_LE)) < 0) {
     fprintf (stderr, "audio_open_input: cannot set sample format (%s)\n",
             snd_strerror (err));
     audio_close_input();
@@ -277,7 +273,8 @@ fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device);
 
   snd_pcm_hw_params_free (hw_params);
 
-  mic_buffer=(unsigned char *)malloc(MIC_BUFFER_SIZE);
+  mic_buffer=g_new0(float,mic_buffer_size);
+
 
   running=TRUE;
   mic_read_thread_id = g_thread_new( "local mic", mic_read_thread, NULL);
@@ -456,14 +453,14 @@ fprintf(stderr,"mic_read_thread: mic_buffer_size=%d\n",mic_buffer_size);
       // process the mic input
       switch(protocol) {
         case ORIGINAL_PROTOCOL:
-          old_protocol_process_local_mic(mic_buffer,1);
+          old_protocol_process_local_mic(mic_buffer);
           break;
         case NEW_PROTOCOL:
-          new_protocol_process_local_mic(mic_buffer,1);
+          new_protocol_process_local_mic(mic_buffer);
           break;
 #ifdef SOAPYSDR
         case SOAPYSDR_PROTOCOL:
-          soapy_protocol_process_local_mic(mic_buffer,1);
+          soapy_protocol_process_local_mic(mic_buffer);
           break;
 #endif
         default:
@@ -486,16 +483,11 @@ void audio_get_cards() {
 
 fprintf(stderr,"audio_get_cards\n");
 
-  for(i=0;i<n_input_devices;i++) {
-    free(input_devices[i]);
-  }
   n_input_devices=0;
-
-  for(i=0;i<n_output_devices;i++) {
-    free(output_devices[i]);
-  }
   n_output_devices=0;
 
+  snd_ctl_card_info_alloca(&info);
+  snd_pcm_info_alloca(&pcminfo);
   while (snd_card_next(&card) >= 0 && card >= 0) {
     int err = 0;
     snd_ctl_t *handle;
@@ -519,24 +511,36 @@ fprintf(stderr,"audio_get_cards\n");
       // input devices
       snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
       if ((err = snd_ctl_pcm_info(handle, pcminfo)) == 0) {
-        device_id=malloc(64);
-        snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
-        input_devices[n_input_devices++]=device_id;
+        device_id=malloc(128);
+        snprintf(device_id, 128, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
+        if(n_input_devices<MAX_AUDIO_DEVICES) {
+          input_devices[n_input_devices].name=g_new0(char,strlen(device_id)+1);
+          strcpy(input_devices[n_input_devices].name,device_id);
+          input_devices[n_input_devices].description=g_new0(char,strlen(device_id)+1);
+          strcpy(input_devices[n_input_devices].description,device_id);
+          input_devices[n_input_devices].index=i;
+          n_input_devices++;
+        }
 fprintf(stderr,"input_device: %s\n",device_id);
       }
 
       // ouput devices
       snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
       if ((err = snd_ctl_pcm_info(handle, pcminfo)) == 0) {
-        device_id=malloc(64);
-        snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
-        output_devices[n_output_devices++]=device_id;
+        device_id=malloc(128);
+        snprintf(device_id, 128, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
+        if(n_output_devices<MAX_AUDIO_DEVICES) {
+          output_devices[n_output_devices].name=g_new0(char,strlen(device_id)+1);
+          strcpy(output_devices[n_output_devices].name,device_id);
+          output_devices[n_output_devices].description=g_new0(char,strlen(device_id)+1);
+          strcpy(output_devices[n_output_devices].description,device_id);
+          input_devices[n_output_devices].index=i;
+          n_output_devices++;
+        }
 fprintf(stderr,"output_device: %s\n",device_id);
       }
     }
-
     snd_ctl_close(handle);
-   
   }
 
   // look for dmix
@@ -550,13 +554,20 @@ fprintf(stderr,"output_device: %s\n",device_id);
     name = snd_device_name_get_hint(*n, "NAME");
     descr = snd_device_name_get_hint(*n, "DESC");
     io = snd_device_name_get_hint(*n, "IOID");
-    
+
     if(strncmp("dmix:", name, 5)==0/* || strncmp("pulse", name, 5)==0*/) {
       fprintf(stderr,"name=%s descr=%s io=%s\n",name, descr, io);
-      device_id=malloc(64);
-      
-      snprintf(device_id, 64, "%s", name);
-      output_devices[n_output_devices++]=device_id;
+      device_id=malloc(128);
+
+      snprintf(device_id, 128, "%s", name);
+      if(n_output_devices<MAX_AUDIO_DEVICES) {
+        output_devices[n_output_devices].name=g_new0(char,strlen(device_id)+1);
+        strcpy(output_devices[n_output_devices].name,device_id);
+        output_devices[n_output_devices].description=g_new0(char,strlen(device_id)+1);
+        strcpy(output_devices[n_output_devices].description,device_id);
+        input_devices[n_output_devices].index=i;
+        n_output_devices++;
+      }
 fprintf(stderr,"output_device: %s\n",device_id);
     }
 
diff --git a/audio.h b/audio.h
index e8a56f41ee864f75d370f1cc5ed34e320b1bcd04..7db45ee6282ca7c7e7ca905ef90d3d97a35f2162 100644 (file)
--- a/audio.h
+++ b/audio.h
 
 #include "receiver.h"
 
-extern char *input_devices[];
-extern int n_input_devices;
-//extern int n_selected_input_device;
+#define MAX_AUDIO_DEVICES 64
+
+typedef struct _audio_devices {
+  char *name;
+  int index;
+  char *description;
+} AUDIO_DEVICE;
 
-extern char *output_devices[];
+extern int n_input_devices;
+extern AUDIO_DEVICE input_devices[MAX_AUDIO_DEVICES];
 extern int n_output_devices;
-//extern int n_selected_output_device;
+extern AUDIO_DEVICE output_devices[MAX_AUDIO_DEVICES];
 
 extern int audio_open_input();
 extern void audio_close_input();
index acf99a7d7d2d2884b660804222cfa3e5d2500ca4..de1dae6b00da425d1453e80055442ceb97073dd4 100644 (file)
@@ -279,6 +279,9 @@ GtkWidget* getRadioButton(int action) {
     case ENCODER_RIT_RX2:
       button=b_rit_rx2;
       break;
+    case ENCODER_XIT:
+      button=b_xit;
+      break;
     case ENCODER_CW_SPEED:
       button=b_cw_speed;
       break;
@@ -337,6 +340,9 @@ GtkWidget* getTopRadioButton(int action) {
     case ENCODER_RIT_RX2:
       button=b_top_rit_rx2;
       break;
+    case ENCODER_XIT:
+      button=b_top_xit;
+      break;
     case ENCODER_CW_SPEED:
       button=b_top_cw_speed;
       break;
@@ -773,7 +779,7 @@ void encoder_menu(GtkWidget *parent) {
   g_signal_connect(enc5,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC5));
   col++;
   
-#ifdef CONTROLLER2
+#if defined (CONTROLLER2_V2)
   GtkWidget *enc5_top=gtk_button_new_with_label(encoder_string[e5_top_encoder_action]);
   gtk_grid_attach(GTK_GRID(grid),enc5_top,col,row,1,1);
   g_signal_connect(enc5_top,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC5_TOP));
index a671a10ca8ae13a4bb5182ca54d868ce43469156..52dc79b675f328dc0a9db5cbef31a84e2963aa85 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+#include "main.h"
 #include "new_menu.h"
 #include "exit_menu.h"
+#include "discovery.h"
 #include "radio.h"
 #include "new_protocol.h"
 #include "old_protocol.h"
@@ -48,6 +50,33 @@ static void cleanup() {
   }
 }
 
+static gboolean discovery_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+  cleanup();
+#ifdef GPIO
+  gpio_close();
+#endif
+  switch(protocol) {
+    case ORIGINAL_PROTOCOL:
+      old_protocol_stop();
+      break;
+    case NEW_PROTOCOL:
+      new_protocol_stop();
+      break;
+#ifdef SOAPYSDR
+    case SOAPYSDR_PROTOCOL:
+      soapy_protocol_stop();
+      break;
+#endif
+  }
+  radioSaveState();
+  radio_stop();
+  gtk_container_remove(GTK_CONTAINER(top_window), fixed);
+  gtk_widget_destroy(fixed);
+  gtk_container_add(GTK_CONTAINER(top_window), grid);
+  discovery();
+  return TRUE;
+}
+
 static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
   cleanup();
   return TRUE;
@@ -76,6 +105,7 @@ static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data
 #endif
   }
   radioSaveState();
+
   _exit(0);
 }
 
@@ -152,17 +182,21 @@ void exit_menu(GtkWidget *parent) {
   g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
   gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
 
+  GtkWidget *discovery_b=gtk_button_new_with_label("Discovery");
+  g_signal_connect (discovery_b, "pressed", G_CALLBACK(discovery_cb), NULL);
+  gtk_grid_attach(GTK_GRID(grid),discovery_b,0,1,1,1);
+
   GtkWidget *exit_b=gtk_button_new_with_label("Exit");
   g_signal_connect (exit_b, "pressed", G_CALLBACK(exit_cb), NULL);
-  gtk_grid_attach(GTK_GRID(grid),exit_b,0,1,1,1);
+  gtk_grid_attach(GTK_GRID(grid),exit_b,1,1,1,1);
 
   GtkWidget *reboot_b=gtk_button_new_with_label("Reboot");
   g_signal_connect (reboot_b, "pressed", G_CALLBACK(reboot_cb), NULL);
-  gtk_grid_attach(GTK_GRID(grid),reboot_b,1,1,1,1);
+  gtk_grid_attach(GTK_GRID(grid),reboot_b,2,1,1,1);
 
   GtkWidget *shutdown_b=gtk_button_new_with_label("Shutdown");
   g_signal_connect (shutdown_b, "pressed", G_CALLBACK(shutdown_cb), NULL);
-  gtk_grid_attach(GTK_GRID(grid),shutdown_b,2,1,1,1);
+  gtk_grid_attach(GTK_GRID(grid),shutdown_b,3,1,1,1);
 
   gtk_container_add(GTK_CONTAINER(content),grid);
 
diff --git a/ext.c b/ext.c
index ca80aeb978c4da27587caad7db7befc0bf1e0d9c..155f4e58e122c9e1dead03e0b1c145b3980340ba 100644 (file)
--- a/ext.c
+++ b/ext.c
@@ -458,10 +458,21 @@ int ext_rit_clear(void *data) {
 }
 
 int ext_xit_update(void *data) {
+  if(can_transmit) {
+    transmitter->xit_enabled=transmitter->xit_enabled==1?0:1;
+    if(protocol==NEW_PROTOCOL) {
+      schedule_high_priority();
+    }
+  }
+  vfo_update();
   return 0;
 }
 
 int ext_xit_clear(void *data) {
+  if(can_transmit) {
+    transmitter->xit=0;
+    vfo_update();
+  }
   return 0;
 }
 
@@ -550,6 +561,17 @@ int ext_diversity_update(void *data) {
   return 0;
 }
 
+int ext_sat_update(void *data) {
+  int mode=GPOINTER_TO_INT(data);
+  if(sat_mode==mode) {
+    sat_mode=SAT_NONE;
+  } else {
+    sat_mode=mode;
+  }
+  vfo_update();
+  return 0;
+}
+
 int ext_function_update(void *data) {
   function++;
   if(function>MAX_FUNCTION) {
diff --git a/ext.h b/ext.h
index a4a259d37e249491b40f5ee621fee72d58fb494d..115d05eb8e8f408b7ef302c55e7ac69ce5fe11af 100644 (file)
--- a/ext.h
+++ b/ext.h
@@ -102,3 +102,4 @@ int ext_set_compression(void *data);
 
 int ext_start_rx(void *data);
 int ext_diversity_update(void *data);
+int ext_sat_update(void *data);
diff --git a/gpio.c b/gpio.c
index 2f17b94c7d3ef1c28f422819ad4b729a5882d577..e9e18dcb46d1df08eab56ecc8cabce27f448f63c 100644 (file)
--- a/gpio.c
+++ b/gpio.c
@@ -337,6 +337,8 @@ char *sw_string[SWITCH_ACTIONS] = {
   "AGC",
   "SPLIT",
   "DIVERSITY",
+  "SAT",
+  "RSAT",
   "BAND MENU",
   "BANDSTACK MENU",
   "MODE MENU",
@@ -448,18 +450,18 @@ static int e_function_pressed(void *data) {
 fprintf(stderr,"e_function_pressed: %d\n",action);
   switch(action) {
     case TUNE:
-      g_idle_add(ext_tune_update,NULL);
+      if(can_transmit) g_idle_add(ext_tune_update,NULL);
       break;
     case MOX:
-      g_idle_add(ext_mox_update,NULL);
+      if(can_transmit) g_idle_add(ext_mox_update,NULL);
       break;
     case PS:
 #ifdef PURESIGNAL
-      g_idle_add(ext_ps_update,NULL);
+      if(can_transmit) g_idle_add(ext_ps_update,NULL);
 #endif
       break;
     case TWO_TONE:
-      g_idle_add(ext_two_tone,NULL);
+      if(can_transmit) g_idle_add(ext_two_tone,NULL);
       break;
     case NR:
       g_idle_add(ext_nr_update,NULL);
@@ -477,10 +479,10 @@ fprintf(stderr,"e_function_pressed: %d\n",action);
       g_idle_add(ext_rit_clear,NULL);
       break;
     case XIT:
-      g_idle_add(ext_xit_update,NULL);
+      if(can_transmit) g_idle_add(ext_xit_update,NULL);
       break;
     case XIT_CLEAR:
-      g_idle_add(ext_xit_clear,NULL);
+      if(can_transmit) g_idle_add(ext_xit_clear,NULL);
       break;
     case BAND_PLUS:
       g_idle_add(ext_band_plus,NULL);
@@ -525,11 +527,17 @@ fprintf(stderr,"e_function_pressed: %d\n",action);
       g_idle_add(ext_agc_update,NULL);
       break;
     case SPLIT:
-      g_idle_add(ext_split_update,NULL);
+      if(can_transmit) g_idle_add(ext_split_update,NULL);
       break;
     case DIVERSITY:
       g_idle_add(ext_diversity_update,GINT_TO_POINTER(0));
       break;
+    case SAT:
+      if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(SAT_MODE));
+      break;
+    case RSAT:
+      if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(RSAT_MODE));
+      break;
     case MENU_BAND:
       g_idle_add(ext_band_update,NULL);
       break;
@@ -1716,6 +1724,26 @@ static void encoder_changed(int action,int pos) {
       }
       set_af_gain(1,value);
       break;
+    case ENCODER_RF_GAIN_RX1:
+      value=receiver[0]->rf_gain;
+      value+=(double)pos;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>100.0) {
+        value=100.0;
+      }
+      set_rf_gain(0,value);
+      break;
+    case ENCODER_RF_GAIN_RX2:
+      value=receiver[1]->rf_gain;
+      value+=(double)pos;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>71.0) {
+        value=71.0;
+      }
+      set_rf_gain(1,value);
+      break;
     case ENCODER_AGC_GAIN_RX1:
       value=receiver[0]->agc_gain;
       value+=(double)pos;
@@ -1761,8 +1789,8 @@ static void encoder_changed(int action,int pos) {
     case ENCODER_MIC_GAIN:
       value=mic_gain;
       value+=(double)pos;
-      if(value<-10.0) {
-        value=-10.0;
+      if(value<-12.0) {
+        value=-12.0;
       } else if(value>50.0) {
         value=50.0;
       }
@@ -1781,10 +1809,10 @@ static void encoder_changed(int action,int pos) {
     case ENCODER_RIT_RX1:
       value=(double)vfo[receiver[0]->id].rit;
       value+=(double)(pos*rit_increment);
-      if(value<-1000.0) {
-        value=-1000.0;
-      } else if(value>1000.0) {
-        value=1000.0;
+      if(value<-10000.0) {
+        value=-10000.0;
+      } else if(value>10000.0) {
+        value=10000.0;
       }
       vfo[receiver[0]->id].rit=(int)value;
       if(protocol==NEW_PROTOCOL) {
@@ -1795,10 +1823,10 @@ static void encoder_changed(int action,int pos) {
     case ENCODER_RIT_RX2:
       value=(double)vfo[receiver[1]->id].rit;
       value+=(double)(pos*rit_increment);
-      if(value<-1000.0) {
-        value=-1000.0;
-      } else if(value>1000.0) {
-        value=1000.0;
+      if(value<-10000.0) {
+        value=-10000.0;
+      } else if(value>10000.0) {
+        value=10000.0;
       }
       vfo[receiver[1]->id].rit=(int)value;
       if(protocol==NEW_PROTOCOL) {
@@ -1806,6 +1834,20 @@ static void encoder_changed(int action,int pos) {
       }
       g_idle_add(ext_vfo_update,NULL);
       break;
+    case ENCODER_XIT:
+      value=(double)transmitter->xit;
+      value+=(double)(pos*rit_increment);
+      if(value<-10000.0) {
+        value=-10000.0;
+      } else if(value>10000.0) {
+        value=10000.0;
+      }
+      transmitter->xit=(int)value;
+      if(protocol==NEW_PROTOCOL) {
+        schedule_high_priority();
+      }
+      g_idle_add(ext_vfo_update,NULL);
+      break;
     case ENCODER_CW_SPEED:
       value=(double)cw_keyer_speed;
       value+=(double)pos;
diff --git a/gpio.h b/gpio.h
index 2d825367b6d740b2a8158bd1b3c537a49827064c..ca99052c55721dd475770d5878fbe5f563648bf4 100644 (file)
--- a/gpio.h
+++ b/gpio.h
@@ -78,6 +78,8 @@ enum {
   AGC,
   SPLIT,
   DIVERSITY,
+  SAT,
+  RSAT,
   MENU_BAND,
   MENU_BANDSTACK,
   MENU_MODE,
diff --git a/i2c.c b/i2c.c
index d299a612b477ccd25857a92ba21a31377268beb9..d9333ad2ce3ab30db5f67140cbd00aea0d9eb6bc 100644 (file)
--- a/i2c.c
+++ b/i2c.c
@@ -185,26 +185,26 @@ void i2c_interrupt() {
 //g_print("i1c_interrupt: sw=%d action=%d\n",i,sw_action[i]);
         switch(sw_action[i]) {
           case TUNE:
-            {
-            int tune=getTune();
-            if(tune==0) tune=1; else tune=0;
-            g_idle_add(ext_tune_update,GINT_TO_POINTER(tune));
+            if(can_transmit) {
+              int tune=getTune();
+              if(tune==0) tune=1; else tune=0;
+              g_idle_add(ext_tune_update,GINT_TO_POINTER(tune));
             }
             break;
           case MOX:
-            {
-            int mox=getMox();
-            if(mox==0) mox=1; else mox=0;
-            g_idle_add(ext_mox_update,GINT_TO_POINTER(mox));
+            if(can_transmit) {
+              int mox=getMox();
+              if(mox==0) mox=1; else mox=0;
+              g_idle_add(ext_mox_update,GINT_TO_POINTER(mox));
             }
             break;
           case PS:
 #ifdef PURESIGNAL
-            g_idle_add(ext_ps_update,NULL);
+            if(can_transmit) g_idle_add(ext_ps_update,NULL);
 #endif
             break;
           case TWO_TONE:
-            g_idle_add(ext_two_tone,NULL);
+            if(can_transmit) g_idle_add(ext_two_tone,NULL);
             break;
           case NR:
             g_idle_add(ext_nr_update,NULL);
@@ -222,10 +222,10 @@ void i2c_interrupt() {
             g_idle_add(ext_rit_clear,NULL);
             break;
           case XIT:
-            g_idle_add(ext_xit_update,NULL);
+            if(can_transmit) g_idle_add(ext_xit_update,NULL);
             break;
           case XIT_CLEAR:
-            g_idle_add(ext_xit_clear,NULL);
+            if(can_transmit) g_idle_add(ext_xit_clear,NULL);
             break;
           case BAND_PLUS:
             g_idle_add(ext_band_plus,NULL);
@@ -270,7 +270,37 @@ void i2c_interrupt() {
             g_idle_add(ext_agc_update,NULL);
             break;
           case SPLIT:
-            g_idle_add(ext_split_update,NULL);
+            if(can_transmit) g_idle_add(ext_split_update,NULL);
+            break;
+          case DIVERSITY:
+            g_idle_add(ext_diversity_update,GINT_TO_POINTER(0));
+            break;
+          case SAT:
+            if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(SAT_MODE));
+            break;
+          case RSAT:
+            if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(RSAT_MODE));
+            break;
+          case MENU_BAND:
+            g_idle_add(ext_band_update,NULL);
+            break;
+          case MENU_BANDSTACK:
+            g_idle_add(ext_bandstack_update,NULL);
+            break;
+          case MENU_MODE:
+            g_idle_add(ext_mode_update,NULL);
+            break;
+          case MENU_FILTER:
+            g_idle_add(ext_filter_update,NULL);
+            break;
+          case MENU_FREQUENCY:
+            g_idle_add(ext_frequency_update,NULL);
+            break;
+          case MENU_MEMORY:
+            g_idle_add(ext_memory_update,NULL);
+            break;
+          case MENU_DIVERSITY:
+            g_idle_add(ext_diversity_update,GINT_TO_POINTER(1));
             break;
         }
       }
diff --git a/midi3.c b/midi3.c
index efa5361f68cf3bb05a87991e8581bd2fb72c72e9..2a2fd05c165b7f6d514b3bc4dea2dab148bb581c 100644 (file)
--- a/midi3.c
+++ b/midi3.c
@@ -240,19 +240,21 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            break;
        case COMPRESS:
            // Use values in the range 0 ... 20
-           if (type == MIDI_WHEEL) {
-              dnew=transmitter->compressor_level + val;
-             if (dnew > 20.0) dnew=20.0;
-             if (dnew < 0 ) dnew=0;
-           } else if (type == MIDI_KNOB){
+            if(can_transmit) {
+             if (type == MIDI_WHEEL) {
+                dnew=transmitter->compressor_level + val;
+               if (dnew > 20.0) dnew=20.0;
+               if (dnew < 0 ) dnew=0;
+             } else if (type == MIDI_KNOB){
              dnew=(20.0*val)/100.0;
-           } else {
+             } else {
                break;
-           }
-           transmitter->compressor_level=dnew;
-           if (dnew < 0.5) transmitter->compressor=0;
-           if (dnew > 0.5) transmitter->compressor=1;
-           g_idle_add(ext_set_compression, NULL);
+             }
+             transmitter->compressor_level=dnew;
+             if (dnew < 0.5) transmitter->compressor=0;
+             if (dnew > 0.5) transmitter->compressor=1;
+             g_idle_add(ext_set_compression, NULL);
+            }
            break;
        case MIDI_NB:
            // cycle through NoiseBlanker settings
@@ -284,8 +286,10 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            break;
        case VOX:
            // toggle VOX
-           vox_enabled = !vox_enabled;
-           g_idle_add(ext_vfo_update, NULL);
+            if(can_transmit) {
+             vox_enabled = !vox_enabled;
+             g_idle_add(ext_vfo_update, NULL);
+            }
            break;
        case MIDI_CTUN:
            // toggle CTUN
@@ -303,20 +307,24 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
        case MIDI_PS:
 #ifdef PURESIGNAL
            // toggle PURESIGNAL
-           new=!(transmitter->puresignal);
-           g_idle_add(ext_tx_set_ps,GINT_TO_POINTER(new));
+            if(can_transmit) {
+             new=!(transmitter->puresignal);
+             g_idle_add(ext_tx_set_ps,GINT_TO_POINTER(new));
+            }
 #endif
            break;
        case MIDI_SPLIT:
            // toggle split mode
-           if(!split) {
+            if(can_transmit) {
+              if(!split) {
                split=1;
                tx_set_mode(transmitter,vfo[VFO_B].mode);
-           } else {
+             } else {
                split=0;
                tx_set_mode(transmitter,vfo[VFO_A].mode);
-           }
-           g_idle_add(ext_vfo_update, NULL);
+             }
+             g_idle_add(ext_vfo_update, NULL);
+            }
            break;
        case VFO_A2B:
            g_idle_add(ext_vfo_a_to_b, NULL);
index 178513ba5b899b1adfd84639873e50f1b02375bc..bd020c5a3a4aa2200e55c6a9f958ba0f8088c620 100644 (file)
@@ -727,6 +727,9 @@ static void new_protocol_high_priority() {
 //
 
     txFrequency=vfo[txvfo].frequency-vfo[txvfo].lo+vfo[txvfo].offset;
+    if(transmitter->xit_enabled) {
+      txFrequency+=transmitter->xit;
+    }
 
     if (!cw_is_on_vfo_freq) {
       if(txmode==modeCWU) {
@@ -1841,20 +1844,12 @@ static void process_mic_data(int bytes) {
   }
 }
 
-void new_protocol_process_local_mic(unsigned char *buffer,int le) {
-  int b;
+void new_protocol_process_local_mic(float *buffer) {
   int i;
   short sample;
 
-  b=0;
   for(i=0;i<MIC_SAMPLES;i++) {
-    if(le) {
-      sample = (short)(buffer[b++]&0xFF);
-      sample |= (short) (buffer[b++]<<8);
-    } else {
-      sample = (short)(buffer[b++]<<8);
-      sample |= (short) (buffer[b++]&0xFF);
-    }
+    sample = (short)(buffer[i]*32767.0);
 #ifdef FREEDV
     if(active_receiver->freedv) {
       add_freedv_mic_sample(transmitter,sample);
index fe900b3d83d02bdd6b1ea28c8f0933156ee849cf..82875c5032979958b451575dd587089d245f2887 100644 (file)
@@ -88,7 +88,7 @@ extern int getMox();
 extern void setTune(int state);
 extern int getTune();
 
-extern void new_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void new_protocol_process_local_mic(float *buffer);
 extern void new_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample);
 extern void new_protocol_iq_samples(int isample,int qsample);
 extern void new_protocol_flush_iq_samples();
index 98b3ccc9f97aa30a1857c95c521c1908073c487b..b4701df0438e6fd55a8b7ce23b32040ef0eafdca 100644 (file)
@@ -735,6 +735,9 @@ static long long channel_freq(int chan) {
       }
     }
     freq=vfo[vfonum].frequency-vfo[vfonum].lo+vfo[vfonum].offset;
+    if(transmitter->xit_enabled) {
+      freq+=transmitter->xit;
+    }
     if (!cw_is_on_vfo_freq) {
       if(vfo[vfonum].mode==modeCWU) {
         freq+=(long long)cw_keyer_sidetone_frequency;
@@ -1044,23 +1047,15 @@ void old_protocol_iq_samples(int isample,int qsample) {
 }
 
 
-void old_protocol_process_local_mic(unsigned char *buffer,int le) {
-  int b;
+void old_protocol_process_local_mic(float *buffer) {
   int i;
   short sample;
 
 // always 48000 samples per second
-  b=0;
   for(i=0;i<720;i++) {
     // avoid pointer increments in logical-or constructs, as the sequence
     // is undefined
-    if(le) {
-      sample = (short) (buffer[b++]&0xFF);
-      sample |= (short) (buffer[b++]<<8);
-    } else {
-      sample = (short)(buffer[b++]<<8);
-      sample |=  (short) (buffer[b++]&0xFF);
-    }
+    sample = (short) (buffer[i]*32767.0);
 #ifdef FREEDV
     if(active_receiver->freedv) {
       add_freedv_mic_sample(transmitter,sample);
index c7cf63cc1eb81a01af0280e05ad562bad2fa29fa..bda0ab2e2f6312df62c2b84e19b3b16c53b7dcbf 100644 (file)
@@ -26,7 +26,7 @@ extern void old_protocol_run();
 extern void old_protocol_init(int rx,int pixels,int rate);
 extern void old_protocol_set_mic_sample_rate(int rate);
 
-extern void old_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void old_protocol_process_local_mic(float *buffer);
 extern void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample);
 extern void old_protocol_iq_samples(int isample,int qsample);
 extern void old_protocol_iq_samples_with_sidetone(int isample,int qsample,int side);
diff --git a/radio.c b/radio.c
index faa0ee793a7e5fd42837630623e68f6bb455307d..fb6385752225f82ba89af5e2ae4e241c7c9a8b33 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -97,7 +97,7 @@
 #define FREEDV_WATERFALL_HEIGHT (105)
 #endif
 
-static GtkWidget *fixed;
+GtkWidget *fixed;
 static GtkWidget *vfo_panel;
 static GtkWidget *meter;
 static GtkWidget *menu;
@@ -120,6 +120,8 @@ static GtkWidget *encoders;
 static cairo_surface_t *encoders_surface = NULL;
 #endif
 
+gint sat_mode;
+
 int region=REGION_OTHER;
 
 int echo=0;
@@ -317,6 +319,21 @@ double display_calibration=0.0;
 
 int can_transmit=0;
 
+gboolean duplex=FALSE;
+
+void radio_stop() {
+  if(can_transmit) {
+g_print("radio_stop: TX: CloseChannel: %d\n",transmitter->id);
+    CloseChannel(transmitter->id);
+  }
+  set_displaying(receiver[0],0);
+g_print("radio_stop: RX0: CloseChannel: %d\n",receiver[0]->id);
+  CloseChannel(receiver[0]->id);
+  set_displaying(receiver[1],0);
+g_print("radio_stop: RX1: CloseChannel: %d\n",receiver[1]->id);
+  CloseChannel(receiver[1]->id);
+}
+
 void reconfigure_radio() {
   int i;
   int y;
@@ -750,6 +767,7 @@ void start_radio() {
   y=0;
 
   fixed=gtk_fixed_new();
+  g_object_ref(grid);  // so it does not get deleted
   gtk_container_remove(GTK_CONTAINER(top_window),grid);
   gtk_container_add(GTK_CONTAINER(top_window), fixed);
 
@@ -787,7 +805,6 @@ void start_radio() {
   int tx_height=rx_height;
   rx_height=rx_height/RECEIVERS;
 
-
   //
   // To be on the safe side, we create ALL receiver panels here
   // If upon startup, we only should display one panel, we do the switch below
@@ -811,7 +828,7 @@ void start_radio() {
 
   //fprintf(stderr,"Create transmitter\n");
   if(can_transmit) {
-    transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height);
+    transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width/2, tx_height/2);
     transmitter->x=0;
     transmitter->y=VFO_HEIGHT;
 
@@ -821,6 +838,7 @@ void start_radio() {
     receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width);
     SetPSHWPeak(transmitter->id, protocol==ORIGINAL_PROTOCOL? 0.4067 : 0.2899);
 #endif
+
   }
 
 #ifdef AUDIO_WATERFALL
@@ -923,20 +941,27 @@ void start_radio() {
     if(can_transmit) {
       soapy_protocol_create_transmitter(transmitter);
       soapy_protocol_set_tx_antenna(transmitter,dac[0].antenna);
+/*
       for(int i=0;i<radio->info.soapy.tx_gains;i++) {
-        soapy_protocol_set_tx_gain(transmitter,radio->info.soapy.tx_gain[i],dac[0].tx_gain[i]);
+        soapy_protocol_set_tx_gain_element(transmitter,radio->info.soapy.tx_gain[i],dac[0].tx_gain[i]);
       }
+*/
+      soapy_protocol_set_tx_gain(transmitter,transmitter->drive);
       soapy_protocol_set_tx_frequency(transmitter);
+      soapy_protocol_start_transmitter(transmitter);
     }
 
     soapy_protocol_set_rx_antenna(rx,adc[0].antenna);
+/*
     for(int i=0;i<radio->info.soapy.rx_gains;i++) {
-      soapy_protocol_set_gain(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
+      soapy_protocol_set_gain_element(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
     }
+*/
+
     soapy_protocol_set_rx_frequency(rx,VFO_A);
     soapy_protocol_set_automatic_gain(rx,adc[0].agc);
     for(int i=0;i<radio->info.soapy.rx_gains;i++) {
-      soapy_protocol_set_gain(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
+      soapy_protocol_set_gain_element(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
     }
 
     if(vfo[0].ctun) {
@@ -944,6 +969,9 @@ void start_radio() {
     }
     soapy_protocol_start_receiver(rx);
 
+//g_print("radio: set rf_gain=%f\n",rx->rf_gain);
+    soapy_protocol_set_gain(rx,rx->rf_gain);
+
   }
 #endif
 
@@ -1014,6 +1042,7 @@ void radio_change_sample_rate(int rate) {
 static void rxtx(int state) {
   int i;
 
+  g_print("rxtx: state=%d duplex=%d\n",state,duplex);
   if(state) {
     // switch to tx
 #ifdef FREEDV
@@ -1029,20 +1058,22 @@ static void rxtx(int state) {
     tx_feedback->samples=0;
 #endif
 
-    for(i=0;i<receivers;i++) {
-      // Delivery of RX samples
-      // to WDSP via fexchange0() may come to an abrupt stop
-      // (especially with PURESIGNAL or DIVERSITY).
-      // Therefore, wait for *all* receivers to complete
-      // their slew-down before going TX.
-      SetChannelState(receiver[i]->id,0,1);
-      set_displaying(receiver[i],0);
-      g_object_ref((gpointer)receiver[i]->panel);
-      g_object_ref((gpointer)receiver[i]->panadapter);
-      if(receiver[i]->waterfall!=NULL) {
-        g_object_ref((gpointer)receiver[i]->waterfall);
+    if(!duplex) {
+      for(i=0;i<receivers;i++) {
+        // Delivery of RX samples
+        // to WDSP via fexchange0() may come to an abrupt stop
+        // (especially with PURESIGNAL or DIVERSITY).
+        // Therefore, wait for *all* receivers to complete
+        // their slew-down before going TX.
+        SetChannelState(receiver[i]->id,0,1);
+        set_displaying(receiver[i],0);
+        g_object_ref((gpointer)receiver[i]->panel);
+        g_object_ref((gpointer)receiver[i]->panadapter);
+        if(receiver[i]->waterfall!=NULL) {
+          g_object_ref((gpointer)receiver[i]->waterfall);
+        }
+        gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel);
       }
-      gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel);
     }
 //#ifdef FREEDV
 //    if(active_receiver->freedv) {
@@ -1050,10 +1081,26 @@ static void rxtx(int state) {
 //    }
 //#endif
     gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,transmitter->x,transmitter->y);
+    
     SetChannelState(transmitter->id,1,0);
     tx_set_displaying(transmitter,1);
+    switch(protocol) {
+#ifdef SOAPYSDR
+      case SOAPYSDR_PROTOCOL:
+        soapy_protocol_set_tx_frequency(transmitter);
+        //soapy_protocol_start_transmitter(transmitter);
+        break;
+#endif
+    }
   } else {
     // switch to rx
+    switch(protocol) {
+#ifdef SOAPYSDR
+      case SOAPYSDR_PROTOCOL:
+        //soapy_protocol_stop_transmitter(transmitter);
+        break;
+#endif
+    }
     SetChannelState(transmitter->id,0,1);
     tx_set_displaying(transmitter,0);
     g_object_ref((gpointer)transmitter->panel);
@@ -1064,10 +1111,12 @@ static void rxtx(int state) {
 //      gtk_widget_hide(audio_waterfall);
 //    }
 //#endif
-    for(i=0;i<receivers;i++) {
-      gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,receiver[i]->x,receiver[i]->y);
-      SetChannelState(receiver[i]->id,1,0);
-      set_displaying(receiver[i],1);
+    if(!duplex) {
+      for(i=0;i<receivers;i++) {
+        gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,receiver[i]->x,receiver[i]->y);
+        SetChannelState(receiver[i]->id,1,0);
+        set_displaying(receiver[i],1);
+      }
     }
 //#ifdef FREEDV
 //    if(active_receiver->freedv) {
@@ -1084,6 +1133,7 @@ static void rxtx(int state) {
 }
 
 void setMox(int state) {
+g_print("setMox: %d\n",state);
   if(!can_transmit) return;
   vox_cancel();  // remove time-out
   if(mox!=state) {
@@ -1100,18 +1150,6 @@ void setMox(int state) {
       schedule_high_priority();
       schedule_receive_specific();
       break;
-#ifdef SOAPYSDR
-    case SOAPYSDR_PROTOCOL:
-      if(transmitter!=NULL) {
-        if(mox) {
-          soapy_protocol_set_tx_frequency(transmitter);
-          soapy_protocol_start_transmitter(transmitter);
-        } else {
-          soapy_protocol_stop_transmitter(transmitter);
-        }
-      }
-      break;
-#endif
     default:
       break;
   }
@@ -1204,16 +1242,18 @@ void setTune(int state) {
       //schedule_general();
     }
     if(state) {
-      for(i=0;i<receivers;i++) {
-        // Delivery of RX samples
-        // to WDSP via fexchange0() may come to an abrupt stop
-        // (especially with PURESIGNAL or DIVERSITY)
-        // Therefore, wait for *all* receivers to complete
-        // their slew-down before going TX.
-        SetChannelState(receiver[i]->id,0,1);
-        set_displaying(receiver[i],0);
-        if(protocol==NEW_PROTOCOL) {
-          schedule_high_priority();
+      if(!duplex) {
+        for(i=0;i<receivers;i++) {
+          // Delivery of RX samples
+          // to WDSP via fexchange0() may come to an abrupt stop
+          // (especially with PURESIGNAL or DIVERSITY)
+          // Therefore, wait for *all* receivers to complete
+          // their slew-down before going TX.
+          SetChannelState(receiver[i]->id,0,1);
+          set_displaying(receiver[i],0);
+          if(protocol==NEW_PROTOCOL) {
+            schedule_high_priority();
+          }
         }
       }
 
@@ -1372,7 +1412,18 @@ void calcDriveLevel() {
 
 void setDrive(double value) {
     transmitter->drive=value;
-    calcDriveLevel();
+    switch(protocol) {
+      case ORIGINAL_PROTOCOL:
+      case NEW_PROTOCOL:
+        calcDriveLevel();
+        break;
+#ifdef SOAPYSDR
+      case SOAPYSDR_PROTOCOL:
+        soapy_protocol_set_tx_gain(transmitter,transmitter->drive);
+        
+        break;
+#endif
+    }
 }
 
 double getTuneDrive() {
@@ -1652,6 +1703,13 @@ fprintf(stderr,"sem_wait: returner\n");
     value=getProperty("rx2_gain_slider");
     if(value) rx_gain_slider[1]=atoi(value);
 
+    value=getProperty("split");
+    if(value) split=atoi(value);
+    value=getProperty("duplex");
+    if(value) duplex=atoi(value);
+    value=getProperty("sat_mode");
+    if(value) sat_mode=atoi(value);
+
 #ifdef SOAPYSDR
   if(radio->device==SOAPYSDR_USB_DEVICE) {
     for(int i=0;i<radio->info.soapy.rx_gains;i++) {
@@ -1664,6 +1722,8 @@ fprintf(stderr,"sem_wait: returner\n");
     value=getProperty("radio.adc[0].antenna");
     if(value!=NULL) adc[0].antenna=atoi(value);
 
+    value=getProperty("radio.dac[0].antenna");
+    if(value!=NULL) dac[0].antenna=atoi(value);
     for(int i=0;i<radio->info.soapy.tx_gains;i++) {
       sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]);
       value=getProperty(name);
@@ -1867,6 +1927,10 @@ fprintf(stderr,"sem_wait: returned\n");
       sprintf(value,"%d", adc[0].antenna);
       setProperty(name,value);
 
+      sprintf(name,"radio.dac[0].antenna");
+      sprintf(value,"%d", dac[0].antenna);
+      setProperty(name,value);
+
       for(int i=0;i<radio->info.soapy.tx_gains;i++) {
         sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]);
         sprintf(value,"%d", dac[0].tx_gain[i]);
@@ -1885,6 +1949,10 @@ fprintf(stderr,"sem_wait: returned\n");
       sprintf(value,"%d", adc[1].antenna);
       setProperty(name,value);
 
+      sprintf(name,"radio.dac[1].antenna");
+      sprintf(value,"%d", dac[1].antenna);
+      setProperty(name,value);
+
       for(int i=0;i<radio->info.soapy.tx_gains;i++) {
         sprintf(name,"radio.dac[1].tx_gain.%s",radio->info.soapy.tx_gain[i]);
         sprintf(value,"%d", dac[1].tx_gain[i]);
@@ -1915,6 +1983,14 @@ fprintf(stderr,"sem_wait: returned\n");
     if(can_transmit) {
       transmitter_save_state(transmitter);
     }
+
+    sprintf(value,"%d",duplex);
+    setProperty("duplex",value);
+    sprintf(value,"%d",split);
+    setProperty("split",value);
+    sprintf(value,"%d",sat_mode);
+    setProperty("sat_mode",value);
+
 #ifdef FREEDV
     freedv_save_state();
 #endif
diff --git a/radio.h b/radio.h
index 7f1a46b5eccbe3e3dd205f3bebc1ff4a8b1f5e4b..de3c11efd24aa4b8a2aad3d753963d9116addab6 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -48,6 +48,8 @@
 
 extern DISCOVERED *radio;
 
+extern GtkWidget *fixed;
+
 extern char property_path[];
 
 #define NONE 0
@@ -88,6 +90,14 @@ extern TRANSMITTER *transmitter;
 #define KEYER_MODE_A 1
 #define KEYER_MODE_B 2
 
+enum {
+  SAT_NONE,
+  SAT_MODE,
+  RSAT_MODE
+};
+
+extern gint sat_mode;
+
 extern int echo;
 
 extern int radio_sample_rate;
@@ -159,9 +169,10 @@ int rx_gain_slider[2];
 int locked;
 
 extern long long step;
-//extern int rit;
 extern int rit_increment;
 
+extern gboolean duplex;
+
 extern int lt2208Dither;
 extern int lt2208Random;
 extern int attenuation;
@@ -264,6 +275,7 @@ extern double display_calibration;
 
 extern int can_transmit;
 
+extern void radio_stop();
 extern void reconfigure_radio();
 extern void start_radio();
 //extern void init_radio();
index 62840fe188353c74baf3a3edc48c7fce963f058d..163aa4badde6915e0f480c739436a398ec97b4df 100644 (file)
 #include "soapy_protocol.h"
 #endif
 #include "gpio.h"
+#include "vfo.h"
 
 static GtkWidget *parent_window=NULL;
-
 static GtkWidget *menu_b=NULL;
-
 static GtkWidget *dialog=NULL;
+static GtkWidget *rx_gains[3];
+static GtkWidget *tx_gains[2];
+static GtkWidget *sat_b;
+static GtkWidget *rsat_b;
 
 static void cleanup() {
   if(dialog!=NULL) {
@@ -64,18 +67,47 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d
 }
 
 #ifdef SOAPYSDR
+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->device==SOAPYSDR_USB_DEVICE) {
+    soapy_protocol_set_gain(receiver[0],active_receiver->rf_gain);
+  }
+
+  for(int i=0;i<radio->info.soapy.rx_gains;i++) {
+    int value=soapy_protocol_get_gain_element(active_receiver,radio->info.soapy.rx_gain[i]);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)value);
+  }
+}
+
 static void rx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   ADC *adc=(ADC *)data;
   int gain;
   if(radio->device==SOAPYSDR_USB_DEVICE) {
     gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
-    soapy_protocol_set_gain(receiver[0],(char *)gtk_widget_get_name(widget),gain);
+    soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),gain);
+
     for(int i=0;i<radio->info.soapy.rx_gains;i++) {
       if(strcmp(radio->info.soapy.rx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
         adc[0].rx_gain[i]=gain;
         break;
       }
     }
+
+  }
+}
+
+static void drive_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
+  DAC *dac=(DAC *)data;
+  int gain;
+  if(radio->device==SOAPYSDR_USB_DEVICE) {
+    gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+    soapy_protocol_set_tx_gain(transmitter,(double)gain);
+    for(int i=0;i<radio->info.soapy.tx_gains;i++) {
+      int value=soapy_protocol_get_tx_gain_element(transmitter,radio->info.soapy.tx_gain[i]);
+      gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),(double)value);
+    }
   }
 }
 
@@ -84,7 +116,7 @@ static void tx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   int gain;
   if(radio->device==SOAPYSDR_USB_DEVICE) {
     gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
-    soapy_protocol_set_tx_gain(transmitter,(char *)gtk_widget_get_name(widget),gain);
+    soapy_protocol_set_tx_gain_element(transmitter,(char *)gtk_widget_get_name(widget),gain);
     for(int i=0;i<radio->info.soapy.tx_gains;i++) {
       if(strcmp(radio->info.soapy.tx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
         dac[0].tx_gain[i]=gain;
@@ -107,7 +139,7 @@ static void dac0_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
   int gain;
   if(radio->device==SOAPYSDR_USB_DEVICE) {
     gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
-    soapy_protocol_set_tx_gain(radio->transmitter,(char *)gtk_widget_get_name(widget),gain);
+    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++) {
       if(strcmp(radio->discovered->info.soapy.tx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
         radio->dac[0].tx_gain[i]=gain;
@@ -158,6 +190,35 @@ static void iqswap_cb(GtkWidget *widget, gpointer data) {
   iqswap=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
 }
 
+static void split_cb(GtkWidget *widget, gpointer data) {
+  split=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+  vfo_update();
+}
+
+static void duplex_cb(GtkWidget *widget, gpointer data) {
+  duplex=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+  vfo_update();
+}
+
+static void sat_cb(GtkWidget *widget, gpointer data) {
+  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rsat_b), FALSE);
+    sat_mode=SAT_MODE;
+  } else {
+    sat_mode=SAT_NONE;
+  }
+  vfo_update();
+}
+
+static void rsat_cb(GtkWidget *widget, gpointer data) {
+  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sat_b), FALSE);
+    sat_mode=RSAT_MODE;
+  } else {
+    sat_mode=SAT_NONE;
+  }
+  vfo_update();
+}
 
 static void load_filters(void) {
   if(protocol==NEW_PROTOCOL) {
@@ -290,6 +351,8 @@ void radio_menu(GtkWidget *parent) {
   gtk_grid_attach(GTK_GRID(grid),region_combo,col,row,1,1);
   g_signal_connect(region_combo,"changed",G_CALLBACK(region_cb),NULL);
 
+  col++;
+
 
   row++;
   col=0;
@@ -468,7 +531,7 @@ void radio_menu(GtkWidget *parent) {
 
   row=1;
 
-  GtkWidget *rit_label=gtk_label_new("RIT step (Hz): ");
+  GtkWidget *rit_label=gtk_label_new("R/XIT step (Hz): ");
   gtk_grid_attach(GTK_GRID(grid),rit_label,col,row,1,1);
   row++;
 
@@ -564,9 +627,40 @@ void radio_menu(GtkWidget *parent) {
     if(row>temp_row) temp_row=row;
   }
 
-#ifdef SOAPYSDR
   row=temp_row;
   col=0;
+
+  GtkWidget *split_b=gtk_check_button_new_with_label("Split");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (split_b), split);
+  gtk_grid_attach(GTK_GRID(grid),split_b,col,row,1,1);
+  g_signal_connect(split_b,"toggled",G_CALLBACK(split_cb),NULL);
+
+  col++;
+
+  GtkWidget *duplex_b=gtk_check_button_new_with_label("Duplex");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (duplex_b), duplex);
+  gtk_grid_attach(GTK_GRID(grid),duplex_b,col,row,1,1);
+  g_signal_connect(duplex_b,"toggled",G_CALLBACK(duplex_cb),NULL);
+
+  col++;
+
+  sat_b=gtk_check_button_new_with_label("SAT");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sat_b), sat_mode==SAT_MODE);
+  gtk_grid_attach(GTK_GRID(grid),sat_b,col,row,1,1);
+  g_signal_connect(sat_b,"toggled",G_CALLBACK(sat_cb),NULL);
+
+  col++;
+
+  rsat_b=gtk_check_button_new_with_label("RSAT");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rsat_b), sat_mode==RSAT_MODE);
+  gtk_grid_attach(GTK_GRID(grid),rsat_b,col,row,1,1);
+  g_signal_connect(rsat_b,"toggled",G_CALLBACK(rsat_cb),NULL);
+
+  row++;
+  if(row>temp_row) temp_row=row;
+
+#ifdef SOAPYSDR
+  col=0;
   if(radio->device==SOAPYSDR_USB_DEVICE) {
     int i;
     if(radio->info.soapy.rx_gains>0) {
@@ -594,6 +688,7 @@ void radio_menu(GtkWidget *parent) {
     }
 
 
+    //rx_gains=g_new(GtkWidget*,radio->info.soapy.rx_gains);
     for(i=0;i<radio->info.soapy.rx_gains;i++) {
       col=0;
       GtkWidget *rx_gain_label=gtk_label_new(radio->info.soapy.rx_gain[i]);
@@ -603,18 +698,35 @@ void radio_menu(GtkWidget *parent) {
       if(range.step==0.0) {
         range.step=1.0;
       }
-      GtkWidget *rx_gain_b=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
-      gtk_widget_set_name (rx_gain_b, radio->info.soapy.rx_gain[i]);
-      gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gain_b),(double)adc[0].rx_gain[i]);
-      gtk_grid_attach(GTK_GRID(grid),rx_gain_b,col,row,1,1);
-      g_signal_connect(rx_gain_b,"value_changed",G_CALLBACK(rx_gain_value_changed_cb),&adc[0]);
-      col++;
+      rx_gains[i]=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
+      gtk_widget_set_name (rx_gains[i], radio->info.soapy.rx_gain[i]);
+      int value=soapy_protocol_get_gain_element(active_receiver,radio->info.soapy.rx_gain[i]);
+      gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)value);
+      //gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)adc[0].rx_gain[i]);
+      gtk_grid_attach(GTK_GRID(grid),rx_gains[i],col,row,1,1);
+      g_signal_connect(rx_gains[i],"value_changed",G_CALLBACK(rx_gain_value_changed_cb),&adc[0]);
+
+      gtk_widget_set_sensitive(rx_gains[i], FALSE);
+
       row++;
     }
 
+    // used single gain control - LimeSDR works out best setting for the 3 rx gains
+    col=0;
+    GtkWidget *rf_gain_label=gtk_label_new("RF Gain");
+    gtk_grid_attach(GTK_GRID(grid),rf_gain_label,col,row,1,1);
+    col++;
+    GtkWidget *rf_gain_b=gtk_spin_button_new_with_range(0.0,60.0,1.0);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),active_receiver->rf_gain);
+    gtk_grid_attach(GTK_GRID(grid),rf_gain_b,col,row,1,1);
+    g_signal_connect(rf_gain_b,"value_changed",G_CALLBACK(rf_gain_value_changed_cb),&adc[0]);
+    col++;
+    row++;
+
     row=temp_row;
 
     if(can_transmit) {
+      //tx_gains=g_new(GtkWidget*,radio->info.soapy.tx_gains);
       for(i=0;i<radio->info.soapy.tx_gains;i++) {
         col=2;
         GtkWidget *tx_gain_label=gtk_label_new(radio->info.soapy.tx_gain[i]);
@@ -624,15 +736,29 @@ void radio_menu(GtkWidget *parent) {
         if(range.step==0.0) {
           range.step=1.0;
         }
-        GtkWidget *tx_gain_b=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
-        gtk_widget_set_name (tx_gain_b, radio->info.soapy.tx_gain[i]);
-        gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gain_b),(double)dac[0].tx_gain[i]);
-        gtk_grid_attach(GTK_GRID(grid),tx_gain_b,col,row,1,1);
-        g_signal_connect(tx_gain_b,"value_changed",G_CALLBACK(tx_gain_value_changed_cb),&dac[0]);
+        tx_gains[i]=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
+        gtk_widget_set_name (tx_gains[i], radio->info.soapy.tx_gain[i]);
+        int value=soapy_protocol_get_tx_gain_element(transmitter,radio->info.soapy.tx_gain[i]);
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),(double)value);
+        //gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),(double)dac[0].tx_gain[i]);
+        gtk_grid_attach(GTK_GRID(grid),tx_gains[i],col,row,1,1);
+        g_signal_connect(tx_gains[i],"value_changed",G_CALLBACK(tx_gain_value_changed_cb),&dac[0]);
+
+        gtk_widget_set_sensitive(tx_gains[i], FALSE);
+
         row++;
       }
-    }
 
+      // used single gain control - LimeSDR works out best setting for the 3 rx gains
+      col=2;
+      GtkWidget *tx_gain_label=gtk_label_new("TX Gain");
+      gtk_grid_attach(GTK_GRID(grid),tx_gain_label,col,row,1,1);
+      col++;
+      tx_gains[i]=gtk_spin_button_new_with_range(0.0,100.0,1.0);
+      gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),transmitter->drive);
+      gtk_grid_attach(GTK_GRID(grid),tx_gains[i],col,row,1,1);
+      g_signal_connect(tx_gains[i],"value_changed",G_CALLBACK(drive_gain_value_changed_cb),&adc[0]);
+    }
   }
 #endif
 
index 411e38564d69b09b0d606422aa634bca51458cac..4f4be8144e877572c04f9143339b549f550332ab 100644 (file)
@@ -116,7 +116,7 @@ gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton *event,
           vfo_move((long long)((float)(x-last_x)*rx->hz_per_pixel));
         } else {
           // move to this frequency
-          vfo_move_to((long long)((float)(x-(display_width/2))*rx->hz_per_pixel));
+          vfo_move_to((long long)((float)x*rx->hz_per_pixel));
         }
         last_x=x;
         pressed=FALSE;
@@ -140,7 +140,8 @@ gboolean receiver_motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
                                 &state);
     // G0ORX: removed test as with it unable to drag screen
     //if(state & GDK_BUTTON1_MASK) {
-      int moved=last_x-x;
+      //int moved=last_x-x;
+      int moved=x-last_x;
       vfo_move((long long)((float)moved*rx->hz_per_pixel));
       last_x=x;
       has_moved=TRUE;
@@ -152,17 +153,9 @@ gboolean receiver_motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
 
 gboolean receiver_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) {
   if(event->direction==GDK_SCROLL_UP) {
-    if(vfo[active_receiver->id].ctun) {
-      vfo_move(-step);
-    } else {
-      vfo_move(step);
-    }
+    vfo_move(step);
   } else {
-    if(vfo[active_receiver->id].ctun) {
-      vfo_move(step);
-    } else {
-      vfo_move(-step);
-    }
+    vfo_move(-step);
   }
   return TRUE;
 }
@@ -226,6 +219,9 @@ void receiver_save_state(RECEIVER *rx) {
   sprintf(name,"receiver.%d.volume",rx->id);
   sprintf(value,"%f",rx->volume);
   setProperty(name,value);
+  sprintf(name,"receiver.%d.rf_gain",rx->id);
+  sprintf(value,"%f",rx->rf_gain);
+  setProperty(name,value);
   sprintf(name,"receiver.%d.agc",rx->id);
   sprintf(value,"%d",rx->agc);
   setProperty(name,value);
@@ -285,6 +281,11 @@ void receiver_save_state(RECEIVER *rx) {
   sprintf(name,"receiver.%d.local_audio",rx->id);
   sprintf(value,"%d",rx->local_audio);
   setProperty(name,value);
+  if(rx->audio_name!=NULL) {
+    sprintf(name,"receiver.%d.audio_name",rx->id);
+    sprintf(value,"%s",rx->audio_name);
+    setProperty(name,value);
+  }
   sprintf(name,"receiver.%d.mute_when_not_active",rx->id);
   sprintf(value,"%d",rx->mute_when_not_active);
   setProperty(name,value);
@@ -398,6 +399,9 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id);
   sprintf(name,"receiver.%d.volume",rx->id);
   value=getProperty(name);
   if(value) rx->volume=atof(value);
+  sprintf(name,"receiver.%d.rf_gain",rx->id);
+  value=getProperty(name);
+  if(value) rx->rf_gain=atof(value);
   sprintf(name,"receiver.%d.agc",rx->id);
   value=getProperty(name);
   if(value) rx->agc=atoi(value);
@@ -457,6 +461,12 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id);
   sprintf(name,"receiver.%d.local_audio",rx->id);
   value=getProperty(name);
   if(value) rx->local_audio=atoi(value);
+  sprintf(name,"receiver.%d.audio_name",rx->id);
+  value=getProperty(name);
+  if(value) {
+    rx->audio_name=g_new(gchar,strlen(value)+1);
+    strcpy(rx->audio_name,value);
+  }
   sprintf(name,"receiver.%d.mute_when_not_active",rx->id);
   value=getProperty(name);
   if(value) rx->mute_when_not_active=atoi(value);
@@ -594,6 +604,10 @@ void set_displaying(RECEIVER *rx,int state) {
   rx->displaying=state;
   if(state) {
     rx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/rx->fps, update_display, rx, NULL);
+  } else {
+    if(rx->update_timer_id!=-1) {
+      rx->update_timer_id=-1;
+    }
   }
 }
 
@@ -814,7 +828,8 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
   rx->panadapter_low=-140;
   rx->panadapter_step=20;
 
-  rx->volume=0.0;
+  rx->volume=5.0;
+  rx->rf_gain=50.0;
 
   rx->squelch_enable=0;
   rx->squelch=0;
@@ -846,6 +861,7 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
   rx->playback_handle=NULL;
   rx->playback_buffer=NULL;
   rx->local_audio=0;
+  rx->audio_name=NULL;
   rx->mute_when_not_active=0;
   rx->audio_channel=STEREO;
   rx->audio_device=-1;
@@ -930,6 +946,7 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
   rx->fft_size=fft_size;
   rx->pixels=pixels;
   rx->fps=fps;
+  rx->update_timer_id=-1;
 
 
 //  rx->dds_offset=0;
@@ -986,6 +1003,7 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
   
   rx->playback_handle=NULL;
   rx->local_audio=0;
+  rx->audio_name=NULL;
   rx->mute_when_not_active=0;
   rx->audio_channel=STEREO;
   rx->audio_device=-1;
@@ -1312,7 +1330,7 @@ static void process_rx_buffer(RECEIVER *rx) {
   short right_audio_sample;
   int i;
   for(i=0;i<rx->output_samples;i++) {
-    if(isTransmitting()) {
+    if(isTransmitting() && !duplex) {
       left_audio_sample=0;
       right_audio_sample=0;
     } else {
index 8a98c2ab5fb6b75ccaad1d9f485e8423ac737e40..f201bfbeaefb17c94e83311f7f0fd50392a98b7c 100644 (file)
@@ -43,6 +43,8 @@ typedef struct _receiver {
   gint adc;
 
   gdouble volume;
+  gdouble rf_gain;
+
   gint agc;
   gdouble agc_gain;
   gdouble agc_slope;
@@ -110,6 +112,7 @@ typedef struct _receiver {
   gint local_audio;
   gint mute_when_not_active;
   gint audio_device;
+  gchar *audio_name;
 #ifdef PORTAUDIO
   PaStream *playback_handle;
   gfloat *playback_buffer;
diff --git a/release/pihpsdr-controller1.v2.0.1-beta.tar b/release/pihpsdr-controller1.v2.0.1-beta.tar
new file mode 100644 (file)
index 0000000..c9b2335
Binary files /dev/null and b/release/pihpsdr-controller1.v2.0.1-beta.tar differ
diff --git a/release/pihpsdr-controller2-v1.v2.0.1-beta.tar b/release/pihpsdr-controller2-v1.v2.0.1-beta.tar
new file mode 100644 (file)
index 0000000..42c5970
Binary files /dev/null and b/release/pihpsdr-controller2-v1.v2.0.1-beta.tar differ
diff --git a/release/pihpsdr-controller2-v2.v2.0.1-beta.tar b/release/pihpsdr-controller2-v2.v2.0.1-beta.tar
new file mode 100644 (file)
index 0000000..6e1c279
Binary files /dev/null and b/release/pihpsdr-controller2-v2.v2.0.1-beta.tar differ
diff --git a/release/pihpsdr-nocontroller.v2.0.1-beta.tar b/release/pihpsdr-nocontroller.v2.0.1-beta.tar
new file mode 100644 (file)
index 0000000..d40f2cb
Binary files /dev/null and b/release/pihpsdr-nocontroller.v2.0.1-beta.tar differ
index 0ee5bab146f551449c4fe0abc87e3cdaf7328131..c22bfb8644d2dd65ab9ebb10d0f24af9d4ac9281 100755 (executable)
Binary files a/release/pihpsdr/pihpsdr and b/release/pihpsdr/pihpsdr differ
index 24db9fc568b7cc98280ae271b10117f728e7ef4d..f986b5138389bee7b41e2a646885b9b94130b8f5 100644 (file)
--- a/rx_menu.c
+++ b/rx_menu.c
 #include "new_protocol.h"
 
 static GtkWidget *parent_window=NULL;
-
 static GtkWidget *menu_b=NULL;
-
 static GtkWidget *dialog=NULL;
+static GtkWidget *local_audio_b=NULL;
+static GtkWidget *output=NULL;
 
 static void cleanup() {
   if(dialog!=NULL) {
@@ -96,6 +96,12 @@ static void adc_cb(GtkWidget *widget, gpointer data) {
 
 static void local_audio_cb(GtkWidget *widget, gpointer data) {
 fprintf(stderr,"local_audio_cb: rx=%d\n",active_receiver->id);
+
+  if(active_receiver->audio_name==NULL) {
+    int i=gtk_combo_box_get_active(GTK_COMBO_BOX(output));
+    active_receiver->audio_name=g_new(gchar,strlen(output_devices[i].name)+1);
+    strcpy(active_receiver->audio_name,output_devices[i].name);
+  }
   if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
     if(audio_open_output(active_receiver)==0) {
       active_receiver->local_audio=1;
@@ -126,21 +132,30 @@ static void mute_radio_cb(GtkWidget *widget, gpointer data) {
 // call audo_close_output with old device, audio_open_output with new one
 //
 static void local_output_changed_cb(GtkWidget *widget, gpointer data) {
-  int newdev = (int)(long)data;
-  fprintf(stderr,"local_output_changed rx=%d from %d to %d\n",active_receiver->id,active_receiver->audio_device,newdev);
+  int i = GPOINTER_TO_INT(data);
+  fprintf(stderr,"local_output_changed rx=%d %s\n",active_receiver->id,output_devices[i].name);
   if(active_receiver->local_audio) {
     audio_close_output(active_receiver);                     // audio_close with OLD device
-    active_receiver->audio_device=newdev;                    // update rx to NEW device
-    if(audio_open_output(active_receiver)==0) {              // audio_open with NEW device
-      active_receiver->local_audio=1;
-    } else {
+  }
+    
+  if(active_receiver->audio_name!=NULL) {
+    g_free(active_receiver->audio_name);
+    active_receiver->audio_name=NULL;
+  }
+  
+  if(i>=0) {
+    active_receiver->audio_name=g_new(gchar,strlen(output_devices[i].name)+1);
+    strcpy(active_receiver->audio_name,output_devices[i].name);
+    //active_receiver->audio_device=output_devices[i].index;  // update rx to NEW device
+  }
+
+  if(active_receiver->local_audio) {
+    if(audio_open_output(active_receiver)<0) {              // audio_open with NEW device
       active_receiver->local_audio=0;
+      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (local_audio_b),FALSE);
     }
-    fprintf(stderr,"local_output_changed rx=%d local_audio=%d\n",active_receiver->id,active_receiver->local_audio);
-  } else {
-    // If not (currently) using local audio, just change dev num
-    active_receiver->audio_device=newdev;
   }
+  fprintf(stderr,"local_output_changed rx=%d local_audio=%d\n",active_receiver->id,active_receiver->local_audio);
 }
 
 static void audio_channel_cb(GtkWidget *widget, gpointer data) {
@@ -316,7 +331,7 @@ void rx_menu(GtkWidget *parent) {
 
   int row=0;
   if(n_output_devices>0) {
-    GtkWidget *local_audio_b=gtk_check_button_new_with_label("Local Audio Output");
+    local_audio_b=gtk_check_button_new_with_label("Local Audio Output");
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_audio_b), active_receiver->local_audio);
     gtk_widget_show(local_audio_b);
     gtk_grid_attach(GTK_GRID(grid),local_audio_b,x,++row,1,1);
@@ -324,13 +339,17 @@ void rx_menu(GtkWidget *parent) {
 
     if(active_receiver->audio_device==-1) active_receiver->audio_device=0;
 
-    GtkWidget *output=NULL;
+    output=NULL;
     for(i=0;i<n_output_devices;i++) {
-      output=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(output),output_devices[i]);
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output), active_receiver->audio_device==i);
+      output=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(output),output_devices[i].description);
+      if(active_receiver->audio_name!=NULL) {
+        if(strcmp(active_receiver->audio_name,output_devices[i].description)==0) {
+          gtk_combo_box_set_active(GTK_COMBO_BOX(output),i);
+        }
+      }
       gtk_widget_show(output);
       gtk_grid_attach(GTK_GRID(grid),output,x,++row,1,1);
-      g_signal_connect(output,"pressed",G_CALLBACK(local_output_changed_cb),(gpointer)(long)i);
+      g_signal_connect(output,"pressed",G_CALLBACK(local_output_changed_cb),GINT_TO_POINTER(i));
     }
 
     row=0;
index 7ba22ac71a50eb425dc6fc1d88c2f98cdb091b53..37e24bd9f473ae37b5ac3c29e41c51ae2b92873b 100644 (file)
@@ -387,6 +387,11 @@ void rx_panadapter_update(RECEIVER *rx) {
   samples[display_width-1]=-200.0;
   s1=(double)samples[0]+(double)adc_attenuation[rx->adc];
   if (filter_board == ALEX && rx->adc == 0) s1 += (double)(10*rx->alex_attenuation);
+#ifdef SOAPYSDR
+  if(protocol==SOAPYSDR_PROTOCOL) {
+    s1-=rx->rf_gain;
+  }
+#endif
 
   s1 = floor((rx->panadapter_high - s1)
                         * (double) display_height
@@ -395,6 +400,11 @@ void rx_panadapter_update(RECEIVER *rx) {
   for(i=1;i<display_width;i++) {
     s2=(double)samples[i]+(double)adc_attenuation[rx->adc];
     if (filter_board == ALEX && rx->adc == 0) s2 += (double)(10*rx->alex_attenuation);
+#ifdef SOAPYSDR
+    if(protocol==SOAPYSDR_PROTOCOL) {
+      s2-=rx->rf_gain;
+    }
+#endif
     s2 = floor((rx->panadapter_high - s2)
                             * (double) display_height
                             / (rx->panadapter_high - rx->panadapter_low));
index f6ffca5c2d4af7d0b75abb0a9f52de989509cb77..71e631168034dca12e95a8cd80a7576b71bc0611 100644 (file)
--- a/sliders.c
+++ b/sliders.c
@@ -44,6 +44,9 @@
 #include "band.h"
 #include "discovered.h"
 #include "new_protocol.h"
+#ifdef SOAPYSDR
+#include "soapy_protocol.h"
+#endif
 #include "vfo.h"
 #include "alex.h"
 #include "agc.h"
@@ -62,22 +65,25 @@ static GtkWidget *sliders;
 
 #define NONE 0
 #define AF_GAIN 1
-#define MIC_GAIN 2
-#define LINEIN_GAIN 3
-#define AGC_GAIN 4
-#define DRIVE 5
-#define ATTENUATION 6
-#define SQUELCH 7
-#define COMP 8
-#define FILTER_WIDTH 9
-#define DIVERSITY_GAIN 10
-#define DIVERSITY_PHASE 11
+#define RF_GAIN 2
+#define MIC_GAIN 3
+#define LINEIN_GAIN 4
+#define AGC_GAIN 5
+#define DRIVE 6
+#define ATTENUATION 7
+#define SQUELCH 8
+#define COMP 9
+#define FILTER_WIDTH 10
+#define DIVERSITY_GAIN 11
+#define DIVERSITY_PHASE 12
 
 static gint scale_timer;
 static int scale_status=NONE;
 static GtkWidget *scale_dialog;
 static GtkWidget *af_gain_label;
 static GtkWidget *af_gain_scale;
+static GtkWidget *rf_gain_label;
+static GtkWidget *rf_gain_scale;
 static GtkWidget *agc_gain_label;
 static GtkWidget *agc_scale;
 static GtkWidget *attenuation_label;
@@ -111,8 +117,8 @@ void sliders_update() {
         gtk_range_set_range(GTK_RANGE(mic_gain_scale),0.0,31.0);
         gtk_range_set_value (GTK_RANGE(mic_gain_scale),linein_gain);
       } else {
-        gtk_label_set_text(GTK_LABEL(mic_gain_label),"Mic (dB):");
-        gtk_range_set_range(GTK_RANGE(mic_gain_scale),-10.0,50.0);
+        gtk_label_set_text(GTK_LABEL(mic_gain_label),"Mic:");
+        gtk_range_set_range(GTK_RANGE(mic_gain_scale),-12.0,50.0);
         gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain);
       }
     }
@@ -368,6 +374,56 @@ void set_af_gain(int rx,double value) {
   }
 }
 
+static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
+    active_receiver->rf_gain=gtk_range_get_value(GTK_RANGE(af_gain_scale));
+#ifdef SOAPYSDR
+    if(protocol=SOAPYSDR_PROTOCOL) {
+      soapy_protocol_set_gain(active_receiver,active_receiver->rf_gain);
+    }
+#endif
+}
+
+void update_rf_gain() {
+  set_rf_gain(active_receiver->id,active_receiver->rf_gain);
+}
+
+void set_rf_gain(int rx,double value) {
+  receiver[rx]->rf_gain=value;
+#ifdef SOAPYSDR
+  if(protocol==SOAPYSDR_PROTOCOL) {
+    soapy_protocol_set_gain(active_receiver,active_receiver->rf_gain);
+  }
+#endif
+  if(display_sliders) {
+    gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+  } else {
+    if(scale_status!=RF_GAIN) {
+      if(scale_status!=NONE) {
+        g_source_remove(scale_timer);
+        gtk_widget_destroy(scale_dialog);
+        scale_status=NONE;
+      }
+    }
+    if(scale_status==NONE) {
+      scale_status=RF_GAIN;
+      scale_dialog=gtk_dialog_new_with_buttons("RF Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+      GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
+      rf_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
+      gtk_widget_set_size_request (rf_gain_scale, 400, 30);
+      gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+      gtk_widget_show(rf_gain_scale);
+      gtk_container_add(GTK_CONTAINER(content),rf_gain_scale);
+      scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
+      //gtk_widget_show_all(scale_dialog);
+      int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
+    } else {
+      g_source_remove(scale_timer);
+      gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+      scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
+    }
+  }
+}
+
 void set_filter_width(int rx,int width) {
     if(scale_status!=FILTER_WIDTH) {
       if(scale_status!=NONE) {
@@ -401,16 +457,14 @@ static void micgain_value_changed_cb(GtkWidget *widget, gpointer data) {
       linein_gain=(int)gtk_range_get_value(GTK_RANGE(widget));
     } else {
       mic_gain=gtk_range_get_value(GTK_RANGE(widget));
-      double gain=pow(10.0, mic_gain / 20.0);
-      SetTXAPanelGain1(transmitter->id,gain);
+      SetTXAPanelGain1(transmitter->id,pow(10.0, mic_gain/20.0));
     }
 }
 
 void set_mic_gain(double value) {
   if(can_transmit) {
     mic_gain=value;
-    double gain=pow(10.0, mic_gain / 20.0);
-    SetTXAPanelGain1(transmitter->id,gain);
+    SetTXAPanelGain1(transmitter->id,pow(10.0, mic_gain/20.0));
     if(display_sliders) {
       gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain);
     } else {
@@ -423,9 +477,9 @@ void set_mic_gain(double value) {
       }
       if(scale_status==NONE) {
         scale_status=MIC_GAIN;
-        scale_dialog=gtk_dialog_new_with_buttons("Mic Gain (dB)",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+        scale_dialog=gtk_dialog_new_with_buttons("Mic Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
         GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
-        mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-10.0, 50.0, 1.00);
+        mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-12.0, 50.0, 1.00);
         gtk_widget_set_size_request (mic_gain_scale, 400, 30);
         gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain);
         gtk_widget_show(mic_gain_scale);
@@ -759,11 +813,11 @@ fprintf(stderr,"sliders_init: width=%d height=%d\n", width,height);
 
   if(can_transmit) {
 
-    mic_gain_label=gtk_label_new(mic_linein?"Linein:":"Mic (dB):");
+    mic_gain_label=gtk_label_new(mic_linein?"Linein:":"Mic:");
     gtk_widget_override_font(mic_gain_label, pango_font_description_from_string("Sans 10"));
     gtk_grid_attach(GTK_GRID(sliders),mic_gain_label,0,1,1,1);
 
-    mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,mic_linein?0.0:-10.0,mic_linein?31.0:50.0, 1.0);
+    mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,mic_linein?0.0:1.0,mic_linein?31.0:100.0, 1.0);
     gtk_widget_override_font(mic_gain_scale, pango_font_description_from_string("Sans 10"));
     gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_linein?linein_gain:mic_gain);
     gtk_grid_attach(GTK_GRID(sliders),mic_gain_scale,1,1,2,1);
index 32fef862452fa54f0eb2dc829e57138284f50fae..bf93e7abd711df5ea342d8d557d2dc25eae85586 100644 (file)
--- a/sliders.h
+++ b/sliders.h
@@ -34,6 +34,7 @@ extern int update_tune_drive(void *);
 
 extern void set_agc_gain(int rx,double value);
 extern void set_af_gain(int rx,double value);
+extern void set_rf_gain(int rx,double value);
 extern void set_mic_gain(double value);
 extern void set_drive(double drive);
 //extern void set_tune(double tune);
index a556300f9576278aa9e1183e4121800b91b9d8cc..fdbaa41c23d5240ecb0cdde8c07ef358b9f1d39b 100644 (file)
@@ -64,7 +64,6 @@ static SoapySDRDevice *soapy_device;
 static SoapySDRStream *rx_stream;
 static SoapySDRStream *tx_stream;
 static int soapy_rx_sample_rate;
-static int soapy_tx_sample_rate;
 static int max_samples;
 
 static int samples=0;
@@ -163,12 +162,11 @@ fprintf(stderr,"soapy_protocol_start_receiver: create receive_thread\n");
 void soapy_protocol_create_transmitter(TRANSMITTER *tx) {
   int rc;
 
-  soapy_tx_sample_rate=tx->iq_output_rate;
 
-fprintf(stderr,"soapy_protocol_create_transmitter: setting samplerate=%f\n",(double)soapy_tx_sample_rate);
-  rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_TX,tx->dac,(double)soapy_tx_sample_rate);
+fprintf(stderr,"soapy_protocol_create_transmitter: setting samplerate=%f\n",(double)tx->iq_output_rate);
+  rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_TX,tx->dac,(double)tx->iq_output_rate);
   if(rc!=0) {
-    fprintf(stderr,"soapy_protocol_configure_transmitter: SoapySDRDevice_setSampleRate(%f) failed: %s\n",(double)soapy_tx_sample_rate,SoapySDR_errToStr(rc));
+    fprintf(stderr,"soapy_protocol_configure_transmitter: SoapySDRDevice_setSampleRate(%f) failed: %s\n",(double)tx->iq_output_rate,SoapySDR_errToStr(rc));
   }
 
   size_t channel=tx->dac;
@@ -354,21 +352,13 @@ fprintf(stderr,"soapy_protocol: receive_thread: SoapySDRDevice_unmake\n");
   //_exit(0);
 }
 
-void soapy_protocol_process_local_mic(unsigned char *buffer,int le) {
-  int b;
+void soapy_protocol_process_local_mic(float *buffer) {
   int i;
   short sample;
 
 // always 48000 samples per second
-  b=0;
   for(i=0;i<720;i++) {
-    if(le) {
-      sample = (short) (buffer[b++]&0xFF);
-      sample |= (short) (buffer[b++]<<8);
-    } else {
-      sample = (short)(buffer[b++]<<8);
-      sample |=  (short) (buffer[b++]&0xFF);
-    }
+    sample=(short)(buffer[i]*32767.0);
 #ifdef FREEDV
     if(active_receiver->freedv) {
       add_freedv_mic_sample(transmitter,sample);
@@ -386,11 +376,12 @@ void soapy_protocol_iq_samples(float isample,float qsample) {
   int flags=0;
   long long timeNs=0;
   long timeoutUs=100000L;
-  if(isTransmitting(radio)) {
+  if(isTransmitting()) {
     output_buffer[output_buffer_index++]=isample;
     output_buffer[output_buffer_index++]=qsample;
     if(output_buffer_index>=max_tx_samples) {
 // write the buffer
+//g_print("soapy_protocol_iq_samples: writeStream\n");
       int elements=SoapySDRDevice_writeStream(soapy_device,tx_stream,tx_buffs,max_tx_samples,&flags,timeNs,timeoutUs);
       if(elements!=max_tx_samples) {
         g_print("soapy_protocol_iq_samples: writeStream returned %d for %d elements\n",elements,max_tx_samples);
@@ -421,10 +412,14 @@ void soapy_protocol_set_rx_frequency(RECEIVER *rx,int v) {
 }
 
 void soapy_protocol_set_tx_frequency(TRANSMITTER *tx) {
-  int v=active_receiver->id;
+  int v;
   int rc;
   double f;
 
+  v=active_receiver->id;
+  if(split) {
+    v=active_receiver->id==0?1:0;
+  }
   if(soapy_device!=NULL) {
     //f=(double)(vfo[v].frequency+vfo[v].ctun_frequency-vfo[v].lo_tx);
     if(vfo[v].ctun) {
@@ -432,6 +427,12 @@ void soapy_protocol_set_tx_frequency(TRANSMITTER *tx) {
     } else {
       f=(double)(vfo[v].frequency-vfo[v].lo_tx);
     }
+
+    if(transmitter->xit_enabled) {
+      f+=(double)(transmitter->xit);
+    }
+
+       
 g_print("soapy_protocol_set_tx_frequency: %f\n",f);
     rc=SoapySDRDevice_setFrequency(soapy_device,SOAPY_SDR_TX,tx->dac,f,NULL);
     if(rc!=0) {
@@ -462,29 +463,52 @@ void soapy_protocol_set_tx_antenna(TRANSMITTER *tx,int ant) {
   }
 }
 
-void soapy_protocol_set_gain(RECEIVER *rx,char *name,int gain) {
+void soapy_protocol_set_gain(RECEIVER *rx,double gain) {
+  int rc;
+//fprintf(stderr,"soapy_protocol_set_gain: adc=%d gain=%f\n",gain);
+  rc=SoapySDRDevice_setGain(soapy_device,SOAPY_SDR_RX,rx->adc,gain);
+  if(rc!=0) {
+    fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain failed: %s\n",SoapySDR_errToStr(rc));
+  }
+}
+
+void soapy_protocol_set_gain_element(RECEIVER *rx,char *name,int gain) {
   int rc;
 //fprintf(stderr,"soapy_protocol_set_gain: adc=%d %s=%d\n",rx->adc,name,gain);
   rc=SoapySDRDevice_setGainElement(soapy_device,SOAPY_SDR_RX,rx->adc,name,(double)gain);
   if(rc!=0) {
-    fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain %s failed: %s\n",name,SoapySDR_errToStr(rc));
+    fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGainElement %s failed: %s\n",name,SoapySDR_errToStr(rc));
+  }
+}
+
+void soapy_protocol_set_tx_gain(TRANSMITTER *tx,int gain) {
+  int rc;
+  rc=SoapySDRDevice_setGain(soapy_device,SOAPY_SDR_TX,tx->dac,(double)gain);
+  if(rc!=0) {
+    fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain failed: %s\n",SoapySDR_errToStr(rc));
   }
 }
 
-void soapy_protocol_set_tx_gain(TRANSMITTER *tx,char *name,int gain) {
+void soapy_protocol_set_tx_gain_element(TRANSMITTER *tx,char *name,int gain) {
   int rc;
   rc=SoapySDRDevice_setGainElement(soapy_device,SOAPY_SDR_TX,tx->dac,name,(double)gain);
   if(rc!=0) {
-    fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain %s failed: %s\n",name,SoapySDR_errToStr(rc));
+    fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGainElement %s failed: %s\n",name,SoapySDR_errToStr(rc));
   }
 }
 
-int soapy_protocol_get_gain(RECEIVER *rx,char *name) {
+int soapy_protocol_get_gain_element(RECEIVER *rx,char *name) {
   double gain;
   gain=SoapySDRDevice_getGainElement(soapy_device,SOAPY_SDR_RX,rx->adc,name);
   return (int)gain;
 }
 
+int soapy_protocol_get_tx_gain_element(TRANSMITTER *tx,char *name) {
+  double gain;
+  gain=SoapySDRDevice_getGainElement(soapy_device,SOAPY_SDR_TX,tx->dac,name);
+  return (int)gain;
+}
+
 gboolean soapy_protocol_get_automatic_gain(RECEIVER *rx) {
   gboolean mode=SoapySDRDevice_getGainMode(soapy_device, SOAPY_SDR_RX, rx->adc);
   return mode;
index 39e6c96a2549028aca273949126a870c32665ec7..22b80a6b869c76162d3a33953de1001536b5a29b 100644 (file)
@@ -32,8 +32,9 @@ void soapy_protocol_stop();
 void soapy_protocol_set_rx_frequency(RECEIVER *rx,int v);
 void soapy_protocol_set_rx_antenna(RECEIVER *rx,int ant);
 void soapy_protocol_set_lna_gain(RECEIVER *rx,int gain);
-void soapy_protocol_set_gain(RECEIVER *rx,char *name,int gain);
-int soapy_protocol_get_gain(RECEIVER *rx,char *name);
+void soapy_protocol_set_gain(RECEIVER *rx,double gain);
+void soapy_protocol_set_gain_element(RECEIVER *rx,char *name,int gain);
+int soapy_protocol_get_gain_element(RECEIVER *rx,char *name);
 void soapy_protocol_change_sample_rate(RECEIVER *rx,int rate);
 gboolean soapy_protocol_get_automatic_gain(RECEIVER *rx);
 void soapy_protocol_set_automatic_gain(RECEIVER *rx,gboolean mode);
@@ -42,8 +43,10 @@ void soapy_protocol_start_transmitter(TRANSMITTER *tx);
 void soapy_protocol_stop_transmitter(TRANSMITTER *tx);
 void soapy_protocol_set_tx_frequency(TRANSMITTER *tx);
 void soapy_protocol_set_tx_antenna(TRANSMITTER *tx,int ant);
-void soapy_protocol_set_tx_gain(TRANSMITTER *tx,char *name,int gain);
-void soapy_protocol_process_local_mic(unsigned char *buffer,int le);
+void soapy_protocol_set_tx_gain(TRANSMITTER *tx,int gain);
+void soapy_protocol_set_tx_gain_element(TRANSMITTER *tx,char *name,int gain);
+int soapy_protocol_get_tx_gain_element(TRANSMITTER *tx,char *name);
+void soapy_protocol_process_local_mic(float *buffer);
 void soapy_protocol_iq_samples(float isample,float qsample);
 void soapy_protocol_set_mic_sample_rate(int rate);
 #endif
index fa210e1084bb8004a075fdd709668ec30a8d5284..4dbc037fc758691ed4f4cc2a9332113e1176eabd 100644 (file)
--- a/toolbar.c
+++ b/toolbar.c
@@ -78,12 +78,26 @@ static GdkRGBA gray;
 
 static gint rit_plus_timer=-1;
 static gint rit_minus_timer=-1;
+static gint xit_plus_timer=-1;
+static gint xit_minus_timer=-1;
 
 static gboolean rit_timer_cb(gpointer data) {
   int i=GPOINTER_TO_INT(data);
   vfo[active_receiver->id].rit+=(i*rit_increment);
-  if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000;
-  if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000;
+  if(vfo[active_receiver->id].rit>10000) vfo[active_receiver->id].rit=10000;
+  if(vfo[active_receiver->id].rit<-10000) vfo[active_receiver->id].rit=-10000;
+  if(protocol==NEW_PROTOCOL) {
+    schedule_high_priority();
+  }
+  g_idle_add(ext_vfo_update,NULL);
+  return TRUE;
+}
+
+static gboolean xit_timer_cb(gpointer data) {
+  int i=GPOINTER_TO_INT(data);
+  transmitter->xit+=(i*rit_increment);
+  if(transmitter->xit>10000) transmitter->xit=10000;
+  if(transmitter->xit<-10000) transmitter->xit=-10000;
   if(protocol==NEW_PROTOCOL) {
     schedule_high_priority();
   }
@@ -94,7 +108,11 @@ static gboolean rit_timer_cb(gpointer data) {
 void update_toolbar_labels() {
   switch(function) {
     case 0:
-      gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"");
+      }
       gtk_button_set_label(GTK_BUTTON(sim_s1),"Band");
       gtk_button_set_label(GTK_BUTTON(sim_s2),"BStack");
       gtk_button_set_label(GTK_BUTTON(sim_s3),"Mode");
@@ -104,38 +122,86 @@ void update_toolbar_labels() {
       set_button_text_color(sim_s1,"black");
       set_button_text_color(sim_s2,"black");
       break;
-
     case 1:
-      gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"");
+      }
       gtk_button_set_label(GTK_BUTTON(sim_s1),"Lock");
       gtk_button_set_label(GTK_BUTTON(sim_s2),"CTUN");
       gtk_button_set_label(GTK_BUTTON(sim_s3),"A>B");
       gtk_button_set_label(GTK_BUTTON(sim_s4),"A<B");
       gtk_button_set_label(GTK_BUTTON(sim_s5),"A<>B");
-      gtk_button_set_label(GTK_BUTTON(sim_s6),"Split");
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_s6),"Split");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_s6),"");
+      }
       break;
     case 2:
-      gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"");
+      }
       gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq");
       gtk_button_set_label(GTK_BUTTON(sim_s2),"Mem");
-      //gtk_button_set_label(GTK_BUTTON(sim_s3),"Vox");
       gtk_button_set_label(GTK_BUTTON(sim_s3),"RIT");
-
       gtk_button_set_label(GTK_BUTTON(sim_s4),"RIT+");
       gtk_button_set_label(GTK_BUTTON(sim_s5),"RIT-");
       gtk_button_set_label(GTK_BUTTON(sim_s6),"RIT CL");
-      if(full_tune) {
-        set_button_text_color(sim_s1,"red");
+      break;
+    case 3:
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"");
       }
-      if(memory_tune) {
-        set_button_text_color(sim_s2,"red");
+      gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq");
+      gtk_button_set_label(GTK_BUTTON(sim_s2),"Mem");
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_s3),"XIT");
+        gtk_button_set_label(GTK_BUTTON(sim_s4),"XIT+");
+        gtk_button_set_label(GTK_BUTTON(sim_s5),"XIT-");
+        gtk_button_set_label(GTK_BUTTON(sim_s6),"XIT CL");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_s3),"");
+        gtk_button_set_label(GTK_BUTTON(sim_s4),"");
+        gtk_button_set_label(GTK_BUTTON(sim_s5),"");
+        gtk_button_set_label(GTK_BUTTON(sim_s6),"");
       }
       break;
-    case 3:
-      gtk_button_set_label(GTK_BUTTON(sim_mox),"Tune");
-      if(OCtune!=0 && OCfull_tune_time!=0) {
-        gtk_button_set_label(GTK_BUTTON(sim_s1),"Full");
+    case 4:
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
       } else {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"");
+      }
+      gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq");
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_s2),"Split");
+        gtk_button_set_label(GTK_BUTTON(sim_s3),"Duplex");
+        gtk_button_set_label(GTK_BUTTON(sim_s4),"SAT");
+        gtk_button_set_label(GTK_BUTTON(sim_s5),"RSAT");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_s2),"");
+        gtk_button_set_label(GTK_BUTTON(sim_s3),"");
+        gtk_button_set_label(GTK_BUTTON(sim_s4),"");
+        gtk_button_set_label(GTK_BUTTON(sim_s5),"");
+      }
+      gtk_button_set_label(GTK_BUTTON(sim_s6),"");
+      break;
+    case 5:
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"Tune");
+        if(OCtune!=0 && OCfull_tune_time!=0) {
+          gtk_button_set_label(GTK_BUTTON(sim_s1),"Full");
+        } else {
+          gtk_button_set_label(GTK_BUTTON(sim_s1),"");
+        }
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_mox),"");
         gtk_button_set_label(GTK_BUTTON(sim_s1),"");
       }
       if(OCtune!=0 && OCmemory_tune_time!=0) {
@@ -146,7 +212,11 @@ void update_toolbar_labels() {
       gtk_button_set_label(GTK_BUTTON(sim_s3),"Band");
       gtk_button_set_label(GTK_BUTTON(sim_s4),"Mode");
       gtk_button_set_label(GTK_BUTTON(sim_s5),"Filter");
-      gtk_button_set_label(GTK_BUTTON(sim_s6),"Mox");
+      if(can_transmit) {
+        gtk_button_set_label(GTK_BUTTON(sim_s6),"Mox");
+      } else {
+        gtk_button_set_label(GTK_BUTTON(sim_s6),"");
+      }
       if(full_tune) {
         set_button_text_color(sim_s1,"red");
       }
@@ -210,13 +280,44 @@ static void aswapb_cb (GtkWidget *widget, gpointer data) {
 }
 
 static void split_cb (GtkWidget *widget, gpointer data) {
-  split=split==1?0:1;
-  if(split) {
-    tx_set_mode(transmitter,vfo[VFO_B].mode);
-  } else {
-    tx_set_mode(transmitter,vfo[VFO_A].mode);
+  if(can_transmit) {
+    split=split==1?0:1;
+    if(split) {
+      tx_set_mode(transmitter,vfo[VFO_B].mode);
+    } else {
+      tx_set_mode(transmitter,vfo[VFO_A].mode);
+    }
+    g_idle_add(ext_vfo_update,NULL);
+  }
+}
+
+static void duplex_cb (GtkWidget *widget, gpointer data) {
+  if(can_transmit) {
+    duplex=duplex==1?0:1;
+    g_idle_add(ext_vfo_update,NULL);
+  }
+}
+
+static void sat_cb (GtkWidget *widget, gpointer data) {
+  if(can_transmit) {
+    if(sat_mode==SAT_MODE) {
+      sat_mode=SAT_NONE;
+    } else {
+      sat_mode=SAT_MODE;
+    }
+    g_idle_add(ext_vfo_update,NULL);
+  }
+}
+
+static void rsat_cb (GtkWidget *widget, gpointer data) {
+  if(can_transmit) {
+    if(sat_mode==RSAT_MODE) {
+      sat_mode=SAT_NONE;
+    } else {
+      sat_mode=RSAT_MODE;
+    }
+    g_idle_add(ext_vfo_update,NULL);
   }
-  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void rit_enable_cb(GtkWidget *widget, gpointer data) {
@@ -230,8 +331,8 @@ static void rit_enable_cb(GtkWidget *widget, gpointer data) {
 static void rit_cb(GtkWidget *widget, gpointer data) {
   int i=GPOINTER_TO_INT(data);
   vfo[active_receiver->id].rit+=i*rit_increment;
-  if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000;
-  if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000;
+  if(vfo[active_receiver->id].rit>10000) vfo[active_receiver->id].rit=10000;
+  if(vfo[active_receiver->id].rit<-10000) vfo[active_receiver->id].rit=-10000;
   if(protocol==NEW_PROTOCOL) {
     schedule_high_priority();
   }
@@ -248,6 +349,41 @@ static void rit_clear_cb(GtkWidget *widget, gpointer data) {
   g_idle_add(ext_vfo_update,NULL);
 }
 
+static void xit_enable_cb(GtkWidget *widget, gpointer data) {
+  if(can_transmit) {
+    transmitter->xit_enabled=transmitter->xit_enabled==1?0:1;
+    if(protocol==NEW_PROTOCOL) {
+      schedule_high_priority();
+    }
+    g_idle_add(ext_vfo_update,NULL);
+  }
+}
+
+static void xit_cb(GtkWidget *widget, gpointer data) {
+  if(can_transmit) {
+    int i=GPOINTER_TO_INT(data);
+    transmitter->xit+=i*rit_increment;
+    if(transmitter->xit>10000) transmitter->xit=10000;
+    if(transmitter->xit<-10000) transmitter->xit=-10000;
+    if(protocol==NEW_PROTOCOL) {
+      schedule_high_priority();
+    }
+    g_idle_add(ext_vfo_update,NULL);
+    if(i<0) {
+      xit_minus_timer=g_timeout_add(200,xit_timer_cb,(gpointer)(long)i);
+    } else {
+      xit_plus_timer=g_timeout_add(200,xit_timer_cb,(gpointer)(long)i);
+    }
+  }
+}
+
+static void xit_clear_cb(GtkWidget *widget, gpointer data) {
+  if(can_transmit) {
+    transmitter->xit=0;
+    g_idle_add(ext_vfo_update,NULL);
+  }
+}
+
 static void freq_cb(GtkWidget *widget, gpointer data) {
   start_vfo();
 }
@@ -409,6 +545,12 @@ void sim_s1_pressed_cb(GtkWidget *widget, gpointer data) {
       freq_cb(widget,data);
       break;
     case 3:
+      freq_cb(widget,data);
+      break;
+    case 4:
+      freq_cb(widget,data);
+      break;
+    case 5:
       full_tune=full_tune==1?0:1;
       if(full_tune) {
         set_button_text_color(sim_s2,"black");
@@ -430,6 +572,10 @@ void sim_s1_released_cb(GtkWidget *widget, gpointer data) {
       break;
     case 3:
       break;
+    case 4:
+      break;
+    case 5:
+      break;
   }
 }
 
@@ -445,6 +591,12 @@ void sim_s2_pressed_cb(GtkWidget *widget, gpointer data) {
       mem_cb(widget,data);
       break;
     case 3:
+      mem_cb(widget,data);
+      break;
+    case 4:
+      split_cb(widget,data);
+      break;
+    case 5:
       memory_tune=memory_tune==1?0:1;
       if(memory_tune) {
         set_button_text_color(sim_s1,"black");
@@ -466,6 +618,10 @@ void sim_s2_released_cb(GtkWidget *widget, gpointer data) {
       break;
     case 3:
       break;
+    case 4:
+      break;
+    case 5:
+      break;
   }
 }
 
@@ -480,10 +636,15 @@ void sim_s3_pressed_cb(GtkWidget *widget, gpointer data) {
       atob_cb(widget,data);
       break;
     case 2:
-      //vox_cb(widget,data);
       rit_enable_cb(widget,data);
       break;
     case 3:
+      xit_enable_cb(widget,data);
+      break;
+    case 4:
+      duplex_cb(widget,data);
+      break;
+    case 5:
       band_cb(widget,data);
       break;
   }
@@ -499,6 +660,10 @@ void sim_s3_released_cb(GtkWidget *widget, gpointer data) {
       break;
     case 3:
       break;
+    case 4:
+      break;
+    case 5:
+      break;
   }
 }
 
@@ -517,6 +682,14 @@ void sim_s4_pressed_cb(GtkWidget *widget, gpointer data) {
       }
       break;
     case 3:
+      if(xit_minus_timer==-1 && xit_plus_timer==-1) {
+        xit_cb(widget,(void *)1);
+      }
+      break;
+    case 4:
+      sat_cb(widget,data);
+      break;
+    case 5:
       mode_cb(widget,data);
       break;
   }
@@ -535,6 +708,14 @@ void sim_s4_released_cb(GtkWidget *widget, gpointer data) {
       }
       break;
     case 3:
+      if(xit_plus_timer!=-1) {
+        g_source_remove(xit_plus_timer);
+        xit_plus_timer=-1;
+      }
+      break;
+    case 4:
+      break;
+    case 5:
       break;
   }
 }
@@ -554,6 +735,14 @@ void sim_s5_pressed_cb(GtkWidget *widget, gpointer data) {
       }
       break;
     case 3:
+      if(xit_minus_timer==-1 && xit_plus_timer==-1) {
+        xit_cb(widget,(void *)-1);
+      }
+      break;
+    case 4:
+      rsat_cb(widget,data);
+      break;
+    case 5:
       filter_cb(widget,data);
       break;
   }
@@ -572,6 +761,14 @@ void sim_s5_released_cb(GtkWidget *widget, gpointer data) {
       }
       break;
     case 3:
+      if(xit_minus_timer!=-1) {
+        g_source_remove(xit_minus_timer);
+        xit_minus_timer=-1;
+      }
+      break;
+    case 4:
+      break;
+    case 5:
       break;
   }
 }
@@ -588,6 +785,11 @@ void sim_s6_pressed_cb(GtkWidget *widget, gpointer data) {
       rit_clear_cb(widget,NULL);
       break;
     case 3:
+      xit_clear_cb(widget,NULL);
+      break;
+    case 4:
+      break;
+    case 5:
       break;
   }
 }
@@ -601,7 +803,10 @@ void sim_s6_released_cb(GtkWidget *widget, gpointer data) {
     case 2:
       break;
     case 3:
-      mox_cb((GtkWidget *)NULL, (gpointer)NULL);
+      break;
+    case 4:
+      break;
+    case 5:
       break;
   }
 }
@@ -611,9 +816,11 @@ void sim_mox_cb(GtkWidget *widget, gpointer data) {
     case 0:
     case 1:
     case 2:
+    case 3:
+    case 4:
       mox_cb((GtkWidget *)NULL, (gpointer)NULL);
       break;
-    case 3:
+    case 5:
       tune_cb((GtkWidget *)NULL, (gpointer)NULL);
       break;
   }
index 19b1adfca2e2c9559ff4bc8247958c7e41160b23..5a1b8879783cb419a0b82ae981cf0e84af8281f6 100644 (file)
--- a/toolbar.h
+++ b/toolbar.h
@@ -20,7 +20,7 @@
 #ifndef _TOOLBAR_H
 #define _TOOLBAR_H
 
-#define MAX_FUNCTION 3
+#define MAX_FUNCTION 5
 
 extern int function;
 
index a79f5a758d5363d46f800d182ecf59b2010c182c..7a44d4ffca856f2aa7e747aac7644c1357b0dfb2 100644 (file)
@@ -169,10 +169,11 @@ void transmitter_save_state(TRANSMITTER *tx) {
   sprintf(name,"transmitter.%d.local_microphone",tx->id);
   sprintf(value,"%d",tx->local_microphone);
   setProperty(name,value);
-  sprintf(name,"transmitter.%d.input_device",tx->id);
-  sprintf(value,"%d",tx->input_device);
-  setProperty(name,value);
-
+  if(tx->microphone_name!=NULL) {
+    sprintf(name,"transmitter.%d.microphone_name",tx->id);
+    sprintf(value,"%s",tx->microphone_name);
+    setProperty(name,value);
+  }
   sprintf(name,"transmitter.%d.low_latency",tx->id);
   sprintf(value,"%d",tx->low_latency);
   setProperty(name,value);
@@ -230,6 +231,12 @@ void transmitter_save_state(TRANSMITTER *tx) {
   sprintf(name,"transmitter.%d.compressor_level",tx->id);
   sprintf(value,"%f",tx->compressor_level);
   setProperty(name,value);
+  sprintf(name,"transmitter.%d.xit_enabled",tx->id);
+  sprintf(value,"%d",tx->xit_enabled);
+  setProperty(name,value);
+  sprintf(name,"transmitter.%d.xit",tx->id);
+  sprintf(value,"%lld",tx->xit);
+  setProperty(name,value);
 }
 
 void transmitter_restore_state(TRANSMITTER *tx) {
@@ -259,9 +266,12 @@ void transmitter_restore_state(TRANSMITTER *tx) {
   sprintf(name,"transmitter.%d.local_microphone",tx->id);
   value=getProperty(name);
   if(value) tx->local_microphone=atoi(value);
-  sprintf(name,"transmitter.%d.input_device",tx->id);
+  sprintf(name,"transmitter.%d.microphone_name",tx->id);
   value=getProperty(name);
-  if(value) tx->input_device=atoi(value);
+  if(value) {
+    tx->microphone_name=g_new(gchar,strlen(value)+1);
+    strcpy(tx->microphone_name,value);
+  }
   sprintf(name,"transmitter.%d.low_latency",tx->id);
   value=getProperty(name);
   if(value) tx->low_latency=atoi(value);
@@ -317,6 +327,12 @@ void transmitter_restore_state(TRANSMITTER *tx) {
   sprintf(name,"transmitter.%d.compressor_level",tx->id);
   value=getProperty(name);
   if(value) tx->compressor_level=atof(value);
+  sprintf(name,"transmitter.%d.xit_enabled",tx->id);
+  value=getProperty(name);
+  if(value) tx->xit_enabled=atoi(value);
+  sprintf(name,"transmitter.%d.xit",tx->id);
+  value=getProperty(name);
+  if(value) tx->xit=atoll(value);
 }
 
 static gboolean update_display(gpointer data) {
@@ -574,9 +590,15 @@ TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps,
       tx->mic_sample_rate=48000;
       tx->mic_dsp_rate=96000;
       tx->iq_output_rate=radio_sample_rate;
-      tx->buffer_size=1024;
-      tx->output_samples=1024*(tx->iq_output_rate/tx->mic_sample_rate);
-      tx->pixels=width*8; // to allow 384k to 24k conversion
+      tx->output_samples=tx->buffer_size*(tx->iq_output_rate/tx->mic_sample_rate);
+      tx->pixels=width*(tx->iq_output_rate/tx->mic_sample_rate);
+/*
+      tx->mic_sample_rate=48000;
+      tx->mic_dsp_rate=48000;
+      tx->iq_output_rate=48000;
+      tx->output_samples=tx->buffer_size;
+      tx->pixels=width; // to allow 48k to 24k conversion
+*/
       break;
 #endif
 
@@ -594,7 +616,7 @@ TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps,
   
   tx->alex_antenna=ALEX_TX_ANTENNA_1;
 
-fprintf(stderr,"create_transmitter: id=%d buffer_size=%d mic_sample_rate=%d mic_dsp_rate=%d iq_output_rate=%d output_samples=%d fps=%d\n",tx->id, tx->buffer_size, tx->mic_sample_rate, tx->mic_dsp_rate, tx->iq_output_rate, tx->output_samples,tx->fps);
+fprintf(stderr,"create_transmitter: id=%d buffer_size=%d mic_sample_rate=%d mic_dsp_rate=%d iq_output_rate=%d output_samples=%d fps=%d width=%d height=%d\n",tx->id, tx->buffer_size, tx->mic_sample_rate, tx->mic_dsp_rate, tx->iq_output_rate, tx->output_samples,tx->fps,tx->width,tx->height);
 
   tx->filter_low=tx_filter_low;
   tx->filter_high=tx_filter_high;
@@ -629,6 +651,10 @@ fprintf(stderr,"create_transmitter: id=%d buffer_size=%d mic_sample_rate=%d mic_
   tx->compressor_level=0.0;
 
   tx->local_microphone=0;
+  tx->microphone_name=NULL;
+
+  tx->xit_enabled=FALSE;
+  tx->xit=0LL;
 
   transmitter_restore_state(tx);
 
@@ -716,8 +742,7 @@ fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%p iq_output_buf
   SetTXAPostGenToneFreq(tx->id, 0.0);
   SetTXAPostGenRun(tx->id, 0);
 
-  double gain=pow(10.0, mic_gain / 20.0);
-  SetTXAPanelGain1(tx->id,gain);
+  SetTXAPanelGain1(tx->id,pow(10.0, mic_gain/20.0));
   SetTXAPanelRun(tx->id, 1);
 
   SetTXAFMDeviation(tx->id, (double)tx->deviation);
@@ -755,7 +780,9 @@ void tx_set_filter(TRANSMITTER *tx,int low,int high) {
   } else {
     mode=vfo[0].mode;
   }
-//fprintf(stderr,"tx_set_filter: tx=%p mode=%d low=%d high=%d\n",tx,mode,low,high);
+
+fprintf(stderr,"tx_set_filter: tx=%p mode=%s low=%d high=%d\n",tx,mode_string[mode],low,high);
+
   switch(mode) {
     case modeLSB:
     case modeCWL:
@@ -793,6 +820,7 @@ void tx_set_filter(TRANSMITTER *tx,int low,int high) {
   double fl=tx->filter_low;
   double fh=tx->filter_high;
 
+/*
   if(split) {
     fl+=vfo[VFO_B].offset;
     fh+=vfo[VFO_B].offset;
@@ -800,6 +828,7 @@ void tx_set_filter(TRANSMITTER *tx,int low,int high) {
     fl+=vfo[VFO_A].offset;
     fh+=vfo[VFO_A].offset;
   }
+*/
   SetTXABandpassFreqs(tx->id, fl,fh);
 }
 
@@ -958,8 +987,14 @@ static void full_tx_buffer(TRANSMITTER *tx) {
        // Original code without pulse shaping and without side tone
        //
        for(j=0;j<tx->output_samples;j++) {
-           double is=tx->iq_output_buffer[j*2];
-           double qs=tx->iq_output_buffer[(j*2)+1];
+            double is,qs;
+            if(iqswap) {
+             qs=tx->iq_output_buffer[j*2];
+             qs=tx->iq_output_buffer[(j*2)+1];
+            } else {
+             is=tx->iq_output_buffer[j*2];
+             qs=tx->iq_output_buffer[(j*2)+1];
+            }
            isample=is>=0.0?(long)floor(is*gain+0.5):(long)ceil(is*gain-0.5);
            qsample=qs>=0.0?(long)floor(qs*gain+0.5):(long)ceil(qs*gain-0.5);
            switch(protocol) {
@@ -971,7 +1006,7 @@ static void full_tx_buffer(TRANSMITTER *tx) {
                    break;
 #ifdef SOAPYSDR
                 case SOAPYSDR_PROTOCOL:
-                    soapy_protocol_iq_samples((float)tx->iq_output_buffer[j*2],(float)tx->iq_output_buffer[(j*2)+1]);
+                    soapy_protocol_iq_samples((float)isample,(float)qsample);
                     break;
 #endif
            }
index 388682423bc7fc634c904bd474008f903bd1d9c5..83c15a38d459f0fe8915bc353294e6384126351f 100644 (file)
@@ -49,12 +49,6 @@ typedef struct _transmitter {
   int filter_low;
   int filter_high;
 
-/*
-  long long frequency;
-  long long display_frequency;
-  long long dds_frequency;
-  long long dds_offset;
-*/
   int alex_antenna;
 
   int width;
@@ -69,7 +63,7 @@ typedef struct _transmitter {
   cairo_surface_t *panadapter_surface;
 
   int local_microphone;
-  int input_device;
+  gchar *microphone_name;
 
   int out_of_band;
   gint out_of_band_timer_id;
@@ -111,6 +105,9 @@ typedef struct _transmitter {
   double rev;
   double alc;
 
+  gint xit_enabled;
+  long long xit;
+  
   int x;
   int y;
 
index 760eb10b866e2a1f03f46a205c8fb07bbc27b616..2528754249fe0541331a9e0ea788bc0b80f7d24e 100644 (file)
--- a/tx_menu.c
+++ b/tx_menu.c
 #include "ext.h"
 
 static GtkWidget *parent_window=NULL;
-
 static GtkWidget *dialog=NULL;
-
 static GtkWidget *last_filter;
-
+static GtkWidget *input;
 static GtkWidget *micin_b=NULL;
 static GtkWidget *linein_b=NULL;
 static GtkWidget *micboost_b=NULL;
@@ -114,6 +112,11 @@ static void tune_percent_cb (GtkWidget *widget, gpointer data) {
 
 static void local_microphone_cb(GtkWidget *widget, gpointer data) {
   if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
+    if(transmitter->microphone_name==NULL) {
+      int i=gtk_combo_box_get_active(GTK_COMBO_BOX(input));
+      transmitter->microphone_name=g_new(gchar,strlen(input_devices[i].name)+1);
+      strcpy(transmitter->microphone_name,input_devices[i].name);
+    }
     if(audio_open_input()==0) {
       transmitter->local_microphone=1;
       if(micin_b!=NULL) gtk_widget_hide(micin_b);
@@ -148,12 +151,20 @@ static void linein_changed(GtkWidget *widget, gpointer data) {
 }
 
 static void local_input_changed_cb(GtkWidget *widget, gpointer data) {
-  transmitter->input_device=(int)(long)data;
+  int i=GPOINTER_TO_INT(data);
   if(transmitter->local_microphone) {
     audio_close_input();
-    if(audio_open_input()==0) {
-      transmitter->local_microphone=1;
-    } else {
+  }
+
+  if(transmitter->microphone_name!=NULL) {
+    g_free(transmitter->microphone_name);
+  }
+
+  transmitter->microphone_name=g_new(gchar,strlen(input_devices[i].name)+1);
+  strcpy(transmitter->microphone_name,input_devices[i].name);
+
+  if(transmitter->local_microphone) {
+    if(audio_open_input()<0) {
       transmitter->local_microphone=0;
     }
   }
@@ -233,22 +244,24 @@ void tx_menu(GtkWidget *parent) {
     row++;
     col=0;
 
-    GtkWidget *comp_enable=gtk_check_button_new_with_label("Compression (dB):");
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_enable), transmitter->compressor);
-    gtk_grid_attach(GTK_GRID(grid),comp_enable,col,row,1,1);
-    g_signal_connect(comp_enable,"toggled",G_CALLBACK(comp_enable_cb),NULL);
+  }
 
-    col++;
 
-    GtkWidget *comp=gtk_spin_button_new_with_range(0.0,20.0,1.0);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(comp),(double)transmitter->compressor_level);
-    gtk_grid_attach(GTK_GRID(grid),comp,col,row,1,1);
-    g_signal_connect(comp,"value-changed",G_CALLBACK(comp_cb),NULL);
+  GtkWidget *comp_enable=gtk_check_button_new_with_label("Compression (dB):");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_enable), transmitter->compressor);
+  gtk_grid_attach(GTK_GRID(grid),comp_enable,col,row,1,1);
+  g_signal_connect(comp_enable,"toggled",G_CALLBACK(comp_enable_cb),NULL);
 
-    row++;
-    col=0;
+  col++;
+
+  GtkWidget *comp=gtk_spin_button_new_with_range(0.0,20.0,1.0);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(comp),(double)transmitter->compressor_level);
+  gtk_grid_attach(GTK_GRID(grid),comp,col,row,1,1);
+  g_signal_connect(comp,"value-changed",G_CALLBACK(comp_cb),NULL);
+
+  row++;
+  col=0;
 
-  }
 
   if(n_input_devices>0) {
     GtkWidget *local_microphone_b=gtk_check_button_new_with_label("Local Microphone Input");
@@ -257,14 +270,14 @@ void tx_menu(GtkWidget *parent) {
     gtk_grid_attach(GTK_GRID(grid),local_microphone_b,col,row++,2,1);
     g_signal_connect(local_microphone_b,"toggled",G_CALLBACK(local_microphone_cb),NULL);
 
-    if(transmitter->input_device==-1) {
-      transmitter->input_device=0;
-    }
-
-    GtkWidget *input=NULL;
+    input=NULL;
     for(i=0;i<n_input_devices;i++) {
-      input=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(input),input_devices[i]);
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (input), transmitter->input_device==i);
+      input=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(input),input_devices[i].description);
+      if(transmitter->microphone_name!=NULL) {
+        if(strcmp(transmitter->microphone_name,input_devices[i].description)==0) {
+          gtk_combo_box_set_active(GTK_COMBO_BOX(input),i);
+        }
+      }
       gtk_widget_show(input);
       gtk_grid_attach(GTK_GRID(grid),input,col,row++,2,1);
       g_signal_connect(input,"pressed",G_CALLBACK(local_input_changed_cb),(gpointer)(long)i);
@@ -325,7 +338,7 @@ void tx_menu(GtkWidget *parent) {
 
   col++;
 
-  GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
+  GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-400.0,100.0,1.0);
   gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)transmitter->panadapter_low);
   gtk_widget_show(panadapter_low_r);
   gtk_grid_attach(GTK_GRID(grid),panadapter_low_r,col,row,1,1);
index efa8a84e6c0655b6263553fafa8a10d7300d323d..e78ea10d898011cb083bcc94da49871669c16225 100644 (file)
@@ -62,6 +62,7 @@ tx_panadapter_configure_event_cb (GtkWidget         *widget,
   int display_width=gtk_widget_get_allocated_width (tx->panadapter);
   int display_height=gtk_widget_get_allocated_height (tx->panadapter);
 
+g_print("tx_panadapter_configure_event_cb: width=%d height=%d\n",display_width,display_height);
   if (tx->panadapter_surface)
     cairo_surface_destroy (tx->panadapter_surface);
 
@@ -251,7 +252,12 @@ void tx_panadapter_update(TRANSMITTER *tx) {
   //long long half=12000LL; //(long long)(tx->output_rate/2);
   long long half=24000LL; //(long long)(tx->output_rate/2);
   long long frequency;
-  frequency=vfo[id].frequency+vfo[id].offset;
+  //frequency=vfo[id].frequency+vfo[id].offset;
+  if(vfo[id].ctun) {
+    frequency=vfo[id].ctun_frequency-vfo[id].lo_tx;
+  } else {
+    frequency=vfo[id].frequency-vfo[id].lo_tx;
+  }
   double vfofreq=(double)display_width * 0.5;
   if (!cw_is_on_vfo_freq) {
     if(vfo[id].mode==modeCWU) {
@@ -315,8 +321,10 @@ void tx_panadapter_update(TRANSMITTER *tx) {
   cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
   cairo_set_line_width(cr, 1.0);
 //fprintf(stderr,"cursor: x=%f\n",(double)(display_width/2.0)+(vfo[tx->id].offset/hz_per_pixel));
-  cairo_move_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),0.0);
-  cairo_line_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),(double)display_height);
+  //cairo_move_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),0.0);
+  //cairo_line_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),(double)display_height);
+  cairo_move_to(cr,vfofreq,0.0);
+  cairo_line_to(cr,vfofreq,(double)display_height);
   cairo_stroke(cr);
 
   // signal
@@ -328,13 +336,16 @@ void tx_panadapter_update(TRANSMITTER *tx) {
 
   switch(protocol) {
     case ORIGINAL_PROTOCOL:
-      //offset=(tx->pixels/4)*1;
       offset=0;
       break;
     case NEW_PROTOCOL:
-      //offset=(tx->pixels/16)*7;
       offset=(tx->pixels/8)*3;
       break;
+#ifdef SOAPYSDR
+    case SOAPYSDR_PROTOCOL:
+      offset=(tx->pixels/16)*7;
+      break;
+#endif
   }
 
   s1=(double)samples[0+offset];
index 06ccee09efd4349cd595a9920ea706b0474f8ec6..b81b88f97deec7b46685eb51d901e0dc99fdfba6 100644 (file)
--- a/version.c
+++ b/version.c
@@ -21,11 +21,11 @@ char build_date[]=GIT_DATE;
 char build_version[]=GIT_VERSION;
 
 #if defined (CONTROLLER2_V1)
-char version[]="2.0.0 (Controller2 V1)";
+char version[]="2.0.1 (Controller2 V1)";
 #elif defined (CONTROLLER2_V2)
-char version[]="2.0.0 (Controller2 V2)";
+char version[]="2.0.1 (Controller2 V2)";
 #elif defined (GPIO)
-char version[]="2.0.0 (Controller1)";
+char version[]="2.0.1 (Controller1)";
 #else
-char version[]="2.0.0";
+char version[]="2.0.1";
 #endif
diff --git a/vfo.c b/vfo.c
index 006c4e4d23e65796571d918ba51c0cf556b5676f..9097885a29f5aa268b2eeaae650f9656785a754b 100644 (file)
--- a/vfo.c
+++ b/vfo.c
@@ -291,6 +291,8 @@ void vfo_band_changed(int b) {
   vfo[id].lo=band->frequencyLO+band->errorLO;
   vfo[id].lo_tx=band->txFrequencyLO+band->txErrorLO;
 
+  // turn off ctun
+  vfo[id].ctun=0;
 
   switch(id) {
     case 0:
@@ -550,6 +552,29 @@ void vfo_step(int steps) {
     } else {
       vfo[id].frequency=vfo[id].frequency+(steps*step);
     }
+
+    int sid=id==0?1:0;
+    switch(sat_mode) {
+      case SAT_NONE:
+        break;
+      case SAT_MODE:
+        // A and B increment and decrement together
+        if(vfo[sid].ctun) {
+          vfo[sid].ctun_frequency=vfo[sid].ctun_frequency+(steps*step);
+        } else {
+          vfo[sid].frequency=vfo[sid].frequency+(steps*step);
+        }
+        break;
+      case RSAT_MODE:
+        // A increments and B decrements or A decrments and B increments
+        if(vfo[sid].ctun) {
+          vfo[sid].ctun_frequency=vfo[sid].ctun_frequency-(steps*step);
+        } else {
+          vfo[sid].frequency=vfo[sid].frequency-(steps*step);
+        }
+        break;
+    }
+
     receiver_frequency_changed(active_receiver);
 #ifdef INCLUDED
     BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
@@ -561,20 +586,31 @@ void vfo_step(int steps) {
 
 void vfo_move(long long hz) {
   int id=active_receiver->id;
+g_print("vfo_move: id=%d hz=%lld\n",id,hz);
   if(!locked) {
-    switch(protocol) {
-/*
-#ifdef SOAPYSDR
-      case SOAPYSDR_PROTOCOL:
-        vfo[id].ctun_frequency=((vfo[id].ctun_frequency-hz)/step)*step;
+    if(vfo[id].ctun) {
+      vfo[id].ctun_frequency=((vfo[id].ctun_frequency+hz)/step)*step;
+    } else {
+      vfo[id].frequency=((vfo[id].frequency+hz)/step)*step;
+    }
+    int sid=id==0?1:0;
+    switch(sat_mode) {
+      case SAT_NONE:
         break;
-#endif
-*/
-      default:
-        if(vfo[id].ctun) {
-          vfo[id].ctun_frequency=((vfo[id].ctun_frequency-hz)/step)*step;
+      case SAT_MODE:
+        // A and B increment and decrement together
+        if(vfo[sid].ctun) {
+          vfo[sid].ctun_frequency=((vfo[sid].ctun_frequency+hz)/step)*step;
         } else {
-          vfo[id].frequency=((vfo[id].frequency+hz)/step)*step;
+          vfo[sid].frequency=((vfo[sid].frequency+hz)/step)*step;
+        }
+        break;
+      case RSAT_MODE:
+        // A increments and B decrements or A decrments and B increments
+        if(vfo[sid].ctun) {
+          vfo[sid].ctun_frequency=((vfo[sid].ctun_frequency-hz)/step)*step;
+        } else {
+          vfo[sid].frequency=((vfo[sid].frequency-hz)/step)*step;
         }
         break;
     }
@@ -584,27 +620,64 @@ void vfo_move(long long hz) {
 }
 
 void vfo_move_to(long long hz) {
+  // hz is the offset from the min frequency
   int id=active_receiver->id;
+  long long offset=(hz/step)*step;
+  long long half=(long long)(active_receiver->sample_rate/2);
+  long long f=vfo[id].frequency-half+offset;
+  long long diff; 
+
+g_print("vfo_move_to: id=%d hz=%lld f=%lld\n",id,hz,f);
+
   if(!locked) {
-    switch(protocol) {
-      default:
-        if(vfo[id].ctun) {
-          vfo[id].ctun_frequency=(vfo[id].frequency+hz)/step*step;
-          if(vfo[id].mode==modeCWL) {
-            vfo[id].ctun_frequency+=cw_keyer_sidetone_frequency;
-          } else if(vfo[id].mode==modeCWU) {
-            vfo[id].ctun_frequency-=cw_keyer_sidetone_frequency;
-          }
+    if(vfo[id].ctun) {
+      diff=f-vfo[id].ctun_frequency;
+      vfo[id].ctun_frequency=f;
+      if(vfo[id].mode==modeCWL) {
+        vfo[id].ctun_frequency+=cw_keyer_sidetone_frequency;
+      } else if(vfo[id].mode==modeCWU) {
+        vfo[id].ctun_frequency-=cw_keyer_sidetone_frequency;
+      }
+g_print("vfo_move_to: vfo=%d ctun_frequency=%lld diff=%lld\n",id,vfo[id].ctun_frequency,diff);
+    } else {
+      diff=f-vfo[id].frequency;
+      vfo[id].frequency=f;
+      if(vfo[id].mode==modeCWL) {
+        vfo[id].frequency+=cw_keyer_sidetone_frequency;
+      } else if(vfo[id].mode==modeCWU) {
+        vfo[id].frequency-=cw_keyer_sidetone_frequency;
+      }
+g_print("vfo_move_to: vfo=%d frequency=%lld diff==%%ld\n",id,vfo[id].frequency,diff);
+    }
+
+    int sid=id==0?1:0;
+    switch(sat_mode) {
+      case SAT_NONE:
+        break;
+      case SAT_MODE:
+        f=vfo[sid].frequency-half+offset;
+        // A and B increment and decrement together
+        if(vfo[sid].ctun) {
+          vfo[sid].ctun_frequency+=diff;
+g_print("vfo_move_to: SAT vfo=%d ctun_frequency=%lld\n",sid,vfo[sid].ctun_frequency);
         } else {
-          vfo[id].frequency=(vfo[id].frequency+hz)/step*step;
-          if(vfo[id].mode==modeCWL) {
-            vfo[id].frequency+=cw_keyer_sidetone_frequency;
-          } else if(vfo[id].mode==modeCWU) {
-            vfo[id].frequency-=cw_keyer_sidetone_frequency;
-          }
+          vfo[sid].frequency+=diff;
+g_print("vfo_move_to: SAT vfo=%d frequency=%lld\n",sid,vfo[sid].frequency);
+        }
+        break;
+      case RSAT_MODE:
+        f=vfo[sid].frequency+half-offset;
+        // A increments and B decrements or A decrements and B increments
+        if(vfo[sid].ctun) {
+          vfo[sid].ctun_frequency-=diff;
+g_print("vfo_move_to: RSAT vfo=%d ctun_frequency=%lld\n",sid,vfo[sid].ctun_frequency);
+        } else {
+          vfo[sid].frequency-=diff;
+g_print("vfo_move_to: RSAT vfo=%d frequency=%lld\n",sid,vfo[sid].frequency);
         }
         break;
     }
+
     receiver_vfo_changed(active_receiver);
 
 #ifdef INCLUDED
@@ -745,7 +818,21 @@ void vfo_update() {
        // id == 1, split == 1 : TX freq = VFO_A
 
 
-        long long af=vfo[0].frequency+vfo[0].offset;
+        long long af;
+        if(isTransmitting() && !split) {
+          if(vfo[0].ctun) {
+            af=(double)(vfo[0].ctun_frequency-vfo[0].lo_tx);
+          } else {
+            af=(double)(vfo[0].frequency-vfo[0].lo_tx);
+          }
+        } else {
+          if(vfo[0].ctun) {
+            af=(double)(vfo[0].ctun_frequency);
+          } else {
+            af=(double)(vfo[0].frequency);
+          }
+        }
+
         sprintf(temp_text,"VFO A: %0lld.%06lld",af/(long long)1000000,af%(long long)1000000);
         if(isTransmitting() && ((id  == 0 && !split) || (id == 1 && split))) {
            if (transmitter->out_of_band) sprintf(temp_text,"VFO A: Out of band");
@@ -762,7 +849,20 @@ void vfo_update() {
         cairo_show_text(cr, temp_text);
 
 
-        long long bf=vfo[1].frequency+vfo[1].offset;
+        long long bf;
+        if(isTransmitting() && split) {
+          if(vfo[1].ctun) {
+            bf=(double)(vfo[1].ctun_frequency-vfo[1].lo_tx);
+          } else {
+            bf=(double)(vfo[1].frequency-vfo[1].lo_tx);
+          }
+        } else {
+          if(vfo[1].ctun) {
+            bf=(double)(vfo[1].ctun_frequency);
+          } else {
+            bf=(double)(vfo[1].frequency);
+          }
+        }
         sprintf(temp_text,"VFO B: %0lld.%06lld",bf/(long long)1000000,bf%(long long)1000000);
         if(isTransmitting() && ((id == 0 && split) || (id == 1 && !split))) {
            if (transmitter->out_of_band) sprintf(temp_text,"VFO B: Out of band");
@@ -774,23 +874,50 @@ void vfo_update() {
               cairo_set_source_rgb(cr, 0.0, 0.65, 0.0);
             }
         }
-        cairo_move_to(cr, 260, 38);  
+        cairo_move_to(cr, 270, 38);  
         cairo_show_text(cr, temp_text);
 
+#ifdef PURESIGNAL
+        if(can_transmit) {
+          cairo_move_to(cr, 180, 15);
+          if(transmitter->puresignal) {
+            cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+          } else {
+            cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+          }
+          cairo_set_font_size(cr, 12);
+          cairo_show_text(cr, "PS");
+        }
+#endif
+
+
         if(vfo[id].rit_enabled==0) {
             cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
         } else {
-            cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+            cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
         }
-        sprintf(temp_text,"RIT: %lld Hz",vfo[id].rit);
+        sprintf(temp_text,"RIT: %lldHz",vfo[id].rit);
         cairo_move_to(cr, 210, 15);
         cairo_set_font_size(cr, 12);
         cairo_show_text(cr, temp_text);
 
+
+        if(can_transmit) {
+          if(transmitter->xit_enabled==0) {
+              cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+          } else {
+              cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+          }
+          sprintf(temp_text,"XIT: %lldHz",transmitter->xit);
+          cairo_move_to(cr, 310, 15);
+          cairo_set_font_size(cr, 12);
+          cairo_show_text(cr, temp_text);
+        }
+
        // NB and NB2 are mutually exclusive, therefore
        // they are put to the same place in order to save
        // some space
-        cairo_move_to(cr, 150, 50);
+        cairo_move_to(cr, 155, 50);
         if(active_receiver->nb) {
           cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
           cairo_show_text(cr, "NB");
@@ -831,7 +958,8 @@ void vfo_update() {
         }
         cairo_show_text(cr, "SNB");
 
-        cairo_move_to(cr, 300, 50);  
+        //cairo_move_to(cr, 300, 50);  
+        cairo_move_to(cr, 270, 50);  
         switch(active_receiver->agc) {
           case AGC_OFF:
             cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
@@ -860,7 +988,8 @@ void vfo_update() {
        // we should display the compressor (level)
        //
         if(can_transmit) {
-          cairo_move_to(cr, 400, 50);  
+          //cairo_move_to(cr, 400, 50);  
+          cairo_move_to(cr, 330, 50);  
          if (transmitter->compressor) {
              sprintf(temp_text,"CMPR %d dB",(int) transmitter->compressor_level);
               cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
@@ -884,7 +1013,8 @@ void vfo_update() {
           s++;
         }
         sprintf(temp_text,"Step %s",step_labels[s]);
-        cairo_move_to(cr, 300, 15);
+        //cairo_move_to(cr, 300, 15);
+        cairo_move_to(cr, 400, 15);
         cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
         cairo_show_text(cr, temp_text);
 
@@ -894,7 +1024,8 @@ void vfo_update() {
         cairo_show_text(cr, getFrequencyInfo(af));
 */
          
-        cairo_move_to(cr, 400, 15);  
+        //cairo_move_to(cr, 400, 15);  
+        cairo_move_to(cr, 430, 50);  
         if(vfo[id].ctun) {
           cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
         } else {
@@ -902,7 +1033,8 @@ void vfo_update() {
         }
         cairo_show_text(cr, "CTUN");
 
-        cairo_move_to(cr, 450, 15);  
+        //cairo_move_to(cr, 450, 15);  
+        cairo_move_to(cr, 470, 50);  
         if(cat_control>0) {
           cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
         } else {
@@ -934,19 +1066,28 @@ void vfo_update() {
         }
         cairo_show_text(cr, "Split");
 
-#ifdef PURESIGNAL
-        if(can_transmit) {
-          cairo_move_to(cr, 105, 50);
-          if(transmitter->puresignal) {
-            cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
-          } else {
-            cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
-          }
-          cairo_show_text(cr, "PS");
+        cairo_move_to(cr, 95, 50);
+        if(sat_mode!=SAT_NONE) {
+          cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+        } else {
+          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+        }
+        if(sat_mode==SAT_NONE || sat_mode==SAT_MODE) {
+          cairo_show_text(cr, "SAT");
+        } else {
+          cairo_show_text(cr, "RSAT");
         }
-#endif
 
 
+        if(duplex) {
+            cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+        } else {
+            cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+        }
+        sprintf(temp_text,"DUP");
+        cairo_move_to(cr, 130, 50);
+        cairo_set_font_size(cr, 12);
+        cairo_show_text(cr, temp_text);
 
         cairo_destroy (cr);
         gtk_widget_queue_draw (vfo_panel);
diff --git a/vfo.h b/vfo.h
index c2218851e23eca3e2617e8ef6f77c1d5d97d638a..310e35c91576c39c1f3df52a21870c67293f0215 100644 (file)
--- a/vfo.h
+++ b/vfo.h
@@ -37,6 +37,7 @@ struct _vfo {
 
   int ctun;
   long long ctun_frequency;
+
   int rit_enabled;
   long long rit;
 
index 0e5b1dab23d3e243dac4bcfad65d5e11b2b29e9c..3f5da0dc92f7198ff17b2322a26167930c96f5a2 100644 (file)
@@ -325,10 +325,12 @@ void vfo_menu(GtkWidget *parent) {
 #endif
 
 #ifdef PURESIGNAL
-  GtkWidget *enable_ps=gtk_check_button_new_with_label("Enable Pure Signal");
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_ps), transmitter->puresignal);
-  gtk_grid_attach(GTK_GRID(grid),enable_ps,3,7,1,1);
-  g_signal_connect(enable_ps,"toggled",G_CALLBACK(enable_ps_cb),NULL);
+  if(can_transmit) {
+    GtkWidget *enable_ps=gtk_check_button_new_with_label("Enable Pure Signal");
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_ps), transmitter->puresignal);
+    gtk_grid_attach(GTK_GRID(grid),enable_ps,3,7,1,1);
+    g_signal_connect(enable_ps,"toggled",G_CALLBACK(enable_ps_cb),NULL);
+  }
 #endif
 
   gtk_container_add(GTK_CONTAINER(content),grid);
index d8258183d00856adc1d3c9a5179c2014e2b47ef8..5d5534a4aa227042cd444d0e834759ed66433db9 100644 (file)
@@ -96,10 +96,10 @@ void update_receiver(int band,gboolean error) {
   int i;
   RECEIVER *rx=active_receiver;
   gboolean saved_ctun;
-g_print("update_receiver: band=%d error=%d\n",band,error);
+//g_print("update_receiver: band=%d error=%d\n",band,error);
   if(vfo[0].band==band) {
     BAND *xvtr=band_get_band(band);
-g_print("update_receiver: found band: %s\n",xvtr->title);
+//g_print("update_receiver: found band: %s\n",xvtr->title);
     vfo[0].lo=xvtr->frequencyLO+xvtr->errorLO;
     vfo[0].lo_tx=xvtr->txFrequencyLO+xvtr->txErrorLO;
     saved_ctun=vfo[0].ctun;