diff options
Diffstat (limited to 'gtk2_ardour/mixer_ui.cc')
-rw-r--r-- | gtk2_ardour/mixer_ui.cc | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 6eb5095016..8fcb76975b 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -47,9 +47,11 @@ #include "ardour/amp.h" #include "ardour/debug.h" +#include "ardour/audio_port.h" #include "ardour/audio_track.h" #include "ardour/midi_track.h" #include "ardour/monitor_control.h" +#include "ardour/panner_shell.h" #include "ardour/plugin_manager.h" #include "ardour/route_group.h" #include "ardour/selection.h" @@ -134,6 +136,7 @@ Mixer_UI::Mixer_UI () _content.set_data ("ardour-bindings", bindings); PresentationInfo::Change.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::presentation_info_changed, this, _1), gui_context()); + Route::FanOut.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::fan_out, this, _1, false, true), gui_context()); scroller.set_can_default (true); // set_default (scroller); @@ -928,6 +931,115 @@ Mixer_UI::sync_treeview_from_presentation_info (PropertyChange const & what_chan redisplay_track_list (); } +void +Mixer_UI::fan_out (boost::weak_ptr<Route> wr, bool to_busses, bool group) +{ + boost::shared_ptr<ARDOUR::Route> route = wr.lock (); + + if (!ARDOUR_UI_UTILS::engine_is_running () || ! route) { + return; + } + + DisplaySuspender ds; + boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (route->the_instrument ()); + assert (pi); + + const uint32_t n_outputs = pi->output_streams ().n_audio (); + if (route->n_outputs ().n_audio () != n_outputs) { + MessageDialog msg (string_compose ( + _("The Plugin's number of audio outputs ports (%1) does not match the Tracks's number of audio outputs (%2). Cannot fan out."), + n_outputs, route->n_outputs ().n_audio ())); + msg.run (); + return; + } + +#define BUSNAME pd.group_name + "(" + route->name () + ")" + + /* count busses and channels/bus */ + boost::shared_ptr<Plugin> plugin = pi->plugin (); + std::map<std::string, uint32_t> busnames; + for (uint32_t p = 0; p < n_outputs; ++p) { + const Plugin::IOPortDescription& pd (plugin->describe_io_port (DataType::AUDIO, false, p)); + std::string bn = BUSNAME; + busnames[bn]++; + } + + if (busnames.size () < 2) { + MessageDialog msg (_("Instrument has only 1 output bus. Nothing to fan out.")); + msg.run (); + return; + } + + uint32_t outputs = 2; + if (_session->master_out ()) { + outputs = std::max (outputs, _session->master_out ()->n_inputs ().n_audio ()); + } + + route->output ()->disconnect (this); + route->panner_shell ()->set_bypassed (true); + + boost::shared_ptr<AutomationControl> msac = route->master_send_enable_controllable (); + if (msac) { + msac->start_touch (msac->session().transport_sample()); + msac->set_value (0, PBD::Controllable::NoGroup); + } + + RouteList to_group; + for (uint32_t p = 0; p < n_outputs; ++p) { + const Plugin::IOPortDescription& pd (plugin->describe_io_port (DataType::AUDIO, false, p)); + std::string bn = BUSNAME; + boost::shared_ptr<Route> r = _session->route_by_name (bn); + if (!r) { + try { + if (to_busses) { + RouteList rl = _session->new_audio_route (busnames[bn], outputs, NULL, 1, bn, PresentationInfo::AudioBus, PresentationInfo::max_order); + r = rl.front (); + assert (r); + } else { + list<boost::shared_ptr<AudioTrack> > tl = + _session->new_audio_track (busnames[bn], outputs, NULL, 1, bn, PresentationInfo::max_order, Normal); + r = tl.front (); + assert (r); + + boost::shared_ptr<ControlList> cl (new ControlList); + cl->push_back (r->monitoring_control ()); + _session->set_controls (cl, (double) MonitorInput, Controllable::NoGroup); + } + } catch (...) { + if (!to_group.empty()) { + boost::shared_ptr<RouteList> rl (&to_group); + _session->remove_routes (rl); + } + return; + } + r->input ()->disconnect (this); + } + to_group.push_back (r); + route->output ()->audio (p)->connect (r->input ()->audio (pd.group_channel).get()); + } +#undef BUSNAME + + if (group) { + RouteGroup* rg = NULL; + const std::list<RouteGroup*>& rgs (_session->route_groups ()); + for (std::list<RouteGroup*>::const_iterator i = rgs.begin (); i != rgs.end (); ++i) { + if ((*i)->name () == pi->name ()) { + rg = *i; + break; + } + } + if (!rg) { + rg = new RouteGroup (*_session, pi->name ()); + _session->add_route_group (rg); + rg->set_gain (false); + } + + GroupTabs::set_group_color (rg, route->presentation_info().color()); + for (RouteList::const_iterator i = to_group.begin(); i != to_group.end(); ++i) { + rg->add (*i); + } + } +} MixerStrip* Mixer_UI::strip_by_route (boost::shared_ptr<Route> r) const |