esphome 2024.8.2__py3-none-any.whl → 2024.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. esphome/__main__.py +6 -2
  2. esphome/components/api/api_connection.cpp +53 -0
  3. esphome/components/api/api_connection.h +4 -0
  4. esphome/components/api/api_pb2.cpp +280 -0
  5. esphome/components/api/api_pb2.h +91 -0
  6. esphome/components/api/api_pb2_service.cpp +85 -0
  7. esphome/components/api/api_pb2_service.h +28 -0
  8. esphome/components/async_tcp/__init__.py +3 -3
  9. esphome/components/atm90e26/sensor.py +10 -10
  10. esphome/components/atm90e32/sensor.py +1 -1
  11. esphome/components/bl0906/__init__.py +1 -0
  12. esphome/components/bl0906/bl0906.cpp +238 -0
  13. esphome/components/bl0906/bl0906.h +96 -0
  14. esphome/components/bl0906/const.py +4 -0
  15. esphome/components/bl0906/constants.h +122 -0
  16. esphome/components/bl0906/sensor.py +184 -0
  17. esphome/components/bl0942/__init__.py +1 -1
  18. esphome/components/bl0942/bl0942.cpp +127 -34
  19. esphome/components/bl0942/bl0942.h +87 -3
  20. esphome/components/bl0942/sensor.py +46 -8
  21. esphome/components/ble_client/__init__.py +1 -3
  22. esphome/components/ble_presence/binary_sensor.py +2 -2
  23. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
  24. esphome/components/bmp280/sensor.py +2 -93
  25. esphome/components/bmp280_base/__init__.py +88 -0
  26. esphome/components/{bmp280/bmp280.cpp → bmp280_base/bmp280_base.cpp} +11 -4
  27. esphome/components/{bmp280/bmp280.h → bmp280_base/bmp280_base.h} +9 -5
  28. esphome/components/bmp280_i2c/__init__.py +0 -0
  29. esphome/components/bmp280_i2c/bmp280_i2c.cpp +27 -0
  30. esphome/components/bmp280_i2c/bmp280_i2c.h +22 -0
  31. esphome/components/bmp280_i2c/sensor.py +22 -0
  32. esphome/components/bmp280_spi/__init__.py +0 -0
  33. esphome/components/bmp280_spi/bmp280_spi.cpp +65 -0
  34. esphome/components/bmp280_spi/bmp280_spi.h +20 -0
  35. esphome/components/bmp280_spi/sensor.py +22 -0
  36. esphome/components/captive_portal/captive_portal.cpp +2 -0
  37. esphome/components/captive_portal/captive_portal.h +3 -1
  38. esphome/components/ch422g/__init__.py +67 -0
  39. esphome/components/ch422g/ch422g.cpp +122 -0
  40. esphome/components/ch422g/ch422g.h +70 -0
  41. esphome/components/debug/debug_esp32.cpp +3 -1
  42. esphome/components/display/__init__.py +5 -4
  43. esphome/components/dsmr/dsmr.cpp +6 -0
  44. esphome/components/dsmr/dsmr.h +6 -0
  45. esphome/components/dsmr/text_sensor.py +7 -2
  46. esphome/components/e131/e131.cpp +2 -0
  47. esphome/components/e131/e131.h +3 -1
  48. esphome/components/e131/e131_addressable_light_effect.cpp +2 -0
  49. esphome/components/e131/e131_addressable_light_effect.h +2 -1
  50. esphome/components/e131/e131_packet.cpp +2 -0
  51. esphome/components/esp32_ble/ble_uuid.cpp +7 -0
  52. esphome/components/esp32_ble/ble_uuid.h +1 -0
  53. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +11 -9
  54. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +3 -3
  55. esphome/components/esp32_camera/__init__.py +4 -0
  56. esphome/components/esp32_camera/esp32_camera.cpp +9 -1
  57. esphome/components/esp32_camera/esp32_camera.h +3 -0
  58. esphome/components/esp32_can/canbus.py +18 -7
  59. esphome/components/esp32_can/esp32_can.cpp +8 -0
  60. esphome/components/esp32_can/esp32_can.h +4 -0
  61. esphome/components/esp32_rmt_led_strip/led_strip.cpp +14 -2
  62. esphome/components/esp32_rmt_led_strip/led_strip.h +3 -2
  63. esphome/components/esp32_rmt_led_strip/light.py +21 -4
  64. esphome/components/esphome/ota/ota_esphome.cpp +2 -1
  65. esphome/components/esphome/ota/ota_esphome.h +2 -0
  66. esphome/components/font/__init__.py +11 -22
  67. esphome/components/font/font.cpp +3 -2
  68. esphome/components/font/font.h +12 -3
  69. esphome/components/gree/climate.py +2 -1
  70. esphome/components/gree/gree.cpp +54 -3
  71. esphome/components/gree/gree.h +10 -2
  72. esphome/components/gt911/touchscreen/__init__.py +6 -4
  73. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +17 -0
  74. esphome/components/gt911/touchscreen/gt911_touchscreen.h +2 -0
  75. esphome/components/hmac_md5/__init__.py +2 -0
  76. esphome/components/hmac_md5/hmac_md5.cpp +56 -0
  77. esphome/components/hmac_md5/hmac_md5.h +48 -0
  78. esphome/components/homeassistant/__init__.py +13 -0
  79. esphome/components/homeassistant/switch/__init__.py +15 -2
  80. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  81. esphome/components/i2s_audio/__init__.py +88 -9
  82. esphome/components/i2s_audio/i2s_audio.h +20 -2
  83. esphome/components/i2s_audio/media_player/__init__.py +8 -4
  84. esphome/components/i2s_audio/media_player/i2s_audio_media_player.h +1 -1
  85. esphome/components/i2s_audio/microphone/__init__.py +19 -51
  86. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +18 -15
  87. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +0 -12
  88. esphome/components/i2s_audio/speaker/__init__.py +39 -27
  89. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +49 -37
  90. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +3 -4
  91. esphome/components/ili9xxx/display.py +16 -17
  92. esphome/components/ili9xxx/ili9xxx_display.cpp +1 -1
  93. esphome/components/ili9xxx/ili9xxx_display.h +18 -18
  94. esphome/components/ili9xxx/ili9xxx_init.h +0 -3
  95. esphome/components/improv_serial/improv_serial_component.cpp +2 -1
  96. esphome/components/improv_serial/improv_serial_component.h +2 -1
  97. esphome/components/ledc/ledc_output.cpp +11 -7
  98. esphome/components/libretiny/__init__.py +8 -13
  99. esphome/components/ltr501/__init__.py +1 -0
  100. esphome/components/ltr501/ltr501.cpp +542 -0
  101. esphome/components/ltr501/ltr501.h +184 -0
  102. esphome/components/ltr501/ltr_definitions_501.h +260 -0
  103. esphome/components/ltr501/sensor.py +274 -0
  104. esphome/components/ltr_als_ps/sensor.py +2 -2
  105. esphome/components/lvgl/__init__.py +19 -16
  106. esphome/components/lvgl/automation.py +90 -9
  107. esphome/components/lvgl/defines.py +29 -2
  108. esphome/components/lvgl/gradient.py +61 -0
  109. esphome/components/lvgl/lv_validation.py +45 -27
  110. esphome/components/lvgl/lvcode.py +8 -3
  111. esphome/components/lvgl/lvgl_esphome.cpp +54 -0
  112. esphome/components/lvgl/lvgl_esphome.h +9 -3
  113. esphome/components/lvgl/number/__init__.py +1 -0
  114. esphome/components/lvgl/number/lvgl_number.h +3 -1
  115. esphome/components/lvgl/schemas.py +16 -11
  116. esphome/components/lvgl/select/__init__.py +1 -0
  117. esphome/components/lvgl/select/lvgl_select.h +3 -1
  118. esphome/components/lvgl/switch/__init__.py +2 -1
  119. esphome/components/lvgl/switch/lvgl_switch.h +3 -1
  120. esphome/components/lvgl/text/__init__.py +1 -0
  121. esphome/components/lvgl/text/lvgl_text.h +3 -1
  122. esphome/components/lvgl/trigger.py +3 -2
  123. esphome/components/lvgl/types.py +2 -1
  124. esphome/components/lvgl/widgets/__init__.py +23 -8
  125. esphome/components/lvgl/widgets/arc.py +5 -1
  126. esphome/components/lvgl/widgets/buttonmatrix.py +5 -1
  127. esphome/components/lvgl/widgets/checkbox.py +8 -3
  128. esphome/components/lvgl/widgets/meter.py +8 -1
  129. esphome/components/lvgl/widgets/msgbox.py +26 -15
  130. esphome/components/lvgl/widgets/page.py +51 -7
  131. esphome/components/lvgl/widgets/tileview.py +2 -8
  132. esphome/components/max31856/max31856.cpp +12 -1
  133. esphome/components/max31856/max31856.h +5 -2
  134. esphome/components/max31856/sensor.py +20 -0
  135. esphome/components/mcp9600/sensor.py +2 -2
  136. esphome/components/mdns/__init__.py +6 -6
  137. esphome/components/media_player/media_player.h +16 -0
  138. esphome/components/micro_wake_word/__init__.py +2 -25
  139. esphome/components/microphone/microphone.h +1 -1
  140. esphome/components/mics_4514/mics_4514.cpp +26 -36
  141. esphome/components/modbus_controller/__init__.py +6 -0
  142. esphome/components/modbus_controller/const.py +2 -0
  143. esphome/components/modbus_controller/modbus_controller.cpp +30 -27
  144. esphome/components/modbus_controller/modbus_controller.h +22 -4
  145. esphome/components/network/__init__.py +11 -8
  146. esphome/components/pipsolar/pipsolar.cpp +3 -0
  147. esphome/components/pipsolar/pipsolar.h +1 -0
  148. esphome/components/pipsolar/switch/__init__.py +2 -0
  149. esphome/components/prometheus/prometheus_handler.cpp +2 -0
  150. esphome/components/prometheus/prometheus_handler.h +3 -1
  151. esphome/components/rp2040/__init__.py +7 -8
  152. esphome/components/rpi_dpi_rgb/display.py +20 -17
  153. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +36 -6
  154. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h +4 -0
  155. esphome/components/socket/socket.cpp +2 -0
  156. esphome/components/socket/socket.h +2 -0
  157. esphome/components/speaker/speaker.h +1 -1
  158. esphome/components/st7701s/display.py +35 -37
  159. esphome/components/st7701s/st7701s.cpp +11 -6
  160. esphome/components/st7701s/st7701s.h +1 -0
  161. esphome/components/statsd/__init__.py +65 -0
  162. esphome/components/statsd/statsd.cpp +156 -0
  163. esphome/components/statsd/statsd.h +86 -0
  164. esphome/components/tuya/__init__.py +1 -0
  165. esphome/components/tuya/number/__init__.py +39 -2
  166. esphome/components/tuya/number/tuya_number.cpp +58 -2
  167. esphome/components/tuya/number/tuya_number.h +12 -3
  168. esphome/components/udp/__init__.py +158 -0
  169. esphome/components/udp/binary_sensor.py +27 -0
  170. esphome/components/udp/sensor.py +27 -0
  171. esphome/components/udp/udp_component.cpp +616 -0
  172. esphome/components/udp/udp_component.h +158 -0
  173. esphome/components/uponor_smatrix/uponor_smatrix.cpp +4 -6
  174. esphome/components/uponor_smatrix/uponor_smatrix.h +0 -1
  175. esphome/components/veml7700/sensor.py +2 -2
  176. esphome/components/voice_assistant/__init__.py +6 -0
  177. esphome/components/voice_assistant/voice_assistant.cpp +24 -2
  178. esphome/components/voice_assistant/voice_assistant.h +20 -0
  179. esphome/components/web_server/__init__.py +11 -11
  180. esphome/components/web_server/list_entities.cpp +2 -0
  181. esphome/components/web_server/list_entities.h +3 -1
  182. esphome/components/web_server/web_server.cpp +2 -1
  183. esphome/components/web_server/web_server.h +2 -0
  184. esphome/components/web_server_base/web_server_base.cpp +2 -0
  185. esphome/components/web_server_base/web_server_base.h +3 -1
  186. esphome/components/wifi/wifi_component_libretiny.cpp +15 -1
  187. esphome/components/wireguard/__init__.py +9 -6
  188. esphome/components/wireguard/wireguard.cpp +2 -1
  189. esphome/components/wireguard/wireguard.h +3 -1
  190. esphome/config_validation.py +8 -0
  191. esphome/const.py +8 -1
  192. esphome/core/bytebuffer.cpp +117 -84
  193. esphome/core/bytebuffer.h +69 -21
  194. esphome/core/config.py +0 -3
  195. esphome/core/defines.h +2 -0
  196. esphome/core/ring_buffer.cpp +13 -2
  197. esphome/core/ring_buffer.h +56 -0
  198. esphome/external_files.py +5 -3
  199. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/METADATA +1 -1
  200. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/RECORD +204 -169
  201. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/LICENSE +0 -0
  202. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/WHEEL +0 -0
  203. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/entry_points.txt +0 -0
  204. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/top_level.txt +0 -0
@@ -1,16 +1,16 @@
1
- import esphome.config_validation as cv
2
- import esphome.final_validate as fv
3
- import esphome.codegen as cg
4
-
5
1
  from esphome import pins
6
- from esphome.const import CONF_ID
2
+ import esphome.codegen as cg
7
3
  from esphome.components.esp32 import get_esp32_variant
8
4
  from esphome.components.esp32.const import (
9
5
  VARIANT_ESP32,
6
+ VARIANT_ESP32C3,
10
7
  VARIANT_ESP32S2,
11
8
  VARIANT_ESP32S3,
12
- VARIANT_ESP32C3,
13
9
  )
10
+ import esphome.config_validation as cv
11
+ from esphome.const import CONF_CHANNEL, CONF_ID, CONF_SAMPLE_RATE
12
+ from esphome.cpp_generator import MockObjClass
13
+ import esphome.final_validate as fv
14
14
 
15
15
  CODEOWNERS = ["@jesserockz"]
16
16
  DEPENDENCIES = ["esp32"]
@@ -25,16 +25,26 @@ CONF_I2S_LRCLK_PIN = "i2s_lrclk_pin"
25
25
  CONF_I2S_AUDIO = "i2s_audio"
26
26
  CONF_I2S_AUDIO_ID = "i2s_audio_id"
27
27
 
28
+ CONF_BITS_PER_SAMPLE = "bits_per_sample"
28
29
  CONF_I2S_MODE = "i2s_mode"
29
30
  CONF_PRIMARY = "primary"
30
31
  CONF_SECONDARY = "secondary"
31
32
 
33
+ CONF_USE_APLL = "use_apll"
34
+ CONF_BITS_PER_SAMPLE = "bits_per_sample"
35
+ CONF_BITS_PER_CHANNEL = "bits_per_channel"
36
+ CONF_MONO = "mono"
37
+ CONF_LEFT = "left"
38
+ CONF_RIGHT = "right"
39
+ CONF_STEREO = "stereo"
40
+
32
41
  i2s_audio_ns = cg.esphome_ns.namespace("i2s_audio")
33
42
  I2SAudioComponent = i2s_audio_ns.class_("I2SAudioComponent", cg.Component)
34
- I2SAudioIn = i2s_audio_ns.class_("I2SAudioIn", cg.Parented.template(I2SAudioComponent))
35
- I2SAudioOut = i2s_audio_ns.class_(
36
- "I2SAudioOut", cg.Parented.template(I2SAudioComponent)
43
+ I2SAudioBase = i2s_audio_ns.class_(
44
+ "I2SAudioBase", cg.Parented.template(I2SAudioComponent)
37
45
  )
46
+ I2SAudioIn = i2s_audio_ns.class_("I2SAudioIn", I2SAudioBase)
47
+ I2SAudioOut = i2s_audio_ns.class_("I2SAudioOut", I2SAudioBase)
38
48
 
39
49
  i2s_mode_t = cg.global_ns.enum("i2s_mode_t")
40
50
  I2S_MODE_OPTIONS = {
@@ -50,6 +60,75 @@ I2S_PORTS = {
50
60
  VARIANT_ESP32C3: 1,
51
61
  }
52
62
 
63
+ i2s_channel_fmt_t = cg.global_ns.enum("i2s_channel_fmt_t")
64
+ I2S_CHANNELS = {
65
+ CONF_MONO: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ALL_LEFT,
66
+ CONF_LEFT: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_LEFT,
67
+ CONF_RIGHT: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_RIGHT,
68
+ CONF_STEREO: i2s_channel_fmt_t.I2S_CHANNEL_FMT_RIGHT_LEFT,
69
+ }
70
+
71
+ i2s_bits_per_sample_t = cg.global_ns.enum("i2s_bits_per_sample_t")
72
+ I2S_BITS_PER_SAMPLE = {
73
+ 8: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_8BIT,
74
+ 16: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_16BIT,
75
+ 24: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_24BIT,
76
+ 32: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_32BIT,
77
+ }
78
+
79
+ i2s_bits_per_chan_t = cg.global_ns.enum("i2s_bits_per_chan_t")
80
+ I2S_BITS_PER_CHANNEL = {
81
+ "default": i2s_bits_per_chan_t.I2S_BITS_PER_CHAN_DEFAULT,
82
+ 8: i2s_bits_per_chan_t.I2S_BITS_PER_CHAN_8BIT,
83
+ 16: i2s_bits_per_chan_t.I2S_BITS_PER_CHAN_16BIT,
84
+ 24: i2s_bits_per_chan_t.I2S_BITS_PER_CHAN_24BIT,
85
+ 32: i2s_bits_per_chan_t.I2S_BITS_PER_CHAN_32BIT,
86
+ }
87
+
88
+ _validate_bits = cv.float_with_unit("bits", "bit")
89
+
90
+
91
+ def i2s_audio_component_schema(
92
+ class_: MockObjClass,
93
+ *,
94
+ default_sample_rate: int,
95
+ default_channel: str,
96
+ default_bits_per_sample: str,
97
+ ):
98
+ return cv.Schema(
99
+ {
100
+ cv.GenerateID(): cv.declare_id(class_),
101
+ cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
102
+ cv.Optional(CONF_CHANNEL, default=default_channel): cv.enum(I2S_CHANNELS),
103
+ cv.Optional(CONF_SAMPLE_RATE, default=default_sample_rate): cv.int_range(
104
+ min=1
105
+ ),
106
+ cv.Optional(CONF_BITS_PER_SAMPLE, default=default_bits_per_sample): cv.All(
107
+ _validate_bits, cv.enum(I2S_BITS_PER_SAMPLE)
108
+ ),
109
+ cv.Optional(CONF_I2S_MODE, default=CONF_PRIMARY): cv.enum(
110
+ I2S_MODE_OPTIONS, lower=True
111
+ ),
112
+ cv.Optional(CONF_USE_APLL, default=False): cv.boolean,
113
+ cv.Optional(CONF_BITS_PER_CHANNEL, default="default"): cv.All(
114
+ cv.Any(cv.float_with_unit("bits", "bit"), "default"),
115
+ cv.enum(I2S_BITS_PER_CHANNEL),
116
+ ),
117
+ }
118
+ )
119
+
120
+
121
+ async def register_i2s_audio_component(var, config):
122
+ await cg.register_parented(var, config[CONF_I2S_AUDIO_ID])
123
+
124
+ cg.add(var.set_i2s_mode(config[CONF_I2S_MODE]))
125
+ cg.add(var.set_channel(config[CONF_CHANNEL]))
126
+ cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
127
+ cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
128
+ cg.add(var.set_bits_per_channel(config[CONF_BITS_PER_CHANNEL]))
129
+ cg.add(var.set_use_apll(config[CONF_USE_APLL]))
130
+
131
+
53
132
  CONFIG_SCHEMA = cv.Schema(
54
133
  {
55
134
  cv.GenerateID(): cv.declare_id(I2SAudioComponent),
@@ -11,9 +11,27 @@ namespace i2s_audio {
11
11
 
12
12
  class I2SAudioComponent;
13
13
 
14
- class I2SAudioIn : public Parented<I2SAudioComponent> {};
14
+ class I2SAudioBase : public Parented<I2SAudioComponent> {
15
+ public:
16
+ void set_i2s_mode(i2s_mode_t mode) { this->i2s_mode_ = mode; }
17
+ void set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; }
18
+ void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
19
+ void set_bits_per_sample(i2s_bits_per_sample_t bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }
20
+ void set_bits_per_channel(i2s_bits_per_chan_t bits_per_channel) { this->bits_per_channel_ = bits_per_channel; }
21
+ void set_use_apll(uint32_t use_apll) { this->use_apll_ = use_apll; }
22
+
23
+ protected:
24
+ i2s_mode_t i2s_mode_{};
25
+ i2s_channel_fmt_t channel_;
26
+ uint32_t sample_rate_;
27
+ i2s_bits_per_sample_t bits_per_sample_;
28
+ i2s_bits_per_chan_t bits_per_channel_;
29
+ bool use_apll_;
30
+ };
31
+
32
+ class I2SAudioIn : public I2SAudioBase {};
15
33
 
16
- class I2SAudioOut : public Parented<I2SAudioComponent> {};
34
+ class I2SAudioOut : public I2SAudioBase {};
17
35
 
18
36
  class I2SAudioComponent : public Component {
19
37
  public:
@@ -12,6 +12,10 @@ from .. import (
12
12
  I2SAudioOut,
13
13
  CONF_I2S_AUDIO_ID,
14
14
  CONF_I2S_DOUT_PIN,
15
+ CONF_LEFT,
16
+ CONF_RIGHT,
17
+ CONF_MONO,
18
+ CONF_STEREO,
15
19
  )
16
20
 
17
21
  CODEOWNERS = ["@jesserockz"]
@@ -30,12 +34,12 @@ CONF_DAC_TYPE = "dac_type"
30
34
  CONF_I2S_COMM_FMT = "i2s_comm_fmt"
31
35
 
32
36
  INTERNAL_DAC_OPTIONS = {
33
- "left": i2s_dac_mode_t.I2S_DAC_CHANNEL_LEFT_EN,
34
- "right": i2s_dac_mode_t.I2S_DAC_CHANNEL_RIGHT_EN,
35
- "stereo": i2s_dac_mode_t.I2S_DAC_CHANNEL_BOTH_EN,
37
+ CONF_LEFT: i2s_dac_mode_t.I2S_DAC_CHANNEL_LEFT_EN,
38
+ CONF_RIGHT: i2s_dac_mode_t.I2S_DAC_CHANNEL_RIGHT_EN,
39
+ CONF_STEREO: i2s_dac_mode_t.I2S_DAC_CHANNEL_BOTH_EN,
36
40
  }
37
41
 
38
- EXTERNAL_DAC_OPTIONS = ["mono", "stereo"]
42
+ EXTERNAL_DAC_OPTIONS = [CONF_MONO, CONF_STEREO]
39
43
 
40
44
  NO_INTERNAL_DAC_VARIANTS = [esp32.const.VARIANT_ESP32S2]
41
45
 
@@ -23,7 +23,7 @@ enum I2SState : uint8_t {
23
23
  I2S_STATE_STOPPING,
24
24
  };
25
25
 
26
- class I2SAudioMediaPlayer : public Component, public media_player::MediaPlayer, public I2SAudioOut {
26
+ class I2SAudioMediaPlayer : public Component, public Parented<I2SAudioComponent>, public media_player::MediaPlayer {
27
27
  public:
28
28
  void setup() override;
29
29
  float get_setup_priority() const override { return esphome::setup_priority::LATE; }
@@ -1,20 +1,17 @@
1
- import esphome.config_validation as cv
2
- import esphome.codegen as cg
3
-
4
1
  from esphome import pins
5
- from esphome.const import CONF_CHANNEL, CONF_ID, CONF_NUMBER, CONF_SAMPLE_RATE
6
- from esphome.components import microphone, esp32
2
+ import esphome.codegen as cg
3
+ from esphome.components import esp32, microphone
7
4
  from esphome.components.adc import ESP32_VARIANT_ADC1_PIN_TO_CHANNEL, validate_adc_pin
5
+ import esphome.config_validation as cv
6
+ from esphome.const import CONF_ID, CONF_NUMBER
8
7
 
9
8
  from .. import (
10
- CONF_I2S_MODE,
11
- CONF_PRIMARY,
12
- I2S_MODE_OPTIONS,
13
- i2s_audio_ns,
14
- I2SAudioComponent,
15
- I2SAudioIn,
16
- CONF_I2S_AUDIO_ID,
17
9
  CONF_I2S_DIN_PIN,
10
+ CONF_RIGHT,
11
+ I2SAudioIn,
12
+ i2s_audio_component_schema,
13
+ i2s_audio_ns,
14
+ register_i2s_audio_component,
18
15
  )
19
16
 
20
17
  CODEOWNERS = ["@jesserockz"]
@@ -23,29 +20,14 @@ DEPENDENCIES = ["i2s_audio"]
23
20
  CONF_ADC_PIN = "adc_pin"
24
21
  CONF_ADC_TYPE = "adc_type"
25
22
  CONF_PDM = "pdm"
26
- CONF_BITS_PER_SAMPLE = "bits_per_sample"
27
- CONF_USE_APLL = "use_apll"
28
23
 
29
24
  I2SAudioMicrophone = i2s_audio_ns.class_(
30
25
  "I2SAudioMicrophone", I2SAudioIn, microphone.Microphone, cg.Component
31
26
  )
32
27
 
33
- i2s_channel_fmt_t = cg.global_ns.enum("i2s_channel_fmt_t")
34
- CHANNELS = {
35
- "left": i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_LEFT,
36
- "right": i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_RIGHT,
37
- }
38
- i2s_bits_per_sample_t = cg.global_ns.enum("i2s_bits_per_sample_t")
39
- BITS_PER_SAMPLE = {
40
- 16: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_16BIT,
41
- 32: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_32BIT,
42
- }
43
-
44
28
  INTERNAL_ADC_VARIANTS = [esp32.const.VARIANT_ESP32]
45
29
  PDM_VARIANTS = [esp32.const.VARIANT_ESP32, esp32.const.VARIANT_ESP32S3]
46
30
 
47
- _validate_bits = cv.float_with_unit("bits", "bit")
48
-
49
31
 
50
32
  def validate_esp32_variant(config):
51
33
  variant = esp32.get_esp32_variant()
@@ -62,21 +44,15 @@ def validate_esp32_variant(config):
62
44
 
63
45
 
64
46
  BASE_SCHEMA = microphone.MICROPHONE_SCHEMA.extend(
65
- {
66
- cv.GenerateID(): cv.declare_id(I2SAudioMicrophone),
67
- cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
68
- cv.Optional(CONF_CHANNEL, default="right"): cv.enum(CHANNELS),
69
- cv.Optional(CONF_SAMPLE_RATE, default=16000): cv.int_range(min=1),
70
- cv.Optional(CONF_BITS_PER_SAMPLE, default="32bit"): cv.All(
71
- _validate_bits, cv.enum(BITS_PER_SAMPLE)
72
- ),
73
- cv.Optional(CONF_USE_APLL, default=False): cv.boolean,
74
- cv.Optional(CONF_I2S_MODE, default=CONF_PRIMARY): cv.enum(
75
- I2S_MODE_OPTIONS, lower=True
76
- ),
77
- }
47
+ i2s_audio_component_schema(
48
+ I2SAudioMicrophone,
49
+ default_sample_rate=16000,
50
+ default_channel=CONF_RIGHT,
51
+ default_bits_per_sample="32bit",
52
+ )
78
53
  ).extend(cv.COMPONENT_SCHEMA)
79
54
 
55
+
80
56
  CONFIG_SCHEMA = cv.All(
81
57
  cv.typed_schema(
82
58
  {
@@ -88,7 +64,7 @@ CONFIG_SCHEMA = cv.All(
88
64
  "external": BASE_SCHEMA.extend(
89
65
  {
90
66
  cv.Required(CONF_I2S_DIN_PIN): pins.internal_gpio_input_pin_number,
91
- cv.Required(CONF_PDM): cv.boolean,
67
+ cv.Optional(CONF_PDM, default=False): cv.boolean,
92
68
  }
93
69
  ),
94
70
  },
@@ -101,8 +77,8 @@ CONFIG_SCHEMA = cv.All(
101
77
  async def to_code(config):
102
78
  var = cg.new_Pvariable(config[CONF_ID])
103
79
  await cg.register_component(var, config)
104
-
105
- await cg.register_parented(var, config[CONF_I2S_AUDIO_ID])
80
+ await register_i2s_audio_component(var, config)
81
+ await microphone.register_microphone(var, config)
106
82
 
107
83
  if config[CONF_ADC_TYPE] == "internal":
108
84
  variant = esp32.get_esp32_variant()
@@ -112,11 +88,3 @@ async def to_code(config):
112
88
  else:
113
89
  cg.add(var.set_din_pin(config[CONF_I2S_DIN_PIN]))
114
90
  cg.add(var.set_pdm(config[CONF_PDM]))
115
-
116
- cg.add(var.set_i2s_mode(config[CONF_I2S_MODE]))
117
- cg.add(var.set_channel(config[CONF_CHANNEL]))
118
- cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
119
- cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
120
- cg.add(var.set_use_apll(config[CONF_USE_APLL]))
121
-
122
- await microphone.register_microphone(var, config)
@@ -58,7 +58,7 @@ void I2SAudioMicrophone::start_() {
58
58
  .tx_desc_auto_clear = false,
59
59
  .fixed_mclk = 0,
60
60
  .mclk_multiple = I2S_MCLK_MULTIPLE_256,
61
- .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
61
+ .bits_per_chan = this->bits_per_channel_,
62
62
  };
63
63
 
64
64
  esp_err_t err;
@@ -167,21 +167,24 @@ size_t I2SAudioMicrophone::read(int16_t *buf, size_t len) {
167
167
  return 0;
168
168
  }
169
169
  this->status_clear_warning();
170
- if (this->bits_per_sample_ == I2S_BITS_PER_SAMPLE_16BIT) {
171
- return bytes_read;
172
- } else if (this->bits_per_sample_ == I2S_BITS_PER_SAMPLE_32BIT) {
173
- std::vector<int16_t> samples;
174
- size_t samples_read = bytes_read / sizeof(int32_t);
175
- samples.resize(samples_read);
176
- for (size_t i = 0; i < samples_read; i++) {
177
- int32_t temp = reinterpret_cast<int32_t *>(buf)[i] >> 14;
178
- samples[i] = clamp<int16_t>(temp, INT16_MIN, INT16_MAX);
170
+ // ESP-IDF I2S implementation right-extends 8-bit data to 16 bits,
171
+ // and 24-bit data to 32 bits.
172
+ switch (this->bits_per_sample_) {
173
+ case I2S_BITS_PER_SAMPLE_8BIT:
174
+ case I2S_BITS_PER_SAMPLE_16BIT:
175
+ return bytes_read;
176
+ case I2S_BITS_PER_SAMPLE_24BIT:
177
+ case I2S_BITS_PER_SAMPLE_32BIT: {
178
+ size_t samples_read = bytes_read / sizeof(int32_t);
179
+ for (size_t i = 0; i < samples_read; i++) {
180
+ int32_t temp = reinterpret_cast<int32_t *>(buf)[i] >> 14;
181
+ buf[i] = clamp<int16_t>(temp, INT16_MIN, INT16_MAX);
182
+ }
183
+ return samples_read * sizeof(int16_t);
179
184
  }
180
- memcpy(buf, samples.data(), samples_read * sizeof(int16_t));
181
- return samples_read * sizeof(int16_t);
182
- } else {
183
- ESP_LOGE(TAG, "Unsupported bits per sample: %d", this->bits_per_sample_);
184
- return 0;
185
+ default:
186
+ ESP_LOGE(TAG, "Unsupported bits per sample: %d", this->bits_per_sample_);
187
+ return 0;
185
188
  }
186
189
  }
187
190
 
@@ -30,13 +30,6 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
30
30
  }
31
31
  #endif
32
32
 
33
- void set_i2s_mode(i2s_mode_t mode) { this->i2s_mode_ = mode; }
34
-
35
- void set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; }
36
- void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
37
- void set_bits_per_sample(i2s_bits_per_sample_t bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }
38
- void set_use_apll(uint32_t use_apll) { this->use_apll_ = use_apll; }
39
-
40
33
  protected:
41
34
  void start_();
42
35
  void stop_();
@@ -48,11 +41,6 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
48
41
  bool adc_{false};
49
42
  #endif
50
43
  bool pdm_{false};
51
- i2s_mode_t i2s_mode_{};
52
- i2s_channel_fmt_t channel_;
53
- uint32_t sample_rate_;
54
- i2s_bits_per_sample_t bits_per_sample_;
55
- bool use_apll_;
56
44
 
57
45
  HighFrequencyLoopRequester high_freq_;
58
46
  };
@@ -1,15 +1,19 @@
1
- import esphome.codegen as cg
2
- import esphome.config_validation as cv
3
1
  from esphome import pins
4
- from esphome.const import CONF_ID, CONF_MODE
2
+ import esphome.codegen as cg
5
3
  from esphome.components import esp32, speaker
4
+ import esphome.config_validation as cv
5
+ from esphome.const import CONF_CHANNEL, CONF_ID, CONF_MODE, CONF_TIMEOUT
6
6
 
7
7
  from .. import (
8
- CONF_I2S_AUDIO_ID,
9
8
  CONF_I2S_DOUT_PIN,
10
- I2SAudioComponent,
9
+ CONF_LEFT,
10
+ CONF_MONO,
11
+ CONF_RIGHT,
12
+ CONF_STEREO,
11
13
  I2SAudioOut,
14
+ i2s_audio_component_schema,
12
15
  i2s_audio_ns,
16
+ register_i2s_audio_component,
13
17
  )
14
18
 
15
19
  CODEOWNERS = ["@jesserockz"]
@@ -19,19 +23,16 @@ I2SAudioSpeaker = i2s_audio_ns.class_(
19
23
  "I2SAudioSpeaker", cg.Component, speaker.Speaker, I2SAudioOut
20
24
  )
21
25
 
22
- i2s_dac_mode_t = cg.global_ns.enum("i2s_dac_mode_t")
23
26
 
24
- CONF_MUTE_PIN = "mute_pin"
25
27
  CONF_DAC_TYPE = "dac_type"
26
28
 
29
+ i2s_dac_mode_t = cg.global_ns.enum("i2s_dac_mode_t")
27
30
  INTERNAL_DAC_OPTIONS = {
28
- "left": i2s_dac_mode_t.I2S_DAC_CHANNEL_LEFT_EN,
29
- "right": i2s_dac_mode_t.I2S_DAC_CHANNEL_RIGHT_EN,
30
- "stereo": i2s_dac_mode_t.I2S_DAC_CHANNEL_BOTH_EN,
31
+ CONF_LEFT: i2s_dac_mode_t.I2S_DAC_CHANNEL_LEFT_EN,
32
+ CONF_RIGHT: i2s_dac_mode_t.I2S_DAC_CHANNEL_RIGHT_EN,
33
+ CONF_STEREO: i2s_dac_mode_t.I2S_DAC_CHANNEL_BOTH_EN,
31
34
  }
32
35
 
33
- EXTERNAL_DAC_OPTIONS = ["mono", "stereo"]
34
-
35
36
  NO_INTERNAL_DAC_VARIANTS = [esp32.const.VARIANT_ESP32S2]
36
37
 
37
38
 
@@ -44,28 +45,40 @@ def validate_esp32_variant(config):
44
45
  return config
45
46
 
46
47
 
48
+ BASE_SCHEMA = (
49
+ speaker.SPEAKER_SCHEMA.extend(
50
+ i2s_audio_component_schema(
51
+ I2SAudioSpeaker,
52
+ default_sample_rate=16000,
53
+ default_channel=CONF_MONO,
54
+ default_bits_per_sample="16bit",
55
+ )
56
+ )
57
+ .extend(
58
+ {
59
+ cv.Optional(
60
+ CONF_TIMEOUT, default="100ms"
61
+ ): cv.positive_time_period_milliseconds,
62
+ }
63
+ )
64
+ .extend(cv.COMPONENT_SCHEMA)
65
+ )
66
+
47
67
  CONFIG_SCHEMA = cv.All(
48
68
  cv.typed_schema(
49
69
  {
50
- "internal": speaker.SPEAKER_SCHEMA.extend(
70
+ "internal": BASE_SCHEMA.extend(
51
71
  {
52
- cv.GenerateID(): cv.declare_id(I2SAudioSpeaker),
53
- cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
54
72
  cv.Required(CONF_MODE): cv.enum(INTERNAL_DAC_OPTIONS, lower=True),
55
73
  }
56
- ).extend(cv.COMPONENT_SCHEMA),
57
- "external": speaker.SPEAKER_SCHEMA.extend(
74
+ ),
75
+ "external": BASE_SCHEMA.extend(
58
76
  {
59
- cv.GenerateID(): cv.declare_id(I2SAudioSpeaker),
60
- cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
61
77
  cv.Required(
62
78
  CONF_I2S_DOUT_PIN
63
79
  ): pins.internal_gpio_output_pin_number,
64
- cv.Optional(CONF_MODE, default="mono"): cv.one_of(
65
- *EXTERNAL_DAC_OPTIONS, lower=True
66
- ),
67
80
  }
68
- ).extend(cv.COMPONENT_SCHEMA),
81
+ ),
69
82
  },
70
83
  key=CONF_DAC_TYPE,
71
84
  ),
@@ -76,12 +89,11 @@ CONFIG_SCHEMA = cv.All(
76
89
  async def to_code(config):
77
90
  var = cg.new_Pvariable(config[CONF_ID])
78
91
  await cg.register_component(var, config)
92
+ await register_i2s_audio_component(var, config)
79
93
  await speaker.register_speaker(var, config)
80
94
 
81
- await cg.register_parented(var, config[CONF_I2S_AUDIO_ID])
82
-
83
95
  if config[CONF_DAC_TYPE] == "internal":
84
- cg.add(var.set_internal_dac_mode(config[CONF_MODE]))
96
+ cg.add(var.set_internal_dac_mode(config[CONF_CHANNEL]))
85
97
  else:
86
98
  cg.add(var.set_dout_pin(config[CONF_I2S_DOUT_PIN]))
87
- cg.add(var.set_external_dac_channels(2 if config[CONF_MODE] == "stereo" else 1))
99
+ cg.add(var.set_timeout(config[CONF_TIMEOUT]))
@@ -56,6 +56,21 @@ void I2SAudioSpeaker::start_() {
56
56
  this->task_created_ = true;
57
57
  }
58
58
 
59
+ template<typename a, typename b> const uint8_t *convert_data_format(const a *from, b *to, size_t &bytes, bool repeat) {
60
+ if (sizeof(a) == sizeof(b) && !repeat) {
61
+ return reinterpret_cast<const uint8_t *>(from);
62
+ }
63
+ const b *result = to;
64
+ for (size_t i = 0; i < bytes; i += sizeof(a)) {
65
+ b value = static_cast<b>(*from++) << (sizeof(b) - sizeof(a)) * 8;
66
+ *to++ = value;
67
+ if (repeat)
68
+ *to++ = value;
69
+ }
70
+ bytes *= (sizeof(b) / sizeof(a)) * (repeat ? 2 : 1); // NOLINT
71
+ return reinterpret_cast<const uint8_t *>(result);
72
+ }
73
+
59
74
  void I2SAudioSpeaker::player_task(void *params) {
60
75
  I2SAudioSpeaker *this_speaker = (I2SAudioSpeaker *) params;
61
76
 
@@ -64,19 +79,19 @@ void I2SAudioSpeaker::player_task(void *params) {
64
79
  xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY);
65
80
 
66
81
  i2s_driver_config_t config = {
67
- .mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX),
68
- .sample_rate = 16000,
69
- .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
70
- .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
82
+ .mode = (i2s_mode_t) (this_speaker->i2s_mode_ | I2S_MODE_TX),
83
+ .sample_rate = this_speaker->sample_rate_,
84
+ .bits_per_sample = this_speaker->bits_per_sample_,
85
+ .channel_format = this_speaker->channel_,
71
86
  .communication_format = I2S_COMM_FORMAT_STAND_I2S,
72
87
  .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
73
88
  .dma_buf_count = 8,
74
- .dma_buf_len = 128,
75
- .use_apll = false,
89
+ .dma_buf_len = 256,
90
+ .use_apll = this_speaker->use_apll_,
76
91
  .tx_desc_auto_clear = true,
77
- .fixed_mclk = I2S_PIN_NO_CHANGE,
92
+ .fixed_mclk = 0,
78
93
  .mclk_multiple = I2S_MCLK_MULTIPLE_256,
79
- .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
94
+ .bits_per_chan = this_speaker->bits_per_channel_,
80
95
  };
81
96
  #if SOC_I2S_SUPPORTS_DAC
82
97
  if (this_speaker->internal_dac_mode_ != I2S_DAC_CHANNEL_DISABLE) {
@@ -114,10 +129,11 @@ void I2SAudioSpeaker::player_task(void *params) {
114
129
  event.type = TaskEventType::STARTED;
115
130
  xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY);
116
131
 
117
- int16_t buffer[BUFFER_SIZE / 2];
132
+ int32_t buffer[BUFFER_SIZE];
118
133
 
119
134
  while (true) {
120
- if (xQueueReceive(this_speaker->buffer_queue_, &data_event, 100 / portTICK_PERIOD_MS) != pdTRUE) {
135
+ if (xQueueReceive(this_speaker->buffer_queue_, &data_event, this_speaker->timeout_ / portTICK_PERIOD_MS) !=
136
+ pdTRUE) {
121
137
  break; // End of audio from main thread
122
138
  }
123
139
  if (data_event.stop) {
@@ -125,17 +141,28 @@ void I2SAudioSpeaker::player_task(void *params) {
125
141
  xQueueReset(this_speaker->buffer_queue_); // Flush queue
126
142
  break;
127
143
  }
128
- size_t bytes_written;
129
-
130
- memmove(buffer, data_event.data, data_event.len);
131
- size_t remaining = data_event.len / 2;
132
- size_t current = 0;
133
144
 
134
- while (remaining > 0) {
135
- uint32_t sample = (buffer[current] << 16) | (buffer[current] & 0xFFFF);
145
+ const uint8_t *data = data_event.data;
146
+ size_t remaining = data_event.len;
147
+ switch (this_speaker->bits_per_sample_) {
148
+ case I2S_BITS_PER_SAMPLE_8BIT:
149
+ case I2S_BITS_PER_SAMPLE_16BIT: {
150
+ data = convert_data_format(reinterpret_cast<const int16_t *>(data), reinterpret_cast<int16_t *>(buffer),
151
+ remaining, this_speaker->channel_ == I2S_CHANNEL_FMT_ALL_LEFT);
152
+ break;
153
+ }
154
+ case I2S_BITS_PER_SAMPLE_24BIT:
155
+ case I2S_BITS_PER_SAMPLE_32BIT: {
156
+ data = convert_data_format(reinterpret_cast<const int16_t *>(data), reinterpret_cast<int32_t *>(buffer),
157
+ remaining, this_speaker->channel_ == I2S_CHANNEL_FMT_ALL_LEFT);
158
+ break;
159
+ }
160
+ }
136
161
 
137
- esp_err_t err = i2s_write(this_speaker->parent_->get_port(), &sample, sizeof(sample), &bytes_written,
138
- (10 / portTICK_PERIOD_MS));
162
+ while (remaining != 0) {
163
+ size_t bytes_written;
164
+ esp_err_t err =
165
+ i2s_write(this_speaker->parent_->get_port(), data, remaining, &bytes_written, (32 / portTICK_PERIOD_MS));
139
166
  if (err != ESP_OK) {
140
167
  event = {.type = TaskEventType::WARNING, .err = err};
141
168
  if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) {
@@ -143,21 +170,8 @@ void I2SAudioSpeaker::player_task(void *params) {
143
170
  }
144
171
  continue;
145
172
  }
146
- if (bytes_written != sizeof(sample)) {
147
- event = {.type = TaskEventType::WARNING, .err = ESP_FAIL};
148
- if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) {
149
- ESP_LOGW(TAG, "Failed to send WARNING event");
150
- }
151
- continue;
152
- }
153
- remaining--;
154
- current++;
155
- }
156
-
157
- event.type = TaskEventType::PLAYING;
158
- event.err = current;
159
- if (xQueueSend(this_speaker->event_queue_, &event, 10 / portTICK_PERIOD_MS) != pdTRUE) {
160
- ESP_LOGW(TAG, "Failed to send PLAYING event");
173
+ data += bytes_written;
174
+ remaining -= bytes_written;
161
175
  }
162
176
  }
163
177
 
@@ -213,13 +227,11 @@ void I2SAudioSpeaker::watch_() {
213
227
  case TaskEventType::STARTED:
214
228
  ESP_LOGD(TAG, "Started I2S Audio Speaker");
215
229
  this->state_ = speaker::STATE_RUNNING;
230
+ this->status_clear_warning();
216
231
  break;
217
232
  case TaskEventType::STOPPING:
218
233
  ESP_LOGD(TAG, "Stopping I2S Audio Speaker");
219
234
  break;
220
- case TaskEventType::PLAYING:
221
- this->status_clear_warning();
222
- break;
223
235
  case TaskEventType::STOPPED:
224
236
  this->state_ = speaker::STATE_STOPPED;
225
237
  vTaskDelete(this->player_task_handle_);