ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
microphone_source.h
Go to the documentation of this file.
1#pragma once
2
3#include "microphone.h"
4
6
7#include <bitset>
8#include <cstddef>
9#include <cstdint>
10#include <vector>
11
12namespace esphome {
13namespace microphone {
14
15static const int32_t MAX_GAIN_FACTOR = 64;
16
18 /*
19 * @brief Helper class that handles converting raw microphone data to a requested format.
20 * Components requesting microphone audio should register a callback through this class instead of registering a
21 * callback directly with the microphone if a particular format is required.
22 *
23 * Raw microphone data may have a different number of bits per sample and number of channels than the requesting
24 * component needs. This class handles the conversion by:
25 * - Internally adds a callback to receive the raw microphone data
26 * - The ``process_audio_`` handles the raw data
27 * - Only the channels set in the ``channels_`` bitset are passed through
28 * - Passed through samples have the bits per sample converted
29 * - A gain factor is optionally applied to increase the volume - audio may clip!
30 * - The processed audio is passed to the callback of the component requesting microphone data
31 * - It tracks an internal enabled state, so it ignores raw microphone data when the component requesting
32 * microphone data is not actively requesting audio.
33 *
34 * Note that this class cannot convert sample rates!
35 */
36 public:
37 MicrophoneSource(Microphone *mic, uint8_t bits_per_sample, int32_t gain_factor, bool passive)
38 : mic_(mic), bits_per_sample_(bits_per_sample), gain_factor_(gain_factor), passive_(passive) {}
39
47 void add_channel(uint8_t channel) { this->channels_.set(channel); }
48
49 template<typename F> void add_data_callback(F &&data_callback) {
50 this->mic_->add_data_callback([this, data_callback](const std::vector<uint8_t> &data) {
51 if (this->enabled_ || this->passive_) {
52 if (this->processed_samples_.use_count() == 0) {
53 // Create vector if its unused
54 this->processed_samples_ = std::make_shared<std::vector<uint8_t>>();
55 }
56
57 // Take temporary ownership of samples vector to avoid deallocation before the callback finishes
58 std::shared_ptr<std::vector<uint8_t>> output_samples = this->processed_samples_;
59 this->process_audio_(data, *output_samples);
60 data_callback(*output_samples);
61 }
62 });
63 }
64
65 void set_gain_factor(int32_t gain_factor) { this->gain_factor_ = clamp<int32_t>(gain_factor, 1, MAX_GAIN_FACTOR); }
66 int32_t get_gain_factor() { return this->gain_factor_; }
67
72
73 void start();
74 void stop();
75 bool is_passive() const { return this->passive_; }
76 bool is_running() const { return (this->mic_->is_running() && (this->enabled_ || this->passive_)); }
77 bool is_stopped() const { return !this->is_running(); };
78
79 protected:
80 void process_audio_(const std::vector<uint8_t> &data, std::vector<uint8_t> &filtered_data);
81
82 std::shared_ptr<std::vector<uint8_t>> processed_samples_;
83
86 std::bitset<8> channels_;
87 int32_t gain_factor_;
88 bool enabled_{false};
89 bool passive_; // Only pass audio if ``mic_`` is already running
90};
91
92} // namespace microphone
93} // namespace esphome
void add_data_callback(F &&data_callback)
Definition microphone.h:24
void set_gain_factor(int32_t gain_factor)
MicrophoneSource(Microphone *mic, uint8_t bits_per_sample, int32_t gain_factor, bool passive)
void add_data_callback(F &&data_callback)
std::shared_ptr< std::vector< uint8_t > > processed_samples_
void add_channel(uint8_t channel)
Enables a channel to be processed through the callback.
audio::AudioStreamInfo get_audio_stream_info()
Gets the AudioStreamInfo of the data after processing.
void process_audio_(const std::vector< uint8_t > &data, std::vector< uint8_t > &filtered_data)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7