123 xEventGroupClearBits(this->
event_group_, SOURCE_SPEAKER_COMMAND_FINISH);
127 xEventGroupClearBits(this->
event_group_, SOURCE_SPEAKER_COMMAND_FINISH);
132 xEventGroupClearBits(this->
event_group_, SOURCE_SPEAKER_COMMAND_START);
136 xEventGroupClearBits(this->
event_group_, SOURCE_SPEAKER_COMMAND_START);
143 esp_err_t err = this->
start_();
157 case ESP_ERR_NOT_SUPPORTED:
160 case ESP_ERR_INVALID_ARG:
163 case ESP_ERR_INVALID_STATE:
177 (this->pending_playback_frames_.load(std::memory_order_acquire) == 0)) {
180 this->stop_gracefully_) {
194 (this->pending_playback_frames_.load(std::memory_order_acquire) == 0)) {
358 this->task_stack_in_psram_)) {
359 xEventGroupClearBits(this->
event_group_, MIXER_TASK_COMMAND_START);
361 ESP_LOGE(TAG,
"Failed to start; retrying in 1 second");
369 ESP_LOGD(TAG,
"Starting");
370 xEventGroupClearBits(this->
event_group_, MIXER_TASK_STATE_STARTING);
374 xEventGroupClearBits(this->
event_group_, MIXER_TASK_ERR_ESP_NO_MEM);
377 ESP_LOGV(TAG,
"Started");
379 xEventGroupClearBits(this->
event_group_, MIXER_TASK_STATE_RUNNING);
382 ESP_LOGV(TAG,
"Stopping");
383 xEventGroupClearBits(this->
event_group_, MIXER_TASK_STATE_STOPPING);
387 ESP_LOGD(TAG,
"Stopped");
396 bool all_stopped =
true;
399 all_stopped &= speaker->is_stopped();
413 xEventGroupClearBits(this->
event_group_, MIXER_TASK_COMMAND_STOP);
418 event_group_bits = xEventGroupGetBits(this->
event_group_);
419 if (event_group_bits == 0) {
463 if (output_transfer_buffer ==
nullptr) {
466 vTaskSuspend(
nullptr);
473 bool sent_finished =
false;
488 output_transfer_buffer->transfer_data_to_sink(pdMS_TO_TICKS(TASK_DELAY_MS),
false);
491 this_mixer->
audio_stream_info_.value().bytes_to_frames(output_transfer_buffer->free());
493 speakers_with_data.
clear();
494 audio_sources_with_data.
clear();
497 if (speaker->is_running() && !speaker->get_pause_state()) {
499 std::shared_ptr<audio::RingBufferAudioSource> audio_source = speaker->get_audio_source().lock();
500 if (audio_source ==
nullptr) {
504 speaker->process_data_from_source(audio_source, 0);
506 if (audio_source->available() > 0) {
508 audio_sources_with_data.
push_back(audio_source);
514 if (audio_sources_with_data.
empty()) {
516 delay(TASK_DELAY_MS);
520 uint32_t frames_to_mix = output_frames_free;
524 const uint8_t output_channels = output_info.
get_channels();
526 if ((audio_sources_with_data.
size() == 1) || this_mixer->
queue_mode_) {
535 const uint32_t frames_available_in_buffer =
536 active_stream_info.
bytes_to_frames(audio_sources_with_data[0]->available());
537 frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
538 esp_audio_libs::pcm_convert::copy_frames(
539 audio_sources_with_data[0]->data(), output_transfer_buffer->get_buffer_end(),
541 output_bps, output_channels, frames_to_mix);
544 if (!speakers_with_data[0]->has_contributed_.load(std::memory_order_acquire)) {
545 speakers_with_data[0]->playback_delay_frames_.store(
546 this_mixer->
frames_in_pipeline_.load(std::memory_order_acquire), std::memory_order_release);
547 speakers_with_data[0]->has_contributed_.store(
true, std::memory_order_release);
551 speakers_with_data[0]->pending_playback_frames_.fetch_add(frames_to_mix, std::memory_order_release);
552 audio_sources_with_data[0]->consume(active_stream_info.
frames_to_bytes(frames_to_mix));
555 output_transfer_buffer->increase_buffer_length(output_info.
frames_to_bytes(frames_to_mix));
560 if (!sent_finished) {
562 sent_finished =
true;
573 sent_finished =
false;
578 for (
size_t i = 0; i < audio_sources_with_data.
size(); ++i) {
579 const uint32_t frames_available_in_buffer =
580 speakers_with_data[i]->get_audio_stream_info().bytes_to_frames(audio_sources_with_data[i]->available());
581 frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
583 const uint8_t *primary_buffer = audio_sources_with_data[0]->data();
587 for (
size_t i = 1; i < audio_sources_with_data.
size(); ++i) {
588 esp_audio_libs::mixer::mix_frames(
590 primary_stream_info.
get_channels(), audio_sources_with_data[i]->data(),
591 static_cast<uint8_t
>(speakers_with_data[i]->get_audio_stream_info().get_bits_per_sample() / 8),
592 speakers_with_data[i]->get_audio_stream_info().get_channels(), output_transfer_buffer->get_buffer_end(),
593 output_bps, output_channels, frames_to_mix);
595 if (i != audio_sources_with_data.
size() - 1) {
597 primary_buffer = output_transfer_buffer->get_buffer_end();
598 primary_stream_info = output_info;
606 for (
size_t i = 0; i < audio_sources_with_data.
size(); ++i) {
608 if (!speakers_with_data[i]->has_contributed_.load(std::memory_order_acquire)) {
609 speakers_with_data[i]->playback_delay_frames_.store(current_pipeline_frames, std::memory_order_release);
610 speakers_with_data[i]->has_contributed_.store(
true, std::memory_order_release);
613 speakers_with_data[i]->pending_playback_frames_.fetch_add(frames_to_mix, std::memory_order_release);
614 audio_sources_with_data[i]->consume(
615 speakers_with_data[i]->get_audio_stream_info().frames_to_bytes(frames_to_mix));
619 output_transfer_buffer->increase_buffer_length(output_info.
frames_to_bytes(frames_to_mix));
632 vTaskSuspend(
nullptr);