From 3670859d1620ca0fe3492cffb591bf29e5af849c Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 28 Jul 2023 13:01:18 +1000 Subject: Volume control! Reasonable default volume! Hooray! --- src/audio/i2s_audio_output.cpp | 87 +++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 43 deletions(-) (limited to 'src/audio/i2s_audio_output.cpp') diff --git a/src/audio/i2s_audio_output.cpp b/src/audio/i2s_audio_output.cpp index 8ce43336..5873d80f 100644 --- a/src/audio/i2s_audio_output.cpp +++ b/src/audio/i2s_audio_output.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -23,19 +24,32 @@ #include "i2s_dac.hpp" #include "result.hpp" #include "stream_info.hpp" +#include "wm8523.hpp" static const char* kTag = "I2SOUT"; namespace audio { +// Consumer line level = 0.316 VRMS = -10db = 61 +// Professional line level = 1.228 VRMS = +4dB = 111 +// Cliipping level = 2.44 VRMS = 133? +// all into 650 ohms + +static constexpr uint16_t kMaxVolume = 0x1ff; +static constexpr uint16_t kMinVolume = 0b0; +static constexpr uint16_t kMaxVolumeBeforeClipping = 0x185; +static constexpr uint16_t kLineLevelVolume = 0x13d; +static constexpr uint16_t kDefaultVolume = 0x128; + I2SAudioOutput::I2SAudioOutput(drivers::IGpios* expander, std::weak_ptr dac) : expander_(expander), dac_(dac.lock()), current_config_(), left_difference_(0), - attenuation_() { - SetVolume(25); // For testing + current_volume_(kDefaultVolume), + max_volume_(kLineLevelVolume){ + SetVolume(GetVolume()); dac_->SetSource(stream()); } @@ -53,63 +67,50 @@ auto I2SAudioOutput::SetInUse(bool in_use) -> void { } auto I2SAudioOutput::SetVolumeImbalance(int_fast8_t balance) -> void { - // TODO. + left_difference_ = balance; + SetVolume(GetVolume()); } auto I2SAudioOutput::SetVolume(uint_fast8_t percent) -> void { - // TODO. -} + percent = std::min(percent, 100); + float new_value = static_cast(max_volume_) / 100 * percent; + current_volume_ = std::max(new_value, kMinVolume); + ESP_LOGI(kTag, "set volume to %u%% = %u", percent, current_volume_); -auto I2SAudioOutput::GetVolume() -> uint_fast8_t { - // TODO. - return 100; -} + int32_t left_unclamped = current_volume_ + left_difference_; + uint16_t left = std::clamp(left_unclamped, kMinVolume, max_volume_); -auto I2SAudioOutput::GetAdjustedMaxAttenuation() -> int_fast8_t { - // TODO - return 0; + using drivers::wm8523::Register; + drivers::wm8523::WriteRegister(Register::kDacGainLeft, left); + drivers::wm8523::WriteRegister(Register::kDacGainRight, current_volume_ | 0x200); } -static uint8_t vol = 0xFF; +auto I2SAudioOutput::GetVolume() -> uint_fast8_t { + return + static_cast( + static_cast(current_volume_) / max_volume_ * 100.0f); +} auto I2SAudioOutput::AdjustVolumeUp() -> bool { - vol += 0xF; - { - drivers::I2CTransaction transaction; - transaction.start() - .write_addr(0b0011010, I2C_MASTER_WRITE) - .write_ack(6, 0b01, vol) - .stop(); - transaction.Execute(); + if (GetVolume() >= 100) { + return false; } - { - drivers::I2CTransaction transaction; - transaction.start() - .write_addr(0b0011010, I2C_MASTER_WRITE) - .write_ack(7, 0b11, vol) - .stop(); - transaction.Execute(); + if (GetVolume() >= 95) { + SetVolume(100); + } else { + SetVolume(GetVolume() + 5); } return true; } auto I2SAudioOutput::AdjustVolumeDown() -> bool { - vol -= 0xF; - { - drivers::I2CTransaction transaction; - transaction.start() - .write_addr(0b0011010, I2C_MASTER_WRITE) - .write_ack(6, 0b01, vol) - .stop(); - transaction.Execute(); + if (GetVolume() == 0) { + return false; } - { - drivers::I2CTransaction transaction; - transaction.start() - .write_addr(0b0011010, I2C_MASTER_WRITE) - .write_ack(7, 0b11, vol) - .stop(); - transaction.Execute(); + if (GetVolume() <= 5) { + SetVolume(0); + } else { + SetVolume(GetVolume() - 5); } return true; } -- cgit v1.2.3