From ab3f0f75a88e84a4d4ea0bfef93da2046a347385 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 16 Dec 2015 06:00:56 -0500 Subject: [PATCH] new route API to discover/access well-known automation controls for panning, EQ and compression. The EQ and compression parts do nothing for Ardour, where there is no identifiable and understood plugin to perform their roles. They do work on mixbus, which also serves as a model for how to do this. --- libs/ardour/ardour/route.h | 44 +++++ libs/ardour/route.cc | 331 +++++++++++++++++++++++++++++++++++++ 2 files changed, 375 insertions(+) diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 2bafcf3b63..b63cbb9147 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -473,6 +473,50 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou boost::shared_ptr the_instrument() const; InstrumentInfo& instrument_info() { return _instrument_info; } + /* "well-known" controls for panning. Any or all of these may return + * null. + */ + + boost::shared_ptr pan_azimuth_control() const; + boost::shared_ptr pan_elevation_control() const; + boost::shared_ptr pan_width_control() const; + boost::shared_ptr pan_frontback_control() const; + boost::shared_ptr pan_lfe_control() const; + + /* "well-known" controls for an EQ in this route. Any or all may + * be null. eq_band_cnt() must return 0 if there is no EQ present. + * Passing an @param band value >= eq_band_cnt() will guarantee the + * return of a null ptr (or an empty string for eq_band_name()). + */ + uint32_t eq_band_cnt () const; + std::string eq_band_name (uint32_t) const; + boost::shared_ptr eq_gain_controllable (uint32_t band) const; + boost::shared_ptr eq_freq_controllable (uint32_t band) const; + boost::shared_ptr eq_q_controllable (uint32_t band) const; + boost::shared_ptr eq_shape_controllable (uint32_t band) const; + boost::shared_ptr eq_enable_controllable () const; + boost::shared_ptr eq_hpf_controllable () const; + + /* "well-known" controls for a compressor in this route. Any or all may + * be null. + */ + boost::shared_ptr comp_enable_controllable () const; + boost::shared_ptr comp_threshold_controllable () const; + boost::shared_ptr comp_speed_controllable () const; + boost::shared_ptr comp_mode_controllable () const; + boost::shared_ptr comp_makeup_controllable () const; + boost::shared_ptr comp_redux_controllable () const; + + /* @param mode must be supplied by the comp_mode_controllable(). All other values + * result in undefined behaviour + */ + std::string comp_mode_name (uint32_t mode) const; + /* @param mode - as for comp mode name. This returns the name for the + * parameter/control accessed via comp_speed_controllable(), which can + * be mode dependent. + */ + std::string comp_speed_name (uint32_t mode) const; + void protect_automation (); enum { diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 6ee55fc26e..7d66187e3a 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -5032,3 +5032,334 @@ Route::fill_buffers_with_input (BufferSet& bufs, boost::shared_ptr io, pfram bufs.set_count (io->n_ports()); } } + +boost::shared_ptr +Route::pan_azimuth_control() const +{ +#ifdef MIXBUS + boost::shared_ptr plug = ch_post(); + assert (plug); + const uint32_t port_channel_post_pan = 2; // gtk2_ardour/mixbus_ports.h + return boost::dynamic_pointer_cast (plug->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_channel_post_pan))); +#else + if (!_pannable || !panner()) { + return boost::shared_ptr(); + } + return _pannable->pan_azimuth_control; +#endif +} + +boost::shared_ptr +Route::pan_elevation_control() const +{ + if (Profile->get_mixbus() || !_pannable || !panner()) { + return boost::shared_ptr(); + } + return _pannable->pan_elevation_control; +} +boost::shared_ptr +Route::pan_width_control() const +{ + if (Profile->get_mixbus() || !_pannable || !panner()) { + return boost::shared_ptr(); + } + return _pannable->pan_width_control; +} +boost::shared_ptr +Route::pan_frontback_control() const +{ + if (Profile->get_mixbus() || !_pannable || !panner()) { + return boost::shared_ptr(); + } + return _pannable->pan_frontback_control; +} +boost::shared_ptr +Route::pan_lfe_control() const +{ + if (Profile->get_mixbus() || !_pannable || !panner()) { + return boost::shared_ptr(); + } + return _pannable->pan_lfe_control; +} + +uint32_t +Route::eq_band_cnt () const +{ + if (Profile->get_mixbus()) { + return 3; + } else { + /* Ardour has no well-known EQ object */ + return 0; + } +} + +boost::shared_ptr +Route::eq_gain_controllable (uint32_t band) const +{ +#ifdef MIXBUS + boost::shared_ptr eq = ch_eq(); + + if (!eq) { + return boost::shared_ptr(); + } + + uint32_t port_number; + switch (band) { + case 0: + if (is_master() || mixbus()) { + port_number = 4; + } else { + port_number = 8; + } + break; + case 1: + if (is_master() || mixbus()) { + port_number = 3; + } else { + port_number = 6; + } + break; + case 2: + if (is_master() || mixbus()) { + port_number = 2; + } else { + port_number = 4; + } + break; + default: + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_number))); +#else + return boost::shared_ptr(); +#endif +} +boost::shared_ptr +Route::eq_freq_controllable (uint32_t band) const +{ +#ifdef MIXBUS + + if (mixbus() || is_master()) { + /* no frequency controls for mixbusses or master */ + return boost::shared_ptr(); + } + + boost::shared_ptr eq = ch_eq(); + + if (!eq) { + return boost::shared_ptr(); + } + + uint32_t port_number; + switch (band) { + case 0: + port_number = 7; + break; + case 1: + port_number = 5; + break; + case 2: + port_number = 3; + break; + default: + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_number))); +#else + return boost::shared_ptr(); +#endif +} + +boost::shared_ptr +Route::eq_q_controllable (uint32_t band) const +{ + return boost::shared_ptr(); +} + +boost::shared_ptr +Route::eq_shape_controllable (uint32_t band) const +{ + return boost::shared_ptr(); +} + +boost::shared_ptr +Route::eq_enable_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr eq = ch_eq(); + + if (!eq) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 1))); +#else + return boost::shared_ptr(); +#endif +} + +boost::shared_ptr +Route::eq_hpf_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr eq = ch_eq(); + + if (!eq) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 2))); +#else + return boost::shared_ptr(); +#endif +} + +string +Route::eq_band_name (uint32_t band) const +{ + if (Profile->get_mixbus()) { + switch (band) { + case 0: + return _("lo"); + case 1: + return _("mid"); + case 2: + return _("hi"); + default: + return string(); + } + } else { + return string (); + } +} + +boost::shared_ptr +Route::comp_enable_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr comp = ch_comp(); + + if (!comp) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (comp->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 1))); +#else + return boost::shared_ptr(); +#endif +} +boost::shared_ptr +Route::comp_threshold_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr comp = ch_comp(); + + if (!comp) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (comp->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 2))); + +#else + return boost::shared_ptr(); +#endif +} +boost::shared_ptr +Route::comp_speed_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr comp = ch_comp(); + + if (!comp) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (comp->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 3))); +#else + return boost::shared_ptr(); +#endif +} +boost::shared_ptr +Route::comp_mode_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr comp = ch_comp(); + + if (!comp) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (comp->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 4))); +#else + return boost::shared_ptr(); +#endif +} +boost::shared_ptr +Route::comp_makeup_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr comp = ch_comp(); + + if (!comp) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (comp->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 5))); +#else + return boost::shared_ptr(); +#endif +} +boost::shared_ptr +Route::comp_redux_controllable () const +{ +#ifdef MIXBUS + boost::shared_ptr comp = ch_comp(); + + if (!comp) { + return boost::shared_ptr(); + } + + return boost::dynamic_pointer_cast (comp->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, 6))); +#else + return boost::shared_ptr(); +#endif +} + +string +Route::comp_mode_name (uint32_t mode) const +{ +#ifdef MIXBUS + switch (mode) { + case 0: + return _("Leveler"); + case 1: + return _("Compressor"); + case 2: + return _("Limiter"); + } + + return _("???"); +#else + return _("???"); +#endif +} + +string +Route::comp_speed_name (uint32_t mode) const +{ +#ifdef MIXBUS + switch (mode) { + case 0: + return _("Attk"); + case 1: + return _("Ratio"); + case 2: + return _("Rels"); + } + return _("???"); +#else + return _("???"); +#endif +}