diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 06e06d0196..f5c083d345 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -163,6 +163,7 @@ enum AutomationType { MonitoringAutomation, BusSendLevel, BusSendEnable, + MainOutVolume, /* used only by Controllable Descriptor to access send parameters */ diff --git a/libs/ardour/ardour/value_as_string.h b/libs/ardour/ardour/value_as_string.h index 2b95eb9141..09eb44e9c0 100644 --- a/libs/ardour/ardour/value_as_string.h +++ b/libs/ardour/ardour/value_as_string.h @@ -53,7 +53,7 @@ value_as_string(const ARDOUR::ParameterDescriptor& desc, // Value is not a scale point, print it normally if (desc.unit == ARDOUR::ParameterDescriptor::MIDI_NOTE) { snprintf(buf, sizeof(buf), "%s", ParameterDescriptor::midi_note_name (rint(v)).c_str()); - } else if (desc.type == GainAutomation || desc.type == BusSendLevel || desc.type == TrimAutomation || desc.type == EnvelopeAutomation) { + } else if (desc.type == GainAutomation || desc.type == BusSendLevel || desc.type == TrimAutomation || desc.type == EnvelopeAutomation || desc.type == MainOutVolume) { snprintf(buf, sizeof(buf), "%.1f dB", accurate_coefficient_to_dB (v)); } else if (desc.type == PanWidthAutomation) { snprintf (buf, sizeof (buf), "%d%%", (int) floor (100.0 * v)); diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 16832b8af1..d316768be1 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -196,6 +196,8 @@ Automatable::describe_parameter (Evoral::Parameter param) return _("Send"); } else if (param.type() == TrimAutomation) { return _("Trim"); + } else if (param.type() == MainOutVolume) { + return _("Master Volume"); } else if (param.type() == MuteAutomation) { return _("Mute"); } else if (param.type() == PanAzimuthAutomation) { @@ -554,6 +556,8 @@ Automatable::control_factory(const Evoral::Parameter& param) control = new GainControl(_a_session, param); } else if (param.type() == TrimAutomation) { control = new GainControl(_a_session, param); + } else if (param.type() == MainOutVolume) { + control = new GainControl(_a_session, param); } else if (param.type() == BusSendLevel) { control = new GainControl(_a_session, param); } else if (param.type() == PanAzimuthAutomation || param.type() == PanWidthAutomation || param.type() == PanElevationAutomation) { diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc index 1a3c1cc406..de7e98bfb2 100644 --- a/libs/ardour/automation_list.cc +++ b/libs/ardour/automation_list.cc @@ -231,6 +231,7 @@ AutomationList::default_interpolation () const case EnvelopeAutomation: return ControlList::Exponential; break; + case MainOutVolume: case TrimAutomation: return ControlList::Logarithmic; break; diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 9fe3030794..0a5db37e45 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -200,6 +200,7 @@ setup_enum_writer () REGISTER_ENUM (MonitoringAutomation); REGISTER_ENUM (BusSendLevel); REGISTER_ENUM (BusSendEnable); + REGISTER_ENUM (MainOutVolume); REGISTER (_AutomationType); REGISTER_ENUM (Off); diff --git a/libs/ardour/event_type_map.cc b/libs/ardour/event_type_map.cc index 69e84ef8fc..45e2ddf977 100644 --- a/libs/ardour/event_type_map.cc +++ b/libs/ardour/event_type_map.cc @@ -139,6 +139,8 @@ EventTypeMap::from_symbol(const string& str) const p_type = BusSendLevel; } else if (str == "trim") { p_type = TrimAutomation; + } else if (str == "main-out-volume") { + p_type = MainOutVolume; } else if (str == "solo") { p_type = SoloAutomation; } else if (str == "solo-iso") { @@ -241,6 +243,8 @@ EventTypeMap::to_symbol(const Evoral::Parameter& param) const return "send"; } else if (t == TrimAutomation) { return "trim"; + } else if (t == MainOutVolume) { + return "main-out-volume"; } else if (t == PanAzimuthAutomation) { return "pan-azimuth"; } else if (t == PanElevationAutomation) { diff --git a/libs/ardour/parameter_descriptor.cc b/libs/ardour/parameter_descriptor.cc index 05e5bfbca9..ee109d58c1 100644 --- a/libs/ardour/parameter_descriptor.cc +++ b/libs/ardour/parameter_descriptor.cc @@ -71,6 +71,12 @@ ParameterDescriptor::ParameterDescriptor(const Evoral::Parameter& parameter) normal = 1.0f; logarithmic = true; break; + case MainOutVolume: + upper = 100; // +40dB + lower = .01; // -40dB + normal = 1.0f; + logarithmic = true; + break; case PanAzimuthAutomation: normal = 0.5f; // there really is no _normal but this works for stereo, sort of upper = 1.0f; @@ -198,7 +204,7 @@ ParameterDescriptor::update_steps() if (unit == ParameterDescriptor::MIDI_NOTE) { step = smallstep = 1; // semitone largestep = 12; // octave - } else if (type == GainAutomation || type == TrimAutomation || type == BusSendLevel) { + } else if (type == GainAutomation || type == TrimAutomation || type == BusSendLevel || type == MainOutVolume) { /* dB_coeff_step gives a step normalized for [0, max_gain]. This is like "slider position", so we convert from "slider position" to gain to have the correct unit here. */ @@ -314,11 +320,15 @@ ParameterDescriptor::to_interface (float val, bool rotary) const val = std::min (upper, std::max (lower, val)); switch(type) { case GainAutomation: + /* fallthrough */ case BusSendLevel: + /* fallthrough */ case EnvelopeAutomation: val = gain_to_slider_position_with_max (val, upper); break; case TrimAutomation: + /* fallthrough */ + case MainOutVolume: { const float lower_db = accurate_coefficient_to_dB (lower); const float range_db = accurate_coefficient_to_dB (upper) - lower_db;