mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
add a hack to deal with device discovery race, in which the devices were not actually known to be ready before the last update_surfaces() call (which is where binding between strips and routes occurs) ; add support for Mackie Control touch on/off messages
This commit is contained in:
parent
55c7ce98ab
commit
80d83fd238
5 changed files with 61 additions and 6 deletions
|
|
@ -344,7 +344,9 @@ MackieControlProtocol::switch_banks (uint32_t initial, bool force)
|
||||||
|
|
||||||
if (_current_initial_bank <= sorted.size()) {
|
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
|
// link routes to strips
|
||||||
|
|
||||||
|
|
@ -520,11 +522,23 @@ MackieControlProtocol::update_global_led (int id, LedState ls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// send messages to surface to set controls to correct values
|
||||||
void
|
void
|
||||||
MackieControlProtocol::update_surfaces()
|
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()) {
|
if (!active()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,8 @@ class MackieControlProtocol
|
||||||
const Mackie::DeviceInfo& device_info() const { return _device_info; }
|
const Mackie::DeviceInfo& device_info() const { return _device_info; }
|
||||||
Mackie::DeviceProfile& device_profile() { return _device_profile; }
|
Mackie::DeviceProfile& device_profile() { return _device_profile; }
|
||||||
|
|
||||||
|
void device_ready ();
|
||||||
|
|
||||||
int set_active (bool yn);
|
int set_active (bool yn);
|
||||||
int set_device (const std::string&);
|
int set_device (const std::string&);
|
||||||
void set_profile (const std::string&);
|
void set_profile (const std::string&);
|
||||||
|
|
|
||||||
|
|
@ -626,13 +626,22 @@ Strip::do_parameter_display (AutomationType type, float val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Strip::handle_fader_touch (Fader& fader, bool touch_on)
|
||||||
|
{
|
||||||
|
if (touch_on) {
|
||||||
|
fader.start_touch (_surface->mcp().transport_frame());
|
||||||
|
} else {
|
||||||
|
fader.stop_touch (_surface->mcp().transport_frame(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Strip::handle_fader (Fader& fader, float position)
|
Strip::handle_fader (Fader& fader, float position)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader to %1\n", position));
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader to %1\n", position));
|
||||||
|
|
||||||
fader.set_value (position);
|
fader.set_value (position);
|
||||||
fader.start_touch (_surface->mcp().transport_frame());
|
|
||||||
queue_display_reset (2000);
|
queue_display_reset (2000);
|
||||||
|
|
||||||
// must echo bytes back to slider now, because
|
// must echo bytes back to slider now, because
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ public:
|
||||||
|
|
||||||
void handle_button (Button&, ButtonState bs);
|
void handle_button (Button&, ButtonState bs);
|
||||||
void handle_fader (Fader&, float position);
|
void handle_fader (Fader&, float position);
|
||||||
|
void handle_fader_touch (Fader&, bool touch_on);
|
||||||
void handle_pot (Pot&, float delta);
|
void handle_pot (Pot&, float delta);
|
||||||
|
|
||||||
void periodic (uint64_t now_usecs);
|
void periodic (uint64_t now_usecs);
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,7 @@ Surface::connect_to_signals ()
|
||||||
p->controller.connect_same_thread (*this, boost::bind (&Surface::handle_midi_controller_message, this, _1, _2));
|
p->controller.connect_same_thread (*this, boost::bind (&Surface::handle_midi_controller_message, this, _1, _2));
|
||||||
/* Button messages are NoteOn */
|
/* Button messages are NoteOn */
|
||||||
p->note_on.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
|
p->note_on.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
|
||||||
/* Button messages are NoteOn. libmidi++ sends note-on w/velocity = 0 as note-off so catch them too */
|
/* Button messages are NoteOn but libmidi++ sends note-on w/velocity = 0 as note-off so catch them too */
|
||||||
p->note_off.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
|
p->note_off.connect_same_thread (*this, boost::bind (&Surface::handle_midi_note_on_message, this, _1, _2));
|
||||||
/* Fader messages are Pitchbend */
|
/* Fader messages are Pitchbend */
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
@ -386,7 +386,7 @@ Surface::connect_to_signals ()
|
||||||
void
|
void
|
||||||
Surface::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb, uint32_t fader_id)
|
Surface::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb, uint32_t fader_id)
|
||||||
{
|
{
|
||||||
/* Pitchbend messages are fader messages. Nothing in the data we get
|
/* Pitchbend messages are fader position messages. Nothing in the data we get
|
||||||
* from the MIDI::Parser conveys the fader ID, which was given by the
|
* from the MIDI::Parser conveys the fader ID, which was given by the
|
||||||
* channel ID in the status byte.
|
* channel ID in the status byte.
|
||||||
*
|
*
|
||||||
|
|
@ -394,7 +394,6 @@ Surface::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb, uin
|
||||||
* when we connected to the per-channel pitchbend events.
|
* when we connected to the per-channel pitchbend events.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface::handle_midi_pitchbend_message on port %3, fader = %1 value = %2\n",
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface::handle_midi_pitchbend_message on port %3, fader = %1 value = %2\n",
|
||||||
fader_id, pb, _number));
|
fader_id, pb, _number));
|
||||||
|
|
||||||
|
|
@ -429,6 +428,28 @@ Surface::handle_midi_note_on_message (MIDI::Parser &, MIDI::EventTwoBytes* ev)
|
||||||
turn_it_on ();
|
turn_it_on ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fader touch sense is given by "buttons" 0xe..0xe7 and 0xe8 for the
|
||||||
|
* master.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ev->note_number >= 0xE0 && ev->note_number <= 0xE8) {
|
||||||
|
Fader* fader = faders[ev->note_number];
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface: fader touch message, fader = %1\n", fader));
|
||||||
|
|
||||||
|
if (fader) {
|
||||||
|
|
||||||
|
Strip* strip = dynamic_cast<Strip*> (&fader->group());
|
||||||
|
|
||||||
|
if (ev->velocity > 64) {
|
||||||
|
strip->handle_fader_touch (*fader, true);
|
||||||
|
} else {
|
||||||
|
strip->handle_fader_touch (*fader, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Button* button = buttons[ev->note_number];
|
Button* button = buttons[ev->note_number];
|
||||||
|
|
||||||
if (button) {
|
if (button) {
|
||||||
|
|
@ -516,8 +537,10 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
|
||||||
LCP: Connection Challenge
|
LCP: Connection Challenge
|
||||||
*/
|
*/
|
||||||
if (bytes[4] == 0x10 || bytes[4] == 0x11) {
|
if (bytes[4] == 0x10 || bytes[4] == 0x11) {
|
||||||
|
DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device connection challenge\n");
|
||||||
write_sysex (host_connection_query (bytes));
|
write_sysex (host_connection_query (bytes));
|
||||||
} else {
|
} else {
|
||||||
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mackie Control Device ready, current status = %1\n", _active));
|
||||||
if (!_active) {
|
if (!_active) {
|
||||||
turn_it_on ();
|
turn_it_on ();
|
||||||
}
|
}
|
||||||
|
|
@ -525,6 +548,7 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03: /* LCP Connection Confirmation */
|
case 0x03: /* LCP Connection Confirmation */
|
||||||
|
DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device confirms connection, ardour replies\n");
|
||||||
if (bytes[4] == 0x10 || bytes[4] == 0x11) {
|
if (bytes[4] == 0x10 || bytes[4] == 0x11) {
|
||||||
write_sysex (host_connection_confirmation (bytes));
|
write_sysex (host_connection_confirmation (bytes));
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
@ -532,6 +556,7 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: /* LCP: Confirmation Denied */
|
case 0x04: /* LCP: Confirmation Denied */
|
||||||
|
DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device denies connection\n");
|
||||||
_active = false;
|
_active = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -610,6 +635,8 @@ Surface::turn_it_on ()
|
||||||
|
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
|
_mcp.device_ready ();
|
||||||
|
|
||||||
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
|
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
|
||||||
(*s)->notify_all ();
|
(*s)->notify_all ();
|
||||||
}
|
}
|
||||||
|
|
@ -739,6 +766,8 @@ Surface::map_routes (const vector<boost::shared_ptr<Route> >& routes)
|
||||||
vector<boost::shared_ptr<Route> >::const_iterator r;
|
vector<boost::shared_ptr<Route> >::const_iterator r;
|
||||||
Strips::iterator s = strips.begin();
|
Strips::iterator s = strips.begin();
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mapping %1 routes", routes.size()));
|
||||||
|
|
||||||
for (r = routes.begin(); r != routes.end() && s != strips.end(); ++s) {
|
for (r = routes.begin(); r != routes.end() && s != strips.end(); ++s) {
|
||||||
|
|
||||||
/* don't try to assign routes to a locked strip. it won't
|
/* don't try to assign routes to a locked strip. it won't
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue