mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
Generic MIDI control now saves+restores its state; PBD::ID now requires a buffer size for its print() method
git-svn-id: svn://localhost/ardour2/trunk@949 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
5ad68cf2c5
commit
ffdf5ada61
31 changed files with 209 additions and 77 deletions
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ Track::freeze_state() const
|
|||
}
|
||||
|
||||
Track::RecEnableControllable::RecEnableControllable (Track& s)
|
||||
: track (s)
|
||||
: Controllable (X_("recenable")), track (s)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,6 +345,8 @@ MIDIControllable::set_state (const XMLNode& node)
|
|||
return -1;
|
||||
}
|
||||
|
||||
bind_midi (control_channel, control_type, control_additional);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue