# Simple Switching Script for Multis



## EforEclectic (Jan 13, 2013)

This may well be answered someplace, and if it has, kindly point me at the solution. 

I would like to create multis for a single instrument section which can keyswitch/velocity switch between the different instruments. I have Mind Control right now, but when MC is loaded, you can't access the instrument's panel properly because all the instruments have to be loaded in a bank.

Is there a script out there which allow me to easily keyswitch/velocity switch between instruments for a multi?

I'm having some stability issues with Banks and large instruments causing VEP to hang when loading, which causes the whole template to crash and have to start over. Considering that there seems to be roughly a 10% chance of this happening, and I load about 15 instances of mind control, it usually takes 10 or more attempts to get the whole template to load properly. But my old template (pre mind control) where each instrument gets its own midi channel, I have no issues at all, other than the fact that I have to run a single instrument section through several midi channels, and it is much easier to think about a section's part when it isn't split across 6 channels. 

Cheers!


----------



## Fedor (Jan 14, 2013)

I think TransMIDIfier will be useful for this. Its a standalone midi app, not a multiscript, but very handy. http://www.bewaryprods.com/software/pro ... sMIDIfier/


----------



## Raptor4 (Jan 14, 2013)

Hi EforEclectic,

If I understand correctly you want to use a Multiscript to change the incoming midi channel via key switches (KS) right?
If yes I have a good new for you... Today I had some time to write such script.
By the way this kind of midi complex tools may cause terrible note hanging during the KS. Example: if you have some held notes on instrument A and switch to instrument B, when you release the old layering notes A they will hand/sustain for ever cause their note OFFs will go to instrument B etc.
Well just follow the instructions.

UI Controls (See the image below)

1. Min (KS) here you assign the min KS.
2. Max (KS). *Note:* This assignment MUST match the number of the instruments loaded into the Kontakt. In my scenario I have loaded three instruments set to midi ch.1,2 & 3. In this example C1 will switch to ch.1; C#1 >ch2; D>ch3. If you have set range C1 - G1 and you have only two instruments when you play KS E1 no sound will be produced!
3. This the Channel Monitor which will show the new midi channel during the key switching.

Operation

Play the KS to switch to the channel you want (the Midi Ch. monitor label will show that channel). Play some music on the sample keys for that instrument. 
You can even hold a few notes and switch to new channel via the KS. During the KS switching the old playing notes will still sound. Now play another note in the play sample range - DONE! The new patch will come and the old held notes will be killed.
This is called "smart" switching which will prevent from any hanging notes I was talking about in the beginning.
By the way it's not still the best which can emulate the hardware program "smooth" patch change. I have developed that for other midi environments in the pass so if I have time I will try to update that version to such "Intelligent smooth switching"...








```
{***********************************************
Midi Channel Key Switcher v1.0
Author: www.audiogrocery.com
Written by: Ivan Kovachev 
Modified: January 14, 2013
*************************************************}
on init
  message("AG Trade Mark")
  set_script_title("Midi Channel KS")
  set_ui_height(1)
  declare ui_label $KS_label(2, 1) 
  set_text($KS_label,"KS Range")
  set_control_par(get_ui_id($KS_label),$CONTROL_PAR_TEXT_ALIGNMENT,1)
  declare ui_value_edit $Min(0, 127, 0) 
  declare ui_value_edit $Max(0, 127, 0) 
  declare $Active_KS
  declare $Last_KS
  declare ui_label $KS_Monitor(1, 1) 
  set_text($KS_Monitor,"Midi Ch:")
  move_control($KS_label,2,1)
  move_control($Min,2,2)
  move_control($Max,3,2)
  move_control($KS_Monitor,5,1)
  make_persistent($Min)
  make_persistent($Max)
  make_persistent($Active_KS)
  _read_persistent_var($Active_KS)
  set_text($KS_Monitor,"Midi Ch:    " & ($Active_KS+1))
end on

on ui_control($Min)
  if ($Min>$Max)
    $Max := $Min
  end if
end on

on ui_control($Max)
  if ($Max<$Min)
    $Min := $Max
  end if
end on

on midi_in
  if ($MIDI_COMMAND=$MIDI_COMMAND_NOTE_ON and ($MIDI_BYTE_2>0))
    if (in_range($MIDI_BYTE_1,$Min,$Max))
      if ($EVENT_NOTE-$Min=$Active_KS)
        exit
      else
        $Last_KS := $Active_KS
        $Active_KS := $EVENT_NOTE-$Min
        set_text($KS_Monitor,"Midi Ch:    " & ($Active_KS+1))
        ignore_midi
      end if
    end if
  end if
  if ($MIDI_BYTE_1<$Min or ($MIDI_BYTE_1>$Max))
    set_event_par($EVENT_ID,$EVENT_PAR_MIDI_CHANNEL,$Active_KS)
    set_midi($Last_KS,$MIDI_COMMAND_CC,123,127)
  end if
end on
```
Get the Multi preset (NKP) file from the attachment below (in case you want to use as a Multiscript user Preset) and place it into the directory shown below.
If you are a PC user place the Midi Channel KS v1.0.nkp file into: 
C:\Documents and Settings\User\My Documents\Native Instruments\Kontakt 5\presets\Multiscripts
If you are a MAC user place the Midi Channel KS v1.0 file into: 
Local Drive\Users\User\Documents\Native Instruments\Kontakt 5\presets\Multiscripts 

Regards


----------



## davidgary73 (Jan 14, 2013)

EforEclectic, you can also try KS Router by orangetreessamples @ http://www.orangetreesamples.com/blog/2 ... ltiscript/

Cheers


----------



## EforEclectic (Jan 14, 2013)

Thanks guys - I will test these out tomorrow. Hopefully one of them does the trick nicely.

Thanks for taking the time to write it up Raptor4!

Cheers!


----------



## TGV (Jan 15, 2013)

Some time ago I wrote one too. It's a bit more complex than the one of Raptor4. It does switching based on key, CC or program change. It also allows you to use the switch while holding a key (Raptor4's version will make the note stick, I'm afraid), and it will send all current values for all controls to the newly selected patch.

You can find it here: http://www.vi-control.net/forum/viewtopic.php?t=28342


----------



## Raptor4 (Jan 15, 2013)

I had some time to fix a few problems and create version 1.1. Now the KS do not stack and the channel change offers "smooth patch switching" like I was talking about in the end of my previous post. The operation rules are valid as described in my 1st post.
By the way this scrip was just for fun. Here is the new version in the attachment.

TGV, thanks for posting your version! I could download, unpack and load it into the KSP Multi processor but no UI is loaded either any text script in the editor?
I see that you have packed that NKP on MAC (I have tried on PC today). I'm away of my MAC, so I'll try it there later. I see you are Logic user - heh I have developed such complex tool(s) as Logic Environment tools so you can use with any Software Instrument not Kontakt only by the way...
Regards
R4


----------



## TGV (Jan 15, 2013)

It isn't much of UI, but it should show up. It allows you to change the channel to which it listens and the switching mode (key, CC, PC). Here's the raw text.


```
on init
  
  { this is the channel chosen by the latest matching CC command }
  declare $active_channel
  $active_channel := 0
  
  { stores the channel for each active note; 0 means not active }
  declare %active_notes[128] := (-1)
  
  { stores the latest values for the CCs; -1 means nothing received }
  declare %cc_values[128] := (-1)
  declare $i
  
  { create UI }
  
  set_ui_height_px(54)
  
  { note names for the interface }  
  declare !note_names[128]
  declare $count
  while ($count < 128)
    !note_names[$count + 0] := "C" & (($count/12)-2)
    !note_names[$count + 1] := "Db" & (($count/12)-2)
    !note_names[$count + 2] := "D" & (($count/12)-2)
    !note_names[$count + 3] := "Eb" & (($count/12)-2)
    !note_names[$count + 4] := "E" & (($count/12)-2)
    !note_names[$count + 5] := "F" & (($count/12)-2)
    !note_names[$count + 6] := "Gb" & (($count/12)-2)
    !note_names[$count + 7] := "G" & (($count/12)-2)
    if ($count < 120)
      !note_names[$count + 8] := "Ab" & (($count/12)-2)
      !note_names[$count + 9] := "A" & (($count/12)-2)
      !note_names[$count + 10] := "Bb" & (($count/12)-2)
      !note_names[$count + 11] := "B" & (($count/12)-2)
    end if
    $count := $count + 12
  end while
  
  { define UI controls }
  
  declare ui_label $msgb(1, 1)
  move_control_px($msgb, 60, 22)
  set_text($msgb, "")
  
  { type of channel switch }
  declare ui_menu $switch_type
  add_menu_item($switch_type, "bypass", 0)
  add_menu_item($switch_type, "control", 1)
  add_menu_item($switch_type, "program change", 2)
  add_menu_item($switch_type, "key switch", 3)
  make_persistent($switch_type)
  _read_persistent_var($switch_type)
  
  declare ui_knob $cc(0, 127, 1)
  set_text($cc, "CC")
  set_knob_defval($cc, 4)
  make_persistent($cc)
  _read_persistent_var($cc)
  
  declare ui_knob $switch_channel(0, 16, 1)
  move_control_px($switch_channel, 150, 0)
  set_text($switch_channel, "Channel")
  set_knob_defval($switch_channel, 1)
  make_persistent($switch_channel)
  _read_persistent_var($switch_channel)
  if ($switch_channel = 0)
    set_knob_label($switch_channel, "Omni")
  end if
  
  declare ui_knob $lowkey(0, 127, 1)
  set_knob_label($lowkey, !note_names[$lowkey])
  set_text($lowkey, "Lowest")
  set_knob_defval($lowkey, 12)
  make_persistent($lowkey)
  _read_persistent_var($lowkey)
  set_knob_label($lowkey, !note_names[$lowkey])
  
  declare ui_knob $keyrange(0, 15, 1)
  set_text($keyrange, "Highest")
  set_knob_defval($keyrange, 0)
  make_persistent($keyrange)
  _read_persistent_var($keyrange)
  set_knob_label($keyrange, !note_names[$lowkey + $keyrange])
  
  { code from move_variable_controls }
  select ($switch_type)
    case 0
      move_control($cc, 0, 0)
      move_control($lowkey, 0, 0)
      move_control($keyrange, 0, 0)
    case 1
      move_control_px($cc, 240, 0)
      move_control($lowkey, 0, 0)
      move_control($keyrange, 0, 0)
    case 2
      move_control($cc, 0, 0)
      move_control($lowkey, 0, 0)
      move_control($keyrange, 0, 0)
    case 3
      move_control_px($lowkey, 240, 0)
      move_control_px($keyrange, 330, 0)
      move_control($cc, 0, 0)
  end select
  
end on { init }

function move_variable_controls
  select ($switch_type)
    case 0
      move_control($cc, 0, 0)
      move_control($lowkey, 0, 0)
      move_control($keyrange, 0, 0)
    case 1
      move_control_px($cc, 240, 0)
      move_control($lowkey, 0, 0)
      move_control($keyrange, 0, 0)
    case 2
      move_control($cc, 0, 0)
      move_control($lowkey, 0, 0)
      move_control($keyrange, 0, 0)
    case 3
      move_control_px($lowkey, 240, 0)
      move_control_px($keyrange, 330, 0)
      move_control($cc, 0, 0)
  end select
end function

on ui_control($switch_type)
  call move_variable_controls
end on

on ui_control($switch_channel)
  if ($switch_channel = 0)
    set_knob_label($switch_channel, "Omni")
  else
    set_knob_label($switch_channel, $switch_channel)
  end if
end on

on ui_control($lowkey)
  set_knob_label($lowkey, !note_names[$lowkey])
  set_knob_label($keyrange, !note_names[$lowkey + $keyrange])
end on

on ui_control($keyrange)
  set_knob_label($keyrange, !note_names[$lowkey + $keyrange])
end on

function update_channel
  set_text($msgb, "active: " & $active_channel)
  $i := 0
  while ($i # 128)
    if (%cc_values[$i] # -1)
      set_midi($active_channel, $MIDI_COMMAND_CC, $i, %cc_values[$i])
    end if
    inc($i)
  end while
end function

on midi_in
  if ($MIDI_CHANNEL = $switch_channel - 1 or $switch_channel = 0)
    select ($MIDI_COMMAND)
      case $MIDI_COMMAND_CC
        if ($switch_type = 1 and $MIDI_BYTE_1 = $cc and $MIDI_BYTE_2 # 0)
          $active_channel := $MIDI_BYTE_2
          call update_channel
          ignore_midi
        else
          if ($switch_type # 0 and $active_channel > 0)
            %cc_values[$MIDI_BYTE_1] := $MIDI_BYTE_2
            set_event_par($EVENT_ID, $EVENT_PAR_MIDI_CHANNEL, $active_channel - 1)
          end if
        end if
      case $MIDI_COMMAND_PROGRAM_CHANGE
        if ($switch_type = 2 and $MIDI_BYTE_1 # 0)
          $active_channel := $MIDI_BYTE_1
          call update_channel
          ignore_midi
        end if
      case $MIDI_COMMAND_NOTE_ON
        if ($switch_type = 3 and in_range($MIDI_BYTE_1, $lowkey, $lowkey + $keyrange - 1) and $MIDI_BYTE_2 > 0)
          $active_channel := $MIDI_BYTE_1 - $lowkey + 1
          call update_channel
          ignore_midi
        else
          if ($MIDI_BYTE_2 > 0)
            if ($switch_type > 0 and $active_channel > 0)
              set_event_par($EVENT_ID, $EVENT_PAR_MIDI_CHANNEL, $active_channel - 1)
              if (%active_notes[$MIDI_BYTE_1] # 0)
                set_midi(%active_notes[$MIDI_BYTE_1], $MIDI_COMMAND_NOTE_OFF, $MIDI_BYTE_1, 64)
              end if
              %active_notes[$MIDI_BYTE_1] := $active_channel - 1
            end if
          else
            if (%active_notes[$MIDI_BYTE_1] # -1)
              set_event_par($EVENT_ID, $EVENT_PAR_MIDI_CHANNEL, %active_notes[$MIDI_BYTE_1])
              %active_notes[$MIDI_BYTE_1] := -1
            end if
          end if
        end if
      case $MIDI_COMMAND_NOTE_OFF
        if (%active_notes[$MIDI_BYTE_1] # -1)
          set_event_par($EVENT_ID, $EVENT_PAR_MIDI_CHANNEL, %active_notes[$MIDI_BYTE_1])
          %active_notes[$MIDI_BYTE_1] := -1
        end if
    end select
  end if
end on
```


----------

