diff options
author | Chris Robinson <[email protected]> | 2017-02-18 17:32:07 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-02-18 17:32:07 -0800 |
commit | 247f56249ade334f8f7ef9eda9c380af0278562f (patch) | |
tree | 9c342e82e26e39bc7b075b62ca33ddd97969015f /Alc | |
parent | 2448f88e70f6207ad5743f0a55eaa5de7cbce737 (diff) |
Always lock the device backend before calling aluMixData
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 4 | ||||
-rw-r--r-- | Alc/ALu.c | 2 | ||||
-rw-r--r-- | Alc/backends/coreaudio.c | 2 | ||||
-rw-r--r-- | Alc/backends/dsound.c | 2 | ||||
-rw-r--r-- | Alc/backends/mmdevapi.c | 4 | ||||
-rw-r--r-- | Alc/backends/null.c | 2 | ||||
-rw-r--r-- | Alc/backends/portaudio.c | 2 | ||||
-rw-r--r-- | Alc/backends/qsa.c | 89 | ||||
-rw-r--r-- | Alc/backends/sndio.c | 2 | ||||
-rw-r--r-- | Alc/backends/wave.c | 2 | ||||
-rw-r--r-- | Alc/backends/winmm.c | 2 |
11 files changed, 63 insertions, 50 deletions
@@ -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); } @@ -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, ¶m); - 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)); |