diff --git a/esphome/components/audio/audio.cpp b/esphome/components/audio/audio.cpp index 402e741059b..54406df2aaa 100644 --- a/esphome/components/audio/audio.cpp +++ b/esphome/components/audio/audio.cpp @@ -23,7 +23,8 @@ AudioStreamInfo::AudioStreamInfo(uint8_t bits_per_sample, uint8_t channels, uint } uint32_t AudioStreamInfo::frames_to_microseconds(uint32_t frames) const { - return (frames * 1000000 + (this->sample_rate_ >> 1)) / this->sample_rate_; + // In 64 bits: frames * 1000000 overflows 32 bits above 4294 frames, about 90 ms at 48 kHz. + return (static_cast(frames) * 1000000 + (this->sample_rate_ >> 1)) / this->sample_rate_; } uint32_t AudioStreamInfo::frames_to_milliseconds_with_remainder(uint32_t *total_frames) const { diff --git a/tests/components/audio/test_audio_stream_info.cpp b/tests/components/audio/test_audio_stream_info.cpp new file mode 100644 index 00000000000..e948bc32b2f --- /dev/null +++ b/tests/components/audio/test_audio_stream_info.cpp @@ -0,0 +1,20 @@ +#include + +#include "esphome/components/audio/audio.h" + +namespace esphome::audio::testing { + +TEST(AudioStreamInfo, FramesToMicroseconds) { + AudioStreamInfo info(16, 2, 48000); + EXPECT_EQ(info.frames_to_microseconds(48), 1000U); + EXPECT_EQ(info.frames_to_microseconds(1), 21U); // 20.83 us, rounded +} + +TEST(AudioStreamInfo, FramesToMicrosecondsAboveFourThousandFrames) { + // frames * 1000000 no longer fits 32 bits above 4294 frames, about 90 ms at 48 kHz. + AudioStreamInfo info(24, 2, 48000); + EXPECT_EQ(info.frames_to_microseconds(4800), 100000U); + EXPECT_EQ(info.frames_to_microseconds(48000), 1000000U); +} + +} // namespace esphome::audio::testing