]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
The "big switch" is now invoked by the GTK idle queue. Only CW-key MIDI
authorc vw <dl1ycf@darc.de>
Tue, 4 May 2021 14:55:37 +0000 (16:55 +0200)
committerc vw <dl1ycf@darc.de>
Tue, 4 May 2021 14:55:37 +0000 (16:55 +0200)
messages are processed immediately.

midi3.c

diff --git a/midi3.c b/midi3.c
index 9e5e228d7d03ac14f7ee1ec2c4f5294b8d9f2aec..38ea44ad0f325c190cd26c0c3a482cc1aced31b1 100644 (file)
--- a/midi3.c
+++ b/midi3.c
 #ifdef LOCALCW
 #include "iambic.h"
 #endif
+#include "wdsp.h"
+#include "diversity_menu.h"
+#include "radio_menu.h"
+#include "toolbar.h"
+#include "noise_menu.h"
+#include "zoompan.h"
+
+//
+// Virtually all MIDI actions at the end lead to functions that have
+// to be invoked by GTK. Instead of having dozens of g_idle_add() in the
+// code below, one can queue the "big switch statement" into the GTK
+// idle queue and exectue all GUI functions directly.
+//
+// However, this is not wanted for CWKEY, CWL and CWR since
+// these have to be processed with minimal delay (and do not call GUI functions).
+//
+// Therefore, these three cases are already handled in the MIDI callback
+// function and everything else is put into the GTK queue
+//
+
+//
+// This is the data struct generated by processing the MIDI event
+// it is passed to the function DoTheMidi
+//
+struct _MIDIcmd {
+   enum MIDIaction action;
+   enum MIDItype type;
+   int val;
+};
+
+typedef struct _MIDIcmd MIDIcmd;
+
+static int DoTheRestOfTheMIDI(void *data);
 
 void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
+    if (action == MIDI_ACTION_CWKEY) {
+          //
+          // This is a CW key-up/down which uses functions from the keyer
+          // that by-pass the interrupt-driven standard action.
+          // It is intended to
+          // be used with external keyers that send key-up/down messages via
+          // MIDI using this command.
+          //
+          // NO BREAK-IN! The keyer has to take care of sending MIDI PTT
+          // on/off messages at appropriate times.
+          //
+          // Since this if for immediate key-down, it does not rely on LOCALCW
+          //
+          if (val != 0) {
+            cw_key_down=960000;  // max. 20 sec to protect hardware
+            cw_key_up=0;
+            cw_key_hit=1;
+          } else {
+            cw_key_down=0;
+            cw_key_up=0;
+          }
+          return;
+    }
+#ifdef LOCALCW
+    if (action == MIDI_ACTION_CWL) {
+         keyer_event(1, val);
+         return;
+    }
+    if (action == MIDI_ACTION_CWR) {
+         keyer_event(0, val);
+         return;
+    }
+#endif
+    //
+    // For all other MIDI actions, the parser is put into the idle queu
+    //
+    MIDIcmd *cmd=malloc(sizeof(MIDIcmd));
+    cmd->action = action;
+    cmd->type   = type;
+    cmd->val    = val;
+    g_idle_add(DoTheRestOfTheMIDI, cmd);
+    return;
+}
 
+int DoTheRestOfTheMIDI(void *data) {
+    MIDIcmd *cmd = (MIDIcmd *)data;
+   
     int new;
     double dnew;
-    double *dp;
-    int    *ip;
+
+    enum MIDIaction action = cmd->action;
+    enum MIDItype   type   = cmd->type;
+    int             val    = cmd->val;
+
+    free(data);
 
     //
     // Handle cases in alphabetical order of the key words in midi.props
@@ -41,7 +124,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
        /////////////////////////////////////////////////////////// "A2B"
        case MIDI_ACTION_VFO_A2B: // only key supported
            if (type == MIDI_TYPE_KEY) {
-             g_idle_add(ext_vfo_a_to_b, NULL);
+              vfo_a_to_b();
            }
            break;
        /////////////////////////////////////////////////////////// "AFGAIN"
@@ -60,7 +143,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                // we should not come here anyway
                break;
            }
-           g_idle_add(ext_update_af_gain, NULL);
+            update_af_gain();
            break;
        /////////////////////////////////////////////////////////// "AGCATTACK"
        case MIDI_ACTION_AGCATTACK: // only key supported
@@ -69,33 +152,40 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
              new=active_receiver->agc + 1;
              if (new > AGC_FAST) new=0;
              active_receiver->agc=new;
-             g_idle_add(ext_vfo_update, NULL);
+              vfo_update();
            }
            break;
        /////////////////////////////////////////////////////////// "AGCVAL"
        case MIDI_ACTION_AGC: // knob or wheel supported
            switch (type) {
              case MIDI_TYPE_KNOB:
-               new = -20 + (140*val)/100;
+               dnew = -20.0 + 1.4*val;
                break;
              case MIDI_TYPE_WHEEL:
-               new=active_receiver->agc_gain + val;
-               if (new < -20) new = -20;
-                if (new > 120) new = 120;
+               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
-               new=active_receiver->agc_gain;
+               dnew=active_receiver->agc_gain;
                break;
            }
-            val = new + 1000;
-           g_idle_add(ext_set_agc_gain, GINT_TO_POINTER(val));
+            set_agc_gain(active_receiver->id, dnew);
            break;
        /////////////////////////////////////////////////////////// "ANF"
        case MIDI_ACTION_ANF:   // only key supported
            if (type == MIDI_TYPE_KEY) {
-             g_idle_add(ext_anf_update, NULL);
+              if (active_receiver->anf==0) {
+                active_receiver->anf=1;
+                mode_settings[vfo[active_receiver->id].mode].anf=1;
+              } else {
+                active_receiver->snb=0;
+                mode_settings[vfo[active_receiver->id].mode].anf=0;
+              }
+              SetRXAANFRun(active_receiver->id, active_receiver->anf);
+              vfo_update();
            }
            break;
        /////////////////////////////////////////////////////////// "ATT"
@@ -105,36 +195,34 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                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);
+                  set_alex_attenuation(new);
+                  update_att_preamp();
                }
                break;
              case MIDI_TYPE_WHEEL:
-               new=adc_attenuation[active_receiver->adc] + val;
+               dnew=adc_attenuation[active_receiver->adc] + val;
                 if(have_rx_gain) {
-                  if(new < -12) {
-                    new = -12;
-                  } else if(new > 48) {
-                    new=48;
+                  if(dnew < -12.0) {
+                    dnew = -12.0;
+                  } else if(dnew > 48.0) {
+                    dnew=48.0;
                   }
                 } else {
-                  if (new < 0) {
-                    new = 0;
-                  } else if (new > 31) {
-                    new = 31;
+                  if (dnew < 0.0) {
+                    dnew = 0.0;
+                  } else if (dnew > 31.0) {
+                    dnew = 31.0;
                   }
                 }
-                val =  new+1000;
-                g_idle_add(ext_set_attenuation_value,GINT_TO_POINTER(val));
+                set_attenuation_value(dnew);
                break;
              case MIDI_TYPE_KNOB:
                 if (have_rx_gain) {
-                 new = -12 + (60 * val) / 100;
+                 dnew = -12.0 + 0.6*val;
                 } else {
-                  dnew  = (31*val)/100;
+                  dnew  = 0.31*val;
                 }
-                val =  new+1000;
-                g_idle_add(ext_set_attenuation_value,GINT_TO_POINTER(val));
+                set_attenuation_value(dnew);
                break;
              default:
                // do nothing
@@ -145,7 +233,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
        /////////////////////////////////////////////////////////// "B2A"
        case MIDI_ACTION_VFO_B2A: // only key supported
            if (type == MIDI_TYPE_KEY) {
-             g_idle_add(ext_vfo_b_to_a, NULL);
+              vfo_b_to_a();
            }
            break;
        /////////////////////////////////////////////////////////// "BANDDOWN"
@@ -177,7 +265,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
              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));
+              vfo_band_changed(active_receiver->id, new);
            }
            break;
        /////////////////////////////////////////////////////////// "COMPRESS"
@@ -197,63 +285,32 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                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);
+            if (can_transmit) {
+             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;
+              set_compression(transmitter);
+            }
            break;
        /////////////////////////////////////////////////////////// "CTUN"
        case MIDI_ACTION_CTUN: // only key supported
            // toggle CTUN
            if (type == MIDI_TYPE_KEY) {
-             g_idle_add(ext_ctun_update, NULL);
+              int id=active_receiver->id;
+              vfo[id].ctun=vfo[id].ctun==1?0:1;
+              if(!vfo[id].ctun) {
+                vfo[id].offset=0;
+              }
+              vfo[id].ctun_frequency=vfo[id].frequency;
+              set_offset(receiver[id],vfo[id].offset);
            }
            break;
        /////////////////////////////////////////////////////////// "CURRVFO"
        case MIDI_ACTION_VFO: // only wheel supported
            if (type == MIDI_TYPE_WHEEL && !locked) {
-               g_idle_add(ext_vfo_step, GINT_TO_POINTER(val));
-           }
-           break;
-       /////////////////////////////////////////////////////////// "CW"
-       case MIDI_ACTION_CWKEY: // only key
-         //
-         // This is a CW key-up/down which uses functions from the keyer
-         // that by-pass the interrupt-driven standard action.
-         // It is intended to
-         // be used with external keyers that send key-up/down messages via
-         // MIDI using this command.
-         //
-         // NO BREAK-IN! The keyer has to take care of sending MIDI PTT
-         // on/off messages at appropriate times.
-          //
-          // Since this if for immediate key-down, it does not rely on LOCALCW
-          //
-           if (type == MIDI_TYPE_KEY) {
-              if (val != 0) {
-                cw_key_down=960000;  // max. 20 sec to protect hardware
-                cw_key_up=0;
-                cw_key_hit=1;
-              } else {
-                cw_key_down=0;
-                cw_key_up=0;
-              }
-            }
-           break;
-       /////////////////////////////////////////////////////////// "CWL"
-       /////////////////////////////////////////////////////////// "CWR"
-       case MIDI_ACTION_CWL: // only key
-       case MIDI_ACTION_CWR: // only key
-#ifdef LOCALCW
-           if (type == MIDI_TYPE_KEY) {
-               new=(action == MIDI_ACTION_CWL);
-               keyer_event(new,val);
+                vfo_step(val);
            }
-#else
-           g_print("%s: %s:%d\n",__FUNCTION__,action==MIDI_ACTION_CWL?"CWL":"CWR",val);
-
-#endif
            break;
        /////////////////////////////////////////////////////////// "CWSPEED"
        case MIDI_ACTION_CWSPEED: // knob or wheel
@@ -278,7 +335,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
 #ifdef LOCALCW
            keyer_update();
 #endif
-            g_idle_add(ext_vfo_update, NULL);
+            vfo_update();
            break;
        /////////////////////////////////////////////////////////// "DIVCOARSEGAIN"
        case MIDI_ACTION_DIV_COARSEGAIN:  // knob or wheel supported
@@ -311,11 +368,8 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                dnew = 0.0;
                 break;
             }
-           // dnew is the delta times 10, it is in the range -250 - 250 in steps of 0.1
-            if (dnew < -250.0) dnew = -250.0;
-            if (dnew >  250.0) dnew =  250.0;
-            val = (int) (dnew * 10.0 + 10000.5);
-            g_idle_add(ext_diversity_change_gain, GINT_TO_POINTER(val));
+           // dnew is the delta times 10
+            update_diversity_gain(dnew);
             break;
         /////////////////////////////////////////////////////////// "DIVPHASE"
         case MIDI_ACTION_DIV_COARSEPHASE:   // knob or wheel supported
@@ -349,25 +403,22 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                 dnew = 0.0;
                 break;
             }
-            // dnew is the delta, the range is -250.0 - 250.0 in steps of 0.1
-            if (dnew < -250.0) dnew = -250.0;
-            if (dnew >  250.0) dnew =  250.0;
-            val = (int) (dnew * 10.0 + 10000.5);
-            g_idle_add(ext_diversity_change_phase, GINT_TO_POINTER(val));
+            // dnew is the delta
+            update_diversity_phase(dnew);
             break;
         /////////////////////////////////////////////////////////// "DIVTOGGLE"
         case MIDI_ACTION_DIV_TOGGLE:   // only key supported
             if (type == MIDI_TYPE_KEY) {
                 // enable/disable DIVERSITY
                 diversity_enabled = diversity_enabled ? 0 : 1;
-                g_idle_add(ext_vfo_update, NULL);
+                vfo_update();
             }
             break;
        /////////////////////////////////////////////////////////// "DUP"
         case MIDI_ACTION_DUP:
            if (can_transmit && !isTransmitting()) {
              duplex=duplex==1?0:1;
-              g_idle_add(ext_set_duplex, NULL);
+              setDuplex();
            }
             break;
        /////////////////////////////////////////////////////////// "FILTERDOWN"
@@ -399,14 +450,14 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
              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));
+              vfo_filter_changed(new);
            }
            break;
        /////////////////////////////////////////////////////////// "LOCK"
        case MIDI_ACTION_LOCK: // only key supported
            if (type == MIDI_TYPE_KEY) {
              locked=!locked;
-             g_idle_add(ext_vfo_update, NULL);
+              vfo_update();
            }
            break;
        /////////////////////////////////////////////////////////// "MICGAIN"
@@ -414,21 +465,20 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            // TODO: possibly adjust linein value if that is effective
            switch (type) {
              case MIDI_TYPE_KNOB:
-               new = -10 + (60*val)/100;
+               dnew = -10.0 + 0.6*val;
                break;
              case MIDI_TYPE_WHEEL:
-               new = mic_gain + val;
-               if (new < -10) new = -10;
-                if (new >  50) new =  50;
+               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
-               new = mic_gain;
+               dnew = mic_gain;
                break;
            }
-            val = new + 1000;
-           g_idle_add(ext_set_mic_gain, GINT_TO_POINTER(val));
+            set_mic_gain(dnew);
            break;
        /////////////////////////////////////////////////////////// "MODEDOWN"
        /////////////////////////////////////////////////////////// "MODEUP"
@@ -455,7 +505,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
              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));
+              vfo_mode_changed(new);
            }
            break;
        /////////////////////////////////////////////////////////// "MOX"
@@ -465,13 +515,13 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
             // *setting* PTT
            if (type == MIDI_TYPE_KEY && can_transmit) {
                new = !mox;
-               g_idle_add(ext_mox_update, GINT_TO_POINTER(new));
+                mox_update(new);
            }
            break;    
         /////////////////////////////////////////////////////////// "MUTE"
         case MIDI_ACTION_MUTE:
             if (type == MIDI_TYPE_KEY) {
-              g_idle_add(ext_mute_update,NULL);
+              active_receiver->mute_radio=!active_receiver->mute_radio;
            }
             break;
        /////////////////////////////////////////////////////////// "NOISEBLANKER"
@@ -488,7 +538,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                active_receiver->nb = 1;
                active_receiver->nb2= 0;
              }
-             g_idle_add(ext_vfo_update, NULL);
+              vfo_update();
            }
            break;
        /////////////////////////////////////////////////////////// "NOISEREDUCTION"
@@ -505,18 +555,22 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                active_receiver->nr = 1;
                active_receiver->nr2= 0;
              }
-             g_idle_add(ext_update_noise, NULL);
-             g_idle_add(ext_vfo_update, NULL);
+              update_noise();
+              vfo_update();
            }
            break;
        /////////////////////////////////////////////////////////// "PAN"
         case MIDI_ACTION_PAN:  // wheel and knob
            switch (type) {
               case MIDI_TYPE_WHEEL:
-                g_idle_add(ext_pan_update,GINT_TO_POINTER(val*10));
+                update_pan(val*10.0);
                 break;
              case MIDI_TYPE_KNOB:
-                g_idle_add(ext_pan_set,GINT_TO_POINTER(val));
+                if(active_receiver->zoom>1) {
+                  int pos=GPOINTER_TO_INT(data);
+                  double pan=(double)((active_receiver->zoom-1)*active_receiver->width)*((double)pos/100.0);
+                  set_pan(active_receiver->id,(double)pan);
+                }
                 break;
              default:
                // no action for keys (we should not come here anyway)
@@ -548,7 +602,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                // we should not come here anyway
                break;
            }
-           g_idle_add(ext_vfo_update, NULL);
+            vfo_update();
            break;
        /////////////////////////////////////////////////////////// "PANLOW"
        case MIDI_ACTION_PAN_LOW:  // wheel and knob
@@ -577,7 +631,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                // we should not come here anyway
                break;
            }
-           g_idle_add(ext_vfo_update, NULL);
+            vfo_update();
            break;
        /////////////////////////////////////////////////////////// "PREAMP"
        case MIDI_ACTION_PRE:   // only key supported
@@ -609,14 +663,14 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                        if (c25) active_receiver->dither=1;
                        break;
                }
-               g_idle_add(ext_update_att_preamp, NULL);
+                update_att_preamp();
            }
            break;
        /////////////////////////////////////////////////////////// "PTTONOFF"
         case MIDI_ACTION_PTTONOFF:  // key only
             // always use with "ONOFF"
            if (type == MIDI_TYPE_KEY && can_transmit) {
-               g_idle_add(ext_mox_update, GINT_TO_POINTER(val));
+                mox_update(val);
            }
            break;    
        /////////////////////////////////////////////////////////// "PURESIGNAL"
@@ -624,8 +678,10 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
 #ifdef PURESIGNAL
            // toggle PURESIGNAL
            if (type == MIDI_TYPE_KEY) {
-             new=!(transmitter->puresignal);
-             g_idle_add(ext_tx_set_ps,GINT_TO_POINTER(new));
+              if (can_transmit) {
+               new=!(transmitter->puresignal);
+                tx_set_ps(transmitter, new);
+              }
            }
 #endif
            break;
@@ -639,18 +695,20 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            // only key supported
             //
             if (type == MIDI_TYPE_KEY) {
-                new = action - MIDI_ACTION_MEM_RECALL_M0,
-               g_idle_add(ext_recall_memory_slot, GINT_TO_POINTER(new));
+                new = action - MIDI_ACTION_MEM_RECALL_M0;
+                recall_memory_slot(new);
            }
             break;
        /////////////////////////////////////////////////////////// "RFGAIN"
         case MIDI_ACTION_RF_GAIN: // knob or wheel supported
             if (type == MIDI_TYPE_KNOB) {
-                new=val;
+                dnew=-12.0 + 0.6*val;
             } else  if (type == MIDI_TYPE_WHEEL) {
-                new=(int)active_receiver->rf_gain+val;
+                dnew=active_receiver->rf_gain+val;
             }
-            g_idle_add(ext_set_rf_gain, GINT_TO_POINTER((int)new));
+            if (dnew < -12.0) dnew = -12.0;
+            if (dnew >  48.0) dnew =  48.0;
+            set_rf_gain(active_receiver->id, dnew);
            break;
        /////////////////////////////////////////////////////////// "RFPOWER"
        case MIDI_ACTION_TX_DRIVE: // knob or wheel supported
@@ -668,15 +726,14 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                dnew=transmitter->drive;
                break;
            }
-           val=(int) (dnew + 0.5);
-           g_idle_add(ext_set_drive, GINT_TO_POINTER(val));
+            set_drive(dnew);
            break;
        /////////////////////////////////////////////////////////// "RITCLEAR"
        case MIDI_ACTION_RIT_CLEAR:       // only key supported
            if (type == MIDI_TYPE_KEY) {
              // clear RIT value
              vfo[active_receiver->id].rit = new;
-             g_idle_add(ext_vfo_update, NULL);
+              vfo_update();
            }
        /////////////////////////////////////////////////////////// "RITSTEP"
         case MIDI_ACTION_RIT_STEP: // key or wheel supported
@@ -700,7 +757,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                 // do nothing
                 break;
             }
-            g_idle_add(ext_vfo_update, NULL);
+            vfo_update();
             break;
        /////////////////////////////////////////////////////////// "RITTOGGLE"
        case MIDI_ACTION_RIT_TOGGLE:  // only key supported
@@ -708,7 +765,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                // 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);
+                vfo_update();
            }
            break;
        /////////////////////////////////////////////////////////// "RITVAL"
@@ -734,7 +791,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            }
            // 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);
+            vfo_update();
            break;
        /////////////////////////////////////////////////////////// "SAT"
         case MIDI_ACTION_SAT:
@@ -750,19 +807,27 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                  sat_mode=SAT_NONE;
                  break;
            }
-           g_idle_add(ext_vfo_update, NULL);
+            vfo_update();
             break;
        /////////////////////////////////////////////////////////// "SNB"
        case MIDI_ACTION_SNB:   // only key supported
            if (type == MIDI_TYPE_KEY) {
-             g_idle_add(ext_snb_update, NULL);
+              if(active_receiver->snb==0) {
+                active_receiver->snb=1;
+                mode_settings[vfo[active_receiver->id].mode].snb=1;
+              } else {
+                active_receiver->snb=0;
+                mode_settings[vfo[active_receiver->id].mode].snb=0;
+              }
+              update_noise();
            }
            break;
        /////////////////////////////////////////////////////////// "SPLIT"
        case MIDI_ACTION_SPLIT: // only key supported
            // toggle split mode
            if (type == MIDI_TYPE_KEY) {
-              g_idle_add(ext_split_toggle, NULL);
+              new= split ? 0:1;
+              set_split(new);
            }
            break;
        /////////////////////////////////////////////////////////// "STOREM[0-4]"
@@ -776,7 +841,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
             //
             if (type == MIDI_TYPE_KEY) {
                 new = action - MIDI_ACTION_MEM_STORE_M0;
-               g_idle_add(ext_store_memory_slot, GINT_TO_POINTER(new));
+                store_memory_slot(new);
            }
             break;
        /////////////////////////////////////////////////////////// "SWAPRX"
@@ -786,21 +851,21 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                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);
+                vfo_update();
            }
            break;    
        /////////////////////////////////////////////////////////// "SWAPVFO"
        case MIDI_ACTION_SWAP_VFO:      // only key supported
            if (type == MIDI_TYPE_KEY) {
-               g_idle_add(ext_vfo_a_swap_b,NULL);
+                vfo_a_swap_b();
            }
            break;    
        /////////////////////////////////////////////////////////// "TUNE"
        case MIDI_ACTION_TUNE: // only key supported
            if (type == MIDI_TYPE_KEY && can_transmit) {
                new = !tune;
-               g_idle_add(ext_tune_update, GINT_TO_POINTER(new));
+                tune_update(new);
            }
            break;    
        /////////////////////////////////////////////////////////// "VFOA"
@@ -808,9 +873,8 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
        case MIDI_ACTION_VFOA: // only wheel supported
        case MIDI_ACTION_VFOB: // only wheel supported
            if (type == MIDI_TYPE_WHEEL && !locked) {
-               new = (action == MIDI_ACTION_VFOA) ? 0 : 10000;
-                new += (val+1000);
-               g_idle_add(ext_vfo_id_step, GINT_TO_POINTER(new));
+               new = (action == MIDI_ACTION_VFOA) ? 0 : 1;
+                vfo_id_step(new, val);
            }
            break;
        /////////////////////////////////////////////////////////// "VFOSTEPDOWN"
@@ -820,24 +884,49 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            switch (type) {
              case MIDI_TYPE_KEY:
                new =  (action == MIDI_ACTION_VFO_STEP_UP) ? 1 : -1;
-               g_idle_add(ext_update_vfo_step, GINT_TO_POINTER(new));
                break;
              case MIDI_TYPE_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
+                new = 0;
                break;
            }
+            if (new != 0) {
+              //
+              // locate where the current step size is located in our table
+              //
+              int i=0;
+              while(steps[i]!=step && steps[i]!=0) {
+                i++;
+              }
+              if(steps[i]!=0) {
+                // found. current step size is at position #i
+                if (new>0) {
+                  // next higher step size, if not yet at end of list
+                  i++;
+                  if(steps[i]!=0) {
+                    step=steps[i];
+                  }
+                } else {
+                  // next lower step size, if not yet at end of list
+                  i--;
+                  if(i>=0) {
+                    step=steps[i];
+                  }
+                }
+              }
+              vfo_update();
+            }
             break;
        /////////////////////////////////////////////////////////// "VOX"
        case MIDI_ACTION_VOX: // only key supported
            // toggle VOX
            if (type == MIDI_TYPE_KEY) {
              vox_enabled = !vox_enabled;
-             g_idle_add(ext_vfo_update, NULL);
+              vfo_update();
            }
            break;
        /////////////////////////////////////////////////////////// "VOXLEVEL"
@@ -867,7 +956,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                 if(can_transmit) {
                   transmitter->xit = 0;
                   transmitter->xit_enabled = 0;
-                  g_idle_add(ext_vfo_update, NULL);
+                  vfo_update();
                 }
             }
             break;
@@ -895,7 +984,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
               }
               // enable/disable XIT according to XIT value
               transmitter->xit_enabled = (transmitter->xit == 0) ? 0 : 1;
-              g_idle_add(ext_vfo_update, NULL);
+              vfo_update();
            }
             break;
        /////////////////////////////////////////////////////////// "ZOOM"
@@ -911,15 +1000,18 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            switch (type) {
              case MIDI_TYPE_KEY:
                 if (action == MIDI_ACTION_ZOOM) break;
-               new =  (action == MIDI_ACTION_ZOOM_UP) ? 1 :-1;
-                g_idle_add(ext_zoom_update,GINT_TO_POINTER(new));
+               dnew =  (action == MIDI_ACTION_ZOOM_UP) ? 1.0 :-1.0;
+                update_zoom(dnew);
                break;
              case MIDI_TYPE_WHEEL:
-               new = (val > 0) ? 1 : -1;
-                g_idle_add(ext_zoom_update,GINT_TO_POINTER(new));
+               dnew = (val > 0) ? 1.0 : -1.0;
+                update_zoom(dnew);
                break;
               case MIDI_TYPE_KNOB:
-                g_idle_add(ext_zoom_set,GINT_TO_POINTER(val));
+                dnew= 1.0+ 0.07*val;  // from 1.0 to 8.0
+                if((int)dnew != active_receiver->zoom) {
+                  set_zoom(active_receiver->id, dnew);
+                }
                 break;
              default:
                // do nothing
@@ -935,4 +1027,5 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
            // This means we have forgotten to implement an action, so we inform on stderr.
            fprintf(stderr,"Unimplemented MIDI action: A=%d\n", (int) action);
     }
+    return 0;
 }