diff --git a/common/params.cc b/common/params.cc index 975e846..bfe0e95 100644 --- a/common/params.cc +++ b/common/params.cc @@ -212,19 +212,27 @@ std::unordered_map keys = { {"AccelerationPath", PERSISTENT}, {"AccelerationProfile", PERSISTENT}, {"AggressiveAcceleration", PERSISTENT}, + {"AlertVolumeControl", PERSISTENT}, {"ApiCache_DriveStats", PERSISTENT}, {"CustomAlerts", PERSISTENT}, {"CustomUI", PERSISTENT}, {"DecelerationProfile", PERSISTENT}, + {"DisengageVolume", PERSISTENT}, {"DriveStats", PERSISTENT}, + {"EngageVolume", PERSISTENT}, {"FrogPilotTogglesUpdated", PERSISTENT}, {"FrogsGoMoo", PERSISTENT}, {"LateralTune", PERSISTENT}, {"LongitudinalTune", PERSISTENT}, + {"PromptVolume", PERSISTENT}, + {"PromptDistractedVolume", PERSISTENT}, {"QOLControls", PERSISTENT}, {"QOLVisuals", PERSISTENT}, + {"RefuseVolume", PERSISTENT}, {"SilentMode", PERSISTENT}, {"StockTune", PERSISTENT}, + {"WarningSoftVolume", PERSISTENT}, + {"WarningImmediateVolume", PERSISTENT}, }; } // namespace diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_mute.png b/selfdrive/frogpilot/assets/toggle_icons/icon_mute.png new file mode 100644 index 0000000..3e31a13 Binary files /dev/null and b/selfdrive/frogpilot/assets/toggle_icons/icon_mute.png differ diff --git a/selfdrive/frogpilot/ui/visual_settings.cc b/selfdrive/frogpilot/ui/visual_settings.cc index 1b52cac..8ba0fe5 100644 --- a/selfdrive/frogpilot/ui/visual_settings.cc +++ b/selfdrive/frogpilot/ui/visual_settings.cc @@ -2,6 +2,15 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { const std::vector> visualToggles { + {"AlertVolumeControl", "Alert Volume Control", "Control the volume level for each individual sound in openpilot.", "../frogpilot/assets/toggle_icons/icon_mute.png"}, + {"DisengageVolume", "Disengage Volume", "Related alerts:\n\nAdaptive Cruise Disabled\nParking Brake Engaged\nPedal Pressed\nSpeed too Low", ""}, + {"EngageVolume", "Engage Volume", "Related alerts:\n\nNNFF Torque Controller loaded", ""}, + {"PromptVolume", "Prompt Volume", "Related alerts:\n\nCar Detected in Blindspot\nLight turned green\nSpeed too Low\nSteer Unavailable Below 'X'\nTake Control, Turn Exceeds Steering Limit", ""}, + {"PromptDistractedVolume", "Prompt Distracted Volume", "Related alerts:\n\nPay Attention, Driver Distracted\nTouch Steering Wheel, Driver Unresponsive", ""}, + {"RefuseVolume", "Refuse Volume", "Related alerts:\n\nopenpilot Unavailable", ""}, + {"WarningSoftVolume", "Warning Soft Volume", "Related alerts:\n\nBRAKE!, Risk of Collision\nTAKE CONTROL IMMEDIATELY", ""}, + {"WarningImmediateVolume", "Warning Immediate Volume", "Related alerts:\n\nDISENGAGE IMMEDIATELY, Driver Distracted\nDISENGAGE IMMEDIATELY, Driver Unresponsive", ""}, + {"CustomAlerts", "Custom Alerts", "Enable custom alerts for various logic or situational changes.", "../frogpilot/assets/toggle_icons/icon_green_light.png"}, {"CustomUI", "Custom Onroad UI", "Customize the Onroad UI with some additional visual functions.", "../assets/offroad/icon_road.png"}, @@ -14,7 +23,23 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot for (const auto &[param, title, desc, icon] : visualToggles) { ParamControl *toggle; - if (param == "CustomAlerts") { + if (param == "AlertVolumeControl") { + FrogPilotParamManageControl *alertVolumeControlToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(alertVolumeControlToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + parentToggleClicked(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(alertVolumeControlKeys.find(key.c_str()) != alertVolumeControlKeys.end()); + } + }); + toggle = alertVolumeControlToggle; + } else if (alertVolumeControlKeys.find(param) != alertVolumeControlKeys.end()) { + if (param == "WarningImmediateVolume") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 25, 100, std::map(), this, false, "%"); + } else { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map(), this, false, "%"); + } + + } else if (param == "CustomAlerts") { FrogPilotParamManageControl *customAlertsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); QObject::connect(customAlertsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { parentToggleClicked(); diff --git a/selfdrive/frogpilot/ui/visual_settings.h b/selfdrive/frogpilot/ui/visual_settings.h index c021e80..389b816 100644 --- a/selfdrive/frogpilot/ui/visual_settings.h +++ b/selfdrive/frogpilot/ui/visual_settings.h @@ -28,7 +28,7 @@ private: void updateState(const UIState &s); void updateToggles(); - std::set alertVolumeControlKeys = {}; + std::set alertVolumeControlKeys = {"EngageVolume", "DisengageVolume", "RefuseVolume", "PromptVolume", "PromptDistractedVolume", "WarningSoftVolume", "WarningImmediateVolume"}; std::set customAlertsKeys = {}; std::set customOnroadUIKeys = {"AccelerationPath"}; std::set customThemeKeys = {}; diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 2546a15..8b4150e 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -153,10 +153,13 @@ class Soundd: while True: sm.update(0) - if sm.updated['microphone'] and self.current_alert == AudibleAlert.none: # only update volume filter when not playing alert + if sm.updated['microphone'] and self.current_alert == AudibleAlert.none and not self.alert_volume_control: # only update volume filter when not playing alert self.spl_filter_weighted.update(sm["microphone"].soundPressureWeightedDb) self.current_volume = self.calculate_volume(float(self.spl_filter_weighted.x)) + elif self.alert_volume_control and self.current_alert in self.volume_map: + self.current_volume = self.volume_map[self.current_alert] / 100.0 + self.get_audible_alert(sm) rk.keep_time() @@ -168,6 +171,22 @@ class Soundd: self.update_frogpilot_params() def update_frogpilot_params(self): + self.alert_volume_control = self.params.get_bool("AlertVolumeControl") + + self.volume_map = { + AudibleAlert.engage: self.params.get_int("EngageVolume"), + AudibleAlert.disengage: self.params.get_int("DisengageVolume"), + AudibleAlert.refuse: self.params.get_int("RefuseVolume"), + + AudibleAlert.prompt: self.params.get_int("PromptVolume"), + AudibleAlert.promptRepeat: self.params.get_int("PromptVolume"), + AudibleAlert.promptDistracted: self.params.get_int("PromptDistractedVolume"), + + AudibleAlert.warningSoft: self.params.get_int("WarningSoftVolume"), + AudibleAlert.warningImmediate: self.params.get_int("WarningImmediateVolume") + } + + self.load_sounds() def main(): s = Soundd()