diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2006-07-10 20:01:47 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2006-07-10 20:01:47 +0000 |
commit | 26843b34fdd62e6f80630868c5eb3f8fee0c17f1 (patch) | |
tree | fe4001528aa6e4e360ec6392c7b1120ca75e0aa9 /libs/surfaces/generic_midi | |
parent | 05f8fcd189ca714c2c18b9fb174d5813140849df (diff) |
modification to make generic MIDI actually work again
git-svn-id: svn://localhost/ardour2/trunk@673 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/surfaces/generic_midi')
5 files changed, 96 insertions, 14 deletions
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index dec891703e..d905c0bc41 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -20,6 +20,9 @@ #include <algorithm> +#include <pbd/error.h> +#include <pbd/failed_constructor.h> + #include <midi++/port.h> #include <midi++/manager.h> #include <midi++/port_request.h> @@ -39,9 +42,17 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s) : ControlProtocol (s, _("GenericMIDI")) { MIDI::Manager* mm = MIDI::Manager::instance(); - MIDI::PortRequest pr ("ardour:MIDI control", "ardour:MIDI control", "duplex", "alsa/seq"); + + /* XXX it might be nice to run "control" through i18n, but thats a bit tricky because + the name is defined in ardour.rc which is likely not internationalized. + */ - _port = mm->add_port (pr); + _port = mm->port (X_("control")); + + if (_port == 0) { + error << _("no MIDI port named \"control\" exists - generic MIDI control disabled") << endmsg; + throw failed_constructor(); + } _feedback_interval = 10000; // microseconds last_feedback_time = 0; @@ -112,11 +123,13 @@ GenericMidiControlProtocol::start_learning (Controllable* c) MIDIControllable* mc = new MIDIControllable (*_port, *c); - { Glib::Mutex::Lock lm (pending_lock); - pending_controllables.push_back (mc); - mc->learning_stopped.connect (bind (mem_fun (*this, &GenericMidiControlProtocol::learning_stopped), mc)); + std::pair<MIDIControllables::iterator,bool> result; + result = pending_controllables.insert (mc); + if (result.second) { + c->LearningFinished.connect (bind (mem_fun (*this, &GenericMidiControlProtocol::learning_stopped), mc)); + } } mc->learn_about_external_control (); @@ -135,7 +148,7 @@ GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc) pending_controllables.erase (i); } - controllables.push_back (mc); + controllables.insert (mc); } void @@ -156,3 +169,65 @@ GenericMidiControlProtocol::stop_learning (Controllable* c) } } } + +XMLNode& +GenericMidiControlProtocol::get_state () +{ + XMLNode* node = new XMLNode (_name); /* node name must match protocol name */ + XMLNode* children = new XMLNode (X_("controls")); + + node->add_child_nocopy (*children); + + Glib::Mutex::Lock lm2 (controllables_lock); + for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) { + children->add_child_nocopy ((*i)->get_state()); + } + + return *node; +} + +int +GenericMidiControlProtocol::set_state (const XMLNode& node) +{ + XMLNodeList nlist; + XMLNodeConstIterator niter; + Controllable* c; + + { + Glib::Mutex::Lock lm (pending_lock); + pending_controllables.clear (); + } + + Glib::Mutex::Lock lm2 (controllables_lock); + + controllables.clear (); + + nlist = node.children(); + + if (nlist.empty()) { + return 0; + } + + nlist = nlist.front()->children (); + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + + 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); + } + } + } + } + + return 0; +} diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h index f86f5f6434..5f5a470b13 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h @@ -1,7 +1,7 @@ #ifndef ardour_generic_midi_control_protocol_h #define ardour_generic_midi_control_protocol_h -#include <vector> +#include <set> #include <glibmm/thread.h> #include <ardour/types.h> @@ -32,6 +32,9 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol { MIDI::Port* port () const { return _port; } void set_feedback_interval (ARDOUR::microseconds_t); + XMLNode& get_state (); + int set_state (const XMLNode&); + private: MIDI::Port* _port; ARDOUR::microseconds_t _feedback_interval; @@ -40,7 +43,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol { void _send_feedback (); void send_feedback (); - typedef std::vector<MIDIControllable*> MIDIControllables; + typedef std::set<MIDIControllable*> MIDIControllables; MIDIControllables controllables; MIDIControllables pending_controllables; Glib::Mutex controllables_lock; diff --git a/libs/surfaces/generic_midi/interface.cc b/libs/surfaces/generic_midi/interface.cc index c6c59c6589..230be694f2 100644 --- a/libs/surfaces/generic_midi/interface.cc +++ b/libs/surfaces/generic_midi/interface.cc @@ -1,3 +1,5 @@ +#include <pbd/failed_constructor.h> + #include <control_protocol/control_protocol.h> #include "generic_midi_control_protocol.h" @@ -6,7 +8,13 @@ using namespace ARDOUR; ControlProtocol* new_generic_midi_protocol (ControlProtocolDescriptor* descriptor, Session* s) { - GenericMidiControlProtocol* gmcp = new GenericMidiControlProtocol (*s); + GenericMidiControlProtocol* gmcp; + + try { + gmcp = new GenericMidiControlProtocol (*s); + } catch (failed_constructor& err) { + return 0; + } if (gmcp->set_active (true)) { delete gmcp; diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc index f4b7ef665b..d6135fd2a8 100644 --- a/libs/surfaces/generic_midi/midicontrollable.cc +++ b/libs/surfaces/generic_midi/midicontrollable.cc @@ -90,7 +90,6 @@ MIDIControllable::learn_about_external_control () { drop_external_control (); midi_learn_connection = _port.input()->any.connect (mem_fun (*this, &MIDIControllable::midi_receiver)); - learning_started (); } void @@ -199,7 +198,7 @@ MIDIControllable::midi_receiver (Parser &p, byte *msg, size_t len) bind_midi ((channel_t) (msg[0] & 0xf), eventType (msg[0] & 0xF0), msg[1]); - learning_stopped (); + controllable.LearningFinished (); } void diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h index 7dd0be1d87..ab15f9f4ab 100644 --- a/libs/surfaces/generic_midi/midicontrollable.h +++ b/libs/surfaces/generic_midi/midicontrollable.h @@ -53,9 +53,6 @@ class MIDIControllable : public Stateful void stop_learning (); void drop_external_control (); - sigc::signal<void> learning_started; - sigc::signal<void> learning_stopped; - bool get_midi_feedback () { return feedback; } void set_midi_feedback (bool val) { feedback = val; } |