ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
audio.h
Go to the documentation of this file.
1#pragma once
2
4#include "esphome/core/helpers.h" // for ESPDEPRECATED
5
6#include <cstddef>
7#include <cstdint>
8
9namespace esphome::audio {
10
12 /* Class to respresent important parameters of the audio stream that also provides helper function to convert between
13 * various audio related units.
14 *
15 * - An audio sample represents a unit of audio for one channel.
16 * - A frame represents a unit of audio with a sample for every channel.
17 *
18 * In general, converting between bytes, samples, and frames shouldn't result in rounding errors so long as frames
19 * are used as the main unit when transferring audio data. Durations may result in rounding for certain sample rates;
20 * e.g., 44.1 KHz. The ``frames_to_milliseconds_with_remainder`` function should be used for accuracy, as it takes
21 * into account the remainder rather than just ignoring any rounding.
22 */
23 public:
25 : AudioStreamInfo(16, 1, 16000) {}; // Default values represent ESPHome's audio components historical values
26 AudioStreamInfo(uint8_t bits_per_sample, uint8_t channels, uint32_t sample_rate);
27
28 uint8_t get_bits_per_sample() const { return this->bits_per_sample_; }
29 uint8_t get_channels() const { return this->channels_; }
30 uint32_t get_sample_rate() const { return this->sample_rate_; }
31
36 uint32_t bytes_to_ms(size_t bytes) const {
37 return static_cast<uint64_t>(bytes) * 1000 / (this->sample_rate_ * this->bytes_per_sample_ * this->channels_);
38 }
39
43 uint32_t bytes_to_frames(size_t bytes) const { return (bytes / (this->bytes_per_sample_ * this->channels_)); }
44
48 uint32_t bytes_to_samples(size_t bytes) const { return (bytes / this->bytes_per_sample_); }
49
53 size_t frames_to_bytes(uint32_t frames) const { return frames * this->bytes_per_sample_ * this->channels_; }
54
58 size_t samples_to_bytes(uint32_t samples) const { return samples * this->bytes_per_sample_; }
59
63 uint32_t ms_to_frames(uint32_t ms) const { return (static_cast<uint64_t>(ms) * this->sample_rate_) / 1000; }
64
69 return (static_cast<uint64_t>(ms) * this->channels_ * this->sample_rate_) / 1000;
70 }
71
75 size_t ms_to_bytes(uint32_t ms) const {
76 return (static_cast<uint64_t>(ms) * this->bytes_per_sample_ * this->channels_ * this->sample_rate_) / 1000;
77 }
78
84
91
92 // Class comparison operators
93 bool operator==(const AudioStreamInfo &rhs) const;
94 bool operator!=(const AudioStreamInfo &rhs) const { return !operator==(rhs); }
95
96 protected:
98 uint8_t channels_;
100
101 // The greatest common divisor between 1000 ms = 1 second and the sample rate. Used to avoid accumulating error when
102 // converting from frames to duration. Computed at construction.
104
105 // Conversion factor derived from the number of bits per sample. Assumes audio data is aligned to the byte. Computed
106 // at construction.
108};
109
110enum class AudioFileType : uint8_t {
111 NONE = 0,
112#ifdef USE_AUDIO_FLAC_SUPPORT
113 FLAC,
114#endif
115#ifdef USE_AUDIO_MP3_SUPPORT
116 MP3,
117#endif
118#ifdef USE_AUDIO_OPUS_SUPPORT
119 OPUS,
120#endif
121#ifdef USE_AUDIO_WAV_SUPPORT
122 WAV,
123#endif
124};
125
126struct AudioFile {
127 const uint8_t *data;
128 size_t length;
130};
131
135const char *audio_file_type_to_string(AudioFileType file_type);
136
142AudioFileType detect_audio_file_type(const char *content_type, const char *url);
143
149// Remove before 2026.12.0
150ESPDEPRECATED("Use esp_audio_libs::gain::apply() (from <gain.h>) instead. Removed in 2026.12.0.", "2026.6.0")
151void scale_audio_samples(const int16_t *audio_samples, int16_t *output_buffer, int16_t scale_factor,
153
158inline int32_t unpack_audio_sample_to_q31(const uint8_t *data, size_t bytes_per_sample) {
159 int32_t sample = 0;
160 if (bytes_per_sample == 1) {
161 sample |= data[0] << 24;
162 } else if (bytes_per_sample == 2) {
163 sample |= data[0] << 16;
164 sample |= data[1] << 24;
165 } else if (bytes_per_sample == 3) {
166 sample |= data[0] << 8;
167 sample |= data[1] << 16;
168 sample |= data[2] << 24;
169 } else if (bytes_per_sample == 4) {
170 sample |= data[0];
171 sample |= data[1] << 8;
172 sample |= data[2] << 16;
173 sample |= data[3] << 24;
174 }
175
176 return sample;
177}
178
184inline void pack_q31_as_audio_sample(int32_t sample, uint8_t *data, size_t bytes_per_sample) {
185 if (bytes_per_sample == 1) {
186 data[0] = static_cast<uint8_t>(sample >> 24);
187 } else if (bytes_per_sample == 2) {
188 data[0] = static_cast<uint8_t>(sample >> 16);
189 data[1] = static_cast<uint8_t>(sample >> 24);
190 } else if (bytes_per_sample == 3) {
191 data[0] = static_cast<uint8_t>(sample >> 8);
192 data[1] = static_cast<uint8_t>(sample >> 16);
193 data[2] = static_cast<uint8_t>(sample >> 24);
194 } else if (bytes_per_sample == 4) {
195 data[0] = static_cast<uint8_t>(sample);
196 data[1] = static_cast<uint8_t>(sample >> 8);
197 data[2] = static_cast<uint8_t>(sample >> 16);
198 data[3] = static_cast<uint8_t>(sample >> 24);
199 }
200}
201
202} // namespace esphome::audio
bool operator!=(const AudioStreamInfo &rhs) const
Definition audio.h:94
size_t ms_to_bytes(uint32_t ms) const
Converts duration to bytes.
Definition audio.h:75
size_t frames_to_bytes(uint32_t frames) const
Converts frames to bytes.
Definition audio.h:53
uint8_t get_bits_per_sample() const
Definition audio.h:28
uint32_t frames_to_microseconds(uint32_t frames) const
Computes the duration, in microseconds, the given amount of frames represents.
Definition audio.cpp:25
uint32_t ms_to_samples(uint32_t ms) const
Converts duration to samples.
Definition audio.h:68
size_t samples_to_bytes(uint32_t samples) const
Converts samples to bytes.
Definition audio.h:58
uint32_t bytes_to_frames(size_t bytes) const
Convert bytes to frames.
Definition audio.h:43
uint8_t get_channels() const
Definition audio.h:29
uint32_t ms_to_frames(uint32_t ms) const
Converts duration to frames.
Definition audio.h:63
uint32_t frames_to_milliseconds_with_remainder(uint32_t *frames) const
Computes the duration, in milliseconds, the given amount of frames represents.
Definition audio.cpp:30
bool operator==(const AudioStreamInfo &rhs) const
Definition audio.cpp:39
uint32_t bytes_to_ms(size_t bytes) const
Convert bytes to duration in milliseconds.
Definition audio.h:36
uint32_t get_sample_rate() const
Definition audio.h:30
uint32_t bytes_to_samples(size_t bytes) const
Convert bytes to samples.
Definition audio.h:48
int32_t unpack_audio_sample_to_q31(const uint8_t *data, size_t bytes_per_sample)
Unpacks a quantized audio sample into a Q31 fixed-point number.
Definition audio.h:158
void scale_audio_samples(const int16_t *audio_samples, int16_t *output_buffer, int16_t scale_factor, size_t samples_to_scale)
Definition audio.cpp:123
int16_t int16_t scale_factor
Definition audio.h:151
void pack_q31_as_audio_sample(int32_t sample, uint8_t *data, size_t bytes_per_sample)
Packs a Q31 fixed-point number as an audio sample with the specified number of bytes per sample.
Definition audio.h:184
const char * audio_file_type_to_string(AudioFileType file_type)
Helper function to convert file type to a const char string.
Definition audio.cpp:44
ESPDEPRECATED("Use esp_audio_libs::gain::apply() (from <gain.h>) instead. Removed in 2026.12.0.", "2026.6.0") void scale_audio_samples(const int16_t *audio_samples
Scales Q15 fixed point audio samples.
int16_t * output_buffer
Definition audio.h:151
AudioFileType detect_audio_file_type(const char *content_type, const char *url)
Detect audio file type from a Content-Type header value and/or URL extension.
Definition audio.cpp:67
int16_t int16_t size_t samples_to_scale
Definition audio.h:152
static void uint32_t
const uint8_t * data
Definition audio.h:127
AudioFileType file_type
Definition audio.h:129