aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-02-18 17:32:07 -0800
committerChris Robinson <[email protected]>2017-02-18 17:32:07 -0800
commit247f56249ade334f8f7ef9eda9c380af0278562f (patch)
tree9c342e82e26e39bc7b075b62ca33ddd97969015f /Alc
parent2448f88e70f6207ad5743f0a55eaa5de7cbce737 (diff)
Always lock the device backend before calling aluMixData
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c4
-rw-r--r--Alc/ALu.c2
-rw-r--r--Alc/backends/coreaudio.c2
-rw-r--r--Alc/backends/dsound.c2
-rw-r--r--Alc/backends/mmdevapi.c4
-rw-r--r--Alc/backends/null.c2
-rw-r--r--Alc/backends/portaudio.c2
-rw-r--r--Alc/backends/qsa.c89
-rw-r--r--Alc/backends/sndio.c2
-rw-r--r--Alc/backends/wave.c2
-rw-r--r--Alc/backends/winmm.c2
11 files changed, 63 insertions, 50 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 1028321e..17b2727d 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -4182,7 +4182,11 @@ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, AL
else if(samples < 0 || (samples > 0 && buffer == NULL))
alcSetError(device, ALC_INVALID_VALUE);
else
+ {
+ V0(device->Backend,lock)();
aluMixData(device, buffer, samples);
+ V0(device->Backend,unlock)();
+ }
if(device) ALCdevice_DecRef(device);
}
diff --git a/Alc/ALu.c b/Alc/ALu.c
index d5065199..9dcef6ff 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1423,7 +1423,6 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
memset(device->FOAOut.Buffer[c], 0, SamplesToDo*sizeof(ALfloat));
IncrementRef(&device->MixCount);
- V0(device->Backend,lock)();
if((slot=device->DefaultSlot) != NULL)
{
@@ -1488,7 +1487,6 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
device->SamplesDone += SamplesToDo;
device->ClockBase += (device->SamplesDone/device->Frequency) * DEVICE_CLOCK_RES;
device->SamplesDone %= device->Frequency;
- V0(device->Backend,unlock)();
IncrementRef(&device->MixCount);
if(device->Hrtf.Handle)
diff --git a/Alc/backends/coreaudio.c b/Alc/backends/coreaudio.c
index 24aeabd4..eb93f9ea 100644
--- a/Alc/backends/coreaudio.c
+++ b/Alc/backends/coreaudio.c
@@ -89,8 +89,10 @@ static OSStatus ca_callback(void *inRefCon, AudioUnitRenderActionFlags *ioAction
ALCdevice *device = (ALCdevice*)inRefCon;
ca_data *data = (ca_data*)device->ExtraData;
+ ALCdevice_Lock(device);
aluMixData(device, ioData->mBuffers[0].mData,
ioData->mBuffers[0].mDataByteSize / data->frameSize);
+ ALCdevice_Unlock(device);
return noErr;
}
diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c
index bb38d516..084d1125 100644
--- a/Alc/backends/dsound.c
+++ b/Alc/backends/dsound.c
@@ -299,8 +299,10 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr)
if(SUCCEEDED(err))
{
// If we have an active context, mix data directly into output buffer otherwise fill with silence
+ ALCdevice_Lock(device);
aluMixData(device, WritePtr1, WriteCnt1/FrameSize);
aluMixData(device, WritePtr2, WriteCnt2/FrameSize);
+ ALCdevice_Unlock(device);
// Unlock output buffer only when successfully locked
IDirectSoundBuffer_Unlock(self->Buffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c
index 92089416..6ff9d931 100644
--- a/Alc/backends/mmdevapi.c
+++ b/Alc/backends/mmdevapi.c
@@ -629,10 +629,10 @@ FORCE_ALIGN static int ALCmmdevPlayback_mixerProc(void *arg)
hr = IAudioRenderClient_GetBuffer(self->render, len, &buffer);
if(SUCCEEDED(hr))
{
- V0(device->Backend,lock)();
+ ALCmmdevPlayback_lock(self);
aluMixData(device, buffer, len);
self->Padding = written + len;
- V0(device->Backend,unlock)();
+ ALCmmdevPlayback_unlock(self);
hr = IAudioRenderClient_ReleaseBuffer(self->render, len, 0);
}
if(FAILED(hr))
diff --git a/Alc/backends/null.c b/Alc/backends/null.c
index 5b153cd9..41636538 100644
--- a/Alc/backends/null.c
+++ b/Alc/backends/null.c
@@ -109,7 +109,9 @@ static int ALCnullBackend_mixerProc(void *ptr)
al_nssleep(restTime);
else while(avail-done >= device->UpdateSize)
{
+ ALCnullBackend_lock(self);
aluMixData(device, NULL, device->UpdateSize);
+ ALCnullBackend_unlock(self);
done += device->UpdateSize;
}
}
diff --git a/Alc/backends/portaudio.c b/Alc/backends/portaudio.c
index 1dbca941..129b0606 100644
--- a/Alc/backends/portaudio.c
+++ b/Alc/backends/portaudio.c
@@ -177,7 +177,9 @@ static int ALCportPlayback_WriteCallback(const void *UNUSED(inputBuffer), void *
{
ALCportPlayback *self = userData;
+ ALCportPlayback_lock(self);
aluMixData(STATIC_CAST(ALCbackend, self)->mDevice, outputBuffer, framesPerBuffer);
+ ALCportPlayback_unlock(self);
return 0;
}
diff --git a/Alc/backends/qsa.c b/Alc/backends/qsa.c
index b7923517..dabe5ee9 100644
--- a/Alc/backends/qsa.c
+++ b/Alc/backends/qsa.c
@@ -33,6 +33,8 @@
#include "alu.h"
#include "threads.h"
+#include "backends/base.h"
+
typedef struct {
snd_pcm_t* pcmHandle;
@@ -161,13 +163,13 @@ FORCE_ALIGN static int qsa_proc_playback(void* ptr)
{
ALCdevice* device=(ALCdevice*)ptr;
qsa_data* data=(qsa_data*)device->ExtraData;
- char* write_ptr;
- int avail;
snd_pcm_channel_status_t status;
struct sched_param param;
- fd_set wfds;
- int selectret;
struct timeval timeout;
+ char* write_ptr;
+ fd_set wfds;
+ ALint len;
+ int sret;
SetRTPriority();
althrd_setname(althrd_current(), MIXER_THREAD_NAME);
@@ -177,59 +179,53 @@ FORCE_ALIGN static int qsa_proc_playback(void* ptr)
param.sched_priority=param.sched_curpriority+1;
SchedSet(0, 0, SCHED_NOCHANGE, &param);
- ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
+ const ALint frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
- while (!data->killNow)
+ V0(device->Backend,lock)();
+ while(!data->killNow)
{
- ALint len=data->size;
- write_ptr=data->buffer;
-
- avail=len/frame_size;
- aluMixData(device, write_ptr, avail);
+ FD_ZERO(&wfds);
+ FD_SET(data->audio_fd, &wfds);
+ timeout.tv_sec=2;
+ timeout.tv_usec=0;
- while (len>0 && !data->killNow)
+ /* Select also works like time slice to OS */
+ V0(device->Backend,unlock)();
+ sret = select(data->audio_fd+1, NULL, &wfds, NULL, &timeout);
+ V0(device->Backend,lock)();
+ if(sret == -1)
{
- FD_ZERO(&wfds);
- FD_SET(data->audio_fd, &wfds);
- timeout.tv_sec=2;
- timeout.tv_usec=0;
-
- /* Select also works like time slice to OS */
- selectret=select(data->audio_fd+1, NULL, &wfds, NULL, &timeout);
- switch (selectret)
- {
- case -1:
- aluHandleDisconnect(device);
- return 1;
- case 0:
- break;
- default:
- if (FD_ISSET(data->audio_fd, &wfds))
- {
- break;
- }
- break;
- }
-
- int wrote=snd_pcm_plugin_write(data->pcmHandle, write_ptr, len);
+ ERR("select error: %s\n", strerror(errno));
+ aluHandleDisconnect(device);
+ break;
+ }
+ if(sret == 0)
+ {
+ ERR("select timeout\n");
+ continue;
+ }
- if (wrote<=0)
+ len = data->size;
+ write_ptr = data->buffer;
+ aluMixData(device, write_ptr, len/frame_size);
+ while(len>0 && !data->killNow)
+ {
+ int wrote = snd_pcm_plugin_write(data->pcmHandle, write_ptr, len);
+ if(wrote <= 0)
{
- if ((errno==EAGAIN) || (errno==EWOULDBLOCK))
- {
+ if(errno==EAGAIN || errno==EWOULDBLOCK)
continue;
- }
- memset(&status, 0, sizeof (status));
- status.channel=SND_PCM_CHANNEL_PLAYBACK;
+ memset(&status, 0, sizeof(status));
+ status.channel = SND_PCM_CHANNEL_PLAYBACK;
snd_pcm_plugin_status(data->pcmHandle, &status);
/* we need to reinitialize the sound channel if we've underrun the buffer */
- if ((status.status==SND_PCM_STATUS_UNDERRUN) ||
- (status.status==SND_PCM_STATUS_READY))
+ if(status.status == SND_PCM_STATUS_UNDERRUN ||
+ status.status == SND_PCM_STATUS_READY)
{
- if ((snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK))<0)
+ if(snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK) < 0)
{
aluHandleDisconnect(device);
break;
@@ -238,11 +234,12 @@ FORCE_ALIGN static int qsa_proc_playback(void* ptr)
}
else
{
- write_ptr+=wrote;
- len-=wrote;
+ write_ptr += wrote;
+ len -= wrote;
}
}
}
+ V0(device->Backend,unlock)();
return 0;
}
diff --git a/Alc/backends/sndio.c b/Alc/backends/sndio.c
index af519794..00d7c654 100644
--- a/Alc/backends/sndio.c
+++ b/Alc/backends/sndio.c
@@ -105,7 +105,9 @@ static int ALCsndioBackend_mixerProc(void *ptr)
ALsizei len = self->data_size;
ALubyte *WritePtr = self->mix_data;
+ ALCsndioBackend_lock(self);
aluMixData(device, WritePtr, len/frameSize);
+ ALCsndioBackend_unlock(self);
while(len > 0 && !self->killNow)
{
wrote = sio_write(self->sndHandle, WritePtr, len);
diff --git a/Alc/backends/wave.c b/Alc/backends/wave.c
index 9bf5a727..ac0ffd80 100644
--- a/Alc/backends/wave.c
+++ b/Alc/backends/wave.c
@@ -157,7 +157,9 @@ static int ALCwaveBackend_mixerProc(void *ptr)
al_nssleep(restTime);
else while(avail-done >= device->UpdateSize)
{
+ ALCwaveBackend_lock(self);
aluMixData(device, self->mBuffer, device->UpdateSize);
+ ALCwaveBackend_unlock(self);
done += device->UpdateSize;
if(!IS_LITTLE_ENDIAN)
diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c
index 9d8f8e9d..2b6db4ad 100644
--- a/Alc/backends/winmm.c
+++ b/Alc/backends/winmm.c
@@ -232,8 +232,10 @@ FORCE_ALIGN static int ALCwinmmPlayback_mixerProc(void *arg)
}
WaveHdr = ((WAVEHDR*)msg.lParam);
+ ALCwinmmPlayback_lock(self);
aluMixData(device, WaveHdr->lpData, WaveHdr->dwBufferLength /
self->Format.nBlockAlign);
+ ALCwinmmPlayback_unlock(self);
// Send buffer back to play more data
waveOutWrite(self->OutHdl, WaveHdr, sizeof(WAVEHDR));