Discontinuity glitches on Realtek (and any exclusive mic)
Environment:
- OS: Windows 11
- miniaudio 0.11.24
- Backend: WASAPI (Exclusive Mode, Capture)
- Format: Tested on Realtek & M-Audio duo interface (2-channel, 48kHz, s16)
Description
When running a capture device in exclusive mode (ma_share_mode_exclusive), the captured audio runs ~1.44x faster than wall-clock time, and individual periods (e.g., 30ms / 1440 frames) appear duplicated in the captured buffer.
In addition, AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY is triggered on almost every packet (~50/sec) during pure capture.
Shared mode capture on the same hardware and period size works as expected with no duplication or glitches.
Suspected Root Causes
Double
GetBufferper event inma_device_read__wasapi(): In WASAPI event-driven exclusive mode, the event fires once per ready packet. Insidema_device_read__wasapi(), the inner loop callsGetBuffer->ReleaseBufferand immediately attempts anotherGetBufferbefore waiting on the event again. This appears to consume the subsequent packet prematurely, resulting in 2 packets read per 1 wait event and duplicating audio frames.Discontinuity handling missing for pure capture: The exclusive-mode recovery path for buffer discontinuities seems to only be applied to duplex configurations, leaving pure capture streams continuously flagging
DATA_DISCONTINUITYonce an overrun occurs.
Minimal Reproducible Example
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
#include <stdio.h>
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) {
// Inspect pInput: identical frame blocks repeat every period.
(void)pOutput;
(void)pDevice;
(void)frameCount;
}
int main() {
ma_device_config config = ma_device_config_init(ma_device_type_capture);
config.capture.shareMode = ma_share_mode_exclusive;
config.capture.format = ma_format_unknown; // Native format
config.dataCallback = data_callback;
// e.g. 10ms - 30ms periods
config.periodSizeInMilliseconds = 10;
ma_device device;
if (ma_device_init(NULL, &config, &device) != MA_SUCCESS) {
printf("Failed to init capture device.\n");
return -1;
}
ma_device_start(&device);
printf("Capturing... Press Enter to stop.\n");
getchar();
ma_device_uninit(&device);
return 0;
}Source: mackron/miniaudio