#include <float.h>
#include <sys/time.h>
#include <errno.h>
-#include <poll.h>
#include <boost/shared_array.hpp>
#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"
using namespace ARDOUR;
using namespace std;
-using namespace Mackie;
using namespace PBD;
using namespace Glib;
+using namespace ArdourSurface;
+using namespace Mackie;
#include "i18n.h"
, _initialized (false)
, _surfaces_state (0)
, _surfaces_version (0)
+ , _session_load (true)
{
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
if (route_is_locked_to_strip(route)) {
continue;
}
-
+ /* This next section which is not used yet, looks wrong to me
+ The first four belong here but the bottom five are not a selection
+ of routes and belong elsewhere as they are v-pot modes.
+ */
switch (_view_mode) {
case Mixer:
break;
if (_current_initial_bank <= sorted.size()) {
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to %1, %2, available routes %3\n", _current_initial_bank, strip_cnt, sorted.size()));
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to %1, %2, available routes %3 on %4 surfaces\n",
+ _current_initial_bank, strip_cnt, sorted.size(),
+ surfaces.size()));
// link routes to strips
if (!_device_info.has_global_controls()) {
return;
}
-
- boost::shared_ptr<Surface> surface = surfaces.front();
+ // surface needs to be master surface
+ boost::shared_ptr<Surface> surface = _master_surface;
map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (id);
if (x != surface->controls_by_device_independent_id.end()) {
if (!_device_info.has_global_controls()) {
return;
}
-
- boost::shared_ptr<Surface> surface = surfaces.front();
+ boost::shared_ptr<Surface> surface = _master_surface;
map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (id);
}
}
+void
+MackieControlProtocol::device_ready ()
+{
+ /* this is not required to be called, but for devices which do
+ * handshaking, it can be called once the device has verified the
+ * connection.
+ */
+
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("device ready init (active=%1)\n", active()));
+ update_surfaces ();
+}
+
// send messages to surface to set controls to correct values
void
MackieControlProtocol::update_surfaces()
{
- DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::update_surfaces() init\n");
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::update_surfaces() init (active=%1)\n", active()));
if (!active()) {
return;
}
return;
}
- if (!surfaces.front()->active ()) {
+ if (!_master_surface->active ()) {
return;
}
// sometimes the jog wheel is a pot
if (_device_info.has_jog_wheel()) {
- surfaces.front()->blank_jog_ring ();
+ _master_surface->blank_jog_ring ();
}
}
return 0;
}
+gboolean
+ArdourSurface::ipmidi_input_handler (GIOChannel*, GIOCondition condition, void *data)
+{
+ ArdourSurface::MackieControlProtocol::ipMIDIHandler* ipm = static_cast<ArdourSurface::MackieControlProtocol::ipMIDIHandler*>(data);
+ return ipm->mcp->midi_input_handler (Glib::IOCondition (condition), ipm->port);
+}
+
int
MackieControlProtocol::create_surfaces ()
{
string device_name;
- surface_type_t stype = mcu;
+ surface_type_t stype = mcu; // type not yet determined
char buf[128];
if (_device_info.extenders() == 0) {
boost::shared_ptr<Surface> surface;
+ if (n == _device_info.master_position()) {
+ stype = mcu;
+ } else {
+ stype = ext;
+ }
try {
surface.reset (new Surface (*this, device_name, n, stype));
} catch (...) {
return -1;
}
+ if (n == _device_info.master_position()) {
+ _master_surface = surface;
+ }
+
if (_surfaces_state) {
surface->set_state (*_surfaces_state, _surfaces_version);
}
Glib::Threads::Mutex::Lock lm (surfaces_lock);
surfaces.push_back (surface);
}
-
- /* next device will be an extender */
if (_device_info.extenders() < 2) {
device_name = X_("mackie control #2");
snprintf (buf, sizeof (buf), X_("mackie control #%d"), n+2);
device_name = buf;
}
- stype = ext;
if (!_device_info.uses_ipmidi()) {
session->engine().make_port_name_non_relative (surface->port().output_port().name())
);
- session->BundleAdded (_input_bundle);
- session->BundleAdded (_output_bundle);
+ session->BundleAddedOrRemoved ();
} else {
_input_bundle.reset ((ARDOUR::Bundle*) 0);
_output_bundle.reset ((ARDOUR::Bundle*) 0);
- session->BundleRemoved (_input_bundle);
- session->BundleRemoved (_output_bundle);
+ session->BundleAddedOrRemoved ();
}
- int fd;
MIDI::Port& input_port (surface->port().input_port());
+ AsyncMIDIPort* asp = dynamic_cast<AsyncMIDIPort*> (&input_port);
- if ((fd = input_port.selectable ()) >= 0) {
- Glib::RefPtr<IOSource> psrc = IOSource::create (fd, IO_IN|IO_HUP|IO_ERR);
+ if (asp) {
- 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*
+ /* async MIDI port */
- port_sources.push_back (psrc->gobj());
- g_source_ref (psrc->gobj());
+ asp->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &MackieControlProtocol::midi_input_handler), &input_port));
+ asp->xthread().attach (main_loop()->get_context());
+
+ } else {
+
+ /* ipMIDI port, no IOSource method at this time */
+
+ int fd;
+
+ if ((fd = input_port.selectable ()) >= 0) {
+
+ GIOChannel* ioc = g_io_channel_unix_new (fd);
+ GSource* gsrc = g_io_create_watch (ioc, GIOCondition (G_IO_IN|G_IO_HUP|G_IO_ERR));
+
+ /* hack up an object so that in the callback from the event loop
+ we have both the MackieControlProtocol and the input port.
+
+ If we were using C++ for this stuff we wouldn't need this
+ but a nasty, not-fixable bug in the binding between C
+ and C++ makes it necessary to avoid C++ for the IO
+ callback setup.
+ */
+
+ ipMIDIHandler* ipm = new ipMIDIHandler (); /* we will leak this sizeof(pointer)*2 sized object */
+ ipm->mcp = this;
+ ipm->port = &input_port;
+
+ g_source_set_callback (gsrc, (GSourceFunc) ipmidi_input_handler, ipm, NULL);
+ g_source_attach (gsrc, main_loop()->get_context()->gobj());
+ }
}
}
const XMLProperty* prop;
uint32_t bank = 0;
+ if (ControlProtocol::set_state (node, version)) {
+ return -1;
+ }
+
if ((prop = node.property (X_("ipmidi-base"))) != 0) {
set_ipmidi_base (atoi (prop->value()));
}
return;
}
- boost::shared_ptr<Surface> surface = surfaces.front();
+ boost::shared_ptr<Surface> surface = _master_surface;
if (surface->type() != mcu || !_device_info.has_timecode_display() || !surface->active ()) {
return;
void MackieControlProtocol::notify_parameter_changed (std::string const & p)
{
if (p == "punch-in") {
- update_global_button (Button::PunchIn, session->config.get_punch_in());
+ // no such button right now
+ // update_global_button (Button::PunchIn, session->config.get_punch_in());
} else if (p == "punch-out") {
- update_global_button (Button::PunchOut, session->config.get_punch_out());
+ // no such button right now
+ // update_global_button (Button::PunchOut, session->config.get_punch_out());
} else if (p == "clicking") {
// update_global_button (Button::RelayClick, Config->get_clicking());
} else {
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
- surface = surfaces.front ();
+ surface = _master_surface;
}
map<int,Control*>::iterator x = surface->controls_by_device_independent_id.find (Led::RudeSolo);
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
- surface = surfaces.front();
+ surface = _master_surface;
}
/* rec is a tristate */
#define DEFINE_BUTTON_HANDLER(b,p,r) button_map.insert (pair<Button::ID,ButtonHandlers> ((b), ButtonHandlers ((p),(r))));
- DEFINE_BUTTON_HANDLER (Button::IO, &MackieControlProtocol::io_press, &MackieControlProtocol::io_release);
- DEFINE_BUTTON_HANDLER (Button::Sends, &MackieControlProtocol::sends_press, &MackieControlProtocol::sends_release);
+ DEFINE_BUTTON_HANDLER (Button::Track, &MackieControlProtocol::track_press, &MackieControlProtocol::track_release);
+ DEFINE_BUTTON_HANDLER (Button::Send, &MackieControlProtocol::send_press, &MackieControlProtocol::send_release);
DEFINE_BUTTON_HANDLER (Button::Pan, &MackieControlProtocol::pan_press, &MackieControlProtocol::pan_release);
DEFINE_BUTTON_HANDLER (Button::Plugin, &MackieControlProtocol::plugin_press, &MackieControlProtocol::plugin_release);
DEFINE_BUTTON_HANDLER (Button::Eq, &MackieControlProtocol::eq_press, &MackieControlProtocol::eq_release);
DEFINE_BUTTON_HANDLER (Button::ChannelLeft, &MackieControlProtocol::channel_left_press, &MackieControlProtocol::channel_left_release);
DEFINE_BUTTON_HANDLER (Button::ChannelRight, &MackieControlProtocol::channel_right_press, &MackieControlProtocol::channel_right_release);
DEFINE_BUTTON_HANDLER (Button::Flip, &MackieControlProtocol::flip_press, &MackieControlProtocol::flip_release);
- DEFINE_BUTTON_HANDLER (Button::Edit, &MackieControlProtocol::edit_press, &MackieControlProtocol::edit_release);
+ DEFINE_BUTTON_HANDLER (Button::View, &MackieControlProtocol::view_press, &MackieControlProtocol::view_release);
DEFINE_BUTTON_HANDLER (Button::NameValue, &MackieControlProtocol::name_value_press, &MackieControlProtocol::name_value_release);
DEFINE_BUTTON_HANDLER (Button::TimecodeBeats, &MackieControlProtocol::timecode_beats_press, &MackieControlProtocol::timecode_beats_release);
DEFINE_BUTTON_HANDLER (Button::F1, &MackieControlProtocol::F1_press, &MackieControlProtocol::F1_release);
DEFINE_BUTTON_HANDLER (Button::F6, &MackieControlProtocol::F6_press, &MackieControlProtocol::F6_release);
DEFINE_BUTTON_HANDLER (Button::F7, &MackieControlProtocol::F7_press, &MackieControlProtocol::F7_release);
DEFINE_BUTTON_HANDLER (Button::F8, &MackieControlProtocol::F8_press, &MackieControlProtocol::F8_release);
- DEFINE_BUTTON_HANDLER (Button::F9, &MackieControlProtocol::F9_press, &MackieControlProtocol::F9_release);
- DEFINE_BUTTON_HANDLER (Button::F10, &MackieControlProtocol::F10_press, &MackieControlProtocol::F10_release);
- DEFINE_BUTTON_HANDLER (Button::F11, &MackieControlProtocol::F11_press, &MackieControlProtocol::F11_release);
- DEFINE_BUTTON_HANDLER (Button::F12, &MackieControlProtocol::F12_press, &MackieControlProtocol::F12_release);
- DEFINE_BUTTON_HANDLER (Button::F13, &MackieControlProtocol::F13_press, &MackieControlProtocol::F13_release);
- DEFINE_BUTTON_HANDLER (Button::F14, &MackieControlProtocol::F14_press, &MackieControlProtocol::F14_release);
- DEFINE_BUTTON_HANDLER (Button::F15, &MackieControlProtocol::F15_press, &MackieControlProtocol::F15_release);
- DEFINE_BUTTON_HANDLER (Button::F16, &MackieControlProtocol::F16_press, &MackieControlProtocol::F16_release);
+ DEFINE_BUTTON_HANDLER (Button::MidiTracks, &MackieControlProtocol::miditracks_press, &MackieControlProtocol::miditracks_release);
+ DEFINE_BUTTON_HANDLER (Button::Inputs, &MackieControlProtocol::inputs_press, &MackieControlProtocol::inputs_release);
+ DEFINE_BUTTON_HANDLER (Button::AudioTracks, &MackieControlProtocol::audiotracks_press, &MackieControlProtocol::audiotracks_release);
+ DEFINE_BUTTON_HANDLER (Button::AudioInstruments, &MackieControlProtocol::audioinstruments_press, &MackieControlProtocol::audioinstruments_release);
+ DEFINE_BUTTON_HANDLER (Button::Aux, &MackieControlProtocol::aux_press, &MackieControlProtocol::aux_release);
+ DEFINE_BUTTON_HANDLER (Button::Busses, &MackieControlProtocol::busses_press, &MackieControlProtocol::busses_release);
+ DEFINE_BUTTON_HANDLER (Button::Outputs, &MackieControlProtocol::outputs_press, &MackieControlProtocol::outputs_release);
+ DEFINE_BUTTON_HANDLER (Button::User, &MackieControlProtocol::user_press, &MackieControlProtocol::user_release);
DEFINE_BUTTON_HANDLER (Button::Shift, &MackieControlProtocol::shift_press, &MackieControlProtocol::shift_release);
DEFINE_BUTTON_HANDLER (Button::Option, &MackieControlProtocol::option_press, &MackieControlProtocol::option_release);
DEFINE_BUTTON_HANDLER (Button::Ctrl, &MackieControlProtocol::control_press, &MackieControlProtocol::control_release);
DEFINE_BUTTON_HANDLER (Button::CmdAlt, &MackieControlProtocol::cmd_alt_press, &MackieControlProtocol::cmd_alt_release);
- DEFINE_BUTTON_HANDLER (Button::On, &MackieControlProtocol::on_press, &MackieControlProtocol::on_release);
- DEFINE_BUTTON_HANDLER (Button::RecReady, &MackieControlProtocol::rec_ready_press, &MackieControlProtocol::rec_ready_release);
- DEFINE_BUTTON_HANDLER (Button::Undo, &MackieControlProtocol::undo_press, &MackieControlProtocol::undo_release);
- DEFINE_BUTTON_HANDLER (Button::Save, &MackieControlProtocol::save_press, &MackieControlProtocol::save_release);
+ DEFINE_BUTTON_HANDLER (Button::Read, &MackieControlProtocol::read_press, &MackieControlProtocol::read_release);
+ DEFINE_BUTTON_HANDLER (Button::Write, &MackieControlProtocol::write_press, &MackieControlProtocol::write_release);
+ DEFINE_BUTTON_HANDLER (Button::Trim, &MackieControlProtocol::trim_press, &MackieControlProtocol::trim_release);
DEFINE_BUTTON_HANDLER (Button::Touch, &MackieControlProtocol::touch_press, &MackieControlProtocol::touch_release);
- DEFINE_BUTTON_HANDLER (Button::Redo, &MackieControlProtocol::redo_press, &MackieControlProtocol::redo_release);
- DEFINE_BUTTON_HANDLER (Button::Marker, &MackieControlProtocol::marker_press, &MackieControlProtocol::marker_release);
- DEFINE_BUTTON_HANDLER (Button::Enter, &MackieControlProtocol::enter_press, &MackieControlProtocol::enter_release);
+ DEFINE_BUTTON_HANDLER (Button::Latch, &MackieControlProtocol::latch_press, &MackieControlProtocol::latch_release);
+ DEFINE_BUTTON_HANDLER (Button::Grp, &MackieControlProtocol::grp_press, &MackieControlProtocol::grp_release);
+ DEFINE_BUTTON_HANDLER (Button::Save, &MackieControlProtocol::save_press, &MackieControlProtocol::save_release);
+ DEFINE_BUTTON_HANDLER (Button::Undo, &MackieControlProtocol::undo_press, &MackieControlProtocol::undo_release);
DEFINE_BUTTON_HANDLER (Button::Cancel, &MackieControlProtocol::cancel_press, &MackieControlProtocol::cancel_release);
- DEFINE_BUTTON_HANDLER (Button::Mixer, &MackieControlProtocol::mixer_press, &MackieControlProtocol::mixer_release);
- DEFINE_BUTTON_HANDLER (Button::FrmLeft, &MackieControlProtocol::frm_left_press, &MackieControlProtocol::frm_left_release);
- DEFINE_BUTTON_HANDLER (Button::FrmRight, &MackieControlProtocol::frm_right_press, &MackieControlProtocol::frm_right_release);
+ DEFINE_BUTTON_HANDLER (Button::Enter, &MackieControlProtocol::enter_press, &MackieControlProtocol::enter_release);
+ DEFINE_BUTTON_HANDLER (Button::Marker, &MackieControlProtocol::marker_press, &MackieControlProtocol::marker_release);
+ DEFINE_BUTTON_HANDLER (Button::Nudge, &MackieControlProtocol::nudge_press, &MackieControlProtocol::nudge_release);
DEFINE_BUTTON_HANDLER (Button::Loop, &MackieControlProtocol::loop_press, &MackieControlProtocol::loop_release);
- DEFINE_BUTTON_HANDLER (Button::PunchIn, &MackieControlProtocol::punch_in_press, &MackieControlProtocol::punch_in_release);
- DEFINE_BUTTON_HANDLER (Button::PunchOut, &MackieControlProtocol::punch_out_press, &MackieControlProtocol::punch_out_release);
- DEFINE_BUTTON_HANDLER (Button::Home, &MackieControlProtocol::home_press, &MackieControlProtocol::home_release);
- DEFINE_BUTTON_HANDLER (Button::End, &MackieControlProtocol::end_press, &MackieControlProtocol::end_release);
+ DEFINE_BUTTON_HANDLER (Button::Drop, &MackieControlProtocol::drop_press, &MackieControlProtocol::drop_release);
+ DEFINE_BUTTON_HANDLER (Button::Replace, &MackieControlProtocol::replace_press, &MackieControlProtocol::replace_release);
+ DEFINE_BUTTON_HANDLER (Button::Click, &MackieControlProtocol::click_press, &MackieControlProtocol::click_release);
+ DEFINE_BUTTON_HANDLER (Button::ClearSolo, &MackieControlProtocol::clearsolo_press, &MackieControlProtocol::clearsolo_release);
DEFINE_BUTTON_HANDLER (Button::Rewind, &MackieControlProtocol::rewind_press, &MackieControlProtocol::rewind_release);
DEFINE_BUTTON_HANDLER (Button::Ffwd, &MackieControlProtocol::ffwd_press, &MackieControlProtocol::ffwd_release);
DEFINE_BUTTON_HANDLER (Button::Stop, &MackieControlProtocol::stop_press, &MackieControlProtocol::stop_release);
DEFINE_BUTTON_HANDLER (Button::UserB, &MackieControlProtocol::user_b_press, &MackieControlProtocol::user_b_release);
DEFINE_BUTTON_HANDLER (Button::MasterFaderTouch, &MackieControlProtocol::master_fader_touch_press, &MackieControlProtocol::master_fader_touch_release);
- DEFINE_BUTTON_HANDLER (Button::Snapshot, &MackieControlProtocol::snapshot_press, &MackieControlProtocol::snapshot_release);
- DEFINE_BUTTON_HANDLER (Button::Read, &MackieControlProtocol::read_press, &MackieControlProtocol::read_release);
- DEFINE_BUTTON_HANDLER (Button::Write, &MackieControlProtocol::write_press, &MackieControlProtocol::write_release);
- DEFINE_BUTTON_HANDLER (Button::FdrGroup, &MackieControlProtocol::fdrgroup_press, &MackieControlProtocol::fdrgroup_release);
- DEFINE_BUTTON_HANDLER (Button::ClearSolo, &MackieControlProtocol::clearsolo_press, &MackieControlProtocol::clearsolo_release);
- DEFINE_BUTTON_HANDLER (Button::Track, &MackieControlProtocol::track_press, &MackieControlProtocol::track_release);
- DEFINE_BUTTON_HANDLER (Button::Send, &MackieControlProtocol::send_press, &MackieControlProtocol::send_release);
- DEFINE_BUTTON_HANDLER (Button::MidiTracks, &MackieControlProtocol::miditracks_press, &MackieControlProtocol::miditracks_release);
- DEFINE_BUTTON_HANDLER (Button::Inputs, &MackieControlProtocol::inputs_press, &MackieControlProtocol::inputs_release);
- DEFINE_BUTTON_HANDLER (Button::AudioTracks, &MackieControlProtocol::audiotracks_press, &MackieControlProtocol::audiotracks_release);
- DEFINE_BUTTON_HANDLER (Button::AudioInstruments, &MackieControlProtocol::audioinstruments_press, &MackieControlProtocol::audioinstruments_release);
- DEFINE_BUTTON_HANDLER (Button::Aux, &MackieControlProtocol::aux_press, &MackieControlProtocol::aux_release);
- DEFINE_BUTTON_HANDLER (Button::Busses, &MackieControlProtocol::busses_press, &MackieControlProtocol::busses_release);
- DEFINE_BUTTON_HANDLER (Button::Outputs, &MackieControlProtocol::outputs_press, &MackieControlProtocol::outputs_release);
- DEFINE_BUTTON_HANDLER (Button::User, &MackieControlProtocol::user_press, &MackieControlProtocol::user_release);
- DEFINE_BUTTON_HANDLER (Button::Trim, &MackieControlProtocol::trim_press, &MackieControlProtocol::trim_release);
- DEFINE_BUTTON_HANDLER (Button::Latch, &MackieControlProtocol::latch_press, &MackieControlProtocol::latch_release);
- DEFINE_BUTTON_HANDLER (Button::Grp, &MackieControlProtocol::grp_press, &MackieControlProtocol::grp_release);
- DEFINE_BUTTON_HANDLER (Button::Nudge, &MackieControlProtocol::nudge_press, &MackieControlProtocol::nudge_release);
- DEFINE_BUTTON_HANDLER (Button::Drop, &MackieControlProtocol::drop_press, &MackieControlProtocol::drop_release);
- DEFINE_BUTTON_HANDLER (Button::Replace, &MackieControlProtocol::replace_press, &MackieControlProtocol::replace_release);
- DEFINE_BUTTON_HANDLER (Button::Click, &MackieControlProtocol::click_press, &MackieControlProtocol::click_release);
- DEFINE_BUTTON_HANDLER (Button::View, &MackieControlProtocol::view_press, &MackieControlProtocol::view_release);
}
void
*/
if (!_device_info.uses_ipmidi()) {
- CrossThreadChannel::drain (port->selectable());
+ AsyncMIDIPort* asp = dynamic_cast<AsyncMIDIPort*>(port);
+ if (asp) {
+ asp->clear ();
+ }
}
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name()));
_input_bundle->remove_channels ();
_output_bundle->remove_channels ();
}
-
- for (PortSources::iterator i = port_sources.begin(); i != port_sources.end(); ++i) {
- g_source_destroy (*i);
- g_source_unref (*i);
- }
-
- port_sources.clear ();
}
void