ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
i2s_audio.h
Go to the documentation of this file.
1#pragma once
2
3#ifdef USE_ESP32
4
8#include <esp_idf_version.h>
9#include <driver/i2s_std.h>
10
11namespace esphome::i2s_audio {
12
13class I2SAudioComponent;
14
15class I2SAudioBase : public Parented<I2SAudioComponent> {
16 public:
17 void set_i2s_role(i2s_role_t role) { this->i2s_role_ = role; }
18 void set_slot_mode(i2s_slot_mode_t slot_mode) { this->slot_mode_ = slot_mode; }
19 void set_std_slot_mask(i2s_std_slot_mask_t std_slot_mask) { this->std_slot_mask_ = std_slot_mask; }
20 void set_slot_bit_width(i2s_slot_bit_width_t slot_bit_width) { this->slot_bit_width_ = slot_bit_width; }
21 void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
22 void set_use_apll(uint32_t use_apll) { this->use_apll_ = use_apll; }
23 void set_mclk_multiple(i2s_mclk_multiple_t mclk_multiple) { this->mclk_multiple_ = mclk_multiple; }
24
25 protected:
26 i2s_clock_src_t get_clock_source_() const {
27#ifdef I2S_CLK_SRC_APLL
28 if (this->use_apll_) {
29 return I2S_CLK_SRC_APLL;
30 }
31#endif
32 return I2S_CLK_SRC_DEFAULT;
33 }
34
35 i2s_role_t i2s_role_{};
36 i2s_slot_mode_t slot_mode_;
37 i2s_std_slot_mask_t std_slot_mask_;
38 i2s_slot_bit_width_t slot_bit_width_;
41 i2s_mclk_multiple_t mclk_multiple_;
42};
43
44class I2SAudioIn : public I2SAudioBase {
45#ifdef USE_I2S_AUDIO_FULL_DUPLEX
46 public:
48 virtual void build_full_duplex_config(i2s_std_config_t &std_cfg) = 0;
49#endif
50};
51
52class I2SAudioOut : public I2SAudioBase {
53#ifdef USE_I2S_AUDIO_FULL_DUPLEX
54 public:
58 virtual void build_full_duplex_config(i2s_chan_config_t &chan_cfg, i2s_std_config_t &std_cfg) {}
59#endif
60};
61
62class I2SAudioComponent final : public Component {
63 public:
64#ifdef USE_I2S_AUDIO_FULL_DUPLEX
65 void setup() override;
66
67 void set_audio_in(I2SAudioIn *audio_in) { this->audio_in_ = audio_in; }
68 void set_audio_out(I2SAudioOut *audio_out) { this->audio_out_ = audio_out; }
69
71 bool is_full_duplex() const { return this->audio_in_ != nullptr && this->audio_out_ != nullptr; }
72
75 i2s_chan_handle_t acquire_rx_channel();
77 void release_rx_channel();
78
82 i2s_chan_handle_t acquire_tx_channel();
85 void release_tx_channel();
87 bool is_tx_in_use() const { return this->tx_in_use_; }
88#endif
89 i2s_std_gpio_config_t get_pin_config() const {
90 return {.mclk = (gpio_num_t) this->mclk_pin_,
91 .bclk = (gpio_num_t) this->bclk_pin_,
92 .ws = (gpio_num_t) this->lrclk_pin_,
93 .dout = I2S_GPIO_UNUSED, // add local ports
94 .din = I2S_GPIO_UNUSED,
95 .invert_flags = {
96 .mclk_inv = false,
97 .bclk_inv = false,
98 .ws_inv = false,
99 }};
100 }
101
102 void set_mclk_pin(int pin) { this->mclk_pin_ = pin; }
103 void set_bclk_pin(int pin) { this->bclk_pin_ = pin; }
104 void set_lrclk_pin(int pin) { this->lrclk_pin_ = pin; }
105 void set_port(int port) { this->port_ = port; }
106#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
107 int get_port() const { return this->port_; }
108#else
109 i2s_port_t get_port() const { return static_cast<i2s_port_t>(this->port_); }
110#endif
111
112 void lock() { this->lock_.lock(); }
113 bool try_lock() { return this->lock_.try_lock(); }
114 void unlock() { this->lock_.unlock(); }
115
116 protected:
118
119#ifdef USE_I2S_AUDIO_FULL_DUPLEX
121 i2s_chan_handle_t acquire_(bool &in_use, i2s_chan_handle_t handle);
123 bool update_rx_channel_();
124
127 i2s_chan_handle_t rx_handle_{nullptr};
128 i2s_chan_handle_t tx_handle_{nullptr};
129 bool rx_in_use_{false};
130 bool tx_in_use_{false};
131 bool rx_enabled_{false};
132#endif
133 int mclk_pin_{I2S_GPIO_UNUSED};
134 int bclk_pin_{I2S_GPIO_UNUSED};
136 int port_{};
137};
138
139} // namespace esphome::i2s_audio
140
141#endif // USE_ESP32
Mutex implementation, with API based on the unavailable std::mutex.
Definition helpers.h:2096
void unlock()
Definition helpers.h:2107
bool try_lock()
Definition helpers.h:2106
Helper class to easily give an object a parent of type T.
Definition helpers.h:2073
i2s_std_slot_mask_t std_slot_mask_
Definition i2s_audio.h:37
i2s_slot_bit_width_t slot_bit_width_
Definition i2s_audio.h:38
void set_sample_rate(uint32_t sample_rate)
Definition i2s_audio.h:21
void set_mclk_multiple(i2s_mclk_multiple_t mclk_multiple)
Definition i2s_audio.h:23
void set_i2s_role(i2s_role_t role)
Definition i2s_audio.h:17
void set_use_apll(uint32_t use_apll)
Definition i2s_audio.h:22
void set_std_slot_mask(i2s_std_slot_mask_t std_slot_mask)
Definition i2s_audio.h:19
i2s_clock_src_t get_clock_source_() const
Definition i2s_audio.h:26
i2s_mclk_multiple_t mclk_multiple_
Definition i2s_audio.h:41
void set_slot_bit_width(i2s_slot_bit_width_t slot_bit_width)
Definition i2s_audio.h:20
void set_slot_mode(i2s_slot_mode_t slot_mode)
Definition i2s_audio.h:18
void set_audio_out(I2SAudioOut *audio_out)
Definition i2s_audio.h:68
i2s_std_gpio_config_t get_pin_config() const
Definition i2s_audio.h:89
i2s_chan_handle_t acquire_rx_channel()
Enables the full duplex RX channel.
Definition i2s_audio.cpp:56
bool is_full_duplex() const
True when a microphone and a speaker share this bus at the same time.
Definition i2s_audio.h:71
bool is_tx_in_use() const
True while another speaker holds the full duplex TX channel.
Definition i2s_audio.h:87
void set_audio_in(I2SAudioIn *audio_in)
Definition i2s_audio.h:67
i2s_chan_handle_t acquire_(bool &in_use, i2s_chan_handle_t handle)
Marks one side active and brings the shared clocks up; undoes the mark if that fails.
Definition i2s_audio.cpp:45
bool update_rx_channel_()
Enables the RX channel while either side is active, since it drives the shared clocks.
Definition i2s_audio.cpp:77
void release_rx_channel()
Releases the RX channel; it keeps running while the TX side needs its clocks. Main loop only.
Definition i2s_audio.cpp:58
i2s_chan_handle_t acquire_tx_channel()
Starts the shared clocks and hands over the full duplex TX channel, still disabled,...
Definition i2s_audio.cpp:63
void release_tx_channel()
Disables the TX channel and stops the shared clocks if the RX side is idle.
Definition i2s_audio.cpp:70
virtual void build_full_duplex_config(i2s_std_config_t &std_cfg)=0
Builds the RX configuration the parent uses to set up a full duplex channel pair.
virtual void build_full_duplex_config(i2s_chan_config_t &chan_cfg, i2s_std_config_t &std_cfg)
Builds the TX configuration the parent uses to set up a full duplex channel pair.
Definition i2s_audio.h:58
static void uint32_t
spi_device_handle_t handle