diff --git a/libs/ardour/ardour/async_midi_port.h b/libs/ardour/ardour/async_midi_port.h index 26946e3016..373d6b7668 100644 --- a/libs/ardour/ardour/async_midi_port.h +++ b/libs/ardour/ardour/async_midi_port.h @@ -57,15 +57,19 @@ class LIBARDOUR_API AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port { void parse (framecnt_t timestamp); int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp); int read (MIDI::byte *buf, size_t bufsize); + /* waits for output to be cleared */ void drain (int check_interval_usecs); - int selectable () const { -#ifdef PLATFORM_WINDOWS - return false; -#else - return xthread.selectable(); -#endif - } + /* clears async request communication channel */ + void clear () { + return xthread.drain (); + } + /* Not selectable; use ios() */ + int selectable() const { return -1; } + + Glib::RefPtr ios() { + return xthread.ios(); + } void set_timer (boost::function&); static void set_process_thread (pthread_t); @@ -80,9 +84,7 @@ class LIBARDOUR_API AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port { RingBuffer< Evoral::Event > output_fifo; Evoral::EventRingBuffer input_fifo; Glib::Threads::Mutex output_fifo_lock; -#ifndef PLATFORM_WINDOWS CrossThreadChannel xthread; -#endif int create_port (); diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc index e00ec587ec..d5a0b2b444 100644 --- a/libs/ardour/midi_ui.cc +++ b/libs/ardour/midi_ui.cc @@ -81,9 +81,10 @@ MidiControlUI::midi_input_handler (IOCondition ioc, AsyncMIDIPort* port) if (ioc & IO_IN) { -#ifndef PLATFORM_WINDOWS - CrossThreadChannel::drain (port->selectable()); -#endif + AsyncMIDIPort* asp = dynamic_cast (port); + if (asp) { + asp->clear (); + } DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", ((ARDOUR::Port*)port)->name())); framepos_t now = _session.engine().sample_time(); @@ -131,12 +132,11 @@ MidiControlUI::reset_ports () return; } - int fd; for (vector::const_iterator pi = ports.begin(); pi != ports.end(); ++pi) { - if ((fd = (*pi)->selectable ()) >= 0) { - Glib::RefPtr psrc = IOSource::create (fd, IO_IN|IO_HUP|IO_ERR); - + Glib::RefPtr psrc = (*pi)->ios(); + + if (psrc) { psrc->connect (sigc::bind (sigc::mem_fun (this, &MidiControlUI::midi_input_handler), *pi)); psrc->attach (_main_loop->get_context()); diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index a2667b8a7d..563ca14d7d 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -41,6 +41,7 @@ #include "pbd/convert.h" #include "ardour/automation_control.h" +#include "ardour/async_midi_port.h" #include "ardour/dB.h" #include "ardour/debug.h" #include "ardour/location.h" @@ -727,11 +728,28 @@ MackieControlProtocol::create_surfaces () session->BundleRemoved (_output_bundle); } - int fd; MIDI::Port& input_port (surface->port().input_port()); + AsyncMIDIPort* asp = dynamic_cast (&input_port); + Glib::RefPtr psrc; + + if (asp) { - if ((fd = input_port.selectable ()) >= 0) { - Glib::RefPtr psrc = IOSource::create (fd, IO_IN|IO_HUP|IO_ERR); + /* async MIDI port */ + + psrc = asp->ios(); + + } else { + + /* ipMIDI port, no IOSource method at this time */ + + int fd; + + if ((fd = input_port.selectable ()) >= 0) { + psrc = IOSource::create (fd, IO_IN|IO_HUP|IO_ERR); + } + } + + if (psrc) { psrc->connect (sigc::bind (sigc::mem_fun (this, &MackieControlProtocol::midi_input_handler), &input_port)); psrc->attach (main_loop()->get_context()); @@ -740,6 +758,16 @@ MackieControlProtocol::create_surfaces () port_sources.push_back (psrc->gobj()); g_source_ref (psrc->gobj()); + + } else { + + if (n == 0) { + error << string_compose (_("Could not create IOSource for Mackie Control surface, MIDI port was called %1"), + input_port.name()); + } else { + error << string_compose (_("Could not create IOSource for Mackie Control extender #%1, MIDI port was called %2"), + n+1, input_port.name()); + } } } @@ -1285,9 +1313,10 @@ MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port) */ if (!_device_info.uses_ipmidi()) { -#ifndef PLATFORM_WINDOWS - CrossThreadChannel::drain (port->selectable()); -#endif + AsyncMIDIPort* asp = dynamic_cast(port); + if (asp) { + asp->clear (); + } } DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name()));