| 630 | struct LiveAudioEnv : AudioConfig::Environment |
| 631 | { |
| 632 | const SoundSystemOAL* sys; |
| 633 | explicit LiveAudioEnv(const SoundSystemOAL* s) : sys(s) {} |
| 634 | std::vector<std::string> ListOutputDevices() const override |
| 635 | { |
| 636 | return sys ? sys->ListOutputDevices() : std::vector<std::string>{}; |
| 637 | } |
| 638 | std::vector<std::string> ListInputDevices() const override { return VoNCapture::listDevices(); } |
| 639 | }; |
| 640 | } // namespace |
| 641 | |
| 642 | void SoundSystemOAL::LoadConfig() |
| 643 | { |
| 644 | const std::string path = AudioConfigPath(); |
| 645 | |
| 646 | AudioConfig cfg; |
| 647 | if (!cfg.Load(path)) |
| 648 | { |
| 649 | // Missing or unparseable file → eager-write defaults so the file |
| 650 | // exists for the user to find and edit. |
| 651 | cfg.LoadDefaults(); |
| 652 | cfg.Save(path); |
| 653 | LOG_INFO(Audio, "LoadConfig: created defaults at '{}'", path); |
| 654 | } |
| 655 | |
| 656 | // Validate against the live device lists. If anything was reset |
| 657 | // (volume out of range, output/input device gone), we keep the |
| 658 | // normalized values in memory but DO NOT write them back — the |
| 659 | // user might reconnect the device later, and we don't want one |
| 660 | // boot to silently lose their setting. Persistence on a normalized |
| 661 | // field happens when AudioPage::Unmount calls SaveConfig(). |
| 662 | LiveAudioEnv env(this); |
| 663 | if (cfg.Normalize(env)) |
| 664 | LOG_INFO(Audio, "LoadConfig: normalized invalid fields (not persisted)"); |
| 665 | |
| 666 | // Apply to runtime. UI scale is 0..100 percent; backend scale is |
| 667 | // 0..10 floats (the IAudioSystem contract). |
| 668 | SetCDVolume(cfg.musicVolume / 10.0f); |
| 669 | SetWaveVolume(cfg.effectsVolume / 10.0f); |
| 670 | SetSpeechVolume(cfg.speechVolume / 10.0f); |
| 671 | if (cfg.eaxEnabled && _canEAX) |
| 672 | EnableEAX(true); |
| 673 | |
| 674 | if (!cfg.outputDevice.empty()) |
| 675 | SwitchOutputDevice(cfg.outputDevice.c_str()); |
| 676 | // Input device picker is owned by the AudioPage UI — no runtime |
nothing calls this directly
no test coverage detected