diff --git a/README.md b/README.md index dfff377..b50db7a 100644 --- a/README.md +++ b/README.md @@ -271,7 +271,7 @@ For real-time visualization, I'm using web server number/slider controls to disp With 10 x 6 = 60 SOS filters, the component uses about 60-70% of the CPU, and I assume the web server also consumes some CPU power to send approximately 100 messages per second. So, this is quite a CPU-intensive task. I chose 6th-order filters somewhat arbitrarily; you could experiment with lower-order filters, which might meet your needs while using less CPU power. -https://github.com/user-attachments/assets/91cd7d5c-e636-4d90-b046-68bd33df8db2 +https://github.com/user-attachments/assets/904a2a96-0c16-4797-9587-2558cc0c70f8 While this example serves as a stress test, you could also use it to monitor different frequencies over longer time intervals with less frequent updates. diff --git a/components/sound_level_meter/__init__.py b/components/sound_level_meter/__init__.py index 8ae3d87..be997f8 100644 --- a/components/sound_level_meter/__init__.py +++ b/components/sound_level_meter/__init__.py @@ -60,6 +60,7 @@ CONF_MIC_SENSITIVITY_REF = "mic_sensitivity_ref" CONF_OFFSET = "offset" CONF_IS_ON = "is_on" +CONF_IS_HIGH_FREQ = "is_high_freq" CONF_DSP_FILTERS = "dsp_filters" ICON_WAVEFORM = "mdi:waveform" @@ -150,6 +151,7 @@ CONF_UPDATE_INTERVAL, default="60s" ): cv.positive_time_period_milliseconds, cv.Optional(CONF_IS_ON, default=True): cv.boolean, + cv.Optional(CONF_IS_HIGH_FREQ, default=False): cv.boolean, cv.Optional(CONF_BUFFER_SIZE, default=1024): cv.positive_not_null_int, cv.Optional( CONF_WARMUP_INTERVAL, default="500ms" @@ -208,6 +210,7 @@ async def to_code(config): cg.add(var.set_task_stack_size(config[CONF_TASK_STACK_SIZE])) cg.add(var.set_task_priority(config[CONF_TASK_PRIORITY])) cg.add(var.set_task_core(config[CONF_TASK_CORE])) + cg.add(var.set_is_high_freq(config[CONF_IS_HIGH_FREQ])) if CONF_MIC_SENSITIVITY in config: cg.add(var.set_mic_sensitivity(config[CONF_MIC_SENSITIVITY])) if CONF_MIC_SENSITIVITY_REF in config: diff --git a/components/sound_level_meter/sound_level_meter.cpp b/components/sound_level_meter/sound_level_meter.cpp index fe7ad2c..a91267c 100644 --- a/components/sound_level_meter/sound_level_meter.cpp +++ b/components/sound_level_meter/sound_level_meter.cpp @@ -32,6 +32,7 @@ void SoundLevelMeter::set_mic_sensitivity_ref(optional mic_sensitivity_re optional SoundLevelMeter::get_mic_sensitivity_ref() { return this->mic_sensitivity_ref_; } void SoundLevelMeter::set_offset(optional offset) { this->offset_ = offset; } optional SoundLevelMeter::get_offset() { return this->offset_; } +void SoundLevelMeter::set_is_high_freq(bool is_high_freq) { this->is_high_freq_ = is_high_freq; } void SoundLevelMeter::add_sensor(SoundLevelMeterSensor *sensor) { this->sensors_.push_back(sensor); } void SoundLevelMeter::add_dsp_filter(Filter *dsp_filter) { this->dsp_filters_.push_back(dsp_filter); } @@ -59,7 +60,7 @@ void SoundLevelMeter::loop() { if (!this->defer_queue_.empty()) { auto &f = this->defer_queue_.front(); f(); - this->defer_queue_.pop(); + this->defer_queue_.pop_front(); } } @@ -68,6 +69,8 @@ void SoundLevelMeter::turn_on() { this->reset(); this->is_on_ = true; this->on_cv_.notify_one(); + if (this->is_high_freq_) + this->high_freq_.start(); ESP_LOGD(TAG, "Turned on"); } @@ -76,6 +79,8 @@ void SoundLevelMeter::turn_off() { this->reset(); this->is_on_ = false; this->on_cv_.notify_one(); + if (this->is_high_freq_) + this->high_freq_.stop(); ESP_LOGD(TAG, "Turned off"); } @@ -95,9 +100,10 @@ void SoundLevelMeter::task(void *param) { auto warmup_start = millis(); while (millis() - warmup_start < this_->warmup_interval_) this_->i2s_->read_samples(buffers); - uint32_t process_time = 0, process_count = 0; uint64_t process_start; + if (this_->is_on_ && this_->is_high_freq_) + this_->high_freq_.start(); while (1) { { std::unique_lock lock(this_->on_mutex_); @@ -160,7 +166,7 @@ void SoundLevelMeter::process(BufferStack &buffers) { void SoundLevelMeter::defer(std::function &&f) { std::lock_guard lock(this->defer_mutex_); - this->defer_queue_.push(std::move(f)); + this->defer_queue_.push_back(std::move(f)); } void SoundLevelMeter::reset() { diff --git a/components/sound_level_meter/sound_level_meter.h b/components/sound_level_meter/sound_level_meter.h index d9db569..cfd8322 100644 --- a/components/sound_level_meter/sound_level_meter.h +++ b/components/sound_level_meter/sound_level_meter.h @@ -34,6 +34,7 @@ class SoundLevelMeter : public Component { optional get_mic_sensitivity_ref(); void set_offset(optional offset); optional get_offset(); + void set_is_high_freq(bool is_high_freq); void add_sensor(SoundLevelMeterSensor *sensor); void add_dsp_filter(Filter *dsp_filter); virtual void setup() override; @@ -56,12 +57,14 @@ class SoundLevelMeter : public Component { optional mic_sensitivity_{}; optional mic_sensitivity_ref_{}; optional offset_{}; - std::queue> defer_queue_; + std::deque> defer_queue_; std::mutex defer_mutex_; uint32_t update_interval_{60000}; bool is_on_{true}; + bool is_high_freq_{false}; std::mutex on_mutex_; std::condition_variable on_cv_; + HighFrequencyLoopRequester high_freq_; void sort_sensors(); void process(BufferStack &buffers);