Add Trim to Mackie controls.

This commit is contained in:
Len Ovens 2015-10-07 21:36:16 -07:00
parent c9658134ce
commit 6899bd7c15
9 changed files with 229 additions and 62 deletions

View File

@ -429,6 +429,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
boost::shared_ptr<PannerShell> panner_shell() const;
boost::shared_ptr<AutomationControl> gain_control() const;
boost::shared_ptr<Pannable> pannable() const;
boost::shared_ptr<AutomationControl> trim_control() const;
/**
Return the first processor that accepts has at least one MIDI input

View File

@ -4236,6 +4236,12 @@ Route::gain_control() const
return _amp->gain_control();
}
boost::shared_ptr<AutomationControl>
Route::trim_control() const
{
return _trim->gain_control();
}
boost::shared_ptr<AutomationControl>
Route::get_control (const Evoral::Parameter& param)
{

View File

@ -107,6 +107,7 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
, _scrub_mode (false)
, _flip_mode (Normal)
, _view_mode (Mixer)
, _pot_mode (Pan)
, _current_selected_track (-1)
, _modifier_state (0)
, _ipmidi_base (MIDI::IPMIDIPort::lowest_ipmidi_port_default)
@ -292,16 +293,8 @@ MackieControlProtocol::get_sorted_routes()
break;
case MidiTracks:
break;
case Dynamics:
break;
case EQ:
break;
case Loop:
break;
case Sends:
break;
case Plugins:
break;
}
sorted.push_back (*it);
@ -1441,6 +1434,20 @@ MackieControlProtocol::set_flip_mode (FlipMode fm)
}
}
void
MackieControlProtocol::set_pot_mode (PotMode m)
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
_pot_mode = m;
for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
(*s)->update_potmode ();
}
}
void
MackieControlProtocol::set_master_on_surface_strip (uint32_t surface, uint32_t strip_number)
{

View File

@ -102,16 +102,21 @@ class MackieControlProtocol
enum ViewMode {
Mixer,
Dynamics,
EQ,
Loop,
AudioTracks,
MidiTracks,
Busses,
Sends,
Plugins,
};
enum PotMode {
Tracks,
Send,
Pan,
PlugIn,
EQ,
Instrument,
};
enum FlipMode {
Normal, /* fader controls primary, vpot controls secondary */
Mirror, /* fader + vpot control secondary */
@ -135,11 +140,13 @@ class MackieControlProtocol
FlipMode flip_mode () const { return _flip_mode; }
ViewMode view_mode () const { return _view_mode; }
PotMode pot_mode () const { return _pot_mode; }
bool zoom_mode () const { return modifier_state() & MODIFIER_ZOOM; }
bool metering_active () const { return _metering_active; }
void set_view_mode (ViewMode);
void set_flip_mode (FlipMode);
void set_pot_mode (PotMode);
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
@ -302,6 +309,7 @@ class MackieControlProtocol
bool _scrub_mode;
FlipMode _flip_mode;
ViewMode _view_mode;
PotMode _pot_mode;
int _current_selected_track;
int _modifier_state;
ButtonMap button_map;

View File

@ -659,7 +659,14 @@ MackieControlProtocol::F8_release (Button &)
LedState
MackieControlProtocol::pan_press (Button &)
{
return off;
set_pot_mode (Pan);
update_global_button (Button::Track, off);
update_global_button (Button::Send, off);
update_global_button (Button::Plugin, off);
update_global_button (Button::Eq, off);
update_global_button (Button::Dyn, off);
return on;
}
LedState
MackieControlProtocol::pan_release (Button &)
@ -830,8 +837,14 @@ MackieControlProtocol::clearsolo_release (Mackie::Button&)
Mackie::LedState
MackieControlProtocol::track_press (Mackie::Button&)
{
set_pot_mode (Tracks);
update_global_button (Button::Pan, off);
update_global_button (Button::Send, off);
update_global_button (Button::Plugin, off);
update_global_button (Button::Eq, off);
update_global_button (Button::Dyn, off);
return on;
return off;
}
Mackie::LedState
MackieControlProtocol::track_release (Mackie::Button&)
@ -841,13 +854,15 @@ MackieControlProtocol::track_release (Mackie::Button&)
Mackie::LedState
MackieControlProtocol::send_press (Mackie::Button&)
{
// code moved here from "sends_press"
//set_view_mode (Sends);
// Led state for vpot assignment should be radio button-ish
// Pressing any one should turn the rest off.
// but this is not implemented yet so leave off
//return on;
return off;
// remove above line when sends implemented
set_pot_mode (Send);
update_global_button (Button::Track, off);
update_global_button (Button::Pan, off);
update_global_button (Button::Plugin, off);
update_global_button (Button::Eq, off);
update_global_button (Button::Dyn, off);
return on;
}
Mackie::LedState
MackieControlProtocol::send_release (Mackie::Button&)

View File

@ -93,9 +93,11 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<Button::
, _transport_is_rolling (false)
, _metering_active (true)
, _reset_display_at (0)
, _pan_mode (PanAzimuthAutomation)
, _last_gain_position_written (-1.0)
, _last_pan_azi_position_written (-1.0)
, _last_pan_width_position_written (-1.0)
, _last_trim_position_written (-1.0)
, redisplay_requests (256)
{
_fader = dynamic_cast<Fader*> (Fader::factory (*_surface, index, "fader", *this));
@ -185,13 +187,19 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
_solo->set_control (_route->solo_control());
_mute->set_control (_route->mute_control());
set_vpot_parameter (PanAzimuthAutomation);
_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());
_route->mute_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_mute_changed, this), ui_context());
if (_route->trim()) {
_route->trim_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_trim_changed, this, false), ui_context());
}
boost::shared_ptr<Pannable> pannable = _route->pannable();
if (pannable && _route->panner()) {
@ -259,6 +267,7 @@ Strip::notify_all()
notify_panner_azi_changed ();
notify_panner_width_changed ();
notify_record_enable_changed ();
notify_trim_changed ();
}
void
@ -340,6 +349,39 @@ Strip::notify_gain_changed (bool force_update)
}
}
void
Strip::notify_trim_changed (bool force_update)
{
if (_route) {
if (!_route->trim()) {
_surface->write (_vpot->zero());
return;
}
Control* control = control_by_parameter[TrimAutomation];
boost::shared_ptr<AutomationControl> ac = _route->trim_control();
float gain_coefficient = ac->get_value();
float normalized_position = ac->internal_to_interface (gain_coefficient);
if (force_update || normalized_position != _last_trim_position_written) {
if (control == _fader) {
if (!_fader->in_use()) {
_surface->write (_fader->set_position (normalized_position));
queue_parameter_display (TrimAutomation, gain_coefficient);
}
} else if (control == _vpot) {
_surface->write (_vpot->set (normalized_position, true, Pot::dot));
queue_parameter_display (TrimAutomation, gain_coefficient);
}
_last_trim_position_written = normalized_position;
queue_display_reset (2000);
}
}
}
void
Strip::notify_property_changed (const PropertyChange& what_changed)
{
@ -388,12 +430,13 @@ Strip::notify_panner_azi_changed (bool force_update)
if (control == _fader) {
if (!_fader->in_use()) {
_surface->write (_fader->set_position (pos));
queue_parameter_display (PanAzimuthAutomation, pos);
}
} else if (control == _vpot) {
_surface->write (_vpot->set (pos, true, Pot::dot));
queue_parameter_display (PanAzimuthAutomation, pos);
}
queue_parameter_display (PanAzimuthAutomation, pos);
queue_display_reset (2000);
_last_pan_azi_position_written = pos;
}
@ -430,14 +473,15 @@ Strip::notify_panner_width_changed (bool force_update)
if (control == _fader) {
if (!control->in_use()) {
_surface->write (_fader->set_position (pos));
queue_parameter_display (PanWidthAutomation, pos);
}
}
} else if (control == _vpot) {
_surface->write (_vpot->set (pos, true, Pot::spread));
queue_parameter_display (PanWidthAutomation, pos);
}
queue_parameter_display (PanWidthAutomation, pos);
queue_display_reset (2000);
_last_pan_azi_position_written = pos;
}
@ -650,6 +694,15 @@ Strip::do_parameter_display (AutomationType type, float val)
}
break;
case TrimAutomation:
if (_route) {
char buf[16];
float dB = accurate_coefficient_to_dB (val);
snprintf (buf, sizeof (buf), "%6.1f", dB);
_surface->write (display (1, buf));
}
break;
default:
break;
}
@ -747,6 +800,12 @@ Strip::update_automation ()
notify_panner_width_changed (false);
}
}
if (_route->trim()) {
ARDOUR::AutoState trim_state = _route->trim_control()->automation_state();
if (trim_state == Touch || trim_state == Play) {
notify_trim_changed (false);
}
}
}
void
@ -853,6 +912,8 @@ Strip::vpot_mode_string () const
switch (ac->parameter().type()) {
case GainAutomation:
return "Fader";
case TrimAutomation:
return "Trim";
case PanAzimuthAutomation:
return "Pan";
case PanWidthAutomation:
@ -868,6 +929,45 @@ Strip::vpot_mode_string () const
return "???";
}
void
Strip::potmode_changed (bool notify)
{
if (!_route) {
return;
}
if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
/* do not change vpot mode while in flipped mode */
DEBUG_TRACE (DEBUG::MackieControl, "not stepping pot mode - in flip mode\n");
_surface->write (display (1, "Flip"));
queue_display_reset (1000);
return;
}
// 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");
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;
}
if (notify) {
notify_all ();
}
}
void
Strip::flip_mode_changed (bool notify)
{
@ -1023,30 +1123,30 @@ Strip::next_pot_mode ()
if (!ac) {
return;
}
if (possible_pot_parameters.empty() || (possible_pot_parameters.size() == 1 && possible_pot_parameters.front() == ac->parameter())) {
return;
}
for (i = possible_pot_parameters.begin(); i != possible_pot_parameters.end(); ++i) {
if ((*i) == ac->parameter()) {
break;
if (_surface->mcp().pot_mode() == MackieControlProtocol::Pan) {
if (possible_pot_parameters.empty() || (possible_pot_parameters.size() == 1 && possible_pot_parameters.front() == ac->parameter())) {
return;
}
for (i = possible_pot_parameters.begin(); i != possible_pot_parameters.end(); ++i) {
if ((*i) == ac->parameter()) {
break;
}
}
/* move to the next mode in the list, or back to the start (which will
also happen if the current mode is not in the current pot mode list)
*/
if (i != possible_pot_parameters.end()) {
++i;
}
if (i == possible_pot_parameters.end()) {
i = possible_pot_parameters.begin();
}
set_vpot_parameter (*i);
}
/* move to the next mode in the list, or back to the start (which will
also happen if the current mode is not in the current pot mode list)
*/
if (i != possible_pot_parameters.end()) {
++i;
}
if (i == possible_pot_parameters.end()) {
i = possible_pot_parameters.begin();
}
set_vpot_parameter (*i);
}
void
@ -1057,9 +1157,15 @@ 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;
}
}
switch (p.type()) {
case PanAzimuthAutomation:
_pan_mode = PanAzimuthAutomation;
pannable = _route->pannable ();
if (pannable) {
if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
@ -1088,6 +1194,7 @@ Strip::set_vpot_parameter (Evoral::Parameter p)
}
break;
case PanWidthAutomation:
_pan_mode = PanWidthAutomation;
pannable = _route->pannable ();
if (pannable) {
if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
@ -1121,6 +1228,30 @@ Strip::set_vpot_parameter (Evoral::Parameter p)
break;
case PanLFEAutomation:
break;
case TrimAutomation:
if (_route->trim()) {
if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
/* gain to vpot, trim to fader */
_vpot->set_control (_route->gain_control());
control_by_parameter[GainAutomation] = _vpot;
_fader->set_control (_route->trim_control());
control_by_parameter[TrimAutomation] = _fader;
} else {
/* gain to fader, trim to vpot */
_fader->set_control (_route->gain_control());
control_by_parameter[GainAutomation] = _fader;
_vpot->set_control (_route->trim_control());
control_by_parameter[TrimAutomation] = _vpot;
}
} else {
_vpot->set_control (boost::shared_ptr<AutomationControl>());
control_by_parameter[TrimAutomation] = 0;
}
break;
default:
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("vpot mode %1 not known.\n", p));
break;
}
_surface->write (display (1, vpot_mode_string()));
@ -1132,6 +1263,7 @@ Strip::reset_saved_values ()
_last_pan_azi_position_written = -1.0;
_last_pan_width_position_written = -1.0;
_last_gain_position_written = -1.0;
_last_trim_position_written = -1.0;
}

View File

@ -76,6 +76,7 @@ public:
void zero ();
void flip_mode_changed (bool notify=false);
void potmode_changed (bool notify=false);
void lock_controls ();
void unlock_controls ();
@ -104,9 +105,12 @@ private:
boost::shared_ptr<ARDOUR::Route> _route;
PBD::ScopedConnectionList route_connections;
int _pan_mode;
float _last_gain_position_written;
float _last_pan_azi_position_written;
float _last_pan_width_position_written;
float _last_trim_position_written;
void notify_solo_changed ();
void notify_mute_changed ();
@ -117,6 +121,7 @@ private:
void notify_panner_width_changed (bool force_update = true);
void notify_active_changed ();
void notify_route_deleted ();
void notify_trim_changed (bool force_update = true);
void update_automation ();
void update_meter ();

View File

@ -974,6 +974,14 @@ Surface::update_flip_mode_display ()
}
}
void
Surface::update_potmode ()
{
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
(*s)->potmode_changed (false);
}
}
void
Surface::update_view_mode_display ()
{
@ -987,15 +995,7 @@ Surface::update_view_mode_display ()
switch (_mcp.view_mode()) {
case MackieControlProtocol::Mixer:
show_two_char_display ("Mx");
id = Button::Pan;
break;
case MackieControlProtocol::Dynamics:
show_two_char_display ("Dy");
id = Button::Dyn;
break;
case MackieControlProtocol::EQ:
show_two_char_display ("EQ");
id = Button::Eq;
//id = Button::Pan;
break;
case MackieControlProtocol::Loop:
show_two_char_display ("LP");
@ -1007,14 +1007,6 @@ Surface::update_view_mode_display ()
case MackieControlProtocol::MidiTracks:
show_two_char_display ("MT");
break;
case MackieControlProtocol::Sends:
show_two_char_display ("Sn");
id = Button::Send;
break;
case MackieControlProtocol::Plugins:
show_two_char_display ("Pl");
id = Button::Plugin;
break;
default:
break;
}

View File

@ -151,6 +151,7 @@ public:
void update_view_mode_display ();
void update_flip_mode_display ();
void update_potmode ();
void gui_selection_changed (const ARDOUR::StrongRouteNotificationList&);