summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-03-07 14:59:40 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2016-05-31 15:30:39 -0400
commit1f6800d421fc41e6797e0bc3b6e78a6e07e97120 (patch)
treea08ec9f91927f3f0c438e4b749b351a146ebc92f /libs
parenta03d969a978126d72f0825096d9d9ec89816a0d9 (diff)
redesign Route and VCA objects to inherit from ARDOUR::Stripable
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/route.h21
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/ardour/stripable.h139
-rw-r--r--libs/ardour/ardour/vca.h93
-rw-r--r--libs/ardour/gain_control.cc4
-rw-r--r--libs/ardour/route.cc6
-rw-r--r--libs/ardour/session.cc15
-rw-r--r--libs/ardour/session_rtevents.cc2
-rw-r--r--libs/ardour/vca.cc160
-rw-r--r--libs/ardour/vca_manager.cc11
10 files changed, 372 insertions, 80 deletions
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index ed32769058..b187c39629 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -48,6 +48,7 @@
#include "ardour/types.h"
#include "ardour/mute_master.h"
#include "ardour/route_group_member.h"
+#include "ardour/stripable.h"
#include "ardour/graphnode.h"
#include "ardour/automatable.h"
#include "ardour/unknown_processor.h"
@@ -74,7 +75,7 @@ class CapturingProcessor;
class InternalSend;
class VCA;
-class LIBARDOUR_API Route : public SessionObject, public Automatable, public RouteGroupMember, public GraphNode, public boost::enable_shared_from_this<Route>
+class LIBARDOUR_API Route : public Stripable, public Automatable, public RouteGroupMember, public GraphNode, public boost::enable_shared_from_this<Route>
{
public:
@@ -203,8 +204,8 @@ public:
boost::shared_ptr<Amp> amp() const { return _amp; }
boost::shared_ptr<Amp> trim() const { return _trim; }
- PeakMeter& peak_meter() { return *_meter.get(); }
- const PeakMeter& peak_meter() const { return *_meter.get(); }
+ boost::shared_ptr<PeakMeter> peak_meter() { return _meter; }
+ boost::shared_ptr<const PeakMeter> peak_meter() const { return _meter; }
boost::shared_ptr<PeakMeter> shared_peak_meter() const { return _meter; }
boost::shared_ptr<DelayLine> delay_line() const { return _delayline; }
@@ -560,11 +561,11 @@ public:
void set_control (AutomationType, double val, PBD::Controllable::GroupControlDisposition group_override);
- boost::shared_ptr<SoloControllable> solo_control() const {
+ boost::shared_ptr<AutomationControl> solo_control() const {
return _solo_control;
}
- boost::shared_ptr<MuteControllable> mute_control() const {
+ boost::shared_ptr<AutomationControl> mute_control() const {
return _mute_control;
}
@@ -572,11 +573,11 @@ public:
return _mute_master;
}
- boost::shared_ptr<SoloIsolateControllable> solo_isolate_control() const {
+ boost::shared_ptr<AutomationControl> solo_isolate_control() const {
return _solo_isolate_control;
}
- boost::shared_ptr<SoloSafeControllable> solo_safe_control() const {
+ boost::shared_ptr<AutomationControl> solo_safe_control() const {
return _solo_safe_control;
}
@@ -594,11 +595,11 @@ public:
boost::shared_ptr<Panner> panner() const; /* may return null */
boost::shared_ptr<PannerShell> panner_shell() const;
- boost::shared_ptr<GainControl> gain_control() const;
boost::shared_ptr<Pannable> pannable() const;
- boost::shared_ptr<GainControl> trim_control() const;
- boost::shared_ptr<PhaseControllable> phase_control() const;
+ boost::shared_ptr<GainControl> gain_control() const;
+ boost::shared_ptr<AutomationControl> trim_control() const;
+ boost::shared_ptr<AutomationControl> phase_control() const;
/**
Return the first processor that accepts has at least one MIDI input
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index e774666ce5..47329f7395 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -305,6 +305,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
boost::shared_ptr<Route> route_by_name (std::string);
boost::shared_ptr<Route> route_by_id (PBD::ID);
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
+ boost::shared_ptr<Stripable> stripable_by_remote_id (uint32_t id);
boost::shared_ptr<Route> route_by_selected_count (uint32_t cnt);
boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID);
void routes_using_input_from (const std::string& str, RouteList& rl);
diff --git a/libs/ardour/ardour/stripable.h b/libs/ardour/ardour/stripable.h
new file mode 100644
index 0000000000..e97fe79103
--- /dev/null
+++ b/libs/ardour/ardour/stripable.h
@@ -0,0 +1,139 @@
+/*
+ Copyright (C) 2016 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __libardour_stripable_h__
+#define __libardour_stripable_h__
+
+#include <stdint.h>
+
+#include <string>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "ardour/gain_control.h"
+#include "ardour/session_object.h"
+
+namespace ARDOUR {
+
+class AutomationControl;
+class PeakMeter;
+
+/* This is a virtual base class for any object that needs to be potentially
+ * represented by a control-centric user interface using the general model of a
+ * mixing console "strip" - a collection of controls that determine the state
+ * and behaviour of the object.
+ */
+
+class Stripable : public SessionObject {
+ public:
+ Stripable (Session& session, const std::string& name)
+ : SessionObject (session, name) {}
+
+ /* XXX
+ midi on/off
+ selected status
+ visible/hidden
+ */
+
+ virtual uint32_t remote_control_id () const = 0;
+
+ virtual boost::shared_ptr<PeakMeter> peak_meter() = 0;
+ virtual boost::shared_ptr<const PeakMeter> peak_meter() const = 0;
+
+ virtual boost::shared_ptr<GainControl> gain_control() const = 0;
+
+ virtual boost::shared_ptr<AutomationControl> solo_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> mute_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> phase_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> trim_control() const = 0;
+
+ virtual boost::shared_ptr<AutomationControl> monitoring_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> recenable_control() const { return boost::shared_ptr<AutomationControl>(); }
+
+ /* "well-known" controls for panning. Any or all of these may return
+ * null.
+ */
+
+ virtual boost::shared_ptr<AutomationControl> pan_azimuth_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> pan_elevation_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> pan_width_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> pan_frontback_control() const = 0;
+ virtual boost::shared_ptr<AutomationControl> pan_lfe_control() const = 0;
+
+ /* "well-known" controls for an EQ in this route. Any or all may
+ * be null. eq_band_cnt() must return 0 if there is no EQ present.
+ * Passing an @param band value >= eq_band_cnt() will guarantee the
+ * return of a null ptr (or an empty string for eq_band_name()).
+ */
+ virtual uint32_t eq_band_cnt () const = 0;
+ virtual std::string eq_band_name (uint32_t) const = 0;
+ virtual boost::shared_ptr<AutomationControl> eq_gain_controllable (uint32_t band) const = 0;
+ virtual boost::shared_ptr<AutomationControl> eq_freq_controllable (uint32_t band) const = 0;
+ virtual boost::shared_ptr<AutomationControl> eq_q_controllable (uint32_t band) const = 0;
+ virtual boost::shared_ptr<AutomationControl> eq_shape_controllable (uint32_t band) const = 0;
+ virtual boost::shared_ptr<AutomationControl> eq_enable_controllable () const = 0;
+ virtual boost::shared_ptr<AutomationControl> eq_hpf_controllable () const = 0;
+
+ /* "well-known" controls for a compressor in this route. Any or all may
+ * be null.
+ */
+ virtual boost::shared_ptr<AutomationControl> comp_enable_controllable () const = 0;
+ virtual boost::shared_ptr<AutomationControl> comp_threshold_controllable () const = 0;
+ virtual boost::shared_ptr<AutomationControl> comp_speed_controllable () const = 0;
+ virtual boost::shared_ptr<AutomationControl> comp_mode_controllable () const = 0;
+ virtual boost::shared_ptr<AutomationControl> comp_makeup_controllable () const = 0;
+ virtual boost::shared_ptr<AutomationControl> comp_redux_controllable () const = 0;
+
+ /* @param mode must be supplied by the comp_mode_controllable(). All other values
+ * result in undefined behaviour
+ */
+ virtual std::string comp_mode_name (uint32_t mode) const = 0;
+ /* @param mode - as for comp mode name. This returns the name for the
+ * parameter/control accessed via comp_speed_controllable(), which can
+ * be mode dependent.
+ */
+ virtual std::string comp_speed_name (uint32_t mode) const = 0;
+
+ /* "well-known" controls for sends to well-known busses in this route. Any or all may
+ * be null.
+ *
+ * In Mixbus, these are the sends that connect to the mixbusses.
+ * In Ardour, these are user-created sends that connect to user-created
+ * Aux busses.
+ */
+ virtual boost::shared_ptr<AutomationControl> send_level_controllable (uint32_t n) const = 0;
+ virtual boost::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const = 0;
+ /* for the same value of @param n, this returns the name of the send
+ * associated with the pair of controllables returned by the above two methods.
+ */
+ virtual std::string send_name (uint32_t n) const = 0;
+
+ /* well known control that enables/disables sending to the master bus.
+ *
+ * In Ardour, this returns null.
+ * In Mixbus, it will return a suitable control, or null depending on
+ * the route.
+ */
+ virtual boost::shared_ptr<AutomationControl> master_send_enable_controllable () const = 0;
+};
+
+
+}
+
+#endif /* __libardour_stripable_h__ */
diff --git a/libs/ardour/ardour/vca.h b/libs/ardour/ardour/vca.h
index 15850242cc..cca83a13f2 100644
--- a/libs/ardour/ardour/vca.h
+++ b/libs/ardour/ardour/vca.h
@@ -21,60 +21,112 @@
#include <string>
#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
#include "pbd/controllable.h"
#include "pbd/statefuldestructible.h"
#include "ardour/automatable.h"
-#include "ardour/session_handle.h"
+#include "ardour/stripable.h"
namespace ARDOUR {
class GainControl;
class Route;
-class LIBARDOUR_API VCA : public SessionHandleRef, public PBD::StatefulDestructible, public Automatable {
+class LIBARDOUR_API VCA : public Stripable, public Automatable, public boost::enable_shared_from_this<VCA> {
public:
VCA (Session& session, uint32_t num, const std::string& name);
- VCA (Session& session, XMLNode const&, int version);
~VCA();
- std::string name() const { return _name; }
uint32_t number () const { return _number; }
+ uint32_t remote_control_id() const;
- void set_name (std::string const&);
-
- void set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
- double get_value () const;
-
- boost::shared_ptr<GainControl> control() const { return _control; }
-
+ int init ();
XMLNode& get_state();
int set_state (XMLNode const&, int version);
void add_solo_mute_target (boost::shared_ptr<Route>);
void remove_solo_mute_target (boost::shared_ptr<Route>);
- void set_solo (bool yn);
bool soloed () const;
-
- void set_mute (bool yn);
bool muted () const;
- PBD::Signal0<void> SoloChange;
- PBD::Signal0<void> MuteChange;
-
static std::string default_name_template ();
static int next_vca_number ();
static std::string xml_node_name;
+ virtual boost::shared_ptr<GainControl> gain_control() const { return _gain_control; }
+ virtual boost::shared_ptr<AutomationControl> solo_control() const { return _solo_control; }
+ virtual boost::shared_ptr<AutomationControl> mute_control() const { return _mute_control; }
+
+ /* null Stripable API, because VCAs don't have any of this */
+
+ virtual boost::shared_ptr<PeakMeter> peak_meter() { return boost::shared_ptr<PeakMeter>(); }
+ virtual boost::shared_ptr<const PeakMeter> peak_meter() const { return boost::shared_ptr<PeakMeter>(); }
+ virtual boost::shared_ptr<AutomationControl> phase_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> trim_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> monitoring_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> recenable_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> pan_azimuth_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> pan_elevation_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> pan_width_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> pan_frontback_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> pan_lfe_control() const { return boost::shared_ptr<AutomationControl>(); }
+ virtual uint32_t eq_band_cnt () const { return 0; }
+ virtual std::string eq_band_name (uint32_t) const { return std::string(); }
+ virtual boost::shared_ptr<AutomationControl> eq_gain_controllable (uint32_t band) const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> eq_freq_controllable (uint32_t band) const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> eq_q_controllable (uint32_t band) const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> eq_shape_controllable (uint32_t band) const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> eq_enable_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> eq_hpf_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> comp_enable_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> comp_threshold_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> comp_speed_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> comp_mode_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> comp_makeup_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> comp_redux_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+ virtual std::string comp_mode_name (uint32_t mode) const { return std::string(); }
+ virtual std::string comp_speed_name (uint32_t mode) const { return std::string(); }
+ virtual boost::shared_ptr<AutomationControl> send_level_controllable (uint32_t n) const { return boost::shared_ptr<AutomationControl>(); }
+ virtual boost::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const { return boost::shared_ptr<AutomationControl>(); }
+ virtual std::string send_name (uint32_t n) const { return std::string(); }
+ virtual boost::shared_ptr<AutomationControl> master_send_enable_controllable () const { return boost::shared_ptr<AutomationControl>(); }
+
private:
+ class VCASoloControllable : public AutomationControl {
+ public:
+ VCASoloControllable (std::string const & name, boost::shared_ptr<VCA> vca);
+ 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);
+ boost::weak_ptr<VCA> _vca;
+ };
+
+ class VCAMuteControllable : public AutomationControl {
+ public:
+ VCAMuteControllable (std::string const & name, boost::shared_ptr<VCA> vca);
+ 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);
+ boost::weak_ptr<VCA> _vca;
+ };
+
+ friend class VCASoloControllable;
+ friend class VCAMuteControllable;
+
uint32_t _number;
- std::string _name;
- boost::shared_ptr<GainControl> _control;
RouteList solo_mute_targets;
PBD::ScopedConnectionList solo_mute_connections;
mutable Glib::Threads::RWLock solo_mute_lock;
+ boost::shared_ptr<GainControl> _gain_control;
+ boost::shared_ptr<VCASoloControllable> _solo_control;
+ boost::shared_ptr<VCAMuteControllable> _mute_control;
bool _solo_requested;
bool _mute_requested;
@@ -84,6 +136,9 @@ class LIBARDOUR_API VCA : public SessionHandleRef, public PBD::StatefulDestructi
bool soloed_locked () const;
bool muted_locked () const;
+ void set_solo (bool yn);
+ void set_mute (bool yn);
+
};
} /* namespace */
diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc
index 3eff20b1f1..3415f7c620 100644
--- a/libs/ardour/gain_control.cc
+++ b/libs/ardour/gain_control.cc
@@ -180,7 +180,7 @@ GainControl::add_master (boost::shared_ptr<VCA> vca)
/* ratio will be recomputed below */
- res = _masters.insert (make_pair<uint32_t,MasterRecord> (vca->number(), MasterRecord (vca->control(), 0.0)));
+ res = _masters.insert (make_pair<uint32_t,MasterRecord> (vca->number(), MasterRecord (vca->gain_control(), 0.0)));
if (res.second) {
@@ -197,7 +197,7 @@ GainControl::add_master (boost::shared_ptr<VCA> vca)
and we no longer hear about changes to the VCA.
*/
- vca->control()->Changed.connect_same_thread (res.first->second.connection, boost::bind (&PBD::Signal0<void>::operator(), &Changed));
+ vca->gain_control()->Changed.connect_same_thread (res.first->second.connection, boost::bind (&PBD::Signal0<void>::operator(), &Changed));
}
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 581031c405..db92edf786 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -83,7 +83,7 @@ PBD::Signal3<int,boost::shared_ptr<Route>, boost::shared_ptr<PluginInsert>, Rout
/** Base class for all routable/mixable objects (tracks and busses) */
Route::Route (Session& sess, string name, Flag flg, DataType default_type)
- : SessionObject (sess, name)
+ : Stripable (sess, name)
, Automatable (sess)
, GraphNode (sess._process_graph)
, _active (true)
@@ -4732,13 +4732,13 @@ Route::gain_control() const
return _gain_control;
}
-boost::shared_ptr<GainControl>
+boost::shared_ptr<AutomationControl>
Route::trim_control() const
{
return _trim_control;
}
-boost::shared_ptr<Route::PhaseControllable>
+boost::shared_ptr<AutomationControl>
Route::phase_control() const
{
if (phase_invert().size()) {
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index b9dbaa72fd..86d698a2cb 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -4195,6 +4195,21 @@ Session::route_by_remote_id (uint32_t id)
}
+boost::shared_ptr<Stripable>
+Session::stripable_by_remote_id (uint32_t id)
+{
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if ((*i)->remote_control_id() == id) {
+ return *i;
+ }
+ }
+
+ return boost::shared_ptr<Route> ((Route*) 0);
+}
+
+
boost::shared_ptr<Route>
Session::route_by_selected_count (uint32_t id)
{
diff --git a/libs/ardour/session_rtevents.cc b/libs/ardour/session_rtevents.cc
index 132f706c66..5850643739 100644
--- a/libs/ardour/session_rtevents.cc
+++ b/libs/ardour/session_rtevents.cc
@@ -150,7 +150,7 @@ Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeve
{
/* Set superficial value of mute controls for automation. */
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
- boost::shared_ptr<Route::MuteControllable> mc = (*i)->mute_control();
+ boost::shared_ptr<Route::MuteControllable> mc = boost::dynamic_pointer_cast<Route::MuteControllable> ((*i)->mute_control());
mc->set_superficial_value(yn);
}
diff --git a/libs/ardour/vca.cc b/libs/ardour/vca.cc
index 6a696b5a55..f627dc033e 100644
--- a/libs/ardour/vca.cc
+++ b/libs/ardour/vca.cc
@@ -1,19 +1,19 @@
/*
- Copyright (C) 2016 Paul Davis
+ Copyright (C) 2016 Paul Davis
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your option)
+ any later version.
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 675 Mass Ave, Cambridge, MA 02139, USA.
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "pbd/convert.h"
@@ -48,28 +48,26 @@ VCA::next_vca_number ()
}
VCA::VCA (Session& s, uint32_t num, const string& name)
- : SessionHandleRef (s)
+ : Stripable (s, name)
, Automatable (s)
, _number (num)
- , _name (name)
- , _control (new GainControl (s, Evoral::Parameter (GainAutomation), boost::shared_ptr<AutomationList> ()))
+ , _gain_control (new GainControl (s, Evoral::Parameter (GainAutomation), boost::shared_ptr<AutomationList> ()))
, _solo_requested (false)
, _mute_requested (false)
{
- add_control (_control);
}
-VCA::VCA (Session& s, XMLNode const & node, int version)
- : SessionHandleRef (s)
- , Automatable (s)
- , _number (0)
- , _control (new GainControl (s, Evoral::Parameter (GainAutomation), boost::shared_ptr<AutomationList> ()))
- , _solo_requested (false)
- , _mute_requested (false)
+int
+VCA::init ()
{
- add_control (_control);
+ _solo_control.reset (new VCASoloControllable (X_("solo"), shared_from_this()));
+ _mute_control.reset (new VCAMuteControllable (X_("mute"), shared_from_this()));
- set_state (node, version);
+ add_control (_gain_control);
+ add_control (_solo_control);
+ add_control (_mute_control);
+
+ return 0;
}
VCA::~VCA ()
@@ -77,22 +75,10 @@ VCA::~VCA ()
DropReferences (); /* emit signal */
}
-void
-VCA::set_value (double val, Controllable::GroupControlDisposition gcd)
-{
- _control->set_value (val, gcd);
-}
-
-double
-VCA::get_value() const
-{
- return _control->get_value();
-}
-
-void
-VCA::set_name (string const& str)
+uint32_t
+VCA::remote_control_id () const
{
- _name = str;
+ return 9999999 + _number;
}
XMLNode&
@@ -104,7 +90,7 @@ VCA::get_state ()
node->add_property (X_("soloed"), (_solo_requested ? X_("yes") : X_("no")));
node->add_property (X_("muted"), (_mute_requested ? X_("yes") : X_("no")));
- node->add_child_nocopy (_control->get_state());
+ node->add_child_nocopy (_gain_control->get_state());
node->add_child_nocopy (get_automation_xml_state());
return *node;
@@ -128,7 +114,7 @@ VCA::set_state (XMLNode const& node, int version)
if ((*i)->name() == Controllable::xml_node_name) {
XMLProperty* prop = (*i)->property ("name");
if (prop && prop->value() == X_("gaincontrol")) {
- _control->set_state (**i, version);
+ _gain_control->set_state (**i, version);
}
}
}
@@ -187,7 +173,6 @@ VCA::set_solo (bool yn)
}
_solo_requested = yn;
- SoloChange(); /* EMIT SIGNAL */
}
void
@@ -204,7 +189,6 @@ VCA::set_mute (bool yn)
}
_mute_requested = yn;
- MuteChange(); /* EMIT SIGNAL */
}
bool
@@ -218,3 +202,91 @@ VCA::muted () const
{
return _mute_requested;
}
+
+VCA::VCASoloControllable::VCASoloControllable (string const & name, boost::shared_ptr<VCA> vca)
+ : AutomationControl (vca->session(), Evoral::Parameter (SoloAutomation), ParameterDescriptor (Evoral::Parameter (SoloAutomation)),
+ boost::shared_ptr<AutomationList>(), name)
+ , _vca (vca)
+{
+}
+
+void
+VCA::VCASoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
+{
+ if (writable()) {
+ _set_value (val, gcd);
+ }
+}
+
+void
+VCA::VCASoloControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition /*gcd*/)
+{
+ boost::shared_ptr<VCA> vca = _vca.lock();
+ if (!vca) {
+ return;
+ }
+ vca->set_solo (val >= 0.5);
+}
+
+void
+VCA::VCASoloControllable::set_value_unchecked (double val)
+{
+ /* used only by automation playback */
+ _set_value (val, Controllable::NoGroup);
+}
+
+double
+VCA::VCASoloControllable::get_value() const
+{
+ boost::shared_ptr<VCA> vca = _vca.lock();
+ if (!vca) {
+ return 0.0;
+ }
+
+ return vca->soloed() ? 1.0 : 0.0;
+}
+
+/*----*/
+
+VCA::VCAMuteControllable::VCAMuteControllable (string const & name, boost::shared_ptr<VCA> vca)
+ : AutomationControl (vca->session(), Evoral::Parameter (MuteAutomation), ParameterDescriptor (Evoral::Parameter (MuteAutomation)),
+ boost::shared_ptr<AutomationList>(), name)
+ , _vca (vca)
+{
+}
+
+void
+VCA::VCAMuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
+{
+ if (writable()) {
+ _set_value (val, gcd);
+ }
+}
+
+void
+VCA::VCAMuteControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition /*gcd*/)
+{
+ boost::shared_ptr<VCA> vca = _vca.lock();
+ if (!vca) {
+ return;
+ }
+ vca->set_mute (val >= 0.5);
+}
+
+void
+VCA::VCAMuteControllable::set_value_unchecked (double val)
+{
+ /* used only by automation playback */
+ _set_value (val, Controllable::NoGroup);
+}
+
+double
+VCA::VCAMuteControllable::get_value() const
+{
+ boost::shared_ptr<VCA> vca = _vca.lock();
+ if (!vca) {
+ return 0.0;
+ }
+
+ return vca->muted() ? 1.0 : 0.0;
+}
diff --git a/libs/ardour/vca_manager.cc b/libs/ardour/vca_manager.cc
index 71c3fe8029..6cc287554a 100644
--- a/libs/ardour/vca_manager.cc
+++ b/libs/ardour/vca_manager.cc
@@ -18,6 +18,7 @@
*/
#include "pbd/convert.h"
+#include "pbd/error.h"
#include "pbd/replace_all.h"
#include "ardour/vca.h"
@@ -27,6 +28,7 @@
using namespace ARDOUR;
using namespace Glib::Threads;
+using namespace PBD;
using std::string;
string VCAManager::xml_node_name (X_("VCAManager"));
@@ -76,6 +78,8 @@ VCAManager::create_vca (uint32_t howmany, std::string const & name_template)
boost::shared_ptr<VCA> vca = boost::shared_ptr<VCA> (new VCA (_session, num, name));
+ vca->init ();
+
_vcas.push_back (vca);
vcal.push_back (vca);
}
@@ -145,7 +149,12 @@ VCAManager::set_state (XMLNode const& node, int version)
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == VCA::xml_node_name) {
- boost::shared_ptr<VCA> vca = boost::shared_ptr<VCA> (new VCA (_session, **i, version));
+ boost::shared_ptr<VCA> vca = boost::shared_ptr<VCA> (new VCA (_session, 0, X_("tobereset")));
+
+ if (vca->init() || vca->set_state (**i, version)) {
+ error << _("Cannot set state of a VCA") << endmsg;
+ return -1;
+ }
/* can't hold the lock for the entire loop,
* because the new VCA maybe slaved and needs