Fix root cause of audio profile never persisting; document ADAU1701 registers
Root cause (found via SigmaStudio firmware analysis requested this session): NVS was initialized AFTER HardwareBootstrap::boot(), which internally calls AudioService::loadAndApply() to restore the saved mixer/EQ/master-volume profile. Every nvs_open() inside NvsAudioProfileStore::hasProfile()/loadProfile() failed with ESP_ERR_NVS_NOT_INITIALIZED (0x1101), silently swallowed as "no saved profile" -- the audio profile was never actually restored on any boot, regardless of how many times it was saved via PUT /api/audio/profile. Fixed by moving secure_store::initEncryptedStorage() to the top of app_main(), before HardwareBootstrap::boot() (nvs_flash_init() has no hardware dependency, so this is safe). Second, related bug: HardwareBootstrap::boot() called AudioService::applyRadioFirstMix() unconditionally right after loadAndApply(), discarding any just-restored mixer/master values on every boot. loadAndApply() now returns whether it actually restored a profile from NVS; the radio-first fallback only applies when nothing was saved. Verified live: a distinct mixer+master+5-EQ-band test pattern now survives a full reboot exactly as saved (previously always reset to factory default). DAB/FM/BT unaffected. Also: added a "locked" flag per EQ band in the audio profile JSON -- band 0 is always locked (fixed high-pass, Adau1701Driver::applyEq() never safeloads it) and bands 1-2/3-5 are locked whenever bass_level/stereo_level is active (core::applyEnhancementsToEq() overwrites them with formula-derived values). This was previously undiscoverable from the API -- GET echoed back the stored, inert value with no indication it wasn't what was actually playing. Full register-by-register analysis of the compiled SigmaStudio program (signal chain, all 74 Parameter RAM addresses grouped by function, HTTP API mapping, every endpoint tested live) in docs/adau1701-sigmastudio-analysis.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -253,13 +253,22 @@ std::expected<void, HardwareBootError> HardwareBootstrap::boot()
|
||||
"auto-tune");
|
||||
}
|
||||
|
||||
if (auto audioResult = gAudioService.loadAndApply(); !audioResult) {
|
||||
// Only fall back to the hardcoded radio-first mix (Si4684 open, ESP32
|
||||
// muted) when NO saved profile was restored (2026-08-24 fix): this used
|
||||
// to run unconditionally, silently discarding the user's saved
|
||||
// mixer/master-volume settings on every single boot regardless of
|
||||
// whether loadAndApply() actually found something in NVS.
|
||||
const auto audioResult = gAudioService.loadAndApply();
|
||||
if (!audioResult) {
|
||||
ESP_LOGW(kTag, "ADAU1701 profile apply failed");
|
||||
}
|
||||
if (auto radioMix = gAudioService.applyRadioFirstMix(false); !radioMix) {
|
||||
ESP_LOGW(kTag, "ADAU1701 radio-first mix failed");
|
||||
} else {
|
||||
ESP_LOGI(kTag, "ADAU1701 Si4684 input routed (radio-first mix)");
|
||||
} else if (!*audioResult) {
|
||||
if (auto radioMix = gAudioService.applyRadioFirstMix(false);
|
||||
!radioMix) {
|
||||
ESP_LOGW(kTag, "ADAU1701 radio-first mix failed");
|
||||
} else {
|
||||
ESP_LOGI(kTag, "ADAU1701 Si4684 input routed (radio-first mix, "
|
||||
"no saved profile)");
|
||||
}
|
||||
}
|
||||
|
||||
if (auto btResult = gBt1035.boot(); !btResult) {
|
||||
|
||||
Reference in New Issue
Block a user