# Change cc midi channel in Instrument Scripts



## Geoffury (Aug 31, 2010)

Hi

I'm just starting to change over to Kontakt 4 from EXS24 where I've been using midi channels to select articulations in one instance of EXS. In the EXS you can have the controllers on one channel affecting all the articulations, but Kontakt does things differently.

I now have a different Kontakt Instrument on a different midi channel for each Articulation but the controllers only affect one channel at a time.

Is there a way to have a script in every instrument that changes the cc midi channel to that of the instrument?

Thanks in advance


----------



## kotori (Aug 31, 2010)

If you use instrument banks and program change see http://www.traktordj.com/forum/showthread.php?t=68052&page=2

I'm not sure if there is any script that does this for midi channels, but it should be quite simple I think. Here is a very basic multi script that you could use as a start point:

```
on midi_in
  if ($MIDI_COMMAND = $MIDI_COMMAND_CC and $MIDI_CHANNEL = 0)     
    set_midi(1, $MIDI_COMMAND, $MIDI_BYTE_1, $MIDI_BYTE_2)    
  end if 
end on
```

Expressed in plain english: "if the midi data is a CC message and the channel is 0 (the first), then send the same message on midi channel 1 (the second channel)."
The midi channel can range from 0 to 63 (16 channels times 4 ports) when Kontakt is used as a plugin.

Please be sure to load it as a multi script and not on an instrument since the latter wouldn't work. Click the script icon to the next of the AUX button at the top-right of the user interface to show the multi script view. I hope this helps.

/Nils


----------



## Geoffury (Aug 31, 2010)

Hi

Thanks Nils for your suggestion. I think a multi script will solve my problem. Is it possible to do this:

whatever midi channel comes in, send data out on channels 0-15, but leave note data on original channel.

I can do this in logics environment but it will take me a while to get up to speed in kontakt scripting.

Geoff


----------



## EvilDragon (Aug 31, 2010)

Yes, it's possible to do stuff like that. So, you basically want to multiplex everything EXCEPT the note data to all other channels?

So, if you have a CC1 on channel 7, the same CC1 events would be sent out on channels 1-6, 8-16?


----------



## Geoffury (Aug 31, 2010)

Hi

Yes Evil, that's it. I can see how it would work using Nils example a multi times for each possible input and output channel, just not knowledgable enough at this point to do it more economically using the scripting.


----------



## EvilDragon (Aug 31, 2010)

Fairly easy (if my nested while loops turn out to be correct, I have no material to test this on):


```
on init
	declare $a
	declare $b
end on

on midi_in
	$a := 0
	while ($a < 16)
		$b := 0
		while  ($b < 16)
			if ($MIDI_COMMAND # $MIDI_COMMAND_NOTE_ON and $MIDI_COMMAND # $MIDI_COMMAND_NOTE_OFF and $MIDI_CHANNEL = $a)
				if ($b # $a)
					set_midi($b,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
				end if
			end if
			inc($b)
		end while
		inc($a)
	end while
end on
```


----------



## Geoffury (Aug 31, 2010)

Thanks evil, that does the trick. Seems to increase the cpu a bit with heavy cc use, so will have to see if it's too much when I have my whole template using K4. 

I might be able to change the script so the heavily used ccs stay on their original channels like the notes and don't get multiplexed (just means more editing in the track)

Thanks again for your help


----------



## EvilDragon (Sep 1, 2010)

Well, the script could be expanded. What do you say about having two tables: one table with 16 columns to select to which channels events would get multiplexed, one table with 128 columns to select which CCs would get multiplexed, then buttons for other events like pitch bend, RPN/NRPN, Channel AT, Poly AT?

The only thing that could be problematic is fiddliness of the big CC table. Perhaps breaking that down in 2 tables of 64? Like this:

http://a.imageshack.us/img716/9403/2xtable.png


----------



## Geoffury (Sep 1, 2010)

Yes that's what I had in mind but just buttons to selected a few of the most used CCs say 1 2 4 11 along with PB and Channel AT.


----------



## EvilDragon (Sep 1, 2010)

This is a wholesome solution, on the other hand 


EDIT: And here's the complete script. I hope this should work. Please report the CPU usage of this version of the script - it has a lot more queries, but I hope it should work faster if you activate only a few event types.

[code:1:d26665bdc1]on init
set_ui_height_px(150)
declare ui_label $title (5,1)
declare ui_label $label1 (1,1)
declare ui_label $label2 (1,1)
declare ui_label $label3 (1,1)
declare ui_label $label4 (1,1)
declare ui_label $label5 (1,1)
declare ui_label $fake1 (1,1)
declare ui_label $fake2 (1,1)

declare ui_button $PB
declare ui_button $RPN
declare ui_button $CAT
declare ui_button $PAT

declare ui_table %CC1[64] (1,1,1)
declare ui_table %CC2[64] (1,1,1)
declare ui_table %ChIn[16] (1,1,1)
declare ui_table %ChOut[16] (1,1,1)

declare $a
declare $loop1
declare $loop2
declare $loop3
declare $loop4

declare %copy1[64]
declare %copy2[64]
declare %copy3[16]
declare %copy4[16]

declare !state[2]
!state[0] := "Off"
!state[1] := "On"

set_text($title,"MIDI Event Channel Multiplexer ")
set_text($label1,"Event Types: ")
set_text($label2,"CC Events: ")
set_text($label3,"From Channels: ")
set_text($label4,"To Channels: ")
set_text($label5,"")
set_text($fake1,"")
set_text($fake2,"")
set_text($PB,"Pitch Bend ")
set_text($RPN,"RPN/NRPN ")
set_text($CAT,"Mono Aftertouch ")
set_text($PAT,"Poly Aftertouch ")

set_control_par(get_ui_id(%CC1),$CONTROL_PAR_WIDTH,454)
set_control_par(get_ui_id(%CC1),$CONTROL_PAR_HEIGHT,22)
set_control_par(get_ui_id(%CC1),$CONTROL_PAR_POS_X,151)
set_control_par(get_ui_id(%CC1),$CONTROL_PAR_POS_Y,44)
set_control_par(get_ui_id(%CC2),$CONTROL_PAR_WIDTH,454)
set_control_par(get_ui_id(%CC2),$CONTROL_PAR_HEIGHT,22)
set_control_par(get_ui_id(%CC2),$CONTROL_PAR_POS_X,151)
set_control_par(get_ui_id(%CC2),$CONTROL_PAR_POS_Y,61)
set_control_par(get_ui_id(%ChIn),$CONTROL_PAR_WIDTH,454)
set_control_par(get_ui_id(%ChIn),$CONTROL_PAR_POS_X,151)
set_control_par(get_ui_id(%ChIn),$CONTROL_PAR_POS_Y,86)
set_control_par(get_ui_id(%ChOut),$CONTROL_PAR_WIDTH,454)
set_control_par(get_ui_id(%ChOut),$CONTROL_PAR_POS_X,151)
set_control_par(get_ui_id(%ChOut),$CONTROL_PAR_POS_Y,107)
set_control_par(get_ui_id($title),$CONTROL_PAR_WIDTH,453)
set_control_par(get_ui_id($title),$CONTROL_PAR_POS_X,152)
set_control_par(get_ui_id($title),$CONTROL_PAR_POS_Y,2)
set_control_par(get_ui_id($label5),$CONTROL_PAR_WIDTH,85)
set_control_par(get_ui_id($label5),$CONTROL_PAR_POS_X,520)
set_control_par(get_ui_id($label5),$CONTROL_PAR_POS_Y,23)
set_control_par(get_ui_id($title),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par(get_ui_id($label1),$CONTROL_PAR_TEXT_ALIGNMENT,2)
set_control_par(get_ui_id($label2),$CONTROL_PAR_TEXT_ALIGNMENT,2)
set_control_par(get_ui_id($label3),$CONTROL_PAR_TEXT_ALIGNMENT,2)
set_control_par(get_ui_id($label4),$CONTROL_PAR_TEXT_ALIGNMENT,2)
set_control_par(get_ui_id($PB),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par(get_ui_id($CAT),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par(get_ui_id($PAT),$CONTROL_PAR_TEXT_ALIGNMENT,1)
set_control_par(get_ui_id($RPN),$CONTROL_PAR_TEXT_ALIGNMENT,1)

move_control($label1,1,2)
move_control_px($label2,60,55)
move_control($label3,1,5)
move_control($label4,1,6)
move_control($fake1,1,3)
move_control($fake2,1,4)

move_control($PB,2,2)
move_control($CAT,3,2)
move_control($PAT,4,2)
move_control($RPN,5,2)

make_persistent($PB)
make_persistent($CAT)
make_persistent($PAT)
make_persistent($RPN)
make_persistent(%CC1)
make_persistent(%CC2)
make_persistent(%ChIn)
make_persistent(%ChOut)
make_persistent(%copy1)
make_persistent(%copy2)
make_persistent(%copy3)
make_persistent(%copy4)

message("")
end on

on ui_control($PB)
set_text($label5,"Pitch Bend: " & !state[$PB])
end on

on ui_control($CAT)
set_text($label5,"Mono AT: " & !state[$CAT])
end on

on ui_control($PAT)
set_text($label5,"Poly AT: " & !state[$PAT])
end on

on ui_control($RPN)
set_text($label5,"RPN/NRPN: " & !state[$RPN])
end on

on ui_control(%CC1)
$a := 0
while ($a < 64)
if (%CC1[$a] # %copy1[$a])
set_text($label5,"CC #" & $a & ": " & !state[%CC1[$a]])
end if
%copy1[$a] := %CC1[$a]
inc($a)
end while
end on

on ui_control(%CC2)
$a := 0
while ($a < 64)
if (%CC2[$a] # %copy2[$a])
set_text($label5,"CC #" & $a+64 & ": " & !state[%CC2[$a]])
end if
%copy2[$a] := %CC2[$a]
inc($a)
end while
end on

on ui_control(%ChIn)
$a := 0
while ($a < 16)
if (%ChIn[$a] # %copy3[$a])
set_text($label5,"Input Ch. " & $a+1 & ": " & !state[%ChIn[$a]])
end if
%copy3[$a] := %ChIn[$a]
inc($a)
end while
end on

on ui_control(%ChOut)
$a := 0
while ($a < 16)
if (%ChOut[$a] # %copy4[$a])
set_text($label5,"Output Ch. " & $a+1 & ": " & !state[%ChOut[$a]])
end if
%copy4[$a] := %ChOut[$a]
inc($a)
end while
end on

on midi_in
$loop1 := 0
while ($loop1 < 16)	{ sweeping MIDI channels from port 1 }
if (%ChIn[$loop1] = 1)	{ if the channel is activated in the From Channels table }
$loop2 := 0	
while ($loop2 < 16)	{ sweeping MIDI channels to port 1 }
if(%ChOut[$loop2] = 1)	{ if the channel is activated in the To Channels table }
{ send pitch bend events to activated output channels }
if ($MIDI_COMMAND = $MIDI_COMMAND_PITCH_BEND and $PB = 1 and $MIDI_CHANNEL = $loop1 and $loop1 # $loop2)
set_midi($loop2,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
end if
{ send mono aftertouch to activated output channels }
if ($MIDI_COMMAND = $MIDI_COMMAND_MONO_AT and $CAT = 1 and $MIDI_CHANNEL = $loop1 and $loop1 # $loop2)
set_midi($loop2,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
end if
{ send poly aftertouch to activated output channels }
if ($MIDI_COMMAND = $MIDI_COMMAND_POLY_AT and $PAT = 1 and $MIDI_CHANNEL = $loop1 and $loop1 # $loop2)
set_midi($loop2,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
end if
{ send RPN/NRPN to activated output channels }
if (($MIDI_COMMAND = $MIDI_COMMAND_RPN or $MIDI_COMMAND = $MIDI_COMMAND_NRPN) and $RPN = 1 and $MIDI_CHANNEL = $loop1 and $loop1 # $loop2)
set_midi($loop2,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
end if
$loop3 := 0
while ($loop3 < 128)	{ sweeping the CC arrays for activated CCs }
if ($loop3 < 64)
{ send the currently sweeped CC to activated output channels - CCs 0-63 }
if ($MIDI_COMMAND = $MIDI_COMMAND_CC and $MIDI_BYTE_1 = $loop3 and %CC1[$loop3] = 1 and $MIDI_CHANNEL = $loop1 and $loop1 # $loop2)
set_midi($loop2,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
end if
else
{ send the currently sweeped CC to activated output channels - CCs 64-127 }
if ($MIDI_COMMAND = $MIDI_COMMAND_CC and $MIDI_BYTE_1 = $loop3 and %CC2[$loop3-64] = 1 and $MIDI_CHANNEL = $loop1 and $loop1 # $loop2)
set_midi($loop2,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
end if
end if
inc($loop3)
end while
end if
inc($loop2òÎ   äªÎ   ä«Î   ä¬Î   ä­Î   ä®Î   ä¯Î   ä°Î   ä±Î   ä²Î   ä³


----------



## Geoffury (Sep 1, 2010)

Oh well, back to the drawing board. I tried out the new script and here's the results:

Moving Mod wheel rapidly -

Your first simple script : 2% CPU hit.

Your greatly expanded script, 1 Channel in and 16 out: 6% CPU hit. 16 Channel in and out: 37% CPU hit!

So I think the best way to go is buttons for the common CCs, PB and AT that either leave them on their original channels or let them go out on the 16 channels with everything else.

Thanks for effort anyway.


----------



## EvilDragon (Sep 1, 2010)

Damn, didn't expect that high CPU hit!

I guess the first script would do, then. :(


----------

