From: c vw <dl1ycf@darc.de>
Date: Fri, 8 Nov 2019 16:34:24 +0000 (+0100)
Subject: Merge branch 'master' of https://github.com/g0orx/pihpsdr
X-Git-Url: https://git.rkrishnan.org/frontends/simplejson/(%5B%5E?a=commitdiff_plain;h=f4741f686d3ba467ef39408910b2d0908ff4a06e;p=pihpsdr.git

Merge branch 'master' of https://github.com/g0orx/pihpsdr
---

f4741f686d3ba467ef39408910b2d0908ff4a06e
diff --cc ext.c
index bfdcb71,20e72d3..2453f51
--- a/ext.c
+++ b/ext.c
@@@ -591,3 -581,16 +590,17 @@@ int ext_function_update(void *data) 
    return 0;
  }
  
+ int ext_set_rf_gain(void *data) {
+   int pos=GPOINTER_TO_INT(data);
+   double value;
+   value=(double)pos;
+   if(value<0.0) {
+     value=0.0;
+   } else if(value>100.0) {
+     value=100.0;
+   }
+   set_rf_gain(active_receiver->id,value);
+   return 0;
++>>>>>>> baa20fb6e81527751cd7e97f910c6c56880d6898
+ }
+ 
diff --cc midi.h
index 654cea0,2104e43..6aa186c
--- a/midi.h
+++ b/midi.h
@@@ -69,22 -70,23 +70,27 @@@ enum MIDIaction 
    PAN_HIGH,		// "high" value of current panadapter
    PAN_LOW,		// "low" value of current panadapter
    MIDI_PS,		// PURESIGNAL on/off
+   MIDI_RF_GAIN,		// RF gain
 -  MIDI_RIT_CLEAR,	// clear RIT value
 +  RIT_STEP,		// cycle through RIT values
 +  RIT_TOGGLE,  		// RIT on/off
    RIT_VAL,		// change RIT value
+   MIDI_RSAT,		// RSAT on/off
+   MIDI_SAT,		// SAT on/off
    MIDI_SPLIT,		// Split on/off
    SWAP_VFO,		// swap VFO A/B frequency
 +  SWAP_RX, 		// swap active receiver (if there are two receivers)
    MIDI_TUNE,		// toggle "tune" state
    TX_DRIVE,		// RF output power
    VFO,			// change VFO frequency
 +  VFOA,			// change VFO-A frequency
 +  VFOB,			// change VFO-B frequency
    VFO_A2B,		// VFO A -> B
    VFO_B2A,		// VFO B -> A
 -  VOX, 			// VOX on/off
    VFO_STEP_UP,		// cycle through vfo steps upwards;
    VFO_STEP_DOWN,	// cycle through vfo steps downwards;
 +  VOX, 			// VOX on/off
+   MIDI_XIT_CLEAR,	// clear XIT
+   XIT_VAL,		// change XIT value
  };
  
  //
diff --cc midi2.c
index 18e5737,f862bde..4754f52
--- a/midi2.c
+++ b/midi2.c
@@@ -88,52 -84,54 +88,61 @@@ void NewMidiEvent(enum MIDIevent event
  
  /*
   * This data structre connects names as used in the midi.inp file with
-- * our MIDIaction enum values
++ * our MIDIaction enum values.
++ * Take care that no key word is contained in another one!
++ * Example: use "CURRVFO" not "VFO" otherwise there is possibly
++ * a match for "VFO" when the key word is "VFOA".
   */
  
  static struct {
    enum MIDIaction action;
    const char *str;
  } ActionTable[] = {
 -        { AF_GAIN,      "AFGAIN"},
 -        { MIDI_AGC,     "AGC"},
 -	{ AGCATTACK,   	"AGCATTACK"},
 -        { ATT,          "ATT"},
 -        { BAND_DOWN,    "BANDDOWN"},
 -        { BAND_UP,      "BANDUP"},
 -        { COMPRESS,     "COMPRESS"},
 -	{ MIDI_CTUN,  	"CTUN"},
 -	{ MIDI_DUP,  	"DUP"},
 -        { FILTER_DOWN,  "FILTERDOWN"},
 -        { FILTER_UP,    "FILTERUP"},
 -	{ MIDI_LOCK,    "LOCK"},
 -        { MIC_VOLUME,   "MICGAIN"},
 -	{ MODE_DOWN,	"MODEDOWN"},
 -	{ MODE_UP,	"MODEUP"},
 -        { MIDI_MOX,     "MOX"},
 -	{ MIDI_NB,    	"NOISEBLANKER"},
 -	{ MIDI_NR,    	"NOISEREDUCTION"},
 -        { PAN_HIGH,     "PANHIGH"},
 -        { PAN_LOW,      "PANLOW"},
 -        { PRE,          "PREAMP"},
 -	{ MIDI_PS,    	"PURESIGNAL"},
 -	{ MIDI_RF_GAIN, "RFGAIN"},
 -        { MIDI_RIT_CLEAR,"RITCLEAR"},
 -        { RIT_VAL,      "RITVAL"},
 -        { MIDI_RSAT,    "RSAT"},
 -        { MIDI_SAT,     "SAT"},
 -	{ MIDI_SPLIT,  	"SPLIT"},
 -	{ SWAP_VFO,	"SWAPVFO"},
 -        { MIDI_TUNE,    "TUNE"},
 -        { TX_DRIVE,     "RFPOWER"},
 -        { VFO,          "VFO"},
 -	{ VFO_A2B,	"VFOA2B"},
 -	{ VFO_B2A,	"VFOB2A"},
 -	{ VOX,   	"VOX"},
 -	{ VFO_STEP_UP,  "VFOSTEPUP"},
 -	{ VFO_STEP_DOWN,  "VFOSTEPDOWN"},
 -	{ MIDI_XIT_CLEAR,  "XITCLEAR"},
 -	{ XIT_VAL,  "XITVAL"},
 -        { ACTION_NONE,  "NONE"},
 -        { ACTION_NONE,  NULL}
 +        { AF_GAIN,      	"AFGAIN"},
 +        { MIDI_AGC,     	"AGC"},
 +	{ AGCATTACK,   		"AGCATTACK"},
 +        { ATT,          	"ATT"},
 +        { BAND_DOWN,    	"BANDDOWN"},
 +        { BAND_UP,      	"BANDUP"},
 +        { COMPRESS,     	"COMPRESS"},
 +	{ MIDI_CTUN,  		"CTUN"},
++	{ MIDI_DUP,  		"DUP"},
 +        { FILTER_DOWN,  	"FILTERDOWN"},
 +        { FILTER_UP,    	"FILTERUP"},
 +	{ MIDI_LOCK,    	"LOCK"},
 +        { MIC_VOLUME,   	"MICGAIN"},
 +	{ MODE_DOWN,		"MODEDOWN"},
 +	{ MODE_UP,		"MODEUP"},
 +        { MIDI_MOX,     	"MOX"},
 +	{ MIDI_NB,    		"NOISEBLANKER"},
 +	{ MIDI_NR,    		"NOISEREDUCTION"},
 +        { PAN_HIGH,     	"PANHIGH"},
 +        { PAN_LOW,      	"PANLOW"},
 +        { PRE,          	"PREAMP"},
 +	{ MIDI_PS,    		"PURESIGNAL"},
++	{ MIDI_RF_GAIN, 	"RFGAIN"},
 +        { RIT_TOGGLE,   	"RIT"},
 +	{ RIT_STEP, 		"RITSTEP"},
 +        { RIT_VAL,      	"RITVAL"},
++        { MIDI_RSAT,    	"RSAT"},
++        { MIDI_SAT,     	"SAT"},
 +	{ MIDI_SPLIT,  		"SPLIT"},
 +	{ SWAP_RX,		"SWAPRX"},
 +	{ SWAP_VFO,		"SWAPVFO"},
 +        { MIDI_TUNE,    	"TUNE"},
 +        { TX_DRIVE,     	"RFPOWER"},
-         { VFO,          	"VFO"},
++        { VFO,          	"CURRVFO"},
 +        { VFOA,         	"VFOA"},
- 	{ VFO_A2B,		"VFOA2B"},
++	{ VFO_A2B,		"A2B"},
 +        { VFOB,         	"VFOB"},
- 	{ VFO_B2A,		"VFOB2A"},
++	{ VFO_B2A,		"B2A"},
 +	{ VFO_STEP_UP,  	"VFOSTEPUP"},
 +	{ VFO_STEP_DOWN,	"VFOSTEPDOWN"},
 +	{ VOX,   		"VOX"},
++	{ MIDI_XIT_CLEAR,  	"XITCLEAR"},
++	{ XIT_VAL,  		"XITVAL"},
 +        { ACTION_NONE,  	"NONE"},
 +        { ACTION_NONE,  	NULL}
  };
  
  /*
diff --cc midi3.c
index 47569ab,08bbcd2..2f5c260
--- a/midi3.c
+++ b/midi3.c
@@@ -70,225 -98,117 +70,233 @@@ void DoTheMidi(enum MIDIaction action, 
  	    *dp=dnew;
  	    g_idle_add(ext_set_agc_gain, (gpointer) dp);
  	    break;
 -	case TX_DRIVE: // knob or wheel supported
 -	    if (type == MIDI_KNOB) {
 -		dnew = val;
 -	    } else if (type == MIDI_WHEEL) {
 -		dnew=transmitter->drive + val;
 -		if (dnew < 0.0) dnew=0.0; if (dnew > 100.0) dnew=100.0;
 -	    } else {
 +	case AGCATTACK: // only key supported
 +	    // cycle through fast/med/slow AGC attack
 +	    if (type == MIDI_KEY) {
 +	      new=active_receiver->agc + 1;
 +	      if (new > AGC_FAST) new=0;
 +	      active_receiver->agc=new;
 +	      g_idle_add(ext_vfo_update, NULL);
 +	    }
 +	    break;
 +	case ATT:	// 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_attenuation[active_receiver->adc] + val;
 +		  if (new > 31) new=31;
 +		  if (new < 0 ) new=0;
 +		  dp=malloc(sizeof(double));
 +		  *dp=new;
 +		  g_idle_add(ext_set_attenuation_value,(gpointer) dp);
 +		  break;
 +	      case MIDI_KNOB:
 +		new=(31*val)/100;
 +		dp=malloc(sizeof(double));
 +		*dp=new;
 +		g_idle_add(ext_set_attenuation_value,(gpointer) dp);
 +		break;
 +	      default:
 +		// do nothing
 +		// we should not come here anyway
  		break;
  	    }
 -	    dp=malloc(sizeof(double));
 -	    *dp=dnew;
 -	    g_idle_add(ext_set_drive, (gpointer) dp);
  	    break;
 -	case BAND_UP:     // key or wheel supported
 -	case BAND_DOWN:   // key or wheel supported
 -	    if (type == MIDI_KEY) {
 +	case BAND_DOWN:
 +	case BAND_UP:
 +	    switch (type) {
 +	      case MIDI_KEY:
  		new=(action == BAND_UP) ? 1 : -1;
 -	    } else if (type == MIDI_WHEEL) {
 -		new=val;
 -	    } else {
 +		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;
  	    }
 -            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));
 +	    //
 +	    // 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;
 -	case FILTER_UP:      // key or wheel supported
 -	case FILTER_DOWN:    // key or wheel supported
 -	    if (type == MIDI_KEY) {
 -		new=(action == FILTER_UP) ? 1 : -1;
 -	    } else if (type == MIDI_WHEEL) {
 -		new=val;
 -	    } else {
 +	case COMPRESS: // 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;
  	    }
 -	    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));
 +	    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;
 -	case MODE_UP:      // key or wheel supported
 -	case MODE_DOWN:    // key or wheel supported
 +	case MIDI_CTUN: // only key supported
 +	    // toggle CTUN
  	    if (type == MIDI_KEY) {
 -		new=(action == MODE_UP) ? 1 : -1;
 -	    } else if (type == MIDI_WHEEL) {
 -		new=val;
 -	    } else {
 -		break;
 +	      g_idle_add(ext_ctun_update, NULL);
  	    }
 -	    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;
 -	case PAN_LOW:  // only wheel supported
 -	    if (type == MIDI_WHEEL) {
 -		if (isTransmitting()) {
 -		    // TX panadapter affected
 -		    transmitter->panadapter_low += val;
 -		} else {
 -		    active_receiver->panadapter_low += val;
 -		}
++        case MIDI_DUP:
++            if(duplex) {
++              duplex=0;
++            } else {
++              duplex=1;
++            }
++            g_idle_add(ext_vfo_update, NULL);
++            break;
 +	case FILTER_DOWN:
 +	case FILTER_UP:
 +	    //
 +	    // 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_UP) ? -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;
 -	case MIDI_RIT_CLEAR:  // only key supported
 +	case MIDI_LOCK: // only key supported
  	    if (type == MIDI_KEY) {
 -		// this clears the RIT value and disables RIT
 -		vfo[active_receiver->id].rit = 0;
 -		vfo[active_receiver->id].rit_enabled = 0;
 -	        g_idle_add(ext_vfo_update, NULL);
 +	      locked=!locked;
 +	      g_idle_add(ext_vfo_update, NULL);
  	    }
  	    break;
 -	case RIT_VAL:	// only wheel supported
 -	    if (type == MIDI_WHEEL) {
 -		// This changes the RIT value. If a value of 0 is reached,
 -		// RIT is disabled
 -		new = vfo[active_receiver->id].rit + val*rit_increment;
 -		if (new >  10000) new= 10000;
 -		if (new < -10000) new=-10000;
 -		vfo[active_receiver->id].rit = new;
 -		vfo[active_receiver->id].rit_enabled = (new != 0);
 -	        g_idle_add(ext_vfo_update, NULL);
 +	case MIC_VOLUME: // knob or wheel supported
 +	    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;
 -	case MIDI_XIT_CLEAR:  // only key supported
 +	case MODE_DOWN:
 +	case MODE_UP:
 +	    switch (type) {
 +	      case MIDI_KEY:
 +		new=(action == MODE_UP) ? 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;
 +	case MIDI_MOX: // 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);
 -                }
 +	        new = !mox;
 +		g_idle_add(ext_mox_update, GINT_TO_POINTER(new));
 +	    }
 +	    break;    
 +	case MIDI_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;
 -	case XIT_VAL:	// only wheel supported
 -	    if (type == MIDI_WHEEL) {
 -		// This changes the XIT value. If a value of 0 is reached,
 -		// XIT is disabled
 -                if(can_transmit) {
 -		  new = transmitter->xit + val*rit_increment;
 -		  if (new >  10000) new= 10000;
 -		  if (new < -10000) new=-10000;
 -		  transmitter->xit = new;
 -		  transmitter->xit_enabled = (new != 0);
 -	          g_idle_add(ext_vfo_update, NULL);
 -                }
 +	case MIDI_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_vfo_update, NULL);
  	    }
  	    break;
 -	case PAN_HIGH:  // only wheel supported
 -	    if (type == MIDI_WHEEL) {
 +	case PAN_HIGH:  // wheel or knob
 +	    switch (type) {
 +	      case MIDI_WHEEL:
  		if (mox) {
  		    // TX panadapter affected
  		    transmitter->panadapter_high += val;
@@@ -366,91 -243,136 +374,120 @@@
  		g_idle_add(ext_update_att_preamp, NULL);
  	    }
  	    break;
 -	case ATT:	// 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:
 -		case MIDI_KNOB:
 -		    if (type == MIDI_WHEEL) {
 -		      new=adc_attenuation[active_receiver->adc] + val;
 -		      if (new > 31) new=31;
 -		      if (new < 0 ) new=0;
 -		    } else {
 -		      new=(31*val)/100;
 -		    }
 -		    dp=malloc(sizeof(double));
 -		    *dp=new;
 -		    g_idle_add(ext_set_attenuation_value,(gpointer) dp);
 -		    break;
 -		default:
 -		    break;
 +	case MIDI_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;
 -	case COMPRESS:
 -	    // Use values in the range 0 ... 20
 -            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 {
 -		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);
++        case MIDI_RF_GAIN: // knob or wheel supported
++            if (type == MIDI_KNOB) {
++                new=val;
++            } else  if (type == MIDI_WHEEL) {
++                new=(int)active_receiver->rf_gain+val;
+             }
++            g_idle_add(ext_set_rf_gain, GINT_TO_POINTER((int)val));
 +	case TX_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;
 -	case MIDI_NB:
 -	    // cycle through NoiseBlanker settings
 -	    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;
++	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);
++	    }
 +	case RIT_TOGGLE:  // 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);
  	    }
 -	    g_idle_add(ext_vfo_update, NULL);
  	    break;
 -	case MIDI_NR:
 -	    // cycle through NoiseReduction settings
 -	    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;
 +	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;
 -	case VOX:
 -	    // toggle VOX
 -            if(can_transmit) {
 -	      vox_enabled = !vox_enabled;
 -	      g_idle_add(ext_vfo_update, NULL);
 -            }
 -	    break;
 -	case MIDI_CTUN:
 -	    // toggle CTUN
 -	    new=active_receiver->id;
 -	    if(!vfo[new].ctun) {
 -		vfo[new].ctun=1;
 -		vfo[new].offset=0;
 -	    } else {
 -		vfo[new].ctun=0;
 -	    }
 -	    vfo[new].ctun_frequency=vfo[new].frequency;
 -	    set_offset(active_receiver,vfo[new].offset);
 +	case RIT_VAL:	// 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;
 +	    }
  	    g_idle_add(ext_vfo_update, NULL);
  	    break;
 -        case MIDI_DUP:
 -            if(duplex) {
 -              duplex=0;
 -            } else {
 -              duplex=1;
 -            }
 -            g_idle_add(ext_vfo_update, NULL);
 -            break;
+         case MIDI_RSAT:
+             if(sat_mode==RSAT_MODE) {
+               sat_mode=SAT_NONE;
+             } else {
+               sat_mode=RSAT_MODE;
+             }
+             g_idle_add(ext_vfo_update, NULL);
+             break;
+         case MIDI_SAT:
+             if(sat_mode==SAT_MODE) {
+               sat_mode=SAT_NONE;
+             } else {
+               sat_mode=SAT_MODE;
+             }
+             g_idle_add(ext_vfo_update, NULL);
+             break;
 -	case MIDI_PS:
 -#ifdef PURESIGNAL
 -	    // toggle PURESIGNAL
 -            if(can_transmit) {
 -	      new=!(transmitter->puresignal);
 -	      g_idle_add(ext_tx_set_ps,GINT_TO_POINTER(new));
 -            }
 -#endif
 -	    break;
 -	case MIDI_SPLIT:
 +	case MIDI_SPLIT: // only key supported
  	    // toggle split mode
 -            if(can_transmit) {
 -              if(!split) {
 +	    if (type == MIDI_KEY) {
 +	      if(!split) {
  		split=1;
  		tx_set_mode(transmitter,vfo[VFO_B].mode);
  	      } else {
@@@ -458,77 -380,30 +495,101 @@@
  		tx_set_mode(transmitter,vfo[VFO_A].mode);
  	      }
  	      g_idle_add(ext_vfo_update, NULL);
 -            }
 +	    }
  	    break;
 -	case VFO_A2B:
 -	    g_idle_add(ext_vfo_a_to_b, NULL);
 +	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;    
 +	case SWAP_VFO:	// only key supported
 +	    if (type == MIDI_KEY) {
 +		g_idle_add(ext_vfo_a_swap_b,NULL);
 +	    }
 +	    break;    
 +	case MIDI_TUNE: // only key supported
 +	    if (type == MIDI_KEY) {
 +	        new = !tune;
 +		g_idle_add(ext_tune_update, GINT_TO_POINTER(new));
 +	    }
 +	    break;    
 +	case VFO: // only wheel supported
 +	    if (type == MIDI_WHEEL && !locked) {
 +		g_idle_add(ext_vfo_step, GINT_TO_POINTER(val));
 +	    }
  	    break;
 -	case VFO_B2A:
 -	    g_idle_add(ext_vfo_b_to_a, NULL);
 +	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;
 -	case MIDI_LOCK:
 -	    locked=!locked;
 -	    g_idle_add(ext_vfo_update, NULL);
 +	case VFO_A2B: // only key supported
 +	    if (type == MIDI_KEY) {
 +	      g_idle_add(ext_vfo_a_to_b, NULL);
 +	    }
  	    break;
 -	case AGCATTACK:
 -	    new=active_receiver->agc + 1;
 -	    if (new > AGC_FAST) new=0;
 -	    active_receiver->agc=new;
 -	    g_idle_add(ext_vfo_update, NULL);
 +	case VFO_B2A: // only key supported
 +	    if (type == MIDI_KEY) {
 +	      g_idle_add(ext_vfo_b_to_a, NULL);
 +	    }
  	    break;
 +        case VFO_STEP_DOWN: // key or wheel supported
          case VFO_STEP_UP:
 -	    g_idle_add(ext_update_vfo_step, GINT_TO_POINTER(1));
 +	    switch (type) {
 +	      case MIDI_KEY:
 +		new =  (action == VFO_STEP_UP) ? 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;
 -        case VFO_STEP_DOWN:
 -	    g_idle_add(ext_update_vfo_step, GINT_TO_POINTER(-1));
 +	case VOX: // only key supported
 +	    // toggle VOX
 +	    if (type == MIDI_KEY) {
 +	      vox_enabled = !vox_enabled;
 +	      g_idle_add(ext_vfo_update, NULL);
 +	    }
 +	    break;
++        case MIDI_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;
++        case XIT_VAL:   // only wheel supported
++            if (type == MIDI_WHEEL) {
++                // This changes the XIT value. If a value of 0 is reached,
++                // XIT is disabled
++                if(can_transmit) {
++                  new = transmitter->xit + val*rit_increment;
++                  if (new >  10000) new= 10000;
++                  if (new < -10000) new=-10000;
++                  transmitter->xit = new;
++                  transmitter->xit_enabled = (new != 0);
++                  g_idle_add(ext_vfo_update, NULL);
++                }
++            }
+             break;
  	case ACTION_NONE:
  	    // No error message, this is the "official" action for un-used controller buttons.
  	    break;
diff --cc vfo.h
index af9114c,9ad802b..101a9b5
--- a/vfo.h
+++ b/vfo.h
@@@ -66,8 -66,7 +66,8 @@@ extern char *step_labels[]
  
  extern GtkWidget* vfo_init(int width,int height,GtkWidget *parent);
  extern void vfo_step(int steps);
 +extern void vfo_id_step(int id, int steps);
- extern void vfo_move(long long hz);
+ extern void vfo_move(long long hz,int round);
  extern void vfo_move_to(long long hz);
  extern void vfo_update();
  extern void set_frequency();