From 957de48d80cbee7e3ba7d392925f7fa19453bfc9 Mon Sep 17 00:00:00 2001 From: David Reid Date: Wed, 27 Feb 2019 18:18:01 +1000 Subject: [PATCH] Another potential fix for some full-duplex glitching. This change makes it so reading and writing is done on the smaller of the period sizes between capture and playback devices. --- mini_al.h | 21 +++++++++++++++++---- tests/mal_duplex.c | 15 ++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/mini_al.h b/mini_al.h index aa171651..82cb7c92 100644 --- a/mini_al.h +++ b/mini_al.h @@ -9216,8 +9216,9 @@ mal_result mal_device_map_next_playback_buffer__dsound(mal_device* pDevice) { DWORD periodSizeInBytes = (pDevice->playback.internalBufferSizeInFrames / pDevice->playback.internalPeriods) * mal_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels); DWORD lockOffset = (pDevice->dsound.iNextPeriodPlayback * periodSizeInBytes); + DWORD lockSizeInBytes = periodSizeInBytes; DWORD mappedSizeInBytes; - HRESULT hr = mal_IDirectSoundBuffer_Lock((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, lockOffset, periodSizeInBytes, &pDevice->dsound.pMappedBufferPlayback, &mappedSizeInBytes, NULL, NULL, 0); + HRESULT hr = mal_IDirectSoundBuffer_Lock((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, lockOffset, lockSizeInBytes, &pDevice->dsound.pMappedBufferPlayback, &mappedSizeInBytes, NULL, NULL, 0); if (FAILED(hr)) { return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from playback device in preparation for writing to the device.", MAL_FAILED_TO_MAP_DEVICE_BUFFER); } @@ -9225,6 +9226,8 @@ mal_result mal_device_map_next_playback_buffer__dsound(mal_device* pDevice) pDevice->dsound.mappedBufferFramesCapacityPlayback = (mal_uint32)mappedSizeInBytes / mal_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels); pDevice->dsound.mappedBufferFramesRemainingPlayback = (mal_uint32)mappedSizeInBytes / mal_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels); + //printf("TRACE 1: Playback: iNextPeriod=%d, internalBufferSizeInFrames=%d, periodSizeInBytes=%d, mappedSizeInBytes=%d\n", pDevice->dsound.iNextPeriodPlayback, pDevice->playback.internalBufferSizeInFrames, periodSizeInBytes, mappedSizeInBytes); + return MAL_SUCCESS; } @@ -9346,8 +9349,9 @@ mal_result mal_device_map_next_capture_buffer__dsound(mal_device* pDevice) { DWORD periodSizeInBytes = (pDevice->capture.internalBufferSizeInFrames / pDevice->capture.internalPeriods) * mal_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels); DWORD lockOffset = (pDevice->dsound.iNextPeriodCapture * periodSizeInBytes); + DWORD lockSizeInBytes = periodSizeInBytes; DWORD mappedSizeInBytes; - HRESULT hr = mal_IDirectSoundCaptureBuffer_Lock((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, lockOffset, periodSizeInBytes, &pDevice->dsound.pMappedBufferCapture, &mappedSizeInBytes, NULL, NULL, 0); + HRESULT hr = mal_IDirectSoundCaptureBuffer_Lock((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, lockOffset, lockSizeInBytes, &pDevice->dsound.pMappedBufferCapture, &mappedSizeInBytes, NULL, NULL, 0); if (FAILED(hr)) { return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] Failed to map buffer from capture device in preparation for writing to the device.", MAL_FAILED_TO_MAP_DEVICE_BUFFER); } @@ -9355,6 +9359,8 @@ mal_result mal_device_map_next_capture_buffer__dsound(mal_device* pDevice) pDevice->dsound.mappedBufferFramesCapacityCapture = (mal_uint32)mappedSizeInBytes / mal_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels); pDevice->dsound.mappedBufferFramesRemainingCapture = (mal_uint32)mappedSizeInBytes / mal_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels); + //printf("TRACE 1: Capture: internalBufferSizeInFrames=%d, periodSizeInBytes=%d, mappedSizeInBytes=%d\n", pDevice->capture.internalBufferSizeInFrames, periodSizeInBytes, mappedSizeInBytes); + return MAL_SUCCESS; } @@ -21805,12 +21811,19 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData) ); mal_uint32 periodSizeInFrames; - if (pDevice->type == mal_device_type_capture || pDevice->type == mal_device_type_duplex) { + if (pDevice->type == mal_device_type_capture) { mal_assert(pDevice->capture.internalBufferSizeInFrames >= pDevice->capture.internalPeriods); periodSizeInFrames = pDevice->capture.internalBufferSizeInFrames / pDevice->capture.internalPeriods; - } else { + } else if (pDevice->type == mal_device_type_playback) { mal_assert(pDevice->playback.internalBufferSizeInFrames >= pDevice->playback.internalPeriods); periodSizeInFrames = pDevice->playback.internalBufferSizeInFrames / pDevice->playback.internalPeriods; + } else { + mal_assert(pDevice->capture.internalBufferSizeInFrames >= pDevice->capture.internalPeriods); + mal_assert(pDevice->playback.internalBufferSizeInFrames >= pDevice->playback.internalPeriods); + periodSizeInFrames = mal_min( + pDevice->capture.internalBufferSizeInFrames / pDevice->capture.internalPeriods, + pDevice->playback.internalBufferSizeInFrames / pDevice->playback.internalPeriods + ); } diff --git a/tests/mal_duplex.c b/tests/mal_duplex.c index 3127b00b..045d877c 100644 --- a/tests/mal_duplex.c +++ b/tests/mal_duplex.c @@ -31,7 +31,7 @@ void data_callback(mal_device* pDevice, void* pOutput, const void* pInput, mal_u /* In this test the format and channel count are the same for both input and output which means we can just memcpy(). */ mal_copy_memory(pOutput, pInput, frameCount * mal_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels)); -#if 0 +#if 1 /* Also write to a wav file for debugging. */ drwav* pWav = (drwav*)pDevice->pUserData; mal_assert(pWav != NULL); @@ -44,7 +44,7 @@ int main(int argc, char** argv) { mal_result result; -#if 0 +#if 1 drwav_data_format wavFormat; wavFormat.container = drwav_container_riff; wavFormat.format = DR_WAVE_FORMAT_PCM; @@ -60,7 +60,7 @@ int main(int argc, char** argv) #endif - mal_backend backend = mal_backend_wasapi; + mal_backend backend = mal_backend_dsound; mal_context_config contextConfig = mal_context_config_init(); contextConfig.logCallback = log_callback; @@ -81,11 +81,12 @@ int main(int argc, char** argv) deviceConfig.playback.channels = 2; deviceConfig.playback.shareMode = mal_share_mode_shared; deviceConfig.sampleRate = 44100; - deviceConfig.bufferSizeInMilliseconds = 100; - deviceConfig.periods = 2; + //deviceConfig.bufferSizeInMilliseconds = 60; + deviceConfig.bufferSizeInFrames = 4096; + //deviceConfig.periods = 3; deviceConfig.dataCallback = data_callback; deviceConfig.stopCallback = stop_callback; - deviceConfig.pUserData = NULL/*&wav*/; + deviceConfig.pUserData = &wav; mal_device device; result = mal_device_init(&context, &deviceConfig, &device); @@ -107,7 +108,7 @@ int main(int argc, char** argv) #endif mal_device_uninit(&device); - /*drwav_uninit(&wav);*/ + drwav_uninit(&wav); (void)argc; (void)argv;