X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fardour%2Fmidi_scene_changer.cc;h=7f6c865922cf720602bbb8d9f7d59c7a3ae65222;hb=884cb355230d293233e599bdfebae7f67684a48e;hp=bd32ff308bd27d007beec18e39b6fdfed1f19c63;hpb=11e371c5e7dc90a3814d0425f033db19d8522c59;p=ardour.git diff --git a/libs/ardour/midi_scene_changer.cc b/libs/ardour/midi_scene_changer.cc index bd32ff308b..7f6c865922 100644 --- a/libs/ardour/midi_scene_changer.cc +++ b/libs/ardour/midi_scene_changer.cc @@ -41,7 +41,7 @@ MIDISceneChanger::MIDISceneChanger (Session& s) , 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)); @@ -63,7 +63,7 @@ MIDISceneChanger::locations_changed () } /** Use the session's list of locations to collect all patch changes. - * + * * This is called whenever the locations change in anyway. */ void @@ -86,7 +86,7 @@ MIDISceneChanger::gather (const Locations::LocationList& locations) if (msc->bank() >= 0) { have_seen_bank_changes = true; } - + scenes.insert (std::make_pair ((*l)->start(), msc)); } } @@ -96,6 +96,10 @@ MIDISceneChanger::gather (const Locations::LocationList& locations) void MIDISceneChanger::rt_deliver (MidiBuffer& mbuf, framepos_t when, boost::shared_ptr msc) { + if (!msc->active()) { + return; + } + uint8_t buf[4]; size_t cnt; @@ -121,6 +125,10 @@ MIDISceneChanger::rt_deliver (MidiBuffer& mbuf, framepos_t when, boost::shared_p void MIDISceneChanger::non_rt_deliver (boost::shared_ptr msc) { + if (!msc->active()) { + return; + } + uint8_t buf[4]; size_t cnt; boost::shared_ptr aport = boost::dynamic_pointer_cast(output_port); @@ -129,7 +137,7 @@ 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) { @@ -156,7 +164,7 @@ MIDISceneChanger::run (framepos_t start, framepos_t end) } Glib::Threads::RWLock::ReaderLock lm (scene_lock, Glib::Threads::TRY_LOCK); - + if (!lm.locked()) { return; } @@ -171,9 +179,9 @@ MIDISceneChanger::run (framepos_t start, framepos_t end) if (i->first >= end) { break; } - + rt_deliver (mbuf, i->first - start, i->second); - + ++i; } } @@ -189,9 +197,9 @@ MIDISceneChanger::locate (framepos_t pos) if (scenes.empty()) { return; } - + Scenes::const_iterator i = scenes.lower_bound (pos); - + if (i != scenes.end()) { if (i->first != pos) { @@ -215,25 +223,28 @@ MIDISceneChanger::locate (framepos_t pos) if (msc->program() != last_delivered_program || msc->bank() != last_delivered_bank) { non_rt_deliver (msc); } -} +} void -MIDISceneChanger::set_input_port (MIDI::Port* mp) +MIDISceneChanger::set_input_port (boost::shared_ptr mp) { - input_port = mp; - incoming_connections.drop_connections(); - - if (input_port) { - + input_port.reset (); + + boost::shared_ptr async = boost::dynamic_pointer_cast (mp); + + if (async) { + + input_port = mp; + /* midi port is asynchronous. MIDI parsing will be carried out * by the MIDI UI thread which will emit the relevant signals * and thus invoke our callbacks as necessary. */ for (int channel = 0; channel < 16; ++channel) { - input_port->parser()->channel_bank_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::bank_change_input, this, _1, _2, channel)); - input_port->parser()->channel_program_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::program_change_input, this, _1, _2, channel)); + async->parser()->channel_bank_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::bank_change_input, this, _1, _2, channel)); + async->parser()->channel_program_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::program_change_input, this, _1, _2, channel)); } } } @@ -251,7 +262,7 @@ MIDISceneChanger::set_recording (bool yn) } bool -MIDISceneChanger::recording() const +MIDISceneChanger::recording() const { return _session.transport_rolling() && _session.get_record_enabled(); } @@ -275,12 +286,12 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program if (!recording()) { MIDIInputActivity (); /* EMIT SIGNAL */ - + int bank = -1; if (have_seen_bank_changes) { - bank = input_port->channel (channel)->bank(); + bank = boost::dynamic_pointer_cast(input_port)->channel (channel)->bank(); } - + jump_to (bank, program); return; } @@ -288,29 +299,28 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program Locations* locations (_session.locations ()); Location* loc; bool new_mark = false; - framecnt_t slop = (framecnt_t) floor ((Config->get_inter_scene_gap_msecs() / 1000.0) * _session.frame_rate()); /* check for marker at current location */ - loc = locations->mark_at (time, slop); + loc = locations->mark_at (time, Config->get_inter_scene_gap_frames()); if (!loc) { /* create a new marker at the desired position */ - + std::string new_name; if (!locations->next_available_name (new_name, _("Scene "))) { std::cerr << "No new marker name available\n"; return; } - + loc = new Location (_session, time, time, new_name, Location::IsMark); new_mark = true; } int bank = -1; if (have_seen_bank_changes) { - bank = input_port->channel (channel)->bank(); + bank = boost::dynamic_pointer_cast(input_port)->channel (channel)->bank(); } MIDISceneChange* msc =new MIDISceneChange (channel, bank, program & 0x7f); @@ -329,7 +339,7 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program } loc->set_scene_change (boost::shared_ptr (msc)); - + /* this will generate a "changed" signal to be emitted by locations, and we will call ::gather() to update our list of MIDI events. */