Added Phase control mackie controls as part of the Trim (track) vpot assignment.

This commit is contained in:
Len Ovens 2015-11-01 13:35:02 -08:00
parent e709512f14
commit 2e9de2def0
6 changed files with 194 additions and 6 deletions

View File

@ -410,6 +410,20 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
boost::weak_ptr<Route> _route;
};
class PhaseControllable : public AutomationControl {
public:
PhaseControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double);
void set_channel (int);
double get_value () const;
int channel() const;
private:
boost::weak_ptr<Route> _route;
int _current_phase;
};
boost::shared_ptr<SoloControllable> solo_control() const {
return _solo_control;
}
@ -422,6 +436,10 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
return _mute_master;
}
boost::shared_ptr<PhaseControllable> phase_control() const {
return _phase_control;
}
/* Route doesn't own these items, but sub-objects that it does own have them
and to make UI code a bit simpler, we provide direct access to them
here.
@ -560,6 +578,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
boost::shared_ptr<SoloControllable> _solo_control;
boost::shared_ptr<MuteControllable> _mute_control;
boost::shared_ptr<MuteMaster> _mute_master;
boost::shared_ptr<PhaseControllable> _phase_control;
virtual void act_on_mute () {}

View File

@ -140,6 +140,8 @@ namespace ARDOUR {
EnvelopeAutomation,
RecEnableAutomation,
TrimAutomation,
PhaseAutomation,
SendAutomation,
};
enum AutoState {

View File

@ -135,12 +135,15 @@ Route::init ()
_solo_control.reset (new SoloControllable (X_("solo"), shared_from_this ()));
_mute_control.reset (new MuteControllable (X_("mute"), shared_from_this ()));
_phase_control.reset (new PhaseControllable (X_("phase"), shared_from_this ()));
_solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
_mute_control->set_flags (Controllable::Flag (_mute_control->flags() | Controllable::Toggle));
_phase_control->set_flags (Controllable::Flag (_phase_control->flags() | Controllable::Toggle));
add_control (_solo_control);
add_control (_mute_control);
add_control (_phase_control);
/* panning */
@ -3970,6 +3973,51 @@ Route::MuteControllable::get_value () const
return (r && r->muted()) ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
}
Route::PhaseControllable::PhaseControllable (std::string name, boost::shared_ptr<Route> r)
: AutomationControl (r->session(),
Evoral::Parameter (PhaseAutomation),
ParameterDescriptor (Evoral::Parameter (PhaseAutomation)),
boost::shared_ptr<AutomationList>(),
name)
, _route (r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(PhaseAutomation)));
gl->set_interpolation(Evoral::ControlList::Discrete);
set_list (gl);
}
void
Route::PhaseControllable::set_value (double v)
{
boost::shared_ptr<Route> r = _route.lock ();
if (r->phase_invert().size()) {
if (v == 0 || (v < 1 && v > 0.9) ) {
r->set_phase_invert (_current_phase, false);
} else {
r->set_phase_invert (_current_phase, true);
}
}
}
double
Route::PhaseControllable::get_value () const
{
boost::shared_ptr<Route> r = _route.lock ();
return (double) r->phase_invert (_current_phase);
}
void
Route::PhaseControllable::set_channel (int c)
{
_current_phase = c;
}
int
Route::PhaseControllable::channel () const
{
return _current_phase;
}
void
Route::set_block_size (pframes_t nframes)
{

View File

@ -839,8 +839,6 @@ MackieControlProtocol::track_release (Mackie::Button&)
Mackie::LedState
MackieControlProtocol::send_press (Mackie::Button&)
{
return none;
// remove above line when sends implemented
set_pot_mode (Send);
return none;
}

View File

@ -184,6 +184,7 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
control_by_parameter[PanLFEAutomation] = (Control*) 0;
control_by_parameter[GainAutomation] = (Control*) 0;
control_by_parameter[TrimAutomation] = (Control*) 0;
control_by_parameter[PhaseAutomation] = (Control*) 0;
reset_saved_values ();
@ -198,9 +199,6 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
_solo->set_control (_route->solo_control());
_mute->set_control (_route->mute_control());
_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());
@ -210,6 +208,11 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
_route->trim_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_trim_changed, this, false), ui_context());
}
if (_route->phase_invert().size()) {
_route->phase_invert_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_phase_changed, this, false), ui_context());
_route->phase_control()->set_channel(0);
}
boost::shared_ptr<Pannable> pannable = _route->pannable();
if (pannable && _route->panner()) {
@ -235,6 +238,8 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
_route->DropReferences.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_route_deleted, this), ui_context());
/* Update */
_pan_mode = PanAzimuthAutomation;
potmode_changed (true);
notify_all ();
@ -261,6 +266,16 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
if (_route->trim() && route()->trim()->active()) {
possible_pot_parameters.push_back (TrimAutomation);
}
possible_trim_parameters.clear();
if (_route->trim() && route()->trim()->active()) {
possible_trim_parameters.push_back (TrimAutomation);
}
if (_route->phase_invert().size()) {
possible_trim_parameters.push_back (PhaseAutomation);
}
}
void
@ -279,6 +294,7 @@ Strip::notify_all()
notify_panner_width_changed ();
notify_record_enable_changed ();
notify_trim_changed ();
notify_phase_changed ();
}
void
@ -397,6 +413,33 @@ Strip::notify_trim_changed (bool force_update)
}
}
void
Strip::notify_phase_changed (bool force_update)
{
if (_route) {
Control* control = 0;
ControlParameterMap::iterator i = control_by_parameter.find (PhaseAutomation);
if (i == control_by_parameter.end()) {
return;
}
control = i->second;
float normalized_position = _route->phase_control()->get_value();
if (control == _fader) {
if (!_fader->in_use()) {
_surface->write (_fader->set_position (normalized_position));
queue_parameter_display (PhaseAutomation, normalized_position);
}
} else if (control == _vpot) {
_surface->write (_vpot->set (normalized_position, true, Pot::wrap));
queue_parameter_display (PhaseAutomation, normalized_position);
}
}
}
void
Strip::notify_property_changed (const PropertyChange& what_changed)
{
@ -733,6 +776,17 @@ Strip::do_parameter_display (AutomationType type, float val)
}
break;
case PhaseAutomation:
if (_route) {
if (_route->phase_control()->get_value() < 0.5) {
_surface->write (display (1, "Normal"));
} else {
_surface->write (display (1, "Invert"));
}
screen_hold = true;
}
break;
default:
break;
}
@ -996,6 +1050,8 @@ Strip::vpot_mode_string () const
return "Fader";
case TrimAutomation:
return "Trim";
case PhaseAutomation:
return string_compose ("Phase%1", _route->phase_control()->channel() + 1);
case PanAzimuthAutomation:
return "Pan";
case PanWidthAutomation:
@ -1032,7 +1088,7 @@ Strip::potmode_changed (bool notify)
break;
case MackieControlProtocol::Send:
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Send mode.\n");
// set to current send
set_vpot_parameter (NullAutomation);
break;
}
@ -1109,7 +1165,31 @@ Strip::next_pot_mode ()
i = possible_pot_parameters.begin();
}
set_vpot_parameter (*i);
} else if (_surface->mcp().pot_mode() == MackieControlProtocol::Trim) {
if (possible_trim_parameters.empty() || (possible_trim_parameters.size() == 1 && possible_trim_parameters.front() == ac->parameter())) {
return;
}
for (i = possible_trim_parameters.begin(); i != possible_trim_parameters.end(); ++i) {
if ((*i) == ac->parameter()) {
break;
}
}
// check for phase and more than one phase control
/* 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_trim_parameters.end()) {
++i;
}
if (i == possible_trim_parameters.end()) {
i = possible_trim_parameters.begin();
}
set_vpot_parameter (*i);
}
}
void
@ -1216,6 +1296,45 @@ Strip::set_vpot_parameter (Evoral::Parameter p)
}
}
break;
case PhaseAutomation:
if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
/* gain to vpot, phase to fader */
_vpot->set_control (_route->gain_control());
control_by_parameter[GainAutomation] = _vpot;
if (_route->phase_invert().size()) {
_fader->set_control (_route->phase_control());
control_by_parameter[PhaseAutomation] = _fader;
} else {
_fader->set_control (boost::shared_ptr<AutomationControl>());
control_by_parameter[PhaseAutomation] = 0;
}
} else {
/* gain to fader, phase to vpot */
_fader->set_control (_route->gain_control());
control_by_parameter[GainAutomation] = _fader;
if (_route->phase_invert().size()) {
_vpot->set_control (_route->phase_control());
control_by_parameter[PhaseAutomation] = _vpot;
} else {
_vpot->set_control (boost::shared_ptr<AutomationControl>());
control_by_parameter[PhaseAutomation] = 0;
}
}
break;
case NullAutomation:
// deal with sends, phase, hidden, etc.
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 (boost::shared_ptr<AutomationControl>());
} else {
// gain to fader, trim to vpot
_fader->set_control (_route->gain_control());
control_by_parameter[GainAutomation] = _fader;
_vpot->set_control (boost::shared_ptr<AutomationControl>());
}
break;
default:
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("vpot mode %1 not known.\n", p));
break;

View File

@ -125,6 +125,7 @@ private:
void notify_active_changed ();
void notify_route_deleted ();
void notify_trim_changed (bool force_update = true);
void notify_phase_changed (bool force_update = true);
void update_automation ();
void update_meter ();
@ -148,6 +149,7 @@ private:
void fader_touch_event (Button&, ButtonState);
std::vector<Evoral::Parameter> possible_pot_parameters;
std::vector<Evoral::Parameter> possible_trim_parameters;
void next_pot_mode ();
void set_vpot_parameter (Evoral::Parameter);
void show_route_name ();