while (ma_device_get_state(pDevice) == MA_STATE_STARTED) {
while (ma_device_get_state(pDevice) == ma_device_state_started) {
ma_result result;
/* The first thing to do is wait for space to become available for writing. This will return an error code if the device has been stopped. */
...
...
@@ -24693,7 +24696,7 @@ that point (it may still need to load files or whatnot). Instead, this callback
stream be started which is how it works with literally *every* other callback-based audio API. Since miniaudio forbids firing of the data
callback until the device has been started (as it should be with *all* callback based APIs), logic needs to be added to ensure miniaudio
doesn't just blindly fire the application-defined data callback from within the PulseAudio callback before the stream has actually been
started. The device state is used for this - if the state is anything other than `MA_STATE_STARTING` or `MA_STATE_STARTED`, the main data
started. The device state is used for this - if the state is anything other than `ma_device_state_starting` or `ma_device_state_started`, the main data
callback is not fired.
This, unfortunately, is not the end of the problems with the PulseAudio write callback. Any normal callback based audio API will
if (deviceState == MA_STATE_STARTED || deviceState == MA_STATE_STARTING) { /* Check for starting state just in case this is being used to do the initial fill. */
if (deviceState == ma_device_state_started || deviceState == ma_device_state_starting) { /* Check for starting state just in case this is being used to do the initial fill. */
if (ma_device_get_state(pDevice) == MA_STATE_UNINITIALIZED) {
if (ma_device_get_state(pDevice) == ma_device_state_uninitialized) {
return MA_INVALID_OPERATION; /* Not initialized. */
}
if (ma_device_get_state(pDevice) == MA_STATE_STARTED) {
if (ma_device_get_state(pDevice) == ma_device_state_started) {
return MA_INVALID_OPERATION; /* Already started. Returning an error to let the application know because it probably means they're doing something wrong. */
}
ma_mutex_lock(&pDevice->startStopLock);
{
/* Starting and stopping are wrapped in a mutex which means we can assert that the device is in a stopped or paused state. */
if (ma_device_get_state(pDevice) == MA_STATE_UNINITIALIZED) {
if (ma_device_get_state(pDevice) == ma_device_state_uninitialized) {
return MA_INVALID_OPERATION; /* Not initialized. */
}
if (ma_device_get_state(pDevice) == MA_STATE_STOPPED) {
if (ma_device_get_state(pDevice) == ma_device_state_stopped) {
return MA_INVALID_OPERATION; /* Already stopped. Returning an error to let the application know because it probably means they're doing something wrong. */
}
ma_mutex_lock(&pDevice->startStopLock);
{
/* Starting and stopping are wrapped in a mutex which means we can assert that the device is in a started or paused state. */