mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +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");
|
XMLNode* node = new XMLNode ("Editor");
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
_id.print (buf);
|
_id.print (buf, sizeof (buf));
|
||||||
node->add_property ("id", buf);
|
node->add_property ("id", buf);
|
||||||
|
|
||||||
if (is_realized()) {
|
if (is_realized()) {
|
||||||
|
|
|
||||||
|
|
@ -383,13 +383,7 @@ int main (int argc, char *argv[])
|
||||||
cout << _("Ardour/GTK ")
|
cout << _("Ardour/GTK ")
|
||||||
<< VERSIONSTRING
|
<< VERSIONSTRING
|
||||||
<< _("\n (built using ")
|
<< _("\n (built using ")
|
||||||
<< gtk_ardour_major_version << '.'
|
<< ARDOUR::get_ardour_revision ()
|
||||||
<< gtk_ardour_minor_version << '.'
|
|
||||||
<< gtk_ardour_micro_version
|
|
||||||
<< _(" with libardour ")
|
|
||||||
<< libardour_major_version << '.'
|
|
||||||
<< libardour_minor_version << '.'
|
|
||||||
<< libardour_micro_version
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
<< _(" and GCC version ") << __VERSION__
|
<< _(" and GCC version ") << __VERSION__
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ struct ControlProtocolInfo {
|
||||||
bool requested;
|
bool requested;
|
||||||
bool mandatory;
|
bool mandatory;
|
||||||
XMLNode* state;
|
XMLNode* state;
|
||||||
|
|
||||||
|
ControlProtocolInfo() : descriptor (0), protocol (0), state (0) {}
|
||||||
|
~ControlProtocolInfo() { if (state) { delete state; } }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ControlProtocolManager : public sigc::trackable, public Stateful
|
class ControlProtocolManager : public sigc::trackable, public Stateful
|
||||||
|
|
@ -46,6 +49,8 @@ struct ControlProtocolInfo {
|
||||||
|
|
||||||
static const std::string state_node_name;
|
static const std::string state_node_name;
|
||||||
|
|
||||||
|
void set_protocol_states (const XMLNode&);
|
||||||
|
|
||||||
int set_state (const XMLNode&);
|
int set_state (const XMLNode&);
|
||||||
XMLNode& get_state (void);
|
XMLNode& get_state (void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,7 @@ public:
|
||||||
gain_t initial, gain_t target, bool invert_polarity);
|
gain_t initial, gain_t target, bool invert_polarity);
|
||||||
|
|
||||||
struct GainControllable : public PBD::Controllable {
|
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);
|
void set_value (float val);
|
||||||
float get_value (void) const;
|
float get_value (void) const;
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class StreamPanner : public sigc::trackable, public Stateful
|
||||||
bool _muted;
|
bool _muted;
|
||||||
|
|
||||||
struct PanControllable : public PBD::Controllable {
|
struct PanControllable : public PBD::Controllable {
|
||||||
PanControllable (StreamPanner& p) : panner (p) {}
|
PanControllable (std::string name, StreamPanner& p) : Controllable (name), panner (p) {}
|
||||||
|
|
||||||
StreamPanner& panner;
|
StreamPanner& panner;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,8 @@ class Plugin : public PBD::StatefulDestructible, public sigc::trackable
|
||||||
float step;
|
float step;
|
||||||
float smallstep;
|
float smallstep;
|
||||||
float largestep;
|
float largestep;
|
||||||
|
bool min_unbound;
|
||||||
bool min_unbound;
|
bool max_unbound;
|
||||||
bool max_unbound;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual uint32_t unique_id() const = 0;
|
virtual uint32_t unique_id() const = 0;
|
||||||
|
|
@ -162,7 +161,7 @@ class Plugin : public PBD::StatefulDestructible, public sigc::trackable
|
||||||
void setup_controls ();
|
void setup_controls ();
|
||||||
|
|
||||||
struct PortControllable : public PBD::Controllable {
|
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);
|
float lower, float upper, bool toggled, bool logarithmic);
|
||||||
|
|
||||||
void set_value (float);
|
void set_value (float);
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ class Route : public IO
|
||||||
SoloControl
|
SoloControl
|
||||||
};
|
};
|
||||||
|
|
||||||
ToggleControllable (Route&, ToggleType);
|
ToggleControllable (std::string name, Route&, ToggleType);
|
||||||
void set_value (float);
|
void set_value (float);
|
||||||
float get_value (void) const;
|
float get_value (void) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ class AudioRegion;
|
||||||
class Region;
|
class Region;
|
||||||
class Playlist;
|
class Playlist;
|
||||||
class VSTPlugin;
|
class VSTPlugin;
|
||||||
class ControlProtocolManager;
|
class ControlProtocolInfo;
|
||||||
|
|
||||||
struct AudioExportSpecification;
|
struct AudioExportSpecification;
|
||||||
struct RouteGroup;
|
struct RouteGroup;
|
||||||
|
|
@ -415,7 +415,7 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
|
||||||
XMLNode& get_state();
|
XMLNode& get_state();
|
||||||
int set_state(const XMLNode& node); // not idempotent
|
int set_state(const XMLNode& node); // not idempotent
|
||||||
XMLNode& get_template();
|
XMLNode& get_template();
|
||||||
|
|
||||||
void add_instant_xml (XMLNode&, const std::string& dir);
|
void add_instant_xml (XMLNode&, const std::string& dir);
|
||||||
|
|
||||||
enum StateOfTheState {
|
enum StateOfTheState {
|
||||||
|
|
@ -904,6 +904,9 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
|
||||||
|
|
||||||
PBD::Controllable* controllable_by_id (const PBD::ID&);
|
PBD::Controllable* controllable_by_id (const PBD::ID&);
|
||||||
|
|
||||||
|
void add_controllable (PBD::Controllable*);
|
||||||
|
void remove_controllable (PBD::Controllable*);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class AudioEngine;
|
friend class AudioEngine;
|
||||||
void set_block_size (nframes_t nframes);
|
void set_block_size (nframes_t nframes);
|
||||||
|
|
@ -1667,19 +1670,19 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
|
||||||
LayerModel layer_model;
|
LayerModel layer_model;
|
||||||
CrossfadeModel xfade_model;
|
CrossfadeModel xfade_model;
|
||||||
|
|
||||||
typedef std::list<PBD::Controllable*> Controllables;
|
typedef std::set<PBD::Controllable*> Controllables;
|
||||||
Glib::Mutex controllables_lock;
|
Glib::Mutex controllables_lock;
|
||||||
Controllables controllables;
|
Controllables controllables;
|
||||||
|
|
||||||
void add_controllable (PBD::Controllable*);
|
|
||||||
void remove_controllable (PBD::Controllable*);
|
|
||||||
|
|
||||||
|
|
||||||
void reset_native_file_format();
|
void reset_native_file_format();
|
||||||
bool first_file_data_format_reset;
|
bool first_file_data_format_reset;
|
||||||
bool first_file_header_format_reset;
|
bool first_file_header_format_reset;
|
||||||
|
|
||||||
void config_changed (const char*);
|
void config_changed (const char*);
|
||||||
|
|
||||||
|
void add_control_protocol (const ControlProtocolInfo* const, XMLNode*);
|
||||||
|
XMLNode& get_control_protocol_state ();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -1759,7 +1759,7 @@ AudioDiskstream::get_state ()
|
||||||
node->add_property ("speed", buf);
|
node->add_property ("speed", buf);
|
||||||
|
|
||||||
node->add_property("name", _name);
|
node->add_property("name", _name);
|
||||||
id().print (buf);
|
id().print (buf, sizeof (buf));
|
||||||
node->add_property("id", buf);
|
node->add_property("id", buf);
|
||||||
|
|
||||||
if (!capturing_sources.empty() && _session.get_record_enabled()) {
|
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);
|
sscanf (prop->value().c_str(), "%d", &x);
|
||||||
set_remote_control_id (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) {
|
for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
|
||||||
inode = new XMLNode (X_("insert"));
|
inode = new XMLNode (X_("insert"));
|
||||||
(*i)->id.print (buf);
|
(*i)->id.print (buf, sizeof (buf));
|
||||||
inode->add_property (X_("id"), buf);
|
inode->add_property (X_("id"), buf);
|
||||||
inode->add_child_copy ((*i)->state);
|
inode->add_child_copy ((*i)->state);
|
||||||
|
|
||||||
|
|
@ -317,9 +321,11 @@ AudioTrack::state(bool full_state)
|
||||||
diskstream.
|
diskstream.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_diskstream->id().print (buf);
|
_diskstream->id().print (buf, sizeof (buf));
|
||||||
root.add_property ("diskstream-id", buf);
|
root.add_property ("diskstream-id", buf);
|
||||||
|
|
||||||
|
root.add_child_nocopy (_rec_enable_control.get_state());
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -688,7 +688,7 @@ AudioRegion::state (bool full)
|
||||||
|
|
||||||
for (uint32_t n=0; n < sources.size(); ++n) {
|
for (uint32_t n=0; n < sources.size(); ++n) {
|
||||||
snprintf (buf2, sizeof(buf2), "source-%d", 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);
|
node.add_property (buf2, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ ControlProtocolManager::set_session (Session& s)
|
||||||
instantiate (**i);
|
instantiate (**i);
|
||||||
(*i)->requested = false;
|
(*i)->requested = false;
|
||||||
|
|
||||||
if ((*i)->state) {
|
if ((*i)->protocol && (*i)->state) {
|
||||||
(*i)->protocol->set_state (*(*i)->state);
|
(*i)->protocol->set_state (*(*i)->state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +93,10 @@ ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)
|
||||||
Glib::Mutex::Lock lm (protocols_lock);
|
Glib::Mutex::Lock lm (protocols_lock);
|
||||||
control_protocols.push_back (cpi.protocol);
|
control_protocols.push_back (cpi.protocol);
|
||||||
|
|
||||||
|
if (cpi.state) {
|
||||||
|
cpi.protocol->set_state (*cpi.state);
|
||||||
|
}
|
||||||
|
|
||||||
return cpi.protocol;
|
return cpi.protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,7 +158,7 @@ ControlProtocolManager::discover_control_protocols (string path)
|
||||||
vector<string *> *found;
|
vector<string *> *found;
|
||||||
PathScanner scanner;
|
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);
|
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) {
|
for (citer = clist.begin(); citer != clist.end(); ++citer) {
|
||||||
if ((*citer)->name() == X_("Protocol")) {
|
if ((*citer)->name() == X_("Protocol")) {
|
||||||
|
|
||||||
prop = (*citer)->property (X_("active"));
|
prop = (*citer)->property (X_("active"));
|
||||||
|
|
||||||
if (prop && prop->value() == X_("yes")) {
|
if (prop && prop->value() == X_("yes")) {
|
||||||
if ((prop = (*citer)->property (X_("name"))) != 0) {
|
if ((prop = (*citer)->property (X_("name"))) != 0) {
|
||||||
ControlProtocolInfo* cpi = cpi_by_name (prop->value());
|
ControlProtocolInfo* cpi = cpi_by_name (prop->value());
|
||||||
if (cpi) {
|
if (cpi) {
|
||||||
|
|
||||||
|
if (!(*citer)->children().empty()) {
|
||||||
|
cpi->state = (*citer)->children().front ();
|
||||||
|
} else {
|
||||||
|
cpi->state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (_session) {
|
if (_session) {
|
||||||
instantiate (*cpi);
|
instantiate (*cpi);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -294,3 +307,34 @@ ControlProtocolManager::get_state (void)
|
||||||
|
|
||||||
return *root;
|
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];
|
char buf[64];
|
||||||
LocaleGuard lg (X_("POSIX"));
|
LocaleGuard lg (X_("POSIX"));
|
||||||
|
|
||||||
_out->id().print (buf);
|
_out->id().print (buf, sizeof (buf));
|
||||||
node->add_property ("out", buf);
|
node->add_property ("out", buf);
|
||||||
_in->id().print (buf);
|
_in->id().print (buf, sizeof (buf));
|
||||||
node->add_property ("in", buf);
|
node->add_property ("in", buf);
|
||||||
node->add_property ("active", (_active ? "yes" : "no"));
|
node->add_property ("active", (_active ? "yes" : "no"));
|
||||||
node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no"));
|
node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no"));
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ IO::IO (Session& s, string name,
|
||||||
: _session (s),
|
: _session (s),
|
||||||
_name (name),
|
_name (name),
|
||||||
_default_type(default_type),
|
_default_type(default_type),
|
||||||
_gain_control (*this),
|
_gain_control (X_("gaincontrol"), *this),
|
||||||
_gain_automation_curve (0.0, 2.0, 1.0),
|
_gain_automation_curve (0.0, 2.0, 1.0),
|
||||||
_input_minimum (input_min),
|
_input_minimum (input_min),
|
||||||
_input_maximum (input_max),
|
_input_maximum (input_max),
|
||||||
|
|
@ -1431,7 +1431,7 @@ IO::state (bool full_state)
|
||||||
Glib::Mutex::Lock lm (io_lock);
|
Glib::Mutex::Lock lm (io_lock);
|
||||||
|
|
||||||
node->add_property("name", _name);
|
node->add_property("name", _name);
|
||||||
id().print (buf);
|
id().print (buf, sizeof (buf));
|
||||||
node->add_property("id", buf);
|
node->add_property("id", buf);
|
||||||
|
|
||||||
str = "";
|
str = "";
|
||||||
|
|
@ -1513,6 +1513,7 @@ IO::state (bool full_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
node->add_child_nocopy (_panner->state (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());
|
snprintf (buf, sizeof(buf), "%2.12f", gain());
|
||||||
node->add_property ("gain", buf);
|
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) {
|
for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
|
||||||
|
|
||||||
if ((*iter)->name() == "Panner") {
|
if ((*iter)->name() == "Panner") {
|
||||||
_panner->set_state (**iter);
|
_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) {
|
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));
|
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("id", buf);
|
||||||
node->add_property ("name", name());
|
node->add_property ("name", name());
|
||||||
snprintf (buf, sizeof (buf), "%u", start());
|
snprintf (buf, sizeof (buf), "%u", start());
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ static double direct_pan_to_control (pan_t val) {
|
||||||
|
|
||||||
StreamPanner::StreamPanner (Panner& p)
|
StreamPanner::StreamPanner (Panner& p)
|
||||||
: parent (p),
|
: parent (p),
|
||||||
_control (*this)
|
_control (X_("panner"), *this)
|
||||||
{
|
{
|
||||||
_muted = false;
|
_muted = false;
|
||||||
|
|
||||||
|
|
@ -543,6 +543,7 @@ EqualPowerStereoPanner::state (bool full_state)
|
||||||
root->add_property (X_("automation-style"), buf);
|
root->add_property (X_("automation-style"), buf);
|
||||||
|
|
||||||
StreamPanner::add_state (*root);
|
StreamPanner::add_state (*root);
|
||||||
|
root->add_child_nocopy (_control.get_state ());
|
||||||
|
|
||||||
return *root;
|
return *root;
|
||||||
}
|
}
|
||||||
|
|
@ -575,6 +576,13 @@ EqualPowerStereoPanner::set_state (const XMLNode& node)
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamPanner::set_state (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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1420,7 +1420,7 @@ Playlist::state (bool full_state)
|
||||||
|
|
||||||
node->add_property (X_("name"), _name);
|
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_("orig_diskstream_id"), buf);
|
||||||
node->add_property (X_("frozen"), _frozen ? "yes" : "no");
|
node->add_property (X_("frozen"), _frozen ? "yes" : "no");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,15 +95,17 @@ Plugin::get_nth_control (uint32_t n)
|
||||||
Plugin::ParameterDescriptor desc;
|
Plugin::ParameterDescriptor desc;
|
||||||
|
|
||||||
get_parameter_descriptor (n, 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];
|
return controls[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin::PortControllable::PortControllable (Plugin& p, uint32_t port_id, float low, float up, bool t, bool loga)
|
Plugin::PortControllable::PortControllable (string name, Plugin& p, uint32_t port_id,
|
||||||
: plugin (p), absolute_port (port_id)
|
float low, float up, bool t, bool loga)
|
||||||
|
: Controllable (name), plugin (p), absolute_port (port_id)
|
||||||
{
|
{
|
||||||
toggled = t;
|
toggled = t;
|
||||||
logarithmic = loga;
|
logarithmic = loga;
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ Redirect::state (bool full_state)
|
||||||
|
|
||||||
path = _session.snap_name();
|
path = _session.snap_name();
|
||||||
path += "-redirect-";
|
path += "-redirect-";
|
||||||
id().print (buf);
|
id().print (buf, sizeof (buf));
|
||||||
path += buf;
|
path += buf;
|
||||||
path += ".automation";
|
path += ".automation";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -860,7 +860,7 @@ Region::state (bool full_state)
|
||||||
XMLNode *node = new XMLNode ("Region");
|
XMLNode *node = new XMLNode ("Region");
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
_id.print (buf);
|
_id.print (buf, sizeof (buf));
|
||||||
node->add_property ("id", buf);
|
node->add_property ("id", buf);
|
||||||
node->add_property ("name", _name);
|
node->add_property ("name", _name);
|
||||||
snprintf (buf, sizeof (buf), "%u", _start);
|
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)
|
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),
|
: IO (sess, name, input_min, input_max, output_min, output_max, default_type),
|
||||||
_flags (flg),
|
_flags (flg),
|
||||||
_solo_control (*this, ToggleControllable::SoloControl),
|
_solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
|
||||||
_mute_control (*this, ToggleControllable::MuteControl)
|
_mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
Route::Route (Session& sess, const XMLNode& node)
|
Route::Route (Session& sess, const XMLNode& node)
|
||||||
: IO (sess, "route"),
|
: IO (sess, "route"),
|
||||||
_solo_control (*this, ToggleControllable::SoloControl),
|
_solo_control (X_("solo"), *this, ToggleControllable::SoloControl),
|
||||||
_mute_control (*this, ToggleControllable::MuteControl)
|
_mute_control (X_("mute"), *this, ToggleControllable::MuteControl)
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
set_state (node);
|
set_state (node);
|
||||||
|
|
@ -1379,6 +1379,8 @@ Route::state(bool full_state)
|
||||||
node->add_property ("order-keys", order_string);
|
node->add_property ("order-keys", order_string);
|
||||||
|
|
||||||
node->add_child_nocopy (IO::state (full_state));
|
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) {
|
if (_control_outs) {
|
||||||
XMLNode* cnode = new XMLNode (X_("ControlOuts"));
|
XMLNode* cnode = new XMLNode (X_("ControlOuts"));
|
||||||
|
|
@ -1684,6 +1686,12 @@ Route::set_state (const XMLNode& node)
|
||||||
|
|
||||||
} else if (child->name() == "extra") {
|
} else if (child->name() == "extra") {
|
||||||
_extra_xml = new XMLNode (*child);
|
_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::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
|
||||||
: route (s), type(tp)
|
: Controllable (name), route (s), type(tp)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@
|
||||||
#include <ardour/region_factory.h>
|
#include <ardour/region_factory.h>
|
||||||
#include <ardour/source_factory.h>
|
#include <ardour/source_factory.h>
|
||||||
|
|
||||||
|
#include <control_protocol/control_protocol.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include <locale.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));
|
Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
|
||||||
AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
|
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));
|
Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
|
||||||
|
|
||||||
IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
|
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 (_tempo_map->get_state());
|
||||||
|
|
||||||
|
node->add_child_nocopy (get_control_protocol_state());
|
||||||
|
|
||||||
if (_extra_xml) {
|
if (_extra_xml) {
|
||||||
node->add_child_copy (*_extra_xml);
|
node->add_child_copy (*_extra_xml);
|
||||||
}
|
}
|
||||||
|
|
@ -974,6 +977,25 @@ Session::state(bool full_state)
|
||||||
return *node;
|
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
|
int
|
||||||
Session::set_state (const XMLNode& node)
|
Session::set_state (const XMLNode& node)
|
||||||
{
|
{
|
||||||
|
|
@ -1030,6 +1052,7 @@ Session::set_state (const XMLNode& node)
|
||||||
EditGroups
|
EditGroups
|
||||||
MixGroups
|
MixGroups
|
||||||
Click
|
Click
|
||||||
|
ControlProtocols
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (use_config_midi_ports ()) {
|
if (use_config_midi_ports ()) {
|
||||||
|
|
@ -1161,6 +1184,10 @@ Session::set_state (const XMLNode& node)
|
||||||
_click_io->set_state (*child);
|
_click_io->set_state (*child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((child = find_named_node (node, "ControlProtocols")) != 0) {
|
||||||
|
ControlProtocolManager::instance().set_protocol_states (*child);
|
||||||
|
}
|
||||||
|
|
||||||
/* here beginneth the second phase ... */
|
/* here beginneth the second phase ... */
|
||||||
|
|
||||||
StateReady (); /* EMIT SIGNAL */
|
StateReady (); /* EMIT SIGNAL */
|
||||||
|
|
@ -2719,7 +2746,7 @@ void
|
||||||
Session::add_controllable (Controllable* c)
|
Session::add_controllable (Controllable* c)
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lm (controllables_lock);
|
Glib::Mutex::Lock lm (controllables_lock);
|
||||||
controllables.push_back (c);
|
controllables.insert (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2730,7 +2757,12 @@ Session::remove_controllable (Controllable* c)
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::Mutex::Lock lm (controllables_lock);
|
Glib::Mutex::Lock lm (controllables_lock);
|
||||||
controllables.remove (c);
|
|
||||||
|
Controllables::iterator x = controllables.find (c);
|
||||||
|
|
||||||
|
if (x != controllables.end()) {
|
||||||
|
controllables.erase (x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controllable*
|
Controllable*
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ Source::get_state ()
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
node->add_property ("name", _name);
|
node->add_property ("name", _name);
|
||||||
_id.print (buf);
|
_id.print (buf, sizeof (buf));
|
||||||
node->add_property ("id", buf);
|
node->add_property ("id", buf);
|
||||||
|
|
||||||
if (_timestamp != 0) {
|
if (_timestamp != 0) {
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ Track::freeze_state() const
|
||||||
}
|
}
|
||||||
|
|
||||||
Track::RecEnableControllable::RecEnableControllable (Track& s)
|
Track::RecEnableControllable::RecEnableControllable (Track& s)
|
||||||
: track (s)
|
: Controllable (X_("recenable")), track (s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,40 @@
|
||||||
#include <pbd/controllable.h>
|
#include <pbd/controllable.h>
|
||||||
#include <pbd/xml++.h>
|
#include <pbd/xml++.h>
|
||||||
|
#include <pbd/error.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
sigc::signal<void,Controllable*> Controllable::Created;
|
|
||||||
sigc::signal<void,Controllable*> Controllable::GoingAway;
|
sigc::signal<void,Controllable*> Controllable::GoingAway;
|
||||||
sigc::signal<bool,Controllable*> Controllable::StartLearning;
|
sigc::signal<bool,Controllable*> Controllable::StartLearning;
|
||||||
sigc::signal<void,Controllable*> Controllable::StopLearning;
|
sigc::signal<void,Controllable*> Controllable::StopLearning;
|
||||||
|
|
||||||
Controllable::Controllable ()
|
Controllable::Controllable (std::string name)
|
||||||
|
: _name (name)
|
||||||
{
|
{
|
||||||
Created (this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode&
|
XMLNode&
|
||||||
Controllable::get_state ()
|
Controllable::get_state ()
|
||||||
{
|
{
|
||||||
XMLNode* node = new XMLNode (X_("Controllable"));
|
XMLNode* node = new XMLNode (_name);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
_id.print (buf);
|
_id.print (buf, sizeof (buf));
|
||||||
node->add_property (X_("id"), buf);
|
node->add_property (X_("id"), buf);
|
||||||
return *node;
|
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
|
void
|
||||||
ID::print (char* buf) const
|
ID::print (char* buf, uint32_t bufsize) const
|
||||||
{
|
{
|
||||||
/* XXX sizeof buf is unknown. bad API design */
|
snprintf (buf, bufsize, "%" PRIu64, _id);
|
||||||
snprintf (buf, 32, "%" PRIu64, _id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string ID::to_s() const
|
string ID::to_s() const
|
||||||
{
|
{
|
||||||
char buf[32]; // see print()
|
char buf[32]; // see print()
|
||||||
print(buf);
|
print(buf, sizeof (buf));
|
||||||
return string(buf);
|
return string(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +63,7 @@ ostream&
|
||||||
operator<< (ostream& ostr, const ID& _id)
|
operator<< (ostream& ostr, const ID& _id)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
_id.print (buf);
|
_id.print (buf, sizeof (buf));
|
||||||
ostr << buf;
|
ostr << buf;
|
||||||
return ostr;
|
return ostr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef __pbd_controllable_h__
|
#ifndef __pbd_controllable_h__
|
||||||
#define __pbd_controllable_h__
|
#define __pbd_controllable_h__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <sigc++/trackable.h>
|
#include <sigc++/trackable.h>
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
|
||||||
|
|
@ -13,7 +15,7 @@ namespace PBD {
|
||||||
|
|
||||||
class Controllable : public virtual sigc::trackable, public Stateful {
|
class Controllable : public virtual sigc::trackable, public Stateful {
|
||||||
public:
|
public:
|
||||||
Controllable ();
|
Controllable (std::string name);
|
||||||
virtual ~Controllable() { GoingAway (this); }
|
virtual ~Controllable() { GoingAway (this); }
|
||||||
|
|
||||||
virtual void set_value (float) = 0;
|
virtual void set_value (float) = 0;
|
||||||
|
|
@ -23,22 +25,20 @@ class Controllable : public virtual sigc::trackable, public Stateful {
|
||||||
|
|
||||||
sigc::signal<void> LearningFinished;
|
sigc::signal<void> LearningFinished;
|
||||||
|
|
||||||
static sigc::signal<void,Controllable*> Created;
|
|
||||||
static sigc::signal<void,Controllable*> GoingAway;
|
static sigc::signal<void,Controllable*> GoingAway;
|
||||||
|
|
||||||
|
|
||||||
static sigc::signal<bool,PBD::Controllable*> StartLearning;
|
static sigc::signal<bool,PBD::Controllable*> StartLearning;
|
||||||
static sigc::signal<void,PBD::Controllable*> StopLearning;
|
static sigc::signal<void,PBD::Controllable*> StopLearning;
|
||||||
|
|
||||||
sigc::signal<void> Changed;
|
sigc::signal<void> Changed;
|
||||||
|
|
||||||
const PBD::ID& id() const { return _id; }
|
int set_state (const XMLNode&);
|
||||||
|
|
||||||
int set_state (const XMLNode&) { return 0; }
|
|
||||||
XMLNode& get_state ();
|
XMLNode& get_state ();
|
||||||
|
|
||||||
|
std::string name() const { return _name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PBD::ID _id;
|
std::string _name;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class ID {
|
||||||
return _id < other._id;
|
return _id < other._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print (char* buf) const;
|
void print (char* buf, uint32_t bufsize) const;
|
||||||
std::string to_s() const;
|
std::string to_s() const;
|
||||||
|
|
||||||
static uint64_t counter() { return _counter; }
|
static uint64_t counter() { return _counter; }
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ using namespace PBD;
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
||||||
: ControlProtocol (s, _("GenericMIDI"))
|
: ControlProtocol (s, _("Generic MIDI"))
|
||||||
{
|
{
|
||||||
MIDI::Manager* mm = MIDI::Manager::instance();
|
MIDI::Manager* mm = MIDI::Manager::instance();
|
||||||
|
|
||||||
|
|
@ -173,7 +173,10 @@ GenericMidiControlProtocol::stop_learning (Controllable* c)
|
||||||
XMLNode&
|
XMLNode&
|
||||||
GenericMidiControlProtocol::get_state ()
|
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"));
|
XMLNode* children = new XMLNode (X_("controls"));
|
||||||
|
|
||||||
node->add_child_nocopy (*children);
|
node->add_child_nocopy (*children);
|
||||||
|
|
@ -215,19 +218,24 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
|
||||||
XMLProperty* prop;
|
XMLProperty* prop;
|
||||||
|
|
||||||
if ((prop = (*niter)->property ("id")) != 0) {
|
if ((prop = (*niter)->property ("id")) != 0) {
|
||||||
|
|
||||||
ID id = prop->value ();
|
ID id = prop->value ();
|
||||||
|
|
||||||
c = session->controllable_by_id (id);
|
c = session->controllable_by_id (id);
|
||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
MIDIControllable* mc = new MIDIControllable (*_port, *c);
|
MIDIControllable* mc = new MIDIControllable (*_port, *c);
|
||||||
if (mc->set_state (**niter) == 0) {
|
if (mc->set_state (**niter) == 0) {
|
||||||
controllables.insert (mc);
|
controllables.insert (mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
warning << string_compose (_("Generic MIDI control: controllable %1 not found in session (ignored)"),
|
||||||
|
id)
|
||||||
|
<< endmsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,8 @@ MIDIControllable::set_state (const XMLNode& node)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bind_midi (control_channel, control_type, control_additional);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1577,7 +1577,8 @@ TranzportControlProtocol::print (int row, int col, const char *text)
|
||||||
XMLNode&
|
XMLNode&
|
||||||
TranzportControlProtocol::get_state ()
|
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;
|
return *node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue