_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 */
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)
{
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 ();
_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());
_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()) {
_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 ();
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
notify_panner_width_changed ();
notify_record_enable_changed ();
notify_trim_changed ();
+ notify_phase_changed ();
}
void
}
}
+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)
{
}
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;
}
return "Fader";
case TrimAutomation:
return "Trim";
+ case PhaseAutomation:
+ return string_compose ("Phase%1", _route->phase_control()->channel() + 1);
case PanAzimuthAutomation:
return "Pan";
case PanWidthAutomation:
break;
case MackieControlProtocol::Send:
DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Send mode.\n");
- // set to current send
+ set_vpot_parameter (NullAutomation);
break;
}
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
}
}
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;