Switching articulation of instruments

I have a bunch orchestral instruments with different articulations. The articulations can be switched via the keys from A to B in the lowest end of the keyboard.

I built three led buttons for each instrument, that work like radio-buttons (only one is active at the time) and trigger those keys as well. I can choose my articulations via the buttons and all will be stored in the Rackspace Variation.

The manual switching fron the keyboard still works. Those temporary changes are not stored in the variation but are indicated by LEDs underneath the buttons.

image

The script was a bit tricky to implement, because the “On WidgetValueChanged”-function is called, even if you change the value via script.

Here is the code snipped just for the Oboe.
The declarations in the beginning and the callback functions at the end have to be repeated for every instrument. The functions in the middle are fully parameterized.

Hope this is useful for anyone.

// DO NOT EDIT THIS SECTION MANUALLY
Var
   OboeMidi : MidiInBlock
   OboeA : Widget
   OboeB : Widget
   OboeAis : Widget
   OboeLedB : Widget
   OboeLedAis : Widget
   OboeLedA : Widget
//$</AutoDeclare>


   OboeRadio : Widget Array
   OboeLed : widget Array
  

initialization
   var i : integer
   OboeRadio = [OboeA,OboeAis,OboeB] 
   OboeLed = [OboeLedA,OboeLedAis,OboeLedB]
end



// **** sends Note to MidiInBlock


Function SendKeySwitch (MidiBlock: MidiInBlock, Note: integer)
  var Message: MidiMessage   
  Message:= MakeNoteMessage(Note, 100)
  Print (Note)
  SendNow(MidiBlock,Message)   // send with low Velocity
  SendNow(MidiBlock,ReinterpretAsNoteOffMessage(Message)) //and Note Off
End


// ****  when RadioButton is pressed ****


Function SetRadio(MidiBlock: MidiInBlock, LedArray: Widget Array, RadioArray: Widget Array, StartKey: integer, Index : integer, Value : Double)
  var i: integer
 
  if Value>0 then  // has the button been activated?
    SetWidgetValue(LedArray[Index], 1) 
    for i = 0; i < Size(RadioArray); i = i + 1 do  // deactivate all others
      if not (i==Index) then
        SetWidgetValue(RadioArray[i], 0) 
        SetWidgetValue(LedArray[i], 0) 
      end
    end
  end
   
End


// ****  when an LED is activated ****


Function SetLed(MidiBlock: MidiInBlock, LedArray: Widget Array, StartKey: integer, Index : integer, Value : Double)
  var i: integer
 
  if Value>0 then  // has the LED been activated?
    SendKeySwitch (MidiBlock, StartKey+Index)    // send KeySwitch Note  
    for i = 0; i < Size(LedArray); i = i + 1 do  // deactivate all others
      if not (i==Index) then
        SetWidgetValue(LedArray[i], 0) 
      end
    end
  end
   
End

// ****  when a KeySwitch has been pressed manually on the keyboard ****

Function ManualKeyswitch(MidiBlock: MidiInBlock, LedArray: Widget Array, StartKey: integer, Note:NoteMessage)
    var Index: integer
    Index:=GetNoteNumber(Note)-StartKey 
    SetWidgetValue(LedArray[Index], 1)     
end





On WidgetValueChanged(val : double) from OboeA
   SetRadio(OboeMidi, OboeLed, OboeRadio, A-1, 0, val)
end

On WidgetValueChanged(val : double) from OboeAis
   SetRadio(OboeMidi, OboeLed, OboeRadio, A-1, 1, val)
end

On WidgetValueChanged(val : double) from OboeB
   SetRadio(OboeMidi, OboeLed, OboeRadio, A-1, 2, val)
end

On WidgetValueChanged(val : double) from OboeLedA
   SetLed(OboeMidi, OboeLed, A-1, 0, val)
end

On WidgetValueChanged(val : double) from OboeLedAis
   SetLed(OboeMidi, OboeLed, A-1, 1, val)
end

On WidgetValueChanged(val : double) from OboeLedB
   SetLed(OboeMidi, OboeLed, A-1, 2, val)
end

On NoteOnEvent(Note: NoteMessage) From OboeMidi
    if Note in [A-1..B-1] then
       ManualKeyswitch(OboeMidi, OboeLed, A-1, Note)
    else
       SendNow(OboeMidi, Note)
    end
end
4 Likes

As pianopaul and David-san pointed out, the last callback function can be shortened like that:

On NoteOnEvent(Note: NoteMessage) matching [A-1..B-1] From OboeMidi
       ManualKeyswitch(OboeMidi, OboeLed, A-1, Note)
end

Somehow I am not able to change that in my initial post.