Commit 4f8e8de3 authored by David Reid's avatar David Reid

Migrate atomics from ma_device to new atomics system.

parent 84e91172
...@@ -4256,7 +4256,6 @@ MA_ATOMIC_SAFE_TYPE_DECL(f32, 4, float) ...@@ -4256,7 +4256,6 @@ MA_ATOMIC_SAFE_TYPE_DECL(f32, 4, float)
MA_ATOMIC_SAFE_TYPE_DECL(32, 4, bool32) MA_ATOMIC_SAFE_TYPE_DECL(32, 4, bool32)
/* Spinlocks are 32-bit for compatibility reasons. */ /* Spinlocks are 32-bit for compatibility reasons. */
typedef ma_uint32 ma_spinlock; typedef ma_uint32 ma_spinlock;
...@@ -6308,6 +6307,9 @@ typedef enum ...@@ -6308,6 +6307,9 @@ typedef enum
ma_device_state_stopping = 4 /* Transitioning from a started state to stopped. */ ma_device_state_stopping = 4 /* Transitioning from a started state to stopped. */
} ma_device_state; } ma_device_state;
MA_ATOMIC_SAFE_TYPE_DECL(i32, 4, device_state)
#ifdef MA_SUPPORT_WASAPI #ifdef MA_SUPPORT_WASAPI
/* We need a IMMNotificationClient object for WASAPI. */ /* We need a IMMNotificationClient object for WASAPI. */
typedef struct typedef struct
...@@ -7372,7 +7374,7 @@ struct ma_device ...@@ -7372,7 +7374,7 @@ struct ma_device
ma_context* pContext; ma_context* pContext;
ma_device_type type; ma_device_type type;
ma_uint32 sampleRate; ma_uint32 sampleRate;
MA_ATOMIC(4, ma_device_state) state; /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */ ma_atomic_device_state state; /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */
ma_device_data_proc onData; /* Set once at initialization time and should not be changed after. */ ma_device_data_proc onData; /* Set once at initialization time and should not be changed after. */
ma_device_notification_proc onNotification; /* Set once at initialization time and should not be changed after. */ ma_device_notification_proc onNotification; /* Set once at initialization time and should not be changed after. */
ma_stop_proc onStop; /* DEPRECATED. Use the notification callback instead. Set once at initialization time and should not be changed after. */ ma_stop_proc onStop; /* DEPRECATED. Use the notification callback instead. Set once at initialization time and should not be changed after. */
...@@ -7388,7 +7390,7 @@ struct ma_device ...@@ -7388,7 +7390,7 @@ struct ma_device
ma_bool8 noClip; ma_bool8 noClip;
ma_bool8 noDisableDenormals; ma_bool8 noDisableDenormals;
ma_bool8 noFixedSizedCallback; ma_bool8 noFixedSizedCallback;
MA_ATOMIC(4, float) masterVolumeFactor; /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */ ma_atomic_float masterVolumeFactor; /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */
ma_duplex_rb duplexRB; /* Intermediary buffer for duplex device on asynchronous backends. */ ma_duplex_rb duplexRB; /* Intermediary buffer for duplex device on asynchronous backends. */
struct struct
{ {
...@@ -7476,8 +7478,8 @@ struct ma_device ...@@ -7476,8 +7478,8 @@ struct ma_device
void* pMappedBufferPlayback; void* pMappedBufferPlayback;
ma_uint32 mappedBufferPlaybackCap; ma_uint32 mappedBufferPlaybackCap;
ma_uint32 mappedBufferPlaybackLen; ma_uint32 mappedBufferPlaybackLen;
MA_ATOMIC(4, ma_bool32) isStartedCapture; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */ ma_atomic_bool32 isStartedCapture; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
MA_ATOMIC(4, ma_bool32) isStartedPlayback; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */ ma_atomic_bool32 isStartedPlayback; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
ma_uint32 loopbackProcessID; ma_uint32 loopbackProcessID;
ma_bool8 loopbackProcessExclude; ma_bool8 loopbackProcessExclude;
ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */ ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
...@@ -7650,7 +7652,7 @@ struct ma_device ...@@ -7650,7 +7652,7 @@ struct ma_device
ma_uint32 currentPeriodFramesRemainingCapture; ma_uint32 currentPeriodFramesRemainingCapture;
ma_uint64 lastProcessedFramePlayback; ma_uint64 lastProcessedFramePlayback;
ma_uint64 lastProcessedFrameCapture; ma_uint64 lastProcessedFrameCapture;
MA_ATOMIC(4, ma_bool32) isStarted; /* Read and written by multiple threads. Must be used atomically, and must be 32-bit for compiler compatibility. */ ma_atomic_bool32 isStarted; /* Read and written by multiple threads. Must be used atomically, and must be 32-bit for compiler compatibility. */
} null_device; } null_device;
#endif #endif
}; };
...@@ -15580,7 +15582,7 @@ MA_ATOMIC_SAFE_TYPE_IMPL(i32, int32) ...@@ -15580,7 +15582,7 @@ MA_ATOMIC_SAFE_TYPE_IMPL(i32, int32)
MA_ATOMIC_SAFE_TYPE_IMPL(64, uint64) MA_ATOMIC_SAFE_TYPE_IMPL(64, uint64)
MA_ATOMIC_SAFE_TYPE_IMPL(f32, float) MA_ATOMIC_SAFE_TYPE_IMPL(f32, float)
MA_ATOMIC_SAFE_TYPE_IMPL(32, bool32) MA_ATOMIC_SAFE_TYPE_IMPL(32, bool32)
MA_ATOMIC_SAFE_TYPE_IMPL(i32, device_state)
MA_API ma_uint64 ma_calculate_frame_count_after_resampling(ma_uint32 sampleRateOut, ma_uint32 sampleRateIn, ma_uint64 frameCountIn) MA_API ma_uint64 ma_calculate_frame_count_after_resampling(ma_uint32 sampleRateOut, ma_uint32 sampleRateIn, ma_uint64 frameCountIn)
...@@ -18606,7 +18608,7 @@ static ma_result ma_device__handle_duplex_callback_playback(ma_device* pDevice, ...@@ -18606,7 +18608,7 @@ static ma_result ma_device__handle_duplex_callback_playback(ma_device* pDevice,
/* A helper for changing the state of the device. */ /* A helper for changing the state of the device. */
static MA_INLINE void ma_device__set_state(ma_device* pDevice, ma_device_state newState) static MA_INLINE void ma_device__set_state(ma_device* pDevice, ma_device_state newState)
{ {
c89atomic_exchange_i32((ma_int32*)&pDevice->state, (ma_int32)newState); ma_atomic_device_state_set(&pDevice->state, newState);
} }
...@@ -19117,7 +19119,7 @@ static ma_result ma_device_start__null(ma_device* pDevice) ...@@ -19117,7 +19119,7 @@ static ma_result ma_device_start__null(ma_device* pDevice)
ma_device_do_operation__null(pDevice, MA_DEVICE_OP_START__NULL); ma_device_do_operation__null(pDevice, MA_DEVICE_OP_START__NULL);
c89atomic_exchange_32(&pDevice->null_device.isStarted, MA_TRUE); ma_atomic_bool32_set(&pDevice->null_device.isStarted, MA_TRUE);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -19127,10 +19129,17 @@ static ma_result ma_device_stop__null(ma_device* pDevice) ...@@ -19127,10 +19129,17 @@ static ma_result ma_device_stop__null(ma_device* pDevice)
ma_device_do_operation__null(pDevice, MA_DEVICE_OP_SUSPEND__NULL); ma_device_do_operation__null(pDevice, MA_DEVICE_OP_SUSPEND__NULL);
c89atomic_exchange_32(&pDevice->null_device.isStarted, MA_FALSE); ma_atomic_bool32_set(&pDevice->null_device.isStarted, MA_FALSE);
return MA_SUCCESS; return MA_SUCCESS;
} }
static ma_bool32 ma_device_is_started__null(ma_device* pDevice)
{
MA_ASSERT(pDevice != NULL);
return ma_atomic_bool32_get(&pDevice->null_device.isStarted);
}
static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten) static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{ {
ma_result result = MA_SUCCESS; ma_result result = MA_SUCCESS;
...@@ -19141,7 +19150,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame ...@@ -19141,7 +19150,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame
*pFramesWritten = 0; *pFramesWritten = 0;
} }
wasStartedOnEntry = c89atomic_load_32(&pDevice->null_device.isStarted); wasStartedOnEntry = ma_device_is_started__null(pDevice);
/* Keep going until everything has been read. */ /* Keep going until everything has been read. */
totalPCMFramesProcessed = 0; totalPCMFramesProcessed = 0;
...@@ -19167,7 +19176,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame ...@@ -19167,7 +19176,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame
if (pDevice->null_device.currentPeriodFramesRemainingPlayback == 0) { if (pDevice->null_device.currentPeriodFramesRemainingPlayback == 0) {
pDevice->null_device.currentPeriodFramesRemainingPlayback = 0; pDevice->null_device.currentPeriodFramesRemainingPlayback = 0;
if (!c89atomic_load_32(&pDevice->null_device.isStarted) && !wasStartedOnEntry) { if (!ma_device_is_started__null(pDevice) && !wasStartedOnEntry) {
result = ma_device_start__null(pDevice); result = ma_device_start__null(pDevice);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
break; break;
...@@ -19187,7 +19196,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame ...@@ -19187,7 +19196,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame
ma_uint64 currentFrame; ma_uint64 currentFrame;
/* Stop waiting if the device has been stopped. */ /* Stop waiting if the device has been stopped. */
if (!c89atomic_load_32(&pDevice->null_device.isStarted)) { if (!ma_device_is_started__null(pDevice)) {
break; break;
} }
...@@ -19258,7 +19267,7 @@ static ma_result ma_device_read__null(ma_device* pDevice, void* pPCMFrames, ma_u ...@@ -19258,7 +19267,7 @@ static ma_result ma_device_read__null(ma_device* pDevice, void* pPCMFrames, ma_u
ma_uint64 currentFrame; ma_uint64 currentFrame;
/* Stop waiting if the device has been stopped. */ /* Stop waiting if the device has been stopped. */
if (!c89atomic_load_32(&pDevice->null_device.isStarted)) { if (!ma_device_is_started__null(pDevice)) {
break; break;
} }
...@@ -22229,8 +22238,8 @@ static ma_result ma_device_init__wasapi(ma_device* pDevice, const ma_device_conf ...@@ -22229,8 +22238,8 @@ static ma_result ma_device_init__wasapi(ma_device* pDevice, const ma_device_conf
} }
#endif #endif
c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture, MA_FALSE); ma_atomic_bool32_set(&pDevice->wasapi.isStartedCapture, MA_FALSE);
c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_FALSE); ma_atomic_bool32_set(&pDevice->wasapi.isStartedPlayback, MA_FALSE);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -22335,7 +22344,7 @@ static ma_result ma_device_start__wasapi(ma_device* pDevice) ...@@ -22335,7 +22344,7 @@ static ma_result ma_device_start__wasapi(ma_device* pDevice)
return ma_result_from_HRESULT(hr); return ma_result_from_HRESULT(hr);
} }
c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture, MA_TRUE); ma_atomic_bool32_set(&pDevice->wasapi.isStartedCapture, MA_TRUE);
} }
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
...@@ -22345,7 +22354,7 @@ static ma_result ma_device_start__wasapi(ma_device* pDevice) ...@@ -22345,7 +22354,7 @@ static ma_result ma_device_start__wasapi(ma_device* pDevice)
return ma_result_from_HRESULT(hr); return ma_result_from_HRESULT(hr);
} }
c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_TRUE); ma_atomic_bool32_set(&pDevice->wasapi.isStartedPlayback, MA_TRUE);
} }
return MA_SUCCESS; return MA_SUCCESS;
...@@ -22385,7 +22394,7 @@ static ma_result ma_device_stop__wasapi(ma_device* pDevice) ...@@ -22385,7 +22394,7 @@ static ma_result ma_device_stop__wasapi(ma_device* pDevice)
pDevice->wasapi.mappedBufferCaptureLen = 0; pDevice->wasapi.mappedBufferCaptureLen = 0;
} }
c89atomic_exchange_32(&pDevice->wasapi.isStartedCapture, MA_FALSE); ma_atomic_bool32_set(&pDevice->wasapi.isStartedCapture, MA_FALSE);
} }
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
...@@ -22393,7 +22402,7 @@ static ma_result ma_device_stop__wasapi(ma_device* pDevice) ...@@ -22393,7 +22402,7 @@ static ma_result ma_device_stop__wasapi(ma_device* pDevice)
The buffer needs to be drained before stopping the device. Not doing this will result in the last few frames not getting output to The buffer needs to be drained before stopping the device. Not doing this will result in the last few frames not getting output to
the speakers. This is a problem for very short sounds because it'll result in a significant portion of it not getting played. the speakers. This is a problem for very short sounds because it'll result in a significant portion of it not getting played.
*/ */
if (c89atomic_load_32(&pDevice->wasapi.isStartedPlayback)) { if (ma_atomic_bool32_get(&pDevice->wasapi.isStartedPlayback)) {
/* We need to make sure we put a timeout here or else we'll risk getting stuck in a deadlock in some cases. */ /* We need to make sure we put a timeout here or else we'll risk getting stuck in a deadlock in some cases. */
DWORD waitTime = pDevice->wasapi.actualBufferSizeInFramesPlayback / pDevice->playback.internalSampleRate; DWORD waitTime = pDevice->wasapi.actualBufferSizeInFramesPlayback / pDevice->playback.internalSampleRate;
...@@ -22447,7 +22456,7 @@ static ma_result ma_device_stop__wasapi(ma_device* pDevice) ...@@ -22447,7 +22456,7 @@ static ma_result ma_device_stop__wasapi(ma_device* pDevice)
pDevice->wasapi.mappedBufferPlaybackLen = 0; pDevice->wasapi.mappedBufferPlaybackLen = 0;
} }
c89atomic_exchange_32(&pDevice->wasapi.isStartedPlayback, MA_FALSE); ma_atomic_bool32_set(&pDevice->wasapi.isStartedPlayback, MA_FALSE);
} }
return MA_SUCCESS; return MA_SUCCESS;
...@@ -40571,7 +40580,7 @@ MA_API ma_result ma_device_init(ma_context* pContext, const ma_device_config* pC ...@@ -40571,7 +40580,7 @@ MA_API ma_result ma_device_init(ma_context* pContext, const ma_device_config* pC
pDevice->noClip = pConfig->noClip; pDevice->noClip = pConfig->noClip;
pDevice->noDisableDenormals = pConfig->noDisableDenormals; pDevice->noDisableDenormals = pConfig->noDisableDenormals;
pDevice->noFixedSizedCallback = pConfig->noFixedSizedCallback; pDevice->noFixedSizedCallback = pConfig->noFixedSizedCallback;
pDevice->masterVolumeFactor = 1; ma_atomic_float_set(&pDevice->masterVolumeFactor, 1);
pDevice->type = pConfig->deviceType; pDevice->type = pConfig->deviceType;
pDevice->sampleRate = pConfig->sampleRate; pDevice->sampleRate = pConfig->sampleRate;
...@@ -41279,7 +41288,7 @@ MA_API ma_device_state ma_device_get_state(const ma_device* pDevice) ...@@ -41279,7 +41288,7 @@ MA_API ma_device_state ma_device_get_state(const ma_device* pDevice)
return ma_device_state_uninitialized; return ma_device_state_uninitialized;
} }
return (ma_device_state)c89atomic_load_i32((ma_int32*)&pDevice->state); /* Naughty cast to get rid of a const warning. */ return ma_atomic_device_state_get((ma_atomic_device_state*)&pDevice->state); /* Naughty cast to get rid of a const warning. */
} }
MA_API ma_result ma_device_set_master_volume(ma_device* pDevice, float volume) MA_API ma_result ma_device_set_master_volume(ma_device* pDevice, float volume)
...@@ -41292,7 +41301,7 @@ MA_API ma_result ma_device_set_master_volume(ma_device* pDevice, float volume) ...@@ -41292,7 +41301,7 @@ MA_API ma_result ma_device_set_master_volume(ma_device* pDevice, float volume)
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
c89atomic_exchange_f32(&pDevice->masterVolumeFactor, volume); ma_atomic_float_set(&pDevice->masterVolumeFactor, volume);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -41308,7 +41317,7 @@ MA_API ma_result ma_device_get_master_volume(ma_device* pDevice, float* pVolume) ...@@ -41308,7 +41317,7 @@ MA_API ma_result ma_device_get_master_volume(ma_device* pDevice, float* pVolume)
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
*pVolume = c89atomic_load_f32(&pDevice->masterVolumeFactor); *pVolume = ma_atomic_float_get(&pDevice->masterVolumeFactor);
return MA_SUCCESS; return MA_SUCCESS;
} }
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