# Modulator MIDI CC



## d.healey (Oct 8, 2012)

Is it possible, via KSP, to change the MIDI CC assigned to a modulator?


----------



## Raptor4 (Oct 8, 2012)

TotalComposure @ Mon Oct 08 said:


> Is it possible, via KSP, to change the MIDI CC assigned to a modulator?


It is not possible if you are talking about the External Source CC# setting. Anyway you can use a workaround which can do something similar. Imagine you have set the Midi CC# in the modulator to some "Dead CC#" let say CC110. Later you can construct a filter which will block any physical CC110 messages.
You will need a condition assigner UI box where you will set the wished External CC#.
So, if you set that box to say CC1 then CC1 will be transformed to the dead # set in the modulator i.e CC110. If you set the UI box to CC11 it will be transformed to CC110 etc. All non-matching CC# will pass thru unless the physical CC110 which is ignored in the script. Here is my prototype below:

```
on init
  make_perfview
  declare const $dead_cc := 110 {This is the Dead CC# set as External Source in the modulator}
  declare ui_value_edit $CC_num(1, 127, 1) 
  set_text($CC_num,"CC#")
  make_persistent($CC_num)
end on

on controller
  if ($CC_NUM=$dead_cc)
    ignore_controller
  else
    if ($CC_NUM=$CC_num)
      set_controller($dead_cc,%CC[$CC_num])
    end if
  end if
end on
```

Regards,
R4


----------



## d.healey (Oct 9, 2012)

Ah that's a cool idea, thanks I'll give it a go!


----------



## Casey Edwards (Nov 4, 2012)

I'm glad I came across this because this is exactly something I'm trying to do now. I do have a question though:

1) How do you implement 'MIDI LEARN' when right clicking the UI box?


----------



## mk282 (Nov 5, 2012)

Raptor4 @ 8.10.2012 said:


> TotalComposure @ Mon Oct 08 said:
> 
> 
> > Is it possible, via KSP, to change the MIDI CC assigned to a modulator?
> ...




I would recommend not using "dead CCs". Instead of a CC modulator, use a Constant modulator, then modulate the modulation amount of that modulator in controller callback. This saves you from filtering out the CC you would have used as an external modulator.


----------



## mk282 (Nov 5, 2012)

Casey Edwards @ 5.11.2012 said:


> 1) How do you implement 'MIDI LEARN' when right clicking the UI box?



Some UI controls are not automatable/MIDI learnable at all. ui_menu is one of them.


----------



## Raptor4 (Nov 5, 2012)

> Instead of a CC modulator, use a Constant modulator, then modulate the modulation amount of that modulator in controller callback.


Hi,
If I read the original topic correctly _"Is it possible, via KSP, to change the MIDI CC assigned to a modulator?" _ it is directed to "How to remote/change a given CC# via KSP" not "How to control the Modulator via any CC#".
These are to different things. For example if you need to change/remote a given CC# which controls the modulator in real time you will need one more CC# which must be previously learned to the UI box I show in my example script - yes the ui_value_edit box can not be learned but it is supposed that in the complex project it will be replaced with a slider and a custom UI box - read below).
In this scenario the remote CC assigner can be a pedal switch which is set to say CC12 and toggles between values (down 20 which will switch the UI box to CC#20) and (up 21 which will toggle the UI box to CC#21). It is supposed that you will use two more external controllers previously set to CC20 & CC21 so you will tweak the pedal (CC12) to toggle CC20 & 21 control etc. Some soft take over features must be added in such schemes as well. 


> 1) How do you implement 'MIDI LEARN' when right clicking the UI box?


As mk282 pointed some UIs like ui_menu, ui_value_edit can not be learned. I show a demo using ui_value_edit box in my script example above but you can replace it with say an ui_knob or with a slider assigned to some custom UI box image etc.


----------



## Casey Edwards (Nov 5, 2012)

Okay, cool. Thanks a lot guys! I've now made a ui_knob that controls a LP filter in my first insert slot of the instrument fx rack. I'd still like to have the option to insert a custom CC# into my ui_value_edit box and control the knob with that CC#. Also, I'd like to do the inverse of that and if the user wants to right-click the knob for 'MIDI LEARN', I'd like for that new CC# to show up in the ui_value_edit box. I've already learned so much in the past 2 days and I'm still searching the manual and the internet for more answers as I go.


----------



## mk282 (Nov 5, 2012)

Casey Edwards @ 5.11.2012 said:


> Also, I'd like to do the inverse of that and if the user wants to right-click the knob for 'MIDI LEARN', I'd like for that new CC# to show up in the ui_value_edit box.



Sorry, but unfortunately this will not be possible. Kontakt's MIDI learn functionality is not accessible to KSP at all, so there's no way to find out to which CC was the control linked via Kontakt's built in MIDI learn feature.


----------



## Casey Edwards (Nov 5, 2012)

mk282 @ Mon Nov 05 said:


> Casey Edwards @ 5.11.2012 said:
> 
> 
> > Also, I'd like to do the inverse of that and if the user wants to right-click the knob for 'MIDI LEARN', I'd like for that new CC# to show up in the ui_value_edit box.
> ...



Ah, that's a bummer. You think something like get_midi_learnCC would be something easy to implement. Is there a way to retrieve the MIDI CC# controlling a knob after it's been moved? You'd think there was at least a work-around to retrieve that number in some fashion. 

That still leaves me at a crossroad for the first one. I found this: 

on init
declare ui_knob $MyKnob(0, 127, 1)
end on

on controller
if ($CC_NUM=1)
$MyKnob := %CC[$CC_NUM]
end if
end on

but when I pass my variables to this it doesn't work. I'm sill searching around until I get it right though.


----------



## mk282 (Nov 5, 2012)

Casey Edwards @ 5.11.2012 said:


> Is there a way to retrieve the MIDI CC# controlling a knob after it's been moved?



Not as far as I know. KSP doesn't discern between MIDI learned moved knob and mouse-click moved knob. It's all the same - same callback gets executed. So the only way to do this reliably is disregard the built-in MIDI learn, and do your own.


----------



## Raptor4 (Nov 5, 2012)

mk282 @ Mon Nov 05 said:


> So the only way to do this reliably is disregard the built-in MIDI learn, and do your own.


Hi Casey,
Here is a simple example of that.
Copy my code and paste it in the KSP. You will see a small "L" button right to the ui-value box - the "L" button behaves as "Learn" button. Click it (it will star to blink), move the external controller you want. The "L" button will auto-off, the CC# will be shown in the ui_box and the "Test" knob will follow the external control.
Replace the "Test" line code in the Controller CB with the destination or target you want. 

```
on init
  message("")
  set_ui_height_px(65)
  make_perfview
  declare ui_value_edit $cc_assign(0, 127, 1) 
  set_control_par(get_ui_id($cc_assign),$CONTROL_PAR_WIDTH,58)
  set_text($cc_assign,"CC#")
  move_control_px($cc_assign,100,20)
  make_persistent($cc_assign)
  declare ui_switch $Learn
  set_control_par(get_ui_id($Learn),$CONTROL_PAR_FONT_TYPE,3)
  set_text($Learn,"L")
  set_control_par(get_ui_id($Learn),$CONTROL_PAR_WIDTH,18)
  move_control_px($Learn,158,20)
  declare ui_knob $Test(0, 127, 1) 
  make_persistent($Test)
  move_control_px($Test,200,10)
end on

on ui_control($Learn)
  while ($Learn=1)
    set_text($Learn,"L")
    set_control_par(get_ui_id($Learn),$CONTROL_PAR_FONT_TYPE,2)
    wait(250000)
    set_control_par(get_ui_id($Learn),$CONTROL_PAR_FONT_TYPE,3)
    wait(250000)
  end while
end on

on controller
  if ($Learn=1)
    $cc_assign := $CC_NUM
    $Learn := 0
  end if
  if ($cc_assign=$CC_NUM)
    $Test := %CC[$cc_assign]
  end if
end on
```

Regards :wink: 
R4


----------



## Casey Edwards (Nov 5, 2012)

Thanks again for coming to the rescue guys. Surprise! I have yet another question. When I give the parameters for the second knob to be set to the Instrument Insert Rack effect slot 1 for a LP filter the knob stops tracking when I change 127 to 1000000 to get the appropriate data. (This is under the Dynamic control coding, not the layer control.)

Here's the code:


```
on init
  message("")
  set_ui_height_px(65)
  make_perfview

  {Layer CC value box}
  declare ui_value_edit $layerCC(0, 127, 1)
  set_control_par(get_ui_id($layerCC),$CONTROL_PAR_WIDTH,58)
  set_text($layerCC,"CC#")
  move_control_px($layerCC,200,10)
  make_persistent($layerCC)
  {Layer learn switch}
  declare ui_switch $layerLearn
  set_control_par(get_ui_id($layerLearn),$CONTROL_PAR_FONT_TYPE,3)
  set_text($layerLearn,"L")
  set_control_par(get_ui_id($layerLearn),$CONTROL_PAR_WIDTH,18)
  move_control_px($layerLearn,200,30)
  {Layer Knob}
  declare ui_knob $layerKnob(0, 127, 1)
  make_persistent($layerKnob)
  set_text($layerKnob,"Layers")
  move_control_px($layerKnob,110,10)

  {Dynamic CC value box}
  declare ui_value_edit $dynCC(0, 127, 1)
  set_control_par(get_ui_id($dynCC),$CONTROL_PAR_WIDTH,58)
  set_text($dynCC,"CC#")
  move_control_px($dynCC,400,10)
  make_persistent($dynCC)
  {Dynamic learn switch}
  declare ui_switch $dynLearn
  set_control_par(get_ui_id($dynLearn),$CONTROL_PAR_FONT_TYPE,3)
  set_text($dynLearn,"L")
  set_control_par(get_ui_id($dynLearn),$CONTROL_PAR_WIDTH,18)
  move_control_px($dynLearn,400,30)
  {Dynamic Knob}
  declare ui_knob $dynKnob(0,1000000, 1)
  make_persistent($dynKnob)
  set_text($dynKnob,"Dynamics")
  move_control_px($dynKnob,310,10)
  set_knob_unit($dynKnob,$KNOB_UNIT_HZ)

end on

on ui_control($layerLearn)
  while ($layerLearn=1)
    set_text($layerLearn,"L")
    set_control_par(get_ui_id($layerLearn),$CONTROL_PAR_FONT_TYPE,2)
    wait(250000)
    set_control_par(get_ui_id($layerLearn),$CONTROL_PAR_FONT_TYPE,3)
    wait(250000)
  end while
end on

on ui_control($dynLearn)
  while ($dynLearn=1)
    set_text($dynLearn,"L")
    set_control_par(get_ui_id($dynLearn),$CONTROL_PAR_FONT_TYPE,2)
    wait(250000)
    set_control_par(get_ui_id($dynLearn),$CONTROL_PAR_FONT_TYPE,3)
    wait(250000)
  end while
end on

on ui_control($dynKnob)
    {Connect to LP Filter}
  set_engine_par($ENGINE_PAR_CUTOFF,$dynKnob,-1,0,1)
  set_knob_label($dynKnob,get_engine_par_disp($ENGINE_PAR_CUTOFF,-1,0,1))
end on

on controller
  if ($layerLearn=1)
    $layerCC := $CC_NUM
    $layerLearn := 0
  end if
  if ($layerCC=$CC_NUM)
    $layerKnob := %CC[$layerCC]
  end if

  if ($dynLearn=1)
    $dynCC := $CC_NUM
    $dynLearn := 0
  end if
  if ($dynCC=$CC_NUM)
    $dynKnob := %CC[$dynCC]
  end if
end on
```


----------



## TBAudio (Nov 6, 2012)

Hey Casey, I'm Casey. Nice to meet you! 

you just need a couple more lines and you're there. You didn't set the destination for the controller in Raptor4's template, also you have to scale the knob and midi values on one end.

Try adding these changes to the Controller CB.

```
if ($dynLearn=1)
    $dynCC := $CC_NUM
    $dynLearn := 0
  end if
  if ($dynCC=$CC_NUM)
    $dynKnob := %CC[$dynCC] * 7874
    set_engine_par($ENGINE_PAR_CUTOFF,$dynKnob,-1,0,1)
    set_knob_label($dynKnob,get_engine_par_disp($ENGINE_PAR_CUTOFF,-1,0,1)) 
  end if
end on
```

First post on the forums. Hope it's useful. Big fan of the community here, you guys are amazing.


----------



## Casey Edwards (Nov 6, 2012)

TBAudio @ Tue Nov 06 said:


> Hey Casey, I'm Casey. Nice to meet you!
> 
> you just need a couple more lines and you're there. You didn't set the destination for the controller in Raptor4's template, also you have to scale the knob and midi values on one end.
> 
> ...



I knew it had to be an algorithm change to that exact line, but I was too tired to mess with everything after I got home celebrating my wife's birthday last night. I however did not know you had to set_engine_par and knob_label again. I've got so much to learn about this language still, but the code you guys are providing me is making me look in all the right places in the manual so I really appreciate it!

In this example of a user defined CC# for both knobs, is it still safe to use the $dead_cc idea to control my modulators, or is there another way I should approach this last step?

EDIT: I think I should add what the first knob is supposed to do. This particular instrument has 3 groups, and each group has a midi CC modulator added to control volume of that group so that I could activate the table and draw in my own x-fade curves to cross between the different layers of activity. I assigned them all midi CC 1 as default so they'd all react to a single CC#.


----------



## TBAudio (Nov 6, 2012)

Casey Edwards @ Tue Nov 06 said:


> . I however did not know you had to set_engine_par and knob_label again.



The reason this is needed is because you are using a custom midi learn function. this means that the sliders ui control callback isn't triggered like it would be if you used the built in midi learn, but this is the price needed to get that visual feedback you desired. So keep in mind you will basically need to duplicate the code you put in the knobs ui_control section inside the on_controller section as well.



Casey Edwards @ Tue Nov 06 said:


> In this example of a user defined CC# for both knobs, is it still safe to use the $dead_cc idea to control my modulators, or is there another way I should approach this last step?



I'll be honest that I'm not 100 percent understanding what you are trying to do, but I don't see any reason why it wouldn't work. you will just need to set the knob to the appropriate destination for all 3 cc modulators, and do the same in the on_controller section.

I wish you luck. I'd be glad to help out more if I can, but I think I would need to understand your end goal just a bit better.


----------

