summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/editor.cc2
-rw-r--r--gtk2_ardour/main.cc8
-rw-r--r--libs/ardour/ardour/control_protocol_manager.h5
-rw-r--r--libs/ardour/ardour/io.h2
-rw-r--r--libs/ardour/ardour/panner.h2
-rw-r--r--libs/ardour/ardour/plugin.h7
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/session.h17
-rw-r--r--libs/ardour/audio_diskstream.cc2
-rw-r--r--libs/ardour/audio_track.cc10
-rw-r--r--libs/ardour/audioregion.cc2
-rw-r--r--libs/ardour/control_protocol_manager.cc48
-rw-r--r--libs/ardour/crossfade.cc4
-rw-r--r--libs/ardour/io.cc11
-rw-r--r--libs/ardour/location.cc2
-rw-r--r--libs/ardour/panner.cc10
-rw-r--r--libs/ardour/playlist.cc2
-rw-r--r--libs/ardour/plugin.cc10
-rw-r--r--libs/ardour/redirect.cc2
-rw-r--r--libs/ardour/region.cc2
-rw-r--r--libs/ardour/route.cc20
-rw-r--r--libs/ardour/session_state.cc38
-rw-r--r--libs/ardour/source.cc2
-rw-r--r--libs/ardour/track.cc2
-rw-r--r--libs/pbd/controllable.cc24
-rw-r--r--libs/pbd/id.cc9
-rw-r--r--libs/pbd/pbd/controllable.h14
-rw-r--r--libs/pbd/pbd/id.h2
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc20
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.cc2
-rw-r--r--libs/surfaces/tranzport/tranzport_control_protocol.cc3
31 files changed, 209 insertions, 77 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 9ab8efb742..f1fe88cd7a 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -2162,7 +2162,7 @@ Editor::get_state ()
XMLNode* node = new XMLNode ("Editor");
char buf[32];
- _id.print (buf);
+ _id.print (buf, sizeof (buf));
node->add_property ("id", buf);
if (is_realized()) {
diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc
index ce7a129d08..049ef29ead 100644
--- a/gtk2_ardour/main.cc
+++ b/gtk2_ardour/main.cc
@@ -383,13 +383,7 @@ int main (int argc, char *argv[])
cout << _("Ardour/GTK ")
<< VERSIONSTRING
<< _("\n (built using ")
- << gtk_ardour_major_version << '.'
- << gtk_ardour_minor_version << '.'
- << gtk_ardour_micro_version
- << _(" with libardour ")
- << libardour_major_version << '.'
- << libardour_minor_version << '.'
- << libardour_micro_version
+ << ARDOUR::get_ardour_revision ()
#ifdef __GNUC__
<< _(" and GCC version ") << __VERSION__
#endif
diff --git a/libs/ardour/ardour/control_protocol_manager.h b/libs/ardour/ardour/control_protocol_manager.h
index 8eda7a4555..99de5479fb 100644
--- a/libs/ardour/ardour/control_protocol_manager.h
+++ b/libs/ardour/ardour/control_protocol_manager.h
@@ -24,6 +24,9 @@ struct ControlProtocolInfo {
bool requested;
bool mandatory;
XMLNode* state;
+
+ ControlProtocolInfo() : descriptor (0), protocol (0), state (0) {}
+ ~ControlProtocolInfo() { if (state) { delete state; } }
};
class ControlProtocolManager : public sigc::trackable, public Stateful
@@ -46,6 +49,8 @@ struct ControlProtocolInfo {
static const std::string state_node_name;
+ void set_protocol_states (const XMLNode&);
+
int set_state (const XMLNode&);
XMLNode& get_state (void);
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 163ae462f3..c32ef31de8 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -295,7 +295,7 @@ public:
gain_t initial, gain_t target, bool invert_polarity);
struct GainControllable : public PBD::Controllable {
- GainControllable (IO& i) : io (i) {}
+ GainControllable (std::string name, IO& i) : Controllable (name), io (i) {}
void set_value (float val);
float get_value (void) const;
diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h
index 3091527e59..0cb0c3dfaa 100644
--- a/libs/ardour/ardour/panner.h
+++ b/libs/ardour/ardour/panner.h
@@ -114,7 +114,7 @@ class StreamPanner : public sigc::trackable, public Stateful
bool _muted;
struct PanControllable : public PBD::Controllable {
- PanControllable (StreamPanner& p) : panner (p) {}
+ PanControllable (std::string name, StreamPanner& p) : Controllable (name), panner (p) {}
StreamPanner& panner;
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index dcc657018a..bc71da84ae 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -98,9 +98,8 @@ class Plugin : public PBD::StatefulDestructible, public sigc::trackable
float step;
float smallstep;
float largestep;
-
- bool min_unbound;
- bool max_unbound;
+ bool min_unbound;
+ bool max_unbound;
};
virtual uint32_t unique_id() const = 0;
@@ -162,7 +161,7 @@ class Plugin : public PBD::StatefulDestructible, public sigc::trackable
void setup_controls ();
struct PortControllable : public PBD::Controllable {
- PortControllable (Plugin&, uint32_t abs_port_id,
+ PortControllable (std::string name, Plugin&, uint32_t abs_port_id,
float lower, float upper, bool toggled, bool logarithmic);
void set_value (float);
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 8ebc598e95..b3ac609880 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -222,7 +222,7 @@ class Route : public IO
SoloControl
};
- ToggleControllable (Route&, ToggleType);
+ ToggleControllable (std::string name, Route&, ToggleType);
void set_value (float);
float get_value (void) const;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 79fd442995..ca7c38b281 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -93,7 +93,7 @@ class AudioRegion;
class Region;
class Playlist;
class VSTPlugin;
-class ControlProtocolManager;
+class ControlProtocolInfo;
struct AudioExportSpecification;
struct RouteGroup;
@@ -415,7 +415,7 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
XMLNode& get_state();
int set_state(const XMLNode& node); // not idempotent
XMLNode& get_template();
-
+
void add_instant_xml (XMLNode&, const std::string& dir);
enum StateOfTheState {
@@ -904,6 +904,9 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
PBD::Controllable* controllable_by_id (const PBD::ID&);
+ void add_controllable (PBD::Controllable*);
+ void remove_controllable (PBD::Controllable*);
+
protected:
friend class AudioEngine;
void set_block_size (nframes_t nframes);
@@ -1667,19 +1670,19 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
LayerModel layer_model;
CrossfadeModel xfade_model;
- typedef std::list<PBD::Controllable*> Controllables;
+ typedef std::set<PBD::Controllable*> Controllables;
Glib::Mutex controllables_lock;
Controllables controllables;
- void add_controllable (PBD::Controllable*);
- void remove_controllable (PBD::Controllable*);
-
-
void reset_native_file_format();
bool first_file_data_format_reset;
bool first_file_header_format_reset;
void config_changed (const char*);
+
+ void add_control_protocol (const ControlProtocolInfo* const, XMLNode*);
+ XMLNode& get_control_protocol_state ();
+
};
} // namespace ARDOUR
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index efe4e89cd1..1374589608 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1759,7 +1759,7 @@ AudioDiskstream::get_state ()
node->add_property ("speed", buf);
node->add_property("name", _name);
- id().print (buf);
+ id().print (buf, sizeof (buf));
node->add_property("id", buf);
if (!capturing_sources.empty() && _session.get_record_enabled()) {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 2860470abd..171f2d7c6b 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -246,6 +246,10 @@ AudioTrack::set_state (const XMLNode& node)
sscanf (prop->value().c_str(), "%d", &x);
set_remote_control_id (x);
}
+
+ } else if (child->name() == X_("recenable")) {
+ _rec_enable_control.set_state (*child);
+ _session.add_controllable (&_rec_enable_control);
}
}
@@ -273,7 +277,7 @@ AudioTrack::state(bool full_state)
for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
inode = new XMLNode (X_("insert"));
- (*i)->id.print (buf);
+ (*i)->id.print (buf, sizeof (buf));
inode->add_property (X_("id"), buf);
inode->add_child_copy ((*i)->state);
@@ -317,9 +321,11 @@ AudioTrack::state(bool full_state)
diskstream.
*/
- _diskstream->id().print (buf);
+ _diskstream->id().print (buf, sizeof (buf));
root.add_property ("diskstream-id", buf);
+ root.add_child_nocopy (_rec_enable_control.get_state());
+
return root;
}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index ee3840063d..855ff074ca 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -688,7 +688,7 @@ AudioRegion::state (bool full)
for (uint32_t n=0; n < sources.size(); ++n) {
snprintf (buf2, sizeof(buf2), "source-%d", n);
- sources[n]->id().print (buf);
+ sources[n]->id().print (buf, sizeof (buf));
node.add_property (buf2, buf);
}
diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc
index 5c02936ba0..7170b45656 100644
--- a/libs/ardour/control_protocol_manager.cc
+++ b/libs/ardour/control_protocol_manager.cc
@@ -50,7 +50,7 @@ ControlProtocolManager::set_session (Session& s)
instantiate (**i);
(*i)->requested = false;
- if ((*i)->state) {
+ if ((*i)->protocol && (*i)->state) {
(*i)->protocol->set_state (*(*i)->state);
}
}
@@ -93,6 +93,10 @@ ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
Glib::Mutex::Lock lm (protocols_lock);
control_protocols.push_back (cpi.protocol);
+ if (cpi.state) {
+ cpi.protocol->set_state (*cpi.state);
+ }
+
return cpi.protocol;
}
@@ -154,7 +158,7 @@ ControlProtocolManager::discover_control_protocols (string path)
vector<string *> *found;
PathScanner scanner;
- cerr << "looking for control protocols in " << path << endl;
+ info << string_compose (_("looking for control protocols in %1"), path) << endmsg;
found = scanner (path, protocol_filter, 0, false, true);
@@ -261,11 +265,20 @@ ControlProtocolManager::set_state (const XMLNode& node)
for (citer = clist.begin(); citer != clist.end(); ++citer) {
if ((*citer)->name() == X_("Protocol")) {
+
prop = (*citer)->property (X_("active"));
+
if (prop && prop->value() == X_("yes")) {
if ((prop = (*citer)->property (X_("name"))) != 0) {
ControlProtocolInfo* cpi = cpi_by_name (prop->value());
if (cpi) {
+
+ if (!(*citer)->children().empty()) {
+ cpi->state = (*citer)->children().front ();
+ } else {
+ cpi->state = 0;
+ }
+
if (_session) {
instantiate (*cpi);
} else {
@@ -294,3 +307,34 @@ ControlProtocolManager::get_state (void)
return *root;
}
+
+void
+ControlProtocolManager::set_protocol_states (const XMLNode& node)
+{
+ XMLNodeList nlist;
+ XMLNodeConstIterator niter;
+ XMLProperty* prop;
+
+ nlist = node.children();
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+ XMLNode* child = (*niter);
+
+ if ((prop = child->property ("name")) == 0) {
+ error << _("control protocol XML node has no name property. Ignored.") << endmsg;
+ continue;
+ }
+
+ ControlProtocolInfo* cpi = cpi_by_name (prop->value());
+
+ if (!cpi) {
+ warning << string_compose (_("control protocol \"%1\" is not known. Ignored"), prop->value()) << endmsg;
+ continue;
+ }
+
+ /* copy the node so that ownership is clear */
+
+ cpi->state = new XMLNode (*child);
+ }
+}
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index acf254e73a..32a9e2b533 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -679,9 +679,9 @@ Crossfade::get_state ()
char buf[64];
LocaleGuard lg (X_("POSIX"));
- _out->id().print (buf);
+ _out->id().print (buf, sizeof (buf));
node->add_property ("out", buf);
- _in->id().print (buf);
+ _in->id().print (buf, sizeof (buf));
node->add_property ("in", buf);
node->add_property ("active", (_active ? "yes" : "no"));
node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no"));
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index f38f938675..34070f3dff 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -107,7 +107,7 @@ IO::IO (Session& s, string name,
: _session (s),
_name (name),
_default_type(default_type),
- _gain_control (*this),
+ _gain_control (X_("gaincontrol"), *this),
_gain_automation_curve (0.0, 2.0, 1.0),
_input_minimum (input_min),
_input_maximum (input_max),
@@ -1431,7 +1431,7 @@ IO::state (bool full_state)
Glib::Mutex::Lock lm (io_lock);
node->add_property("name", _name);
- id().print (buf);
+ id().print (buf, sizeof (buf));
node->add_property("id", buf);
str = "";
@@ -1513,6 +1513,7 @@ IO::state (bool full_state)
}
node->add_child_nocopy (_panner->state (full_state));
+ node->add_child_nocopy (_gain_control.get_state ());
snprintf (buf, sizeof(buf), "%2.12f", gain());
node->add_property ("gain", buf);
@@ -1627,9 +1628,15 @@ IO::set_state (const XMLNode& node)
}
for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
+
if ((*iter)->name() == "Panner") {
_panner->set_state (**iter);
}
+
+ if ((*iter)->name() == X_("gaincontrol")) {
+ _gain_control.set_state (**iter);
+ _session.add_controllable (&_gain_control);
+ }
}
if ((prop = node.property ("automation-state")) != 0) {
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index 5716d9fad5..39331cfda6 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -266,7 +266,7 @@ Location::get_state (void)
node->add_child_nocopy(cd_info_node(m->first, m->second));
}
- id().print (buf);
+ id().print (buf, sizeof (buf));
node->add_property("id", buf);
node->add_property ("name", name());
snprintf (buf, sizeof (buf), "%u", start());
diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc
index 257a21fe58..22053ce56b 100644
--- a/libs/ardour/panner.cc
+++ b/libs/ardour/panner.cc
@@ -67,7 +67,7 @@ static double direct_pan_to_control (pan_t val) {
StreamPanner::StreamPanner (Panner& p)
: parent (p),
- _control (*this)
+ _control (X_("panner"), *this)
{
_muted = false;
@@ -543,6 +543,7 @@ EqualPowerStereoPanner::state (bool full_state)
root->add_property (X_("automation-style"), buf);
StreamPanner::add_state (*root);
+ root->add_child_nocopy (_control.get_state ());
return *root;
}
@@ -575,6 +576,13 @@ EqualPowerStereoPanner::set_state (const XMLNode& node)
}
StreamPanner::set_state (node);
+
+ for (XMLNodeConstIterator iter = node.children().begin(); iter != node.children().end(); ++iter) {
+ if ((*iter)->name() == X_("panner")) {
+ _control.set_state (**iter);
+ parent.session().add_controllable (&_control);
+ }
+ }
return 0;
}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 7a87033a56..6d6a07da95 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -1420,7 +1420,7 @@ Playlist::state (bool full_state)
node->add_property (X_("name"), _name);
- _orig_diskstream_id.print (buf);
+ _orig_diskstream_id.print (buf, sizeof (buf));
node->add_property (X_("orig_diskstream_id"), buf);
node->add_property (X_("frozen"), _frozen ? "yes" : "no");
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 9a82c3bbab..3b471014eb 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -95,15 +95,17 @@ Plugin::get_nth_control (uint32_t n)
Plugin::ParameterDescriptor desc;
get_parameter_descriptor (n, desc);
-
- controls[n] = new PortControllable (*this, n, desc.lower, desc.upper, desc.toggled, desc.logarithmic);
+
+ controls[n] = new PortControllable (describe_parameter (n), *this, n,
+ desc.lower, desc.upper, desc.toggled, desc.logarithmic);
}
return controls[n];
}
-Plugin::PortControllable::PortControllable (Plugin& p, uint32_t port_id, float low, float up, bool t, bool loga)
- : plugin (p), absolute_port (port_id)
+Plugin::PortControllable::PortControllable (string name, Plugin& p, uint32_t port_id,
+ float low, float up, bool t, bool loga)
+ : Controllable (name), plugin (p), absolute_port (port_id)
{
toggled = t;
logarithmic = loga;
diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc
index 41d6e59246..9323966f96 100644
--- a/libs/ardour/redirect.cc
+++ b/libs/ardour/redirect.cc
@@ -233,7 +233,7 @@ Redirect::state (bool full_state)
path = _session.snap_name();
path += "-redirect-";
- id().print (buf);
+ id().print (buf, sizeof (buf));
path += buf;
path += ".automation";
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 6c7e72be46..a13ddd77cd 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -860,7 +860,7 @@ Region::state (bool full_state)
XMLNode *node = new XMLNode ("Region");
char buf[64];
- _id.print (buf);
+ _id.print (buf, sizeof (buf));
node->add_property ("id", buf);
node->add_property ("name", _name);
snprintf (buf, sizeof (buf), "%u", _start);
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 9c752eefeb..70a5d586a0 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -55,16 +55,16 @@ uint32_t Route::order_key_cnt = 0;
Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
: IO (sess, name, input_min, input_max, output_min, output_max, default_type),
_flags (flg),
- _solo_control (*this, ToggleControllable::SoloControl),
- _mute_control (*this, ToggleControllable::MuteControl)
+ _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
+ _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
{
init ();
}
Route::Route (Session& sess, const XMLNode& node)
: IO (sess, "route"),
- _solo_control (*this, ToggleControllable::SoloControl),
- _mute_control (*this, ToggleControllable::MuteControl)
+ _solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
+ _mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
{
init ();
set_state (node);
@@ -1379,6 +1379,8 @@ Route::state(bool full_state)
node->add_property ("order-keys", order_string);
node->add_child_nocopy (IO::state (full_state));
+ node->add_child_nocopy (_solo_control.get_state ());
+ node->add_child_nocopy (_mute_control.get_state ());
if (_control_outs) {
XMLNode* cnode = new XMLNode (X_("ControlOuts"));
@@ -1684,6 +1686,12 @@ Route::set_state (const XMLNode& node)
} else if (child->name() == "extra") {
_extra_xml = new XMLNode (*child);
+ } else if (child->name() == "solo") {
+ _solo_control.set_state (*child);
+ _session.add_controllable (&_solo_control);
+ } else if (child->name() == "mute") {
+ _mute_control.set_state (*child);
+ _session.add_controllable (&_mute_control);
}
}
@@ -2220,8 +2228,8 @@ Route::automation_snapshot (nframes_t now)
}
}
-Route::ToggleControllable::ToggleControllable (Route& s, ToggleType tp)
- : route (s), type(tp)
+Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
+ : Controllable (name), route (s), type(tp)
{
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index cb52b9c4e4..159f8a8473 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -84,6 +84,8 @@
#include <ardour/region_factory.h>
#include <ardour/source_factory.h>
+#include <control_protocol/control_protocol.h>
+
#include "i18n.h"
#include <locale.h>
@@ -242,7 +244,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
- Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
@@ -967,6 +968,8 @@ Session::state(bool full_state)
node->add_child_nocopy (_tempo_map->get_state());
+ node->add_child_nocopy (get_control_protocol_state());
+
if (_extra_xml) {
node->add_child_copy (*_extra_xml);
}
@@ -974,6 +977,25 @@ Session::state(bool full_state)
return *node;
}
+XMLNode&
+Session::get_control_protocol_state ()
+{
+ ControlProtocolManager& cpm (ControlProtocolManager::instance());
+ XMLNode* node = new XMLNode (X_("ControlProtocols"));
+
+ cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
+
+ return *node;
+}
+
+void
+Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
+{
+ if (cpi->protocol) {
+ node->add_child_nocopy (cpi->protocol->get_state());
+ }
+}
+
int
Session::set_state (const XMLNode& node)
{
@@ -1030,6 +1052,7 @@ Session::set_state (const XMLNode& node)
EditGroups
MixGroups
Click
+ ControlProtocols
*/
if (use_config_midi_ports ()) {
@@ -1161,6 +1184,10 @@ Session::set_state (const XMLNode& node)
_click_io->set_state (*child);
}
+ if ((child = find_named_node (node, "ControlProtocols")) != 0) {
+ ControlProtocolManager::instance().set_protocol_states (*child);
+ }
+
/* here beginneth the second phase ... */
StateReady (); /* EMIT SIGNAL */
@@ -2719,7 +2746,7 @@ void
Session::add_controllable (Controllable* c)
{
Glib::Mutex::Lock lm (controllables_lock);
- controllables.push_back (c);
+ controllables.insert (c);
}
void
@@ -2730,7 +2757,12 @@ Session::remove_controllable (Controllable* c)
}
Glib::Mutex::Lock lm (controllables_lock);
- controllables.remove (c);
+
+ Controllables::iterator x = controllables.find (c);
+
+ if (x != controllables.end()) {
+ controllables.erase (x);
+ }
}
Controllable*
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index e4e036584c..7ade8a8573 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -71,7 +71,7 @@ Source::get_state ()
char buf[64];
node->add_property ("name", _name);
- _id.print (buf);
+ _id.print (buf, sizeof (buf));
node->add_property ("id", buf);
if (_timestamp != 0) {
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index cfa7d71a23..6d959ed88d 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -119,7 +119,7 @@ Track::freeze_state() const
}
Track::RecEnableControllable::RecEnableControllable (Track& s)
- : track (s)
+ : Controllable (X_("recenable")), track (s)
{
}
diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc
index b1176c64a5..80c6811e6a 100644
--- a/libs/pbd/controllable.cc
+++ b/libs/pbd/controllable.cc
@@ -1,26 +1,40 @@
#include <pbd/controllable.h>
#include <pbd/xml++.h>
+#include <pbd/error.h>
#include "i18n.h"
using namespace PBD;
-sigc::signal<void,Controllable*> Controllable::Created;
sigc::signal<void,Controllable*> Controllable::GoingAway;
sigc::signal<bool,Controllable*> Controllable::StartLearning;
sigc::signal<void,Controllable*> Controllable::StopLearning;
-Controllable::Controllable ()
+Controllable::Controllable (std::string name)
+ : _name (name)
{
- Created (this);
}
XMLNode&
Controllable::get_state ()
{
- XMLNode* node = new XMLNode (X_("Controllable"));
+ XMLNode* node = new XMLNode (_name);
char buf[64];
- _id.print (buf);
+ _id.print (buf, sizeof (buf));
node->add_property (X_("id"), buf);
return *node;
}
+
+int
+Controllable::set_state (const XMLNode& node)
+{
+ const XMLProperty* prop = node.property (X_("id"));
+
+ if (prop) {
+ _id = prop->value();
+ return 0;
+ } else {
+ error << _("Controllable state node has no ID property") << endmsg;
+ return -1;
+ }
+}
diff --git a/libs/pbd/id.cc b/libs/pbd/id.cc
index c99e242bee..353776de9f 100644
--- a/libs/pbd/id.cc
+++ b/libs/pbd/id.cc
@@ -40,16 +40,15 @@ ID::string_assign (string str)
}
void
-ID::print (char* buf) const
+ID::print (char* buf, uint32_t bufsize) const
{
- /* XXX sizeof buf is unknown. bad API design */
- snprintf (buf, 32, "%" PRIu64, _id);
+ snprintf (buf, bufsize, "%" PRIu64, _id);
}
string ID::to_s() const
{
char buf[32]; // see print()
- print(buf);
+ print(buf, sizeof (buf));
return string(buf);
}
@@ -64,7 +63,7 @@ ostream&
operator<< (ostream& ostr, const ID& _id)
{
char buf[32];
- _id.print (buf);
+ _id.print (buf, sizeof (buf));
ostr << buf;
return ostr;
}
diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h
index c46e477b6e..ff8f8a9b52 100644
--- a/libs/pbd/pbd/controllable.h
+++ b/libs/pbd/pbd/controllable.h
@@ -1,6 +1,8 @@
#ifndef __pbd_controllable_h__
#define __pbd_controllable_h__
+#include <string>
+
#include <sigc++/trackable.h>
#include <sigc++/signal.h>
@@ -13,7 +15,7 @@ namespace PBD {
class Controllable : public virtual sigc::trackable, public Stateful {
public:
- Controllable ();
+ Controllable (std::string name);
virtual ~Controllable() { GoingAway (this); }
virtual void set_value (float) = 0;
@@ -23,22 +25,20 @@ class Controllable : public virtual sigc::trackable, public Stateful {
sigc::signal<void> LearningFinished;
- static sigc::signal<void,Controllable*> Created;
static sigc::signal<void,Controllable*> GoingAway;
-
static sigc::signal<bool,PBD::Controllable*> StartLearning;
static sigc::signal<void,PBD::Controllable*> StopLearning;
sigc::signal<void> Changed;
- const PBD::ID& id() const { return _id; }
-
- int set_state (const XMLNode&) { return 0; }
+ int set_state (const XMLNode&);
XMLNode& get_state ();
+ std::string name() const { return _name; }
+
private:
- PBD::ID _id;
+ std::string _name;
};
}
diff --git a/libs/pbd/pbd/id.h b/libs/pbd/pbd/id.h
index c110362734..eb3691d99e 100644
--- a/libs/pbd/pbd/id.h
+++ b/libs/pbd/pbd/id.h
@@ -27,7 +27,7 @@ class ID {
return _id < other._id;
}
- void print (char* buf) const;
+ void print (char* buf, uint32_t bufsize) const;
std::string to_s() const;
static uint64_t counter() { return _counter; }
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index d905c0bc41..a8a5b6eace 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -39,7 +39,7 @@ using namespace PBD;
#include "i18n.h"
GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
- : ControlProtocol (s, _("GenericMIDI"))
+ : ControlProtocol (s, _("Generic MIDI"))
{
MIDI::Manager* mm = MIDI::Manager::instance();
@@ -173,7 +173,10 @@ GenericMidiControlProtocol::stop_learning (Controllable* c)
XMLNode&
GenericMidiControlProtocol::get_state ()
{
- XMLNode* node = new XMLNode (_name); /* node name must match protocol name */
+ XMLNode* node = new XMLNode ("Protocol");
+
+ node->add_property (X_("name"), _name);
+
XMLNode* children = new XMLNode (X_("controls"));
node->add_child_nocopy (*children);
@@ -215,19 +218,24 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
XMLProperty* prop;
if ((prop = (*niter)->property ("id")) != 0) {
-
+
ID id = prop->value ();
-
+
c = session->controllable_by_id (id);
-
+
if (c) {
MIDIControllable* mc = new MIDIControllable (*_port, *c);
if (mc->set_state (**niter) == 0) {
controllables.insert (mc);
}
+
+ } else {
+ warning << string_compose (_("Generic MIDI control: controllable %1 not found in session (ignored)"),
+ id)
+ << endmsg;
}
}
}
-
+
return 0;
}
diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc
index d6135fd2a8..1cf32f11f6 100644
--- a/libs/surfaces/generic_midi/midicontrollable.cc
+++ b/libs/surfaces/generic_midi/midicontrollable.cc
@@ -345,6 +345,8 @@ MIDIControllable::set_state (const XMLNode& node)
return -1;
}
+ bind_midi (control_channel, control_type, control_additional);
+
return 0;
}
diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.cc b/libs/surfaces/tranzport/tranzport_control_protocol.cc
index 04d56c575c..2e2d943244 100644
--- a/libs/surfaces/tranzport/tranzport_control_protocol.cc
+++ b/libs/surfaces/tranzport/tranzport_control_protocol.cc
@@ -1577,7 +1577,8 @@ TranzportControlProtocol::print (int row, int col, const char *text)
XMLNode&
TranzportControlProtocol::get_state ()
{
- XMLNode* node = new XMLNode (_name); /* node name must match protocol name */
+ XMLNode* node = new XMLNode (X_("Protocol"));
+ node->add_property (X_("name"), _name);
return *node;
}