summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-04-12 14:36:03 +1000
committerjacqueline <me@jacqueline.id.au>2024-04-12 14:36:03 +1000
commitade00945951ff49481a161479f7d9798cc4c564f (patch)
tree3e244f54c4fa3f5d640d6017cf0f05ad079a90ab /src
parentb319b3f07f61ce7212f84ea6e7e69d27ef97ef5e (diff)
downloadtangara-fw-ade00945951ff49481a161479f7d9798cc4c564f.tar.gz
switch to software volume scaling (it's bad tho i need daniel to do maths for me please)
Diffstat (limited to 'src')
-rw-r--r--src/audio/bt_audio_output.cpp27
-rw-r--r--src/audio/include/bt_audio_output.hpp3
-rw-r--r--src/drivers/bluetooth.cpp31
-rw-r--r--src/drivers/include/bluetooth.hpp7
4 files changed, 34 insertions, 34 deletions
diff --git a/src/audio/bt_audio_output.cpp b/src/audio/bt_audio_output.cpp
index 7d6bade2..1b8866c1 100644
--- a/src/audio/bt_audio_output.cpp
+++ b/src/audio/bt_audio_output.cpp
@@ -7,9 +7,9 @@
#include "bt_audio_output.hpp"
#include <algorithm>
+#include <cmath>
#include <cstddef>
#include <cstdint>
-#include <cmath>
#include <memory>
#include <variant>
@@ -32,7 +32,7 @@ namespace audio {
BluetoothAudioOutput::BluetoothAudioOutput(StreamBufferHandle_t s,
drivers::Bluetooth& bt,
tasks::WorkerPool& p)
- : IAudioOutput(s), bluetooth_(bt), bg_worker_(p), volume_(10) {}
+ : IAudioOutput(s), bluetooth_(bt), bg_worker_(p), volume_() {}
BluetoothAudioOutput::~BluetoothAudioOutput() {}
@@ -44,10 +44,16 @@ auto BluetoothAudioOutput::changeMode(Modes mode) -> void {
}
}
-auto BluetoothAudioOutput::SetVolumeImbalance(int_fast8_t balance) -> void {}
+auto BluetoothAudioOutput::SetVolumeImbalance(int_fast8_t balance) -> void {
+ // FIXME: Support two separate scaling factors in the bluetooth driver.
+}
auto BluetoothAudioOutput::SetVolume(uint16_t v) -> void {
- volume_ = std::clamp<uint16_t>(v, 0, 0x7f);
+ volume_ = std::clamp<uint16_t>(v, 0, 100);
+ bg_worker_.Dispatch<void>([&]() {
+ float factor = volume_ / 100.;
+ bluetooth_.SetVolumeFactor(factor);
+ });
}
auto BluetoothAudioOutput::GetVolume() -> uint16_t {
@@ -55,20 +61,19 @@ auto BluetoothAudioOutput::GetVolume() -> uint16_t {
}
auto BluetoothAudioOutput::GetVolumePct() -> uint_fast8_t {
- return static_cast<uint_fast8_t>(round(static_cast<int>(volume_) * 100.0 / 0x7f));
+ return static_cast<uint_fast8_t>(round(static_cast<int>(volume_)));
}
auto BluetoothAudioOutput::SetVolumePct(uint_fast8_t val) -> bool {
if (val > 100) {
return false;
}
- uint16_t vol = (val * (0x7f))/100;
- SetVolume(vol);
+ SetVolume(val);
return true;
}
auto BluetoothAudioOutput::GetVolumeDb() -> int_fast16_t {
- double pct = GetVolumePct()/100.0;
+ double pct = GetVolumePct() / 100.0;
if (pct <= 0) {
pct = 0.01;
}
@@ -82,11 +87,11 @@ auto BluetoothAudioOutput::SetVolumeDb(int_fast16_t val) -> bool {
}
auto BluetoothAudioOutput::AdjustVolumeUp() -> bool {
- if (volume_ == 0x7f) {
+ if (volume_ == 100) {
return false;
}
volume_++;
- bg_worker_.Dispatch<void>([&]() { bluetooth_.SetVolume(volume_); });
+ SetVolume(volume_);
return true;
}
@@ -95,7 +100,7 @@ auto BluetoothAudioOutput::AdjustVolumeDown() -> bool {
return false;
}
volume_--;
- bg_worker_.Dispatch<void>([&]() { bluetooth_.SetVolume(volume_); });
+ SetVolume(volume_);
return true;
}
diff --git a/src/audio/include/bt_audio_output.hpp b/src/audio/include/bt_audio_output.hpp
index 74b0301a..cc3b2462 100644
--- a/src/audio/include/bt_audio_output.hpp
+++ b/src/audio/include/bt_audio_output.hpp
@@ -54,7 +54,8 @@ class BluetoothAudioOutput : public IAudioOutput {
private:
drivers::Bluetooth& bluetooth_;
tasks::WorkerPool& bg_worker_;
- uint8_t volume_;
+
+ uint16_t volume_;
};
} // namespace audio
diff --git a/src/drivers/bluetooth.cpp b/src/drivers/bluetooth.cpp
index d15ffd7f..edd5f67e 100644
--- a/src/drivers/bluetooth.cpp
+++ b/src/drivers/bluetooth.cpp
@@ -25,6 +25,7 @@
#include "freertos/portmacro.h"
#include "freertos/projdefs.h"
#include "freertos/timers.h"
+#include "sample.hpp"
#include "tinyfsm/include/tinyfsm.hpp"
#include "bluetooth_types.hpp"
@@ -37,6 +38,8 @@ namespace drivers {
[[maybe_unused]] static constexpr char kTag[] = "bluetooth";
DRAM_ATTR static StreamBufferHandle_t sStream = nullptr;
+DRAM_ATTR static std::atomic<float> sVolumeFactor = 1.f;
+
static tasks::WorkerPool* sBgWorker;
auto gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t* param) -> void {
@@ -69,7 +72,16 @@ IRAM_ATTR auto a2dp_data_cb(uint8_t* buf, int32_t buf_size) -> int32_t {
if (stream == nullptr) {
return 0;
}
- return xStreamBufferReceive(stream, buf, buf_size, 0);
+ size_t bytes_received = xStreamBufferReceive(stream, buf, buf_size, 0);
+
+ // Apply software volume scaling.
+ int16_t* samples = reinterpret_cast<int16_t*>(buf);
+ float factor = sVolumeFactor.load();
+ for (size_t i = 0; i < bytes_received / 2; i++) {
+ samples[i] *= factor;
+ }
+
+ return bytes_received;
}
Bluetooth::Bluetooth(NvsStorage& storage, tasks::WorkerPool& bg_worker) {
@@ -150,10 +162,8 @@ auto Bluetooth::SetSource(StreamBufferHandle_t src) -> void {
bluetooth::events::SourceChanged{});
}
-auto Bluetooth::SetVolume(uint8_t vol) -> void {
- auto lock = bluetooth::BluetoothState::lock();
- tinyfsm::FsmList<bluetooth::BluetoothState>::dispatch(
- bluetooth::events::ChangeVolume{.volume = vol});
+auto Bluetooth::SetVolumeFactor(float f) -> void {
+ sVolumeFactor = f;
}
auto Bluetooth::SetEventHandler(std::function<void(bluetooth::Event)> cb)
@@ -654,17 +664,6 @@ void Connected::react(const events::SourceChanged& ev) {
}
}
-void Connected::react(const events::ChangeVolume& ev) {
- esp_err_t err = esp_avrc_ct_send_set_absolute_volume_cmd(
- transaction_num_++, std::clamp<uint8_t>(ev.volume, 0, 0x7f));
- if (err != ESP_OK) {
- ESP_LOGW(kTag, "send vol failed %u", err);
- }
- if (transaction_num_ > ESP_AVRC_TRANS_LABEL_MAX) {
- transaction_num_ = 0;
- }
-}
-
void Connected::react(const events::internal::Gap& ev) {
sScanner_->HandleGapEvent(ev);
switch (ev.type) {
diff --git a/src/drivers/include/bluetooth.hpp b/src/drivers/include/bluetooth.hpp
index 988c7e93..8da5ce2e 100644
--- a/src/drivers/include/bluetooth.hpp
+++ b/src/drivers/include/bluetooth.hpp
@@ -43,7 +43,7 @@ class Bluetooth {
auto PreferredDevice() -> std::optional<bluetooth::MacAndName>;
auto SetSource(StreamBufferHandle_t) -> void;
- auto SetVolume(uint8_t) -> void;
+ auto SetVolumeFactor(float) -> void;
auto SetEventHandler(std::function<void(bluetooth::Event)> cb) -> void;
};
@@ -60,9 +60,6 @@ struct SourceChanged : public tinyfsm::Event {};
struct DeviceDiscovered : public tinyfsm::Event {
const Device& device;
};
-struct ChangeVolume : public tinyfsm::Event {
- const uint8_t volume;
-};
namespace internal {
struct Gap : public tinyfsm::Event {
@@ -131,7 +128,6 @@ class BluetoothState : public tinyfsm::Fsm<BluetoothState> {
virtual void react(const events::ConnectTimedOut& ev){};
virtual void react(const events::PreferredDeviceChanged& ev){};
virtual void react(const events::SourceChanged& ev){};
- virtual void react(const events::ChangeVolume&) {}
virtual void react(const events::DeviceDiscovered&);
@@ -204,7 +200,6 @@ class Connected : public BluetoothState {
void react(const events::PreferredDeviceChanged& ev) override;
void react(const events::SourceChanged& ev) override;
- void react(const events::ChangeVolume&) override;
void react(const events::Disable& ev) override;
void react(const events::internal::Gap& ev) override;