Files
ma3-osc-feedback/MA3 OSC FEEDBACK.lua
T
2024-09-09 18:56:26 +02:00

101 lines
3.1 KiB
Lua

-- This plugin was written by Ebbe Baß (umpi)
-- I will not take any responsibility if something breaks at any time. I consider this plugin as unstable.
-- To this date (10.08.2024) I've never had problems with it, but still I am going to consider it as unstable.
local executor_table = {101,102,103,104,105,106,107,108,201,202,203,204,205,206,207,208,301,302,303,304,305,306,307,308,401,402,403,404,405,406,407,408,291,292,293,294,295,296,297,298,191,192,193,194,195,196,197,198}
local osc_config = 1
local osc_template = 'SendOSC %i "/%s%i,i,%i"'
local osc_str_template = 'SendOSC %i "/%s%i,s,%s"'
local enabled = false
local Printf, Echo, GetExecutor, Cmd, ipairs, mfloor = Printf, Echo, GetExecutor, Cmd, ipairs, math.floor
local debug = true
local color_map = {
Sequence = {166, 125, 0},
Group = {0, 64, 128},
Preset = {0, 128, 128},
Master = {0, 128, 128},
Macro = {128, 0, 0},
Quickey = {33, 34, 38},
Sound = {50, 34, 82},
World = {0, 0, 128},
View = {103, 103, 110},
User = {103, 103, 110},
UserPlugin = {112, 0, 80},
ScreenConfig = {103, 103, 110},
Timer = {103, 103, 110}
}
local function debug_print(msg)
if debug then
Printf(msg)
end
end
local function send_osc(etype, exec_no, value)
local cmd_str = osc_template:format(osc_config, etype, exec_no, value)
debug_print(cmd_str)
Cmd(cmd_str)
end
-- Reuse function to handle empty playback
local function handle_empty_playback(exec_no)
debug_print('Empty playback found on:'..tostring(exec_no))
if (exec_no >= 291 and exec_no <= 298) or (exec_no >= 191 and exec_no <= 198) then
Cmd(osc_str_template:format(osc_config, "xKey", exec_no, ""))
end
send_osc("ExecCol_R", exec_no, 0)
send_osc("ExecCol_G", exec_no, 0)
send_osc("ExecCol_B", exec_no, 0)
end
local function poll(exec_no)
local exec = GetExecutor(exec_no)
local execAssObjNoClass = exec and exec:GetAssignedObj()
if not execAssObjNoClass then
handle_empty_playback(exec_no)
else
-- Extract object appearance and class
local execAssObj = execAssObjNoClass:GetClass()
local colors = color_map[execAssObj] or {0, 0, 0} -- fallback colors
-- Appearance-based color override
local assObjApp = execAssObjNoClass:Get("Appearance")
if assObjApp then
local app_id = tonumber(assObjApp:gsub("Appearance ", ""))
local app_data = ShowData().Appearances[app_id]
colors = {tonumber(app_data.BackR), tonumber(app_data.BackG), tonumber(app_data.BackB)}
end
-- Send colors through OSC
send_osc("ExecCol_R", exec_no, colors[1])
send_osc("ExecCol_G", exec_no, colors[2])
send_osc("ExecCol_B", exec_no, colors[3])
-- Handle special xKey case
if (exec_no >= 291 and exec_no <= 298) or (exec_no >= 191 and exec_no <= 198) then
local exec_label = execAssObjNoClass:Get("Name")
Cmd(osc_str_template:format(osc_config, "xKey", exec_no, exec_label))
end
end
end
local function mainloop()
while enabled do
for _, exec_no in ipairs(executor_table) do
poll(exec_no)
end
coroutine.yield(0.05)
end
end
local function maintoggle()
enabled = not enabled
if enabled then
mainloop()
end
end
return maintoggle