Пример #1
0
AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value)
{
    ALCdevice *device;
    ALCcontext *context;
    ALbuffer *albuf;

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    if((albuf=LookupBuffer(device, buffer)) == NULL)
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);

    switch(param)
    {
    case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
        if(!(value >= 0))
            SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
        ExchangeInt(&albuf->UnpackAlign, value);
        break;

    case AL_PACK_BLOCK_ALIGNMENT_SOFT:
        if(!(value >= 0))
            SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
        ExchangeInt(&albuf->PackAlign, value);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}
Пример #2
0
AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
{
    ALCcontext *Context;

    Context = GetContextRef();
    if(!Context) return;

    if(ExchangeInt(&Context->DeferUpdates, AL_FALSE))
    {
        ALsizei pos;

        LockContext(Context);
        LockUIntMapRead(&Context->SourceMap);
        for(pos = 0;pos < Context->SourceMap.size;pos++)
        {
            ALsource *Source = Context->SourceMap.array[pos].value;
            ALenum new_state;

            if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
               Source->Offset >= 0.0)
                ApplyOffset(Source);

            new_state = ExchangeInt(&Source->new_state, AL_NONE);
            if(new_state)
                SetSourceState(Source, Context, new_state);
        }
        UnlockUIntMapRead(&Context->SourceMap);
        UnlockContext(Context);
    }

    ALCcontext_DecRef(Context);
}
Пример #3
0
AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
{
    ALCcontext *Context;

    Context = GetContextRef();
    if(!Context) return;

    if(!Context->DeferUpdates)
    {
        ALboolean UpdateSources;
        ALsource **src, **src_end;
        ALeffectslot **slot, **slot_end;
        FPUCtl oldMode;

        SetMixerFPUMode(&oldMode);

        LockContext(Context);
        Context->DeferUpdates = AL_TRUE;

        /* Make sure all pending updates are performed */
        UpdateSources = ExchangeInt(&Context->UpdateSources, AL_FALSE);

        src = Context->ActiveSources;
        src_end = src + Context->ActiveSourceCount;
        while(src != src_end)
        {
            if((*src)->state != AL_PLAYING)
            {
                Context->ActiveSourceCount--;
                *src = *(--src_end);
                continue;
            }

            if(ExchangeInt(&(*src)->NeedsUpdate, AL_FALSE) || UpdateSources)
                ALsource_Update(*src, Context);

            src++;
        }

        slot = Context->ActiveEffectSlots;
        slot_end = slot + Context->ActiveEffectSlotCount;
        while(slot != slot_end)
        {
            if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE))
                VCALL((*slot)->EffectState,update,(Context->Device, *slot));
            slot++;
        }

        UnlockContext(Context);
        RestoreFPUMode(&oldMode);
    }

    ALCcontext_DecRef(Context);
}
Пример #4
0
void FreeThunkEntry(ALuint index)
{
    ReadLock(&ThunkLock);
    if(index > 0 && index <= ThunkArraySize)
        ExchangeInt(&ThunkArray[index-1], AL_FALSE);
    ReadUnlock(&ThunkLock);
}
Пример #5
0
ALenum NewThunkEntry(ALuint *index)
{
    ALenum *NewList;
    ALuint i;

    ReadLock(&ThunkLock);
    for(i = 0;i < ThunkArraySize;i++)
    {
        if(ExchangeInt(&ThunkArray[i], AL_TRUE) == AL_FALSE)
        {
            ReadUnlock(&ThunkLock);
            *index = i+1;
            return AL_NO_ERROR;
        }
    }
    ReadUnlock(&ThunkLock);

    WriteLock(&ThunkLock);
    NewList = realloc(ThunkArray, ThunkArraySize*2 * sizeof(*ThunkArray));
    if(!NewList)
    {
        WriteUnlock(&ThunkLock);
        ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2);
        return AL_OUT_OF_MEMORY;
    }
    memset(&NewList[ThunkArraySize], 0, ThunkArraySize*sizeof(*ThunkArray));
    ThunkArraySize *= 2;
    ThunkArray = NewList;

    ThunkArray[i] = AL_TRUE;
    WriteUnlock(&ThunkLock);

    *index = i+1;
    return AL_NO_ERROR;
}
Пример #6
0
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;
}
Пример #7
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);
}
Пример #8
0
AL_API ALenum AL_APIENTRY alGetError(void)
{
    ALCcontext *Context;
    ALenum errorCode;

    Context = GetContextRef();
    if(!Context) return AL_INVALID_OPERATION;

    errorCode = ExchangeInt(&Context->LastError, AL_NO_ERROR);

    ALCcontext_DecRef(Context);

    return errorCode;
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
static inline void MidiSynth_setState(MidiSynth *self, ALenum state)
{
    ExchangeInt(&self->State, state);
}
Пример #12
0
static void Unlock(volatile ALenum *l)
{
    ExchangeInt(l, AL_FALSE);
}
Пример #13
0
static void Lock(volatile ALenum *l)
{
    while(ExchangeInt(l, AL_TRUE) == AL_TRUE)
        sched_yield();
}
Пример #14
0
static void Lock(volatile ALenum *l)
{
    while(ExchangeInt(l, AL_TRUE) == AL_TRUE)
        Sleep(0);
}