예제 #1
0
static void GenModList_accumGen(GenModList *self, const Generator *gen)
{
    Generator *i = VECTOR_ITER_BEGIN(self->gens);
    Generator *end = VECTOR_ITER_END(self->gens);
    for(;i != end;i++)
    {
        if(i->mGenerator == gen->mGenerator)
        {
            if(gen->mGenerator == 43 || gen->mGenerator == 44)
            {
                /* Range generators accumulate by taking the intersection of
                 * the two ranges.
                 */
                ALushort low = maxu(i->mAmount&0x00ff, gen->mAmount&0x00ff);
                ALushort high = minu(i->mAmount&0xff00, gen->mAmount&0xff00);
                i->mAmount = low | high;
            }
            else
                i->mAmount += gen->mAmount;
            return;
        }
    }

    if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE)
    {
        ERR("Failed to insert generator (from %d elements)\n", VECTOR_SIZE(self->gens));
        return;
    }
    if(gen->mGenerator < 60)
        VECTOR_BACK(self->gens).mAmount += DefaultGenValue[gen->mGenerator];
}
예제 #2
0
static void RemoveEffectSlotArray(ALCcontext *context, const ALeffectslot *slot)
{
    ALeffectslot **iter;

    LockContext(context);
#define MATCH_SLOT(_i)  (slot == *(_i))
    VECTOR_FIND_IF(iter, ALeffectslot*, context->ActiveAuxSlots, MATCH_SLOT);
    if(iter != VECTOR_ITER_END(context->ActiveAuxSlots))
    {
        *iter = VECTOR_BACK(context->ActiveAuxSlots);
        VECTOR_POP_BACK(context->ActiveAuxSlots);
    }
#undef MATCH_SLOT
    UnlockContext(context);
}
예제 #3
0
static void GenModList_accumMod(GenModList *self, const Modulator *mod)
{
    Modulator *i = VECTOR_ITER_BEGIN(self->mods);
    Modulator *end = VECTOR_ITER_END(self->mods);
    for(;i != end;i++)
    {
        if(i->mDstOp == mod->mDstOp && i->mSrcOp == mod->mSrcOp &&
           i->mAmtSrcOp == mod->mAmtSrcOp && i->mTransOp == mod->mTransOp)
        {
            i->mAmount += mod->mAmount;
            return;
        }
    }

    if(VECTOR_PUSH_BACK(self->mods, *mod) == AL_FALSE)
    {
        ERR("Failed to insert modulator (from %d elements)\n", VECTOR_SIZE(self->mods));
        return;
    }

    if(mod->mSrcOp == 0x0502 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 960;
    else if(mod->mSrcOp == 0x0102 && mod->mDstOp == 8 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += -2400;
    else if(mod->mSrcOp == 0x000D && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 50;
    else if(mod->mSrcOp == 0x0081 && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 50;
    else if(mod->mSrcOp == 0x0582 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 960;
    else if(mod->mSrcOp == 0x028A && mod->mDstOp == 17 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 1000;
    else if(mod->mSrcOp == 0x058B && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 960;
    else if(mod->mSrcOp == 0x00DB && mod->mDstOp == 16 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 200;
    else if(mod->mSrcOp == 0x00DD && mod->mDstOp == 15 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 200;
    /*else if(mod->mSrcOp == 0x020E && mod->mDstOp == ?initialpitch? && mod->mAmtSrcOp == 0x0010 && mod->mTransOp == 0)
        VECTOR_BACK(self->mods).mAmount += 12700;*/
}
예제 #4
0
static ALeffect *AllocEffect(ALCcontext *context)
{
    ALCdevice *device = context->Device;
    EffectSubList *sublist, *subend;
    ALeffect *effect = NULL;
    ALsizei lidx = 0;
    ALsizei slidx;

    almtx_lock(&device->EffectLock);
    sublist = VECTOR_BEGIN(device->EffectList);
    subend = VECTOR_END(device->EffectList);
    for(;sublist != subend;++sublist)
    {
        if(sublist->FreeMask)
        {
            slidx = CTZ64(sublist->FreeMask);
            effect = sublist->Effects + slidx;
            break;
        }
        ++lidx;
    }
    if(UNLIKELY(!effect))
    {
        const EffectSubList empty_sublist = { 0, NULL };
        /* Don't allocate so many list entries that the 32-bit ID could
         * overflow...
         */
        if(UNLIKELY(VECTOR_SIZE(device->EffectList) >= 1<<25))
        {
            almtx_unlock(&device->EffectLock);
            alSetError(context, AL_OUT_OF_MEMORY, "Too many effects allocated");
            return NULL;
        }
        lidx = (ALsizei)VECTOR_SIZE(device->EffectList);
        VECTOR_PUSH_BACK(device->EffectList, empty_sublist);
        sublist = &VECTOR_BACK(device->EffectList);
        sublist->FreeMask = ~U64(0);
        sublist->Effects = al_calloc(16, sizeof(ALeffect)*64);
        if(UNLIKELY(!sublist->Effects))
        {
            VECTOR_POP_BACK(device->EffectList);
            almtx_unlock(&device->EffectLock);
            alSetError(context, AL_OUT_OF_MEMORY, "Failed to allocate effect batch");
            return NULL;
        }

        slidx = 0;
        effect = sublist->Effects + slidx;
    }

    memset(effect, 0, sizeof(*effect));
    InitEffectParams(effect, AL_EFFECT_NULL);

    /* Add 1 to avoid effect ID 0. */
    effect->id = ((lidx<<6) | slidx) + 1;

    sublist->FreeMask &= ~(U64(1)<<slidx);
    almtx_unlock(&device->EffectLock);

    return effect;
}
예제 #5
0
void ReadALConfig(void)
{
    al_string confpaths = AL_STRING_INIT_STATIC();
    al_string fname = AL_STRING_INIT_STATIC();
    const char *str;
    FILE *f;

    str = "/etc/openal/alsoft.conf";

    TRACE("Loading config %s...\n", str);
    f = al_fopen(str, "r");
    if(f)
    {
        LoadConfigFromFile(f);
        fclose(f);
    }

    if(!(str=getenv("XDG_CONFIG_DIRS")) || str[0] == 0)
        str = "/etc/xdg";
    alstr_copy_cstr(&confpaths, str);
    /* Go through the list in reverse, since "the order of base directories
     * denotes their importance; the first directory listed is the most
     * important". Ergo, we need to load the settings from the later dirs
     * first so that the settings in the earlier dirs override them.
     */
    while(!alstr_empty(confpaths))
    {
        char *next = strrchr(alstr_get_cstr(confpaths), ':');
        if(next)
        {
            size_t len = next - alstr_get_cstr(confpaths);
            alstr_copy_cstr(&fname, next+1);
            VECTOR_RESIZE(confpaths, len, len+1);
            VECTOR_ELEM(confpaths, len) = 0;
        }
        else
        {
            alstr_reset(&fname);
            fname = confpaths;
            AL_STRING_INIT(confpaths);
        }

        if(alstr_empty(fname) || VECTOR_FRONT(fname) != '/')
            WARN("Ignoring XDG config dir: %s\n", alstr_get_cstr(fname));
        else
        {
            if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/alsoft.conf");
            else alstr_append_cstr(&fname, "alsoft.conf");

            TRACE("Loading config %s...\n", alstr_get_cstr(fname));
            f = al_fopen(alstr_get_cstr(fname), "r");
            if(f)
            {
                LoadConfigFromFile(f);
                fclose(f);
            }
        }
        alstr_clear(&fname);
    }

    if((str=getenv("HOME")) != NULL && *str)
    {
        alstr_copy_cstr(&fname, str);
        if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/.alsoftrc");
        else alstr_append_cstr(&fname, ".alsoftrc");

        TRACE("Loading config %s...\n", alstr_get_cstr(fname));
        f = al_fopen(alstr_get_cstr(fname), "r");
        if(f)
        {
            LoadConfigFromFile(f);
            fclose(f);
        }
    }

    if((str=getenv("XDG_CONFIG_HOME")) != NULL && str[0] != 0)
    {
        alstr_copy_cstr(&fname, str);
        if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/alsoft.conf");
        else alstr_append_cstr(&fname, "alsoft.conf");
    }
    else
    {
        alstr_clear(&fname);
        if((str=getenv("HOME")) != NULL && str[0] != 0)
        {
            alstr_copy_cstr(&fname, str);
            if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/.config/alsoft.conf");
            else alstr_append_cstr(&fname, ".config/alsoft.conf");
        }
    }
    if(!alstr_empty(fname))
    {
        TRACE("Loading config %s...\n", alstr_get_cstr(fname));
        f = al_fopen(alstr_get_cstr(fname), "r");
        if(f)
        {
            LoadConfigFromFile(f);
            fclose(f);
        }
    }

    alstr_clear(&fname);
    GetProcBinary(&fname, NULL);
    if(!alstr_empty(fname))
    {
        if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/alsoft.conf");
        else alstr_append_cstr(&fname, "alsoft.conf");

        TRACE("Loading config %s...\n", alstr_get_cstr(fname));
        f = al_fopen(alstr_get_cstr(fname), "r");
        if(f)
        {
            LoadConfigFromFile(f);
            fclose(f);
        }
    }

    if((str=getenv("ALSOFT_CONF")) != NULL && *str)
    {
        TRACE("Loading config %s...\n", str);
        f = al_fopen(str, "r");
        if(f)
        {
            LoadConfigFromFile(f);
            fclose(f);
        }
    }

    alstr_reset(&fname);
    alstr_reset(&confpaths);
}
예제 #6
0
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsizei cur;

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

    if(n < 0)
        SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effect slots", n);
    if(n == 0) goto done;

    LockEffectSlotList(context);
    device = context->Device;
    for(cur = 0;cur < n;cur++)
    {
        ALeffectslotPtr *iter = VECTOR_BEGIN(context->EffectSlotList);
        ALeffectslotPtr *end = VECTOR_END(context->EffectSlotList);
        ALeffectslot *slot = NULL;
        ALenum err = AL_OUT_OF_MEMORY;

        for(;iter != end;iter++)
        {
            if(!*iter)
                break;
        }
        if(iter == end)
        {
            if(device->AuxiliaryEffectSlotMax == VECTOR_SIZE(context->EffectSlotList))
            {
                UnlockEffectSlotList(context);
                alDeleteAuxiliaryEffectSlots(cur, effectslots);
                SETERR_GOTO(context, AL_OUT_OF_MEMORY, done,
                    "Exceeding %u auxiliary effect slot limit", device->AuxiliaryEffectSlotMax);
            }
            VECTOR_PUSH_BACK(context->EffectSlotList, NULL);
            iter = &VECTOR_BACK(context->EffectSlotList);
        }
        slot = al_calloc(16, sizeof(ALeffectslot));
        if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR)
        {
            al_free(slot);
            UnlockEffectSlotList(context);

            alDeleteAuxiliaryEffectSlots(cur, effectslots);
            SETERR_GOTO(context, err, done, "Effect slot object allocation failed");
        }
        aluInitEffectPanning(slot);

        slot->id = (iter - VECTOR_BEGIN(context->EffectSlotList)) + 1;
        *iter = slot;

        effectslots[cur] = slot->id;
    }
    AddActiveEffectSlots(effectslots, n, context);
    UnlockEffectSlotList(context);

done:
    ALCcontext_DecRef(context);
}
예제 #7
0
static ALfilter *AllocFilter(ALCcontext *context)
{
    ALCdevice *device = context->Device;
    FilterSubList *sublist, *subend;
    ALfilter *filter = NULL;
    ALsizei lidx = 0;
    ALsizei slidx;

    almtx_lock(&device->FilterLock);
    sublist = VECTOR_BEGIN(device->FilterList);
    subend = VECTOR_END(device->FilterList);
    for(;sublist != subend;++sublist)
    {
        if(sublist->FreeMask)
        {
            slidx = CTZ64(sublist->FreeMask);
            filter = sublist->Filters + slidx;
            break;
        }
        ++lidx;
    }
    if(UNLIKELY(!filter))
    {
        const FilterSubList empty_sublist = { 0, NULL };
        /* Don't allocate so many list entries that the 32-bit ID could
         * overflow...
         */
        if(UNLIKELY(VECTOR_SIZE(device->FilterList) >= 1<<25))
        {
            almtx_unlock(&device->FilterLock);
            alSetError(context, AL_OUT_OF_MEMORY, "Too many filters allocated");
            return NULL;
        }
        lidx = (ALsizei)VECTOR_SIZE(device->FilterList);
        VECTOR_PUSH_BACK(device->FilterList, empty_sublist);
        sublist = &VECTOR_BACK(device->FilterList);
        sublist->FreeMask = ~U64(0);
        sublist->Filters = al_calloc(16, sizeof(ALfilter)*64);
        if(UNLIKELY(!sublist->Filters))
        {
            VECTOR_POP_BACK(device->FilterList);
            almtx_unlock(&device->FilterLock);
            alSetError(context, AL_OUT_OF_MEMORY, "Failed to allocate filter batch");
            return NULL;
        }

        slidx = 0;
        filter = sublist->Filters + slidx;
    }

    memset(filter, 0, sizeof(*filter));
    InitFilterParams(filter, AL_FILTER_NULL);

    /* Add 1 to avoid filter ID 0. */
    filter->id = ((lidx<<6) | slidx) + 1;

    sublist->FreeMask &= ~(U64(1)<<slidx);
    almtx_unlock(&device->FilterLock);

    return filter;
}