#include <float.h>
#include <sys/time.h>
#include <errno.h>
-#include <poll.h>
#include <boost/shared_array.hpp>
, AbstractUI<MackieControlUIRequest> ("mackie")
, _current_initial_bank (0)
, _timecode_type (ARDOUR::AnyTime::BBT)
- , _input_bundle (new ARDOUR::Bundle (_("Mackie Control In"), true))
- , _output_bundle (new ARDOUR::Bundle (_("Mackie Control Out"), false))
, _gui (0)
, _zoom_mode (false)
, _scrub_mode (false)
- , _flip_mode (false)
+ , _flip_mode (Normal)
, _view_mode (Mixer)
, _current_selected_track (-1)
, _modifier_state (0)
, needs_ipmidi_restart (false)
, _metering_active (true)
, _initialized (false)
+ , _surfaces_state (0)
+ , _surfaces_version (0)
{
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol tear_down_gui ()\n");
tear_down_gui ();
- _active = false;
+ delete _surfaces_state;
/* stop event loop */
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::~MackieControlProtocol BaseUI::quit ()\n");
for (Surfaces::const_iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
(*si)->say_hello ();
}
+
+ if (_device_info.no_handshake()) {
+ for (Surfaces::const_iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
+ (*si)->turn_it_on ();
+ }
+ }
}
// go to the previous track.
continue;
}
- if (route->is_hidden() || route->is_master() || route->is_monitor()) {
+ if (route->is_auditioner() || route->is_master() || route->is_monitor()) {
continue;
}
{
DEBUG_TRACE (DEBUG::MackieControl, string_compose("MackieControlProtocol::set_active init with yn: '%1'\n", yn));
- if (yn == _active) {
+ if (yn == active()) {
return 0;
}
BaseUI::run ();
- create_surfaces ();
+ if (create_surfaces ()) {
+ return -1;
+ }
connect_session_signals ();
- _active = true;
update_surfaces ();
/* set up periodic task for metering and automation
BaseUI::quit ();
close ();
- _active = false;
}
+ ControlProtocol::set_active (yn);
+
DEBUG_TRACE (DEBUG::MackieControl, string_compose("MackieControlProtocol::set_active done with yn: '%1'\n", yn));
return 0;
bool
MackieControlProtocol::periodic ()
{
- if (!_active) {
+ if (!active()) {
return false;
}
MackieControlProtocol::update_surfaces()
{
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::update_surfaces() init\n");
- if (!_active) {
+ if (!active()) {
return;
}
void
MackieControlProtocol::initialize()
{
- Glib::Threads::Mutex::Lock lm (surfaces_lock);
-
- if (surfaces.empty()) {
- return;
- }
-
- if (!surfaces.front()->active ()) {
- return;
+ {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ if (surfaces.empty()) {
+ return;
+ }
+
+ if (!surfaces.front()->active ()) {
+ return;
+ }
+
+ // sometimes the jog wheel is a pot
+ if (_device_info.has_jog_wheel()) {
+ surfaces.front()->blank_jog_ring ();
+ }
}
- // sometimes the jog wheel is a pot
- if (_device_info.has_jog_wheel()) {
- surfaces.front()->blank_jog_ring ();
- }
-
// update global buttons and displays
notify_record_state_changed();
_device_profile = d->second;
}
-void
-MackieControlProtocol::set_device (const string& device_name, bool allow_activation)
+int
+MackieControlProtocol::set_device_info (const string& device_name)
{
map<string,DeviceInfo>::iterator d = DeviceInfo::device_info.find (device_name);
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("new device chosen %1, activation allowed ? %2\n",
- device_name, allow_activation));
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("new device chosen %1\n", device_name));
if (d == DeviceInfo::device_info.end()) {
- return;
+ return -1;
}
- if (_active) {
- clear_ports ();
- clear_surfaces ();
+ _device_info = d->second;
+
+ return 0;
+}
+
+int
+MackieControlProtocol::set_device (const string& device_name)
+{
+ if (set_device_info (device_name)) {
+ return -1;
}
- _device_info = d->second;
+ clear_surfaces ();
- if (allow_activation) {
- set_active (true);
- } else {
- if (_active) {
- create_surfaces ();
- switch_banks (0, true);
- }
+ if (create_surfaces ()) {
+ return -1;
}
+
+ switch_banks (0, true);
+
+ return 0;
}
-void
+int
MackieControlProtocol::create_surfaces ()
{
string device_name;
for (uint32_t n = 0; n < 1 + _device_info.extenders(); ++n) {
- boost::shared_ptr<Surface> surface (new Surface (*this, device_name, n, stype));
+ boost::shared_ptr<Surface> surface;
+
+ try {
+ surface.reset (new Surface (*this, device_name, n, stype));
+ } catch (...) {
+ return -1;
+ }
+
+ if (_surfaces_state) {
+ surface->set_state (*_surfaces_state, _surfaces_version);
+ }
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
stype = ext;
if (!_device_info.uses_ipmidi()) {
+
+ _input_bundle.reset (new ARDOUR::Bundle (_("Mackie Control In"), true));
+ _output_bundle.reset (new ARDOUR::Bundle (_("Mackie Control Out"), false));
+
_input_bundle->add_channel (
surface->port().input_port().name(),
ARDOUR::DataType::MIDI,
ARDOUR::DataType::MIDI,
session->engine().make_port_name_non_relative (surface->port().output_port().name())
);
+
+ session->BundleAdded (_input_bundle);
+ session->BundleAdded (_output_bundle);
+
+ } else {
+ _input_bundle.reset ((ARDOUR::Bundle*) 0);
+ _output_bundle.reset ((ARDOUR::Bundle*) 0);
+
+ session->BundleRemoved (_input_bundle);
+ session->BundleRemoved (_output_bundle);
}
int fd;
g_source_ref (psrc->gobj());
}
}
+
+ return 0;
}
void
MackieControlProtocol::close()
{
- clear_ports ();
-
- port_connections.drop_connections ();
session_connections.drop_connections ();
route_connections.drop_connections ();
periodic_connection.disconnect ();
XMLNode&
MackieControlProtocol::get_state()
{
+ XMLNode& node (ControlProtocol::get_state());
+
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state init\n");
char buf[16];
- // add name of protocol
- XMLNode* node = new XMLNode (X_("Protocol"));
- node->add_property (X_("name"), ARDOUR::ControlProtocol::_name);
-
// add current bank
snprintf (buf, sizeof (buf), "%d", _current_initial_bank);
- node->add_property (X_("bank"), buf);
+ node.add_property (X_("bank"), buf);
// ipMIDI base port (possibly not used)
snprintf (buf, sizeof (buf), "%d", _ipmidi_base);
- node->add_property (X_("ipmidi-base"), buf);
+ node.add_property (X_("ipmidi-base"), buf);
+
+ node.add_property (X_("device-profile"), _device_profile.name());
+ node.add_property (X_("device-name"), _device_info.name());
- node->add_property (X_("device-profile"), _device_profile.name());
- node->add_property (X_("device-name"), _device_info.name());
+ XMLNode* snode = new XMLNode (X_("Surfaces"));
+ for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ snode->add_child_nocopy ((*s)->get_state());
+ }
+
+ node.add_child_nocopy (*snode);
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state done\n");
- return *node;
+ return node;
}
int
-MackieControlProtocol::set_state (const XMLNode & node, int /*version*/)
+MackieControlProtocol::set_state (const XMLNode & node, int version)
{
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::set_state: active %1\n", _active));
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieControlProtocol::set_state: active %1\n", active()));
int retval = 0;
const XMLProperty* prop;
uint32_t bank = 0;
- bool active = _active;
if ((prop = node.property (X_("ipmidi-base"))) != 0) {
set_ipmidi_base (atoi (prop->value()));
bank = atoi (prop->value());
}
- if ((prop = node.property (X_("active"))) != 0) {
- active = string_is_affirmative (prop->value());
- }
-
if ((prop = node.property (X_("device-name"))) != 0) {
- set_device (prop->value(), false);
+ set_device_info (prop->value());
}
if ((prop = node.property (X_("device-profile"))) != 0) {
set_profile (prop->value());
}
+
+ XMLNode* snode = node.child (X_("Surfaces"));
+
+ delete _surfaces_state;
+ _surfaces_state = 0;
- set_active (active);
-
- if (_active) {
- switch_banks (bank, true);
+ if (snode) {
+ _surfaces_state = new XMLNode (*snode);
+ _surfaces_version = version;
}
+ switch_banks (bank, true);
+
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::set_state done\n");
return retval;
MackieControlProtocol::bundles ()
{
list<boost::shared_ptr<ARDOUR::Bundle> > b;
- b.push_back (_input_bundle);
- b.push_back (_output_bundle);
+
+ if (_input_bundle) {
+ b.push_back (_input_bundle);
+ b.push_back (_output_bundle);
+ }
+
return b;
}
*/
if (!_device_info.uses_ipmidi()) {
+#ifndef PLATFORM_WINDOWS
CrossThreadChannel::drain (port->selectable());
+#endif
}
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name()));
- framepos_t now = session->engine().frame_time();
+ framepos_t now = session->engine().sample_time();
port->parse (now);
}
void
MackieControlProtocol::clear_ports ()
{
- _input_bundle->remove_channels ();
- _output_bundle->remove_channels ();
+ if (_input_bundle) {
+ _input_bundle->remove_channels ();
+ _output_bundle->remove_channels ();
+ }
for (PortSources::iterator i = port_sources.begin(); i != port_sources.end(); ++i) {
g_source_destroy (*i);
}
void
-MackieControlProtocol::set_flip_mode (bool yn)
+MackieControlProtocol::set_flip_mode (FlipMode fm)
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
- _flip_mode = yn;
+ _flip_mode = fm;
for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
(*s)->update_flip_mode_display ();
void
MackieControlProtocol::remove_down_select_button (int surface, int strip)
{
- DownButtonList::iterator x = find (_down_select_buttons.begin(), _down_select_buttons.end(), (surface<<8)|(strip&0xf));
+ DownButtonList::iterator x = find (_down_select_buttons.begin(), _down_select_buttons.end(), (uint32_t) (surface<<8)|(strip&0xf));
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("removing surface %1 strip %2 from down select buttons\n", surface, strip));
if (x != _down_select_buttons.end()) {
_down_select_buttons.erase (x);
to restart.
*/
- if (_active && _device_info.uses_ipmidi()) {
+ if (active() && _device_info.uses_ipmidi()) {
needs_ipmidi_restart = true;
}
}
-void
+int
MackieControlProtocol::ipmidi_restart ()
{
- clear_ports ();
clear_surfaces ();
- create_surfaces ();
+ if (create_surfaces ()) {
+ return -1;
+ }
switch_banks (_current_initial_bank, true);
needs_ipmidi_restart = false;
+ return 0;
}
void
MackieControlProtocol::clear_surfaces ()
{
+ clear_ports ();
Glib::Threads::Mutex::Lock lm (surfaces_lock);
surfaces.clear ();
}