13#define MINIAUDIO_IMPLEMENTATION
16#define MA_BUFFER_COUNT 10
17#define MA_BUFFER_SIZE 1200
18#define MA_START_COUNT 2
76 info.is_output =
false;
79 info.is_input =
false;
80 info.is_output =
true;
84 info.is_output =
true;
87 info.is_input =
false;
88 info.is_output =
false;
121 config_ma = ma_device_config_init(ma_device_type_playback);
123 config_ma = ma_device_config_init(ma_device_type_capture);
125 config_ma = ma_device_config_init(ma_device_type_duplex);
127 config_ma = ma_device_config_init(ma_device_type_loopback);
135 config_ma.playback.format = ma_format_u8;
138 config_ma.playback.format = ma_format_s16;
141 config_ma.playback.format = ma_format_s24;
144 config_ma.playback.format = ma_format_s32;
147 LOGE(
"Invalid format");
157 if (ma_device_start(&
device_ma) != MA_SUCCESS) {
182 size_t write(
const uint8_t* data,
size_t len)
override {
184 if (!data || len == 0) {
185 LOGW(
"Invalid write parameters: data=%p, len=%zu", data, len);
190 LOGW(
"Output buffer not initialized");
195 LOGW(
"Stream not active");
199 LOGD(
"write: %zu", len);
205 const int max_retries = 1000;
207 while (open > 0 && retry_count < max_retries) {
210 std::lock_guard<std::mutex> guard(
write_mtx);
224 if (retry_count >= max_retries) {
225 LOGE(
"Write timeout after %d retries, written %d of %zu bytes",
226 max_retries, written, len);
232 bool should_start_playing =
false;
237 if (current_buffer_size > 0) {
241 if (!
is_playing.load() && available_data >= threshold) {
242 should_start_playing =
true;
243 }
else if (
is_playing.load() && available_data == 0) {
245 LOGW(
"Buffer empty, pausing playback");
250 if (should_start_playing) {
251 LOGI(
"starting audio playback");
264 if (!data || len == 0) {
265 LOGW(
"Invalid read parameters: data=%p, len=%zu", data, len);
270 LOGW(
"Input buffer not initialized");
275 LOGW(
"Stream not active");
279 LOGD(
"read: %zu", len);
280 std::lock_guard<std::mutex> guard(
read_mtx);
287 LOGW(
"Cannot restart playback - stream not active");
293 LOGI(
"Manually restarting playback");
296 LOGW(
"Cannot restart playback - no data available");
322 std::lock_guard<std::mutex> guard(
write_mtx);
326 if (size <= 0 || size > 1024 * 1024) {
327 LOGE(
"Invalid buffer size: %d", size);
335 size_t total_size =
static_cast<size_t>(size) * buffer_count;
336 if (total_size > 100 * 1024 * 1024) {
337 LOGE(
"Buffer size too large: %zu bytes", total_size);
341 LOGI(
"setupBuffers: %d * %d = %zu bytes", size, buffer_count, total_size);
345 LOGE(
"Failed to resize output buffer");
351 LOGE(
"Failed to resize input buffer");
365 const void* pInput, ma_uint32 frameCount) {
373 LOGE(
"Invalid audio configuration in callback");
378 if (bytes <= 0 || bytes > 1024 * 1024) {
379 LOGE(
"Invalid byte count in callback: %d", bytes);
389 const int max_retries = 100;
391 while (open > 0 && retry_count < max_retries && self->
is_active.load()) {
394 std::unique_lock<std::mutex> guard(self->
read_mtx);
409 memset(pOutput, 0, bytes);
413 int consecutive_failures = 0;
416 while (open > 0 && self->
is_active.load()) {
419 std::lock_guard<std::mutex> guard(self->
write_mtx);
427 consecutive_failures++;
429 if (consecutive_failures >= max_failures &&
431 LOGW(
"Buffer underrun detected, stopping playback");
438 consecutive_failures = 0;
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define MA_DELAY
Definition MiniAudioStream.h:19
#define MA_BUFFER_SIZE
Definition MiniAudioStream.h:17
#define MA_BUFFER_COUNT
Definition MiniAudioStream.h:16
#define MA_START_COUNT
Definition MiniAudioStream.h:18
#define DEFAULT_BUFFER_SIZE
Definition avr.h:20
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26