void ALeffectState_DecRef(ALeffectState *state) { uint ref; ref = DecrementRef(&state->Ref); TRACEREF("%p decreasing refcount to %u\n", state, ref); if(ref == 0) DELETE_OBJ(state); }
ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids) { ALCdevice *device = context->Device; ALsoundfont **sfonts; ALsizei i; if(self->State != AL_INITIAL && self->State != AL_STOPPED) return AL_INVALID_OPERATION; sfonts = calloc(1, count * sizeof(sfonts[0])); if(!sfonts) return AL_OUT_OF_MEMORY; for(i = 0;i < count;i++) { if(ids[i] == 0) sfonts[i] = ALsoundfont_getDefSoundfont(context); else if(!(sfonts[i]=LookupSfont(device, ids[i]))) { free(sfonts); return AL_INVALID_VALUE; } } for(i = 0;i < count;i++) IncrementRef(&sfonts[i]->ref); sfonts = ExchangePtr((XchgPtr*)&self->Soundfonts, sfonts); count = ExchangeInt(&self->NumSoundfonts, count); for(i = 0;i < count;i++) DecrementRef(&sfonts[i]->ref); free(sfonts); return AL_NO_ERROR; }
/* ALCwinmmCapture_waveInProc * * Posts a message to 'ALCwinmmCapture_captureProc' everytime a WaveIn Buffer * is completed and returns to the application (with more data). */ static void CALLBACK ALCwinmmCapture_waveInProc(HWAVEIN UNUSED(device), UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR UNUSED(param2)) { ALCwinmmCapture *self = (ALCwinmmCapture*)instance; if(msg != WIM_DATA) return; DecrementRef(&self->WaveBuffersCommitted); PostThreadMessage(self->thread, msg, 0, param1); }
/* ALCwinmmPlayback_waveOutProc * * Posts a message to 'ALCwinmmPlayback_mixerProc' everytime a WaveOut Buffer * is completed and returns to the application (for more data) */ static void CALLBACK ALCwinmmPlayback_waveOutProc(HWAVEOUT UNUSED(device), UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR UNUSED(param2)) { ALCwinmmPlayback *self = (ALCwinmmPlayback*)instance; if(msg != WOM_DONE) return; DecrementRef(&self->WaveBuffersCommitted); PostThreadMessage(self->thread, msg, 0, param1); }
/* WaveInProc Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and returns to the application (with more data) */ static void CALLBACK WaveInProc(HWAVEIN UNUSED(device), UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR UNUSED(param2)) { ALCdevice *Device = (ALCdevice*)instance; WinMMData *data = Device->ExtraData; if(msg != WIM_DATA) return; DecrementRef(&data->WaveBuffersCommitted); PostThreadMessage(data->thread, msg, 0, param1); }
void MidiSynth_Destruct(MidiSynth *self) { ALsizei i; for(i = 0;i < self->NumSoundfonts;i++) DecrementRef(&self->Soundfonts[i]->ref); free(self->Soundfonts); self->Soundfonts = NULL; self->NumSoundfonts = 0; ResetEvtQueue(&self->EventQueue); }
static void ALsfpreset_Destruct(ALsfpreset *self) { ALsizei i; FreeThunkEntry(self->id); self->id = 0; for(i = 0;i < self->NumSounds;i++) DecrementRef(&self->Sounds[i]->ref); free(self->Sounds); self->Sounds = NULL; self->NumSounds = 0; }
AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids) { ALCdevice *device; ALCcontext *context; ALsfpreset *preset; ALfontsound **sounds; ALsizei i; context = GetContextRef(); if(!context) return; device = context->Device; if(!(preset=LookupPreset(device, id))) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(count < 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if(ReadRef(&preset->ref) != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); if(count == 0) sounds = NULL; else { sounds = calloc(count, sizeof(sounds[0])); if(!sounds) SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); for(i = 0;i < count;i++) { if(!(sounds[i]=LookupFontsound(device, fsids[i]))) { free(sounds); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } } } for(i = 0;i < count;i++) IncrementRef(&sounds[i]->ref); sounds = ExchangePtr((XchgPtr*)&preset->Sounds, sounds); count = ExchangeInt(&preset->NumSounds, count); for(i = 0;i < count;i++) DecrementRef(&sounds[i]->ref); free(sounds); done: ALCcontext_DecRef(context); }
int alcnd_wait(alcnd_t *cond, almtx_t *mtx) { _int_alcnd_t *icond = cond->Ptr; int res; IncrementRef(&icond->wait_count); LeaveCriticalSection(mtx); res = WaitForMultipleObjects(2, icond->events, FALSE, INFINITE); if(DecrementRef(&icond->wait_count) == 0 && res == WAIT_OBJECT_0+BROADCAST) ResetEvent(icond->events[BROADCAST]); EnterCriticalSection(mtx); return althrd_success; }
static void ALsoundfont_Destruct(ALsoundfont *self) { ALsizei i; FreeThunkEntry(self->id); self->id = 0; for(i = 0;i < self->NumPresets;i++) { DecrementRef(&self->Presets[i]->ref); self->Presets[i] = NULL; } free(self->Presets); self->Presets = NULL; self->NumPresets = 0; }
int alcnd_timedwait(alcnd_t *cond, almtx_t *mtx, const struct timespec *time_point) { _int_alcnd_t *icond = cond->Ptr; struct timespec curtime; DWORD sleeptime; int res; if(altimespec_get(&curtime, AL_TIME_UTC) != AL_TIME_UTC) return althrd_error; sleeptime = (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000; sleeptime += (time_point->tv_sec - curtime.tv_sec)*1000; IncrementRef(&icond->wait_count); LeaveCriticalSection(mtx); res = WaitForMultipleObjects(2, icond->events, FALSE, sleeptime); if(DecrementRef(&icond->wait_count) == 0 && res == WAIT_OBJECT_0+BROADCAST) ResetEvent(icond->events[BROADCAST]); EnterCriticalSection(mtx); return (res == WAIT_TIMEOUT) ? althrd_timedout : althrd_success; }
void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device) { ALsfpreset **presets; ALsizei num_presets; VECTOR(ALbuffer*) buffers; ALsizei i; VECTOR_INIT(buffers); presets = ExchangePtr((XchgPtr*)&self->Presets, NULL); num_presets = ExchangeInt(&self->NumPresets, 0); for(i = 0;i < num_presets;i++) { ALsfpreset *preset = presets[i]; ALfontsound **sounds; ALsizei num_sounds; ALboolean deleting; ALsizei j; sounds = ExchangePtr((XchgPtr*)&preset->Sounds, NULL); num_sounds = ExchangeInt(&preset->NumSounds, 0); DeletePreset(device, preset); preset = NULL; for(j = 0;j < num_sounds;j++) DecrementRef(&sounds[j]->ref); /* Some fontsounds may not be immediately deletable because they're * linked to another fontsound. When those fontsounds are deleted * they should become deletable, so use a loop until all fontsounds * are deleted. */ do { deleting = AL_FALSE; for(j = 0;j < num_sounds;j++) { if(sounds[j] && ReadRef(&sounds[j]->ref) == 0) { ALbuffer *buffer; deleting = AL_TRUE; if((buffer=ATOMIC_LOAD(&sounds[j]->Buffer)) != NULL) { ALbuffer **iter; #define MATCH_BUFFER(_i) (buffer == *(_i)) VECTOR_FIND_IF(iter, ALbuffer*, buffers, MATCH_BUFFER); if(iter == VECTOR_ITER_END(buffers)) VECTOR_PUSH_BACK(buffers, buffer); #undef MATCH_BUFFER } DeleteFontsound(device, sounds[j]); sounds[j] = NULL; } } } while(deleting); free(sounds); } ALsoundfont_Destruct(self); free(self); #define DELETE_BUFFER(iter) do { \ assert(ReadRef(&(*(iter))->ref) == 0); \ DeleteBuffer(device, *(iter)); \ } while(0) VECTOR_FOR_EACH(ALbuffer*, buffers, DELETE_BUFFER); #undef DELETE_BUFFER VECTOR_DEINIT(buffers); }
AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids) { ALCdevice *device; ALCcontext *context; ALsoundfont *sfont; ALsfpreset **presets; ALsizei i; context = GetContextRef(); if(!context) return; device = context->Device; if(id == 0) SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); if(!(sfont=LookupSfont(device, id))) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(count < 0) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); WriteLock(&sfont->Lock); if(ReadRef(&sfont->ref) != 0) { WriteUnlock(&sfont->Lock); SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } if(count == 0) presets = NULL; else { presets = calloc(count, sizeof(presets[0])); if(!presets) { WriteUnlock(&sfont->Lock); SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } for(i = 0;i < count;i++) { if(!(presets[i]=LookupPreset(device, pids[i]))) { free(presets); WriteUnlock(&sfont->Lock); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } } } for(i = 0;i < count;i++) IncrementRef(&presets[i]->ref); presets = ExchangePtr((XchgPtr*)&sfont->Presets, presets); count = ExchangeInt(&sfont->NumPresets, count); WriteUnlock(&sfont->Lock); for(i = 0;i < count;i++) DecrementRef(&presets[i]->ref); free(presets); done: ALCcontext_DecRef(context); }
void WriteUnlock(RWLock *lock) { UNLOCK(lock->write_lock); if(DecrementRef(&lock->write_count) == 0) UNLOCK(lock->read_lock); }
void ReadUnlock(RWLock *lock) { if(DecrementRef(&lock->read_count) == 0) UNLOCK(lock->write_lock); }