summaryrefslogtreecommitdiff
path: root/src/audio/audio_fsm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/audio_fsm.cpp')
-rw-r--r--src/audio/audio_fsm.cpp46
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{});