LUA for Beginners: How to send controller values to midi device? #578
-
Hello everyone, I have created a panel for the Kawai SX-240 and would like to have a way to send the current controller data to the synth. They are all CC messages. Snapshot is doesnt work. I've been trying many things for two days now, but I'm not really making any progress as to whether I can program (PHP, JS, C++). What's the easiest way to send a current modulator value to the synth with a CC-MIDI message? Is there somewhere a good overview of all the methods and attributes I can use in CTRLR? Thanks so far! |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 8 replies
-
Hi, Please have a look to my Ctrlr Step by Step guide even if a bit "old". I thought it was still accessible on ctrlr.org but apparently not as you must be logged or have the link. I'm explaining how to send CC. If you want to send all parameters at once, you will need to write a Lua method taking each modulators value and sending it to the synth. Good luck! |
Beta Was this translation helpful? Give feedback.
-
Hi @nemesis2049
Here is one suggestion for how to do this. Substitute your modulator names for the ones I have in -- -- Called when a mouse is down on this component -- myMethod = function(comp,event) local delay = panel:getModulatorByName("sendRate"):getValueMapped() -- milliseconds (adjust to suit) ch = panel:getProperty("panelMidiOutputChannelDevice") - 1 -- global counter = 0 -- global timer:setCallback(1, TimerCallback) -- TimerId 1 timer:startTimer(1, delay) -- Timer delay in milliseconds end snapshotTable = { -- add your modulator names here - that's all :) "LFO rate", "LFO delay", "attack", "decay", "sustain", "release" } TimerCallback = function(timerId) if timerId == 1 then counter = counter + 1 -- keep global local num = panel:getModulatorByName(snapshotTable[counter]):getMidiMessage():getProperty("midiMessageCtrlrNumber") local value = panel:getModulatorByName(snapshotTable[counter]):getModulatorValue() local sysm = string.format("%.2x %.2x %.2x", 176 + ch, num, value) panel:sendMidiMessageNow(CtrlrMidiMessage(sysm)) end if counter == #snapshotTable then timer:stopTimer(timerId) end end |
Beta Was this translation helpful? Give feedback.
-
This version of your code would work. It's a bit unusual for me but interesting! myMethod = function(--[[ CtrlrComponent --]] comp --[[ MouseEvent --]], event) local x = getModulatorValue(1) local ch = panel:getProperty("panelMidiOutputChannelDevice") - 1 -- Example for sending cutoff value (CC74, Mod-ID 1) local midiMessage = { 0xB0 + ch, -- channel = 1, 74, -- controllerNumber = 74, x --value = getModulatorValue(1) } panel:sendMidiMessageNow(CtrlrMidiMessage(midiMessage)) end function getModulatorValue(modulatorID) local modulator = panel:getModulatorByIndex(modulatorID) if modulator ~= nil then return modulator:getValue() else return nil end end |
Beta Was this translation helpful? Give feedback.
-
As usual, thx also to John with his detailed explanations (I'm sorry to not have that time). One thing to pay attention in your method is that only the dynamic modulators have a Midi section (labels do not have a Midi section) and your code should check that to avoid throwing an error.
I'm using this to Mute/Unmute all dynamic modulators when receiving a program from the synth which will adapt all dynamic modulators and that I don't want to have the CC messages sent back to the synth. |
Beta Was this translation helpful? Give feedback.
-
Didn’t know about if mod:getProperty("modulatorIsStatic") == "0" then -- Only Dynamic modulators have a MidiMessage ;-) Thank you Dominique ! |
Beta Was this translation helpful? Give feedback.
-
It occurred to me that the timer code should probably be: TimerCallback = function(timerId) if timerId == 1 then counter = counter + 1 -- keep global local num = panel:getModulatorByName(snapshotTable[counter]):getMidiMessage():getProperty("midiMessageCtrlrNumber") local value = panel:getModulatorByName(snapshotTable[counter]):getModulatorValue() local sysm = string.format("%.2x %.2x %.2x", 176 + ch, num, value) panel:sendMidiMessageNow(CtrlrMidiMessage(sysm)) if counter == #snapshotTable then timer:stopTimer(timerId) end end end Not sure if the previous code contains a subtle bug. |
Beta Was this translation helpful? Give feedback.
Hi @nemesis2049
Here is one suggestion for how to do this.
Substitute your modulator names for the ones I have in
snapshotTable
and it should work for you.