diff --git a/miniaudio.h b/miniaudio.h index 547b1227..4ae36836 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -37606,6 +37606,41 @@ static void ma_device_uninit__sndio(ma_device* pDevice) ma_free(pDeviceStateSndio, ma_device_get_allocation_callbacks(pDevice)); } +static void ma_device_prime_playback_buffer__sndio(ma_device* pDevice) +{ + ma_device_state_sndio* pDeviceStateSndio = ma_device_get_backend_state__sndio(pDevice); + ma_context_state_sndio* pContextStateSndio = ma_context_get_backend_state__sndio(ma_device_get_context(pDevice)); + ma_device_type deviceType = ma_device_get_type(pDevice); + ma_uint8 buffer[4096]; + ma_uint32 bpf; + ma_uint32 framesToWrite; + ma_uint32 framesWritten; + + if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) { + bpf = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels); + framesToWrite = pDevice->playback.internalPeriodSizeInFrames * pDevice->playback.internalPeriods; + framesWritten = 0; + + MA_ZERO_MEMORY(buffer, sizeof(buffer)); + + while (framesWritten < framesToWrite) { + ma_uint32 framesToWriteThisIteration = sizeof(buffer) / bpf; + ma_uint32 framesRemaining = framesToWrite - framesWritten; + if (framesToWriteThisIteration > framesRemaining) { + framesToWriteThisIteration = framesRemaining; + } + + /* Just a guard to ensure we don't get stuck in a loop. Should never happen in practice (would require a massive channel count). */ + if (framesToWriteThisIteration == 0) { + break; + } + + pContextStateSndio->sio_write(pDeviceStateSndio->playback.handle, buffer, framesToWriteThisIteration * bpf); + framesWritten += framesToWriteThisIteration; + } + } +} + static ma_result ma_device_start__sndio(ma_device* pDevice) { ma_device_state_sndio* pDeviceStateSndio = ma_device_get_backend_state__sndio(pDevice); @@ -37618,6 +37653,12 @@ static ma_result ma_device_start__sndio(ma_device* pDevice) if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) { pContextStateSndio->sio_start(pDeviceStateSndio->playback.handle); /* <-- Doesn't actually start until data is written. */ + + /* + Prime the playback buffer with silence. This mainly for duplex mode which needs + a buffer of silence to give the capture side time to produce audio. + */ + ma_device_prime_playback_buffer__sndio(pDevice); } return MA_SUCCESS;