Commit a9af26f7 authored by David Reid's avatar David Reid

Simplify the blocking read/write APIs.

parent 9bf923d3
...@@ -1552,8 +1552,8 @@ struct mal_context ...@@ -1552,8 +1552,8 @@ struct mal_context
mal_result (* onDeviceReinit )(mal_device* pDevice); mal_result (* onDeviceReinit )(mal_device* pDevice);
mal_result (* onDeviceStart )(mal_device* pDevice); mal_result (* onDeviceStart )(mal_device* pDevice);
mal_result (* onDeviceStop )(mal_device* pDevice); mal_result (* onDeviceStop )(mal_device* pDevice);
mal_result (* onDeviceWrite )(mal_device* pDevice, mal_uint32 pcmFrameCount, const void* pPCMFrames, mal_uint32* pPCMFramesWritten); /* Data is in internal device format. */ mal_result (* onDeviceWrite )(mal_device* pDevice, const void* pPCMFrames, mal_uint32 pcmFrameCount); /* Data is in internal device format. */
mal_result (* onDeviceRead )(mal_device* pDevice, mal_uint32 pcmFrameCount, void* pPCMFrames, mal_uint32* pPCMFramesRead); /* Data is in internal device format. */ mal_result (* onDeviceRead )(mal_device* pDevice, void* pPCMFrames, mal_uint32 pcmFrameCount); /* Data is in internal device format. */
mal_result (* onDeviceBreakMainLoop)(mal_device* pDevice); mal_result (* onDeviceBreakMainLoop)(mal_device* pDevice);
mal_result (* onDeviceMainLoop )(mal_device* pDevice); mal_result (* onDeviceMainLoop )(mal_device* pDevice);
...@@ -7010,7 +7010,7 @@ mal_result mal_device_reroute__wasapi(mal_device* pDevice) ...@@ -7010,7 +7010,7 @@ mal_result mal_device_reroute__wasapi(mal_device* pDevice)
return MAL_SUCCESS; return MAL_SUCCESS;
} }
mal_result mal_device_write__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCount, const void* pPCMFrames, mal_uint32* pPCMFramesWritten) mal_result mal_device_write__wasapi(mal_device* pDevice, const void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_result result = MAL_SUCCESS; mal_result result = MAL_SUCCESS;
mal_bool32 wasStartedOnEntry; mal_bool32 wasStartedOnEntry;
...@@ -7018,7 +7018,6 @@ mal_result mal_device_write__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCoun ...@@ -7018,7 +7018,6 @@ mal_result mal_device_write__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCoun
HRESULT hr; HRESULT hr;
DWORD waitResult; DWORD waitResult;
*pPCMFramesWritten = 0;
wasStartedOnEntry = pDevice->wasapi.isStarted; wasStartedOnEntry = pDevice->wasapi.isStarted;
/* Try to write every frame. */ /* Try to write every frame. */
...@@ -7113,11 +7112,10 @@ mal_result mal_device_write__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCoun ...@@ -7113,11 +7112,10 @@ mal_result mal_device_write__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCoun
pDevice->wasapi.deviceBufferFramesRemainingPlayback = pDevice->wasapi.deviceBufferFramesCapacityPlayback; pDevice->wasapi.deviceBufferFramesRemainingPlayback = pDevice->wasapi.deviceBufferFramesCapacityPlayback;
} }
*pPCMFramesWritten = totalPCMFramesWritten;
return result; return result;
} }
mal_result mal_device_read__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCount, void* pPCMFrames, mal_uint32* pPCMFramesRead) mal_result mal_device_read__wasapi(mal_device* pDevice, void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_result result = MAL_SUCCESS; mal_result result = MAL_SUCCESS;
mal_uint32 totalPCMFramesRead; mal_uint32 totalPCMFramesRead;
...@@ -7210,7 +7208,6 @@ mal_result mal_device_read__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCount ...@@ -7210,7 +7208,6 @@ mal_result mal_device_read__wasapi(mal_device* pDevice, mal_uint32 pcmFrameCount
pDevice->wasapi.deviceBufferFramesRemainingCapture = pDevice->wasapi.deviceBufferFramesCapacityCapture; pDevice->wasapi.deviceBufferFramesRemainingCapture = pDevice->wasapi.deviceBufferFramesCapacityCapture;
} }
*pPCMFramesRead = totalPCMFramesRead;
return result; return result;
} }
...@@ -8398,7 +8395,7 @@ mal_result mal_device_map_next_playback_buffer__dsound(mal_device* pDevice) ...@@ -8398,7 +8395,7 @@ mal_result mal_device_map_next_playback_buffer__dsound(mal_device* pDevice)
return MAL_SUCCESS; return MAL_SUCCESS;
} }
mal_result mal_device_write__dsound(mal_device* pDevice, mal_uint32 pcmFrameCount, const void* pPCMFrames, mal_uint32* pPCMFramesWritten) mal_result mal_device_write__dsound(mal_device* pDevice, const void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_result result = MAL_SUCCESS; mal_result result = MAL_SUCCESS;
mal_bool32 wasStartedOnEntry; mal_bool32 wasStartedOnEntry;
...@@ -8408,7 +8405,6 @@ mal_result mal_device_write__dsound(mal_device* pDevice, mal_uint32 pcmFrameCoun ...@@ -8408,7 +8405,6 @@ mal_result mal_device_write__dsound(mal_device* pDevice, mal_uint32 pcmFrameCoun
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
mal_assert(pPCMFrames != NULL); mal_assert(pPCMFrames != NULL);
*pPCMFramesWritten = 0;
wasStartedOnEntry = pDevice->dsound.isStarted; wasStartedOnEntry = pDevice->dsound.isStarted;
/* If the device is not started we do not have a mapped buffer, we'll need to map the first period so we can fill it. */ /* If the device is not started we do not have a mapped buffer, we'll need to map the first period so we can fill it. */
...@@ -8510,7 +8506,6 @@ mal_result mal_device_write__dsound(mal_device* pDevice, mal_uint32 pcmFrameCoun ...@@ -8510,7 +8506,6 @@ mal_result mal_device_write__dsound(mal_device* pDevice, mal_uint32 pcmFrameCoun
} }
} }
*pPCMFramesWritten = totalPCMFramesWritten;
return result; return result;
} }
...@@ -8538,7 +8533,7 @@ mal_result mal_device_map_next_capture_buffer__dsound(mal_device* pDevice) ...@@ -8538,7 +8533,7 @@ mal_result mal_device_map_next_capture_buffer__dsound(mal_device* pDevice)
return MAL_SUCCESS; return MAL_SUCCESS;
} }
mal_result mal_device_read__dsound(mal_device* pDevice, mal_uint32 pcmFrameCount, void* pPCMFrames, mal_uint32* pPCMFramesRead) mal_result mal_device_read__dsound(mal_device* pDevice, void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_result result = MAL_SUCCESS; mal_result result = MAL_SUCCESS;
mal_uint32 totalPCMFramesRead; mal_uint32 totalPCMFramesRead;
...@@ -8630,7 +8625,6 @@ mal_result mal_device_read__dsound(mal_device* pDevice, mal_uint32 pcmFrameCount ...@@ -8630,7 +8625,6 @@ mal_result mal_device_read__dsound(mal_device* pDevice, mal_uint32 pcmFrameCount
} }
} }
*pPCMFramesRead = totalPCMFramesRead;
return result; return result;
} }
...@@ -9345,7 +9339,7 @@ mal_result mal_device_stop__winmm(mal_device* pDevice) ...@@ -9345,7 +9339,7 @@ mal_result mal_device_stop__winmm(mal_device* pDevice)
return MAL_SUCCESS; return MAL_SUCCESS;
} }
mal_result mal_device_write__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount, const void* pPCMFrames, mal_uint32* pPCMFramesWritten) mal_result mal_device_write__winmm(mal_device* pDevice, const void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_result result = MAL_SUCCESS; mal_result result = MAL_SUCCESS;
MMRESULT resultMM; MMRESULT resultMM;
...@@ -9355,8 +9349,6 @@ mal_result mal_device_write__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount ...@@ -9355,8 +9349,6 @@ mal_result mal_device_write__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
mal_assert(pPCMFrames != NULL); mal_assert(pPCMFrames != NULL);
*pPCMFramesWritten = 0;
/* Keep processing as much data as possible. */ /* Keep processing as much data as possible. */
totalPCMFramesWritten = 0; totalPCMFramesWritten = 0;
while (totalPCMFramesWritten < pcmFrameCount) { while (totalPCMFramesWritten < pcmFrameCount) {
...@@ -9427,11 +9419,10 @@ mal_result mal_device_write__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount ...@@ -9427,11 +9419,10 @@ mal_result mal_device_write__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount
} }
} }
*pPCMFramesWritten = totalPCMFramesWritten;
return result; return result;
} }
mal_result mal_device_read__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount, void* pPCMFrames, mal_uint32* pPCMFramesRead) mal_result mal_device_read__winmm(mal_device* pDevice, void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
mal_assert(pPCMFrames != NULL); mal_assert(pPCMFrames != NULL);
...@@ -9441,8 +9432,6 @@ mal_result mal_device_read__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount, ...@@ -9441,8 +9432,6 @@ mal_result mal_device_read__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount,
mal_uint32 totalPCMFramesRead; mal_uint32 totalPCMFramesRead;
WAVEHDR* pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDR; WAVEHDR* pWAVEHDR = (WAVEHDR*)pDevice->winmm.pWAVEHDR;
*pPCMFramesRead = 0;
/* We want to start the device immediately. */ /* We want to start the device immediately. */
if (!pDevice->winmm.isStarted) { if (!pDevice->winmm.isStarted) {
/* Make sure the event is reset to a non-signaled state to ensure we don't prematurely return from WaitForSingleObject(). */ /* Make sure the event is reset to a non-signaled state to ensure we don't prematurely return from WaitForSingleObject(). */
...@@ -9534,7 +9523,6 @@ mal_result mal_device_read__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount, ...@@ -9534,7 +9523,6 @@ mal_result mal_device_read__winmm(mal_device* pDevice, mal_uint32 pcmFrameCount,
} }
} }
*pPCMFramesRead = totalPCMFramesRead;
return result; return result;
} }
...@@ -19899,23 +19887,21 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData) ...@@ -19899,23 +19887,21 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
mal_uint32 bufferSizeInFrames = sizeof(buffer) / mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels); mal_uint32 bufferSizeInFrames = sizeof(buffer) / mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels);
while (totalFramesProcessed < periodSizeInFrames) { while (totalFramesProcessed < periodSizeInFrames) {
mal_uint32 framesProcessed;
mal_uint32 framesRemaining = periodSizeInFrames - totalFramesProcessed; mal_uint32 framesRemaining = periodSizeInFrames - totalFramesProcessed;
mal_uint32 framesToProcess = framesRemaining; mal_uint32 framesToProcess = framesRemaining;
if (framesToProcess > bufferSizeInFrames) { if (framesToProcess > bufferSizeInFrames) {
framesToProcess = bufferSizeInFrames; framesToProcess = bufferSizeInFrames;
} }
framesProcessed = 0;
if (pDevice->type == mal_device_type_playback) { if (pDevice->type == mal_device_type_playback) {
mal_device__read_frames_from_client(pDevice, framesToProcess, buffer); mal_device__read_frames_from_client(pDevice, framesToProcess, buffer);
result = pDevice->pContext->onDeviceWrite(pDevice, framesToProcess, buffer, &framesProcessed); result = pDevice->pContext->onDeviceWrite(pDevice, buffer, framesToProcess);
} else { } else {
result = pDevice->pContext->onDeviceRead(pDevice, framesToProcess, buffer, &framesProcessed); result = pDevice->pContext->onDeviceRead(pDevice, buffer, framesToProcess);
mal_device__send_frames_to_client(pDevice, framesProcessed, buffer); mal_device__send_frames_to_client(pDevice, framesToProcess, buffer);
} }
totalFramesProcessed += framesProcessed; totalFramesProcessed += framesToProcess;
} }
/* Get out of the loop if read()/write() returned an error. It probably means the device has been stopped. */ /* Get out of the loop if read()/write() returned an error. It probably means the device has been stopped. */
...@@ -20748,15 +20734,11 @@ void mal_device_uninit(mal_device* pDevice) ...@@ -20748,15 +20734,11 @@ void mal_device_uninit(mal_device* pDevice)
/* /*
Writes PCM frames to the device. Writes PCM frames to the device.
*/ */
mal_result mal_device_write(mal_device* pDevice, mal_uint32 pcmFrameCount, const void* pPCMFrames, mal_uint32* pPCMFramesWritten) mal_result mal_device_write(mal_device* pDevice, const void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_result result; mal_result result;
mal_uint32 totalPCMFramesWritten = 0; mal_uint32 totalPCMFramesWritten = 0;
if (pPCMFramesWritten != NULL) {
*pPCMFramesWritten = 0; /* Safety. */
}
if (mal_device__is_async(pDevice)) { if (mal_device__is_async(pDevice)) {
return MAL_INVALID_ARGS; return MAL_INVALID_ARGS;
} }
...@@ -20774,7 +20756,7 @@ mal_result mal_device_write(mal_device* pDevice, mal_uint32 pcmFrameCount, const ...@@ -20774,7 +20756,7 @@ mal_result mal_device_write(mal_device* pDevice, mal_uint32 pcmFrameCount, const
/* If it's a passthrough we can call the backend directly, otherwise we need a data conversion into an intermediary buffer. */ /* If it's a passthrough we can call the backend directly, otherwise we need a data conversion into an intermediary buffer. */
if (pDevice->dsp.isPassthrough) { if (pDevice->dsp.isPassthrough) {
/* Fast path. Write directly to the device. */ /* Fast path. Write directly to the device. */
result = pDevice->pContext->onDeviceWrite(pDevice, pcmFrameCount, pPCMFrames, &totalPCMFramesWritten); result = pDevice->pContext->onDeviceWrite(pDevice, pPCMFrames, pcmFrameCount);
} else { } else {
/* Slow path. Perform a data conversion. */ /* Slow path. Perform a data conversion. */
...@@ -20794,9 +20776,8 @@ mal_result mal_device_write(mal_device* pDevice, mal_uint32 pcmFrameCount, const ...@@ -20794,9 +20776,8 @@ mal_result mal_device_write(mal_device* pDevice, mal_uint32 pcmFrameCount, const
mal_pcm_convert(buffer, pDevice->internalFormat, mal_offset_ptr(pPCMFrames, totalPCMFramesWritten * mal_get_bytes_per_frame(pDevice->format, pDevice->channels)), pDevice->format, framesToProcess*pDevice->channels, mal_dither_mode_none); mal_pcm_convert(buffer, pDevice->internalFormat, mal_offset_ptr(pPCMFrames, totalPCMFramesWritten * mal_get_bytes_per_frame(pDevice->format, pDevice->channels)), pDevice->format, framesToProcess*pDevice->channels, mal_dither_mode_none);
mal_uint32 framesProcessed = 0; result = pDevice->pContext->onDeviceWrite(pDevice, buffer, framesToProcess);
result = pDevice->pContext->onDeviceWrite(pDevice, framesToProcess, buffer, &framesProcessed); totalPCMFramesWritten += framesToProcess;
totalPCMFramesWritten += framesProcessed;
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
break; break;
...@@ -20804,26 +20785,17 @@ mal_result mal_device_write(mal_device* pDevice, mal_uint32 pcmFrameCount, const ...@@ -20804,26 +20785,17 @@ mal_result mal_device_write(mal_device* pDevice, mal_uint32 pcmFrameCount, const
} }
} }
if (pPCMFramesWritten != NULL) {
*pPCMFramesWritten = totalPCMFramesWritten;
}
return result; return result;
} }
/* /*
Reads PCM frames from the device. Reads PCM frames from the device.
*/ */
mal_result mal_device_read(mal_device* pDevice, mal_uint32 pcmFrameCount, void* pPCMFrames, mal_uint32* pPCMFramesRead) mal_result mal_device_read(mal_device* pDevice, void* pPCMFrames, mal_uint32 pcmFrameCount)
{ {
mal_result result; mal_result result;
mal_uint32 totalPCMFramesRead = 0; mal_uint32 totalPCMFramesRead = 0;
if (pPCMFramesRead != NULL) {
*pPCMFramesRead = 0; /* Safety. */
}
if (pDevice == NULL || pPCMFrames == NULL) { if (pDevice == NULL || pPCMFrames == NULL) {
return MAL_INVALID_ARGS; return MAL_INVALID_ARGS;
} }
...@@ -20841,7 +20813,7 @@ mal_result mal_device_read(mal_device* pDevice, mal_uint32 pcmFrameCount, void* ...@@ -20841,7 +20813,7 @@ mal_result mal_device_read(mal_device* pDevice, mal_uint32 pcmFrameCount, void*
/* If it's a passthrough we can call the backend directly, otherwise we need a data conversion into an intermediary buffer. */ /* If it's a passthrough we can call the backend directly, otherwise we need a data conversion into an intermediary buffer. */
if (pDevice->dsp.isPassthrough) { if (pDevice->dsp.isPassthrough) {
/* Fast path. Write directly to the device. */ /* Fast path. Write directly to the device. */
result = pDevice->pContext->onDeviceRead(pDevice, pcmFrameCount, pPCMFrames, &totalPCMFramesRead); result = pDevice->pContext->onDeviceRead(pDevice, pPCMFrames, pcmFrameCount);
} else { } else {
/* Slow path. Perform a data conversion. */ /* Slow path. Perform a data conversion. */
...@@ -20859,23 +20831,17 @@ mal_result mal_device_read(mal_device* pDevice, mal_uint32 pcmFrameCount, void* ...@@ -20859,23 +20831,17 @@ mal_result mal_device_read(mal_device* pDevice, mal_uint32 pcmFrameCount, void*
framesToProcess = bufferSizeInFrames; framesToProcess = bufferSizeInFrames;
} }
mal_uint32 framesProcessed = 0; result = pDevice->pContext->onDeviceRead(pDevice, buffer, framesToProcess);
result = pDevice->pContext->onDeviceRead(pDevice, framesToProcess, buffer, &framesProcessed);
mal_pcm_convert(mal_offset_ptr(pPCMFrames, totalPCMFramesRead * mal_get_bytes_per_frame(pDevice->format, pDevice->channels)), pDevice->format, buffer, pDevice->internalFormat, framesToProcess*pDevice->channels, mal_dither_mode_none); mal_pcm_convert(mal_offset_ptr(pPCMFrames, totalPCMFramesRead * mal_get_bytes_per_frame(pDevice->format, pDevice->channels)), pDevice->format, buffer, pDevice->internalFormat, framesToProcess*pDevice->channels, mal_dither_mode_none);
totalPCMFramesRead += framesProcessed; totalPCMFramesRead += framesToProcess;
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
break; break;
} }
} }
} }
if (pPCMFramesRead != NULL) {
*pPCMFramesRead = totalPCMFramesRead;
}
return result; return result;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment