From faf44386460b6cdda0aa249eb138e8fd82700194 Mon Sep 17 00:00:00 2001 From: Thomas Brand Date: Fri, 16 Sep 2016 22:09:05 +0200 Subject: [PATCH] Add convenience Lua bindings to access plugin controls --- libs/ardour/ardour/lua_api.h | 55 +++++++++++++++ libs/ardour/lua_api.cc | 132 ++++++++++++++++++++++++++++++++--- libs/ardour/luabindings.cc | 6 ++ 3 files changed, 183 insertions(+), 10 deletions(-) diff --git a/libs/ardour/ardour/lua_api.h b/libs/ardour/ardour/lua_api.h index f737eddc4b..ffffaea1b4 100644 --- a/libs/ardour/ardour/lua_api.h +++ b/libs/ardour/ardour/lua_api.h @@ -74,6 +74,42 @@ namespace ARDOUR { namespace LuaAPI { */ boost::shared_ptr new_plugin (ARDOUR::Session *s, const std::string& id, ARDOUR::PluginType type, const std::string& preset = ""); + /** set a plugin control-input parameter value by name + * + * @param proc Plugin-Processor + * @param name name of control-input to set + * @param value value to set + * @returns true on success, false on error or out-of-bounds value + */ + bool set_plugin_input_parameter_value_named(boost::shared_ptr proc, const std::string& name, float val); + + /** get a plugin control parameter value by name + * + * @param proc Plugin-Processor + * @param name name of control port to query + * @param ok boolean variable contains true or false after call returned. to be checked by caller before using value. + * @returns value + */ + float get_plugin_parameter_value_named(boost::shared_ptr proc, int type, const std::string& name, bool &ok); + + /** get a plugin control-input parameter value by name + * + * @param proc Plugin-Processor + * @param name name of control-input port to query + * @param ok boolean variable contains true or false after call returned. to be checked by caller before using value. + * @returns value + */ + float get_plugin_input_parameter_value_named(boost::shared_ptr proc, const std::string& name, bool &ok); + + /** get a plugin control-output parameter value by name + * + * @param proc Plugin-Processor + * @param name name of control-output port to query + * @param ok boolean variable contains true or false after call returned. to be checked by caller before using value. + * @returns value + */ + float get_plugin_output_parameter_value_named(boost::shared_ptr proc, const std::string& name, bool &ok); + /** set a plugin control-input parameter value * * @param proc Plugin-Processor @@ -82,6 +118,16 @@ namespace ARDOUR { namespace LuaAPI { * @returns true on success, false on error or out-of-bounds value */ bool set_processor_param (boost::shared_ptr proc, uint32_t which, float val); + + /** get a plugin control parameter value + * + * @param proc Plugin-Processor + * @param which control port to set (starting at 0, including ports of type input and output)) + * @param ok boolean variable contains true or false after call returned. to be checked by caller before using value. + * @returns value + */ + float get_processor_param (boost::shared_ptr proc, uint32_t which, bool &ok); + /** set a plugin control-input parameter value * * This is a wrapper around set_processor_param which looks up the Processor by plugin-insert. @@ -93,6 +139,15 @@ namespace ARDOUR { namespace LuaAPI { */ bool set_plugin_insert_param (boost::shared_ptr pi, uint32_t which, float val); + /** get a plugin control parameter value + * + * @param proc Plugin-Insert + * @param which control port to query (starting at 0, including ports of type input and output) + * @param ok boolean variable contains true or false after call returned. to be checked by caller before using value. + * @returns value + */ + float get_plugin_insert_param (boost::shared_ptr pi, uint32_t which, bool &ok); + /** * A convenience function to get a Automation Lists and ParamaterDescriptor * for a given plugin control. diff --git a/libs/ardour/lua_api.cc b/libs/ardour/lua_api.cc index 1cf403b8b0..0ca51ad2ad 100644 --- a/libs/ardour/lua_api.cc +++ b/libs/ardour/lua_api.cc @@ -156,6 +156,98 @@ ARDOUR::LuaAPI::new_plugin (Session *s, const string& name, ARDOUR::PluginType t return boost::shared_ptr (new PluginInsert (*s, p)); } +bool +ARDOUR::LuaAPI::set_plugin_input_parameter_value_named(boost::shared_ptr proc, const string& name, float val) +{ + boost::shared_ptr pi = boost::dynamic_pointer_cast (proc); + if (!pi) { return false; } + boost::shared_ptr plugin = pi->plugin(); + if (!plugin) { return false; } + + bool test=false; + uint32_t controlid=0; + ParameterDescriptor pd; + + for (uint32_t param_index = 0; param_index < plugin->parameter_count(); ++param_index) + { + controlid = plugin->nth_parameter (param_index, test); + if (!test) + { + break; + } + else + { + //skip output ports + if (!plugin->parameter_is_input (controlid)) { continue; } + string param_name=pi->describe_parameter(Evoral::Parameter(PluginAutomation, 0, controlid)); + if (param_name.compare(name) != 0) { continue; } + if (plugin->get_parameter_descriptor (controlid, pd) != 0) { continue; } + if (val < pd.lower || val > pd.upper) { break; } + boost::shared_ptr c = pi->automation_control (Evoral::Parameter(PluginAutomation, 0, controlid)); + c->set_value (val, PBD::Controllable::NoGroup); + return true; + } + } + return false; +} + +float +ARDOUR::LuaAPI::get_plugin_parameter_value_named(boost::shared_ptr proc, int type, const string& name, bool &ok) +{ + ok=false; + boost::shared_ptr pi = boost::dynamic_pointer_cast (proc); + if (!pi) { return 0; } + boost::shared_ptr plugin = pi->plugin(); + if (!plugin) { return 0; } + + bool test=false; + uint32_t controlid=0; + ParameterDescriptor pd; + + for (uint32_t param_index = 0; param_index < plugin->parameter_count(); ++param_index) + { + controlid = plugin->nth_parameter (param_index, test); + if (!test) + { + return 0; + } + else + { + if(type==0) //input + { + //skip output ports + if (!plugin->parameter_is_input (controlid)) { continue; } + } + else if(type==1) //output + { + //skip input ports + if (plugin->parameter_is_input (controlid)) { continue; } + } + else + { + return 0; + } + string param_name=pi->describe_parameter(Evoral::Parameter(PluginAutomation, 0, controlid)); + if (param_name.compare(name) != 0) { continue; } + ok=true; + return plugin->get_parameter ( controlid ); + } + } + return 0; +} + +float +ARDOUR::LuaAPI::get_plugin_input_parameter_value_named(boost::shared_ptr proc, const string& name, bool &ok) +{ + return get_plugin_parameter_value_named(proc,0,name,ok); +} + +float +ARDOUR::LuaAPI::get_plugin_output_parameter_value_named(boost::shared_ptr proc, const string& name, bool &ok) +{ + return get_plugin_parameter_value_named(proc,1,name,ok); +} + bool ARDOUR::LuaAPI::set_plugin_insert_param (boost::shared_ptr pi, uint32_t which, float val) { @@ -176,6 +268,17 @@ ARDOUR::LuaAPI::set_plugin_insert_param (boost::shared_ptr pi, uin return true; } +float +ARDOUR::LuaAPI::get_plugin_insert_param (boost::shared_ptr pi, uint32_t which, bool &ok) +{ + ok=false; + boost::shared_ptr plugin = pi->plugin(); + if (!plugin) { return 0; } + uint32_t controlid = plugin->nth_parameter (which, ok); + if (!ok) { return 0; } + return plugin->get_parameter ( controlid ); +} + bool ARDOUR::LuaAPI::set_processor_param (boost::shared_ptr proc, uint32_t which, float val) { @@ -184,6 +287,15 @@ ARDOUR::LuaAPI::set_processor_param (boost::shared_ptr proc, uint32_t return set_plugin_insert_param (pi, which, val); } +float +ARDOUR::LuaAPI::get_processor_param (boost::shared_ptr proc, uint32_t which, bool &ok) +{ + ok=false; + boost::shared_ptr pi = boost::dynamic_pointer_cast (proc); + if (!pi) { return false; } + return get_plugin_insert_param (pi, which, ok); +} + int ARDOUR::LuaAPI::plugin_automation (lua_State *L) { @@ -242,7 +354,7 @@ ARDOUR::LuaOSC::Address::send (lua_State *L) int top = lua_gettop(L); if (top < 3) { - return luaL_argerror (L, 1, "invalid number of arguments, :send (path, type, ...)"); + return luaL_argerror (L, 1, "invalid number of arguments, :send (path, type, ...)"); } const char* path = luaL_checkstring (L, 2); @@ -250,7 +362,7 @@ ARDOUR::LuaOSC::Address::send (lua_State *L) assert (path && type); if ((int) strlen(type) != top - 3) { - return luaL_argerror (L, 3, "type description does not match arguments"); + return luaL_argerror (L, 3, "type description does not match arguments"); } lo_message msg = lo_message_new (); @@ -263,7 +375,7 @@ ARDOUR::LuaOSC::Address::send (lua_State *L) case LUA_TSTRING: if (t == LO_STRING) { ok = lo_message_add_string (msg, luaL_checkstring(L, i)); - } else if (t == LO_CHAR) { + } else if (t == LO_CHAR) { char c = luaL_checkstring (L, i) [0]; ok = lo_message_add_char (msg, c); } @@ -352,7 +464,7 @@ ARDOUR::LuaAPI::build_filename (lua_State *L) std::vector elem; int top = lua_gettop(L); if (top < 1) { - return luaL_argerror (L, 1, "invalid number of arguments, build_filename (path, ...)"); + return luaL_argerror (L, 1, "invalid number of arguments, build_filename (path, ...)"); } for (int i = 1; i <= top; ++i) { int lt = lua_type (L, i); @@ -368,14 +480,14 @@ ARDOUR::LuaAPI::build_filename (lua_State *L) luabridge::LuaRef::Proxy& luabridge::LuaRef::Proxy::clone_instance (const void* classkey, void* p) { - lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); - lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); luabridge::UserdataPtr::push_raw (m_L, p, classkey); - lua_rawset (m_L, -3); - lua_pop (m_L, 1); - return *this; + lua_rawset (m_L, -3); + lua_pop (m_L, 1); + return *this; } LuaTableRef::LuaTableRef () {} @@ -451,7 +563,7 @@ LuaTableRef::set (lua_State* L) s.c = classkey; s.p = luabridge::Userdata::get_ptr (L, -2); } - } else { + } else { lua_pop (L, 2); } diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index 6bacc9b7ca..4bca2a7b73 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -1464,8 +1464,14 @@ LuaBindings::common (lua_State* L) .addFunction ("new_luaproc", ARDOUR::LuaAPI::new_luaproc) .addFunction ("new_plugin_info", ARDOUR::LuaAPI::new_plugin_info) .addFunction ("new_plugin", ARDOUR::LuaAPI::new_plugin) + .addFunction ("set_plugin_input_parameter_value_named", ARDOUR::LuaAPI::set_plugin_input_parameter_value_named) + .addRefFunction ("get_plugin_parameter_value_named", ARDOUR::LuaAPI::get_plugin_parameter_value_named) + .addRefFunction ("get_plugin_input_parameter_value_named", ARDOUR::LuaAPI::get_plugin_input_parameter_value_named) + .addRefFunction ("get_plugin_output_parameter_value_named", ARDOUR::LuaAPI::get_plugin_output_parameter_value_named) .addFunction ("set_processor_param", ARDOUR::LuaAPI::set_processor_param) .addFunction ("set_plugin_insert_param", ARDOUR::LuaAPI::set_plugin_insert_param) + .addRefFunction ("get_processor_param", ARDOUR::LuaAPI::get_processor_param) + .addRefFunction ("get_plugin_insert_param", ARDOUR::LuaAPI::get_plugin_insert_param) .addCFunction ("plugin_automation", ARDOUR::LuaAPI::plugin_automation) .addCFunction ("hsla_to_rgba", ARDOUR::LuaAPI::hsla_to_rgba) .addFunction ("usleep", Glib::usleep)