diff --git a/html/locales/de.json b/html/locales/de.json
index 92e4a296..331d0568 100644
--- a/html/locales/de.json
+++ b/html/locales/de.json
@@ -263,6 +263,21 @@
"gainHighPass": "Höhen (in dB)",
"info": "Die Frequenzen sind laut Bibliothek (ESP32-audioI2S) 500 Hz LowShelf, 3000 Hz PeakEQ und 6000 Hz HighShelf."
},
+ "options": {
+ "title": "Optionen",
+ "playMono": "Mono-Wiedergabe",
+ "playMonoExp": "Wenn zwei Lautsprecher verbaut sind, kann Stereo abgespielt werden. Mehr Infos hier .",
+ "savePlayPosShutdown": "Abspielposition beim Ausschalten merken",
+ "savePlayPosShutdownExp": "Beim Ausschalten der Box wird für Hörbücher die Abspielposition gespeichert. Mehr Infos hier unter SAVE_PLAYPOS_BEFORE_SHUTDOWN
.",
+ "savePlayPosRfidChange": "Abspielposition bei RFID-Tag Wechsel merken",
+ "savePlayPosRfidChangeExp": "Beim Wechsel zu einem neuen RFID-Tag wird für Hörbücher die Abspielposition gespeichert. Betrifft keine Modifikations-Tags. Mehr Infos hier unter SAVE_PLAYPOS_WHEN_RFID_CHANGE
.",
+ "pauseOnMinVolume": "Pause bei minimaler Lautstärke",
+ "pauseOnMinVolumeExp": "Die Wiedergabe wird pausiert, wenn die Lautstärke das Minimum erreicht. Mehr Infos hier .",
+ "recoverVolBoot": "Letzte Lautstärke bei Neustart verwenden",
+ "recoverVolBootExp": "Die Box erinnert sich über einen Neustart hinweg, welche Lautstärke zuletzt verwendet wurde und stellt diese automatisch wieder ein.",
+ "volumeCurve" : "Feinere Abstufungen bei niedriger Lautstärke",
+ "volumeCurveExp" : "Verwendung von logarithmischer Lautstärkeberechnung. Kann helfen, wenn im unteren Lautstärkebereich die Abstufungen zu grob sind."
+ },
"neopixel": {
"title": "Neopixel (Helligkeit)",
"restart": "Nach dem Einschalten",
diff --git a/html/locales/en.json b/html/locales/en.json
index 77e2bc2c..346c7af6 100644
--- a/html/locales/en.json
+++ b/html/locales/en.json
@@ -263,6 +263,21 @@
"gainHighPass": "Highs (in dB)",
"info": "According to the library (ESP32-audioI2S), the frequencies are 500 Hz LowShelf, 3000 Hz PeakEQ and 6000 Hz HighShelf."
},
+ "options": {
+ "title": "Options",
+ "playMono": "Mono Playback",
+ "playMonoExp": "If two speakers are installed, stereo can be played. More infos here .",
+ "savePlayPosShutdown": "Remember playback position at shutdown",
+ "savePlayPosShutdownExp": "When the box is switched off, the playback position for audio books is saved. More infos here under SAVE_PLAYPOS_BEFORE_SHUTDOWN
.",
+ "savePlayPosRfidChange": "Remember playback position at RFID tag change",
+ "savePlayPosRfidChangeExp": "When switching to a new RFID tag, the playback position is saved for audio books. Does not affect modification tags. More infos here under SAVE_PLAYPOS_WHEN_RFID_CHANGE
.",
+ "pauseOnMinVolume": "Pause at minimum volume",
+ "pauseOnMinVolumeExp": "Playback is paused when the volume reaches the minimum level. More infos here ",
+ "recoverVolBoot": "Use last volume at restart",
+ "recoverVolBootExp": "After a restart, the speaker remembers which volume was last used and automatically adjusts it again.",
+ "volumeCurve": "Finer gradations at low volume",
+ "volumeCurveExp": "Use of logarithmic volume calculation. Can help if the gradations in the lower volume range are too coarse."
+ },
"neopixel": {
"title": "Neopixel (brightness)",
"restart": "After restart",
diff --git a/html/locales/fr.json b/html/locales/fr.json
index 415ab779..8ca434fd 100644
--- a/html/locales/fr.json
+++ b/html/locales/fr.json
@@ -263,6 +263,21 @@
"gainHighPass": "Aigus (en dB)",
"info": "Les fréquences sont, selon la bibliothèque (ESP32-audioI2S), 500 Hz LowShelf, 3000 Hz PeakEQ et 6000 Hz HighShelf."
},
+ "options": {
+ "title": "Options",
+ "playMono": "Lecture mono",
+ "playMonoExp": "Si deux haut-parleurs sont installés, la stéréo peut être jouée. Plus d'infos ici .",
+ "savePlayPosShutdown": "Mémoriser la position de lecture à l'extinction",
+ "savePlayPosShutdownExp": "Lorsque la boîte est éteinte, la position de lecture est enregistrée pour les livres audio. Plus d'informations ici sous SAVE_PLAYPOS_BEFORE_SHUTDOWN
.",
+ "savePlayPosRfidChange": "Mémoriser la position de lecture au changement de tag RFID",
+ "savePlayPosRfidChangeExp": "Lors du passage à une nouvelle balise RFID, la position de lecture est enregistrée pour les livres audio. Plus d'informations ici sous SAVE_PLAYPOS_WHEN_RFID_CHANGE
.",
+ "pauseOnMinVolume": "Pause au volume minimal",
+ "pauseOnMinVolumeExp": "La lecture est mise en pause lorsque le volume atteint le minimum.Plus d'infos ici .",
+ "recoverVolBoot": "Utiliser le dernier volume au redémarrage",
+ "recoverVolBootExp": "Le boîtier se souvient, après un redémarrage, du dernier volume utilisé et le rétablit automatiquement.",
+ "volumeCurve": "Des nuances plus fines à faible volume",
+ "volumeCurveExp": "Utilisation du calcul logarithmique du volume. Peut aider si les nuances sont trop grossières dans la plage de volume inférieure."
+ },
"neopixel": {
"title": "Neopixel (luminosité)",
"restart": "Après le redémarrage",
diff --git a/html/management.html b/html/management.html
index 943aa69a..e212a033 100644
--- a/html/management.html
+++ b/html/management.html
@@ -940,6 +940,41 @@
+
@@ -1280,6 +1315,11 @@
document.querySelector('#langSel').value = lng;
if (localize) {
localize('body');
+ // (re)initialize all popover buttons to get correct translations in the popovers
+ document.querySelectorAll('[data-bs-toggle="popover"]')
+ .forEach(popoverButton => {
+ new bootstrap.Popover(popoverButton, {html: true, trigger: 'focus'})
+ });
}
$('#navMenu').removeClass("show"); // Hide the menu again
});
@@ -2019,6 +2059,12 @@
$('#maxVolumeSpeaker').bootstrapSlider('setValue', genSettings.maxVolumeSp);
$('#maxVolumeHeadphone').bootstrapSlider('setValue', genSettings.maxVolumeHp);
$('#inactivityTime').bootstrapSlider('setValue', genSettings.sleepInactivity);
+ $('#playMono').prop('checked', genSettings.playMono);
+ $('#savePlayPosShutdown').prop('checked', genSettings.savePosShutdown);
+ $('#savePlayPosRfidChange').prop('checked', genSettings.savePosRfidChg);
+ $('#pauseOnMinVolume').prop('checked', genSettings.pauseOnMinVol);
+ $('#recoverVolBoot').prop('checked', genSettings.recoverVolBoot);
+ $('#volumeCurve').prop('checked', genSettings.volumeCurve > 0);
}
// current values
let currSettings = settings.current;
@@ -2026,29 +2072,6 @@
document.getElementById("rfidIdMusic").value = currSettings.rfidTagId;
volumeSlider.setValue(currSettings.volume);
}
- // default (factory) settings
- let defSettings = settings.defaults;
- if (defSettings) {
- $('#initialVolume').bootstrapSlider('setValue', defSettings.initVolume);
- $('#maxVolumeSpeaker').bootstrapSlider('setValue', defSettings.maxVolumeSp);
- $('#maxVolumeHeadphone').bootstrapSlider('setValue', defSettings.maxVolumeHp);
- $('#inactivityTime').bootstrapSlider('setValue', defSettings.sleepInactivity);
- $('#initBrightness').bootstrapSlider('setValue', defSettings.initBrightness);
- $('#nightBrightness').bootstrapSlider('setValue', defSettings.nightBrightness);
- $('#warningLowVoltage').bootstrapSlider('setValue', defSettings.warnLowVoltage);
- $('#voltageIndicatorLow').bootstrapSlider('setValue', defSettings.indicatorLow);
- $('#voltageIndicatorHigh').bootstrapSlider('setValue', defSettings.indicatorHi);
- $('#voltageCheckInterval').bootstrapSlider('setValue', defSettings.voltageCheckInterval);
- $('#criticalVoltage').bootstrapSlider('setValue', defSettings.criticalVoltage);
- $("#playlistSortMode").val(defSettings.sortMode).change();
- $("#gainLowPass").bootstrapSlider('setValue', defSettings.gainLowPass);
- $("#gainBandPass").bootstrapSlider('setValue', defSettings.gainBandPass);
- $("#gainHighPass").bootstrapSlider('setValue', defSettings.gainHighPass);
- // If there is any better way to overwrite the bootstrap slider tooltip - please change this abdomination!
- formatDBTooltip($('#gainLowPass')[0].previousSibling, defSettings.gainLowPass);
- formatDBTooltip($('#gainBandPass')[0].previousSibling, defSettings.gainBandPass);
- formatDBTooltip($('#gainHighPass')[0].previousSibling, defSettings.gainHighPass);
- }
let eqSettings = settings.equalizer;
if (eqSettings) {
$("#gainLowPass").bootstrapSlider('setValue', eqSettings.gainLowPass);
@@ -2345,24 +2368,30 @@
lastIdclicked = clickedId;
var myObj = {
"general": {
- initVolume: Number(document.getElementById('initialVolume').value),
- maxVolumeSp: Number(document.getElementById('maxVolumeSpeaker').value),
- maxVolumeHp: Number(document.getElementById('maxVolumeHeadphone').value),
- sleepInactivity: Number(document.getElementById('inactivityTime').value)
+ initVolume: Number($('#initialVolume').val()),
+ maxVolumeSp: Number($('#maxVolumeSpeaker').val()),
+ maxVolumeHp: Number($('#maxVolumeHeadphone').val()),
+ sleepInactivity: Number($('#inactivityTime').val()),
+ playMono: $('#playMono').prop('checked'),
+ savePosShutdown: $('#savePlayPosShutdown').prop('checked'),
+ savePosRfidChg: $('#savePlayPosRfidChange').prop('checked'),
+ pauseOnMinVol: $('#pauseOnMinVolume').prop('checked'),
+ recoverVolBoot: $('#recoverVolBoot').prop('checked'),
+ volumeCurve: $("#volumeCurve").prop('checked') ? 1 : 0
},
"led": {
- initBrightness: Number(document.getElementById('initBrightness').value),
- nightBrightness: Number(document.getElementById('nightBrightness').value)
+ initBrightness: Number($('#initBrightness').val()),
+ nightBrightness: Number($('#nightBrightness').val())
},
"battery": {
- warnLowVoltage: Number(document.getElementById('warningLowVoltage').value),
- indicatorLow: Number(document.getElementById('voltageIndicatorLow').value),
- indicatorHi: Number(document.getElementById('voltageIndicatorHigh').value),
- criticalVoltage: Number(document.getElementById('criticalVoltage').value),
- voltageCheckInterval: Number(document.getElementById('voltageCheckInterval').value)
+ warnLowVoltage: Number($('#warningLowVoltage').val()),
+ indicatorLow: Number($('#voltageIndicatorLow').val()),
+ indicatorHi: Number($('#voltageIndicatorHigh').val()),
+ criticalVoltage: Number($('#criticalVoltage').val()),
+ voltageCheckInterval: Number($('#voltageCheckInterval').val())
},
"playlist": {
- sortMode: Number(document.getElementById('playlistSortMode').value)
+ sortMode: Number($('#playlistSortMode').val())
}
};
var myJSON = JSON.stringify(myObj);
diff --git a/src/AudioPlayer.cpp b/src/AudioPlayer.cpp
index ecc6e991..46da89f0 100644
--- a/src/AudioPlayer.cpp
+++ b/src/AudioPlayer.cpp
@@ -80,19 +80,20 @@ void AudioPlayer_Init(void) {
uint8_t playListSortModeValue = gPrefsSettings.getUChar("PLSortMode", EnumUtils::underlying_value(AudioPlayer_PlaylistSortMode));
AudioPlayer_PlaylistSortMode = EnumUtils::to_enum(playListSortModeValue);
-#ifndef USE_LAST_VOLUME_AFTER_REBOOT
- // Get initial volume from NVS
- uint32_t nvsInitialVolume = gPrefsSettings.getUInt("initVolume", 0);
-#else
- // Get volume used at last shutdown
- uint32_t nvsInitialVolume = gPrefsSettings.getUInt("previousVolume", 999);
- if (nvsInitialVolume == 999) {
- gPrefsSettings.putUInt("previousVolume", AudioPlayer_GetInitVolume());
- nvsInitialVolume = AudioPlayer_GetInitVolume();
+ uint32_t nvsInitialVolume;
+ if (!gPrefsSettings.getBool("recoverVolBoot", false)) {
+ // Get initial volume from NVS
+ nvsInitialVolume = gPrefsSettings.getUInt("initVolume", 0);
} else {
- Log_Println(rememberLastVolume, LOGLEVEL_ERROR);
+ // Get volume used at last shutdown
+ nvsInitialVolume = gPrefsSettings.getUInt("previousVolume", 999);
+ if (nvsInitialVolume == 999) {
+ gPrefsSettings.putUInt("previousVolume", AudioPlayer_GetInitVolume());
+ nvsInitialVolume = AudioPlayer_GetInitVolume();
+ } else {
+ Log_Println(rememberLastVolume, LOGLEVEL_ERROR);
+ }
}
-#endif
if (nvsInitialVolume) {
AudioPlayer_SetInitVolume(nvsInitialVolume);
@@ -141,6 +142,8 @@ void AudioPlayer_Init(void) {
gPlayProperties.coverFilePos = 0;
AudioPlayer_StationLogoUrl = "";
gPlayProperties.playlist = new Playlist();
+ gPlayProperties.SavePlayPosRfidChange = gPrefsSettings.getBool("savePosRfidChge", false); // SAVE_PLAYPOS_WHEN_RFID_CHANGE
+ gPlayProperties.pauseOnMinVolume = gPrefsSettings.getBool("pauseOnMinVol", false); // PAUSE_ON_MIN_VOLUME
// Don't start audio-task in BT-speaker mode!
if ((System_GetOperationMode() == OPMODE_NORMAL) || (System_GetOperationMode() == OPMODE_BLUETOOTH_SOURCE)) {
@@ -161,15 +164,13 @@ void AudioPlayer_Exit(void) {
// save playtime total to NVS
playTimeSecTotal += playTimeSecSinceStart;
gPrefsSettings.putULong("playTimeTotal", playTimeSecTotal);
-// Make sure last playposition for audiobook is saved when playback is active while shutdown was initiated
-#ifdef SAVE_PLAYPOS_BEFORE_SHUTDOWN
- if (!gPlayProperties.pausePlay && (gPlayProperties.playMode == AUDIOBOOK || gPlayProperties.playMode == AUDIOBOOK_LOOP)) {
+ // Make sure last playposition for audiobook is saved when playback is active while shutdown was initiated
+ if (gPrefsSettings.getBool("savePosShutdown", false) && !gPlayProperties.pausePlay && (gPlayProperties.playMode == AUDIOBOOK || gPlayProperties.playMode == AUDIOBOOK_LOOP)) {
AudioPlayer_TrackControlToQueueSender(PAUSEPLAY);
while (!gPlayProperties.pausePlay) { // Make sure to wait until playback is paused in order to be sure that playposition saved in NVS
vTaskDelay(portTICK_PERIOD_MS * 100u);
}
}
-#endif
}
static uint32_t lastPlayingTimestamp = 0;
@@ -283,13 +284,8 @@ void Audio_setTitle(const char *format, ...) {
// Set maxVolume depending on headphone-adjustment is enabled and headphone is/is not connected
// Enable/disable PA/HP-amps initially
void AudioPlayer_SetupVolumeAndAmps(void) {
-#ifdef PLAY_MONO_SPEAKER
- gPlayProperties.currentPlayMono = true;
- gPlayProperties.newPlayMono = true;
-#else
- gPlayProperties.currentPlayMono = false;
- gPlayProperties.newPlayMono = false;
-#endif
+ gPlayProperties.currentPlayMono = gPrefsSettings.getBool("playMono", false);
+ gPlayProperties.newPlayMono = gPrefsSettings.getBool("playMono", false);
#ifndef HEADPHONE_ADJUST_ENABLE
AudioPlayer_MaxVolume = AudioPlayer_MaxVolumeSpeaker;
@@ -332,11 +328,7 @@ void AudioPlayer_HeadphoneVolumeManager(void) {
if (AudioPlayer_HeadphoneLastDetectionState != currentHeadPhoneDetectionState && (millis() - AudioPlayer_HeadphoneLastDetectionTimestamp >= headphoneLastDetectionDebounce)) {
if (currentHeadPhoneDetectionState) {
AudioPlayer_MaxVolume = AudioPlayer_MaxVolumeSpeaker;
- #ifdef PLAY_MONO_SPEAKER
- gPlayProperties.newPlayMono = true;
- #else
- gPlayProperties.newPlayMono = false;
- #endif
+ gPlayProperties.newPlayMono = gPrefsSettings.getBool("playMono", false);
#ifdef GPIO_PA_EN
Port_Write(GPIO_PA_EN, true, false);
@@ -391,7 +383,7 @@ void AudioPlayer_Task(void *parameter) {
AudioPlayer_CurrentVolume = AudioPlayer_GetInitVolume();
audio->setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio->setVolumeSteps(AUDIOPLAYER_VOLUME_MAX);
- audio->setVolume(AudioPlayer_CurrentVolume, VOLUMECURVE);
+ audio->setVolume(AudioPlayer_CurrentVolume, gPrefsSettings.getUChar("volumeCurve", 0));
audio->forceMono(gPlayProperties.currentPlayMono);
int8_t currentEqualizer[3] = {gPrefsSettings.getChar("gainLowPass", 0), gPrefsSettings.getChar("gainBandPass", 0), gPrefsSettings.getChar("gainHighPass", 0)};
audio->setTone(currentEqualizer[0], currentEqualizer[1], currentEqualizer[2]);
@@ -412,7 +404,7 @@ void AudioPlayer_Task(void *parameter) {
*/
if (xQueueReceive(gVolumeQueue, ¤tVolume, 0) == pdPASS) {
Log_Printf(LOGLEVEL_INFO, newLoudnessReceivedQueue, currentVolume);
- audio->setVolume(currentVolume, VOLUMECURVE);
+ audio->setVolume(currentVolume, gPrefsSettings.getUChar("volumeCurve", 0));
Web_SendWebsocketData(0, WebsocketCodeType::Volume);
#ifdef MQTT_ENABLE
publishMqtt(topicLoudnessState, currentVolume, false);
@@ -973,36 +965,34 @@ void AudioPlayer_EqualizerToQueueSender(const int8_t gainLowPass, const int8_t g
// Pauses playback if playback is active and volume is changes from minVolume+1 to minVolume (usually 0)
void AudioPlayer_PauseOnMinVolume(const uint8_t oldVolume, const uint8_t newVolume) {
-#ifdef PAUSE_ON_MIN_VOLUME
- if (gPlayProperties.playMode == BUSY || gPlayProperties.playMode == NO_PLAYLIST) {
- return;
- }
+ if (gPlayProperties.pauseOnMinVolume) {
+ if (gPlayProperties.playMode == BUSY || gPlayProperties.playMode == NO_PLAYLIST) {
+ return;
+ }
- if (!gPlayProperties.pausePlay) { // Volume changes from 1 to 0
- if (oldVolume == AudioPlayer_GetMinVolume() + 1 && newVolume == AudioPlayer_GetMinVolume()) {
- Cmd_Action(CMD_PLAYPAUSE);
+ if (!gPlayProperties.pausePlay) { // Volume changes from 1 to 0
+ if (oldVolume == AudioPlayer_GetMinVolume() + 1 && newVolume == AudioPlayer_GetMinVolume()) {
+ Cmd_Action(CMD_PLAYPAUSE);
+ }
}
- }
- if (gPlayProperties.pausePlay) { // Volume changes from 0 to 1
- if (oldVolume == AudioPlayer_GetMinVolume() && newVolume > AudioPlayer_GetMinVolume()) {
- Cmd_Action(CMD_PLAYPAUSE);
+ if (gPlayProperties.pausePlay) { // Volume changes from 0 to 1
+ if (oldVolume == AudioPlayer_GetMinVolume() && newVolume > AudioPlayer_GetMinVolume()) {
+ Cmd_Action(CMD_PLAYPAUSE);
+ }
}
}
-#endif
}
// Receives de-serialized RFID-data (from NVS) and dispatches playlists for the given
// playmode to the track-queue.
void AudioPlayer_TrackQueueDispatcher(const char *_itemToPlay, const uint32_t _lastPlayPos, const uint32_t _playMode, const uint16_t _trackLastPlayed) {
-// Make sure last playposition for audiobook is saved when new RFID-tag is applied
-#ifdef SAVE_PLAYPOS_WHEN_RFID_CHANGE
- if (!gPlayProperties.pausePlay && (gPlayProperties.playMode == AUDIOBOOK || gPlayProperties.playMode == AUDIOBOOK_LOOP)) {
+ // Make sure last playposition for audiobook is saved when new RFID-tag is applied
+ if (gPlayProperties.SavePlayPosRfidChange && !gPlayProperties.pausePlay && (gPlayProperties.playMode == AUDIOBOOK || gPlayProperties.playMode == AUDIOBOOK_LOOP)) {
AudioPlayer_TrackControlToQueueSender(PAUSEPLAY);
while (!gPlayProperties.pausePlay) { // Make sure to wait until playback is paused in order to be sure that playposition saved in NVS
vTaskDelay(portTICK_PERIOD_MS * 100u);
}
}
-#endif
gPlayProperties.startAtFilePos = _lastPlayPos;
gPlayProperties.currentTrackNumber = _trackLastPlayed;
diff --git a/src/AudioPlayer.h b/src/AudioPlayer.h
index ff4a4b19..01c5bd3b 100644
--- a/src/AudioPlayer.h
+++ b/src/AudioPlayer.h
@@ -39,6 +39,8 @@ typedef struct { // Bit field
uint8_t tellMode : 2; // Tell mode for text to speech announcments
bool currentSpeechActive : 1; // If speech-play is active
bool lastSpeechActive : 1; // If speech-play was active
+ bool SavePlayPosRfidChange : 1; // Save last play-position
+ bool pauseOnMinVolume : 1; // When playback is active and volume is changed to zero, playback is paused automatically.
int8_t gainLowPass = 0; // Low Pass for EQ Control
int8_t gainBandPass = 0; // Band Pass for EQ Control
int8_t gainHighPass = 0; // High Pass for EQ Control
diff --git a/src/Bluetooth.cpp b/src/Bluetooth.cpp
index e4f8bcbc..ce27f1d8 100644
--- a/src/Bluetooth.cpp
+++ b/src/Bluetooth.cpp
@@ -202,9 +202,9 @@ void Bluetooth_Init(void) {
a2dp_sink->set_rssi_callback(rssi);
#endif
a2dp_sink->activate_pin_code(false);
- #ifdef PLAY_MONO_SPEAKER
- a2dp_sink->set_mono_downmix(true);
- #endif
+ if (gPrefsSettings.getBool("playMono", false)) {
+ a2dp_sink->set_mono_downmix(true);
+ }
a2dp_sink->set_auto_reconnect(true);
a2dp_sink->set_rssi_active(true);
// start bluetooth sink
diff --git a/src/System.cpp b/src/System.cpp
index e1c898e7..66393e47 100644
--- a/src/System.cpp
+++ b/src/System.cpp
@@ -193,9 +193,9 @@ void System_PreparePowerDown(void) {
Mqtt_Exit();
Led_Exit();
-#ifdef USE_LAST_VOLUME_AFTER_REBOOT
- gPrefsSettings.putUInt("previousVolume", AudioPlayer_GetCurrentVolume());
-#endif
+ if (gPrefsSettings.getBool("recoverVolBoot", false)) {
+ gPrefsSettings.putUInt("previousVolume", AudioPlayer_GetCurrentVolume());
+ }
SdCard_Exit();
Serial.flush();
diff --git a/src/Web.cpp b/src/Web.cpp
index 3f36f939..e84ed0e8 100644
--- a/src/Web.cpp
+++ b/src/Web.cpp
@@ -636,10 +636,13 @@ bool JSONToSettings(JsonObject doc) {
}
if (doc.containsKey("general")) {
// general settings
- if (gPrefsSettings.putUInt("initVolume", doc["general"]["initVolume"].as()) == 0 || gPrefsSettings.putUInt("maxVolumeSp", doc["general"]["maxVolumeSp"].as()) == 0 || gPrefsSettings.putUInt("maxVolumeHp", doc["general"]["maxVolumeHp"].as()) == 0 || gPrefsSettings.putUInt("mInactiviyT", doc["general"]["sleepInactivity"].as()) == 0) {
+ if (gPrefsSettings.putUInt("initVolume", doc["general"]["initVolume"].as()) == 0 || gPrefsSettings.putUInt("maxVolumeSp", doc["general"]["maxVolumeSp"].as()) == 0 || gPrefsSettings.putUInt("maxVolumeHp", doc["general"]["maxVolumeHp"].as()) == 0 || gPrefsSettings.putUInt("mInactiviyT", doc["general"]["sleepInactivity"].as()) == 0 || gPrefsSettings.putBool("playMono", doc["general"]["playMono"].as()) == 0 || gPrefsSettings.putBool("savePosShutdown", doc["general"]["savePosShutdown"].as()) == 0 || gPrefsSettings.putBool("savePosRfidChge", doc["general"]["savePosRfidChge"].as()) == 0 || gPrefsSettings.putBool("pauseOnMinVol", doc["general"]["pauseOnMinVol"].as()) == 0 || gPrefsSettings.putBool("recoverVolBoot", doc["general"]["recoverVolBoot"].as()) == 0 || gPrefsSettings.putUChar("volumeCurve", doc["general"]["volumeCurve"].as()) == 0) {
Log_Printf(LOGLEVEL_ERROR, webSaveSettingsError, "general");
return false;
}
+ gPlayProperties.newPlayMono = doc["general"]["playMono"].as();
+ gPlayProperties.SavePlayPosRfidChange = doc["general"]["savePosRfidChg"].as();
+ gPlayProperties.pauseOnMinVolume = doc["general"]["pauseOnMinVol"].as();
}
if (doc.containsKey("equalizer")) {
int8_t _gainLowPass = doc["equalizer"]["gainLowPass"].as();
@@ -824,6 +827,12 @@ static void settingsToJSON(JsonObject obj, const String section) {
generalObj["maxVolumeSp"].set(gPrefsSettings.getUInt("maxVolumeSp", 0));
generalObj["maxVolumeHp"].set(gPrefsSettings.getUInt("maxVolumeHp", 0));
generalObj["sleepInactivity"].set(gPrefsSettings.getUInt("mInactiviyT", 0));
+ generalObj["playMono"].set(gPrefsSettings.getBool("playMono", false));
+ generalObj["savePosShutdown"].set(gPrefsSettings.getBool("savePosShutdown", false)); // SAVE_PLAYPOS_BEFORE_SHUTDOWN
+ generalObj["savePosRfidChge"].set(gPrefsSettings.getBool("savePosRfidChge", false)); // SAVE_PLAYPOS_WHEN_RFID_CHANGE
+ generalObj["pauseOnMinVol"].set(gPrefsSettings.getBool("pauseOnMinVol", false)); // PAUSE_ON_MIN_VOLUME
+ generalObj["recoverVolBoot"].set(gPrefsSettings.getBool("recoverVolBoot", false)); // USE_LAST_VOLUME_AFTER_REBOOT
+ generalObj["volumeCurve"].set(gPrefsSettings.getUChar("volumeCurve", 0)); // VOLUMECURVE
}
if ((section == "") || (section == "equalizer")) {
// equalizer settings
@@ -881,30 +890,41 @@ static void settingsToJSON(JsonObject obj, const String section) {
}
#endif
if (section == "defaults") {
- // default factory settings
+ // default factory settings NOTE: maintain the settings section structure as above to make it easier for clients to use
JsonObject defaultsObj = obj.createNestedObject("defaults");
- defaultsObj["initVolume"].set(3u); // AUDIOPLAYER_VOLUME_INIT
- defaultsObj["maxVolumeSp"].set(21u); // AUDIOPLAYER_VOLUME_MAX
- defaultsObj["maxVolumeHp"].set(18u); // gPrefsSettings.getUInt("maxVolumeHp", 0));
- defaultsObj["sleepInactivity"].set(10u); // System_MaxInactivityTime
- defaultsObj["gainHighPass"].set(0);
- defaultsObj["gainBandPass"].set(0);
- defaultsObj["gainLowPass"].set(0);
+ JsonObject genSettings = defaultsObj.createNestedObject("general");
+ genSettings["initVolume"].set(3u); // AUDIOPLAYER_VOLUME_INIT
+ genSettings["maxVolumeSp"].set(21u); // AUDIOPLAYER_VOLUME_MAX
+ genSettings["maxVolumeHp"].set(18u); // gPrefsSettings.getUInt("maxVolumeHp", 0));
+ genSettings["sleepInactivity"].set(10u); // System_MaxInactivityTime
+ genSettings["playMono"].set(false); // PLAY_MONO_SPEAKER
+ genSettings["savePosShutdown"].set(false); // SAVE_PLAYPOS_BEFORE_SHUTDOWN
+ genSettings["savePosRfidChg"].set(false); // SAVE_PLAYPOS_WHEN_RFID_CHANGE
+ genSettings["pauseOnMinVol"].set(false); // PAUSE_ON_MIN_VOLUME
+ genSettings["recoverVolBoot"].set(false); // USE_LAST_VOLUME_AFTER_REBOOT
+ genSettings["volumeCurve"].set(0u); // VOLUME_CURVE
+ JsonObject eqSettings = defaultsObj.createNestedObject("equalizer");
+ eqSettings["gainHighPass"].set(0);
+ eqSettings["gainBandPass"].set(0);
+ eqSettings["gainLowPass"].set(0);
#ifdef NEOPIXEL_ENABLE
- defaultsObj["initBrightness"].set(16u); // LED_INITIAL_BRIGHTNESS
- defaultsObj["nightBrightness"].set(2u); // LED_INITIAL_NIGHT_BRIGHTNESS
+ JsonObject ledSettings = defaultsObj.createNestedObject("led");
+ ledSettings["initBrightness"].set(16u); // LED_INITIAL_BRIGHTNESS
+ ledSettings["nightBrightness"].set(2u); // LED_INITIAL_NIGHT_BRIGHTNESS
#endif
- defaultsObj["sortMode"].set(EnumUtils::underlying_value(AUDIOPLAYER_PLAYLIST_SORT_MODE_DEFAULT));
+ JsonObject playlistSettings = defaultsObj.createNestedObject("playlist");
+ playlistSettings["sortMode"].set(EnumUtils::underlying_value(AUDIOPLAYER_PLAYLIST_SORT_MODE_DEFAULT));
#ifdef BATTERY_MEASURE_ENABLE
+ JsonObject batSettings = defaultsObj.createNestedObject("battery");
#ifdef MEASURE_BATTERY_VOLTAGE
- defaultsObj["warnLowVoltage"].set(s_warningLowVoltage);
- defaultsObj["indicatorLow"].set(s_voltageIndicatorLow);
- defaultsObj["indicatorHi"].set(s_voltageIndicatorHigh);
+ batSettings["warnLowVoltage"].set(s_warningLowVoltage);
+ batSettings["indicatorLow"].set(s_voltageIndicatorLow);
+ batSettings["indicatorHi"].set(s_voltageIndicatorHigh);
#ifdef SHUTDOWN_ON_BAT_CRITICAL
- defaultsObj["criticalVoltage"].set(s_warningCriticalVoltage);
+ batSettings["criticalVoltage"].set(s_warningCriticalVoltage);
#endif
#endif
- defaultsObj["voltageCheckInterval"].set(s_batteryCheckInterval);
+ batSettings["voltageCheckInterval"].set(s_batteryCheckInterval);
#endif
}
// FTP
diff --git a/src/settings-override.h.sample b/src/settings-override.h.sample
index 574326f2..804b572a 100644
--- a/src/settings-override.h.sample
+++ b/src/settings-override.h.sample
@@ -44,17 +44,12 @@
//#define MEASURE_BATTERY_MAX17055 // Enables battery-measurement via external fuel gauge (MAX17055)
//#define SHUTDOWN_ON_BAT_CRITICAL // Whether to turn off on critical battery-level (only used if MEASURE_BATTERY_XXX is active)
//#define PLAY_LAST_RFID_AFTER_REBOOT // When restarting ESPuino, the last RFID that was active before, is recalled and played
- //#define USE_LAST_VOLUME_AFTER_REBOOT // Remembers the volume used at last shutdown after reboot
#define USEROTARY_ENABLE // If rotary-encoder is used (don't forget to review WAKEUP_BUTTON if you disable this feature!)
#define BLUETOOTH_ENABLE // If enabled and bluetooth-mode is active, you can stream to your ESPuino or to a headset via bluetooth (a2dp-sink & a2dp-source). Note: This feature consumes a lot of resources and the available flash/ram might not be sufficient.
//#define IR_CONTROL_ENABLE // Enables remote control (https://forum.espuino.de/t/neues-feature-fernsteuerung-per-infrarot-fernbedienung/265)
//#define PAUSE_WHEN_RFID_REMOVED // Playback starts when card is applied and pauses automatically, when card is removed (https://forum.espuino.de/t/neues-feature-pausieren-wenn-rfid-karte-entfernt-wurde/541)
- //#define PAUSE_ON_MIN_VOLUME // When playback is active and volume is changed to zero, playback is paused automatically. Playback is continued if volume reaches 1. (https://forum.espuino.de/t/neues-feature-pausieren-wenn-rfid-karte-entfernt-wurde/541)
//#define DONT_ACCEPT_SAME_RFID_TWICE // RFID-reader doesn't accept the same RFID-tag twice in a row (unless it's a modification-card or RFID-tag is unknown in NVS). Flag will be ignored silently if PAUSE_WHEN_RFID_REMOVED is active. (https://forum.espuino.de/t/neues-feature-dont-accept-same-rfid-twice/1247)
- //#define SAVE_PLAYPOS_BEFORE_SHUTDOWN // When playback is active and mode audiobook was selected, last play-position is saved automatically when shutdown is initiated
- //#define SAVE_PLAYPOS_WHEN_RFID_CHANGE // When playback is active and mode audiobook was selected, last play-position is saved automatically for old playlist when new RFID-tag is applied
//#define HALLEFFECT_SENSOR_ENABLE // Support for hallsensor. For fine-tuning please adjust HallEffectSensor.h Please note: only user-support provided (https://forum.espuino.de/t/magnetische-hockey-tags/1449/35)
- #define VOLUMECURVE 0 // 0=square, 1=logarithmic (1 is more flatten at lower volume)
//################## set PAUSE_WHEN_RFID_REMOVED behaviour #############################
#ifdef PAUSE_WHEN_RFID_REMOVED
diff --git a/src/settings.h b/src/settings.h
index 26c0e0a0..e5f87e37 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -49,17 +49,12 @@
//#define MEASURE_BATTERY_MAX17055 // Enables battery-measurement via external fuel gauge (MAX17055)
//#define SHUTDOWN_ON_BAT_CRITICAL // Whether to turn off on critical battery-level (only used if MEASURE_BATTERY_XXX is active)
//#define PLAY_LAST_RFID_AFTER_REBOOT // When restarting ESPuino, the last RFID that was active before, is recalled and played
- //#define USE_LAST_VOLUME_AFTER_REBOOT // Remembers the volume used at last shutdown after reboot
#define USEROTARY_ENABLE // If rotary-encoder is used (don't forget to review WAKEUP_BUTTON if you disable this feature!)
//#define BLUETOOTH_ENABLE // If enabled and bluetooth-mode is active, you can stream to your ESPuino or to a headset via bluetooth (a2dp-sink & a2dp-source). Note: This feature consumes a lot of resources and the available flash/ram might not be sufficient.
//#define IR_CONTROL_ENABLE // Enables remote control (https://forum.espuino.de/t/neues-feature-fernsteuerung-per-infrarot-fernbedienung/265)
//#define PAUSE_WHEN_RFID_REMOVED // Playback starts when card is applied and pauses automatically, when card is removed (https://forum.espuino.de/t/neues-feature-pausieren-wenn-rfid-karte-entfernt-wurde/541)
- //#define PAUSE_ON_MIN_VOLUME // When playback is active and volume is changed to zero, playback is paused automatically. Playback is continued if volume reaches 1. (https://forum.espuino.de/t/neues-feature-pausieren-wenn-rfid-karte-entfernt-wurde/541)
//#define DONT_ACCEPT_SAME_RFID_TWICE // RFID-reader doesn't accept the same RFID-tag twice in a row (unless it's a modification-card or RFID-tag is unknown in NVS). Flag will be ignored silently if PAUSE_WHEN_RFID_REMOVED is active. (https://forum.espuino.de/t/neues-feature-dont-accept-same-rfid-twice/1247)
- //#define SAVE_PLAYPOS_BEFORE_SHUTDOWN // When playback is active and mode audiobook was selected, last play-position is saved automatically when shutdown is initiated
- //#define SAVE_PLAYPOS_WHEN_RFID_CHANGE // When playback is active and mode audiobook was selected, last play-position is saved automatically for old playlist when new RFID-tag is applied
//#define HALLEFFECT_SENSOR_ENABLE // Support for hallsensor. For fine-tuning please adjust HallEffectSensor.h Please note: only user-support provided (https://forum.espuino.de/t/magnetische-hockey-tags/1449/35)
- #define VOLUMECURVE 0 // 0=square, 1=logarithmic (1 is more flatten at lower volume)
//################## set PAUSE_WHEN_RFID_REMOVED behaviour #############################
#ifdef PAUSE_WHEN_RFID_REMOVED
@@ -73,9 +68,9 @@
//################## select RFID reader ##############################
- #define RFID_READER_TYPE_MFRC522_SPI // use MFRC522 via SPI
+ #define RFID_READER_TYPE_MFRC522_SPI // use MFRC522 via SPI
//#define RFID_READER_TYPE_MFRC522_I2C // use MFRC522 via I2C
- //#define RFID_READER_TYPE_PN5180 // use PN5180 via SPI
+ //#define RFID_READER_TYPE_PN5180 // use PN5180 via SPI
#ifdef RFID_READER_TYPE_MFRC522_I2C
#define MFRC522_ADDR 0x28 // default I2C-address of MFRC522
@@ -224,7 +219,7 @@
#define PROGRESS_HUE_START 85 // Start and end hue of mulitple-LED progress indicator. Hue ranges from basically 0 - 255, but you can also set numbers outside this range to get the desired effect (e.g. 85-215 will go from green to purple via blue, 341-215 start and end at exactly the same color but go from green to purple via yellow and red)
#define PROGRESS_HUE_END -1
#define DIMMABLE_STATES 50 // Number of dimmed values between two full LEDs (https://forum.espuino.de/t/led-verbesserungen-rework/1739)
- //#define LED_OFFSET 0 // shifts the starting LED in the original direction of the neopixel ring
+ //#define LED_OFFSET 0 // shifts the starting LED in the original direction of the neopixel ring
#endif
#if defined(MEASURE_BATTERY_VOLTAGE) || defined(MEASURE_BATTERY_MAX17055)