1) Is there a way to get the value of an executor fader (or knob)?
2) Is there a way to hook (listen) on the fader value changes?

How to get the current value of an executor fader?
BECOME PART OF THE COMMUNITY - Sign up here
-
-
I didn't find any way to do it.
I found an ugly hack workaround.
I turn on OSC out, and I use an external app to listen for OSC, and for each fader value received I send back an OSC Cmd message. This Cmd can either call my LUA plugin with that value, or set a UserVar, so the plugin can get the value when it needs it.
But this is something I can only use myself, I cannot deliver my plugin to users an expect them to run an external App for this. -
1. yes this is possible. (via the GetFader object method)
2. not to my knowledge
-
-
notice the curly brackets in the error message, you need to provide a {table}, however table content is [optional]
Lua "Echo(GetExecutor(201):GetFader({}))"
Lua "Echo(SelectedSequence():GetFader({token='FaderMaster'}))"
-
Amazing !!!
Many "Thank-You"s !
Andreas I guess you get ANOTHER free plugin (-:
This will be for the "True Temp Fader" plugin,
estimated release at March 2023.
In the meantime,
try BETA testing the Pool Browser.
http://www.ma3-pro-plugins.com -
Any idea what the "index" property means?
(In the table where the "token" property is) -
-
I have modified the code provided by Mr. Button, which currently sends fader values for executor 201-208 and 301-308 every half second in a continuous loop, within the range of 0-16368 (I am using the BCF2000 in Mackie mode).
For my convenience, in case there is no information available, I send a value of -1.
Code
Display Morelocal function Read_Fader_Send_OSC_nn(executor_nr) local FaderDataStructure = {} FaderDataStructure.token = "FaderMaster" FaderDataStructure.faderDisabled = false local my_ex_obj_1 = GetExecutor(executor_nr) if my_ex_obj_1 == nil then local osc_value = -1 Cmd("SendOSC 2 \"/Fader"..executor_nr..",i,"..osc_value.."\"") else local fader_current_Value = my_ex_obj_1:GetFader(FaderDataStructure) local exact = fader_current_Value * 163.68 local osc_value = tonumber(string.format("%.1f", exact)) --local osc_value = math.floor(exact) Cmd("SendOSC 2 \"/Fader"..executor_nr..",i,"..osc_value.."\"") end end local function main() local executor_table = {201,202,203,204,205,206,207,208,301,302,303,304,305,306,307,308} local time = Time() + 1 while true do if time <= Time() then time = Time() + 0.5 for i, name in ipairs(executor_table) do Read_Fader_Send_OSC_nn(name) end end end end return main
To complete my requirements, I also need to read whether, for example, executor 201 is active and send OSC feedback in the form of OSC key "Key201" with a value of 1 for active or 0 for inactive or disabled.
I found an example of how to read the active sequence, but I am not proficient enough in Lua to connect it properly.
Code
Display Morelocal function main() local selectedSequence = SelectedSequence() -- Stores the handle of the selected sequence. -- The following is an 'if' that gives different feedback based on the playback status. if selectedSequence:HasActivePlayback() then Printf("Sequence '" ..selectedSequence.name.. "' has active playback.") else Printf("Sequence '" ..selectedSequence.name.. "' has NO active playback.") end end return main
-
please try these two versions of your main function and watch the system monitor
Code
Display Morelocal function main() local executor_table = {201,202,203,204,205,206,207,208,301,302,303,304,305,306,307,308} local time = Time() + 1 while true do Echo('this code is hurting me') if time <= Time() then time = Time() + 0.5 for i, name in ipairs(executor_table) do Read_Fader_Send_OSC_nn(name) end end end end
-
Hi,
Well the issues with sending Exec active state are:
1) You need to resolve the Sequence to which an executor is assigned to.
2) You need to hook the Executor for changes, in case the user assigned a different sequence to that exec.
3) Although a Seq object has a "CURRENTCUE" property, when you hook the seq for change, the callback is NOT trigger when the current cue changes )-:
4) So the only way I found to get notified when a sequence active state is changed, is to add commands to all the cues and to the OffCue. And use these commands to do whatever you want.
So for conclusion.
Too complicated for the value you'll get from all this. -
I found such a way
-
I have modified the code provided by Mr. Button, which currently sends fader values for executor 201-208 and 301-308 every half second in a continuous loop, within the range of 0-16368 (I am using the BCF2000 in Mackie mode).
For my convenience, in case there is no information available, I send a value of -1.
Code
Display Morelocal function Read_Fader_Send_OSC_nn(executor_nr) local FaderDataStructure = {} FaderDataStructure.token = "FaderMaster" FaderDataStructure.faderDisabled = false local my_ex_obj_1 = GetExecutor(executor_nr) if my_ex_obj_1 == nil then local osc_value = -1 Cmd("SendOSC 2 \"/Fader"..executor_nr..",i,"..osc_value.."\"") else local fader_current_Value = my_ex_obj_1:GetFader(FaderDataStructure) local exact = fader_current_Value * 163.68 local osc_value = tonumber(string.format("%.1f", exact)) --local osc_value = math.floor(exact) Cmd("SendOSC 2 \"/Fader"..executor_nr..",i,"..osc_value.."\"") end end local function main() local executor_table = {201,202,203,204,205,206,207,208,301,302,303,304,305,306,307,308} local time = Time() + 1 while true do if time <= Time() then time = Time() + 0.5 for i, name in ipairs(executor_table) do Read_Fader_Send_OSC_nn(name) end end end end return main
To complete my requirements, I also need to read whether, for example, executor 201 is active and send OSC feedback in the form of OSC key "Key201" with a value of 1 for active or 0 for inactive or disabled.
I found an example of how to read the active sequence, but I am not proficient enough in Lua to connect it properly.
Code
Display Morelocal function main() local selectedSequence = SelectedSequence() -- Stores the handle of the selected sequence. -- The following is an 'if' that gives different feedback based on the playback status. if selectedSequence:HasActivePlayback() then Printf("Sequence '" ..selectedSequence.name.. "' has active playback.") else Printf("Sequence '" ..selectedSequence.name.. "' has NO active playback.") end end return main
Thank You Andreas
-
Krzysztof Korzeniowski
Yeah, that's the way to get the associated sequence.I personally don't like a solution that involves polling (sending the fader values every 0.5 second).
So if you are going into resolving each exec's sequence, then you don't need polling to get the faders' values.
You simply need to listen for the outgoing OSC messages of the sequences's MasterFader. )Oh, but what if the exec is a Temp fader.... you need to listen for a TempFader as well? I need to chan that)
But in my opinion, if you go for resolving sequence, then you need to listen for changes in the assigned sequence of an executor.
Or you can use your polling solution to resolve the exec=>seq mapping every 0.5 a second. Or maybe eve every 5 seconds. Or even, just make a plugin/macro that the user needs to run whenever they change the exec's target object (exec's sequence) -
I mean these OSC output messages
The numbers tell you which sequence it is.
The last number is the sequence number (2 in the attached example) -
Krzysztof Korzeniowski
Yeah, that's the way to get the associated sequence.I personally don't like a solution that involves polling (sending the fader values every 0.5 second).
So if you are going into resolving each exec's sequence, then you don't need polling to get the faders' values.
You simply need to listen for the outgoing OSC messages of the sequences's MasterFader. )Oh, but what if the exec is a Temp fader.... you need to listen for a TempFader as well? I need to chan that)
But in my opinion, if you go for resolving sequence, then you need to listen for changes in the assigned sequence of an executor.
Or you can use your polling solution to resolve the exec=>seq mapping every 0.5 a second. Or maybe eve every 5 seconds. Or even, just make a plugin/macro that the user needs to run whenever they change the exec's target object (exec's sequence)In my earlier projects that communicate via webremote - polling the "server" is more frequent - so ledfeedback is practically instantaneous.
I know this solution is not very elegant - but it must be read quite often - so that the faders don't go back to their previous position.
Therefore, the possibility of pressing and sending the status - in this case, is out
Listening to OSC - I did - but unfortunately you are not always able to decode whether something is running or not.
-
I mean these OSC output messages
The numbers tell you which sequence it is.
The last number is the sequence number (2 in the attached example)I managed to get what I wanted - maybe not in a very elegant way - but it works fine.
BCF2000 in Mackie mode
Encoders 301-308 - work on any page with ledfeedback
Executors 301-308 - work on any page with ledfeedback
Executors 201-208 - work on any page with ledfeedback
Faders 201-208 work on any page with posfeedback
I finished the demo for today
The right side of the buttons will remain unprogrammed for now - I have to come up with an idea what to do with it
< PRESET > of course switch pages - +
Thanks again Andreas for your help!
ArtGateOne/ma3bcf2000: use bcf2000 to control ma3 faders OSC (github.com) -
while it is fine to poll every half second, actually sending OSC should only be necessary if something has changed since last poll?
Code
Display Morelocal executor_table = {201,202,203,204,205,206,207,208,301,302,303,304,305,306,307,308} local osc_config = 2 local history_fader, history_status = {}, {} local osc_template = 'SendOSC %i "/%s%i,i,%i"' local enabled = false local Printf, Echo, GetExecutor, Cmd, ipairs, mfloor = Printf, Echo, GetExecutor, Cmd, ipairs, math.floor local function send_osc(etype, exec_no, value) Printf(osc_template:format(osc_config, etype, exec_no, value)) -- Cmd(osc_template:format(osc_config, etype, exec_no, value)) end local function poll(exec_no) local exec = GetExecutor(exec_no) local value = exec and mfloor(exec:GetFader{} * 163.68) or -1 local last_value = history_fader[exec_no] local status = exec and exec.Object and exec.Object:HasActivePlayback() and 1 or 0 local last_status = history_status[exec_no] if value ~= last_value then send_osc('Fader', exec_no, value) history_fader[exec_no] = value end if status ~= last_status then send_osc('Key', exec_no, status) history_status[exec_no] = status end end local function mainloop() while enabled do for _, exec_no in ipairs(executor_table) do poll(exec_no) end coroutine.yield(0.5) end end local function maintoggle() if enabled then enabled = false else enabled = true history_fader, history_status = {}, {} mainloop() end end return maintoggle
-
Thank you Andreas - although this code is not quite understandable for me at the moment - I guess what you want to achieve..
I was doing a similar workaround on the nodejs side and sending midi messages - only changes - so as not to block the controller by sending too many notes.
Thank you!
-
while it is fine to poll every half second, actually sending OSC should only be necessary if something has changed since last poll?
Code
Display Morelocal executor_table = {201,202,203,204,205,206,207,208,301,302,303,304,305,306,307,308} local osc_config = 2 local history_fader, history_status = {}, {} local osc_template = 'SendOSC %i "/%s%i,i,%i"' local enabled = false local Printf, Echo, GetExecutor, Cmd, ipairs, mfloor = Printf, Echo, GetExecutor, Cmd, ipairs, math.floor local function send_osc(etype, exec_no, value) Printf(osc_template:format(osc_config, etype, exec_no, value)) -- Cmd(osc_template:format(osc_config, etype, exec_no, value)) end local function poll(exec_no) local exec = GetExecutor(exec_no) local value = exec and mfloor(exec:GetFader{} * 163.68) or -1 local last_value = history_fader[exec_no] local status = exec and exec.Object and exec.Object:HasActivePlayback() and 1 or 0 local last_status = history_status[exec_no] if value ~= last_value then send_osc('Fader', exec_no, value) history_fader[exec_no] = value end if status ~= last_status then send_osc('Key', exec_no, status) history_status[exec_no] = status end end local function mainloop() while enabled do for _, exec_no in ipairs(executor_table) do poll(exec_no) end coroutine.yield(0.5) end end local function maintoggle() if enabled then enabled = false else enabled = true history_fader, history_status = {}, {} mainloop() end end return maintoggle
Tested - but not work ---
on the screen you can see the commands from my plugin - green - from your version they are white - ???Code
Display Morelocal function Read_Fader_Send_OSC_nn(executor_nr) local FaderDataStructure = {} FaderDataStructure.token = "FaderMaster" FaderDataStructure.faderDisabled = false local my_ex_obj_1 = GetExecutor(executor_nr) if my_ex_obj_1 == nil then local osc_value = -1 Cmd("SendOSC 2 \"/Fader"..executor_nr..",i,"..osc_value.."\"") local osc_value = 0 Cmd("SendOSC 2 \"/Key"..executor_nr..",i,"..osc_value.."\"") else local fader_current_Value = my_ex_obj_1:GetFader(FaderDataStructure) local exact = fader_current_Value * 163.68 local osc_value = tonumber(string.format("%.1f", exact)) --local osc_value = math.floor(exact) Cmd("SendOSC 2 \"/Fader"..executor_nr..",i,"..osc_value.."\"") local exec_str = "Exec " .. executor_nr local exec = ObjectList(exec_str) local seq = exec[1]:GetAssignedObj() if seq:HasActivePlayback() then local osc_value = 1 Cmd("SendOSC 2 \"/Key"..executor_nr..",i,"..osc_value.."\"") else local osc_value = 0 Cmd("SendOSC 2 \"/Key"..executor_nr..",i,"..osc_value.."\"") end end end local function main() local executor_table = {201,202,203,204,205,206,207,208,301,302,303,304,305,306,307,308} while true do coroutine.yield(0.5) for i, name in ipairs(executor_table) do Read_Fader_Send_OSC_nn(name) end end end return main
Participate now!
Don’t have an account yet? Register yourself now and be a part of our community!