diff --git a/app/src/main/java/com/cooper/wheellog/AppConfig.kt b/app/src/main/java/com/cooper/wheellog/AppConfig.kt
index 15d5d892e..3f18d02e5 100644
--- a/app/src/main/java/com/cooper/wheellog/AppConfig.kt
+++ b/app/src/main/java/com/cooper/wheellog/AppConfig.kt
@@ -152,6 +152,22 @@ class AppConfig(var context: Context): KoinComponent {
get() = getValue(R.string.use_stop_music, false)
set(value) = setValue(R.string.use_stop_music, value)
+ var stopMusicSpeed: Int
+ get() = getValue("stop_music_speed", 10)
+ set(value) = setValue("stop_music_speed", value)
+
+ var stopMusicLowVolume: Int
+ get() = getValue("stop_music_low_volume", 5)
+ set(value) = setValue("stop_music_low_volume", value)
+
+ var stopMusicRestoreDelay: Int
+ get() = getValue("stop_music_restore_delay", 3)
+ set(value) = setValue("stop_music_restore_delay", value)
+
+ var stopMusicHighSpeed: Int
+ get() = getValue("stop_music_high_speed", 50)
+ set(value) = setValue("stop_music_high_speed", value)
+
var showUnknownDevices: Boolean
get() = getValue(R.string.show_unknown_devices, false)
set(value) = setValue(R.string.show_unknown_devices, value)
diff --git a/app/src/main/java/com/cooper/wheellog/WheelData.java b/app/src/main/java/com/cooper/wheellog/WheelData.java
index a204fb555..8217bda0f 100644
--- a/app/src/main/java/com/cooper/wheellog/WheelData.java
+++ b/app/src/main/java/com/cooper/wheellog/WheelData.java
@@ -102,6 +102,9 @@ public class WheelData {
private double mCalculatedPwm = 0.0;
private double mMaxPwm = 0.0;
private long mLowSpeedMusicTime = 0;
+ private int mMusicVolumeBeforeQuiet = -1;
+ private boolean mMusicVolumeChangedByWheelLog = false;
+ private boolean mMusicMutedByWheelLog = false;
private boolean mBmsView = false;
private String protoVer = "";
@@ -1143,21 +1146,113 @@ public long getLastLifeData() {
}
private void CheckMuteMusic() {
- if (!appConfig.getUseStopMusic())
+ if (!appConfig.getUseStopMusic()) {
+ releaseMusicControl();
return;
+ }
+
+ final double lowMuteSpeedThreshold = appConfig.getStopMusicSpeed();
+ final double highMuteSpeedThreshold = appConfig.getStopMusicHighSpeed();
- final double muteSpeedThreshold = 3.5;
double speed = getSpeedDouble();
- if (speed <= muteSpeedThreshold) {
+
+ if (speed <= lowMuteSpeedThreshold) {
mLowSpeedMusicTime = 0;
- MainActivity.audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
+ setQuietMusicVolume();
+ } else if (speed >= highMuteSpeedThreshold) {
+ mLowSpeedMusicTime = 0;
+ muteMusic();
} else {
if (mLowSpeedMusicTime == 0)
mLowSpeedMusicTime = System.currentTimeMillis();
- if ((System.currentTimeMillis() - mLowSpeedMusicTime) >= 1500)
- MainActivity.audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
+ long restoreDelayMs = appConfig.getStopMusicRestoreDelay() * 1000L;
+
+ // Задержка возврата обычной громкости.
+ // Нужна, чтобы звук не возвращался от скачка скорости на ямке,
+ // переходе, трамвайных путях и т.п.
+ if ((System.currentTimeMillis() - mLowSpeedMusicTime) >= restoreDelayMs)
+ restoreMusicVolume();
+ }
+ }
+
+ private void setQuietMusicVolume() {
+ if (MainActivity.audioManager == null)
+ return;
+
+ // Если до этого звук был полностью заглушен на высокой скорости,
+ // сначала отпускаем mute.
+ if (mMusicMutedByWheelLog) {
+ MainActivity.audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
+ mMusicMutedByWheelLog = false;
}
+
+ int currentVolume = MainActivity.audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+
+ // Запоминаем уровень громкости только один раз,
+ // перед первым переходом в тихий режим.
+ if (!mMusicVolumeChangedByWheelLog) {
+ mMusicVolumeBeforeQuiet = currentVolume;
+ mMusicVolumeChangedByWheelLog = true;
+ }
+
+ int quietVolume = getMusicVolumeByPercent(appConfig.getStopMusicLowVolume());
+
+ if (currentVolume != quietVolume) {
+ MainActivity.audioManager.setStreamVolume(
+ AudioManager.STREAM_MUSIC,
+ quietVolume,
+ 0
+ );
+ }
+ }
+
+ private void muteMusic() {
+ if (MainActivity.audioManager == null)
+ return;
+
+ MainActivity.audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
+ mMusicMutedByWheelLog = true;
+ }
+
+ private void restoreMusicVolume() {
+ if (MainActivity.audioManager == null)
+ return;
+
+ if (mMusicMutedByWheelLog) {
+ MainActivity.audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
+ mMusicMutedByWheelLog = false;
+ }
+
+ if (mMusicVolumeChangedByWheelLog && mMusicVolumeBeforeQuiet >= 0) {
+ MainActivity.audioManager.setStreamVolume(
+ AudioManager.STREAM_MUSIC,
+ mMusicVolumeBeforeQuiet,
+ 0
+ );
+ }
+
+ mMusicVolumeBeforeQuiet = -1;
+ mMusicVolumeChangedByWheelLog = false;
+ }
+
+ private void releaseMusicControl() {
+ restoreMusicVolume();
+ mLowSpeedMusicTime = 0;
+ }
+
+ private int getMusicVolumeByPercent(int percent) {
+ if (MainActivity.audioManager == null)
+ return 0;
+
+ int maxVolume = MainActivity.audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+
+ percent = Math.max(0, Math.min(percent, 100));
+
+ if (percent == 0)
+ return 0;
+
+ return Math.max(1, (int) Math.round(maxVolume * percent / 100.0));
}
public void resetRideTime() {
@@ -1202,6 +1297,9 @@ void full_reset() {
void reset() {
mLowSpeedMusicTime = 0;
+ mMusicVolumeBeforeQuiet = -1;
+ mMusicVolumeChangedByWheelLog = false;
+ mMusicMutedByWheelLog = false;
mSpeed = 0;
mTorque = 0;
mMotorPower = 0;
diff --git a/app/src/main/java/com/cooper/wheellog/settings/ApplicationScreen.kt b/app/src/main/java/com/cooper/wheellog/settings/ApplicationScreen.kt
index 5b5389858..2ba38fb1c 100644
--- a/app/src/main/java/com/cooper/wheellog/settings/ApplicationScreen.kt
+++ b/app/src/main/java/com/cooper/wheellog/settings/ApplicationScreen.kt
@@ -395,15 +395,74 @@ fun applicationScreen(
appConfig.noConnectionSound = it.toInt()
}
+ var useStopMusic by remember { mutableStateOf(appConfig.useStopMusic) }
+
switchPref(
name = stringResource(R.string.use_stop_music_title),
desc = stringResource(R.string.use_stop_music_description),
themeIcon = ThemeIconEnum.SettingsAutoMute,
- default = appConfig.useStopMusic,
- showDiv = false,
+ default = useStopMusic,
+ showDiv = !useStopMusic,
) {
appConfig.useStopMusic = it
+ useStopMusic = it
+ }
+ AnimatedVisibility(visible = useStopMusic) {
+ Column {
+ sliderPref(
+ name = stringResource(R.string.stop_music_speed_title),
+ desc = stringResource(R.string.stop_music_speed_description),
+ min = 3f,
+ max = 20f,
+ position = appConfig.stopMusicSpeed.toFloat(),
+ unit = R.string.speed_unit_kmh,
+ format = "%.0f",
+ showDiv = true,
+ ) {
+ appConfig.stopMusicSpeed = it.toInt()
+ }
+
+ sliderPref(
+ name = stringResource(R.string.stop_music_low_volume_title),
+ desc = stringResource(R.string.stop_music_low_volume_description),
+ min = 0f,
+ max = 100f,
+ position = appConfig.stopMusicLowVolume.toFloat(),
+ unit = R.string.volume_unit_percent,
+ format = "%.0f",
+ showDiv = true,
+ ) {
+ appConfig.stopMusicLowVolume = it.toInt()
+ }
+
+ sliderPref(
+ name = stringResource(R.string.stop_music_restore_delay_title),
+ desc = stringResource(R.string.stop_music_restore_delay_description),
+ min = 1f,
+ max = 10f,
+ position = appConfig.stopMusicRestoreDelay.toFloat(),
+ unit = R.string.sec,
+ format = "%.0f",
+ showDiv = true,
+ ) {
+ appConfig.stopMusicRestoreDelay = it.toInt()
+ }
+
+ sliderPref(
+ name = stringResource(R.string.stop_music_high_speed_title),
+ desc = stringResource(R.string.stop_music_high_speed_description),
+ min = 20f,
+ max = 120f,
+ position = appConfig.stopMusicHighSpeed.toFloat(),
+ unit = R.string.speed_unit_kmh,
+ format = "%.0f",
+ showDiv = false,
+ ) {
+ appConfig.stopMusicHighSpeed = it.toInt()
+ }
+ }
}
+
}
group(name = stringResource(R.string.connection_category_title)) {
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 3071788b9..8c0932079 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -294,8 +294,18 @@
Измеренная на весу максимальная скорость вращения колеса
Напряжение раскрутки
Напряжение при котором измерялась скорость раскрутки
- Выключение звука
- Автовыключение звука при скорости ниже 3.5 км/ч
+ Автоприглушение музыки
+ Музыка становится тише на малой скорости и выключается на высокой
+ Минимальная скорость для обычной громкости
+ Ниже этой скорости музыка будет тише
+ Тихая громкость
+ Громкость музыки на скорости ниже минимальной
+ Задержка возврата звука
+ Через сколько секунд вернуть обычную громкость
+ Максимальная скорость для музыки
+ Выше этой скорости музыка выключается
+ км/ч
+ %
Н*м
Ограничение тока
Ограничение скорости
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 442e68df7..58718cb94 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -221,8 +221,18 @@
Play sound when Wheel connects or disconnects
Connection lost beeps period
Period of beeps when connection lost, 0sec - no beeps
- Auto mute
- Auto mute at speeds below 3.5 km/h
+ Music auto-ducking
+ Music gets quieter at low speed and is muted at high speed
+ Minimum speed for normal volume
+ Below this speed, music gets quieter
+ Quiet volume
+ Music volume below the minimum speed
+ Sound restore delay
+ How many seconds to wait before restoring normal volume
+ Maximum speed for music
+ Above this speed, music is muted
+ km/h
+ %
Battery capacity
Battery Capacity in Wh
Charging power