16static const UBaseType_t RESAMPLER_TASK_PRIORITY = 1;
18static const uint32_t TRANSFER_BUFFER_DURATION_MS = 50;
20static const uint32_t TASK_DELAY_MS = 20;
21static const uint32_t TASK_STACK_SIZE = 3072;
23static const char *
const TAG =
"resampler_speaker";
41 ESP_LOGE(TAG,
"Failed to create event group");
61 uint32_t event_group_bits = xEventGroupGetBits(this->
event_group_);
64 ESP_LOGD(TAG,
"Starting resampler task");
65 xEventGroupClearBits(this->
event_group_, ResamplingEventGroupBits::STATE_STARTING);
69 this->
status_set_error(
"Resampler task failed to allocate the internal buffers");
70 xEventGroupClearBits(this->
event_group_, ResamplingEventGroupBits::ERR_ESP_NO_MEM);
74 this->
status_set_error(
"Cannot resample due to an unsupported audio stream");
75 xEventGroupClearBits(this->
event_group_, ResamplingEventGroupBits::ERR_ESP_NOT_SUPPORTED);
80 xEventGroupClearBits(this->
event_group_, ResamplingEventGroupBits::ERR_ESP_FAIL);
85 ESP_LOGD(TAG,
"Started resampler task");
87 xEventGroupClearBits(this->
event_group_, ResamplingEventGroupBits::STATE_RUNNING);
90 ESP_LOGD(TAG,
"Stopping resampler task");
91 xEventGroupClearBits(this->
event_group_, ResamplingEventGroupBits::STATE_STOPPING);
95 ESP_LOGD(TAG,
"Stopped resampler task");
102 esp_err_t err = this->
start_();
108 case ESP_ERR_INVALID_STATE:
109 this->
status_set_error(
"Failed to start resampler: resampler task failed to start");
112 this->
status_set_error(
"Failed to start resampler: not enough memory for task stack");
142 size_t bytes_written = 0;
147 std::shared_ptr<RingBuffer> temp_ring_buffer = this->
ring_buffer_.lock();
148 bytes_written = temp_ring_buffer->write_without_replacement(data,
length, ticks_to_wait);
152 return bytes_written;
184 return ESP_ERR_NO_MEM;
193 return ESP_ERR_INVALID_STATE;
227 return ESP_ERR_INVALID_STATE;
233 bool has_ring_buffer_data =
false;
235 has_ring_buffer_data = (this->
ring_buffer_.lock()->available() > 0);
261 std::unique_ptr<audio::AudioResampler> resampler =
269 std::shared_ptr<RingBuffer> temp_ring_buffer =
272 if (temp_ring_buffer.use_count() == 0) {
273 err = ESP_ERR_NO_MEM;
285 }
else if (err == ESP_ERR_NO_MEM) {
287 }
else if (err == ESP_ERR_NOT_SUPPORTED) {
291 while (err == ESP_OK) {
292 uint32_t event_bits = xEventGroupGetBits(this_resampler->
event_group_);
299 int32_t ms_differential = 0;
314 vTaskDelete(
nullptr);
virtual void mark_failed()
Mark this component as failed.
void status_clear_error()
void status_set_error(const char *message="unspecified")
An STL allocator that uses SPI or internal RAM.
void deallocate(T *p, size_t n)
static std::unique_ptr< RingBuffer > create(size_t len)
size_t ms_to_bytes(uint32_t ms) const
Converts duration to bytes.
uint8_t get_bits_per_sample() const
uint8_t get_channels() const
uint32_t get_sample_rate() const
void set_volume(float volume) override
Volume state changes are passed to the parent's output speaker.
std::weak_ptr< RingBuffer > ring_buffer_
bool requires_resampling_() const
audio::AudioStreamInfo target_stream_info_
uint32_t buffer_duration_ms_
bool task_stack_in_psram_
esp_err_t start_()
Starts the output speaker after setting the resampled stream info.
uint8_t target_bits_per_sample_
size_t play(const uint8_t *data, size_t length, TickType_t ticks_to_wait) override
TaskHandle_t task_handle_
speaker::Speaker * output_speaker_
StackType_t * task_stack_buffer_
bool has_buffered_data() const override
EventGroupHandle_t event_group_
esp_err_t delete_task_()
Deallocates the task stack and resets the pointers.
uint64_t callback_remainder_
esp_err_t start_task_()
Starts the resampler task after allocating the task stack.
void stop_()
Stops the output speaker. If the resampling task is running, it sends the stop command.
static void resample_task(void *params)
void set_mute_state(bool mute_state) override
Mute state changes are passed to the parent's output speaker.
virtual size_t play(const uint8_t *data, size_t length)=0
Plays the provided audio data.
virtual void set_volume(float volume)
void add_audio_output_callback(std::function< void(uint32_t, int64_t)> &&callback)
Callback function for sending the duration of the audio written to the speaker since the last callbac...
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_
Providing packet encoding functions for exchanging data with a remote host.
std::unique_ptr< T > make_unique(Args &&...args)