diff options
Diffstat (limited to 'src/audio/audio_fsm.cpp')
| -rw-r--r-- | src/audio/audio_fsm.cpp | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp index b80e8c30..ba6e5ffe 100644 --- a/src/audio/audio_fsm.cpp +++ b/src/audio/audio_fsm.cpp @@ -12,6 +12,7 @@ #include <variant> #include "audio_sink.hpp" +#include "bluetooth_types.hpp" #include "esp_log.h" #include "freertos/portmacro.h" #include "freertos/projdefs.h" @@ -51,14 +52,24 @@ std::shared_ptr<IAudioOutput> AudioState::sOutput; std::optional<database::TrackId> AudioState::sCurrentTrack; bool AudioState::sIsPlaybackAllowed; -void AudioState::react(const system_fsm::KeyLockChanged& ev) { - if (ev.locking && sServices) { - sServices->nvs().AmpCurrentVolume(sOutput->GetVolume()); +void AudioState::react(const system_fsm::BluetoothEvent& ev) { + if (ev.event != drivers::bluetooth::Event::kConnectionStateChanged) { + return; + } + auto dev = sServices->bluetooth().ConnectedDevice(); + if (!dev) { + return; } + sBtOutput->SetVolume(sServices->nvs().BluetoothVolume(dev->mac)); + events::Ui().Dispatch(VolumeChanged{ + .percent = sOutput->GetVolumePct(), + .db = sOutput->GetVolumeDb(), + }); } void AudioState::react(const StepUpVolume& ev) { if (sOutput->AdjustVolumeUp()) { + commitVolume(); events::Ui().Dispatch(VolumeChanged{ .percent = sOutput->GetVolumePct(), .db = sOutput->GetVolumeDb(), @@ -68,6 +79,7 @@ void AudioState::react(const StepUpVolume& ev) { void AudioState::react(const StepDownVolume& ev) { if (sOutput->AdjustVolumeDown()) { + commitVolume(); events::Ui().Dispatch(VolumeChanged{ .percent = sOutput->GetVolumePct(), .db = sOutput->GetVolumeDb(), @@ -126,6 +138,14 @@ void AudioState::react(const OutputModeChanged& ev) { } sOutput->SetMode(IAudioOutput::Modes::kOnPaused); sSampleConverter->SetOutput(sOutput); + + // Bluetooth volume isn't 'changed' until we've connected to a device. + if (new_mode == drivers::NvsStorage::Output::kHeadphones) { + events::Ui().Dispatch(VolumeChanged{ + .percent = sOutput->GetVolumePct(), + .db = sOutput->GetVolumeDb(), + }); + } } auto AudioState::playTrack(database::TrackId id) -> void { @@ -139,6 +159,20 @@ auto AudioState::playTrack(database::TrackId id) -> void { }); } +auto AudioState::commitVolume() -> void { + auto mode = sServices->nvs().OutputMode(); + auto vol = sOutput->GetVolume(); + if (mode == drivers::NvsStorage::Output::kHeadphones) { + sServices->nvs().AmpCurrentVolume(vol); + } else if (mode == drivers::NvsStorage::Output::kBluetooth) { + auto dev = sServices->bluetooth().ConnectedDevice(); + if (!dev) { + return; + } + sServices->nvs().BluetoothVolume(dev->mac, vol); + } +} + auto AudioState::readyToPlay() -> bool { return sCurrentTrack.has_value() && sIsPlaybackAllowed; } @@ -162,11 +196,11 @@ void Uninitialised::react(const system_fsm::BootComplete& ev) { sServices = ev.services; constexpr size_t kDrainBufferSize = - drivers::kI2SBufferLengthFrames * sizeof(sample::Sample) * 8; + drivers::kI2SBufferLengthFrames * sizeof(sample::Sample) * 2 * 8; ESP_LOGI(kTag, "allocating drain buffer, size %u KiB", kDrainBufferSize / 1024); StreamBufferHandle_t stream = xStreamBufferCreateWithCaps( - kDrainBufferSize, sizeof(sample::Sample) * 2, MALLOC_CAP_DMA); + kDrainBufferSize, sizeof(sample::Sample), MALLOC_CAP_DMA); sFileSource.reset( new FatfsAudioInput(sServices->tag_parser(), sServices->bg_worker())); @@ -283,7 +317,7 @@ void Playback::exit() { // Stash the current volume now, in case it changed during playback, since we // might be powering off soon. - sServices->nvs().AmpCurrentVolume(sOutput->GetVolume()); + commitVolume(); events::System().Dispatch(PlaybackStopped{}); events::Ui().Dispatch(PlaybackStopped{}); |
