mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-21 15:56:58 +02:00
PulseAudio: Attempt to fix a deadlock.
Public issues https://github.com/mackron/miniaudio/issues/877 https://github.com/mackron/miniaudio/issues/881
This commit is contained in:
@@ -12,6 +12,7 @@ v0.11.22 - TBD
|
||||
* AAudio: The default minimum SDK version has been increased from 26 to 27 when enabling AAudio. If you need to support version 26, you can use `#define MA_AAUDIO_MIN_ANDROID_SDK_VERSION 26`.
|
||||
* AAudio: Fix ma_device_get_info() implementation
|
||||
* PulseAudio: Allow setting the channel map requested from PulseAudio in device configs
|
||||
* PulseAudio: Attempt to fix a deadlock. This involves converting the PulseAudio main loop from blocking to non-blocking. To restore the old blocking behaviour, you can do so via the device config: `deviceConfig.pulse.blockingMainLoop = MA_TRUE`.
|
||||
|
||||
|
||||
v0.11.21 - 2023-11-15
|
||||
|
||||
+44
-1
@@ -7108,6 +7108,7 @@ struct ma_device_config
|
||||
const char* pStreamNamePlayback;
|
||||
const char* pStreamNameCapture;
|
||||
int channelMap;
|
||||
ma_bool32 blockingMainLoop;
|
||||
} pulse;
|
||||
struct
|
||||
{
|
||||
@@ -7901,6 +7902,7 @@ struct ma_device
|
||||
/*pa_context**/ ma_ptr pPulseContext;
|
||||
/*pa_stream**/ ma_ptr pStreamPlayback;
|
||||
/*pa_stream**/ ma_ptr pStreamCapture;
|
||||
ma_bool32 blockingMainLoop;
|
||||
} pulse;
|
||||
#endif
|
||||
#ifdef MA_SUPPORT_JACK
|
||||
@@ -30471,6 +30473,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi
|
||||
sampleRate = pDescriptorCapture->sampleRate;
|
||||
}
|
||||
|
||||
pDevice->pulse.blockingMainLoop = pConfig->pulse.blockingMainLoop;
|
||||
|
||||
|
||||
result = ma_init_pa_mainloop_and_pa_context__pulse(pDevice->pContext, pDevice->pContext->pulse.pApplicationName, pDevice->pContext->pulse.pServerName, MA_FALSE, &pDevice->pulse.pMainLoop, &pDevice->pulse.pPulseContext);
|
||||
@@ -30956,10 +30959,50 @@ static ma_result ma_device_data_loop__pulse(ma_device* pDevice)
|
||||
the callbacks deal with it.
|
||||
*/
|
||||
while (ma_device_get_state(pDevice) == ma_device_state_started) {
|
||||
resultPA = ((ma_pa_mainloop_iterate_proc)pDevice->pContext->pulse.pa_mainloop_iterate)((ma_pa_mainloop*)pDevice->pulse.pMainLoop, 1, NULL);
|
||||
int block = (pDevice->pulse.blockingMainLoop) ? 1 : 0;
|
||||
|
||||
resultPA = ((ma_pa_mainloop_iterate_proc)pDevice->pContext->pulse.pa_mainloop_iterate)((ma_pa_mainloop*)pDevice->pulse.pMainLoop, block, NULL);
|
||||
if (resultPA < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we're not blocking we need to sleep for a bit to prevent the CPU core being pinned at 100% usage. */
|
||||
if (!block) {
|
||||
ma_uint32 sleepTimeInMilliseconds;
|
||||
|
||||
/*
|
||||
My original idea was to sleep for an amount of time proportionate to the configured period size, but I
|
||||
wasn't able to figure out how to make this work without glitching. Instead I'm just going to hardcode
|
||||
it to 1ms and move on.
|
||||
*/
|
||||
#if 0
|
||||
{
|
||||
if (((ma_pa_stream_writable_size_proc)pDevice->pContext->pulse.pa_stream_writable_size)((ma_pa_stream*)pDevice->pulse.pStreamPlayback) == 0) {
|
||||
/* The amount of time we spend sleeping should be proportionate to the size of a period. */
|
||||
if (pDevice->type == ma_device_type_playback) {
|
||||
sleepTimeInMilliseconds = (pDevice->playback.internalPeriodSizeInFrames * pDevice->playback.internalSampleRate) / 1000;
|
||||
} else {
|
||||
sleepTimeInMilliseconds = (pDevice->capture.internalPeriodSizeInFrames * pDevice->capture.internalSampleRate) / 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
At this point the sleep time is equal to the period size in milliseconds. I'm going to divide this by 2
|
||||
in an attempt to reduce latency as a result of sleeping.
|
||||
*/
|
||||
sleepTimeInMilliseconds /= 2;
|
||||
|
||||
/* Clamp the sleep time to within reasonable values just in case. */
|
||||
sleepTimeInMilliseconds = ma_clamp(sleepTimeInMilliseconds, 1, 10);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
sleepTimeInMilliseconds = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
ma_sleep(sleepTimeInMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: Don't stop the device here. It'll be done at a higher level. */
|
||||
|
||||
Reference in New Issue
Block a user