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;
118 config_ma = ma_device_config_init(ma_device_type_playback);
120 config_ma = ma_device_config_init(ma_device_type_capture);
122 config_ma = ma_device_config_init(ma_device_type_duplex);
124 config_ma = ma_device_config_init(ma_device_type_loopback);
132 format = ma_format_u8;
135 format = ma_format_s16;
138 format = ma_format_s24;
141 format = ma_format_s32;
144 LOGE(
"Invalid format");
161 if (ma_device_start(&
device_ma) != MA_SUCCESS) {
183 if (!
is_active.exchange(
false))
return false;
196 if (!data || len == 0) {
197 LOGW(
"Invalid write parameters: data=%p, len=%zu", data, len);
202 LOGW(
"Output buffer not initialized");
207 LOGW(
"Stream not active");
211 LOGD(
"write: %zu", len);
217 const int max_retries = 1000;
219 while (open > 0 && retry_count < max_retries) {
222 std::lock_guard<std::mutex> guard(
write_mtx);
236 if (retry_count >= max_retries) {
237 LOGE(
"Write timeout after %d retries, written %d of %zu bytes",
238 max_retries, written, len);
244 bool should_start_playing =
false;
249 if (current_buffer_size > 0) {
253 if (!
is_playing.load() && available_data >= threshold) {
254 should_start_playing =
true;
255 }
else if (
is_playing.load() && available_data == 0) {
257 LOGW(
"Buffer empty, pausing playback");
262 if (should_start_playing) {
263 LOGI(
"starting audio playback");
276 if (!data || len == 0) {
277 LOGW(
"Invalid read parameters: data=%p, len=%zu", data, len);
282 LOGW(
"Input buffer not initialized");
287 LOGW(
"Stream not active");
291 LOGD(
"read: %zu", len);
292 std::lock_guard<std::mutex> guard(
read_mtx);
299 LOGW(
"Cannot restart playback - stream not active");
305 LOGI(
"Manually restarting playback");
308 LOGW(
"Cannot restart playback - no data available");
334 std::lock_guard<std::mutex> guard(
write_mtx);
338 if (size <= 0 || size > 1024 * 1024) {
339 LOGE(
"Invalid buffer size: %d", size);
347 size_t total_size =
static_cast<size_t>(size) * buffer_count;
348 if (total_size > 100 * 1024 * 1024) {
349 LOGE(
"Buffer size too large: %zu bytes", total_size);
353 LOGI(
"setupBuffers: %d * %d = %zu bytes", size, buffer_count, total_size);
357 LOGE(
"Failed to resize output buffer");
363 LOGE(
"Failed to resize input buffer");
377 const void* pInput, ma_uint32 frameCount) {
385 LOGE(
"Invalid audio configuration in callback");
390 if (bytes <= 0 || bytes > 1024 * 1024) {
391 LOGE(
"Invalid byte count in callback: %d", bytes);
401 const int max_retries = 100;
403 while (open > 0 && retry_count < max_retries && self->
is_active.load()) {
406 std::unique_lock<std::mutex> guard(self->
read_mtx);
421 memset(pOutput, 0, bytes);
425 int consecutive_failures = 0;
428 while (open > 0 && self->
is_active.load()) {
431 std::lock_guard<std::mutex> guard(self->
write_mtx);
439 consecutive_failures++;
441 if (consecutive_failures >= max_failures &&
443 LOGW(
"Buffer underrun detected, stopping playback");
450 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