mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 23:35:03 +01:00
Move RouteUI::fan_out to Mixer_UI
The previous version had various issues, in particular when creating Tracks with an instrument, the RouteUI was not available when the signal was emitted (likely caused by recent ee-work of Audio+MIDI and Tape track removal). However as side-effect fanned-out tracks/busses may now be ordered before the new instrument route. This also fixes an edge case of multiple fan-out in case there is more than one RouteUI instance (mixer, editor-mixer, meter-bridge).
This commit is contained in:
parent
f0b25a776b
commit
14f15ca1e9
3 changed files with 114 additions and 104 deletions
|
|
@ -47,9 +47,11 @@
|
||||||
|
|
||||||
#include "ardour/amp.h"
|
#include "ardour/amp.h"
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
|
#include "ardour/audio_port.h"
|
||||||
#include "ardour/audio_track.h"
|
#include "ardour/audio_track.h"
|
||||||
#include "ardour/midi_track.h"
|
#include "ardour/midi_track.h"
|
||||||
#include "ardour/monitor_control.h"
|
#include "ardour/monitor_control.h"
|
||||||
|
#include "ardour/panner_shell.h"
|
||||||
#include "ardour/plugin_manager.h"
|
#include "ardour/plugin_manager.h"
|
||||||
#include "ardour/route_group.h"
|
#include "ardour/route_group.h"
|
||||||
#include "ardour/selection.h"
|
#include "ardour/selection.h"
|
||||||
|
|
@ -134,6 +136,7 @@ Mixer_UI::Mixer_UI ()
|
||||||
_content.set_data ("ardour-bindings", bindings);
|
_content.set_data ("ardour-bindings", bindings);
|
||||||
|
|
||||||
PresentationInfo::Change.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::presentation_info_changed, this, _1), gui_context());
|
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);
|
scroller.set_can_default (true);
|
||||||
// set_default (scroller);
|
// set_default (scroller);
|
||||||
|
|
@ -928,6 +931,115 @@ Mixer_UI::sync_treeview_from_presentation_info (PropertyChange const & what_chan
|
||||||
redisplay_track_list ();
|
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*
|
MixerStrip*
|
||||||
Mixer_UI::strip_by_route (boost::shared_ptr<Route> r) const
|
Mixer_UI::strip_by_route (boost::shared_ptr<Route> r) const
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ public:
|
||||||
void do_vca_unassign (boost::shared_ptr<ARDOUR::VCA>);
|
void do_vca_unassign (boost::shared_ptr<ARDOUR::VCA>);
|
||||||
void show_spill (boost::shared_ptr<ARDOUR::Stripable>);
|
void show_spill (boost::shared_ptr<ARDOUR::Stripable>);
|
||||||
bool showing_spill_for (boost::shared_ptr<ARDOUR::Stripable>) const;
|
bool showing_spill_for (boost::shared_ptr<ARDOUR::Stripable>) const;
|
||||||
|
void fan_out (boost::weak_ptr<ARDOUR::Route>, bool to_busses, bool group);
|
||||||
|
|
||||||
sigc::signal1<void,boost::shared_ptr<ARDOUR::Stripable> > show_spill_change;
|
sigc::signal1<void,boost::shared_ptr<ARDOUR::Stripable> > show_spill_change;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2315,110 +2315,7 @@ RouteUI::manage_pins ()
|
||||||
void
|
void
|
||||||
RouteUI::fan_out (bool to_busses, bool group)
|
RouteUI::fan_out (bool to_busses, bool group)
|
||||||
{
|
{
|
||||||
if (!ARDOUR_UI_UTILS::engine_is_running ()) {
|
Mixer_UI::instance()->fan_out (_route, to_busses, group);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplaySuspender ds;
|
|
||||||
boost::shared_ptr<ARDOUR::Route> route = _route;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue