13static const char *
const TAG =
"router.speaker";
15static inline uint32_t atomic_subtract_clamped(std::atomic<uint32_t> &var,
uint32_t amount) {
16 uint32_t current = var.load(std::memory_order_acquire);
21 subtracted = std::min(amount, current);
22 new_value = current - subtracted;
23 }
while (!var.compare_exchange_weak(current, new_value, std::memory_order_release, std::memory_order_acquire));
32 for (
size_t i = 0; i < this->outputs_.size(); i++) {
33 this->outputs_[i]->add_audio_output_callback([
this, i](
uint32_t frames, int64_t timestamp_us) {
40 if (this->active_output_idx_.load(std::memory_order_relaxed) !=
static_cast<int8_t
>(i)) {
58 if (pending_prev_idx >= 0) {
100 static_cast<unsigned>(this->outputs_.size()));
110 vTaskDelay(ticks_to_wait);
120 vTaskDelay(ticks_to_wait);
170 if (target ==
nullptr) {
175 for (
size_t i = 0; i < this->outputs_.size(); i++) {
176 if (this->outputs_[i] == target) {
177 new_idx =
static_cast<int8_t
>(i);
182 ESP_LOGW(TAG,
"Switch target is not a configured output");
185 if (new_idx == this->active_output_idx_.load(std::memory_order_relaxed)) {
196 this->active_output_idx_.store(new_idx, std::memory_order_relaxed);
201 const int8_t old_idx = this->active_output_idx_.load(std::memory_order_relaxed);
204 this->outputs_[old_idx]->stop();
207 this->active_output_idx_.store(new_idx, std::memory_order_relaxed);
uint32_t bytes_to_frames(size_t bytes) const
Convert bytes to frames.
void set_mute_state(bool mute_state) override
size_t play(const uint8_t *data, size_t length) override
speaker::Speaker * get_active_output() const
void apply_cached_state_to_active_()
void set_pause_state(bool pause_state) override
void dump_config() override
void set_volume(float volume) override
bool has_buffered_data() const override
std::atomic< uint32_t > frames_in_pipeline_
bool switch_to_output(speaker::Speaker *target)
Switch the active output to the given speaker.
std::atomic< int8_t > pending_start_prev_idx_
virtual size_t play(const uint8_t *data, size_t length)=0
Plays the provided audio data.
virtual void set_volume(float volume)
virtual void set_pause_state(bool pause_state)
CallbackManager< void(uint32_t, int64_t)> audio_output_callback_
void set_audio_stream_info(const audio::AudioStreamInfo &audio_stream_info)
virtual void set_mute_state(bool mute_state)
virtual bool has_buffered_data() const =0
audio::AudioStreamInfo audio_stream_info_
int64_t esp_timer_get_time(void)