2018-07-31 13:57:22 -04:00
ardour {
2020-01-30 14:43:05 -05:00
[ " type " ] = " EditorAction " ,
name = " Recall Mixer Settings " ,
author = " Mixbus Team " ,
description = [ [
2018-07-31 13:57:22 -04:00
2020-01-30 14:43:05 -05:00
Recalls mixer settings outined by files
created by Store Mixer Settings .
2018-07-31 13:57:22 -04:00
2020-01-30 14:43:05 -05:00
Allows for some room to change Source
and Destination .
2018-07-31 13:57:22 -04:00
2020-01-30 14:43:05 -05:00
] ]
2018-07-31 13:57:22 -04:00
}
2020-01-30 10:09:51 -05:00
function factory ( )
2020-01-30 14:43:05 -05:00
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 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 group = group_by_id ( g_id )
if not ( group ) then
if create_groups then
local group = 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 group : 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
2020-04-16 11:59:16 -04:00
well_known = {
' PRE ' ,
' Trim ' ,
' EQ ' ,
' Comp ' ,
' Fader ' ,
' POST ' ,
" Input Stage " ,
" Mixbus Limiter "
}
2020-01-30 14:43:05 -05:00
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 )
2020-04-16 11:59:16 -04:00
if proc and not ( proc : isnil ( ) ) then
invalidate [ v ] = proc : to_stateful ( ) : id ( ) : to_s ( )
goto nextproc
end
2020-01-30 14:43:05 -05:00
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 )
2020-04-15 14:38:33 -04:00
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
2020-01-30 14:43:05 -05:00
end
end
for k , v in pairs ( enable ) do
ARDOUR.LuaAPI . set_processor_param ( proc , k , v )
end
2020-04-15 14:38:33 -04:00
2020-01-30 14:43:05 -05:00
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 = ' Last Used Recall File '
} ,
{ 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 ( false , rv [ ' file ' ] , dry_return )
else
return
end
else
LuaDialog.Message ( " Recall Mixer Settings: " ,
global_path .. ' does not exist! \n Please 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! \n Please 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
2018-07-31 13:57:22 -04:00
end end