mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
[audio][i2s_audio][micro_wake_word][microphone][mixer][resampler][speaker] Replace use_count() checks with lock and null test (#19046)
This commit is contained in:
@@ -58,6 +58,9 @@ esp_err_t AudioReader::add_sink(const std::weak_ptr<ring_buffer::RingBuffer> &ou
|
||||
if (current_audio_file_ != nullptr) {
|
||||
// A transfer buffer isn't ncessary for a local file
|
||||
this->file_ring_buffer_ = output_ring_buffer.lock();
|
||||
if (this->file_ring_buffer_ == nullptr) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,14 +51,14 @@ void AudioTransferBuffer::increase_buffer_length(size_t bytes) { this->buffer_le
|
||||
|
||||
void AudioTransferBuffer::clear_buffered_data() {
|
||||
this->buffer_length_ = 0;
|
||||
if (this->ring_buffer_.use_count() > 0) {
|
||||
if (this->ring_buffer_ != nullptr) {
|
||||
this->ring_buffer_->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSinkTransferBuffer::clear_buffered_data() {
|
||||
this->buffer_length_ = 0;
|
||||
if (this->ring_buffer_.use_count() > 0) {
|
||||
if (this->ring_buffer_ != nullptr) {
|
||||
this->ring_buffer_->reset();
|
||||
}
|
||||
#ifdef USE_SPEAKER
|
||||
@@ -69,7 +69,7 @@ void AudioSinkTransferBuffer::clear_buffered_data() {
|
||||
}
|
||||
|
||||
bool AudioTransferBuffer::has_buffered_data() const {
|
||||
if (this->ring_buffer_.use_count() > 0) {
|
||||
if (this->ring_buffer_ != nullptr) {
|
||||
return ((this->ring_buffer_->available() > 0) || (this->available() > 0));
|
||||
}
|
||||
return (this->available() > 0);
|
||||
@@ -144,7 +144,7 @@ size_t AudioSourceTransferBuffer::transfer_data_from_source(TickType_t ticks_to_
|
||||
size_t bytes_to_read = AudioTransferBuffer::free();
|
||||
size_t bytes_read = 0;
|
||||
if (bytes_to_read > 0) {
|
||||
if (this->ring_buffer_.use_count() > 0) {
|
||||
if (this->ring_buffer_ != nullptr) {
|
||||
bytes_read = this->ring_buffer_->read((void *) this->get_buffer_end(), bytes_to_read, ticks_to_wait);
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ size_t AudioSinkTransferBuffer::transfer_data_to_sink(TickType_t ticks_to_wait,
|
||||
bytes_written = this->speaker_->play(this->data_start_, this->available(), ticks_to_wait);
|
||||
} else
|
||||
#endif
|
||||
if (this->ring_buffer_.use_count() > 0) {
|
||||
if (this->ring_buffer_ != nullptr) {
|
||||
bytes_written =
|
||||
this->ring_buffer_->write_without_replacement((void *) this->data_start_, this->available(), ticks_to_wait);
|
||||
} else if (this->sink_callback_ != nullptr) {
|
||||
@@ -186,7 +186,7 @@ bool AudioSinkTransferBuffer::has_buffered_data() const {
|
||||
return (this->speaker_->has_buffered_data() || (this->available() > 0));
|
||||
}
|
||||
#endif
|
||||
if (this->ring_buffer_.use_count() > 0) {
|
||||
if (this->ring_buffer_ != nullptr) {
|
||||
return ((this->ring_buffer_->available() > 0) || (this->available() > 0));
|
||||
}
|
||||
return (this->available() > 0);
|
||||
|
||||
@@ -218,8 +218,8 @@ size_t I2SAudioSpeakerBase::play(const uint8_t *data, size_t length, TickType_t
|
||||
}
|
||||
|
||||
bool I2SAudioSpeakerBase::has_buffered_data() const {
|
||||
if (this->audio_ring_buffer_.use_count() > 0) {
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->audio_ring_buffer_.lock();
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->audio_ring_buffer_.lock();
|
||||
if (temp_ring_buffer != nullptr) {
|
||||
return temp_ring_buffer->available() > 0;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -129,7 +129,7 @@ void MicroWakeWord::setup() {
|
||||
return;
|
||||
}
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->ring_buffer_.lock();
|
||||
if (this->ring_buffer_.use_count() > 1) {
|
||||
if (temp_ring_buffer != nullptr) {
|
||||
// Producer-only write: never touches consumer state. If the buffer is full, ask the inference task
|
||||
// to drain it - reset() is a consumer operation and must run on the inference task's thread.
|
||||
// Disable partial writes so audio chunks are either fully accepted or rejected and handled below.
|
||||
|
||||
@@ -48,7 +48,7 @@ class MicrophoneSource final {
|
||||
template<typename F> void add_data_callback(F &&data_callback) {
|
||||
this->mic_->add_data_callback([this, data_callback](const std::vector<uint8_t> &data) {
|
||||
if (this->enabled_ || this->passive_) {
|
||||
if (this->processed_samples_.use_count() == 0) {
|
||||
if (this->processed_samples_ == nullptr) {
|
||||
// Create vector if its unused
|
||||
this->processed_samples_ = std::make_shared<std::vector<uint8_t>>();
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ size_t SourceSpeaker::play(const uint8_t *data, size_t length, TickType_t ticks_
|
||||
}
|
||||
size_t bytes_written = 0;
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->ring_buffer_.lock();
|
||||
if (temp_ring_buffer.use_count() > 0) {
|
||||
if (temp_ring_buffer != nullptr) {
|
||||
// Only write to the ring buffer if the reference is valid
|
||||
bytes_written = temp_ring_buffer->write_without_replacement(data, length, ticks_to_wait);
|
||||
if (bytes_written > 0) {
|
||||
@@ -250,14 +250,14 @@ esp_err_t SourceSpeaker::start_() {
|
||||
// avoids unnecessary single-frame splices.
|
||||
const size_t ring_buffer_size =
|
||||
(this->audio_stream_info_.ms_to_bytes(this->buffer_duration_ms_) / bytes_per_frame) * bytes_per_frame;
|
||||
if (this->audio_source_.use_count() == 0) {
|
||||
if (this->audio_source_ == nullptr) {
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->ring_buffer_.lock();
|
||||
if (!temp_ring_buffer) {
|
||||
if (temp_ring_buffer == nullptr) {
|
||||
temp_ring_buffer = ring_buffer::RingBuffer::create(ring_buffer_size);
|
||||
this->ring_buffer_ = temp_ring_buffer;
|
||||
}
|
||||
|
||||
if (!temp_ring_buffer) {
|
||||
if (temp_ring_buffer == nullptr) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ void SourceSpeaker::stop() { this->send_command_(SOURCE_SPEAKER_COMMAND_STOP); }
|
||||
void SourceSpeaker::finish() { this->send_command_(SOURCE_SPEAKER_COMMAND_FINISH); }
|
||||
|
||||
bool SourceSpeaker::has_buffered_data() const {
|
||||
return ((this->audio_source_.use_count() > 0) && this->audio_source_->has_buffered_data());
|
||||
return ((this->audio_source_ != nullptr) && this->audio_source_->has_buffered_data());
|
||||
}
|
||||
|
||||
void SourceSpeaker::set_mute_state(bool mute_state) {
|
||||
@@ -496,7 +496,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
||||
if (speaker->is_running() && !speaker->get_pause_state()) {
|
||||
// Speaker is running and not paused, so it possibly can provide audio data
|
||||
std::shared_ptr<audio::RingBufferAudioSource> audio_source = speaker->get_audio_source().lock();
|
||||
if (audio_source.use_count() == 0) {
|
||||
if (audio_source == nullptr) {
|
||||
// No audio source allocated, so skip processing this speaker
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ size_t ResamplerSpeaker::play(const uint8_t *data, size_t length, TickType_t tic
|
||||
bytes_written = this->output_speaker_->play(data, length, ticks_to_wait);
|
||||
} else {
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->ring_buffer_.lock();
|
||||
if (temp_ring_buffer) {
|
||||
if (temp_ring_buffer != nullptr) {
|
||||
// Only write to the ring buffer if the reference is valid
|
||||
bytes_written = temp_ring_buffer->write_without_replacement(data, length, ticks_to_wait);
|
||||
} else {
|
||||
@@ -299,7 +299,7 @@ bool ResamplerSpeaker::has_buffered_data() const {
|
||||
bool has_ring_buffer_data = false;
|
||||
if (this->requires_resampling_()) {
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->ring_buffer_.lock();
|
||||
if (temp_ring_buffer) {
|
||||
if (temp_ring_buffer != nullptr) {
|
||||
has_ring_buffer_data = (temp_ring_buffer->available() > 0);
|
||||
}
|
||||
}
|
||||
@@ -342,7 +342,7 @@ void ResamplerSpeaker::resample_task(void *params) {
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = ring_buffer::RingBuffer::create(
|
||||
this_resampler->audio_stream_info_.ms_to_bytes(this_resampler->buffer_duration_ms_));
|
||||
|
||||
if (!temp_ring_buffer) {
|
||||
if (temp_ring_buffer == nullptr) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
} else {
|
||||
this_resampler->ring_buffer_ = temp_ring_buffer;
|
||||
|
||||
@@ -322,17 +322,17 @@ void AudioPipeline::read_task(void *params) {
|
||||
if (err == ESP_OK) {
|
||||
size_t file_ring_buffer_size = this_pipeline->buffer_size_;
|
||||
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer;
|
||||
std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this_pipeline->raw_file_ring_buffer_.lock();
|
||||
|
||||
if (!this_pipeline->raw_file_ring_buffer_.use_count()) {
|
||||
if (temp_ring_buffer == nullptr) {
|
||||
temp_ring_buffer = ring_buffer::RingBuffer::create(file_ring_buffer_size);
|
||||
this_pipeline->raw_file_ring_buffer_ = temp_ring_buffer;
|
||||
}
|
||||
|
||||
if (!this_pipeline->raw_file_ring_buffer_.use_count()) {
|
||||
if (temp_ring_buffer == nullptr) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
} else {
|
||||
reader->add_sink(this_pipeline->raw_file_ring_buffer_);
|
||||
err = reader->add_sink(temp_ring_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,7 +403,9 @@ void AudioPipeline::decode_task(void *params) {
|
||||
make_unique<audio::AudioDecoder>(this_pipeline->transfer_buffer_size_, this_pipeline->transfer_buffer_size_);
|
||||
|
||||
esp_err_t err = decoder->start(this_pipeline->current_audio_file_type_);
|
||||
decoder->add_source(this_pipeline->raw_file_ring_buffer_);
|
||||
if (err == ESP_OK) {
|
||||
err = decoder->add_source(this_pipeline->raw_file_ring_buffer_);
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
// Send specific error message
|
||||
|
||||
Reference in New Issue
Block a user