From 98b66b9f3df35f1511a4c1a571aa752013ea303d Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 5 Nov 2014 13:14:10 -0500 Subject: [PATCH] catch up with waves/tracks version of MIDI scene changer code --- libs/ardour/ardour/midi_scene_changer.h | 11 ++++-- libs/ardour/midi_scene_changer.cc | 47 ++++++++++++++++++------- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/libs/ardour/ardour/midi_scene_changer.h b/libs/ardour/ardour/midi_scene_changer.h index a87ea17da4..81a5eb07f0 100644 --- a/libs/ardour/ardour/midi_scene_changer.h +++ b/libs/ardour/ardour/midi_scene_changer.h @@ -43,6 +43,13 @@ class MIDISceneChanger : public SceneChanger void set_recording (bool); void locate (framepos_t); + /** Signal emitted whenever any relevant MIDI input is detected. + */ + PBD::Signal0 MIDIInputActivity; + /** Signal emitted whenever any relevant MIDI output is sent. + */ + PBD::Signal0 MIDIOutputActivity; + private: typedef std::multimap > Scenes; @@ -51,13 +58,13 @@ class MIDISceneChanger : public SceneChanger Glib::Threads::RWLock scene_lock; Scenes scenes; bool _recording; - framepos_t last_bank_message_time; + bool have_seen_bank_changes; framepos_t last_program_message_time; unsigned short current_bank; int last_delivered_program; int last_delivered_bank; - void gather (); + void gather (const Locations::LocationList&); bool recording () const; void jump_to (int bank, int program); void rt_deliver (MidiBuffer&, framepos_t, boost::shared_ptr); diff --git a/libs/ardour/midi_scene_changer.cc b/libs/ardour/midi_scene_changer.cc index 57fca52e53..75a1a98cb7 100644 --- a/libs/ardour/midi_scene_changer.cc +++ b/libs/ardour/midi_scene_changer.cc @@ -36,14 +36,19 @@ using namespace ARDOUR; MIDISceneChanger::MIDISceneChanger (Session& s) : SceneChanger (s) , _recording (true) - , last_bank_message_time (-1) + , have_seen_bank_changes (false) , last_program_message_time (-1) , last_delivered_program (-1) , last_delivered_bank (-1) { + /* catch any add/remove/clear etc. for all Locations */ _session.locations()->changed.connect_same_thread (*this, boost::bind (&MIDISceneChanger::locations_changed, this)); - Location::scene_changed.connect_same_thread (*this, boost::bind (&MIDISceneChanger::gather, this)); + _session.locations()->added.connect_same_thread (*this, boost::bind (&MIDISceneChanger::locations_changed, this)); + _session.locations()->removed.connect_same_thread (*this, boost::bind (&MIDISceneChanger::locations_changed, this)); + + /* catch class-based signal that notifies of us changes in the scene change state of any Location */ + Location::scene_changed.connect_same_thread (*this, boost::bind (&MIDISceneChanger::locations_changed, this)); } MIDISceneChanger::~MIDISceneChanger () @@ -53,7 +58,7 @@ MIDISceneChanger::~MIDISceneChanger () void MIDISceneChanger::locations_changed () { - gather (); + _session.locations()->apply (*this, &MIDISceneChanger::gather); } /** Use the session's list of locations to collect all patch changes. @@ -61,9 +66,8 @@ MIDISceneChanger::locations_changed () * This is called whenever the locations change in anyway. */ void -MIDISceneChanger::gather () +MIDISceneChanger::gather (const Locations::LocationList& locations) { - const Locations::LocationList& locations (_session.locations()->list()); boost::shared_ptr sc; Glib::Threads::RWLock::WriterLock lm (scene_lock); @@ -75,8 +79,13 @@ MIDISceneChanger::gather () if ((sc = (*l)->scene_change()) != 0) { boost::shared_ptr msc = boost::dynamic_pointer_cast (sc); - + if (msc) { + + if (msc->bank() >= 0) { + have_seen_bank_changes = true; + } + scenes.insert (std::make_pair ((*l)->start(), msc)); } } @@ -89,6 +98,8 @@ MIDISceneChanger::rt_deliver (MidiBuffer& mbuf, framepos_t when, boost::shared_p uint8_t buf[4]; size_t cnt; + MIDIOutputActivity (); /* EMIT SIGNAL */ + if ((cnt = msc->get_bank_msb_message (buf, sizeof (buf))) > 0) { mbuf.push_back (when, cnt, buf); @@ -117,6 +128,8 @@ MIDISceneChanger::non_rt_deliver (boost::shared_ptr msc) non-RT/process context. Using zero means "deliver them as early as possible" (practically speaking, in the next process callback). */ + + MIDIOutputActivity (); /* EMIT SIGNAL */ if ((cnt = msc->get_bank_msb_message (buf, sizeof (buf))) > 0) { aport->write (buf, cnt, 0); @@ -243,13 +256,12 @@ MIDISceneChanger::recording() const } void -MIDISceneChanger::bank_change_input (MIDI::Parser& parser, unsigned short, int) + MIDISceneChanger::bank_change_input (MIDI::Parser& /*parser*/, unsigned short, int) { - if (!recording()) { - return; - } - - last_bank_message_time = parser.get_timestamp (); + if (recording()) { + have_seen_bank_changes = true; + } + MIDIInputActivity (); /* EMIT SIGNAL */ } void @@ -260,6 +272,7 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program last_program_message_time = time; if (!recording()) { + MIDIInputActivity (); /* EMIT SIGNAL */ jump_to (input_port->channel (channel)->bank(), program); return; } @@ -287,7 +300,13 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program new_mark = true; } - unsigned short bank = input_port->channel (channel)->bank(); + unsigned short bank; + + if (have_seen_bank_changes) { + bank = input_port->channel (channel)->bank(); + } else { + bank = -1; + } MIDISceneChange* msc =new MIDISceneChange (channel, bank, program & 0x7f); @@ -300,6 +319,8 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program if (new_mark) { locations->add (loc); } + + MIDIInputActivity (); /* EMIT SIGNAL */ } void