Compare commits

...

5 Commits

Author SHA1 Message Date
Paul Davis b4612616c2 remove incorrect/out of date comment 2016-01-21 12:25:27 -05:00
Paul Davis bcb487e635 no reason to have group edit dialog be modal 2016-01-21 12:24:38 -05:00
Paul Davis f03cfad9f1 fix rebase issue from master 2016-01-21 12:24:28 -05:00
Paul Davis 1dfd9800b1 rename Controllable::WholeGroup => InverseGroup to reflect real intent.
Add logic to RouteGroupMember::use_group() to implement the real intent of InverseGroup
2016-01-21 12:04:45 -05:00
Paul Davis 78d85cbc36 first compiling, mostly working version of group controls changes 2016-01-21 12:04:45 -05:00
36 changed files with 404 additions and 279 deletions

View File

@ -2247,10 +2247,10 @@ ARDOUR_UI::toggle_record_enable (uint32_t rid)
if ((r = _session->route_by_remote_id (rid)) != 0) {
Track* t;
boost::shared_ptr<Track> t;
if ((t = dynamic_cast<Track*>(r.get())) != 0) {
t->set_record_enabled (!t->record_enabled(), this);
if ((t = boost::dynamic_pointer_cast<Track>(r)) != 0) {
t->set_record_enabled (!t->record_enabled(), Controllable::UseGroup);
}
}
}

View File

@ -5701,7 +5701,7 @@ Editor::toggle_record_enable ()
first = false;
}
rtav->track()->set_record_enabled (new_state, this);
rtav->track()->set_record_enabled (new_state, Controllable::UseGroup);
}
}
@ -5727,7 +5727,7 @@ Editor::toggle_solo ()
rl->push_back (rtav->route());
}
_session->set_solo (rl, new_state, Session::rt_cleanup, true);
_session->set_solo (rl, new_state, Session::rt_cleanup, Controllable::UseGroup);
}
void
@ -5752,7 +5752,7 @@ Editor::toggle_mute ()
rl->push_back (rtav->route());
}
_session->set_mute (rl, new_state, Session::rt_cleanup, true);
_session->set_mute (rl, new_state, Session::rt_cleanup, Controllable::UseGroup);
}
void

View File

@ -453,7 +453,7 @@ EditorRoutes::on_tv_solo_isolate_toggled (std::string const & path_string)
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
if (rtv) {
rtv->route()->set_solo_isolated (!rtv->route()->solo_isolated(), this);
rtv->route()->set_solo_isolated (!rtv->route()->solo_isolated(), Controllable::UseGroup);
}
}
@ -467,7 +467,7 @@ EditorRoutes::on_tv_solo_safe_toggled (std::string const & path_string)
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
if (rtv) {
rtv->route()->set_solo_safe (!rtv->route()->solo_safe(), this);
rtv->route()->set_solo_safe (!rtv->route()->solo_safe(), Controllable::UseGroup);
}
}
@ -711,8 +711,8 @@ 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()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
(*x)->route()->listen_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
(*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this), gui_context());
(*x)->route()->listen_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_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()->active_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_active_display, this), gui_context ());
@ -721,7 +721,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
update_rec_display ();
update_mute_display ();
update_solo_display (true);
update_solo_display ();
update_solo_isolate_display ();
update_solo_safe_display ();
update_input_active_display ();
@ -1632,7 +1632,7 @@ EditorRoutes::update_mute_display ()
}
void
EditorRoutes::update_solo_display (bool /* selfsoloed */)
EditorRoutes::update_solo_display ()
{
if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) {
Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc));

View File

@ -86,7 +86,7 @@ private:
bool idle_update_mute_rec_solo_etc ();
void update_rec_display ();
void update_mute_display ();
void update_solo_display (bool);
void update_solo_display ();
void update_solo_isolate_display ();
void update_solo_safe_display ();
void update_input_active_display ();

View File

@ -637,7 +637,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
update_mute_display ();
update_solo_display ();
name_changed ();
comment_changed (0);
comment_changed ();
route_group_changed ();
connect_to_pan ();

View File

@ -1210,7 +1210,7 @@ MonitorSection::cancel_isolate (GdkEventButton*)
{
if (_session) {
boost::shared_ptr<RouteList> rl (_session->get_routes ());
_session->set_solo_isolated (rl, false, Session::rt_cleanup, true);
_session->set_solo_isolated (rl, false, Session::rt_cleanup, Controllable::NoGroup);
}
return true;

View File

@ -53,7 +53,6 @@ RouteGroupDialog::RouteGroupDialog (RouteGroup* g, bool creating_new)
, _share_color (_("Color"))
, _share_monitoring (_("Monitoring"))
{
set_modal (true);
set_skip_taskbar_hint (true);
set_resizable (true);
set_name (N_("RouteGroupDialog"));

View File

@ -259,7 +259,7 @@ 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->mute_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_mute_display, this), gui_context());
_route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::comment_changed, this, _1), gui_context());
_route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::comment_changed, this), gui_context());
_route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
_route->solo_safe_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
@ -426,7 +426,7 @@ RouteUI::mute_press (GdkEventButton* ev)
}
DisplaySuspender ds;
_session->set_mute (rl, !_route->muted(), Session::rt_cleanup, true);
_session->set_mute (rl, !_route->muted(), Session::rt_cleanup, Controllable::InverseGroup);
}
} else {
@ -454,7 +454,7 @@ RouteUI::mute_release (GdkEventButton* /*ev*/)
{
if (_mute_release){
DisplaySuspender ds;
_session->set_mute (_mute_release->routes, _mute_release->active, Session::rt_cleanup, true);
_session->set_mute (_mute_release->routes, _mute_release->active, Session::rt_cleanup, Controllable::UseGroup);
delete _mute_release;
_mute_release = 0;
}
@ -555,9 +555,9 @@ RouteUI::solo_press(GdkEventButton* ev)
DisplaySuspender ds;
if (Config->get_solo_control_is_listen_control()) {
_session->set_listen (_session->get_routes(), !_route->listening_via_monitor(), Session::rt_cleanup, false);
_session->set_listen (_session->get_routes(), !_route->listening_via_monitor(), Session::rt_cleanup, Controllable::NoGroup);
} else {
_session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, false);
_session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, Controllable::NoGroup);
}
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
@ -589,7 +589,7 @@ RouteUI::solo_press(GdkEventButton* ev)
// shift-click: toggle solo isolated status
_route->set_solo_isolated (!_route->solo_isolated(), this);
_route->set_solo_isolated (!_route->solo_isolated(), Controllable::UseGroup);
delete _solo_release;
_solo_release = 0;
@ -620,9 +620,9 @@ RouteUI::solo_press(GdkEventButton* ev)
DisplaySuspender ds;
if (Config->get_solo_control_is_listen_control()) {
_session->set_listen (rl, !_route->listening_via_monitor(), Session::rt_cleanup, true);
_session->set_listen (rl, !_route->listening_via_monitor(), Session::rt_cleanup, Controllable::InverseGroup);
} else {
_session->set_solo (rl, !_route->self_soloed(), Session::rt_cleanup, true);
_session->set_solo (rl, !_route->self_soloed(), Session::rt_cleanup, Controllable::InverseGroup);
}
}
@ -663,9 +663,9 @@ RouteUI::solo_release (GdkEventButton* /*ev*/)
} else {
DisplaySuspender ds;
if (Config->get_solo_control_is_listen_control()) {
_session->set_listen (_solo_release->routes, _solo_release->active, Session::rt_cleanup, false);
_session->set_listen (_solo_release->routes, _solo_release->active, Session::rt_cleanup, Controllable::UseGroup);
} else {
_session->set_solo (_solo_release->routes, _solo_release->active, Session::rt_cleanup, false);
_session->set_solo (_solo_release->routes, _solo_release->active, Session::rt_cleanup, Controllable::UseGroup);
}
}
@ -735,7 +735,7 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
}
DisplaySuspender ds;
_session->set_record_enabled (rl, !_route->record_enabled(), Session::rt_cleanup, true);
_session->set_record_enabled (rl, !_route->record_enabled(), Session::rt_cleanup, Controllable::InverseGroup);
}
} else if (Keyboard::is_context_menu_event (ev)) {
@ -865,7 +865,7 @@ RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
}
DisplaySuspender ds;
_session->set_monitoring (rl, mc, Session::rt_cleanup, true);
_session->set_monitoring (rl, mc, Session::rt_cleanup, Controllable::UseGroup);
return false;
}
@ -1437,11 +1437,11 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
if (model) {
/* disable isolate for all routes */
DisplaySuspender ds;
_session->set_solo_isolated (_session->get_routes(), false, Session::rt_cleanup, true);
_session->set_solo_isolated (_session->get_routes(), false, Session::rt_cleanup, Controllable::NoGroup);
} else {
/* enable isolate for all routes */
DisplaySuspender ds;
_session->set_solo_isolated (_session->get_routes(), true, Session::rt_cleanup, true);
_session->set_solo_isolated (_session->get_routes(), true, Session::rt_cleanup, Controllable::NoGroup);
}
} else {
@ -1453,7 +1453,7 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (_route);
DisplaySuspender ds;
_session->set_solo_isolated (rl, !view, Session::rt_cleanup, true);
_session->set_solo_isolated (rl, !view, Session::rt_cleanup, Controllable::NoGroup);
}
}
}
@ -1478,20 +1478,20 @@ RouteUI::solo_safe_button_release (GdkEventButton* ev)
/* disable solo safe for all routes */
DisplaySuspender ds;
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
(*i)->set_solo_safe (false, this);
(*i)->set_solo_safe (false, Controllable::NoGroup);
}
} else {
/* enable solo safe for all routes */
DisplaySuspender ds;
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
(*i)->set_solo_safe (true, this);
(*i)->set_solo_safe (true, Controllable::NoGroup);
}
}
}
else {
if (model == view) {
/* flip just this route */
_route->set_solo_safe (!view, this);
_route->set_solo_safe (!view, Controllable::NoGroup);
}
}
}
@ -1508,14 +1508,14 @@ RouteUI::toggle_solo_isolated (Gtk::CheckMenuItem* check)
/* called AFTER the view has changed */
if (model != view) {
_route->set_solo_isolated (view, this);
_route->set_solo_isolated (view, Controllable::UseGroup);
}
}
void
RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check)
{
_route->set_solo_safe (check->get_active(), this);
_route->set_solo_safe (check->get_active(), Controllable::UseGroup);
}
/** Ask the user to choose a colour, and then apply that color to my route
@ -1702,17 +1702,13 @@ RouteUI::setup_comment_editor ()
}
void
RouteUI::comment_changed (void *src)
RouteUI::comment_changed ()
{
ENSURE_GUI_THREAD (*this, &MixerStrip::comment_changed, src)
if (src != this) {
ignore_comment_edit = true;
if (comment_area) {
comment_area->get_buffer()->set_text (_route->comment());
}
ignore_comment_edit = false;
ignore_comment_edit = true;
if (comment_area) {
comment_area->get_buffer()->set_text (_route->comment());
}
ignore_comment_edit = false;
}
void

View File

@ -241,7 +241,7 @@ class RouteUI : public virtual AxisView
void toggle_comment_editor ();
gint comment_key_release_handler (GdkEventKey*);
void comment_changed (void *src);
void comment_changed ();
void comment_edited ();
bool ignore_comment_edit;

View File

@ -33,7 +33,8 @@ namespace ARDOUR {
class Session;
struct LIBARDOUR_API GainControl : public AutomationControl {
class LIBARDOUR_API GainControl : public AutomationControl {
public:
GainControl (Session& session, const Evoral::Parameter &param,
boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>());
@ -48,6 +49,8 @@ struct LIBARDOUR_API GainControl : public AutomationControl {
double lower_db;
double range_db;
private:
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
} /* namespace */

View File

@ -50,8 +50,8 @@ public:
boost::shared_ptr<Diskstream> create_diskstream ();
void set_diskstream (boost::shared_ptr<Diskstream>);
void set_record_enabled (bool yn, void *src);
void set_record_safe (bool yn, void *src);
void set_record_enabled (bool yn, PBD::Controllable::GroupControlDisposition);
void set_record_safe (bool yn, PBD::Controllable::GroupControlDisposition);
DataType data_type () const {
return DataType::MIDI;
@ -94,6 +94,9 @@ public:
bool writable() const { return true; }
MidiTrack* _route;
private:
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);

View File

@ -52,6 +52,7 @@ class LIBARDOUR_API PanControllable : public AutomationControl
private:
Pannable* owner;
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
} // namespace

View File

@ -103,6 +103,7 @@ class LIBARDOUR_API PluginInsert : public Processor
private:
PluginInsert* _plugin;
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
/** A control that manipulates a plugin property (message). */

View File

@ -128,9 +128,9 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
virtual bool can_record() { return false; }
virtual void set_record_enabled (bool /*yn*/, void * /*src*/) {}
virtual void set_record_enabled (bool /*yn*/, PBD::Controllable::GroupControlDisposition) {}
virtual bool record_enabled() const { return false; }
virtual void set_record_safe (bool yn, void *src) {}
virtual void set_record_safe (bool /*yn*/, PBD::Controllable::GroupControlDisposition) {}
virtual bool record_safe () const {return false; }
virtual void nonrealtime_handle_transport_stopped (bool abort, bool did_locate, bool flush_processors);
virtual void realtime_handle_transport_stopped () {}
@ -145,20 +145,20 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
void set_gain (gain_t val, PBD::Controllable::GroupControlDisposition);
void inc_gain (gain_t delta);
void set_trim (gain_t val, void *src);
void set_trim (gain_t val, PBD::Controllable::GroupControlDisposition);
void set_mute_points (MuteMaster::MutePoint);
MuteMaster::MutePoint mute_points () const;
bool muted () const;
void set_mute (bool yn, void* src);
void set_mute (bool yn, PBD::Controllable::GroupControlDisposition);
bool muted_by_others() const;
/* controls use set_solo() to modify this route's solo state
*/
void set_solo (bool yn, void *src, bool group_override = false);
void set_solo (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool soloed () const { return self_soloed () || soloed_by_others (); }
void clear_all_solo_state ();
@ -167,13 +167,13 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
bool soloed_by_others_downstream () const { return _soloed_by_others_downstream; }
bool self_soloed () const { return _self_solo; }
void set_solo_isolated (bool yn, void *src);
void set_solo_isolated (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool solo_isolated() const;
void set_solo_safe (bool yn, void *src);
void set_solo_safe (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool solo_safe() const;
void set_listen (bool yn, void* src, bool group_override = false);
void set_listen (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool listening_via_monitor () const;
void enable_monitor_send ();
@ -286,12 +286,12 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
PBD::Signal0<void> active_changed;
PBD::Signal0<void> phase_invert_changed;
PBD::Signal0<void> denormal_protection_changed;
PBD::Signal2<void,void*,bool> listen_changed;
PBD::Signal3<void,bool,void*,bool> solo_changed;
PBD::Signal1<void,void*> solo_safe_changed;
PBD::Signal1<void,void*> solo_isolated_changed;
PBD::Signal1<void,void*> comment_changed;
PBD::Signal1<void,void*> mute_changed;
PBD::Signal1<void,PBD::Controllable::GroupControlDisposition> listen_changed;
PBD::Signal2<void,bool,PBD::Controllable::GroupControlDisposition> solo_changed;
PBD::Signal0<void> solo_safe_changed;
PBD::Signal0<void> solo_isolated_changed;
PBD::Signal0<void> comment_changed;
PBD::Signal0<void> mute_changed;
PBD::Signal0<void> mute_points_changed;
/** track numbers - assigned by session
@ -438,6 +438,8 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
void set_value_unchecked (double);
double get_value () const;
private:
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
struct MuteControllable : public RouteAutomationControl {
@ -452,17 +454,20 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
private:
boost::weak_ptr<Route> _route;
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
class LIBARDOUR_API PhaseControllable : public RouteAutomationControl {
public:
PhaseControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
/* currently no automation, so no need for set_value_unchecked() */
void set_channel (uint32_t);
double get_value () const;
uint32_t channel() const;
private:
uint32_t _current_phase;
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
void set_control (AutomationType, double val, PBD::Controllable::GroupControlDisposition group_override);
@ -654,7 +659,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
bool _solo_isolated;
uint32_t _solo_isolated_by_upstream;
void mod_solo_isolated_by_upstream (bool, void*);
void mod_solo_isolated_by_upstream (bool);
bool _denormal_protection;

View File

@ -25,9 +25,9 @@
#include <string>
#include <stdint.h>
#include "pbd/controllable.h"
#include "pbd/signals.h"
#include "pbd/stateful.h"
#include "pbd/signals.h"
#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
@ -108,7 +108,7 @@ class LIBARDOUR_API RouteGroup : public SessionObject
/* to use these, #include "ardour/route_group_specialized.h" */
template<class T> void apply (void (Track::*func)(T, void *), T val, void *src);
template<class T> void apply (void (Track::*func)(T, PBD::Controllable::GroupControlDisposition), T val, PBD::Controllable::GroupControlDisposition);
/* fills at_set with all members of the group that are AudioTracks */
@ -134,7 +134,7 @@ class LIBARDOUR_API RouteGroup : public SessionObject
int set_state (const XMLNode&, int version);
private:
private:
boost::shared_ptr<RouteList> routes;
boost::shared_ptr<Route> subgroup_bus;

View File

@ -20,6 +20,7 @@
#ifndef __libardour_route_group_member_h__
#define __libardour_route_group_member_h__
#include "pbd/controllable.h"
#include "pbd/signals.h"
namespace ARDOUR {
@ -37,6 +38,8 @@ class LIBARDOUR_API RouteGroupMember
/** Emitted when this member joins or leaves a route group */
PBD::Signal0<void> route_group_changed;
bool use_group (PBD::Controllable::GroupControlDisposition gcd, bool (RouteGroup::*predicate)(void) const) const;
protected:
RouteGroup* _route_group;

View File

@ -26,13 +26,13 @@
namespace ARDOUR {
template<class T> void
RouteGroup::apply (void (Track::*func)(T, void *), T val, void* /*src*/)
RouteGroup::apply (void (Track::*func)(T, PBD::Controllable::GroupControlDisposition), T val, PBD::Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = routes->begin(); i != routes->end(); i++) {
boost::shared_ptr<Track> at;
if ((at = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
(at.get()->*func)(val, this);
(at.get()->*func)(val, group_override);
}
}
}

View File

@ -739,16 +739,16 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
static const SessionEvent::RTeventCallback rt_cleanup;
void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void clear_all_solo_state (boost::shared_ptr<RouteList>);
void set_just_one_solo (boost::shared_ptr<Route>, bool, SessionEvent::RTeventCallback after = rt_cleanup);
void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_record_safe (boost::shared_ptr<RouteList>, bool yn, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_exclusive_input_active (boost::shared_ptr<RouteList> rt, bool onoff, bool flip_others=false);
void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void set_record_safe (boost::shared_ptr<RouteList>, bool yn, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void set_exclusive_input_active (boost::shared_ptr<RouteList> rt, bool onoff, bool flip_others = false);
PBD::Signal1<void,bool> SoloActive;
PBD::Signal0<void> SoloChanged;
@ -1544,10 +1544,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/* mixer stuff */
void route_listen_changed (bool group_override, boost::weak_ptr<Route>);
void route_mute_changed (void *src);
void route_solo_changed (bool self_solo_change, bool group_override, boost::weak_ptr<Route>);
void route_solo_isolated_changed (void *src, boost::weak_ptr<Route>);
void route_listen_changed (PBD::Controllable::GroupControlDisposition, boost::weak_ptr<Route>);
void route_mute_changed ();
void route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route>);
void route_solo_isolated_changed (boost::weak_ptr<Route>);
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
void listen_position_changed ();
@ -1772,8 +1772,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/* realtime "apply to set of routes" operations */
template<typename T> SessionEvent*
get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, bool group_override,
void (Session::*method) (boost::shared_ptr<RouteList>, T, bool)) {
get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, PBD::Controllable::GroupControlDisposition group_override,
void (Session::*method) (boost::shared_ptr<RouteList>, T, PBD::Controllable::GroupControlDisposition)) {
SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
ev->rt_slot = boost::bind (method, this, rl, targ, group_override);
ev->rt_return = after;
@ -1782,15 +1782,15 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
return ev;
}
void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_clear_all_solo_state (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_record_enabled (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_record_safe (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, bool group_override);
void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
void rt_clear_all_solo_state (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition /* ignored*/ );
void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
void rt_set_record_enabled (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
void rt_set_record_safe (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
void rt_set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, PBD::Controllable::GroupControlDisposition group_override);
/** temporary list of Diskstreams used only during load of 2.X sessions */
std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;

View File

@ -108,9 +108,9 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream
bool record_enabled() const;
bool record_safe () const;
void set_record_enabled (bool yn, void *src);
void set_record_safe (bool yn, void *src);
void prep_record_enabled (bool yn, void *src);
void set_record_enabled (bool yn, PBD::Controllable::GroupControlDisposition);
void set_record_safe (bool yn, PBD::Controllable::GroupControlDisposition);
void prep_record_enabled (bool yn, PBD::Controllable::GroupControlDisposition);
bool using_diskstream_id (PBD::ID) const;
@ -203,7 +203,8 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream
FreezeState state;
};
struct RecEnableControl : public AutomationControl {
class RecEnableControl : public AutomationControl {
public:
RecEnableControl (boost::shared_ptr<Track> t);
void set_value (double, PBD::Controllable::GroupControlDisposition);
@ -211,6 +212,9 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream
double get_value (void) const;
boost::weak_ptr<Track> track;
private:
void _set_value (double, PBD::Controllable::GroupControlDisposition);
};
virtual void set_state_part_two () = 0;

View File

@ -37,17 +37,24 @@ GainControl::GainControl (Session& session, const Evoral::Parameter &param, boos
}
void
GainControl::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
GainControl::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
set_value_unchecked (val);
_set_value (val, group_override);
}
}
void
GainControl::set_value_unchecked (double val)
{
AutomationControl::set_value (std::max (std::min (val, (double)_desc.upper), (double)_desc.lower), Controllable::NoGroup);
/* used only automation playback */
_set_value (val, Controllable::NoGroup);
}
void
GainControl::_set_value (double val, Controllable::GroupControlDisposition group_override)
{
AutomationControl::set_value (std::max (std::min (val, (double)_desc.upper), (double)_desc.lower), group_override);
_session.set_dirty ();
}

View File

@ -103,23 +103,23 @@ MidiTrack::create_diskstream ()
void
MidiTrack::set_record_enabled (bool yn, void *src)
MidiTrack::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_step_editing) {
return;
}
Track::set_record_enabled (yn, src);
Track::set_record_enabled (yn, group_override);
}
void
MidiTrack::set_record_safe (bool yn, void *src)
MidiTrack::set_record_safe (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_step_editing) { /* REQUIRES REVIEW */
return;
}
Track::set_record_safe (yn, src);
Track::set_record_safe (yn, group_override);
}
void
@ -725,15 +725,22 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st
}
void
MidiTrack::MidiControl::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
MidiTrack::MidiControl::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
set_value_unchecked (val);
_set_value (val, group_override);
}
}
void
MidiTrack::MidiControl::set_value_unchecked(double val)
MidiTrack::MidiControl::set_value_unchecked (double val)
{
/* used only by automation playback */
_set_value (val, Controllable::NoGroup);
}
void
MidiTrack::MidiControl::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
const Evoral::Parameter &parameter = _list ? _list->parameter() : Control::parameter();
const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
@ -790,7 +797,7 @@ MidiTrack::MidiControl::set_value_unchecked(double val)
_route->write_immediate_event(size, ev);
}
AutomationControl::set_value(val, Controllable::NoGroup);
AutomationControl::set_value(val, group_override);
}
void

View File

@ -35,21 +35,27 @@ PanControllable::lower () const
}
void
PanControllable::set_value (double v, PBD::Controllable::GroupControlDisposition /* group_override */)
PanControllable::set_value (double v, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
set_value_unchecked (v);
_set_value (v, group_override);
}
}
void
PanControllable::set_value_unchecked (double v)
{
/* used only automation playback */
_set_value (v, Controllable::NoGroup);
}
void
PanControllable::set_value_unchecked (double v)
PanControllable::_set_value (double v, Controllable::GroupControlDisposition group_override)
{
boost::shared_ptr<Panner> p = owner->panner();
if (!p) {
/* no panner: just do it */
AutomationControl::set_value (v, Controllable::NoGroup);
AutomationControl::set_value (v, group_override);
return;
}
@ -70,7 +76,7 @@ PanControllable::set_value_unchecked (double v)
}
if (can_set) {
AutomationControl::set_value (v, Controllable::NoGroup);
AutomationControl::set_value (v, group_override);
}
}

View File

@ -1349,15 +1349,21 @@ PluginInsert::PluginControl::PluginControl (PluginInsert* p,
/** @param val `user' value */
void
PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override */)
PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
set_value_unchecked (user_val);
_set_value (user_val, group_override);
}
}
void
PluginInsert::PluginControl::set_value_unchecked (double user_val)
{
/* used only by automation playback */
_set_value (user_val, Controllable::NoGroup);
}
void
PluginInsert::PluginControl::set_value_unchecked (double user_val)
PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
{
/* FIXME: probably should be taking out some lock here.. */
@ -1370,7 +1376,7 @@ PluginInsert::PluginControl::set_value_unchecked (double user_val)
iasp->set_parameter (_list->parameter().id(), user_val);
}
AutomationControl::set_value (user_val, Controllable::NoGroup);
AutomationControl::set_value (user_val, group_override);
}
void

View File

@ -406,7 +406,7 @@ Route::inc_gain (gain_t factor)
void
Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_override)
{
if (_route_group && (group_override != Controllable::NoGroup) && _route_group->is_active() && _route_group->is_gain()) {
if (use_group (group_override, &RouteGroup::is_gain)) {
if (_route_group->is_relative()) {
@ -459,7 +459,7 @@ Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_overrid
}
void
Route::set_trim (gain_t val, void * /* src */)
Route::set_trim (gain_t val, Controllable::GroupControlDisposition /* group override */)
{
// TODO route group, see set_gain()
_trim_control->route_set_value (val);
@ -784,19 +784,14 @@ Route::passthru_silence (framepos_t start_frame, framepos_t end_frame, pframes_t
}
void
Route::set_listen (bool yn, void* src, bool group_override)
Route::set_listen (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_solo_safe) {
return;
}
bool group_active = _route_group && _route_group->is_active() && _route_group->is_solo();
if (group_override && _route_group) {
group_active = !group_active;
}
if (_route_group && src != _route_group && group_active) {
_route_group->foreach_route (boost::bind (&Route::set_listen, _1, yn, _route_group, group_override));
if (use_group (group_override, &RouteGroup::is_solo)) {
_route_group->foreach_route (boost::bind (&Route::set_listen, _1, yn, Controllable::NoGroup));
return;
}
@ -811,7 +806,7 @@ Route::set_listen (bool yn, void* src, bool group_override)
}
_mute_master->set_soloed_by_others (false);
listen_changed (src, group_override); /* EMIT SIGNAL */
listen_changed (group_override); /* EMIT SIGNAL */
}
}
}
@ -827,11 +822,11 @@ Route::listening_via_monitor () const
}
void
Route::set_solo_safe (bool yn, void *src)
Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition /* group_override */)
{
if (_solo_safe != yn) {
_solo_safe = yn;
solo_safe_changed (src);
solo_safe_changed ();
}
}
@ -868,17 +863,17 @@ Route::clear_all_solo_state ()
{
PBD::Unwinder<bool> uw (_solo_safe, false);
set_solo (false, this);
set_solo (false, Controllable::NoGroup);
}
if (emit_changed) {
set_mute_master_solo ();
solo_changed (false, this, false); /* EMIT SIGNAL */
solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
}
void
Route::set_solo (bool yn, void *src, bool group_override)
Route::set_solo (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_solo_safe) {
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 ignore solo change due to solo-safe\n", name()));
@ -890,21 +885,17 @@ Route::set_solo (bool yn, void *src, bool group_override)
return;
}
bool group_active = _route_group && _route_group->is_active() && _route_group->is_solo();
if (group_override && _route_group) {
group_active = !group_active;
}
if (_route_group && src != _route_group && group_active) {
_route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, _route_group, group_override));
if (use_group (group_override, &RouteGroup::is_solo)) {
_route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, Controllable::NoGroup));
return;
}
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: set solo => %2, src: %3 grp ? %4 currently self-soloed ? %5\n",
name(), yn, src, (src == _route_group), self_soloed()));
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: set solo => %2, grp ? %3 currently self-soloed ? %4\n",
name(), yn, enum_2_string(group_override), self_soloed()));
if (self_soloed() != yn) {
set_self_solo (yn);
solo_changed (true, src, group_override); /* EMIT SIGNAL */
solo_changed (true, group_override); /* EMIT SIGNAL */
_solo_control->Changed (); /* EMIT SIGNAL */
}
@ -915,7 +906,7 @@ Route::set_solo (bool yn, void *src, bool group_override)
*/
if (yn && Profile->get_trx()) {
set_mute (false, src);
set_mute (false, Controllable::UseGroup);
}
}
@ -982,7 +973,7 @@ Route::mod_solo_by_others_upstream (int32_t delta)
}
set_mute_master_solo ();
solo_changed (false, this, false); /* EMIT SIGNAL */
solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
void
@ -1004,7 +995,7 @@ Route::mod_solo_by_others_downstream (int32_t delta)
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 SbD delta %2 = %3\n", name(), delta, _soloed_by_others_downstream));
set_mute_master_solo ();
solo_changed (false, this, false); /* EMIT SIGNAL */
solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
void
@ -1015,7 +1006,7 @@ Route::set_mute_master_solo ()
}
void
Route::mod_solo_isolated_by_upstream (bool yn, void* src)
Route::mod_solo_isolated_by_upstream (bool yn)
{
bool old = solo_isolated ();
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 mod_solo_isolated_by_upstream cur: %2 d: %3\n",
@ -1034,19 +1025,19 @@ Route::mod_solo_isolated_by_upstream (bool yn, void* src)
if (solo_isolated() != old) {
/* solo isolated status changed */
_mute_master->set_solo_ignore (solo_isolated());
solo_isolated_changed (src); /* EMIT SIGNAL */
solo_isolated_changed (); /* EMIT SIGNAL */
}
}
void
Route::set_solo_isolated (bool yn, void *src)
Route::set_solo_isolated (bool yn, Controllable::GroupControlDisposition group_override)
{
if (is_master() || is_monitor() || is_auditioner()) {
return;
}
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
_route_group->foreach_route (boost::bind (&Route::set_solo_isolated, _1, yn, _route_group));
if (use_group (group_override, &RouteGroup::is_solo)) {
_route_group->foreach_route (boost::bind (&Route::set_solo_isolated, _1, yn, Controllable::NoGroup));
return;
}
@ -1084,13 +1075,13 @@ Route::set_solo_isolated (bool yn, void *src)
bool does_feed = feeds (*i, &sends_only);
if (does_feed && !sends_only) {
(*i)->mod_solo_isolated_by_upstream (yn, src);
(*i)->mod_solo_isolated_by_upstream (yn);
}
}
/* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */
solo_isolated_changed (src); /* EMIT SIGNAL */
solo_isolated_changed (); /* EMIT SIGNAL */
}
bool
@ -1106,16 +1097,16 @@ Route::set_mute_points (MuteMaster::MutePoint mp)
mute_points_changed (); /* EMIT SIGNAL */
if (_mute_master->muted_by_self()) {
mute_changed (this); /* EMIT SIGNAL */
mute_changed (); /* EMIT SIGNAL */
_mute_control->Changed (); /* EMIT SIGNAL */
}
}
void
Route::set_mute (bool yn, void *src)
Route::set_mute (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_mute()) {
_route_group->foreach_route (boost::bind (&Route::set_mute, _1, yn, _route_group));
if (use_group (group_override, &RouteGroup::is_mute)) {
_route_group->foreach_route (boost::bind (&Route::set_mute, _1, yn, Controllable::NoGroup));
return;
}
@ -1126,7 +1117,7 @@ Route::set_mute (bool yn, void *src)
*/
act_on_mute ();
/* tell everyone else */
mute_changed (src); /* EMIT SIGNAL */
mute_changed (); /* EMIT SIGNAL */
_mute_control->Changed (); /* EMIT SIGNAL */
}
}
@ -2514,11 +2505,11 @@ Route::set_state (const XMLNode& node, int version)
}
if ((prop = node.property ("solo-isolated")) != 0) {
set_solo_isolated (string_is_affirmative (prop->value()), this);
set_solo_isolated (string_is_affirmative (prop->value()), Controllable::NoGroup);
}
if ((prop = node.property ("solo-safe")) != 0) {
set_solo_safe (string_is_affirmative (prop->value()), this);
set_solo_safe (string_is_affirmative (prop->value()), Controllable::NoGroup);
}
if ((prop = node.property (X_("phase-invert"))) != 0) {
@ -2673,7 +2664,7 @@ Route::set_state_2X (const XMLNode& node, int version)
/* XXX force reset of solo status */
set_solo (yn, this);
set_solo (yn);
}
if ((prop = node.property (X_("muted"))) != 0) {
@ -3240,7 +3231,7 @@ void
Route::set_comment (string cmt, void *src)
{
_comment = cmt;
comment_changed (src);
comment_changed ();
_session.set_dirty ();
}
@ -3414,7 +3405,7 @@ Route::input_change_handler (IOChange change, void * /*src*/)
if (_solo_isolated_by_upstream) {
// solo-isolate currently only propagates downstream
if (idelta < 0) {
mod_solo_isolated_by_upstream (false, this);
mod_solo_isolated_by_upstream (false);
}
// TODO think: mod_solo_isolated_by_upstream() does not take delta arg,
// but idelta can't be smaller than -1, can it?
@ -3434,7 +3425,7 @@ Route::input_change_handler (IOChange change, void * /*src*/)
}
if (idelta < 0 && does_feed && !sends_only) {
(*i)->mod_solo_isolated_by_upstream (false, this);
(*i)->mod_solo_isolated_by_upstream (false);
}
}
}
@ -3901,13 +3892,13 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
switch (type) {
case GainAutomation:
/* route must mediate group control */
set_gain (val, group_override);
set_gain (val, group_override);
return;
break;
case TrimAutomation:
/* route must mediate group control */
set_trim (val, this); /* any "src" argument will do other than our route group */
set_trim (val, group_override);
return;
break;
@ -3915,7 +3906,7 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
/* session must mediate group control */
rl.reset (new RouteList);
rl->push_back (shared_from_this());
_session.set_record_enabled (rl, val >= 0.5 ? true : false);
_session.set_record_enabled (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
return;
break;
@ -3924,7 +3915,7 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
rl.reset (new RouteList);
rl->push_back (shared_from_this());
if (Config->get_solo_control_is_listen_control()) {
_session.set_listen (rl, val >= 0.5 ? true : false);
_session.set_listen (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
} else {
_session.set_solo (rl, val >= 0.5 ? true : false);
}
@ -3936,7 +3927,7 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
/* session must mediate group control */
rl.reset (new RouteList);
rl->push_back (shared_from_this());
_session.set_mute (rl, !muted());
_session.set_mute (rl, !muted(), Session::rt_cleanup, group_override);
return;
break;
@ -3976,15 +3967,15 @@ Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<R
}
void
Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
set_value_unchecked (val);
_set_value (val, group_override);
}
}
void
Route::SoloControllable::set_value_unchecked (double val)
Route::SoloControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
const bool bval = ((val >= 0.5) ? true : false);
@ -3998,12 +3989,20 @@ Route::SoloControllable::set_value_unchecked (double val)
rl->push_back (r);
if (Config->get_solo_control_is_listen_control()) {
_session.set_listen (rl, bval);
_session.set_listen (rl, bval, Session::rt_cleanup, group_override);
} else {
_session.set_solo (rl, bval);
_session.set_solo (rl, bval, Session::rt_cleanup, group_override);
}
}
void
Route::SoloControllable::set_value_unchecked (double val)
{
/* Used only by automation playback */
_set_value (val, Controllable::NoGroup);
}
double
Route::SoloControllable::get_value () const
{
@ -4053,15 +4052,22 @@ Route::MuteControllable::set_superficial_value(bool muted)
}
void
Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
set_value_unchecked (val);
_set_value (val, group_override);
}
}
void
Route::MuteControllable::set_value_unchecked (double val)
{
/* used only automation playback */
_set_value (val, Controllable::NoGroup);
}
void
Route::MuteControllable::_set_value (double val, Controllable::GroupControlDisposition group_override)
{
const bool bval = ((val >= 0.5) ? true : false);
@ -4074,12 +4080,12 @@ Route::MuteControllable::set_value_unchecked (double val)
// Set superficial/automation value to drive controller (and possibly record)
set_superficial_value (bval);
// Playing back automation, set route mute directly
r->set_mute (bval, this);
r->set_mute (bval, Controllable::NoGroup);
} else {
// Set from user, queue mute event
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (r);
_session.set_mute (rl, bval, Session::rt_cleanup);
_session.set_mute (rl, bval, Session::rt_cleanup, group_override);
}
}

View File

@ -18,6 +18,7 @@
#include "ardour/libardour_visibility.h"
#include "ardour/route_group_member.h"
#include "ardour/route_group.h"
using namespace ARDOUR;
@ -34,3 +35,13 @@ RouteGroupMember::set_route_group (RouteGroup *rg)
_route_group = rg;
route_group_changed (); /* EMIT SIGNAL */
}
bool
RouteGroupMember::use_group (PBD::Controllable::GroupControlDisposition gcd, bool (RouteGroup::*predicate)(void) const) const
{
return (gcd != PBD::Controllable::NoGroup) &&
_route_group &&
(_route_group->*predicate)() &&
(((_route_group->is_active()) && (gcd != PBD::Controllable::InverseGroup)) ||
((!_route_group->is_active()) && (gcd == PBD::Controllable::InverseGroup)));
}

View File

@ -1839,7 +1839,7 @@ Session::set_all_tracks_record_enabled (bool enable )
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr) {
tr->set_record_enabled (enable, this);
tr->set_record_enabled (enable, Controllable::NoGroup);
}
}
}
@ -3281,10 +3281,10 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
boost::weak_ptr<Route> wpr (*x);
boost::shared_ptr<Route> r (*x);
r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _2, wpr));
r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _3, wpr));
r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
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, _2, wpr));
r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr));
r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this));
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));
@ -3450,7 +3450,7 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
continue;
}
(*iter)->set_solo (false, this);
(*iter)->set_solo (false, Controllable::NoGroup);
rs->remove (*iter);
@ -3558,13 +3558,13 @@ Session::remove_route (boost::shared_ptr<Route> route)
}
void
Session::route_mute_changed (void* /*src*/)
Session::route_mute_changed ()
{
set_dirty ();
}
void
Session::route_listen_changed (bool group_override, boost::weak_ptr<Route> wpr)
Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
{
boost::shared_ptr<Route> route = wpr.lock();
if (!route) {
@ -3575,18 +3575,32 @@ Session::route_listen_changed (bool group_override, boost::weak_ptr<Route> wpr)
if (route->listening_via_monitor ()) {
if (Config->get_exclusive_solo()) {
/* new listen: disable all other listen, except solo-grouped channels */
RouteGroup* rg = route->route_group ();
bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
if (group_override && rg) {
leave_group_alone = !leave_group_alone;
}
const bool group_already_accounted_for = route->use_group (group_override, &RouteGroup::is_solo);
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() || (leave_group_alone && ((*i)->route_group() == rg))) {
if ((*i) == route) {
/* already changed */
continue;
}
(*i)->set_listen (false, this, group_override);
if ((*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
/* route does not get solo propagated to it */
continue;
}
if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
/* this route is a part of the same solo group as the route
* that was changed. Changing that route did change or will
* change all group members appropriately, so we can ignore it
* here
*/
continue;
}
(*i)->set_listen (false, Controllable::NoGroup);
}
}
@ -3600,7 +3614,7 @@ Session::route_listen_changed (bool group_override, boost::weak_ptr<Route> wpr)
update_route_solo_state ();
}
void
Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr)
{
boost::shared_ptr<Route> route = wpr.lock ();
@ -3630,7 +3644,7 @@ Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
}
void
Session::route_solo_changed (bool self_solo_change, bool group_override, boost::weak_ptr<Route> wpr)
Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
{
DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
@ -3651,21 +3665,51 @@ Session::route_solo_changed (bool self_solo_change, bool group_override, boost:
delta = -1;
}
/* the route may be a member of a group that has shared-solo
* semantics. If so, then all members of that group should follow the
* solo of the changed route. But ... this is optional, controlled by a
* Controllable::GroupControlDisposition.
*
* The first argument to the signal that this method is connected to is the
* GroupControlDisposition value that was used to change solo.
*
* If the solo change was done with group semantics (either InverseGroup
* (force the entire group to change even if the group shared solo is
* disabled) or UseGroup (use the group, which may or may not have the
* shared solo property enabled)) then as we propagate the change to
* the entire session we should IGNORE THE GROUP that the changed route
* belongs to.
*/
RouteGroup* rg = route->route_group ();
bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
if (group_override && rg) {
leave_group_alone = !leave_group_alone;
}
const bool group_already_accounted_for = route->use_group (group_override, &RouteGroup::is_solo);
if (delta == 1 && Config->get_exclusive_solo()) {
/* new solo: disable all other solos, but not the group if its solo-enabled */
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i) == route || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
(leave_group_alone && ((*i)->route_group() == rg))) {
if ((*i) == route) {
/* already changed */
continue;
}
(*i)->set_solo (false, this, group_override);
if ((*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
/* route does not get solo propagated to it */
continue;
}
if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
/* this route is a part of the same solo group as the route
* that was changed. Changing that route did change or will
* change all group members appropriately, so we can ignore it
* here
*/
continue;
}
(*i)->set_solo (false, group_override);
}
}
@ -3679,8 +3723,22 @@ Session::route_solo_changed (bool self_solo_change, bool group_override, boost:
bool via_sends_only;
bool in_signal_flow;
if ((*i) == route || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
(leave_group_alone && ((*i)->route_group() == rg))) {
if ((*i) == route) {
/* already changed */
continue;
}
if ((*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
/* route does not get solo propagated to it */
continue;
}
if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
/* this route is a part of the same solo group as the route
* that was changed. Changing that route did change or will
* change all group members appropriately, so we can ignore it
* here
*/
continue;
}
@ -3746,7 +3804,7 @@ Session::route_solo_changed (bool self_solo_change, bool group_override, boost:
for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
(*i)->act_on_mute ();
(*i)->mute_changed (this);
(*i)->mute_changed ();
}
SoloChanged (); /* EMIT SIGNAL */
@ -3777,7 +3835,7 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
listeners++;
something_listening = true;
} else {
(*i)->set_listen (false, this);
(*i)->set_listen (false, Controllable::NoGroup);
}
}

View File

@ -350,7 +350,7 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
if (trk == at->remote_control_id()) {
at->set_record_enabled (enabled, &mmc);
at->set_record_enabled (enabled, Controllable::UseGroup);
break;
}
}

View File

@ -33,13 +33,15 @@ using namespace ARDOUR;
using namespace Glib;
void
Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, SessionEvent::RTeventCallback after, bool group_override)
Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc,
SessionEvent::RTeventCallback after,
Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
}
void
Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, bool /* group_override */)
Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, Controllable::GroupControlDisposition /*group_override*/)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner()) {
@ -56,11 +58,11 @@ Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, b
void
Session::clear_all_solo_state (boost::shared_ptr<RouteList> rl)
{
queue_event (get_rt_event (rl, false, rt_cleanup, false, &Session::rt_clear_all_solo_state));
queue_event (get_rt_event (rl, false, rt_cleanup, Controllable::NoGroup, &Session::rt_clear_all_solo_state));
}
void
Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, bool /* group_override */)
Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, Controllable::GroupControlDisposition /* group_override */)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if ((*i)->is_auditioner()) {
@ -72,17 +74,18 @@ Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */
}
void
Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after,
Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo));
}
void
Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner()) {
(*i)->set_solo (yn, this, group_override);
(*i)->set_solo (yn, group_override);
}
}
@ -104,38 +107,38 @@ Session::set_just_one_solo (boost::shared_ptr<Route> r, bool yn, SessionEvent::R
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (r);
queue_event (get_rt_event (rl, yn, after, false, &Session::rt_set_just_one_solo));
queue_event (get_rt_event (rl, yn, after, Controllable::NoGroup, &Session::rt_set_just_one_solo));
}
void
Session::rt_set_just_one_solo (boost::shared_ptr<RouteList> just_one, bool yn, bool /*ignored*/)
Session::rt_set_just_one_solo (boost::shared_ptr<RouteList> just_one, bool yn, Controllable::GroupControlDisposition /*ignored*/)
{
boost::shared_ptr<RouteList> rl = routes.reader ();
boost::shared_ptr<Route> r = just_one->front();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner() && r != *i) {
(*i)->set_solo (!yn, (*i)->route_group());
(*i)->set_solo (!yn, Controllable::NoGroup);
}
}
r->set_solo (yn, r->route_group());
r->set_solo (yn, Controllable::NoGroup);
set_dirty();
}
void
Session::set_listen (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
Session::set_listen (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_listen));
}
void
Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner()) {
(*i)->set_listen (yn, this, group_override);
(*i)->set_listen (yn, group_override);
}
}
@ -143,7 +146,7 @@ Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, bool group_ove
}
void
Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
/* Set superficial value of mute controls for automation. */
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
@ -155,11 +158,11 @@ Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeve
}
void
Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_monitor() && !(*i)->is_auditioner()) {
(*i)->set_mute (yn, this);
(*i)->set_mute (yn, group_override);
}
}
@ -167,17 +170,17 @@ Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_ove
}
void
Session::set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
Session::set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo_isolated));
}
void
Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
(*i)->set_solo_isolated (yn, this);
(*i)->set_solo_isolated (yn, group_override);
}
}
@ -185,7 +188,7 @@ Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, bool /*
}
void
Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
if (!writable()) {
return;
@ -206,7 +209,7 @@ Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEv
boost::shared_ptr<Track> t;
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
t->prep_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
t->prep_record_enabled (yn, group_override);
}
}
@ -214,7 +217,7 @@ Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEv
}
void
Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if ((*i)->is_auditioner() || (*i)->record_safe ()) {
@ -224,7 +227,7 @@ Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool g
boost::shared_ptr<Track> t;
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
t->set_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
t->set_record_enabled (yn, group_override);
}
}
@ -233,14 +236,14 @@ Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool g
void
Session::set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
Session::set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
set_record_enabled (rl, false, after, group_override);
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_safe));
}
void
Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin (); i != rl->end (); ++i) {
if ((*i)->is_auditioner ()) { // REQUIRES REVIEW Can audiotioner be in Record Safe mode?
@ -250,7 +253,7 @@ Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, bool grou
boost::shared_ptr<Track> t;
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
t->set_record_safe (yn, (group_override ? (void*) t->route_group () : (void *) this));
t->set_record_safe (yn, group_override);
}
}

View File

@ -190,22 +190,30 @@ Track::RecEnableControl::RecEnableControl (boost::shared_ptr<Track> t)
}
void
Track::RecEnableControl::set_value (double val, Controllable::GroupControlDisposition /* group_override */)
Track::RecEnableControl::set_value (double val, Controllable::GroupControlDisposition group_override)
{
if (writable()) {
set_value_unchecked (val);
_set_value (val, group_override);
}
}
void
Track::RecEnableControl::set_value_unchecked (double val)
{
if (writable()) {
_set_value (val, Controllable::NoGroup);
}
}
void
Track::RecEnableControl::_set_value (double val, Controllable::GroupControlDisposition group_override)
{
boost::shared_ptr<Track> t = track.lock ();
if (!t) {
return;
}
t->set_record_enabled (val >= 0.5 ? true : false, this);
t->set_record_enabled (val >= 0.5 ? true : false, group_override);
}
double
@ -238,7 +246,7 @@ Track::can_record()
}
void
Track::prep_record_enabled (bool yn, void *src)
Track::prep_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (yn && record_safe ()) {
return;
@ -252,8 +260,8 @@ Track::prep_record_enabled (bool yn, void *src)
return;
}
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
_route_group->apply (&Track::prep_record_enabled, yn, _route_group);
if (use_group (group_override, &RouteGroup::is_recenable)) {
_route_group->apply (&Track::prep_record_enabled, yn, Controllable::NoGroup);
return;
}
@ -282,7 +290,7 @@ Track::prep_record_enabled (bool yn, void *src)
}
void
Track::set_record_enabled (bool yn, void *src)
Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_diskstream->record_safe ()) {
return;
@ -296,8 +304,8 @@ Track::set_record_enabled (bool yn, void *src)
return;
}
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
_route_group->apply (&Track::set_record_enabled, yn, _route_group);
if (use_group (group_override, &RouteGroup::is_recenable)) {
_route_group->apply (&Track::set_record_enabled, yn, Controllable::NoGroup);
return;
}
@ -313,18 +321,18 @@ Track::record_safe () const
}
void
Track::set_record_safe (bool yn, void *src)
Track::set_record_safe (bool yn, Controllable::GroupControlDisposition group_override)
{
if (!_session.writable()) { /* REQUIRES REVIEW */
if (!_session.writable()) {
return;
}
if (_freeze_record.state == Frozen) { /* REQUIRES REVIEW */
if (_freeze_record.state == Frozen) {
return;
}
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
_route_group->apply (&Track::set_record_safe, yn, _route_group);
if (use_group (group_override, &RouteGroup::is_recenable)) {
_route_group->apply (&Track::set_record_safe, yn, Controllable::NoGroup);
return;
}
@ -1149,4 +1157,3 @@ Track::metering_state () const
}
return rv ? MeteringInput : MeteringRoute;
}

View File

@ -41,7 +41,7 @@ setup_libpbd_enums ()
REGISTER_CLASS_ENUM (Controllable, GainLike);
REGISTER (controllable_flags);
REGISTER_CLASS_ENUM (Controllable, WholeGroup);
REGISTER_CLASS_ENUM (Controllable, InverseGroup);
REGISTER_CLASS_ENUM (Controllable, UseGroup);
REGISTER_CLASS_ENUM (Controllable, NoGroup);
REGISTER (controllable_group_disposition);

View File

@ -82,7 +82,7 @@ class LIBPBD_API Controllable : public PBD::StatefulDestructible {
*/
enum GroupControlDisposition {
WholeGroup, /* set all controls in the same "group" as this one */
InverseGroup, /* set all controls in the same "group" as this one */
NoGroup, /* set only this control */
UseGroup /* use group settings to decide which group controls are altered */
};

View File

@ -199,7 +199,7 @@ ControlProtocol::route_set_rec_enable (uint32_t table_index, bool yn)
boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r);
if (at) {
at->set_record_enabled (yn, this);
at->set_record_enabled (yn, Controllable::NoGroup);
}
}
@ -312,7 +312,7 @@ ControlProtocol::route_set_muted (uint32_t table_index, bool yn)
boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
r->set_mute (yn, this);
r->set_mute (yn, Controllable::UseGroup);
}
}
@ -343,7 +343,7 @@ ControlProtocol::route_set_soloed (uint32_t table_index, bool yn)
boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
r->set_solo (yn, this);
r->set_solo (yn, Controllable::UseGroup);
}
}

View File

@ -1107,9 +1107,9 @@ FaderPort::set_current_route (boost::shared_ptr<Route> r)
if (_current_route) {
_current_route->DropReferences.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::drop_current_route, this), this);
_current_route->mute_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_mute, this, _1), this);
_current_route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_solo, this, _1, _2, _3), this);
_current_route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_listen, this, _1, _2), this);
_current_route->mute_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_mute, this), this);
_current_route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_solo, this), this);
_current_route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_listen, this), this);
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (_current_route);
if (t) {
@ -1187,7 +1187,7 @@ FaderPort::map_cut ()
}
void
FaderPort::map_mute (void*)
FaderPort::map_mute ()
{
if (_current_route) {
if (_current_route->muted()) {
@ -1204,7 +1204,7 @@ FaderPort::map_mute (void*)
}
void
FaderPort::map_solo (bool, void*, bool)
FaderPort::map_solo ()
{
if (_current_route) {
get_button (Solo).set_led_state (_output_port, _current_route->soloed() || _current_route->listening_via_monitor());
@ -1214,7 +1214,7 @@ FaderPort::map_solo (bool, void*, bool)
}
void
FaderPort::map_listen (void*, bool)
FaderPort::map_listen ()
{
if (_current_route) {
get_button (Solo).set_led_state (_output_port, _current_route->listening_via_monitor());
@ -1292,8 +1292,7 @@ FaderPort::map_route_state ()
stop_blinking (Solo);
get_button (Rec).set_led_state (_output_port, false);
} else {
/* arguments to these map_*() methods are all ignored */
map_solo (false, 0, false);
map_solo ();
map_recenable ();
map_gain ();
map_auto ();
@ -1301,7 +1300,7 @@ FaderPort::map_route_state ()
if (_current_route == session->monitor_out()) {
map_cut ();
} else {
map_mute (0);
map_mute ();
}
}
}

View File

@ -302,9 +302,9 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
PBD::ScopedConnectionList route_connections;
void map_route_state ();
void map_solo (bool,void*,bool);
void map_listen (void*,bool);
void map_mute (void*);
void map_solo ();
void map_listen ();
void map_mute ();
void map_recenable ();
void map_gain ();
void map_cut ();

View File

@ -876,15 +876,7 @@ Strip::handle_button (Button& button, ButtonState bs)
DEBUG_TRACE (DEBUG::MackieControl, "add button on press\n");
_surface->mcp().add_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index);
float new_value;
int ms = _surface->mcp().main_modifier_state();
if (ms & MackieControlProtocol::MODIFIER_SHIFT) {
/* reset to default/normal value */
new_value = control->normal();
} else {
new_value = control->get_value() ? 0.0 : 1.0;
}
float new_value = control->get_value() ? 0.0 : 1.0;
/* get all controls that either have their
* button down or are within a range of
@ -897,10 +889,18 @@ Strip::handle_button (Button& button, ButtonState bs)
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("there are %1 buttons down for control type %2, new value = %3\n",
controls.size(), control->parameter().type(), new_value));
/* apply change */
/* apply change, with potential modifier semantics */
Controllable::GroupControlDisposition gcd;
if (_surface->mcp().main_modifier_state() & MackieControlProtocol::MODIFIER_SHIFT) {
gcd = Controllable::NoGroup;
} else {
gcd = Controllable::UseGroup;
}
for (MackieControlProtocol::ControlList::iterator c = controls.begin(); c != controls.end(); ++c) {
(*c)->set_value (new_value, Controllable::NoGroup);
(*c)->set_value (new_value, gcd);
}
} else {

View File

@ -1047,7 +1047,7 @@ OSC::route_mute (int rid, int yn)
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
r->set_mute (yn, this);
r->set_mute (yn, PBD::Controllable::NoGroup);
}
return 0;
@ -1063,7 +1063,7 @@ OSC::route_solo (int rid, int yn)
if (r) {
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (r);
session->set_solo (rl, yn);
session->set_solo (rl, yn, Session::rt_cleanup, PBD::Controllable::NoGroup);
}
return 0;
@ -1077,7 +1077,7 @@ OSC::route_recenable (int rid, int yn)
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
r->set_record_enabled (yn, this);
r->set_record_enabled (yn, PBD::Controllable::NoGroup);
}
return 0;
@ -1112,7 +1112,7 @@ OSC::route_set_trim_abs (int rid, float level)
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
r->set_trim (level, this);
r->set_trim (level, PBD::Controllable::NoGroup);
}
return 0;