switch to software volume scaling (it's bad tho i need daniel to do maths for me please)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ class BluetoothAudioOutput : public IAudioOutput {
|
||||
private:
|
||||
drivers::Bluetooth& bluetooth_;
|
||||
tasks::WorkerPool& bg_worker_;
|
||||
uint8_t volume_;
|
||||
|
||||
uint16_t volume_;
|
||||
};
|
||||
|
||||
} // namespace audio
|
||||
|
||||
+15
-16
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user