Commit c47e9d49 authored by David Reid's avatar David Reid

Work on fixes to device stopping.

parent 9038abef
...@@ -2069,6 +2069,7 @@ MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_device ...@@ -2069,6 +2069,7 @@ MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_device
mal_uint32 lastProcessedFrame; // This is circular. mal_uint32 lastProcessedFrame; // This is circular.
mal_bool32 breakFromMainLoop; mal_bool32 breakFromMainLoop;
mal_uint8* pBuffer; // This is malloc()'d and is used as the destination for reading from the client. Typed as mal_uint8 for easy offsetting. mal_uint8* pBuffer; // This is malloc()'d and is used as the destination for reading from the client. Typed as mal_uint8 for easy offsetting.
mal_bool32 hasStarted : 1; /* Keeps track of whether or not the device has been started at least once. */
} null_device; } null_device;
#endif #endif
}; };
...@@ -4120,7 +4121,6 @@ mal_bool32 mal_event_wait__posix(mal_event* pEvent) ...@@ -4120,7 +4121,6 @@ mal_bool32 mal_event_wait__posix(mal_event* pEvent)
while (pEvent->posix.value == 0) { while (pEvent->posix.value == 0) {
((mal_pthread_cond_wait_proc)pEvent->pContext->posix.pthread_cond_wait)(&pEvent->posix.condition, &pEvent->posix.mutex); ((mal_pthread_cond_wait_proc)pEvent->pContext->posix.pthread_cond_wait)(&pEvent->posix.condition, &pEvent->posix.mutex);
} }
pEvent->posix.value = 0; // Auto-reset. pEvent->posix.value = 0; // Auto-reset.
} }
((mal_pthread_mutex_unlock_proc)pEvent->pContext->posix.pthread_mutex_unlock)(&pEvent->posix.mutex); ((mal_pthread_mutex_unlock_proc)pEvent->pContext->posix.pthread_mutex_unlock)(&pEvent->posix.mutex);
...@@ -4749,8 +4749,11 @@ mal_result mal_device_start__null(mal_device* pDevice) ...@@ -4749,8 +4749,11 @@ mal_result mal_device_start__null(mal_device* pDevice)
{ {
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
mal_timer_init(&pDevice->null_device.timer); if (!pDevice->null_device.hasStarted) {
pDevice->null_device.lastProcessedFrame = 0; mal_timer_init(&pDevice->null_device.timer);
pDevice->null_device.lastProcessedFrame = 0;
pDevice->null_device.hasStarted = MAL_TRUE;
}
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -4854,7 +4857,7 @@ mal_result mal_device_main_loop__null(mal_device* pDevice) ...@@ -4854,7 +4857,7 @@ mal_result mal_device_main_loop__null(mal_device* pDevice)
// If it's a playback device, don't bother grabbing more data if the device is being stopped. // If it's a playback device, don't bother grabbing more data if the device is being stopped.
if (pDevice->null_device.breakFromMainLoop && pDevice->type == mal_device_type_playback) { if (pDevice->null_device.breakFromMainLoop && pDevice->type == mal_device_type_playback) {
return MAL_FALSE; return MAL_ERROR;
} }
if (framesAvailable + pDevice->null_device.lastProcessedFrame > pDevice->bufferSizeInFrames) { if (framesAvailable + pDevice->null_device.lastProcessedFrame > pDevice->bufferSizeInFrames) {
...@@ -4867,7 +4870,7 @@ mal_result mal_device_main_loop__null(mal_device* pDevice) ...@@ -4867,7 +4870,7 @@ mal_result mal_device_main_loop__null(mal_device* pDevice)
if (pDevice->type == mal_device_type_playback) { if (pDevice->type == mal_device_type_playback) {
if (pDevice->null_device.breakFromMainLoop) { if (pDevice->null_device.breakFromMainLoop) {
return MAL_FALSE; return MAL_ERROR;
} }
mal_device__read_frames_from_client(pDevice, framesAvailable, pDevice->null_device.pBuffer + lockOffset); mal_device__read_frames_from_client(pDevice, framesAvailable, pDevice->null_device.pBuffer + lockOffset);
...@@ -8239,25 +8242,8 @@ mal_result mal_device_start__dsound(mal_device* pDevice) ...@@ -8239,25 +8242,8 @@ mal_result mal_device_start__dsound(mal_device* pDevice)
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
if (pDevice->type == mal_device_type_playback) { if (pDevice->type == mal_device_type_playback) {
// Before playing anything we need to grab an initial group of samples from the client. if (FAILED(mal_IDirectSoundBuffer_Play((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, 0, MAL_DSBPLAY_LOOPING))) {
mal_uint32 framesToRead = pDevice->bufferSizeInFrames / pDevice->periods; return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Play() failed.", MAL_FAILED_TO_START_BACKEND_DEVICE);
mal_uint32 desiredLockSize = framesToRead * pDevice->channels * mal_get_bytes_per_sample(pDevice->format);
void* pLockPtr;
DWORD actualLockSize;
void* pLockPtr2;
DWORD actualLockSize2;
if (SUCCEEDED(mal_IDirectSoundBuffer_Lock((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, desiredLockSize, &pLockPtr, &actualLockSize, &pLockPtr2, &actualLockSize2, 0))) {
framesToRead = actualLockSize / mal_get_bytes_per_sample(pDevice->format) / pDevice->channels;
mal_device__read_frames_from_client(pDevice, framesToRead, pLockPtr);
mal_IDirectSoundBuffer_Unlock((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, pLockPtr, actualLockSize, pLockPtr2, actualLockSize2);
pDevice->dsound.lastProcessedFrame = framesToRead;
if (FAILED(mal_IDirectSoundBuffer_Play((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, 0, MAL_DSBPLAY_LOOPING))) {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Play() failed.", MAL_FAILED_TO_START_BACKEND_DEVICE);
}
} else {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Lock() failed.", MAL_FAILED_TO_MAP_DEVICE_BUFFER);
} }
} else { } else {
if (FAILED(mal_IDirectSoundCaptureBuffer_Start((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, MAL_DSCBSTART_LOOPING))) { if (FAILED(mal_IDirectSoundCaptureBuffer_Start((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, MAL_DSCBSTART_LOOPING))) {
...@@ -8276,8 +8262,6 @@ mal_result mal_device_stop__dsound(mal_device* pDevice) ...@@ -8276,8 +8262,6 @@ mal_result mal_device_stop__dsound(mal_device* pDevice)
if (FAILED(mal_IDirectSoundBuffer_Stop((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer))) { if (FAILED(mal_IDirectSoundBuffer_Stop((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer))) {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Stop() failed.", MAL_FAILED_TO_STOP_BACKEND_DEVICE); return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Stop() failed.", MAL_FAILED_TO_STOP_BACKEND_DEVICE);
} }
mal_IDirectSoundBuffer_SetCurrentPosition((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0);
} else { } else {
if (FAILED(mal_IDirectSoundCaptureBuffer_Stop((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer))) { if (FAILED(mal_IDirectSoundCaptureBuffer_Stop((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer))) {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundCaptureBuffer_Stop() failed.", MAL_FAILED_TO_STOP_BACKEND_DEVICE); return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundCaptureBuffer_Stop() failed.", MAL_FAILED_TO_STOP_BACKEND_DEVICE);
...@@ -12267,6 +12251,8 @@ void mal_pulse_device_write_callback(mal_pa_stream* pStream, size_t sizeInBytes, ...@@ -12267,6 +12251,8 @@ void mal_pulse_device_write_callback(mal_pa_stream* pStream, size_t sizeInBytes,
#ifdef MAL_DEBUG_OUTPUT #ifdef MAL_DEBUG_OUTPUT
printf(", framesToReadFromClient=0\n"); printf(", framesToReadFromClient=0\n");
#endif #endif
/* pa_stream_begin_write() returned a null pointer or 0 bytes. Get out of the loop. */
break;
} }
} }
} }
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