From 326cd24c12d8b11402ef0c10507ecbdea8f86d7f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 20 Feb 2007 21:26:20 +0000 Subject: make MMC work again, make tracing MIDI input work again, add GUI control for MMC device ID ++ git-svn-id: svn://localhost/ardour2/trunk@1480 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/configuration_vars.h | 1 + libs/ardour/ardour/session.h | 5 +- libs/ardour/session_midi.cc | 18 ++++++- libs/ardour/session_state.cc | 12 +++++ libs/midi++2/midi++/mmc.h | 2 + libs/midi++2/midiparser.cc | 6 +-- libs/midi++2/mmc.cc | 4 +- libs/pbd/controllable.cc | 55 ++++++++++++++++++++++ libs/pbd/pbd/controllable.h | 11 +++++ .../generic_midi/generic_midi_control_protocol.cc | 20 ++++++-- libs/surfaces/mackie/mackie_control_protocol.cc | 2 +- 11 files changed, 122 insertions(+), 14 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index c1e59baf35..1296ab0dad 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -18,6 +18,7 @@ CONFIG_VARIABLE (bool, send_mmc, "send-mmc", false) CONFIG_VARIABLE (bool, mmc_control, "mmc-control", false) CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false) CONFIG_VARIABLE (bool, midi_control, "midi-control", false) +CONFIG_VARIABLE (uint8_t, mmc_device_id, "mmc-device-id", 0) /* control surfaces */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index f03a067edf..39bb9c3e68 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -724,6 +724,8 @@ class Session : public PBD::StatefulDestructible void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size); + void set_mmc_device_id (uint32_t id); + /* Scrubbing */ void start_scrub (nframes_t where); @@ -1267,8 +1269,7 @@ class Session : public PBD::StatefulDestructible void mmc_record_pause (MIDI::MachineControl &); void mmc_record_strobe (MIDI::MachineControl &); void mmc_record_exit (MIDI::MachineControl &); - void mmc_track_record_status (MIDI::MachineControl &, - uint32_t track, bool enabled); + void mmc_track_record_status (MIDI::MachineControl &, uint32_t track, bool enabled); void mmc_fast_forward (MIDI::MachineControl &); void mmc_rewind (MIDI::MachineControl &); void mmc_locate (MIDI::MachineControl &, const MIDI::byte *); diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 8a553fb12d..24ba406087 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -126,9 +126,20 @@ Session::set_mtc_port (string port_tag) return 0; } +void +Session::set_mmc_device_id (uint32_t device_id) +{ + if (mmc) { + mmc->set_device_id (device_id); + } +} + int Session::set_mmc_port (string port_tag) { + MIDI::byte old_device_id; + bool reset_id = false; + if (port_tag.length() == 0) { if (_mmc_port == 0) { return 0; @@ -146,6 +157,8 @@ Session::set_mmc_port (string port_tag) _mmc_port = port; if (mmc) { + old_device_id = mmc->device_id(); + reset_id = true; delete mmc; } @@ -153,6 +166,9 @@ Session::set_mmc_port (string port_tag) MMC_CommandSignature, MMC_ResponseSignature); + if (reset_id) { + mmc->set_device_id (old_device_id); + } mmc->Play.connect (mem_fun (*this, &Session::mmc_deferred_play)); @@ -181,6 +197,7 @@ Session::set_mmc_port (string port_tag) mmc->TrackRecordStatusChange.connect (mem_fun (*this, &Session::mmc_record_enable)); + /* also handle MIDI SPP because its so common */ _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start)); @@ -543,7 +560,6 @@ Session::mmc_pause (MIDI::MachineControl &mmc) static bool step_queued = false; void - Session::mmc_step (MIDI::MachineControl &mmc, int steps) { if (!Config->get_mmc_control()) { diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 861e03302f..3c58a448c2 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2832,6 +2832,12 @@ Session::set_deletion_in_progress () void Session::add_controllable (Controllable* c) { + /* this adds a controllable to the list managed by the Session. + this is a subset of those managed by the Controllable class + itself, and represents the only ones whose state will be saved + as part of the session. + */ + Glib::Mutex::Lock lm (controllables_lock); controllables.insert (c); } @@ -3065,6 +3071,12 @@ Session::config_changed (const char* parameter_name) poke_midi_thread (); + } else if (PARAM_IS ("mmc-device-id")) { + + if (mmc) { + mmc->set_device_id (Config->get_mmc_device_id()); + } + } else if (PARAM_IS ("midi-control")) { poke_midi_thread (); diff --git a/libs/midi++2/midi++/mmc.h b/libs/midi++2/midi++/mmc.h index 2d569f122c..23e07f5151 100644 --- a/libs/midi++2/midi++/mmc.h +++ b/libs/midi++2/midi++/mmc.h @@ -93,6 +93,8 @@ class MachineControl : public sigc::trackable Port &port() { return _port; } void set_device_id (byte id); + byte device_id () const { return _device_id; } + static bool is_mmc (byte *sysex_buf, size_t len); /* Signals to connect to if you want to run "callbacks" diff --git a/libs/midi++2/midiparser.cc b/libs/midi++2/midiparser.cc index 424bfa04f8..782c3a8239 100644 --- a/libs/midi++2/midiparser.cc +++ b/libs/midi++2/midiparser.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -138,7 +139,6 @@ Parser::~Parser () void Parser::trace_event (Parser &p, byte *msg, size_t len) - { eventType type; ostream *o; @@ -309,15 +309,13 @@ Parser::trace_event (Parser &p, byte *msg, size_t len) void Parser::trace (bool onoff, ostream *o, const string &prefix) - { trace_connection.disconnect (); if (onoff) { trace_stream = o; trace_prefix = prefix; - trace_connection = any.connect - (mem_fun (*this, &Parser::trace_event)); + trace_connection = any.connect (mem_fun (*this, &Parser::trace_event)); } else { trace_prefix = ""; trace_stream = 0; diff --git a/libs/midi++2/mmc.cc b/libs/midi++2/mmc.cc index 61c47e856f..28d6393fb4 100644 --- a/libs/midi++2/mmc.cc +++ b/libs/midi++2/mmc.cc @@ -202,7 +202,7 @@ MachineControl::MachineControl (Port &p, float version, build_mmc_cmd_map (); - _device_id = 1; + _device_id = 0; if ((parser = _port.input()) != 0) { parser->mmc.connect @@ -258,7 +258,7 @@ MachineControl::process_mmc_message (Parser &p, byte *msg, size_t len) */ #if 0 - cerr << "*** MMC message: len = " << len << "\n\t"; + cerr << "*** me = " << (int) _device_id << " MMC message: len = " << len << "\n\t"; for (size_t i = 0; i < len; i++) { cerr << hex << (int) msg[i] << dec << ' '; } diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc index 049ad0aa21..00638e6c06 100644 --- a/libs/pbd/controllable.cc +++ b/libs/pbd/controllable.cc @@ -10,9 +10,64 @@ sigc::signal Controllable::Destroyed; sigc::signal Controllable::StartLearning; sigc::signal Controllable::StopLearning; +Glib::Mutex* Controllable::registry_lock = 0; +Controllable::Controllables Controllable::registry; + Controllable::Controllable (std::string name) : _name (name) { + if (registry_lock == 0) { + registry_lock = new Glib::Mutex; + } + + add (); +} + +void +Controllable::add () +{ + Glib::Mutex::Lock lm (*registry_lock); + registry.insert (this); + this->GoingAway.connect (mem_fun (this, &Controllable::remove)); +} + +void +Controllable::remove () +{ + Glib::Mutex::Lock lm (*registry_lock); + for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) { + if ((*i) == this) { + registry.erase (i); + break; + } + } +} + +Controllable* +Controllable::by_id (const ID& id) +{ + Glib::Mutex::Lock lm (*registry_lock); + + for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) { + if ((*i)->id() == id) { + return (*i); + } + } + return 0; +} + + +Controllable* +Controllable::by_name (const std::string& str) +{ + Glib::Mutex::Lock lm (*registry_lock); + + for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) { + if ((*i)->_name == str) { + return (*i); + } + } + return 0; } XMLNode& diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h index c88eb298bc..c152013c66 100644 --- a/libs/pbd/pbd/controllable.h +++ b/libs/pbd/pbd/controllable.h @@ -2,6 +2,7 @@ #define __pbd_controllable_h__ #include +#include #include #include @@ -36,8 +37,18 @@ class Controllable : public PBD::StatefulDestructible { std::string name() const { return _name; } + static Controllable* by_id (const PBD::ID&); + static Controllable* by_name (const std::string&); + private: std::string _name; + + void add (); + void remove (); + + typedef std::set Controllables; + static Glib::Mutex* registry_lock; + static Controllables registry; }; } diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index e81a45b47a..2289bc0726 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -171,6 +171,8 @@ void GenericMidiControlProtocol::stop_learning (Controllable* c) { Glib::Mutex::Lock lm (pending_lock); + Glib::Mutex::Lock lm2 (controllables_lock); + MIDIControllable* dptr = 0; /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the relevant MIDIControllable and remove it from the pending list. @@ -179,11 +181,22 @@ GenericMidiControlProtocol::stop_learning (Controllable* c) for (MIDIControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) { if (&(*i)->get_controllable() == c) { (*i)->stop_learning (); - delete (*i); + dptr = *i; pending_controllables.erase (i); break; } } + + for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) { + if (&(*i)->get_controllable() == c) { + controllables.erase (i); + break; + } + } + + if (dptr) { + delete dptr; + } } XMLNode& @@ -255,7 +268,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node) ID id = prop->value (); - c = session->controllable_by_id (id); + c = Controllable::by_id (id); if (c) { MIDIControllable* mc = new MIDIControllable (*_port, *c); @@ -264,8 +277,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node) } } else { - warning << string_compose (_("Generic MIDI control: controllable %1 not found in session (ignored)"), - id) + warning << string_compose (_("Generic MIDI control: controllable %1 not found (ignored)"), id) << endmsg; } } diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index 4763915854..2535c19044 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -1160,7 +1160,7 @@ void MackieControlProtocol::notify_remote_id_changed() if ( sorted.size() - _current_initial_bank < route_signals.size() ) { // but don't shift backwards past the zeroth channel - switch_banks( max( (unsigned int)0, sorted.size() - route_signals.size() ) ); + switch_banks( max(0UL, sorted.size() - route_signals.size() ) ); } // Otherwise just refresh the current bank else -- cgit v1.2.3