summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/midi_ui.cc1
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc100
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h11
-rw-r--r--libs/surfaces/mackie/strip.cc22
-rw-r--r--libs/surfaces/mackie/surface.cc11
5 files changed, 116 insertions, 29 deletions
diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc
index 770a371457..fba5d17740 100644
--- a/libs/ardour/midi_ui.cc
+++ b/libs/ardour/midi_ui.cc
@@ -135,6 +135,7 @@ MidiControlUI::reset_ports ()
for (MIDI::Manager::PortList::const_iterator i = plist->begin(); i != plist->end(); ++i) {
if (!(*i)->centrally_parsed()) {
+ cerr << "Skip MIDI port " << (*i)->name() << endl;
continue;
}
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 898075cfb1..331fd4f861 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -42,7 +42,6 @@
#include "ardour/dB.h"
#include "ardour/debug.h"
#include "ardour/location.h"
-#include "ardour/midi_ui.h"
#include "ardour/meter.h"
#include "ardour/panner.h"
#include "ardour/panner_shell.h"
@@ -71,22 +70,23 @@ using namespace ARDOUR;
using namespace std;
using namespace Mackie;
using namespace PBD;
+using namespace Glib;
#include "i18n.h"
#include "pbd/abstract_ui.cc" // instantiate template
-#define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
#define ui_bind(f, ...) boost::protect (boost::bind (f, __VA_ARGS__))
-
extern PBD::EventLoop::InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int);
-#define invalidator(x) __invalidator (*(MidiControlUI::instance()), __FILE__, __LINE__)
+#define invalidator() __invalidator ((*this), __FILE__, __LINE__)
const int MackieControlProtocol::MODIFIER_OPTION = 0x1;
const int MackieControlProtocol::MODIFIER_CONTROL = 0x2;
const int MackieControlProtocol::MODIFIER_SHIFT = 0x3;
const int MackieControlProtocol::MODIFIER_CMDALT = 0x4;
+MackieControlProtocol* MackieControlProtocol::_instance = 0;
+
bool MackieControlProtocol::probe()
{
return true;
@@ -107,9 +107,11 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
AudioEngine::instance()->PortConnectedOrDisconnected.connect (
- audio_engine_connections, invalidator (*this), ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5),
- midi_ui_context ()
+ audio_engine_connections, invalidator (), ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5),
+ this
);
+
+ _instance = this;
}
MackieControlProtocol::~MackieControlProtocol()
@@ -129,13 +131,26 @@ MackieControlProtocol::~MackieControlProtocol()
}
DEBUG_TRACE (DEBUG::MackieControl, "finished ~MackieControlProtocol::MackieControlProtocol\n");
+
+ _instance = 0;
}
void
MackieControlProtocol::thread_init ()
{
+ struct sched_param rtparam;
+
+ pthread_set_name (X_("MackieControl"));
+
PBD::notify_gui_about_thread_creation (X_("gui"), pthread_self(), X_("MackieControl"), 2048);
ARDOUR::SessionEvent::create_per_thread_pool (X_("MackieControl"), 128);
+
+ memset (&rtparam, 0, sizeof (rtparam));
+ rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
+
+ if (pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam) != 0) {
+ // do we care? not particularly.
+ }
}
// go to the previous track.
@@ -307,6 +322,10 @@ MackieControlProtocol::set_active (bool yn)
{
if (yn) {
+ /* start event loop */
+
+ BaseUI::run ();
+
create_surfaces ();
connect_session_signals ();
@@ -432,23 +451,23 @@ void
MackieControlProtocol::connect_session_signals()
{
// receive routes added
- session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_route_added, this, _1), midi_ui_context());
+ session->RouteAdded.connect(session_connections, invalidator(), ui_bind (&MackieControlProtocol::notify_route_added, this, _1), this);
// receive record state toggled
- session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_record_state_changed, this), midi_ui_context());
+ session->RecordStateChanged.connect(session_connections, invalidator(), ui_bind (&MackieControlProtocol::notify_record_state_changed, this), this);
// receive transport state changed
- session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_transport_state_changed, this), midi_ui_context());
+ session->TransportStateChange.connect(session_connections, invalidator(), ui_bind (&MackieControlProtocol::notify_transport_state_changed, this), this);
// receive punch-in and punch-out
- Config->ParameterChanged.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
- session->config.ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), midi_ui_context());
+ Config->ParameterChanged.connect(session_connections, invalidator(), ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), this);
+ session->config.ParameterChanged.connect (session_connections, invalidator(), ui_bind (&MackieControlProtocol::notify_parameter_changed, this, _1), this);
// receive rude solo changed
- session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_solo_active_changed, this, _1), midi_ui_context());
+ session->SoloActive.connect(session_connections, invalidator(), ui_bind (&MackieControlProtocol::notify_solo_active_changed, this, _1), this);
// make sure remote id changed signals reach here
// see also notify_route_added
Sorted sorted = get_sorted_routes();
for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
- (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind(&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
+ (*it)->RemoteControlIDChanged.connect (route_connections, invalidator(), ui_bind(&MackieControlProtocol::notify_remote_id_changed, this), this);
}
}
@@ -480,12 +499,29 @@ MackieControlProtocol::create_surfaces ()
ARDOUR::DataType::MIDI,
session->engine().make_port_name_non_relative (surface->port().output_port().name())
);
+
+ int fd;
+ MIDI::Port& input_port (surface->port().input_port());
+
+ if ((fd = input_port.selectable ()) >= 0) {
+ Glib::RefPtr<IOSource> psrc = IOSource::create (fd, IO_IN|IO_HUP|IO_ERR);
+
+ psrc->connect (sigc::bind (sigc::mem_fun (this, &MackieControlProtocol::midi_input_handler), &input_port));
+ psrc->attach (main_loop()->get_context());
+
+ // glibmm hack: for now, store only the GSource*
+
+ port_sources.push_back (psrc->gobj());
+ g_source_ref (psrc->gobj());
+ }
}
}
void
MackieControlProtocol::close()
{
+ clear_ports ();
+
port_connections.drop_connections ();
session_connections.drop_connections ();
route_connections.drop_connections ();
@@ -658,7 +694,7 @@ MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
typedef ARDOUR::RouteList ARS;
for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) {
- (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::notify_remote_id_changed, this), midi_ui_context());
+ (*it)->RemoteControlIDChanged.connect (route_connections, invalidator(), ui_bind (&MackieControlProtocol::notify_remote_id_changed, this), this);
}
}
@@ -757,7 +793,7 @@ MackieControlProtocol::do_request (MackieControlUIRequest* req)
{
if (req->type == CallSlot) {
- call_slot (MISSING_INVALIDATOR, req->the_slot);
+ call_slot (invalidator(), req->the_slot);
} else if (req->type == Quit) {
@@ -787,7 +823,7 @@ MackieControlProtocol::add_in_use_timeout (Surface& surface, Control& in_use_con
sigc::bind (sigc::mem_fun (*this, &MackieControlProtocol::control_in_use_timeout), &surface, &in_use_control, touch_control));
in_use_control.in_use_touch_control = touch_control;
- timeout->attach (MidiControlUI::instance()->main_loop()->get_context());
+ timeout->attach (main_loop()->get_context());
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout queued for surface %1, control %2 touch control %3\n",
surface.number(), &in_use_control, touch_control));}
@@ -1369,3 +1405,35 @@ MackieControlProtocol::select_track (boost::shared_ptr<Route> r)
}
}
+bool
+MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port)
+{
+ DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", port->name()));
+
+ if (ioc & ~IO_IN) {
+ return false;
+ }
+
+ if (ioc & IO_IN) {
+
+ CrossThreadChannel::drain (port->selectable());
+
+ DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", port->name()));
+ framepos_t now = session->engine().frame_time();
+ port->parse (now);
+ }
+
+ return true;
+}
+
+void
+MackieControlProtocol::clear_ports ()
+{
+ for (PortSources::iterator i = port_sources.begin(); i != port_sources.end(); ++i) {
+ g_source_destroy (*i);
+ g_source_unref (*i);
+ }
+
+ port_sources.clear ();
+}
+
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 2aaa5d43e7..a7601e4bde 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -84,6 +84,8 @@ class MackieControlProtocol
MackieControlProtocol(ARDOUR::Session &);
virtual ~MackieControlProtocol();
+ static MackieControlProtocol* instance() { return _instance; }
+
int set_active (bool yn);
XMLNode& get_state ();
@@ -315,6 +317,8 @@ class MackieControlProtocol
private:
+ static MackieControlProtocol* _instance;
+
void create_surfaces ();
void port_connected_or_disconnected (std::string, std::string, bool);
bool control_in_use_timeout (Mackie::Surface*, Mackie::Control *, Mackie::Control *);
@@ -364,6 +368,13 @@ class MackieControlProtocol
int _modifier_state;
Mackie::MackieMidiBuilder builder;
+
+ typedef std::list<GSource*> PortSources;
+ PortSources port_sources;
+
+ bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
+ void clear_ports ();
+
};
#endif // ardour_mackie_control_protocol_h
diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc
index c9099a86bd..21a312e407 100644
--- a/libs/surfaces/mackie/strip.cc
+++ b/libs/surfaces/mackie/strip.cc
@@ -51,11 +51,11 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-#define midi_ui_context() ARDOUR::MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
+#define ui_context() MackieControlProtocol::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
#define ui_bind(f, ...) boost::protect (boost::bind (f, __VA_ARGS__))
extern PBD::EventLoop::InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int);
-#define invalidator(x) __invalidator (*(MidiControlUI::instance()), __FILE__, __LINE__)
+#define invalidator() __invalidator (*(MackieControlProtocol::instance()), __FILE__, __LINE__)
Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefinition* ctls)
: Group (name)
@@ -237,34 +237,34 @@ Strip::set_route (boost::shared_ptr<Route> r)
if (has_solo()) {
- _route->solo_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_solo_changed, this), midi_ui_context());
+ _route->solo_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_solo_changed, this), ui_context());
}
if (has_mute()) {
- _route->mute_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_mute_changed, this), midi_ui_context());
+ _route->mute_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_mute_changed, this), ui_context());
}
if (has_gain()) {
- _route->gain_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_gain_changed, this, false), midi_ui_context());
+ _route->gain_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_gain_changed, this, false), ui_context());
}
- _route->PropertyChanged.connect (route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_property_changed, this, _1), midi_ui_context());
+ _route->PropertyChanged.connect (route_connections, invalidator(), ui_bind (&Strip::notify_property_changed, this, _1), ui_context());
if (_route->pannable()) {
- _route->pannable()->pan_azimuth_control->Changed.connect(route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_panner_changed, this, false), midi_ui_context());
- _route->pannable()->pan_width_control->Changed.connect(route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_panner_changed, this, false), midi_ui_context());
+ _route->pannable()->pan_azimuth_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context());
+ _route->pannable()->pan_width_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context());
}
boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route);
if (trk) {
- trk->rec_enable_control()->Changed .connect(route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_record_enable_changed, this), midi_ui_context());
+ trk->rec_enable_control()->Changed .connect(route_connections, invalidator(), ui_bind (&Strip::notify_record_enable_changed, this), ui_context());
}
// TODO this works when a currently-banked route is made inactive, but not
// when a route is activated which should be currently banked.
- _route->active_changed.connect (route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_active_changed, this), midi_ui_context());
- _route->DropReferences.connect (route_connections, MISSING_INVALIDATOR, ui_bind (&Strip::notify_route_deleted, this), midi_ui_context());
+ _route->active_changed.connect (route_connections, invalidator(), ui_bind (&Strip::notify_active_changed, this), ui_context());
+ _route->DropReferences.connect (route_connections, invalidator(), ui_bind (&Strip::notify_route_deleted, this), ui_context());
// TODO
// SelectedChanged
diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc
index c23b4c27ca..050f60b9da 100644
--- a/libs/surfaces/mackie/surface.cc
+++ b/libs/surfaces/mackie/surface.cc
@@ -59,8 +59,15 @@ Surface::Surface (MackieControlProtocol& mcp, jack_client_t* jack, const std::st
DEBUG_TRACE (DEBUG::MackieControl, "Surface::init\n");
MIDI::Manager * mm = MIDI::Manager::instance();
- MIDI::Port * input = mm->add_port (new MIDI::Port (string_compose (_("%1 in"), device_name), MIDI::Port::IsInput, jack));
- MIDI::Port * output = mm->add_port (new MIDI::Port (string_compose (_("%1 out"), device_name), MIDI::Port::IsOutput, jack));
+
+ MIDI::Port * input = new MIDI::Port (string_compose (_("%1 in"), device_name), MIDI::Port::IsInput, jack);
+ MIDI::Port * output =new MIDI::Port (string_compose (_("%1 out"), device_name), MIDI::Port::IsOutput, jack);
+
+ input->set_centrally_parsed (false);
+ output->set_centrally_parsed (false);
+
+ mm->add_port (input);
+ mm->add_port (output);
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("surface has ports named %1 and %2\n",
input->name(), output->name()));