mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
yet more work on Ye Fabled Solo Architecture. now do forward and backward propagation of solo status from a soloed track. tweak GUI appearance
git-svn-id: svn://localhost/ardour2/branches/3.0@7001 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
56469c1956
commit
a8e354ed7b
13 changed files with 184 additions and 64 deletions
|
|
@ -395,6 +395,15 @@ style "mixer_solo_button_alternate" = "solo_button_alternate"
|
||||||
xthickness = 0
|
xthickness = 0
|
||||||
ythickness = 0
|
ythickness = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style "mixer_solo_button_alternate2" = "solo_button_alternate2"
|
||||||
|
{
|
||||||
|
font_name = "@FONT_SMALLER@"
|
||||||
|
xthickness = 0
|
||||||
|
ythickness = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
style "mixer_solo_button_active" = "solo_button_active"
|
style "mixer_solo_button_active" = "solo_button_active"
|
||||||
{
|
{
|
||||||
font_name = "@FONT_SMALLER@"
|
font_name = "@FONT_SMALLER@"
|
||||||
|
|
@ -1457,6 +1466,7 @@ widget "*SoloButton-alternate2" style:highest "solo_button_alternate2"
|
||||||
widget "*SoloButton-active" style:highest "solo_button_active"
|
widget "*SoloButton-active" style:highest "solo_button_active"
|
||||||
widget "*MixerSoloButton" style:highest "mixer_solo_button"
|
widget "*MixerSoloButton" style:highest "mixer_solo_button"
|
||||||
widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate"
|
widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate"
|
||||||
|
widget "*MixerSoloButton-alternate2" style:highest "mixer_solo_button_alternate2"
|
||||||
widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active"
|
widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active"
|
||||||
widget "*TrackLoopButton*" style:highest "track_loop_button"
|
widget "*TrackLoopButton*" style:highest "track_loop_button"
|
||||||
widget "*PanAutomationLineSelector*" style:highest "multiline_combo"
|
widget "*PanAutomationLineSelector*" style:highest "multiline_combo"
|
||||||
|
|
|
||||||
|
|
@ -494,8 +494,6 @@ ARDOUR_UI::reattach_tearoff (Box* b, Widget* w, int32_t n)
|
||||||
void
|
void
|
||||||
ARDOUR_UI::soloing_changed (bool onoff)
|
ARDOUR_UI::soloing_changed (bool onoff)
|
||||||
{
|
{
|
||||||
cerr << "solo change, " << onoff << endl;
|
|
||||||
|
|
||||||
if (solo_alert_button.get_active() != onoff) {
|
if (solo_alert_button.get_active() != onoff) {
|
||||||
solo_alert_button.set_active (onoff);
|
solo_alert_button.set_active (onoff);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -461,14 +461,14 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
||||||
}
|
}
|
||||||
|
|
||||||
(*x)->route()->mute_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_mute_display, this), gui_context());
|
(*x)->route()->mute_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_mute_display, this), gui_context());
|
||||||
(*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this), gui_context());
|
(*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
|
||||||
(*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
|
(*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
|
||||||
(*x)->route()->solo_safe_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_safe_display, this), gui_context());
|
(*x)->route()->solo_safe_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_safe_display, this), gui_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
update_rec_display ();
|
update_rec_display ();
|
||||||
update_mute_display ();
|
update_mute_display ();
|
||||||
update_solo_display ();
|
update_solo_display (true);
|
||||||
update_solo_isolate_display ();
|
update_solo_isolate_display ();
|
||||||
update_solo_safe_display ();
|
update_solo_safe_display ();
|
||||||
resume_redisplay ();
|
resume_redisplay ();
|
||||||
|
|
@ -1026,7 +1026,7 @@ EditorRoutes::update_mute_display ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EditorRoutes::update_solo_display ()
|
EditorRoutes::update_solo_display (bool /* selfsoloed */)
|
||||||
{
|
{
|
||||||
TreeModel::Children rows = _model->children();
|
TreeModel::Children rows = _model->children();
|
||||||
TreeModel::Children::iterator i;
|
TreeModel::Children::iterator i;
|
||||||
|
|
@ -1098,7 +1098,6 @@ EditorRoutes::name_edit (Glib::ustring const & path, Glib::ustring const & new_t
|
||||||
void
|
void
|
||||||
EditorRoutes::solo_changed_so_update_mute ()
|
EditorRoutes::solo_changed_so_update_mute ()
|
||||||
{
|
{
|
||||||
ENSURE_GUI_THREAD (*this, &EditorRoutes::solo_changed_so_update_mute)
|
|
||||||
update_mute_display ();
|
update_mute_display ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ private:
|
||||||
void handle_gui_changes (std::string const &, void *);
|
void handle_gui_changes (std::string const &, void *);
|
||||||
void update_rec_display ();
|
void update_rec_display ();
|
||||||
void update_mute_display ();
|
void update_mute_display ();
|
||||||
void update_solo_display ();
|
void update_solo_display (bool);
|
||||||
void update_solo_isolate_display ();
|
void update_solo_isolate_display ();
|
||||||
void update_solo_safe_display ();
|
void update_solo_safe_display ();
|
||||||
void set_all_tracks_visibility (bool);
|
void set_all_tracks_visibility (bool);
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
|
||||||
/* map the current state */
|
/* map the current state */
|
||||||
|
|
||||||
mute_changed (0);
|
mute_changed (0);
|
||||||
solo_changed (0);
|
update_solo_display ();
|
||||||
|
|
||||||
delete input_selector;
|
delete input_selector;
|
||||||
input_selector = 0;
|
input_selector = 0;
|
||||||
|
|
@ -435,7 +435,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
|
||||||
/* now force an update of all the various elements */
|
/* now force an update of all the various elements */
|
||||||
|
|
||||||
mute_changed (0);
|
mute_changed (0);
|
||||||
solo_changed (0);
|
update_solo_display ();
|
||||||
name_changed ();
|
name_changed ();
|
||||||
comment_changed (0);
|
comment_changed (0);
|
||||||
route_group_changed ();
|
route_group_changed ();
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
|
||||||
}
|
}
|
||||||
|
|
||||||
mute_changed (0);
|
mute_changed (0);
|
||||||
solo_changed (0);
|
update_solo_display ();
|
||||||
|
|
||||||
timestretch_rect = 0;
|
timestretch_rect = 0;
|
||||||
no_redraw = false;
|
no_redraw = false;
|
||||||
|
|
|
||||||
|
|
@ -209,10 +209,12 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
|
||||||
|
|
||||||
_route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
|
_route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
|
||||||
_route->mute_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::mute_changed, this, _1), gui_context());
|
_route->mute_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::mute_changed, this, _1), gui_context());
|
||||||
_route->solo_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
|
|
||||||
_route->solo_safe_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
|
_route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
||||||
_route->listen_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::listen_changed, this, _1), gui_context());
|
_route->solo_safe_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
||||||
_route->solo_isolated_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::solo_changed, this, _1), gui_context());
|
_route->listen_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
||||||
|
_route->solo_isolated_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
||||||
|
|
||||||
_route->phase_invert_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::polarity_changed, this), gui_context());
|
_route->phase_invert_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::polarity_changed, this), gui_context());
|
||||||
_route->PropertyChanged.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::property_changed, this, _1), gui_context());
|
_route->PropertyChanged.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::property_changed, this, _1), gui_context());
|
||||||
|
|
||||||
|
|
@ -691,19 +693,6 @@ RouteUI::send_blink (bool onoff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
RouteUI::solo_changed(void* /*src*/)
|
|
||||||
{
|
|
||||||
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteUI::update_solo_display, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
RouteUI::listen_changed(void* /*src*/)
|
|
||||||
{
|
|
||||||
Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteUI::update_solo_display, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
RouteUI::solo_visual_state (boost::shared_ptr<Route> r)
|
RouteUI::solo_visual_state (boost::shared_ptr<Route> r)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ class RouteUI : public virtual AxisView
|
||||||
void create_sends (ARDOUR::Placement);
|
void create_sends (ARDOUR::Placement);
|
||||||
void create_selected_sends (ARDOUR::Placement);
|
void create_selected_sends (ARDOUR::Placement);
|
||||||
|
|
||||||
void solo_changed(void*);
|
void solo_changed(bool, void*);
|
||||||
void solo_changed_so_update_mute ();
|
void solo_changed_so_update_mute ();
|
||||||
void mute_changed(void*);
|
void mute_changed(void*);
|
||||||
void listen_changed(void*);
|
void listen_changed(void*);
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
|
||||||
PBD::Signal0<void> phase_invert_changed;
|
PBD::Signal0<void> phase_invert_changed;
|
||||||
PBD::Signal0<void> denormal_protection_changed;
|
PBD::Signal0<void> denormal_protection_changed;
|
||||||
PBD::Signal1<void,void*> listen_changed;
|
PBD::Signal1<void,void*> listen_changed;
|
||||||
PBD::Signal1<void,void*> solo_changed;
|
PBD::Signal2<void,bool,void*> solo_changed;
|
||||||
PBD::Signal1<void,void*> solo_safe_changed;
|
PBD::Signal1<void,void*> solo_safe_changed;
|
||||||
PBD::Signal1<void,void*> solo_isolated_changed;
|
PBD::Signal1<void,void*> solo_isolated_changed;
|
||||||
PBD::Signal1<void,void*> comment_changed;
|
PBD::Signal1<void,void*> comment_changed;
|
||||||
|
|
@ -273,8 +273,39 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
|
||||||
int listen_via (boost::shared_ptr<Route>, Placement p, bool active, bool aux);
|
int listen_via (boost::shared_ptr<Route>, Placement p, bool active, bool aux);
|
||||||
void drop_listen (boost::shared_ptr<Route>);
|
void drop_listen (boost::shared_ptr<Route>);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true if this route feeds the first argument via at least one
|
||||||
|
* (arbitrarily long) signal pathway.
|
||||||
|
*/
|
||||||
bool feeds (boost::shared_ptr<Route>, bool* via_send_only = 0);
|
bool feeds (boost::shared_ptr<Route>, bool* via_send_only = 0);
|
||||||
std::set<boost::weak_ptr<Route> > fed_by;
|
|
||||||
|
/**
|
||||||
|
* return true if this route feeds the first argument directly, via
|
||||||
|
* either its main outs or a send.
|
||||||
|
*/
|
||||||
|
bool direct_feeds (boost::shared_ptr<Route>, bool* via_send_only = 0);
|
||||||
|
|
||||||
|
struct FeedRecord {
|
||||||
|
boost::weak_ptr<Route> r;
|
||||||
|
bool sends_only;
|
||||||
|
|
||||||
|
FeedRecord (boost::shared_ptr<Route> rp, bool sendsonly)
|
||||||
|
: r (rp)
|
||||||
|
, sends_only (sendsonly) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FeedRecordCompare {
|
||||||
|
bool operator() (const FeedRecord& a, const FeedRecord& b) const {
|
||||||
|
return a.r < b.r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::set<FeedRecord,FeedRecordCompare> FedBy;
|
||||||
|
|
||||||
|
const FedBy& fed_by() const { return _fed_by; }
|
||||||
|
void clear_fed_by ();
|
||||||
|
bool add_fed_by (boost::shared_ptr<Route>, bool sends_only);
|
||||||
|
bool not_fed() const { return _fed_by.empty(); }
|
||||||
|
|
||||||
/* Controls (not all directly owned by the Route */
|
/* Controls (not all directly owned by the Route */
|
||||||
|
|
||||||
|
|
@ -393,6 +424,7 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
|
||||||
bool _have_internal_generator;
|
bool _have_internal_generator;
|
||||||
bool _solo_safe;
|
bool _solo_safe;
|
||||||
DataType _default_type;
|
DataType _default_type;
|
||||||
|
FedBy _fed_by;
|
||||||
|
|
||||||
virtual ChanCount input_streams () const;
|
virtual ChanCount input_streams () const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1218,7 +1218,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
|
|
||||||
void route_listen_changed (void *src, boost::weak_ptr<Route>);
|
void route_listen_changed (void *src, boost::weak_ptr<Route>);
|
||||||
void route_mute_changed (void *src);
|
void route_mute_changed (void *src);
|
||||||
void route_solo_changed (void *src, boost::weak_ptr<Route>);
|
void route_solo_changed (bool self_solo_change, void *src, boost::weak_ptr<Route>);
|
||||||
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
|
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
|
||||||
|
|
||||||
void listen_position_changed ();
|
void listen_position_changed ();
|
||||||
|
|
|
||||||
|
|
@ -581,7 +581,7 @@ Route::set_solo (bool yn, void *src)
|
||||||
if (self_soloed() != yn) {
|
if (self_soloed() != yn) {
|
||||||
set_self_solo (yn);
|
set_self_solo (yn);
|
||||||
set_delivery_solo ();
|
set_delivery_solo ();
|
||||||
solo_changed (src); /* EMIT SIGNAL */
|
solo_changed (true, src); /* EMIT SIGNAL */
|
||||||
_solo_control->Changed (); /* EMIT SIGNAL */
|
_solo_control->Changed (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +610,7 @@ Route::mod_solo_by_others (int32_t delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_delivery_solo ();
|
set_delivery_solo ();
|
||||||
solo_changed (this);
|
solo_changed (false, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -649,7 +649,7 @@ Route::set_solo_isolated (bool yn, void *src)
|
||||||
boost::shared_ptr<RouteList> routes = _session.get_routes ();
|
boost::shared_ptr<RouteList> routes = _session.get_routes ();
|
||||||
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
|
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
|
||||||
bool sends_only;
|
bool sends_only;
|
||||||
bool does_feed = feeds (*i, &sends_only);
|
bool does_feed = direct_feeds (*i, &sends_only);
|
||||||
|
|
||||||
if (does_feed && !sends_only) {
|
if (does_feed && !sends_only) {
|
||||||
(*i)->set_solo_isolated (yn, (*i)->route_group());
|
(*i)->set_solo_isolated (yn, (*i)->route_group());
|
||||||
|
|
@ -2465,7 +2465,53 @@ Route::set_comment (string cmt, void *src)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Route::feeds (boost::shared_ptr<Route> other, bool* only_send)
|
Route::add_fed_by (boost::shared_ptr<Route> other, bool via_sends_only)
|
||||||
|
{
|
||||||
|
FeedRecord fr (other, via_sends_only);
|
||||||
|
|
||||||
|
pair<FedBy::iterator,bool> result = _fed_by.insert (fr);
|
||||||
|
|
||||||
|
if (!result.second) {
|
||||||
|
|
||||||
|
/* already a record for "other" - make sure sends-only information is correct */
|
||||||
|
if (!via_sends_only && result.first->sends_only) {
|
||||||
|
FeedRecord* frp = const_cast<FeedRecord*>(&(*result.first));
|
||||||
|
frp->sends_only = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Route::clear_fed_by ()
|
||||||
|
{
|
||||||
|
_fed_by.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Route::feeds (boost::shared_ptr<Route> other, bool* via_sends_only)
|
||||||
|
{
|
||||||
|
const FedBy& fed_by (other->fed_by());
|
||||||
|
|
||||||
|
for (FedBy::iterator f = fed_by.begin(); f != fed_by.end(); ++f) {
|
||||||
|
boost::shared_ptr<Route> sr = f->r.lock();
|
||||||
|
|
||||||
|
if (sr && (sr.get() == this)) {
|
||||||
|
|
||||||
|
if (via_sends_only) {
|
||||||
|
*via_sends_only = f->sends_only;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Route::direct_feeds (boost::shared_ptr<Route> other, bool* only_send)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1238,13 +1238,13 @@ Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
|
||||||
|
|
||||||
struct RouteSorter {
|
struct RouteSorter {
|
||||||
bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
|
bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
|
||||||
if (r1->fed_by.find (r2) != r1->fed_by.end()) {
|
if (r2->feeds (r1)) {
|
||||||
return false;
|
return false;
|
||||||
} else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
|
} else if (r1->feeds (r2)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (r1->fed_by.empty()) {
|
if (r1->not_fed ()) {
|
||||||
if (r2->fed_by.empty()) {
|
if (r2->not_fed ()) {
|
||||||
/* no ardour-based connections inbound to either route. just use signal order */
|
/* no ardour-based connections inbound to either route. just use signal order */
|
||||||
return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
|
return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1263,21 +1263,21 @@ trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
|
||||||
{
|
{
|
||||||
shared_ptr<Route> r2;
|
shared_ptr<Route> r2;
|
||||||
|
|
||||||
if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
|
if (r1->feeds (rbase) && rbase->feeds (r1)) {
|
||||||
info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
|
info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make a copy of the existing list of routes that feed r1 */
|
/* make a copy of the existing list of routes that feed r1 */
|
||||||
|
|
||||||
set<weak_ptr<Route> > existing = r1->fed_by;
|
Route::FedBy existing (r1->fed_by());
|
||||||
|
|
||||||
/* for each route that feeds r1, recurse, marking it as feeding
|
/* for each route that feeds r1, recurse, marking it as feeding
|
||||||
rbase as well.
|
rbase as well.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
|
for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
|
||||||
if (!(r2 = (*i).lock ())) {
|
if (!(r2 = i->r.lock ())) {
|
||||||
/* (*i) went away, ignore it */
|
/* (*i) went away, ignore it */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1286,7 +1286,7 @@ trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
|
||||||
base as being fed by r2
|
base as being fed by r2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rbase->fed_by.insert (r2);
|
rbase->add_fed_by (r2, i->sends_only);
|
||||||
|
|
||||||
if (r2 != rbase) {
|
if (r2 != rbase) {
|
||||||
|
|
||||||
|
|
@ -1294,7 +1294,7 @@ trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
|
||||||
stop here.
|
stop here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
|
if (r1->feeds (r2) && r2->feeds (r1)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1328,6 +1328,22 @@ Session::resort_routes ()
|
||||||
/* writer goes out of scope and forces update */
|
/* writer goes out of scope and forces update */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
boost::shared_ptr<RouteList> rl = routes.reader ();
|
||||||
|
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||||
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
|
||||||
|
|
||||||
|
const Route::FedBy& fb ((*i)->fed_by());
|
||||||
|
|
||||||
|
for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
|
||||||
|
boost::shared_ptr<Route> sf = f->r.lock();
|
||||||
|
if (sf) {
|
||||||
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
Session::resort_routes_using (shared_ptr<RouteList> r)
|
Session::resort_routes_using (shared_ptr<RouteList> r)
|
||||||
|
|
@ -1336,7 +1352,7 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
|
||||||
|
|
||||||
for (i = r->begin(); i != r->end(); ++i) {
|
for (i = r->begin(); i != r->end(); ++i) {
|
||||||
|
|
||||||
(*i)->fed_by.clear ();
|
(*i)->clear_fed_by ();
|
||||||
|
|
||||||
for (j = r->begin(); j != r->end(); ++j) {
|
for (j = r->begin(); j != r->end(); ++j) {
|
||||||
|
|
||||||
|
|
@ -1350,8 +1366,10 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*j)->feeds (*i)) {
|
bool via_sends_only;
|
||||||
(*i)->fed_by.insert (*j);
|
|
||||||
|
if ((*j)->direct_feeds (*i, &via_sends_only)) {
|
||||||
|
(*i)->add_fed_by (*j, via_sends_only);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1363,13 +1381,11 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
|
||||||
RouteSorter cmp;
|
RouteSorter cmp;
|
||||||
r->sort (cmp);
|
r->sort (cmp);
|
||||||
|
|
||||||
#if 0
|
#ifndef NDEBUG
|
||||||
cerr << "finished route resort\n";
|
DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
|
||||||
|
|
||||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||||
cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n", (*i)->name(), (*i)->order_key ("signal")));
|
||||||
}
|
}
|
||||||
cerr << endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1882,7 +1898,7 @@ Session::add_routes (RouteList& new_routes, bool save)
|
||||||
boost::shared_ptr<Route> r (*x);
|
boost::shared_ptr<Route> r (*x);
|
||||||
|
|
||||||
r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
|
r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
|
||||||
r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
|
r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
|
||||||
r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
|
r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
|
||||||
r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
|
r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
|
||||||
r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
|
r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
|
||||||
|
|
@ -2122,8 +2138,13 @@ Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
|
Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
|
||||||
{
|
{
|
||||||
|
if (!self_solo_change) {
|
||||||
|
// session doesn't care about changes to soloed-by-others
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (solo_update_disabled) {
|
if (solo_update_disabled) {
|
||||||
// We know already
|
// We know already
|
||||||
return;
|
return;
|
||||||
|
|
@ -2146,22 +2167,48 @@ Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
|
||||||
delta = -1;
|
delta = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now mod the solo level of all other routes except master/control outs/auditioner
|
|
||||||
so that they will be silent if appropriate.
|
|
||||||
*/
|
|
||||||
|
|
||||||
solo_update_disabled = true;
|
solo_update_disabled = true;
|
||||||
|
|
||||||
|
/* from IRC:
|
||||||
|
|
||||||
|
<las> oofus_lt: solo a route, do NOT mute anything in the feed-forward chain for the route
|
||||||
|
<las> oofus_lt: and do solo-by-other everything in the feed-backward chain
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||||
bool via_sends_only;
|
bool via_sends_only;
|
||||||
|
|
||||||
if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
|
if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
|
||||||
continue;
|
continue;
|
||||||
} else if ((*i)->feeds (route, &via_sends_only)) {
|
}
|
||||||
|
|
||||||
|
/* feed-backwards (other route to solo change route):
|
||||||
|
|
||||||
|
if (*i) feeds the one whose solo status changed
|
||||||
|
it should be soloed by other if the change was -> solo OR de-soloed by other if change was -> !solo
|
||||||
|
else
|
||||||
|
do nothing
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((*i)->feeds (route, &via_sends_only)) {
|
||||||
if (!via_sends_only) {
|
if (!via_sends_only) {
|
||||||
(*i)->mod_solo_by_others (delta);
|
(*i)->mod_solo_by_others (delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* feed-forward (solo change route to other routes):
|
||||||
|
|
||||||
|
if the route whose solo status changed feeds (*i)
|
||||||
|
do nothing
|
||||||
|
else
|
||||||
|
mute if the change was -> solo OR demute if change was -> !solo
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (route->feeds (*i, &via_sends_only)) {
|
||||||
|
(*i)->mod_solo_by_others (delta);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
solo_update_disabled = false;
|
solo_update_disabled = false;
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ StateButton::set_visual_state (int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_widget_name (name);
|
set_widget_name (name);
|
||||||
|
|
||||||
visual_state = n;
|
visual_state = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue