]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Updated actions. Handle CW MIDI input early (no actions).
authorJohn Melton G0ORX <john.d.melton@googlemail.com>
Thu, 5 Aug 2021 16:09:24 +0000 (17:09 +0100)
committerJohn Melton G0ORX <john.d.melton@googlemail.com>
Thu, 5 Aug 2021 16:09:24 +0000 (17:09 +0100)
18 files changed:
Makefile
action_dialog.c
actions.c
css.c
encoder_menu.c
main.c
meter.c
midi3.c
midi_menu.c
new_protocol.c
old_protocol.c
pulseaudio.c
radio.c
radio.h
radio_menu.c
switch_menu.c
toolbar_menu.c
vfo.c

index 177adafda514d3627661677bb9f094529ee02e80..8f12050ecc67924f94cf9d272591cd95a7bca69e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ PURESIGNAL_INCLUDE=PURESIGNAL
 # USBOZY_INCLUDE=USBOZY
 
 # uncomment the line to below include support local CW keyer
-#LOCALCW_INCLUDE=LOCALCW
+LOCALCW_INCLUDE=LOCALCW
 
 # uncomment the line below for SoapySDR
 #SOAPYSDR_INCLUDE=SOAPYSDR
index a60fd71eee5170fa418e9c0cd813c216887d2aa3..f60063d685ced1b704e991c2f0d997a32bf81629 100644 (file)
@@ -7,6 +7,7 @@ typedef struct _choice {
   int action;
   GtkWidget *button;
   gulong signal_id;
+  struct _choice *previous;
 } CHOICE;
 
 static GtkWidget *dialog;
@@ -26,6 +27,8 @@ static void action_select_cb(GtkWidget *widget,gpointer data) {
 
 int action_dialog(GtkWidget *parent,int filter,int currentAction) {
   int i,j;
+  CHOICE *previous=NULL;
+  CHOICE *choice=NULL;
 
   action=currentAction;
   previous_button=NULL;
@@ -44,15 +47,18 @@ int action_dialog(GtkWidget *parent,int filter,int currentAction) {
   for(i=0;i<ACTIONS;i++) {
     if((ActionTable[i].type&filter) || (ActionTable[i].type==TYPE_NONE)) {
       GtkWidget *button=gtk_toggle_button_new_with_label(ActionTable[i].str);
-      gtk_widget_set_name(button,"small_button");
+      gtk_widget_set_name(button,"small_toggle_button");
       gtk_grid_attach(GTK_GRID(grid),button,j%GRID_WIDTH,j/GRID_WIDTH,1,1);
       if(ActionTable[i].action==currentAction) {
         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),TRUE);
       }
-      CHOICE *choice=g_new0(CHOICE,1);
+      choice=g_new0(CHOICE,1);
       choice->action=i;
       choice->button=button;
       choice->signal_id=g_signal_connect(button,"toggled",G_CALLBACK(action_select_cb),choice);
+      choice->previous=previous;
+      previous=choice;
+
       if(ActionTable[i].action==currentAction) {
         previous_button=button;
         previous_signal_id=choice->signal_id;
@@ -68,6 +74,12 @@ int action_dialog(GtkWidget *parent,int filter,int currentAction) {
   if(result!=GTK_RESPONSE_ACCEPT) {
     action=currentAction;
   }
+  // free up choice structures
+  while(previous!=NULL) {
+    choice=previous;
+    previous=choice->previous;
+    g_free(choice);
+  }
   return action;
 }
 
index b2a2e7e70cbf842c0ca1c8284badd76872dc71f6..1e73ac21547bedf329e2f6044ff4b6350951bc48 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -182,6 +182,21 @@ ACTION_TABLE ActionTable[] = {
   {ACTIONS,            "",                     NULL,           TYPE_NONE}
 };
 
+static gint timer=0;
+static gboolean timer_released;
+
+static int timeout_cb(gpointer data) {
+  if(timer_released) {
+    g_free(data);
+    timer=0;
+    return FALSE;
+  }
+  // process the action;
+  process_action(data);
+  return TRUE;
+}
+
+
 
 int process_action(void *data) {
   PROCESS_ACTION *a=(PROCESS_ACTION *)data;
@@ -193,8 +208,9 @@ int process_action(void *data) {
   FILTER *filter;
   int new_val;
   int i;
+  gboolean free_action=TRUE;
 
-  g_print("%s: action=%d mode=%d value=%d\n",__FUNCTION__,a->action,a->mode,a->val);
+  //g_print("%s: action=%d mode=%d value=%d\n",__FUNCTION__,a->action,a->mode,a->val);
   switch(a->action) {
 
     case A_SWAP_B:
@@ -955,11 +971,25 @@ int process_action(void *data) {
     case RIT_MINUS:
       if(a->mode==PRESSED) {
         vfo_rit(active_receiver->id,-1);
+       if(timer==0) {
+         timer=g_timeout_add(250,timeout_cb,a);
+         timer_released=FALSE;
+       }
+       free_action=FALSE;
+      } else {
+       timer_released=TRUE;
       }
       break;
     case RIT_PLUS:
       if(a->mode==PRESSED) {
         vfo_rit(active_receiver->id,1);
+       if(timer==0) {
+         timer=g_timeout_add(250,timeout_cb,a);
+         timer_released=FALSE;
+       }
+       free_action=FALSE;
+      } else {
+       timer_released=TRUE;
       }
       break;
     case RIT_RX1:
@@ -1192,6 +1222,7 @@ int process_action(void *data) {
         value=10000.0;
       }
       transmitter->xit=(int)value;
+      transmitter->xit_enabled=(value!=0);
       if(protocol==NEW_PROTOCOL) {
         schedule_high_priority();
       }
@@ -1201,6 +1232,10 @@ int process_action(void *data) {
       if(a->mode==PRESSED) {
         if(can_transmit) {
           transmitter->xit=0;
+          transmitter->xit_enabled=0;
+          if(protocol==NEW_PROTOCOL) {
+            schedule_high_priority();
+          }
           g_idle_add(ext_vfo_update, NULL);
         }
       }
@@ -1227,6 +1262,7 @@ int process_action(void *data) {
             value=10000.0;
           }
           transmitter->xit=(int)value;
+         transmitter->xit_enabled=(value!=0);
           if(protocol==NEW_PROTOCOL) {
             schedule_high_priority();
           }
@@ -1245,6 +1281,7 @@ int process_action(void *data) {
             value=10000.0;
           }
           transmitter->xit=(int)value;
+         transmitter->xit_enabled=(value!=0);
           if(protocol==NEW_PROTOCOL) {
             schedule_high_priority();
           }
@@ -1274,7 +1311,9 @@ int process_action(void *data) {
       }
       break;
   }
-  g_free(data);
+  if(free_action) {
+    g_free(data);
+  }
   return 0;
 }
 
diff --git a/css.c b/css.c
index 810492ca70e5d6ef9254584e0ed4093b627b60f5..16bfd7b309186c0b212a8477372ec5798b81485a 100644 (file)
--- a/css.c
+++ b/css.c
@@ -2,11 +2,28 @@
 #include "css.h"
 
 char *css=
+"  @define-color TOGGLE_ON rgb(100%,0%,0%);\n"
+"  @define-color TOGGLE_OFF rgb(70%,70%,70%);\n"
 "  #small_button {\n"
 "    padding: 0;\n"
 "    font-family: Sans;\n"
 "    font-size: 15px;\n"
 "    }\n"
+"  #small_toggle_button {\n"
+"    padding: 0;\n"
+"    font-family: Sans;\n"
+"    font-size: 15px;\n"
+"    background-image: none;\n"
+"    background-color: @TOGGLE_OFF;\n"
+"    }\n"
+"  #small_toggle_button:checked {\n"
+"    padding: 0;\n"
+"    font-family: Sans;\n"
+"    font-size: 15px;\n"
+"    background-image: none;\n"
+"    background-color: @TOGGLE_ON;\n"
+"    }\n"
+
 ;
 
 void load_css() {
index 933be4b6bfb5a1271d914ab1ca4cd4aba20c9024..66b6b2fa2bc64925d19dc6e5744af6928d4e4196 100644 (file)
 #include "gpio.h"
 #include "i2c.h"
 
-typedef struct _choice {
-  int id;
-  int action;
-  GtkWidget *initial_button;
-  GtkWidget *button;
-  gulong signal_id;
-} CHOICE;
-
 static GtkWidget *parent_window=NULL;
 
 static GtkWidget *dialog=NULL;
@@ -101,7 +93,7 @@ void encoder_menu(GtkWidget *parent) {
   dialog=gtk_dialog_new();
   gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent));
   //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
-  char title[32];
+  char title[64];
   switch(controller) {
     case NO_CONTROLLER:
       sprintf(title,"piHPSDR - No Encoders");
diff --git a/main.c b/main.c
index 903f4501ffb56e710413a295f3958e4909c70d5e..def2e87f5208cfc7e07a408b4dbb3386655a51d2 100644 (file)
--- a/main.c
+++ b/main.c
@@ -199,7 +199,7 @@ static int init(void *data) {
   char *c=getcwd(wisdom_directory, sizeof(wisdom_directory));
   strcpy(&wisdom_directory[strlen(wisdom_directory)],"/");
   fprintf(stderr,"Securing wisdom file in directory: %s\n", wisdom_directory);
-  status_text("Creating FFTW Wisdom file ...");
+  status_text("Checking FFTW Wisdom file ...");
   wisdom_running=1;
   pthread_create(&wisdom_thread_id, NULL, wisdom_thread, wisdom_directory);
   while (wisdom_running) {
@@ -209,6 +209,7 @@ static int init(void *data) {
       while (gtk_events_pending ()) {
         gtk_main_iteration ();
       }
+      status_text("Creating FFTW Wisdom file ...");
   }
 
   g_idle_add(ext_discovery,NULL);
diff --git a/meter.c b/meter.c
index fd481764bfeea4e1ceb4181cd8975134c733d6af..f36d6c0c7bf533edaa62dc893ac334737eeed2d2 100644 (file)
--- a/meter.c
+++ b/meter.c
@@ -446,7 +446,9 @@ if(analog_meter) {
 
       double swr;
       if (max_level > reverse) {
-        swr=(max_level+reverse)/(max_level-reverse);
+        //swr=(max_level+reverse)/(max_level-reverse);
+       // fix fhanks to JW1TWP
+       swr=(1+sqrt(max_level/reverse))/(1-sqrt(max_level/reverse));
       } else {
         swr=999.9;
       }
diff --git a/midi3.c b/midi3.c
index f2f0e7b37ac4103055aa8f60473a25f65fad6378..06aad2a1ca39271212df3732d6de4de180fbdd44 100644 (file)
--- a/midi3.c
+++ b/midi3.c
@@ -35,18 +35,22 @@ void DoTheMidi(int action, enum ACTIONtype type, int val) {
     int    *ip;
     PROCESS_ACTION *a;
 
-    //
-    // Handle cases in alphabetical order of the key words in midi.props
-    //
-
-    g_print("%s: action=%d type=%d val=%d\n",__FUNCTION__,action,type,val);
+    //g_print("%s: action=%d type=%d val=%d\n",__FUNCTION__,action,type,val);
 
     switch(type) {
       case MIDI_KEY:
-        a=g_new(PROCESS_ACTION,1);
-        a->action=action;
-        a->mode=val?PRESSED:RELEASED;
-        g_idle_add(process_action,a);
+       if(action==CW_LEFT || action==CW_RIGHT) {
+#ifdef LOCALCW
+          keyer_event(action==CW_LEFT,val);
+#else
+          g_print("MIDI CW key but compiled without LOCALCW\n");
+#endif
+        } else {
+          a=g_new(PROCESS_ACTION,1);
+          a->action=action;
+          a->mode=val?PRESSED:RELEASED;
+          g_idle_add(process_action,a);
+       }
        break;
       case MIDI_KNOB:
         a=g_new(PROCESS_ACTION,1);
@@ -63,1046 +67,4 @@ void DoTheMidi(int action, enum ACTIONtype type, int val) {
         g_idle_add(process_action,a);
         break;
     }
-
-/*
-    switch (action) {
-       /////////////////////////////////////////////////////////// "A2B"
-       case A_TO_B: // only key supported
-           if (type == MIDI_KEY) {
-             a=g_new(PROCESS_ACTION,1);
-              a->action=A_TO_B;
-              a->mode=PRESSED;
-              g_idle_add(process_action,a);
-             //g_idle_add(ext_vfo_a_to_b, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "AFGAIN"
-       case AF_GAIN: // knob or wheel supported
-            switch (type) {
-             case MIDI_KNOB:
-               a=g_new(PROCESS_ACTION,1);
-                a->action=AF_GAIN;
-                a->mode=ABSOLUTE;
-                a->val=val;
-                g_idle_add(process_action,a);
-               break;
-             case MIDI_WHEEL:  
-               a=g_new(PROCESS_ACTION,1);
-                a->action=AF_GAIN;
-                a->mode=RELATIVE;
-                a->val=val;
-                g_idle_add(process_action,a);
-               break;
-             default:
-               // do not change volume
-               // we should not come here anyway
-               break;
-           }
-           g_idle_add(ext_update_af_gain, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "AGCATTACK"
-       case AGC: // only key supported
-           // cycle through fast/med/slow AGC attack
-           if (type == MIDI_KEY) {
-             a=g_new(PROCESS_ACTION,1);
-              a->action=AGC;
-              a->mode=PRESSED;
-              g_idle_add(process_action,a);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "AGCVAL"
-       case AGC_GAIN: // knob or wheel supported
-           switch (type) {
-             case MIDI_KNOB:
-               a=g_new(PROCESS_ACTION,1);
-                a->action=AGC_GAIN;
-                a->mode=ABSOLUTE;
-                a->val=val;
-                g_idle_add(process_action,a);
-               //dnew = -20.0 + 1.4*val;
-               break;
-             case MIDI_WHEEL:
-               a=g_new(PROCESS_ACTION,1);
-                a->action=AGC_GAIN;
-                a->mode=RELATIVE;
-                a->val=val;
-                g_idle_add(process_action,a);
-               //dnew=active_receiver->agc_gain + val;
-               //if (dnew < -20.0) dnew=-20.0; if (dnew > 120.0) dnew=120.0;
-               break;
-             default:
-               // do not change value
-               // we should not come here anyway
-               //dnew=active_receiver->agc_gain;
-               break;
-           }
-           //dp=malloc(sizeof(double));
-           //*dp=dnew;
-           //g_idle_add(ext_set_agc_gain, (gpointer) dp);
-           break;
-       /////////////////////////////////////////////////////////// "ANF"
-       case ANF:       // only key supported
-           if (type == MIDI_KEY) {
-             a=g_new(PROCESS_ACTION,1);
-              a->action=ANF;
-              a->mode=PRESSED;
-              g_idle_add(process_action,a);
-             //g_idle_add(ext_anf_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "ATT"
-       case ATTENUATION:       // Key for ALEX attenuator, wheel or knob for slider
-           switch(type) {
-             case MIDI_KEY:
-               if (filter_board == ALEX && active_receiver->adc == 0) {
-                 new=active_receiver->alex_attenuation + 1;
-                 if (new > 3) new=0;
-                 g_idle_add(ext_set_alex_attenuation, GINT_TO_POINTER(new));
-                 g_idle_add(ext_update_att_preamp, NULL);
-               }
-               break;
-             case MIDI_WHEEL:
-               new=adc[active_receiver->adc].attenuation + val;
-               dp=malloc(sizeof(double));
-               *dp=(double) new;
-                if(have_rx_gain) {
-                  if(*dp<-12.0) {
-                    *dp=-12.0;
-                  } else if(*dp>48.0) {
-                    *dp=48.0;
-                  }
-                } else {
-                  if(*dp<0.0) {
-                    *dp=0.0;
-                  } else if (*dp>31.0) {
-                    *dp=31.0;
-                  }
-                }
-               g_idle_add(ext_set_attenuation_value,(gpointer) dp);
-               break;
-             case MIDI_KNOB:
-               dp=malloc(sizeof(double));
-                if (have_rx_gain) {
-                 *dp=-12.0 + 0.6*(double) val;
-                } else {
-                  *dp = 0.31 * (double) val;
-                }
-               g_idle_add(ext_set_attenuation_value,(gpointer) dp);
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-           break;
-       /////////////////////////////////////////////////////////// "B2A"
-       case B_TO_A: // only key supported
-           if (type == MIDI_KEY) {
-             a=g_new(PROCESS_ACTION,1);
-              a->action=B_TO_A;
-              a->mode=PRESSED;
-              g_idle_add(process_action,a);
-             //g_idle_add(ext_vfo_b_to_a, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "NUMPADxx"
-       case NUMPAD_0:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(0));
-            break;
-       case NUMPAD_1:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(1));
-            break;
-       case NUMPAD_2:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(2));
-            break;
-       case NUMPAD_3:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(3));
-            break;
-       case NUMPAD_4:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(4));
-            break;
-       case NUMPAD_5:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(5));
-            break;
-       case NUMPAD_6:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(6));
-            break;
-       case NUMPAD_7:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(7));
-            break;
-       case NUMPAD_8:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(8));
-            break;
-       case NUMPAD_9:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(9));
-            break;
-       case NUMPAD_CL:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(-1));
-            break;
-       case NUMPAD_ENTER:
-           g_idle_add(ext_num_pad,GINT_TO_POINTER(-2));
-            break;
-           break;
-
-       /////////////////////////////////////////////////////////// "BANDxxx"
-        case BAND_10:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band10));
-            }
-            break;
-        case BAND_12:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band12));
-            }
-            break;
-#ifdef SOAPYSDR
-        case BAND_1240:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band1240));
-            }
-            break;
-        case BAND_144:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band144));
-            }
-            break;
-#endif
-        case BAND_15:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band15));
-            }
-            break;
-        case BAND_160:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band160));
-            }
-            break;
-        case BAND_17:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band17));
-            }
-            break;
-        case BAND_20:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band20));
-            }
-            break;
-#ifdef SOAPYSDR
-        case BAND_220:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band220));
-            }
-            break;
-        case BAND_2300:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band2300));
-            }
-            break;
-#endif
-        case BAND_30:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band30));
-            }
-            break;
-#ifdef SOAPYSDR
-        case BAND_3400:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band3400));
-            }
-            break;
-        case BAND_70:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band70));
-            }
-            break;
-#endif
-        case BAND_40:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band40));
-            }
-            break;
-#ifdef SOAPYSDR
-        case BAND_430:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band430));
-            }
-            break;
-#endif
-        case BAND_6:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band6));
-            }
-            break;
-        case BAND_60:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band60));
-            }
-            break;
-        case BAND_80:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band80));
-            }
-            break;
-#ifdef SOAPYSDR
-        case BAND_902:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(band902));
-            }
-            break;
-        case BAND_AIR:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(bandAIR));
-            }
-            break;
-#endif
-        case BAND_GEN:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(bandGen));
-            }
-            break;
-        case BAND_WWV:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_band_select, GINT_TO_POINTER(bandWWV));
-            }
-            break;
-       /////////////////////////////////////////////////////////// "BANDDOWN"
-       /////////////////////////////////////////////////////////// "BANDUP"
-       case BAND_MINUS:
-       case BAND_PLUS:
-           switch (type) {
-             case MIDI_KEY:
-               new=(action == BAND_PLUS) ? 1 : -1;
-               break;
-             case MIDI_WHEEL:
-               new=val > 0 ? 1 : -1;
-               break;
-             case MIDI_KNOB:
-               // cycle through the bands
-               new = ((BANDS-1) * val) / 100 - vfo[active_receiver->id].band;
-               break;
-             default:
-               // do not change
-               // we should not come here anyway
-               new=0;
-               break;
-           }
-           //
-           // If the band has not changed, do nothing. Otherwise
-           // vfo.c will loop through the band stacks
-           //
-           if (new != 0) {
-             new+=vfo[active_receiver->id].band;
-             if (new >= BANDS) new=0;
-             if (new < 0) new=BANDS-1;
-             g_idle_add(ext_vfo_band_changed, GINT_TO_POINTER(new));
-           }
-           break;
-       /////////////////////////////////////////////////////////// "COMPRESSION"
-       case COMPRESSION: // wheel or knob
-           switch (type) {
-             case MIDI_WHEEL:
-               dnew=transmitter->compressor_level + val;
-               if (dnew > 20.0) dnew=20.0;
-               if (dnew < 0 ) dnew=0;
-               break;
-             case MIDI_KNOB:
-               dnew=(20.0*val)/100.0;
-               break;
-             default:
-               // do not change
-               // we should not come here anyway
-               dnew=transmitter->compressor_level;
-               break;
-           }
-           transmitter->compressor_level=dnew;
-           // automatically engange compressor if level > 0.5
-           if (dnew < 0.5) transmitter->compressor=0;
-           if (dnew > 0.5) transmitter->compressor=1;
-           g_idle_add(ext_set_compression, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "CTUN"
-       case CTUN: // only key supported
-           // toggle CTUN
-           if (type == MIDI_KEY) {
-             g_idle_add(ext_ctun_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "CURRVFO"
-       case VFO: // only wheel supported
-           if (type == MIDI_WHEEL && !locked) {
-               g_idle_add(ext_vfo_step, GINT_TO_POINTER(val));
-           }
-           break;
-       /////////////////////////////////////////////////////////// "CWL"
-       /////////////////////////////////////////////////////////// "CWR"
-       case CW_LEFT: // only key
-       case CW_RIGHT: // only key
-#ifdef LOCALCW
-           if (type == MIDI_KEY) {
-               new=(action == CW_LEFT);
-               keyer_event(new,val);
-           }
-#else
-           g_print("%s: %s:%d\n",__FUNCTION__,action==CW_LEFT?"CWL":"CWR",val);
-
-#endif
-           break;
-       /////////////////////////////////////////////////////////// "CWSPEED"
-       case CW_SPEED: // knob or wheel
-            switch (type) {
-              case MIDI_KNOB:
-               // speed between 5 and 35 wpm
-                new= (int) (5.0 + (double) val * 0.3);
-                break;
-              case MIDI_WHEEL:
-               // here we allow from 1 to 60 wpm
-                new = cw_keyer_speed + val;
-               if (new <  1) new=1;
-               if (new > 60) new=60;
-                break;
-              default:
-                // do not change
-                // we should not come here anyway
-                new = cw_keyer_speed;
-                break;
-            }
-           cw_keyer_speed=new;
-#ifdef LOCALCW
-           keyer_update();
-#endif
-            g_idle_add(ext_vfo_update, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "DIVCOARSEGAIN"
-       case DIV_GAIN_COARSE:  // knob or wheel supported
-       case DIV_GAIN_FINE:    // knob or wheel supported
-       case DIV_GAIN:        // knob or wheel supported
-            switch (type) {
-              case MIDI_KNOB:
-                if (action == DIV_GAIN_COARSE || action == DIV_GAIN) {
-                 // -25 to +25 dB in steps of 0.5 dB
-                 dnew = 10.0*(-25.0 + 0.5*val - div_gain);
-               } else {
-                 // round gain to a multiple of 0.5 dB and apply a +/- 0.5 dB update
-                  new = (int) (2*div_gain + 1.0) / 2;
-                 dnew = 10.0*((double) new + 0.01*val - 0.5 - div_gain);
-               }
-                break;
-              case MIDI_WHEEL:
-                // coarse: increaments in steps of 0.25 dB, medium: steps of 0.1 dB fine: in steps of 0.01 dB
-                if (action == DIV_GAIN) {
-                 dnew = val*0.5;
-               } else if (action == DIV_GAIN_COARSE) {
-                 dnew = val*2.5;
-               } else {
-                 dnew = val * 0.1;
-               }
-                break;
-              default:
-                // do not change
-                // we should not come here anyway
-               dnew = 0.0;
-                break;
-            }
-           // dnew is the delta times 10
-           dp=malloc(sizeof(double));
-           *dp=dnew;
-            g_idle_add(ext_diversity_change_gain, dp);
-            break;
-        /////////////////////////////////////////////////////////// "DIVPHASE"
-        case DIV_PHASE_COARSE:   // knob or wheel supported
-        case DIV_PHASE_FINE:     // knob or wheel supported
-       case DIV_PHASE:         // knob or wheel supported
-            switch (type) {
-              case MIDI_KNOB:
-               // coarse: change phase from -180 to 180
-                // fine: change from -5 to 5
-                if (action == DIV_PHASE_COARSE || action == DIV_PHASE) {
-                 // coarse: change phase from -180 to 180 in steps of 3.6 deg
-                  dnew = (-180.0 + 3.6*val - div_phase);
-                } else {
-                 // fine: round to multiple of 5 deg and apply a +/- 5 deg update
-                  new = 5 * ((int) (div_phase+0.5) / 5);
-                  dnew =  (double) new + 0.1*val -5.0 -div_phase;
-                }
-                break;
-              case MIDI_WHEEL:
-               if (action == DIV_PHASE) {
-                 dnew = val*0.5; 
-               } else if (action == DIV_PHASE_COARSE) {
-                 dnew = val*2.5;
-               } else if (action == DIV_PHASE_FINE) {
-                 dnew = 0.1*val;
-               }
-                break;
-              default:
-                // do not change
-                // we should not come here anyway
-                dnew = 0.0;
-                break;
-            }
-            // dnew is the delta
-            dp=malloc(sizeof(double));
-            *dp=dnew;
-            g_idle_add(ext_diversity_change_phase, dp);
-            break;
-        /////////////////////////////////////////////////////////// "DIVTOGGLE"
-        case DIV:   // only key supported
-            if (type == MIDI_KEY) {
-                // enable/disable DIVERSITY
-                diversity_enabled = diversity_enabled ? 0 : 1;
-                g_idle_add(ext_vfo_update, NULL);
-            }
-            break;
-       /////////////////////////////////////////////////////////// "DUP"
-        case DUPLEX:
-           if (can_transmit && !isTransmitting()) {
-             duplex=duplex==1?0:1;
-              g_idle_add(ext_set_duplex, NULL);
-           }
-            break;
-       /////////////////////////////////////////////////////////// "FILTERDOWN"
-       /////////////////////////////////////////////////////////// "FILTERUP"
-       case FILTER_MINUS:
-       case FILTER_PLUS:
-           //
-           // In filter.c, the filters are sorted such that the widest one comes first
-           // Therefore let FILTER_UP move down.
-           //
-           switch (type) {
-             case MIDI_KEY:
-               new=(action == FILTER_PLUS) ? -1 : 1;
-               break;
-             case MIDI_WHEEL:
-               new=val > 0 ? -1 : 1;
-               break;
-             case MIDI_KNOB:
-               // cycle through all the filters: val=100 maps to filter #0
-               new = ((FILTERS-1) * (val-100)) / 100 - vfo[active_receiver->id].filter;
-               break;
-             default:
-               // do not change filter setting
-               // we should not come here anyway
-               new=0;
-               break;
-           }
-           if (new != 0) {
-             new+=vfo[active_receiver->id].filter;
-             if (new >= FILTERS) new=0;
-             if (new <0) new=FILTERS-1;
-             g_idle_add(ext_vfo_filter_changed, GINT_TO_POINTER(new));
-           }
-           break;
-       /////////////////////////////////////////////////////////// "MENU_FILTFILTERER"
-       case MENU_FILTER:
-           g_idle_add(ext_menu_filter, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "MENU_MODE"
-       case MENU_MODE:
-           g_idle_add(ext_menu_mode, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "LOCK"
-       case LOCK: // only key supported
-           if (type == MIDI_KEY) {
-             locked=!locked;
-             g_idle_add(ext_vfo_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "MICGAIN"
-       case MIC_GAIN: // knob or wheel supported
-           // TODO: possibly adjust linein value if that is effective
-           switch (type) {
-             case MIDI_KNOB:
-               dnew=-10.0 + 0.6*val;
-               break;
-             case MIDI_WHEEL:
-               dnew = mic_gain + val;
-               if (dnew < -10.0) dnew=-10.0; if (dnew > 50.0) dnew=50.0;
-               break;
-             default:
-               // do not change mic gain
-               // we should not come here anyway
-               dnew = mic_gain;
-               break;
-           }
-           dp=malloc(sizeof(double));
-           *dp=dnew;
-           g_idle_add(ext_set_mic_gain, (gpointer) dp);
-           break;
-       /////////////////////////////////////////////////////////// "MODEDOWN"
-       /////////////////////////////////////////////////////////// "MODEUP"
-       case MODE_MINUS:
-       case MODE_PLUS:
-           switch (type) {
-             case MIDI_KEY:
-               new=(action == MODE_PLUS) ? 1 : -1;
-               break;
-             case MIDI_WHEEL:
-               new=val > 0 ? 1 : -1;
-               break;
-             case MIDI_KNOB:
-               // cycle through all the modes
-               new = ((MODES-1) * val) / 100 - vfo[active_receiver->id].mode;
-               break;
-             default:
-               // do not change
-               // we should not come here anyway
-               new=0;
-               break;
-           }
-           if (new != 0) {
-             new+=vfo[active_receiver->id].mode;
-             if (new >= MODES) new=0;
-             if (new <0) new=MODES-1;
-             g_idle_add(ext_vfo_mode_changed, GINT_TO_POINTER(new));
-           }
-           break;
-       /////////////////////////////////////////////////////////// "MOX"
-       case MOX: // only key supported
-           if (type == MIDI_KEY && can_transmit) {
-               new = !mox;
-               g_idle_add(ext_mox_update, GINT_TO_POINTER(new));
-           }
-           break;    
-        /////////////////////////////////////////////////////////// "MUTE"
-        case MUTE:
-            if (type == MIDI_KEY) {
-              g_idle_add(ext_mute_update,NULL);
-           }
-            break;
-       /////////////////////////////////////////////////////////// "NOISEBLANKER"
-       case NB: // only key supported
-           // cycle through NoiseBlanker settings: OFF, NB, NB2
-            if (type == MIDI_KEY) {
-             if (active_receiver->nb) {
-               active_receiver->nb = 0;
-               active_receiver->nb2= 1;
-             } else if (active_receiver->nb2) {
-               active_receiver->nb = 0;
-               active_receiver->nb2= 0;
-             } else {
-               active_receiver->nb = 1;
-               active_receiver->nb2= 0;
-             }
-             g_idle_add(ext_vfo_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "NOISEREDUCTION"
-       case NR: // only key supported
-           // cycle through NoiseReduction settings: OFF, NR1, NR2
-           if (type == MIDI_KEY) {
-             if (active_receiver->nr) {
-               active_receiver->nr = 0;
-               active_receiver->nr2= 1;
-             } else if (active_receiver->nr2) {
-               active_receiver->nr = 0;
-               active_receiver->nr2= 0;
-             } else {
-               active_receiver->nr = 1;
-               active_receiver->nr2= 0;
-             }
-             g_idle_add(ext_update_noise, NULL);
-             g_idle_add(ext_vfo_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "PAN"
-        case PAN:  // wheel and knob
-           switch (type) {
-              case MIDI_WHEEL:
-                g_idle_add(ext_pan_update,GINT_TO_POINTER(val));
-                break;
-             case MIDI_KNOB:
-                g_idle_add(ext_pan_set,GINT_TO_POINTER(val));
-                break;
-             default:
-               // no action for keys (we should not come here anyway)
-               break;
-            }
-            break;
-       /////////////////////////////////////////////////////////// "PANHIGH"
-       case PANADAPTER_HIGH:  // wheel or knob
-           switch (type) {
-             case MIDI_WHEEL:
-               if (mox) {
-                   // TX panadapter affected
-                   transmitter->panadapter_high += val;
-               } else {
-                   active_receiver->panadapter_high += val;
-               }
-               break;
-           case MIDI_KNOB:
-               // Adjust "high water" in the range -50 ... 0 dBm
-               new = -50 + val/2;
-               if (mox) {
-                   transmitter->panadapter_high = new;
-               } else {
-                   active_receiver->panadapter_high = new;
-               }
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-           g_idle_add(ext_vfo_update, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "PANLOW"
-       case PANADAPTER_LOW:  // wheel and knob
-           switch (type) {
-             case MIDI_WHEEL:
-               if (isTransmitting()) {
-                   // TX panadapter affected
-                   transmitter->panadapter_low += val;
-               } else {
-                   active_receiver->panadapter_low += val;
-               }
-               break;
-             case MIDI_KNOB:
-               if (isTransmitting()) {
-                   // TX panadapter: use values -100 through -50
-                   new = -100 + val/2;
-                   transmitter->panadapter_low =new;
-               } else {
-                   // RX panadapter: use values -140 through -90
-                   new = -140 + val/2;
-                   active_receiver->panadapter_low = new;
-               }
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-           g_idle_add(ext_vfo_update, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "PREAMP"
-       case PREAMP:    // only key supported
-           if (type == MIDI_KEY) {
-               //
-               // Normally on/off, but for CHARLY25, cycle through three
-               // possible states. Current HPSDR hardware does no have
-               // switch'able preamps.
-               //
-               int c25= (filter_board == CHARLY25);
-               new = active_receiver->preamp + active_receiver->dither;
-               new++;
-               if (c25) {
-                 if (new >2) new=0;
-               } else {
-                 if (new >1) new=0;
-               }
-               switch (new) {
-                   case 0:
-                       active_receiver->preamp=0;
-                       if (c25) active_receiver->dither=0;
-                       break;
-                   case 1:
-                       active_receiver->preamp=1;
-                       if (c25) active_receiver->dither=0;
-                       break;
-                   case 2:
-                       active_receiver->preamp=1;
-                       if (c25) active_receiver->dither=1;
-                       break;
-               }
-               g_idle_add(ext_update_att_preamp, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "PURESIGNAL"
-       case PS: // only key supported
-#ifdef PURESIGNAL
-           // toggle PURESIGNAL
-           if (type == MIDI_KEY) {
-             new=!(transmitter->puresignal);
-             g_idle_add(ext_tx_set_ps,GINT_TO_POINTER(new));
-           }
-#endif
-           break;
-       /////////////////////////////////////////////////////////// "RFGAIN"
-        case RF_GAIN: // knob or wheel supported
-            if (type == MIDI_KNOB) {
-                new=val;
-            } else  if (type == MIDI_WHEEL) {
-                //new=(int)active_receiver->rf_gain+val;
-                new=(int)adc[active_receiver->id].gain+val;
-            }
-            g_idle_add(ext_set_rf_gain, GINT_TO_POINTER((int)new));
-           break;
-       /////////////////////////////////////////////////////////// "RFPOWER"
-       case DRIVE: // knob or wheel supported
-           switch (type) {
-             case MIDI_KNOB:
-               dnew = val;
-               break;
-             case MIDI_WHEEL:
-               dnew=transmitter->drive + val;
-               if (dnew < 0.0) dnew=0.0; if (dnew > 100.0) dnew=100.0;
-               break;
-             default:
-               // do not change value
-               // we should not come here anyway
-               dnew=transmitter->drive;
-               break;
-           }
-           dp=malloc(sizeof(double));
-           *dp=dnew;
-           g_idle_add(ext_set_drive, (gpointer) dp);
-           break;
-       /////////////////////////////////////////////////////////// "RITCLEAR"
-       case RIT_CLEAR:   // only key supported
-           if (type == MIDI_KEY) {
-             // clear RIT value
-             vfo[active_receiver->id].rit = new;
-             g_idle_add(ext_vfo_update, NULL);
-           }
-       /////////////////////////////////////////////////////////// "RITSTEP"
-        case RIT_STEP: // key or wheel supported
-            // This cycles between RIT increments 1, 10, 100, 1, 10, 100, ...
-            switch (type) {
-              case MIDI_KEY:
-                // key cycles through in upward direction
-                val=1;
-                // FALLTHROUGH
-              case MIDI_WHEEL:
-                // wheel cycles upward or downward
-                if (val > 0) {
-                  rit_increment=10*rit_increment;
-                } else {
-                  rit_increment=rit_increment/10;
-                }
-                if (rit_increment < 1) rit_increment=100;
-                if (rit_increment > 100) rit_increment=1;
-                break;
-              default:
-                // do nothing
-                break;
-            }
-            g_idle_add(ext_vfo_update, NULL);
-            break;
-       /////////////////////////////////////////////////////////// "RITTOGGLE"
-       case RIT_ENABLE:  // only key supported
-           if (type == MIDI_KEY) {
-               // enable/disable RIT
-               new=vfo[active_receiver->id].rit_enabled;
-               vfo[active_receiver->id].rit_enabled = new ? 0 : 1;
-               g_idle_add(ext_vfo_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "RITVAL"
-       case RIT:       // wheel or knob
-           switch (type) {
-             case MIDI_WHEEL:
-               // This changes the RIT value incrementally,
-               // but we restrict the change to +/ 9.999 kHz
-               new = vfo[active_receiver->id].rit + val*rit_increment;
-               if (new >  9999) new= 9999;
-               if (new < -9999) new=-9999;
-               vfo[active_receiver->id].rit = new;
-               break;
-             case MIDI_KNOB:
-               // knob: adjust in the range +/ 50*rit_increment
-               new = (val-50) * rit_increment;
-               vfo[active_receiver->id].rit = new;
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-           // enable/disable RIT according to RIT value
-           vfo[active_receiver->id].rit_enabled = (vfo[active_receiver->id].rit == 0) ? 0 : 1;
-           g_idle_add(ext_vfo_update, NULL);
-           break;
-       /////////////////////////////////////////////////////////// "SAT"
-        case SAT:
-           switch (sat_mode) {
-               case SAT_NONE:
-                 sat_mode=SAT_MODE;
-                 break;
-               case SAT_MODE:
-                 sat_mode=RSAT_MODE;
-                 break;
-               case RSAT_MODE:
-               default:
-                 sat_mode=SAT_NONE;
-                 break;
-           }
-           g_idle_add(ext_vfo_update, NULL);
-            break;
-       /////////////////////////////////////////////////////////// "SNB"
-       case SNB:       // only key supported
-           if (type == MIDI_KEY) {
-             g_idle_add(ext_snb_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "SPLIT"
-       case SPLIT: // only key supported
-           // toggle split mode
-           if (type == MIDI_KEY) {
-              g_idle_add(ext_split_toggle, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "SWAPRX"
-       case SWAP_RX:   // only key supported
-           if (type == MIDI_KEY && receivers == 2) {
-               new=active_receiver->id;        // 0 or 1
-               new= (new == 1) ? 0 : 1;        // id of currently inactive receiver
-               active_receiver=receiver[new];
-               g_idle_add(menu_active_receiver_changed,NULL);
-               g_idle_add(ext_vfo_update,NULL);
-               g_idle_add(sliders_active_receiver_changed,NULL);
-           }
-           break;    
-       /////////////////////////////////////////////////////////// "SWAPVFO"
-       //case SWAP_VFO:        // only key supported
-       //    if (type == MIDI_KEY) {
-//             g_idle_add(ext_vfo_a_swap_b,NULL);
-//         }
-//         break;    
-       /////////////////////////////////////////////////////////// "TUNE"
-       case TUNE: // only key supported
-           if (type == MIDI_KEY && can_transmit) {
-               new = !tune;
-               g_idle_add(ext_tune_update, GINT_TO_POINTER(new));
-           }
-           break;    
-       /////////////////////////////////////////////////////////// "VFOA"
-       /////////////////////////////////////////////////////////// "VFOB"
-       case VFOA: // only wheel supported
-       case VFOB: // only wheel supported
-           if (type == MIDI_WHEEL && !locked) {
-               ip=malloc(2*sizeof(int));
-               *ip = (action == VFOA) ? 0 : 1;   // could use (action - VFOA) to support even more VFOs
-               *(ip+1)=val;
-               g_idle_add(ext_vfo_id_step, ip);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "VFOSTEPDOWN"
-       /////////////////////////////////////////////////////////// "VFOSTEPUP"
-        case VFO_STEP_MINUS: // key or wheel supported
-        case VFO_STEP_PLUS:
-           switch (type) {
-             case MIDI_KEY:
-               new =  (action == VFO_STEP_PLUS) ? 1 : -1;
-               g_idle_add(ext_update_vfo_step, GINT_TO_POINTER(new));
-               break;
-             case MIDI_WHEEL:
-               new = (val > 0) ? 1 : -1;
-               g_idle_add(ext_update_vfo_step, GINT_TO_POINTER(new));
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-            break;
-       /////////////////////////////////////////////////////////// "VOX"
-       case VOX: // only key supported
-           // toggle VOX
-           if (type == MIDI_KEY) {
-             vox_enabled = !vox_enabled;
-             g_idle_add(ext_vfo_update, NULL);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "VOXLEVEL"
-       case VOXLEVEL: // knob or wheel supported
-            switch (type) {
-              case MIDI_WHEEL:
-                // This changes the value incrementally,
-                // but stay within limits (0.0 through 1.0)
-                vox_threshold += (double) val * 0.01;
-               if (vox_threshold > 1.0) vox_threshold=1.0;
-               if (vox_threshold < 0.0) vox_threshold=0.0;
-                break;
-              case MIDI_KNOB:
-                vox_threshold = 0.01 * (double) val;
-                break;
-              default:
-                // do nothing
-                // we should not come here anyway
-                break;
-            }
-           // VOX level not shown on screen, hence no VFO update
-           break;
-       /////////////////////////////////////////////////////////// "XITCLEAR"
-        case XIT_CLEAR:  // only key supported
-            if (type == MIDI_KEY) {
-                // this clears the XIT value and disables XIT
-                if(can_transmit) {
-                  transmitter->xit = 0;
-                  transmitter->xit_enabled = 0;
-                  g_idle_add(ext_vfo_update, NULL);
-                }
-            }
-            break;
-       /////////////////////////////////////////////////////////// "XITVAL"
-        case XIT:   // wheel and knob supported.
-           if (can_transmit) {
-              switch (type) {
-                case MIDI_WHEEL:
-                  // This changes the XIT value incrementally,
-                  // but we restrict the change to +/ 9.999 kHz
-                  new = transmitter->xit + val*rit_increment;
-                  if (new >  9999) new= 9999;
-                  if (new < -9999) new=-9999;
-                  transmitter->xit = new;
-                  break;
-                case MIDI_KNOB:
-                  // knob: adjust in the range +/ 50*rit_increment
-                  new = (val-50) * rit_increment;
-                  transmitter->xit = new;
-                  break;
-                default:
-                  // do nothing
-                  // we should not come here anyway
-                  break;
-              }
-              // enable/disable XIT according to XIT value
-              transmitter->xit_enabled = (transmitter->xit == 0) ? 0 : 1;
-              g_idle_add(ext_vfo_update, NULL);
-           }
-            break;
-       /////////////////////////////////////////////////////////// "ZOOM"
-        case ZOOM:  // wheel and knob
-            switch (type) {
-              case MIDI_WHEEL:
-g_print("MIDI_ZOOM: MIDI_WHEEL: val=%d\n",val);
-                g_idle_add(ext_zoom_update,GINT_TO_POINTER(val));
-                break;
-              case MIDI_KNOB:
-g_print("MIDI_ZOOM: MIDI_KNOB: val=%d\n",val);
-                g_idle_add(ext_zoom_set,GINT_TO_POINTER(val));
-                break;
-             default:
-               // no action for keys (should not come here anyway)
-               break;
-            }
-            break;
-       /////////////////////////////////////////////////////////// "ZOOMDOWN"
-       /////////////////////////////////////////////////////////// "ZOOMUP"
-        case ZOOM_MINUS:  // key
-        case ZOOM_PLUS:  // key
-           switch (type) {
-             case MIDI_KEY:
-               new =  (action == ZOOM_PLUS) ? 1 : -1;
-                g_idle_add(ext_zoom_update,GINT_TO_POINTER(new));
-               break;
-             case MIDI_WHEEL:
-               new = (val > 0) ? 1 : -1;
-                g_idle_add(ext_zoom_update,GINT_TO_POINTER(new));
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-            break;
-
-       case NO_ACTION:
-           // No error message, this is the "official" action for un-used controller buttons.
-           break;
-       default:
-           // This means we have forgotten to implement an action, so we inform on stderr.
-           fprintf(stderr,"Unimplemented MIDI action: A=%d\n", (int) action);
-    }
-    */
 }
index 20acaaf5304c6de02e65eea550b837dc7543e6ab..0d29db86c7a2fe2840ffb8eac60cbb302bef6b57 100644 (file)
@@ -99,13 +99,6 @@ enum {
   UPDATE_EXISTING
 };
 
-typedef struct _choice {
-  int action;
-  GtkWidget *initial_button;
-  GtkWidget *button;
-  gulong signal_id;
-} CHOICE;
-
 static int update(void *data);
 static void load_store();
 
index 0f8bd7dd9481292675bd3805ce9dd42bf5766876..c7eed19f3addbdd8d1df0623159ed3bdb8784e9f 100644 (file)
@@ -693,6 +693,8 @@ static void new_protocol_high_priority() {
           }
         }
 
+       rxFrequency+=calibration;
+
         phase=(long)((4294967296.0*(double)rxFrequency)/122880000.0);
         high_priority_buffer_to_radio[ 9]=phase>>24;
         high_priority_buffer_to_radio[10]=phase>>16;
@@ -724,6 +726,8 @@ static void new_protocol_high_priority() {
             }
           }
 
+         rxFrequency+=calibration;
+
          phase=(long)((4294967296.0*(double)rxFrequency)/122880000.0);
          high_priority_buffer_to_radio[9+(ddc*4)]=phase>>24;
          high_priority_buffer_to_radio[10+(ddc*4)]=phase>>16;
@@ -750,6 +754,8 @@ static void new_protocol_high_priority() {
       }
     }
 
+    txFrequency+=calibration;
+
     phase=(long)((4294967296.0*(double)txFrequency)/122880000.0);
 
     if(isTransmitting() && transmitter->puresignal) {
index 0dfa76828de8e448a34553c9a8811a2adcf59eb2..d8fb6562f4a5735273fbd40ccb71c202f9c75a8c 100644 (file)
@@ -773,6 +773,7 @@ static long long channel_freq(int chan) {
       }
     }
   }
+  freq+=calibration;
   return freq;
 }
 
index 2435907e6c13ff12805b43a67690d2de6b2fd0e2..d4197c91260595acac13c097dd67858e153aaea6 100644 (file)
@@ -323,7 +323,7 @@ float audio_get_next_mic_sample() {
 
   if ((mic_ring_buffer == NULL) || (mic_ring_read_pt == mic_ring_write_pt)) {
     // no buffer, or nothing in buffer: insert silence
-    g_print("%s: no samples\n",__FUNCTION__);
+    //g_print("%s: no samples\n",__FUNCTION__);
     sample=0.0;
   } else {
     // the "existence" of the ring buffer is now guaranteed for 1 msec,
diff --git a/radio.c b/radio.c
index d39d510e7fe74dc051bc705f9b5fdf36c5e3b338..d8d5f49e7b101b696c76bd9ecb25cd4e7ee43c7e 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -114,6 +114,9 @@ static GtkWidget *panadapter;
 static GtkWidget *waterfall;
 static GtkWidget *audio_waterfall;
 
+// RX and TX calibration
+long long calibration=0LL;
+
 /*
 #ifdef GPIO
 static GtkWidget *encoders;
@@ -2072,8 +2075,11 @@ g_print("radioRestoreState: %s\n",property_path);
     value=getProperty("binaural");
     if(value) binaural=atoi(value);
 
+    value=getProperty("calibration");
+    if(value) calibration=atoll(value);
+
     value=getProperty("frequencyB");
-    if(value) frequencyB=atol(value);
+    if(value) frequencyB=atoll(value);
 
     value=getProperty("modeB");
     if(value) modeB=atoi(value);
@@ -2417,6 +2423,9 @@ g_print("radioSaveState: %s\n",property_path);
     sprintf(value,"%d",binaural);
     setProperty("binaural",value);
 
+    sprintf(value,"%lld",calibration);
+    setProperty("calibration",value);
+
     sprintf(value,"%lld",frequencyB);
     setProperty("frequencyB",value);
     sprintf(value,"%d",modeB);
diff --git a/radio.h b/radio.h
index de56307802fea42a74940c4101154964d8b975a3..6a7513fb948d8391a6c776ccf5f23da0ba8589f2 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -63,6 +63,8 @@ extern gboolean radio_is_remote;
 
 extern GtkWidget *fixed;
 
+extern long long calibration;
+
 extern char property_path[];
 
 #define NONE 0
index fbc3080409cd8a52fade7bbd05380e7dd7475477..1a81b996d1b8e09f5ed35562d496299a14860267 100644 (file)
@@ -167,6 +167,10 @@ static void dac0_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
 */
 #endif
 
+static void calibration_value_changed_cb(GtkWidget *widget, gpointer data) {
+  calibration=(long long)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+}
+
 static void rx_gain_calibration_value_changed_cb(GtkWidget *widget, gpointer data) {
   rx_gain_calibration=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
 }
@@ -425,8 +429,10 @@ void radio_menu(GtkWidget *parent) {
   GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
 
   GtkWidget *grid=gtk_grid_new();
-  gtk_grid_set_column_spacing (GTK_GRID(grid),10);
+  gtk_grid_set_column_spacing (GTK_GRID(grid),5);
   gtk_grid_set_row_spacing (GTK_GRID(grid),5);
+  gtk_grid_set_column_homogeneous (GTK_GRID(grid), FALSE);
+  gtk_grid_set_row_homogeneous (GTK_GRID(grid), FALSE);
 
   int col=0;
   int row=0;
@@ -810,9 +816,20 @@ void radio_menu(GtkWidget *parent) {
   g_signal_connect(mute_rx_b,"toggled",G_CALLBACK(mute_rx_cb),NULL);
 
   row++;
+  col=0;
+  GtkWidget *calibration_label=gtk_label_new(NULL);
+  gtk_label_set_markup(GTK_LABEL(calibration_label), "<b>Frequency\nCalibration(Hz):</b>");
+  gtk_grid_attach(GTK_GRID(grid),calibration_label,col,row,1,1);
+  col++;
+
+  GtkWidget *calibration_b=gtk_spin_button_new_with_range(-10000.0,10000.0,1.0);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(calibration_b),(double)calibration);
+  gtk_grid_attach(GTK_GRID(grid),calibration_b,col,row,1,1);
+  g_signal_connect(calibration_b,"value_changed",G_CALLBACK(calibration_value_changed_cb),NULL);
 
   if(have_rx_gain) {
-    col=0;
+    col++;
     GtkWidget *rx_gain_label=gtk_label_new(NULL);
     gtk_label_set_markup(GTK_LABEL(rx_gain_label), "<b>RX Gain Calibration:</b>");
     gtk_grid_attach(GTK_GRID(grid),rx_gain_label,col,row,1,1);
@@ -823,8 +840,8 @@ void radio_menu(GtkWidget *parent) {
     gtk_grid_attach(GTK_GRID(grid),rx_gain_calibration_b,col,row,1,1);
     g_signal_connect(rx_gain_calibration_b,"value_changed",G_CALLBACK(rx_gain_calibration_value_changed_cb),NULL);
 
-    row++;
   }
+  row++;
 
   if(row>temp_row) temp_row=row;
 
index 16d479e39808cc834e9465f61db7381d7e6fd6b1..94bee0dd9b33ac30b06b195aaa9fa052a8609351 100644 (file)
 #include "gpio.h"
 #include "i2c.h"
 
-typedef struct _choice {
-  int sw;
-  int action;
-  GtkWidget *initial_button;
-  GtkWidget *button;
-  gulong signal_id;
-} CHOICE;
-
 static GtkWidget *parent_window=NULL;
 
 static GtkWidget *dialog=NULL;
index 0297e363c21d6ae04e9968b9c71af73b0fb47e6f..4dd2cc5eed46c9b5e4a0f4cd9d43e526ca17cc3b 100644 (file)
 #include "gpio.h"
 #include "i2c.h"
 
-typedef struct _choice {
-  int sw;
-  int action;
-  GtkWidget *initial_button;
-  GtkWidget *button;
-  gulong signal_id;
-} CHOICE;
-
 static GtkWidget *parent_window=NULL;
 
 static GtkWidget *dialog=NULL;
@@ -135,7 +127,6 @@ next_function_set:
     } else {
       widget=gtk_button_new_with_label(ActionTable[temp_switches[i].switch_function].str);
       g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(i));
-g_print("%s: %d\n",__FUNCTION__,i);
     }
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
diff --git a/vfo.c b/vfo.c
index 5fe726c9dd78caa4a903a726204d47837ad29a8e..07ddf0b11ae74c893aafd08aeefedc365db77b3e 100644 (file)
--- a/vfo.c
+++ b/vfo.c
@@ -1301,6 +1301,7 @@ void vfo_rit_update(int rx) {
 
 void vfo_rit_clear(int rx) {
   vfo[receiver[rx]->id].rit=0;
+  vfo[receiver[rx]->id].rit_enabled=0;
   receiver_frequency_changed(receiver[rx]);
   g_idle_add(ext_vfo_update, NULL);
 }
@@ -1313,7 +1314,8 @@ void vfo_rit(int rx,int i) {
   } else if(value>10000.0) {
     value=10000.0;
   }
-  vfo[receiver[rx]->id].rit=(int)value;
+  vfo[receiver[rx]->id].rit=value;
+  vfo[receiver[rx]->id].rit_enabled=(value!=0);
   receiver_frequency_changed(receiver[rx]);
   g_idle_add(ext_vfo_update,NULL);
 }