View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0008784 | ardour | bugs | public | 2021-08-02 14:09 | 2021-11-14 10:00 |
Reporter | Werner Back | Assigned To | |||
Priority | normal | Severity | minor | Reproducibility | always |
Status | new | Resolution | open | ||
Platform | Microsoft | OS | Windows | OS Version | 10 |
Product Version | 6.8 | ||||
Summary | 0008784: LUA: Store Mixer Settings has pan wrong | ||||
Description | I used the "Store Mixer Settings" Lua script to save a "scene", but when I restore from that file the pans are set wrong. I checked the saved values and it looks as if the way the numbers are stored is wrong. It looks like the following: ...,pan_control=0,5,... but should look like ...,pan_control=0.5,0.5,... (this example is for "center position"). If I correct this manually in the file the pans look alright. | ||||
Steps To Reproduce | Store + recall mixer settings with LUA script. | ||||
Tags | No tags attached. | ||||
|
Oh, just saw that it's a locale problem. LUA replaces the "." with "," in german environments. Something like that should work: if pan ~= false then local strPan = tostring(pan) pan = strPan:gsub(",", ".") end |
|
Ah, I played a little with LUA (without understanding everything ;)) and it seems that this works: Replace the following line: if pan:isnil() then pan = false else pan = pan:get_value() end --sometimes a route doesn't have pan, like the master. with if pan:isnil() then pan = false else pan = ARDOUR.LuaAPI.ascii_dtostr(pan:get_value()) end --sometimes a route doesn't have pan, like the master. Probably there are some more parameters where this problem occurs? I couldn't find out what "send_string" does? Guess that's Mixbus only, right? Since the LUA script's author is "Mixbus Team", is it possible, that this bug doesn't appear in Mixbus? |
|
This works for me now. a_db2b41821.lua (10,885 bytes)
ardour { ["type"] = "EditorAction", name = "Store Mixer Settings WB1.1", author = "Mixbus Team", description = [[ Stores the current Mixer state as a file that can be read and recalled arbitrarily by it's companion script, Recall Mixer Settings. Supports: processor settings, grouping, mute, solo, gain, trim, pan and processor ordering, plus re-adding certain deleted plugins. ]] } function factory () return function () local user_cfg = ARDOUR.user_config_directory(-1) local local_path = ARDOUR.LuaAPI.build_filename(Session:path(), 'mixer_settings') local global_path = ARDOUR.LuaAPI.build_filename(user_cfg, 'mixer_settings') function exists(file) local ok, err, code = os.rename(file, file) if not ok then if code == 13 then -- Permission denied, but it exists return true end end return ok, err end function whoami() if not pcall(function() local first_check = Session:get_mixbus(0) end) then return "Ardour" else local second_check = Session:get_mixbus(11) if second_check:isnil() then return "Mixbus" else return "32C" end end end function isdir(path) return exists(path.."/") end function setup_paths() local global_ok, local_ok = false, false if not(isdir(global_path)) then global_ok, _, _ = os.execute('mkdir '.. global_path) if global_ok == 0 then global_ok = true end else global_ok = true end if not(isdir(local_path)) then local_ok, _, _ = os.execute('mkdir ' .. "\"" .. local_path .."\"") if local_ok == 0 then local_ok = true end else local_ok = true end return global_ok, local_ok end function get_processor_by_name(track, name) local i = 0 local proc = track:nth_processor(i) repeat if(proc:display_name() == name) then return proc else i = i + 1 end proc = track:nth_processor(i) until proc:isnil() end function group_by_id(id) local id = tonumber(id) for g in Session:route_groups():iter() do local group_id = tonumber(g:to_stateful():id():to_s()) if group_id == id then return g end end end function group_by_name(name) for g in Session:route_groups():iter() do if g:name() == name then return g end end end function route_groupid_interrogate(t) local group = false for g in Session:route_groups():iter() do for r in g:route_list():iter() do if r:name() == t:name() then group = g:to_stateful():id():to_s() end end end return group end function route_group_interrogate(t) for g in Session:route_groups():iter() do for r in g:route_list():iter() do if r:name() == t:name() then return g end end end end function empty_last_store(path) --empty current file from last run local file = io.open(path, "w") --file:write(string.format("instance = { whoami = '%s' }", whoami()) file:write("") file:close() end function mark_tracks(selected, path) empty_last_store(path) local route_string = [[instance = { route_id = %d, route_name = '%s', gain_control = %s, trim_control = %s, pan_control = %s, sends = {%s}, muted = %s, soloed = %s, order = {%s}, cache = {%s}, group = %s, group_name = '%s', pi_order = %d }]] local group_string = [[instance = { group_id = %s, name = '%s', routes = {%s}, }]] local processor_string = [[instance = { plugin_id = %d, type = %d, display_name = '%s', owned_by_route_name = '%s', owned_by_route_id = %d, parameters = {%s}, active = %s, }]] local group_route_string = " [%d] = %s," local proc_order_string = " [%d] = %d," local proc_cache_string = " [%d] = {'%s', %d}," local params_string = " [%d] = %s," --ensure easy-to-read formatting doesn't make it through local route_string = string.gsub(route_string, "[\n\t%s]", "") local group_string = string.gsub(group_string, "[\n\t%s]", "") local processor_string = string.gsub(processor_string, "[\n\t%s]", "") local sel = Editor:get_selection () local groups_to_write = {} local i = 0 local tracks = Session:get_stripables() if selected then tracks = sel.tracks:routelist() end for r in tracks:iter() do local group = route_group_interrogate(r) if group then local already_there = false for _, v in pairs(groups_to_write) do if group == v then already_there = true end end if not(already_there) then groups_to_write[#groups_to_write + 1] = group end end end for _, g in pairs(groups_to_write) do local tmp_str = "" for t in g:route_list():iter() do tmp_str = tmp_str .. string.format(group_route_string, i, t:to_stateful():id():to_s()) i = i + 1 end local group_str = string.format( group_string, g:to_stateful():id():to_s(), g:name(), tmp_str ) file = io.open(path, "a") file:write(group_str, "\r\n") file:close() end for r in tracks:iter() do if r:is_monitor () or r:is_auditioner () or not(r:to_vca():isnil()) then goto nextroute end -- skip special routes r = r:to_route() if r:isnil() then goto nextroute end local order = ARDOUR.ProcessorList() local x = 0 repeat local proc = r:nth_processor(x) if not proc:isnil() then order:push_back(proc) end x = x + 1 until proc:isnil() local route_group = route_group_interrogate(r) if route_group then route_group = route_group:name() else route_group = "" end local rid = r:to_stateful():id():to_s() local pan = r:pan_azimuth_control() if pan:isnil() then pan = false else pan = ARDOUR.LuaAPI.ascii_dtostr(pan:get_value()) end --sometimes a route doesn't have pan, like the master. -- Get send information, if any. local send_string = "" local i = 0 repeat local fmt = "{%s, %s, %s, %s}" string.gsub(fmt, "[\n\t]", "") local values = {} for j, ctrl in pairs({ r:send_level_controllable(i), r:send_enable_controllable(i), r:send_pan_azimuth_controllable(i), r:send_pan_azimuth_enable_controllable(i), }) do if not(ctrl:isnil()) then values[#values + 1] = ARDOUR.LuaAPI.ascii_dtostr(ctrl:get_value()) else values[#values + 1] = "nil" end end send_string = send_string .. string.format(fmt, table.unpack(values)) send_string = send_string .. "," i = i + 1 until r:send_enable_controllable(i):isnil() --print("send_string="..send_string) local order_nmbr = 0 local tmp_order_str, tmp_cache_str = "", "" for p in order:iter() do local ptype if not(p:to_insert():isnil()) then ptype = p:to_insert():plugin(0):get_info().type else ptype = 99 end local pid = p:to_stateful():id():to_s() if not(string.find(p:display_name(), "latcomp")) then tmp_order_str = tmp_order_str .. string.format(proc_order_string, order_nmbr, pid) tmp_cache_str = tmp_cache_str .. string.format(proc_cache_string, pid, p:display_name(), ptype) end order_nmbr = order_nmbr + 1 end local route_str = string.format( route_string, rid, r:name(), ARDOUR.LuaAPI.ascii_dtostr(r:gain_control():get_value()), ARDOUR.LuaAPI.ascii_dtostr(r:trim_control():get_value()), tostring(pan), send_string, r:muted(), r:soloed(), tmp_order_str, tmp_cache_str, route_groupid_interrogate(r), route_group, r:presentation_info_ptr():order() ) file = io.open(path, "a") file:write(route_str, "\n") file:close() local i = 0 while true do local params = {} local proc = r:nth_plugin (i) if proc:isnil () then break end local active = proc:active() local id = proc:to_stateful():id():to_s() local plug = proc:to_insert ():plugin (0) local ptype = proc:to_insert():plugin(0):get_info().type local n = 0 for j = 0, plug:parameter_count() - 1 do -- Iterate over all plugin parameters if plug:parameter_is_control(j) then local label = plug:parameter_label(j) if plug:parameter_is_input(j) and label ~= "hidden" and label:sub(1,1) ~= "#" then local _, _, pd = ARDOUR.LuaAPI.plugin_automation(proc, n) local val = ARDOUR.LuaAPI.get_processor_param(proc, n, true) -- Clamp values at plugin max and min if val < pd.lower then val = pd.lower end if val > pd.upper then val = pd.upper end --print(r:name(), "->", proc:display_name(), "(#".. n ..")", label, val) params[n] = val end n = n + 1 end end i = i + 1 local tmp_params_str = "" for k, v in pairs(params) do tmp_params_str = tmp_params_str .. string.format(params_string, k, ARDOUR.LuaAPI.ascii_dtostr(v)) end local proc_str = string.format( processor_string, id, ptype, proc:display_name(), r:name(), r:to_stateful():id():to_s(), tmp_params_str, active ) file = io.open(path, "a") file:write(proc_str, "\n") file:close() end ::nextroute:: end end local store_options = { { type = "label", col=0, colspan=1, align="right", title = "Name:" }, { type = "entry", col=1, colspan=1, align="left" , key = "filename", default = Session:name(), title=""}, { type = "label", col=0, colspan=1, align="right", title = "Location:" }, { type = "radio", col=1, colspan=3, align="left", key = "store-dir", title = "", values = { ['Global (accessible from any session)'] = 1, ['Local (this session only)'] = 2 }, default = 'Locally (this session only)' }, { type = "hseparator", title="", col=0, colspan = 3}, { type = "label", col=0, colspan=1, align="right", title = "Selected Tracks Only:" }, { type = "checkbox", col=1, colspan=1, align="left", key = "selected", default = false, title = ""}, --{ type = "label", col=0, colspan=2, align="left", title = ''}, --{ type = "label", col=0, colspan=2, align="left", title = "Global Path: " .. global_path}, --{ type = "label", col=0, colspan=2, align="left", title = "Local Path: " .. local_path}, } local global_ok, local_ok = setup_paths() print("global_ok="..tostring(global_ok)) print("local_ok="..tostring(local_ok)) if global_ok and local_ok then local rv = LuaDialog.Dialog("Store Mixer Settings:", store_options):run() if not(rv) then return end local filename = rv['filename'] if rv['store-dir'] == 1 then local store_path = ARDOUR.LuaAPI.build_filename(global_path, string.format("%s-%s.lua", filename, whoami())) local selected = rv['selected'] mark_tracks(selected, store_path) end if rv['store-dir'] == 2 then local store_path = ARDOUR.LuaAPI.build_filename(local_path, string.format("%s-%s.lua", filename, whoami())) print(store_path) local selected = rv['selected'] mark_tracks(selected, store_path) end end end end |
|
Further Problems: Storing fails if project name contains blanks. Fixed this. Still not fixed and beyond my skills: if the Project contains a foldback, recalling a stored setting duplicates all foldback strips again and again. This leads to unusable projects because DSP load increases every time you load. See the simple attached project files (diff them and you'll see). These were made in mixbus, but in ardour it's the same. mixer_settings_store.lua (10,781 bytes)
ardour { ["type"] = "EditorAction", name = "Store Mixer SettingsWB1.1", author = "Mixbus Team", description = [[ Stores the current Mixer state as a file that can be read and recalled arbitrarily by it's companion script, Recall Mixer Settings. Supports: processor settings, grouping, mute, solo, gain, trim, pan and processor ordering, plus re-adding certain deleted plugins. ]] } function factory () return function () local user_cfg = ARDOUR.user_config_directory(-1) local local_path = ARDOUR.LuaAPI.build_filename(Session:path(), 'mixer_settings') local global_path = ARDOUR.LuaAPI.build_filename(user_cfg, 'mixer_settings') function exists(file) local ok, err, code = os.rename(file, file) if not ok then if code == 13 then -- Permission denied, but it exists return true end end return ok, err end function whoami() if not pcall(function() local first_check = Session:get_mixbus(0) end) then return "Ardour" else local second_check = Session:get_mixbus(11) if second_check:isnil() then return "Mixbus" else return "32C" end end end function isdir(path) return exists("\"" .. path .. "\"" .. "/") end function setup_paths() local global_ok, local_ok = false, false if not(isdir(global_path)) then global_ok, _, _ = os.execute('mkdir '.. "\"" .. global_path .. "\"") if global_ok == 0 then global_ok = true end else global_ok = true end if not(isdir(local_path)) then local_ok, _, _ = os.execute('mkdir '.. "\"" .. local_path .. "\"") if local_ok == 0 then local_ok = true end else local_ok = true end return global_ok, local_ok end function get_processor_by_name(track, name) local i = 0 local proc = track:nth_processor(i) repeat if(proc:display_name() == name) then return proc else i = i + 1 end proc = track:nth_processor(i) until proc:isnil() end function group_by_id(id) local id = tonumber(id) for g in Session:route_groups():iter() do local group_id = tonumber(g:to_stateful():id():to_s()) if group_id == id then return g end end end function group_by_name(name) for g in Session:route_groups():iter() do if g:name() == name then return g end end end function route_groupid_interrogate(t) local group = false for g in Session:route_groups():iter() do for r in g:route_list():iter() do if r:name() == t:name() then group = g:to_stateful():id():to_s() end end end return group end function route_group_interrogate(t) for g in Session:route_groups():iter() do for r in g:route_list():iter() do if r:name() == t:name() then return g end end end end function empty_last_store(path) --empty current file from last run local file = io.open(path, "w") --file:write(string.format("instance = { whoami = '%s' }", whoami()) file:write("") file:close() end function mark_tracks(selected, path) empty_last_store(path) local route_string = [[instance = { route_id = %d, route_name = '%s', gain_control = %s, trim_control = %s, pan_control = %s, sends = {%s}, muted = %s, soloed = %s, order = {%s}, cache = {%s}, group = %s, group_name = '%s', pi_order = %d }]] local group_string = [[instance = { group_id = %s, name = '%s', routes = {%s}, }]] local processor_string = [[instance = { plugin_id = %d, type = %d, display_name = '%s', owned_by_route_name = '%s', owned_by_route_id = %d, parameters = {%s}, active = %s, }]] local group_route_string = " [%d] = %s," local proc_order_string = " [%d] = %d," local proc_cache_string = " [%d] = {'%s', %d}," local params_string = " [%d] = %s," --ensure easy-to-read formatting doesn't make it through local route_string = string.gsub(route_string, "[\n\t%s]", "") local group_string = string.gsub(group_string, "[\n\t%s]", "") local processor_string = string.gsub(processor_string, "[\n\t%s]", "") local sel = Editor:get_selection () local groups_to_write = {} local i = 0 local tracks = Session:get_stripables() if selected then tracks = sel.tracks:routelist() end for r in tracks:iter() do local group = route_group_interrogate(r) if group then local already_there = false for _, v in pairs(groups_to_write) do if group == v then already_there = true end end if not(already_there) then groups_to_write[#groups_to_write + 1] = group end end end for _, g in pairs(groups_to_write) do local tmp_str = "" for t in g:route_list():iter() do tmp_str = tmp_str .. string.format(group_route_string, i, t:to_stateful():id():to_s()) i = i + 1 end local group_str = string.format( group_string, g:to_stateful():id():to_s(), g:name(), tmp_str ) file = io.open(path, "a") file:write(group_str, "\r\n") file:close() end for r in tracks:iter() do if r:is_monitor () or r:is_auditioner () or not(r:to_vca():isnil()) then goto nextroute end -- skip special routes r = r:to_route() if r:isnil() then goto nextroute end local order = ARDOUR.ProcessorList() local x = 0 repeat local proc = r:nth_processor(x) if not proc:isnil() then order:push_back(proc) end x = x + 1 until proc:isnil() local route_group = route_group_interrogate(r) if route_group then route_group = route_group:name() else route_group = "" end local rid = r:to_stateful():id():to_s() local pan = r:pan_azimuth_control() if pan:isnil() then pan = false else pan = pan:get_value() end --sometimes a route doesn't have pan, like the master. -- Get send information, if any. local send_string = "" local i = 0 repeat local fmt = "{%s, %s, %s, %s}" string.gsub(fmt, "[\n\t]", "") local values = {} for j, ctrl in pairs({ r:send_level_controllable(i), r:send_enable_controllable(i), r:send_pan_azimuth_controllable(i), r:send_pan_azimuth_enable_controllable(i), }) do if not(ctrl:isnil()) then values[#values + 1] = ctrl:get_value() else values[#values + 1] = "nil" end end send_string = send_string .. string.format(fmt, table.unpack(values)) send_string = send_string .. "," i = i + 1 until r:send_enable_controllable(i):isnil() print(send_string) local order_nmbr = 0 local tmp_order_str, tmp_cache_str = "", "" for p in order:iter() do local ptype if not(p:to_insert():isnil()) then ptype = p:to_insert():plugin(0):get_info().type else ptype = 99 end local pid = p:to_stateful():id():to_s() if not(string.find(p:display_name(), "latcomp")) then tmp_order_str = tmp_order_str .. string.format(proc_order_string, order_nmbr, pid) tmp_cache_str = tmp_cache_str .. string.format(proc_cache_string, pid, p:display_name(), ptype) end order_nmbr = order_nmbr + 1 end local route_str = string.format( route_string, rid, r:name(), ARDOUR.LuaAPI.ascii_dtostr(r:gain_control():get_value()), ARDOUR.LuaAPI.ascii_dtostr(r:trim_control():get_value()), tostring(ARDOUR.LuaAPI.ascii_dtostr(pan)), send_string, r:muted(), r:soloed(), tmp_order_str, tmp_cache_str, route_groupid_interrogate(r), route_group, r:presentation_info_ptr():order() ) file = io.open(path, "a") file:write(route_str, "\n") file:close() local i = 0 while true do local params = {} local proc = r:nth_plugin (i) if proc:isnil () then break end local active = proc:active() local id = proc:to_stateful():id():to_s() local plug = proc:to_insert ():plugin (0) local ptype = proc:to_insert():plugin(0):get_info().type local n = 0 for j = 0, plug:parameter_count() - 1 do -- Iterate over all plugin parameters if plug:parameter_is_control(j) then local label = plug:parameter_label(j) if plug:parameter_is_input(j) and label ~= "hidden" and label:sub(1,1) ~= "#" then local _, _, pd = ARDOUR.LuaAPI.plugin_automation(proc, n) local val = ARDOUR.LuaAPI.get_processor_param(proc, n, true) -- Clamp values at plugin max and min if val < pd.lower then val = pd.lower end if val > pd.upper then val = pd.upper end print(r:name(), "->", proc:display_name(), "(#".. n ..")", label, val) params[n] = val end n = n + 1 end end i = i + 1 local tmp_params_str = "" for k, v in pairs(params) do tmp_params_str = tmp_params_str .. string.format(params_string, k, ARDOUR.LuaAPI.ascii_dtostr(v)) end local proc_str = string.format( processor_string, id, ptype, proc:display_name(), r:name(), r:to_stateful():id():to_s(), tmp_params_str, active ) file = io.open(path, "a") file:write(proc_str, "\n") file:close() end ::nextroute:: end end local store_options = { { type = "label", col=0, colspan=1, align="right", title = "Name:" }, { type = "entry", col=1, colspan=1, align="left" , key = "filename", default = Session:name(), title=""}, { type = "label", col=0, colspan=1, align="right", title = "Location:" }, { type = "radio", col=1, colspan=3, align="left", key = "store-dir", title = "", values = { ['Global (accessible from any session)'] = 1, ['Local (this session only)'] = 2 }, default = 'Locally (this session only)' }, { type = "hseparator", title="", col=0, colspan = 3}, { type = "label", col=0, colspan=1, align="right", title = "Selected Tracks Only:" }, { type = "checkbox", col=1, colspan=1, align="left", key = "selected", default = false, title = ""}, --{ type = "label", col=0, colspan=2, align="left", title = ''}, --{ type = "label", col=0, colspan=2, align="left", title = "Global Path: " .. global_path}, --{ type = "label", col=0, colspan=2, align="left", title = "Local Path: " .. local_path}, } local global_ok, local_ok = setup_paths() if global_ok and local_ok then local rv = LuaDialog.Dialog("Store Mixer Settings:", store_options):run() if not(rv) then return end local filename = rv['filename'] if rv['store-dir'] == 1 then local store_path = ARDOUR.LuaAPI.build_filename(global_path, string.format("%s-%s.lua", filename, whoami())) local selected = rv['selected'] mark_tracks(selected, store_path) end if rv['store-dir'] == 2 then local store_path = ARDOUR.LuaAPI.build_filename(local_path, string.format("%s-%s.lua", filename, whoami())) print(store_path) local selected = rv['selected'] mark_tracks(selected, store_path) end end end end mixer_settings_recall.lua (14,745 bytes)
ardour { ["type"] = "EditorAction", name = "Recall Mixer SettingsWB4.2", author = "Mixbus Team", description = [[ Recalls mixer settings outined by files created by Store Mixer Settings. Allows for some room to change Source and Destination. ]] } function factory () local acoraida_monicas_last_used_recall_file return function () local user_cfg = ARDOUR.user_config_directory(-1) local local_path = ARDOUR.LuaAPI.build_filename(Session:path(), 'mixer_settings') local global_path = ARDOUR.LuaAPI.build_filename(user_cfg, 'mixer_settings') --local debug = 1 local invalidate = {} function exists(file) local ok, err, code = os.rename(file, file) if not ok then if code == 13 then -- Permission denied, but it exists return true end end return ok, err end function whoami() if not pcall(function() local first_check = Session:get_mixbus(0) end) then return "Ardour" else local second_check = Session:get_mixbus(11) if second_check:isnil() then return "Mixbus" else return "32C" end end end function isdir(path) return exists(path.."/") end function get_processor_by_name(track, name) local i = 0 local proc = track:nth_processor(i) repeat if(proc:display_name() == name) then return proc else i = i + 1 end proc = track:nth_processor(i) until proc:isnil() end function new_plugin(name, type) local plugin = ARDOUR.LuaAPI.new_plugin(Session, name, type, "") if not(plugin:isnil()) then return plugin end end function group_by_id(id) local id = tonumber(id) for g in Session:route_groups():iter() do local group_id = tonumber(g:to_stateful():id():to_s()) if group_id == id then return g end end end function group_by_name(name) for g in Session:route_groups():iter() do if g:name() == name then return g end end end function route_groupid_interrogate(t) local group = false for g in Session:route_groups():iter() do for r in g:route_list():iter() do if r:name() == t:name() then group = g:to_stateful():id():to_s() end end end return group end function route_group_interrogate(t) for g in Session:route_groups():iter() do for r in g:route_list():iter() do if r:name() == t:name() then return g end end end end function recall(debug, path, dry_run) local file = io.open(path, "r") assert(file, "File not found!") local bypass_routes = {} local i = 0 for l in file:lines() do --print(i, l) local create_groups = dry_run["create_groups"] local skip_line = false local plugin, route, group = false, false, false local f = load(l) if debug then --print('create_groups ' .. tostring(create_groups)) --print(i, string.sub(l, 0, 29), f) end if f then f() end if instance["route_id"] then route = true end if instance["plugin_id"] then plugin = true end if instance["group_id"] then group = true end if group then local g_id = instance["group_id"] local routes = instance["routes"] local name = instance["name"] local mygroup = group_by_id(g_id) if not(mygroup) then if create_groups then local newgroup = Session:new_route_group(name) for _, v in pairs(routes) do local rt = Session:route_by_id(PBD.ID(v)) if rt:isnil() then rt = Session:route_by_name(name) end if not(rt:isnil()) then newgroup:add(rt) end end end end end if route then local substitution = tonumber(dry_run["destination-"..i]) if substitution == 0 then bypass_routes[#bypass_routes + 1] = instance["route_id"] goto nextline end local old_order = ARDOUR.ProcessorList() local route_id = instance["route_id"] local r_id = PBD.ID(instance["route_id"]) local muted, soloed = instance["muted"], instance["soloed"] local order = instance["order"] local cache = instance["cache"] local group = instance["group"] local group_name = instance["group_name"] local name = instance["route_name"] local gc, tc, pc = instance["gain_control"], instance["trim_control"], instance["pan_control"] local sends = instance["sends"] if not(substitution == instance["route_id"]) then print('SUBSTITUTION FOR: ', name, substitution, Session:route_by_id(PBD.ID(substitution)):name()) --bypass_routes[#bypass_routes + 1] = route_id was_subbed = true r_id = PBD.ID(substitution) end local rt = Session:route_by_id(r_id) if rt:isnil() then rt = Session:route_by_name(name) end if rt:isnil() then goto nextline end if sends then for i, data in pairs(sends) do i = i-1 for j, ctrl in pairs({ rt:send_level_controllable(i), rt:send_enable_controllable(i), rt:send_pan_azimuth_controllable(i), rt:send_pan_azimuth_enable_controllable(i), }) do if not(ctrl:isnil()) then local value = data[j] if value then if debug then print("Setting " .. ctrl:name() .. " to value " .. value) end ctrl:set_value(value, PBD.GroupControlDisposition.NoGroup) end end end end end local cur_group_id = route_groupid_interrogate(rt) if not(group) and (cur_group_id) then local g = group_by_id(cur_group_id) if g then g:remove(rt) end end local rt_group = group_by_name(group_name) if rt_group then rt_group:add(rt) end well_known = { 'PRE', 'Trim', 'EQ', 'Comp', 'Fader', 'POST', "Input Stage", "Mixbus Limiter" } protected_instrument = false for k, v in pairs(order) do local proc = Session:processor_by_id(PBD.ID(1)) if not(was_subbed) then proc = Session:processor_by_id(PBD.ID(v)) end if proc:isnil() then for id, sub_tbl in pairs(cache) do local name = sub_tbl[1] local type = sub_tbl[2] if v == id then proc = new_plugin(name, type) for _, control in pairs(well_known) do if name == control then proc = get_processor_by_name(rt, control) if proc and not(proc:isnil()) then invalidate[v] = proc:to_stateful():id():to_s() goto nextproc end end end if not(proc) then goto nextproc end if not(proc:isnil()) then rt:add_processor_by_index(proc, 0, nil, true) invalidate[v] = proc:to_stateful():id():to_s() end end end end ::nextproc:: if proc and not(proc:isnil()) then old_order:push_back(proc) end if not(old_order:empty()) and not(protected_instrument) then if not(rt:to_track():to_midi_track():isnil()) then if not(rt:the_instrument():isnil()) then protected_instrument = true old_order:push_back(rt:the_instrument()) end end end end rt:reorder_processors(old_order, nil) if muted then rt:mute_control():set_value(1, 1) else rt:mute_control():set_value(0, 1) end if soloed then rt:solo_control():set_value(1, 1) else rt:solo_control():set_value(0, 1) end rt:gain_control():set_value(gc, 1) rt:trim_control():set_value(tc, 1) if pc ~= false and not(rt:is_master()) then rt:pan_azimuth_control():set_value(pc, 1) end end if plugin then --if the plugin is owned by a route --we decided not to use, skip it for _, v in pairs(bypass_routes) do if instance["owned_by_route_id"] == v then goto nextline end end local enable = {} local params = instance["parameters"] local p_id = instance["plugin_id"] local act = instance["active"] for k, v in pairs(invalidate) do --invalidate any deleted plugin's id if p_id == k then p_id = v end end local proc = Session:processor_by_id(PBD.ID(p_id)) if proc:isnil() then goto nextline end local plug = proc:to_insert():plugin(0) local ctl = 0 for j = 0, plug:parameter_count() - 1 do if plug:parameter_is_control(j) then local label = plug:parameter_label(j) value = params[ctl] if value then if string.find(label, "Assign") or string.find(label, "Enable") then --@ToDo: Check Plugin type == LADSPA or VST? enable[ctl] = value -- Queue enable assignment for later goto skip_param end if not(ARDOUR.LuaAPI.set_processor_param(proc, ctl, value)) then print("Could not set ctrl port " .. ctl .. " to " .. value) end end ::skip_param:: ctl = ctl + 1 end end for k, v in pairs(enable) do ARDOUR.LuaAPI.set_processor_param(proc, k, v) end if act then proc:activate() else proc:deactivate() end end ::nextline:: i = i + 1 end end function dry_run(debug, path) --returns a dialog-able table of --everything we do (logically) --in the recall function local route_values = {['----'] = "0"} for r in Session:get_routes():iter() do route_values[r:name()] = r:to_stateful():id():to_s() end local i = 0 local dry_table = { {type = "label", align="right", key="col-1-title", col=0, colspan=1, title = 'Source:'}, {type = "label", align="left", key="col-2-title", col=1, colspan=1, title = 'Destination:'}, } local file = io.open(path, "r") assert(file, "File not found!") pad = 0 for l in file:lines() do local do_plugin, do_route, do_group = false, false, false local f = load(l) if debug then print(i, string.sub(l, 0, 29), f) end if f then f() end if instance["route_id"] then do_route = true end if instance["plugin_id"] then do_plugin = true end if instance["group_id"] then do_group = true end if do_group then local group_id = instance["group_id"] local group_name = instance["name"] local dlg_title, action_title = "", "" local group_ptr = group_by_id(group_id) if not(group_ptr) then dlg_title = string.format("(Group) %s.", group_name) --action_title = "will create and use settings" else dlg_title = string.format("(Group) %s.", group_ptr:name()) --action_title = "will use group settings" end table.insert(dry_table, { order=pad, type = "label", align="right", key = "group-"..i , col = 0, colspan = 1, title = dlg_title }) pad = pad + 1 end if do_route then local route_id = instance["route_id"] local route_name = instance["route_name"] local dlg_title = "" local route_ptr = Session:route_by_id(PBD.ID(route_id)) if route_ptr:isnil() then route_ptr = Session:route_by_name(route_name) if not(route_ptr:isnil()) then dlg_title = string.format("%s", route_ptr:name()) --action_title = "will use route settings" else dlg_title = string.format("%s", route_name) --action_title = "will be ignored" end else dlg_title = string.format("%s", route_ptr:name()) --action_title = "will use route settings" end if route_ptr:isnil() then name = route_name else name = route_ptr:name() end table.insert(dry_table, { order=instance['pi_order']+pad, type = "label", align="right", key = "route-"..i , col = 0, colspan = 1, title = dlg_title }) table.insert(dry_table, { type = "dropdown", align="left", key = "destination-"..i, col = 1, colspan = 1, title = "", values = route_values, default = name or "----" }) end i = i + 1 end table.insert(dry_table, { type = "checkbox", col=0, colspan=2, align="left", key = "create_groups", default = true, title = "Create Groups if necessary?" }) return dry_table end local global_vs_local_dlg = { { type = "label", col=0, colspan=20, align="left", title = "" }, { type = "radio", col=0, colspan=20, align="left", key = "recall-dir", title = "", values = { ['Pick from Global Settings'] = 1, ['Pick from Local Settings'] = 2, ['Last Used Recall File'] = 3, }, default = 'Pick from Local Settings' }, { type = "label", col=0, colspan=20, align="left", title = ""}, } local recall_options = { { type = "label", col=0, colspan=10, align="left", title = "" }, { type = "file", col=0, colspan=15, align="left", key = "file", title = "Select a Settings File", path = ARDOUR.LuaAPI.build_filename(Session:path(), "export", "params.lua") }, { type = "label", col=0, colspan=10, align="left", title = "" }, } local gvld = LuaDialog.Dialog("Recall Mixer Settings:", global_vs_local_dlg):run() if not(gvld) then return else if gvld['recall-dir'] == 1 then local global_ok = isdir(global_path) local global_default_path = ARDOUR.LuaAPI.build_filename(global_path, string.format("FactoryDefault-%s.lua", whoami())) print(global_default_path) if global_ok then recall_options[2]['path'] = global_default_path local rv = LuaDialog.Dialog("Recall Mixer Settings:", recall_options):run() if not(rv) then return end local dry_return = LuaDialog.Dialog("Recall Mixer Settings:", dry_run(false, rv['file'])):run() if dry_return then acoraida_monicas_last_used_recall_file = rv['file'] recall(true, rv['file'], dry_return) else return end else LuaDialog.Message ("Recall Mixer Settings:", global_path .. ' does not exist!\nPlease run Store Mixer Settings first.', LuaDialog.MessageType.Info, LuaDialog.ButtonType.Close):run() end end if gvld['recall-dir'] == 2 then local local_ok = isdir(local_path) local local_default_path = ARDOUR.LuaAPI.build_filename(local_path, 'asdf') print(local_default_path) if local_ok then recall_options[2]['path'] = local_default_path local rv = LuaDialog.Dialog("Recall Mixer Settings:", recall_options):run() if not(rv) then return end local dry_return = LuaDialog.Dialog("Recall Mixer Settings:", dry_run(false, rv['file'])):run() if dry_return then acoraida_monicas_last_used_recall_file = rv['file'] recall(true, rv['file'], dry_return) else return end else LuaDialog.Message ("Recall Mixer Settings:", local_path .. 'does not exist!\nPlease run Store Mixer Settings first.', LuaDialog.MessageType.Info, LuaDialog.ButtonType.Close):run() end end if gvld['recall-dir'] == 3 then if acoraida_monicas_last_used_recall_file then local dry_return = LuaDialog.Dialog("Recall Mixer Settings:", dry_run(false, acoraida_monicas_last_used_recall_file)):run() if dry_return then recall(true, acoraida_monicas_last_used_recall_file, dry_return) else return end else LuaDialog.Message ("Script has no record of last used file:", 'Please pick a recall file and then this option will be available', LuaDialog.MessageType.Info, LuaDialog.ButtonType.Close):run() end end end end end |
Date Modified | Username | Field | Change |
---|---|---|---|
2021-08-02 14:09 | Werner Back | New Issue | |
2021-08-03 10:53 | Werner Back | Note Added: 0026087 | |
2021-08-04 11:26 | Werner Back | Note Added: 0026089 | |
2021-08-05 06:21 | Werner Back | File Added: a_db2b41821.lua | |
2021-08-05 06:21 | Werner Back | Note Added: 0026090 | |
2021-11-14 10:00 | Werner Back | File Added: mixer_settings_store.lua | |
2021-11-14 10:00 | Werner Back | File Added: mixer_settings_recall.lua | |
2021-11-14 10:00 | Werner Back | File Added: Simple-fb-duplicated.ardour | |
2021-11-14 10:00 | Werner Back | File Added: Simple-fb-triplicated.ardour | |
2021-11-14 10:00 | Werner Back | File Added: Simple.ardour | |
2021-11-14 10:00 | Werner Back | Note Added: 0026216 |