12static const char *
const TAG =
"sound_level";
14static const uint32_t MAX_FILL_DURATION_MS = 30;
15static const uint32_t RING_BUFFER_DURATION_MS = 120;
18static const double MAX_SAMPLE_SQUARED_DENOMINATOR = INT16_MIN * INT16_MIN;
22 "Sound Level Component:\n"
23 " Measurement Duration: %" PRIu32
" ms",
32 std::shared_ptr<ring_buffer::RingBuffer> temp_ring_buffer = this->
ring_buffer_.lock();
33 if (temp_ring_buffer !=
nullptr) {
34 temp_ring_buffer->write((
void *) data.data(), data.size());
57 this->
status_set_warning(LOG_STR(
"Microphone isn't running, can't compute statistics"));
94 const uint32_t samples_available_to_process =
96 const uint32_t samples_to_process = std::min(samples_in_window - this->
sample_count_, samples_available_to_process);
99 const int16_t *audio_data =
reinterpret_cast<const int16_t *
>(this->
audio_source_->data());
102 for (
uint32_t i = 0; i < samples_to_process; ++i) {
104 int32_t squared_sample =
static_cast<int32_t
>(audio_data[i]) *
static_cast<int32_t
>(audio_data[i]);
124 const float peak_db = 10.0f * log10(
static_cast<float>(this->
squared_peak_) / MAX_SAMPLE_SQUARED_DENOMINATOR);
132 const double rms_db = 10.0 * log10((this->
squared_samples_sum_ / MAX_SAMPLE_SQUARED_DENOMINATOR) /
133 static_cast<double>(samples_in_window));
145 ESP_LOGW(TAG,
"Can't start the microphone in passive mode");
153 ESP_LOGW(TAG,
"Can't stop microphone in passive mode");
159bool SoundLevelComponent::start_() {
170 const size_t ring_buffer_size =
171 (stream_info.ms_to_bytes(RING_BUFFER_DURATION_MS) / bytes_per_frame) * bytes_per_frame;
173 if (temp_ring_buffer ==
nullptr) {
181 temp_ring_buffer, stream_info.ms_to_bytes(MAX_FILL_DURATION_MS),
static_cast<uint8_t
>(bytes_per_frame));
void status_momentary_error(const char *name, uint32_t length=5000)
Set error status flag and automatically clear it after a timeout.
void status_set_warning()
void status_clear_error()
bool status_has_warning() const
bool status_has_error() const
void status_clear_warning()
size_t frames_to_bytes(uint32_t frames) const
Converts frames to bytes.
uint32_t ms_to_samples(uint32_t ms) const
Converts duration to samples.
size_t samples_to_bytes(uint32_t samples) const
Converts samples to bytes.
uint32_t bytes_to_samples(size_t bytes) const
Convert bytes to samples.
static std::unique_ptr< RingBufferAudioSource > create(std::shared_ptr< ring_buffer::RingBuffer > ring_buffer, size_t max_fill_bytes, uint8_t alignment_bytes=1)
Creates a new ring-buffer-backed audio source after validating its parameters.
void add_data_callback(F &&data_callback)
audio::AudioStreamInfo get_audio_stream_info()
Gets the AudioStreamInfo of the data after processing.
static std::unique_ptr< RingBuffer > create(size_t len, MemoryPreference preference=MemoryPreference::EXTERNAL_FIRST)
void publish_state(float state)
Publish a new state to the front-end.
void dump_config() override
sensor::Sensor * rms_sensor_
void start()
Starts the MicrophoneSource to start measuring sound levels.
uint32_t measurement_duration_ms_
std::weak_ptr< ring_buffer::RingBuffer > ring_buffer_
microphone::MicrophoneSource * microphone_source_
void stop()
Stops the MicrophoneSource.
sensor::Sensor * peak_sensor_
void stop_()
Internal start command that, if necessary, allocates a ring buffer and a zero-copy RingBufferAudioSou...
std::unique_ptr< audio::RingBufferAudioSource > audio_source_
uint64_t squared_samples_sum_