mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
numerous changes to Mackie support, generally offering better robustness
This commit is contained in:
parent
7c58b4de5f
commit
965b135842
8 changed files with 157 additions and 107 deletions
|
|
@ -118,6 +118,7 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
|
|||
_surface_combo.signal_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::surface_combo_changed));
|
||||
|
||||
_cp.DeviceChanged.connect (device_change_connection, invalidator (*this), boost::bind (&MackieControlProtocolGUI::device_changed, this), gui_context());
|
||||
_cp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&MackieControlProtocolGUI::connection_handler, this), gui_context());
|
||||
|
||||
ipmidi_base_port_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::ipmidi_spinner_changed));
|
||||
|
||||
|
|
@ -239,6 +240,29 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
|
|||
fkey_packer->show_all();
|
||||
}
|
||||
|
||||
void
|
||||
MackieControlProtocolGUI::connection_handler ()
|
||||
{
|
||||
vector<Gtk::ComboBoxText*>::iterator ic;
|
||||
vector<Gtk::ComboBoxText*>::iterator oc;
|
||||
|
||||
vector<string> midi_inputs;
|
||||
vector<string> midi_outputs;
|
||||
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsPhysical), midi_inputs);
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsPhysical), midi_outputs);
|
||||
|
||||
|
||||
for (ic = input_combos.begin(), oc = output_combos.begin(); ic != input_combos.end() && oc != output_combos.end(); ++ic, ++oc) {
|
||||
|
||||
boost::shared_ptr<Surface> surface = _cp.get_surface_by_raw_pointer ((*ic)->get_data ("surface"));
|
||||
|
||||
if (surface) {
|
||||
update_port_combos (midi_inputs, midi_outputs, *ic, *oc, surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MackieControlProtocolGUI::update_port_combos (vector<string> const& midi_inputs, vector<string> const& midi_outputs,
|
||||
Gtk::ComboBoxText* input_combo,
|
||||
|
|
@ -827,47 +851,3 @@ MackieControlProtocolGUI::touch_sensitive_change ()
|
|||
int sensitivity = (int) touch_sensitivity_adjustment.get_value ();
|
||||
_cp.set_touch_sensitivity (sensitivity);
|
||||
}
|
||||
|
||||
void
|
||||
MackieControlProtocolGUI::surface_connectivity_change (Surface* raw_surface)
|
||||
{
|
||||
boost::shared_ptr<Surface> surface;
|
||||
|
||||
for (MackieControlProtocol::Surfaces::iterator s = _cp.surfaces.begin(); s != _cp.surfaces.end(); ++s) {
|
||||
if ((*s).get() == raw_surface) {
|
||||
surface = *s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gtk::ComboBoxText* input_combo = 0;
|
||||
Gtk::ComboBoxText* output_combo = 0;
|
||||
|
||||
for (vector<Gtk::ComboBoxText*>::iterator c = input_combos.begin(); c != input_combos.end(); ++c) {
|
||||
if ((*c)->get_data ("surface") == raw_surface) {
|
||||
input_combo = *c;
|
||||
}
|
||||
}
|
||||
|
||||
for (vector<Gtk::ComboBoxText*>::iterator c = output_combos.begin(); c != output_combos.end(); ++c) {
|
||||
if ((*c)->get_data ("surface") == raw_surface) {
|
||||
output_combo = *c;
|
||||
}
|
||||
}
|
||||
|
||||
if (!input_combo || !output_combo) {
|
||||
return;
|
||||
}
|
||||
|
||||
vector<string> midi_inputs;
|
||||
vector<string> midi_outputs;
|
||||
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsPhysical), midi_inputs);
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsPhysical), midi_outputs);
|
||||
|
||||
update_port_combos (midi_inputs, midi_outputs, input_combo, output_combo, surface);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,11 +135,8 @@ class MackieControlProtocolGUI : public Gtk::Notebook
|
|||
Gtk::ComboBoxText* output_combo,
|
||||
boost::shared_ptr<Mackie::Surface> surface);
|
||||
|
||||
/* this takes a raw pointer to Surface, because it connects to a signal
|
||||
emitted by a Surface and we don't want to use
|
||||
boost::shared_from_this.
|
||||
*/
|
||||
void surface_connectivity_change (Mackie::Surface* raw_surface);
|
||||
PBD::ScopedConnection connection_change_connection;
|
||||
void connection_handler ();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,11 +400,11 @@ MackieControlProtocol::set_active (bool yn)
|
|||
|
||||
BaseUI::run ();
|
||||
|
||||
if (create_surfaces ()) {
|
||||
return -1;
|
||||
}
|
||||
connect_session_signals ();
|
||||
update_surfaces ();
|
||||
|
||||
if (!_device_info.name().empty()) {
|
||||
set_device (_device_info.name(), true);
|
||||
}
|
||||
|
||||
/* set up periodic task for metering and automation
|
||||
*/
|
||||
|
|
@ -534,6 +534,10 @@ MackieControlProtocol::update_global_button (int id, LedState ls)
|
|||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
|
||||
if (surfaces.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_device_info.has_global_controls()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -554,6 +558,10 @@ MackieControlProtocol::update_global_led (int id, LedState ls)
|
|||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
|
||||
if (surfaces.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_device_info.has_global_controls()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -688,6 +696,8 @@ MackieControlProtocol::set_device_info (const string& device_name)
|
|||
int
|
||||
MackieControlProtocol::set_device (const string& device_name, bool force)
|
||||
{
|
||||
cerr << "Set Device\n\n\n\n\n\n";
|
||||
|
||||
if (device_name == device_info().name() && !force) {
|
||||
/* already using that device, nothing to do */
|
||||
return 0;
|
||||
|
|
@ -708,15 +718,17 @@ MackieControlProtocol::set_device (const string& device_name, bool force)
|
|||
hui_timeout->attach (main_loop()->get_context());
|
||||
}
|
||||
|
||||
if (create_surfaces ()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!_device_info.uses_ipmidi()) {
|
||||
/* notice that the handler for this will execute in our event
|
||||
loop, not in the thread where the
|
||||
PortConnectedOrDisconnected signal is emitted.
|
||||
*/
|
||||
ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::connection_handler, this, _1, _2, _3, _4, _5), this);
|
||||
}
|
||||
|
||||
switch_banks (0, true);
|
||||
if (create_surfaces ()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DeviceChanged ();
|
||||
|
||||
|
|
@ -735,18 +747,17 @@ MackieControlProtocol::create_surfaces ()
|
|||
{
|
||||
string device_name;
|
||||
surface_type_t stype = mcu; // type not yet determined
|
||||
char buf[128];
|
||||
|
||||
if (_device_info.extenders() == 0) {
|
||||
device_name = X_("mackie control");
|
||||
} else {
|
||||
device_name = X_("mackie control #1");
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Create %1 surfaces\n", 1 + _device_info.extenders()));
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Create %1 surfaces for %2\n", 1 + _device_info.extenders(), _device_info.name()));
|
||||
|
||||
for (uint32_t n = 0; n < 1 + _device_info.extenders(); ++n) {
|
||||
|
||||
if (n == 0) {
|
||||
device_name = _device_info.name();
|
||||
} else {
|
||||
device_name = string_compose ("%1 #%2", _device_info.name(), n+1);
|
||||
}
|
||||
|
||||
boost::shared_ptr<Surface> surface;
|
||||
|
||||
if (n == _device_info.master_position()) {
|
||||
|
|
@ -765,6 +776,7 @@ MackieControlProtocol::create_surfaces ()
|
|||
}
|
||||
|
||||
if (_surfaces_state) {
|
||||
cerr << "Resetting surface state\n";
|
||||
surface->set_state (*_surfaces_state, _surfaces_version);
|
||||
}
|
||||
|
||||
|
|
@ -773,13 +785,6 @@ MackieControlProtocol::create_surfaces ()
|
|||
surfaces.push_back (surface);
|
||||
}
|
||||
|
||||
if (_device_info.extenders() < 2) {
|
||||
device_name = X_("mackie control #2");
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf), X_("mackie control #%d"), n+2);
|
||||
device_name = buf;
|
||||
}
|
||||
|
||||
if (!_device_info.uses_ipmidi()) {
|
||||
|
||||
_input_bundle.reset (new ARDOUR::Bundle (_("Mackie Control In"), true));
|
||||
|
|
@ -857,6 +862,7 @@ MackieControlProtocol::create_surfaces ()
|
|||
void
|
||||
MackieControlProtocol::close()
|
||||
{
|
||||
port_connection.disconnect ();
|
||||
session_connections.drop_connections ();
|
||||
route_connections.drop_connections ();
|
||||
periodic_connection.disconnect ();
|
||||
|
|
@ -1050,6 +1056,14 @@ void MackieControlProtocol::notify_parameter_changed (std::string const & p)
|
|||
void
|
||||
MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
|
||||
{
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
|
||||
if (surfaces.empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// currently assigned banks are less than the full set of
|
||||
// strips, so activate the new strip now.
|
||||
|
||||
|
|
@ -1072,6 +1086,11 @@ MackieControlProtocol::notify_solo_active_changed (bool active)
|
|||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
|
||||
if (surfaces.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
surface = _master_surface;
|
||||
}
|
||||
|
||||
|
|
@ -1087,6 +1106,14 @@ MackieControlProtocol::notify_solo_active_changed (bool active)
|
|||
void
|
||||
MackieControlProtocol::notify_remote_id_changed()
|
||||
{
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
|
||||
if (surfaces.empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Sorted sorted = get_sorted_routes();
|
||||
uint32_t sz = n_strips();
|
||||
|
||||
|
|
@ -1150,6 +1177,9 @@ MackieControlProtocol::notify_record_state_changed ()
|
|||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
if (surfaces.empty()) {
|
||||
return;
|
||||
}
|
||||
surface = _master_surface;
|
||||
}
|
||||
|
||||
|
|
@ -1771,7 +1801,6 @@ MackieControlProtocol::ipmidi_restart ()
|
|||
void
|
||||
MackieControlProtocol::clear_surfaces ()
|
||||
{
|
||||
port_connection.disconnect ();
|
||||
clear_ports ();
|
||||
|
||||
{
|
||||
|
|
@ -1814,6 +1843,20 @@ MackieControlProtocol::toggle_backlight ()
|
|||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Surface>
|
||||
MackieControlProtocol::get_surface_by_raw_pointer (void* ptr) const
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
|
||||
for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
|
||||
if ((*s).get() == (Surface*) ptr) {
|
||||
return *s;
|
||||
}
|
||||
}
|
||||
|
||||
return boost::shared_ptr<Surface> ();
|
||||
}
|
||||
|
||||
boost::shared_ptr<Surface>
|
||||
MackieControlProtocol::nth_surface (uint32_t n) const
|
||||
{
|
||||
|
|
@ -1831,11 +1874,14 @@ MackieControlProtocol::nth_surface (uint32_t n) const
|
|||
void
|
||||
MackieControlProtocol::connection_handler (boost::weak_ptr<ARDOUR::Port> wp1, std::string name1, boost::weak_ptr<ARDOUR::Port> wp2, std::string name2, bool yn)
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
Surfaces scopy;
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (surfaces_lock);
|
||||
scopy = surfaces;
|
||||
}
|
||||
|
||||
for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
|
||||
for (Surfaces::const_iterator s = scopy.begin(); s != scopy.end(); ++s) {
|
||||
if ((*s)->connection_handler (wp1, name1, wp2, name2, yn)) {
|
||||
cerr << (*s)->name() << " Connected, or disconnected\n";
|
||||
ConnectionChange (*s);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ class MackieControlProtocol
|
|||
typedef std::list<boost::shared_ptr<Mackie::Surface> > Surfaces;
|
||||
Surfaces surfaces;
|
||||
|
||||
boost::shared_ptr<Mackie::Surface> get_surface_by_raw_pointer (void*) const;
|
||||
boost::shared_ptr<Mackie::Surface> nth_surface (uint32_t) const;
|
||||
|
||||
std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
|
||||
|
|
|
|||
|
|
@ -200,7 +200,6 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
|
|||
_pan_mode = PanAzimuthAutomation;
|
||||
potmode_changed (true);
|
||||
|
||||
|
||||
_route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_solo_changed, this), ui_context());
|
||||
_route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_solo_changed, this), ui_context());
|
||||
|
||||
|
|
@ -368,7 +367,14 @@ Strip::notify_trim_changed (bool force_update)
|
|||
_surface->write (_vpot->zero());
|
||||
return;
|
||||
}
|
||||
Control* control = control_by_parameter[TrimAutomation];
|
||||
Control* control = 0;
|
||||
ControlParameterMap::iterator i = control_by_parameter.find (TrimAutomation);
|
||||
|
||||
if (i == control_by_parameter.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
control = i->second;
|
||||
|
||||
boost::shared_ptr<AutomationControl> ac = _route->trim_control();
|
||||
|
||||
|
|
@ -432,12 +438,15 @@ Strip::notify_panner_azi_changed (bool force_update)
|
|||
return;
|
||||
}
|
||||
|
||||
Control* control = control_by_parameter[PanAzimuthAutomation];
|
||||
Control* control = 0;
|
||||
ControlParameterMap::iterator i = control_by_parameter.find (PanAzimuthAutomation);
|
||||
|
||||
if (!control) {
|
||||
if (i == control_by_parameter.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
control = i->second;
|
||||
|
||||
double pos = pannable->pan_azimuth_control->internal_to_interface (pannable->pan_azimuth_control->get_value());
|
||||
|
||||
if (force_update || pos != _last_pan_azi_position_written) {
|
||||
|
|
@ -472,13 +481,15 @@ Strip::notify_panner_width_changed (bool force_update)
|
|||
return;
|
||||
}
|
||||
|
||||
Control* control = 0;
|
||||
ControlParameterMap::iterator i = control_by_parameter.find (PanWidthAutomation);
|
||||
|
||||
Control* control = control_by_parameter[PanWidthAutomation];
|
||||
|
||||
if (!control) {
|
||||
if (i == control_by_parameter.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
control = i->second;
|
||||
|
||||
double pos = pannable->pan_width_control->internal_to_interface (pannable->pan_width_control->get_value());
|
||||
|
||||
if (force_update || pos != _last_pan_azi_position_written) {
|
||||
|
|
@ -1007,22 +1018,23 @@ Strip::potmode_changed (bool notify)
|
|||
// WIP
|
||||
int pm = _surface->mcp().pot_mode();
|
||||
switch (pm) {
|
||||
case MackieControlProtocol::Pan:
|
||||
// This needs to set current pan mode (azimuth or width... or whatever)
|
||||
set_vpot_parameter (_pan_mode);
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Pan mode.\n");
|
||||
break;
|
||||
case MackieControlProtocol::Tracks: // should change the Tracks to Trim
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Trim mode.\n");
|
||||
case MackieControlProtocol::Pan:
|
||||
// This needs to set current pan mode (azimuth or width... or whatever)
|
||||
set_vpot_parameter (_pan_mode);
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Pan mode.\n");
|
||||
break;
|
||||
case MackieControlProtocol::Tracks: // should change the Tracks to Trim
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Trim mode.\n");
|
||||
set_vpot_parameter (TrimAutomation);
|
||||
break;
|
||||
case MackieControlProtocol::Send:
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Send mode.\n");
|
||||
// set to current send
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case MackieControlProtocol::Send:
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Send mode.\n");
|
||||
// set to current send
|
||||
break;
|
||||
default:
|
||||
cerr << "Pot mode " << pm << " not yet handled\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (notify) {
|
||||
notify_all ();
|
||||
|
|
@ -1133,9 +1145,13 @@ Strip::set_vpot_parameter (Evoral::Parameter p)
|
|||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to vpot mode %1\n", p));
|
||||
|
||||
reset_saved_values ();
|
||||
for (int i = 0; i <= TrimAutomation; ++i) {
|
||||
if (control_by_parameter[i] == _vpot) {
|
||||
control_by_parameter[i] = 0;
|
||||
|
||||
/* unset any mapping between the vpot and any existing parameters */
|
||||
|
||||
for (ControlParameterMap::iterator i = control_by_parameter.begin(); i != control_by_parameter.end(); ++i) {
|
||||
|
||||
if (i != control_by_parameter.end() && i->second == _vpot) {
|
||||
i->second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,7 +155,8 @@ private:
|
|||
|
||||
void reset_saved_values ();
|
||||
|
||||
std::map<Evoral::Parameter,Control*> control_by_parameter;
|
||||
typedef std::map<Evoral::Parameter,Control*> ControlParameterMap;
|
||||
ControlParameterMap control_by_parameter;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "ardour/session.h"
|
||||
#include "ardour/utils.h"
|
||||
|
||||
#include <gtkmm2ext/gui_thread.h>
|
||||
|
||||
#include "control_group.h"
|
||||
#include "surface_port.h"
|
||||
#include "surface.h"
|
||||
|
|
@ -221,6 +223,13 @@ Surface::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, b
|
|||
to queue it with the MCP event loop.
|
||||
*/
|
||||
|
||||
/* XXX this is a horrible hack. Without a short sleep here,
|
||||
something prevents the device wakeup messages from being
|
||||
sent and/or the responses from being received.
|
||||
*/
|
||||
|
||||
g_usleep (100000);
|
||||
|
||||
connected ();
|
||||
|
||||
} else {
|
||||
|
|
@ -662,9 +671,7 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
|
|||
write_sysex (host_connection_query (bytes));
|
||||
} else {
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mackie Control Device ready, current status = %1\n", _active));
|
||||
if (!_active) {
|
||||
turn_it_on ();
|
||||
}
|
||||
turn_it_on ();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -672,7 +679,7 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
|
|||
DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device confirms connection, ardour replies\n");
|
||||
if (bytes[4] == 0x10 || bytes[4] == 0x11) {
|
||||
write_sysex (host_connection_confirmation (bytes));
|
||||
_active = true;
|
||||
turn_it_on ();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sigc++/trackable.h>
|
||||
|
||||
#include "pbd/signals.h"
|
||||
#include "pbd/xml++.h"
|
||||
#include "midi++/types.h"
|
||||
|
|
@ -43,7 +45,7 @@ class Jog;
|
|||
class Pot;
|
||||
class Led;
|
||||
|
||||
class Surface : public PBD::ScopedConnectionList
|
||||
class Surface : public PBD::ScopedConnectionList, public sigc::trackable
|
||||
{
|
||||
public:
|
||||
Surface (MackieControlProtocol&, const std::string& name, uint32_t number, surface_type_t stype);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue