Example #1
0
ALCboolean alc_oss_init(BackendFuncs *func_list)
{
    ConfigValueStr("oss", "device", &oss_driver);
    ConfigValueStr("oss", "capture", &oss_capture);

    *func_list = oss_funcs;
    return ALC_TRUE;
}
Example #2
0
ALCboolean alc_solaris_init(BackendFuncs *func_list)
{
    ConfigValueStr("solaris", "device", &solaris_driver);

    *func_list = solaris_funcs;
    return ALC_TRUE;
}
Example #3
0
File: alsa.c Project: 9heart/DT3
static ALCenum alsa_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
    const char *driver = "default";
    alsa_data *data;
    char str[128];
    int i;

    ConfigValueStr("alsa", "device", &driver);

    if(!deviceName)
        deviceName = alsaDevice;
    else if(strcmp(deviceName, alsaDevice) != 0)
    {
        size_t idx;

        if(!allDevNameMap)
            allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames);

        for(idx = 0;idx < numDevNames;idx++)
        {
            if(allDevNameMap[idx].name &&
               strcmp(deviceName, allDevNameMap[idx].name) == 0)
            {
                if(idx > 0)
                {
                    snprintf(str, sizeof(str), "%sCARD=%s,DEV=%d", device_prefix,
                             allDevNameMap[idx].card, allDevNameMap[idx].dev);
                    driver = str;
                }
                break;
            }
        }
        if(idx == numDevNames)
            return ALC_INVALID_VALUE;
    }

    data = (alsa_data*)calloc(1, sizeof(alsa_data));

    i = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
    if(i >= 0)
    {
        i = snd_pcm_nonblock(data->pcmHandle, 0);
        if(i < 0)
            snd_pcm_close(data->pcmHandle);
    }
    if(i < 0)
    {
        free(data);
        ERR("Could not open playback device '%s': %s\n", driver, snd_strerror(i));
        return ALC_OUT_OF_MEMORY;
    }

    device->szDeviceName = strdup(deviceName);
    device->ExtraData = data;
    return ALC_NO_ERROR;
}
Example #4
0
ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context)
{
    ALCdevice *device = context->Device;
    al_string fname = AL_STRING_INIT_STATIC();
    const char *namelist;

    if(device->DefaultSfont)
        return device->DefaultSfont;

    device->DefaultSfont = calloc(1, sizeof(device->DefaultSfont[0]));
    ALsoundfont_Construct(device->DefaultSfont);

    namelist = getenv("ALSOFT_SOUNDFONT");
    if(!namelist || !namelist[0])
        ConfigValueStr("midi", "soundfont", &namelist);
    while(namelist && namelist[0])
    {
        const char *next, *end;
        FILE *f;

        while(*namelist && (isspace(*namelist) || *namelist == ','))
            namelist++;
        if(!*namelist)
            break;
        next = strchr(namelist, ',');
        end = next ? next++ : (namelist+strlen(namelist));
        while(--end != namelist && isspace(*end)) {
        }
        if(end == namelist)
            continue;
        al_string_append_range(&fname, namelist, end+1);
        namelist = next;

        f = OpenDataFile(al_string_get_cstr(fname), "openal/soundfonts");
        if(f == NULL)
            ERR("Failed to open %s\n", al_string_get_cstr(fname));
        else
        {
            Reader reader;
            reader.cb = ALsoundfont_read;
            reader.ptr = f;
            reader.error = 0;
            TRACE("Loading %s\n", al_string_get_cstr(fname));
            loadSf2(&reader, device->DefaultSfont, context);
            fclose(f);
        }

        al_string_clear(&fname);
    }
    AL_STRING_DEINIT(fname);

    return device->DefaultSfont;
}
Example #5
0
static struct Hrtf *LoadHrtf(ALuint deviceRate)
{
    const char *fnamelist = NULL;

    if(!ConfigValueStr(NULL, "hrtf_tables", &fnamelist))
        return NULL;
    while(*fnamelist != '\0')
    {
        struct Hrtf *Hrtf = NULL;
        char fname[PATH_MAX];
        ALchar magic[8];
        ALuint i;
        FILE *f;

        while(isspace(*fnamelist) || *fnamelist == ',')
            fnamelist++;
        i = 0;
        while(*fnamelist != '\0' && *fnamelist != ',')
        {
            const char *next = strpbrk(fnamelist, "%,");
            while(fnamelist != next && *fnamelist && i < sizeof(fname))
                fname[i++] = *(fnamelist++);

            if(!next || *next == ',')
                break;

            /* *next == '%' */
            next++;
            if(*next == 'r')
            {
                int wrote = snprintf(&fname[i], sizeof(fname)-i, "%u", deviceRate);
                i += minu(wrote, sizeof(fname)-i);
                next++;
            }
            else if(*next == '%')
            {
                if(i < sizeof(fname))
                    fname[i++] = '%';
                next++;
            }
            else
                ERR("Invalid marker '%%%c'\n", *next);
            fnamelist = next;
        }
        i = minu(i, sizeof(fname)-1);
        fname[i] = '\0';
        while(i > 0 && isspace(fname[i-1]))
            i--;
        fname[i] = '\0';

        if(fname[0] == '\0')
            continue;

        TRACE("Loading %s...\n", fname);
        f = fopen(fname, "rb");
        if(f == NULL)
        {
            ERR("Could not open %s\n", fname);
            continue;
        }

        if(fread(magic, 1, sizeof(magic), f) != sizeof(magic))
            ERR("Failed to read magic marker\n");
        else
        {
            if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0)
            {
                TRACE("Detected data set format v0\n");
                Hrtf = LoadHrtf00(f, deviceRate);
            }
            else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0)
            {
                TRACE("Detected data set format v1\n");
                Hrtf = LoadHrtf01(f, deviceRate);
            }
            else
                ERR("Invalid magic marker: \"%.8s\"\n", magic);
        }

        fclose(f);
        f = NULL;

        if(Hrtf)
        {
            Hrtf->next = LoadedHrtfs;
            LoadedHrtfs = Hrtf;
            TRACE("Loaded HRTF support for format: %s %uhz\n",
                  DevFmtChannelsString(DevFmtStereo), Hrtf->sampleRate);
            return Hrtf;
        }

        ERR("Failed to load %s\n", fname);
    }

    return NULL;
}
Example #6
0
static void probe_devices(snd_pcm_stream_t stream, vector_DevMap *DeviceList)
{
    const char *main_prefix = "plughw:";
    snd_ctl_t *handle;
    snd_ctl_card_info_t *info;
    snd_pcm_info_t *pcminfo;
    int card, err, dev;
    DevMap entry;

    clear_devlist(DeviceList);

    snd_ctl_card_info_malloc(&info);
    snd_pcm_info_malloc(&pcminfo);

    AL_STRING_INIT(entry.name);
    AL_STRING_INIT(entry.device_name);
    al_string_copy_cstr(&entry.name, alsaDevice);
    al_string_copy_cstr(&entry.device_name, GetConfigValue(NULL, "alsa", (stream==SND_PCM_STREAM_PLAYBACK) ?
                                                           "device" : "capture", "default"));
    VECTOR_PUSH_BACK(*DeviceList, entry);

    card = -1;
    if((err=snd_card_next(&card)) < 0)
        ERR("Failed to find a card: %s\n", snd_strerror(err));
    ConfigValueStr(NULL, "alsa", prefix_name(stream), &main_prefix);
    while(card >= 0)
    {
        const char *card_prefix = main_prefix;
        const char *cardname, *cardid;
        char name[256];

        snprintf(name, sizeof(name), "hw:%d", card);
        if((err = snd_ctl_open(&handle, name, 0)) < 0)
        {
            ERR("control open (hw:%d): %s\n", card, snd_strerror(err));
            goto next_card;
        }
        if((err = snd_ctl_card_info(handle, info)) < 0)
        {
            ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err));
            snd_ctl_close(handle);
            goto next_card;
        }

        cardname = snd_ctl_card_info_get_name(info);
        cardid = snd_ctl_card_info_get_id(info);

        snprintf(name, sizeof(name), "%s-%s", prefix_name(stream), cardid);
        ConfigValueStr(NULL, "alsa", name, &card_prefix);

        dev = -1;
        while(1)
        {
            const char *device_prefix = card_prefix;
            const char *devname;
            char device[128];

            if(snd_ctl_pcm_next_device(handle, &dev) < 0)
                ERR("snd_ctl_pcm_next_device failed\n");
            if(dev < 0)
                break;

            snd_pcm_info_set_device(pcminfo, dev);
            snd_pcm_info_set_subdevice(pcminfo, 0);
            snd_pcm_info_set_stream(pcminfo, stream);
            if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                if(err != -ENOENT)
                    ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err));
                continue;
            }

            devname = snd_pcm_info_get_name(pcminfo);

            snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev);
            ConfigValueStr(NULL, "alsa", name, &device_prefix);

            snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)",
                        cardname, devname, cardid, dev);
            snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d",
                        device_prefix, cardid, dev);

            TRACE("Got device \"%s\", \"%s\"\n", name, device);
            AL_STRING_INIT(entry.name);
            AL_STRING_INIT(entry.device_name);
            al_string_copy_cstr(&entry.name, name);
            al_string_copy_cstr(&entry.device_name, device);
            VECTOR_PUSH_BACK(*DeviceList, entry);
        }
        snd_ctl_close(handle);
    next_card:
        if(snd_card_next(&card) < 0) {
            ERR("snd_card_next failed\n");
            break;
        }
    }

    snd_pcm_info_free(pcminfo);
    snd_ctl_card_info_free(info);
}
void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf_appreq, enum HrtfRequestMode hrtf_userreq)
{
    const char *mode;
    bool headphones;
    int bs2blevel;
    size_t i;

    device->Hrtf = NULL;
    al_string_clear(&device->Hrtf_Name);
    device->Render_Mode = NormalRender;

    memset(&device->Dry.Ambi, 0, sizeof(device->Dry.Ambi));
    device->Dry.CoeffCount = 0;
    device->Dry.NumChannels = 0;

    if(device->FmtChans != DevFmtStereo)
    {
        ALuint speakermap[MAX_OUTPUT_CHANNELS];
        const char *devname, *layout = NULL;
        AmbDecConf conf, *pconf = NULL;

        if(hrtf_appreq == Hrtf_Enable)
            device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;

        ambdec_init(&conf);

        devname = al_string_get_cstr(device->DeviceName);
        switch(device->FmtChans)
        {
            case DevFmtQuad: layout = "quad"; break;
            case DevFmtX51: layout = "surround51"; break;
            case DevFmtX51Rear: layout = "surround51rear"; break;
            case DevFmtX61: layout = "surround61"; break;
            case DevFmtX71: layout = "surround71"; break;
            /* Mono, Stereo, and B-Fornat output don't use custom decoders. */
            case DevFmtMono:
            case DevFmtStereo:
            case DevFmtBFormat3D:
                break;
        }
        if(layout)
        {
            const char *fname;
            if(ConfigValueStr(devname, "decoder", layout, &fname))
            {
                if(!ambdec_load(&conf, fname))
                    ERR("Failed to load layout file %s\n", fname);
                else
                {
                    if(conf.ChanMask > 0xffff)
                        ERR("Unsupported channel mask 0x%04x (max 0xffff)\n", conf.ChanMask);
                    else
                    {
                        if(MakeSpeakerMap(device, &conf, speakermap))
                            pconf = &conf;
                    }
                }
            }
        }

        if(pconf && GetConfigValueBool(devname, "decoder", "hq-mode", 0))
        {
            if(!device->AmbiDecoder)
                device->AmbiDecoder = bformatdec_alloc();
        }
        else
        {
            bformatdec_free(device->AmbiDecoder);
            device->AmbiDecoder = NULL;
        }

        if(!pconf)
            InitPanning(device);
        else if(device->AmbiDecoder)
            InitHQPanning(device, pconf, speakermap);
        else
            InitCustomPanning(device, pconf, speakermap);

        ambdec_deinit(&conf);
        return;
    }

    bformatdec_free(device->AmbiDecoder);
    device->AmbiDecoder = NULL;

    headphones = device->IsHeadphones;
    if(device->Type != Loopback)
    {
        const char *mode;
        if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
        {
            if(strcasecmp(mode, "headphones") == 0)
                headphones = true;
            else if(strcasecmp(mode, "speakers") == 0)
                headphones = false;
            else if(strcasecmp(mode, "auto") != 0)
                ERR("Unexpected stereo-mode: %s\n", mode);
        }
    }

    if(hrtf_userreq == Hrtf_Default)
    {
        bool usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
                       (hrtf_appreq == Hrtf_Enable);
        if(!usehrtf) goto no_hrtf;

        device->Hrtf_Status = ALC_HRTF_ENABLED_SOFT;
        if(headphones && hrtf_appreq != Hrtf_Disable)
            device->Hrtf_Status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
    }
    else
    {
        if(hrtf_userreq != Hrtf_Enable)
        {
            if(hrtf_appreq == Hrtf_Enable)
                device->Hrtf_Status = ALC_HRTF_DENIED_SOFT;
            goto no_hrtf;
        }
        device->Hrtf_Status = ALC_HRTF_REQUIRED_SOFT;
    }

    if(VECTOR_SIZE(device->Hrtf_List) == 0)
    {
        VECTOR_DEINIT(device->Hrtf_List);
        device->Hrtf_List = EnumerateHrtf(device->DeviceName);
    }

    if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
    {
        const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
        if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
        {
            device->Hrtf = entry->hrtf;
            al_string_copy(&device->Hrtf_Name, entry->name);
        }
    }

    for(i = 0;!device->Hrtf && i < VECTOR_SIZE(device->Hrtf_List);i++)
    {
        const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
        if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
        {
            device->Hrtf = entry->hrtf;
            al_string_copy(&device->Hrtf_Name, entry->name);
        }
    }

    if(device->Hrtf)
    {
        device->Render_Mode = HrtfRender;
        if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
        {
            if(strcasecmp(mode, "full") == 0)
                device->Render_Mode = HrtfRender;
            else if(strcasecmp(mode, "basic") == 0)
                device->Render_Mode = NormalRender;
            else
                ERR("Unexpected hrtf-mode: %s\n", mode);
        }

        TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
        InitHrtfPanning(device);
        return;
    }
    device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;

no_hrtf:
    TRACE("HRTF disabled\n");

    bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
                 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
    if(device->Type != Loopback)
        ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
    if(bs2blevel > 0 && bs2blevel <= 6)
    {
        device->Bs2b = al_calloc(16, sizeof(*device->Bs2b));
        bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
        device->Render_Mode = StereoPair;
        TRACE("BS2B enabled\n");
        InitPanning(device);
        return;
    }

    TRACE("BS2B disabled\n");

    device->Render_Mode = NormalRender;
    if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-panning", &mode))
    {
        if(strcasecmp(mode, "paired") == 0)
            device->Render_Mode = StereoPair;
        else if(strcasecmp(mode, "uhj") != 0)
            ERR("Unexpected stereo-panning: %s\n", mode);
    }
    if(device->Render_Mode == NormalRender)
    {
        device->Uhj_Encoder = al_calloc(16, sizeof(Uhj2Encoder));
        TRACE("UHJ enabled\n");
        InitUhjPanning(device);
        return;
    }

    TRACE("UHJ disabled\n");
    InitPanning(device);
}
Example #8
0
static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count)
{
    const char *main_prefix = "plughw:";
    snd_ctl_t *handle;
    int card, err, dev, idx;
    snd_ctl_card_info_t *info;
    snd_pcm_info_t *pcminfo;
    DevMap *DevList;

    snd_ctl_card_info_malloc(&info);
    snd_pcm_info_malloc(&pcminfo);

    DevList = malloc(sizeof(DevMap) * 1);
    DevList[0].name = strdup(alsaDevice);
    DevList[0].device = strdup(GetConfigValue("alsa", (stream==SND_PCM_STREAM_PLAYBACK) ?
                                                      "device" : "capture", "default"));
    idx = 1;

    card = -1;
    if((err=snd_card_next(&card)) < 0)
        ERR("Failed to find a card: %s\n", snd_strerror(err));
    ConfigValueStr("alsa", prefix_name(stream), &main_prefix);
    while(card >= 0)
    {
        const char *card_prefix = main_prefix;
        const char *cardname, *cardid;
        char name[256];

        snprintf(name, sizeof(name), "hw:%d", card);
        if((err = snd_ctl_open(&handle, name, 0)) < 0)
        {
            ERR("control open (hw:%d): %s\n", card, snd_strerror(err));
            goto next_card;
        }
        if((err = snd_ctl_card_info(handle, info)) < 0)
        {
            ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err));
            snd_ctl_close(handle);
            goto next_card;
        }

        cardname = snd_ctl_card_info_get_name(info);
        cardid = snd_ctl_card_info_get_id(info);

        snprintf(name, sizeof(name), "%s-%s", prefix_name(stream), cardid);
        ConfigValueStr("alsa", name, &card_prefix);

        dev = -1;
        while(1)
        {
            const char *devname;
            void *temp;

            if(snd_ctl_pcm_next_device(handle, &dev) < 0)
                ERR("snd_ctl_pcm_next_device failed\n");
            if(dev < 0)
                break;

            snd_pcm_info_set_device(pcminfo, dev);
            snd_pcm_info_set_subdevice(pcminfo, 0);
            snd_pcm_info_set_stream(pcminfo, stream);
            if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
                if(err != -ENOENT)
                    ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err));
                continue;
            }

            temp = realloc(DevList, sizeof(DevMap) * (idx+1));
            if(temp)
            {
                const char *device_prefix = card_prefix;
                char device[128];

                DevList = temp;
                devname = snd_pcm_info_get_name(pcminfo);

                snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev);
                ConfigValueStr("alsa", name, &device_prefix);

                snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)",
                         cardname, devname, cardid, dev);
                snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d",
                         device_prefix, cardid, dev);

                TRACE("Got device \"%s\", \"%s\"\n", name, device);
                DevList[idx].name = strdup(name);
                DevList[idx].device = strdup(device);
                idx++;
            }
        }
        snd_ctl_close(handle);
    next_card:
        if(snd_card_next(&card) < 0) {
            ERR("snd_card_next failed\n");
            break;
        }
    }

    snd_pcm_info_free(pcminfo);
    snd_ctl_card_info_free(info);

    *count = idx;
    return DevList;
}
Example #9
0
void InitHrtf(void)
{
    char *fnamelist=NULL, *next=NULL;
    const char *val;

    if(ConfigValueStr(NULL, "hrtf_tables", &val))
        next = fnamelist = strdup(val);
    while(next && *next)
    {
        const ALubyte maxDelay = SRC_HISTORY_LENGTH-1;
        struct Hrtf newdata;
        ALboolean failed;
        ALchar magic[9];
        ALsizei i, j;
        char *fname;
        FILE *f;

        fname = next;
        next = strchr(fname, ',');
        if(next)
        {
            while(next != fname)
            {
                next--;
                if(!isspace(*next))
                {
                    *(next++) = '\0';
                    break;
                }
            }
            while(isspace(*next) || *next == ',')
                next++;
        }

        if(!fname[0])
            continue;
        TRACE("Loading %s\n", fname);
        f = fopen(fname, "rb");
        if(f == NULL)
        {
            ERR("Could not open %s\n", fname);
            continue;
        }

        failed = AL_FALSE;
        if(fread(magic, 1, sizeof(magicMarker), f) != sizeof(magicMarker))
        {
            ERR("Failed to read magic marker\n");
            failed = AL_TRUE;
        }
        else if(memcmp(magic, magicMarker, sizeof(magicMarker)) != 0)
        {
            magic[8] = 0;
            ERR("Invalid magic marker: \"%s\"\n", magic);
            failed = AL_TRUE;
        }

        if(!failed)
        {
            ALushort hrirCount, hrirSize;
            ALubyte  evCount;

            newdata.sampleRate  = fgetc(f);
            newdata.sampleRate |= fgetc(f)<<8;
            newdata.sampleRate |= fgetc(f)<<16;
            newdata.sampleRate |= fgetc(f)<<24;

            hrirCount  = fgetc(f);
            hrirCount |= fgetc(f)<<8;

            hrirSize  = fgetc(f);
            hrirSize |= fgetc(f)<<8;

            evCount = fgetc(f);

            if(hrirCount != HRIR_COUNT || hrirSize != HRIR_LENGTH || evCount != ELEV_COUNT)
            {
                ERR("Unsupported value: hrirCount=%d (%d), hrirSize=%d (%d), evCount=%d (%d)\n",
                    hrirCount, HRIR_COUNT, hrirSize, HRIR_LENGTH, evCount, ELEV_COUNT);
                failed = AL_TRUE;
            }
        }

        if(!failed)
        {
            for(i = 0;i < ELEV_COUNT;i++)
            {
                ALushort offset;
                offset  = fgetc(f);
                offset |= fgetc(f)<<8;
                if(offset != evOffset[i])
                {
                    ERR("Unsupported evOffset[%d] value: %d (%d)\n", i, offset, evOffset[i]);
                    failed = AL_TRUE;
                }
            }
        }

        if(!failed)
        {
            for(i = 0;i < HRIR_COUNT;i++)
            {
                for(j = 0;j < HRIR_LENGTH;j++)
                {
                    ALshort coeff;
                    coeff  = fgetc(f);
                    coeff |= fgetc(f)<<8;
                    newdata.coeffs[i][j] = coeff;
                }
            }
            for(i = 0;i < HRIR_COUNT;i++)
            {
                ALubyte delay;
                delay = fgetc(f);
                newdata.delays[i] = delay;
                if(delay > maxDelay)
                {
                    ERR("Invalid delay[%d]: %d (%d)\n", i, delay, maxDelay);
                    failed = AL_TRUE;
                }
            }

            if(feof(f))
            {
                ERR("Premature end of data\n");
                failed = AL_TRUE;
            }
        }

        fclose(f);
        f = NULL;

        if(!failed)
        {
            void *temp = realloc(LoadedHrtfs, (NumLoadedHrtfs+1)*sizeof(LoadedHrtfs[0]));
            if(temp != NULL)
            {
                LoadedHrtfs = temp;
                TRACE("Loaded HRTF support for format: %s %uhz\n",
                      DevFmtChannelsString(DevFmtStereo), newdata.sampleRate);
                LoadedHrtfs[NumLoadedHrtfs++] = newdata;
            }
        }
        else
            ERR("Failed to load %s\n", fname);
    }
    free(fnamelist);
    fnamelist = NULL;
}
Example #10
0
File: panning.c Project: 9heart/DT3
static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHANNELS],
                                  enum Channel Speaker2Chan[MAXCHANNELS], ALint chans)
{
    char *confkey, *next;
    char *layout_str;
    char *sep, *end;
    enum Channel val;
    const char *str;
    int i;

    if(!ConfigValueStr(NULL, name, &str) && !ConfigValueStr(NULL, "layout", &str))
        return;

    layout_str = strdup(str);
    next = confkey = layout_str;
    while(next && *next)
    {
        confkey = next;
        next = strchr(confkey, ',');
        if(next)
        {
            *next = 0;
            do {
                next++;
            } while(isspace(*next) || *next == ',');
        }

        sep = strchr(confkey, '=');
        if(!sep || confkey == sep)
        {
            ERR("Malformed speaker key: %s\n", confkey);
            continue;
        }

        end = sep - 1;
        while(isspace(*end) && end != confkey)
            end--;
        *(++end) = 0;

        if(strcmp(confkey, "fl") == 0 || strcmp(confkey, "front-left") == 0)
            val = FRONT_LEFT;
        else if(strcmp(confkey, "fr") == 0 || strcmp(confkey, "front-right") == 0)
            val = FRONT_RIGHT;
        else if(strcmp(confkey, "fc") == 0 || strcmp(confkey, "front-center") == 0)
            val = FRONT_CENTER;
        else if(strcmp(confkey, "bl") == 0 || strcmp(confkey, "back-left") == 0)
            val = BACK_LEFT;
        else if(strcmp(confkey, "br") == 0 || strcmp(confkey, "back-right") == 0)
            val = BACK_RIGHT;
        else if(strcmp(confkey, "bc") == 0 || strcmp(confkey, "back-center") == 0)
            val = BACK_CENTER;
        else if(strcmp(confkey, "sl") == 0 || strcmp(confkey, "side-left") == 0)
            val = SIDE_LEFT;
        else if(strcmp(confkey, "sr") == 0 || strcmp(confkey, "side-right") == 0)
            val = SIDE_RIGHT;
        else
        {
            ERR("Unknown speaker for %s: \"%s\"\n", name, confkey);
            continue;
        }

        *(sep++) = 0;
        while(isspace(*sep))
            sep++;

        for(i = 0;i < chans;i++)
        {
            if(Speaker2Chan[i] == val)
            {
                long angle = strtol(sep, NULL, 10);
                if(angle >= -180 && angle <= 180)
                    SpeakerAngle[i] = angle * F_PI/180.0f;
                else
                    ERR("Invalid angle for speaker \"%s\": %ld\n", confkey, angle);
                break;
            }
        }
    }
    free(layout_str);
    layout_str = NULL;

    for(i = 0;i < chans;i++)
    {
        int min = i;
        int i2;

        for(i2 = i+1;i2 < chans;i2++)
        {
            if(SpeakerAngle[i2] < SpeakerAngle[min])
                min = i2;
        }

        if(min != i)
        {
            ALfloat tmpf;
            enum Channel tmpc;

            tmpf = SpeakerAngle[i];
            SpeakerAngle[i] = SpeakerAngle[min];
            SpeakerAngle[min] = tmpf;

            tmpc = Speaker2Chan[i];
            Speaker2Chan[i] = Speaker2Chan[min];
            Speaker2Chan[min] = tmpc;
        }
    }
}
Example #11
0
int MOB_File_ConfigValueStr(const char *blockName, const char *keyName, const char **ret)
{
	char buffer[ 64 ];
	return ConfigValueStr( ConvertBlockName( blockName ), ConvertKeyName( buffer, keyName ), ret );
}
Example #12
0
int MOB_ConfigValueStr_KeyStr(const char *blockName, const char *keyName, const char **ret)
{
	return ConfigValueStr( blockName, keyName, ret );
}
Example #13
0
static bool LoadChannelSetup(ALCdevice *device)
{
    static const enum Channel mono_chans[1] = {
        FrontCenter
    }, stereo_chans[2] = {
        FrontLeft, FrontRight
    }, quad_chans[4] = {
        FrontLeft, FrontRight,
        BackLeft, BackRight
    }, surround51_chans[5] = {
        FrontLeft, FrontRight, FrontCenter,
        SideLeft, SideRight
    }, surround51rear_chans[5] = {
        FrontLeft, FrontRight, FrontCenter,
        BackLeft, BackRight
    }, surround61_chans[6] = {
        FrontLeft, FrontRight,
        FrontCenter, BackCenter,
        SideLeft, SideRight
    }, surround71_chans[7] = {
        FrontLeft, FrontRight, FrontCenter,
        BackLeft, BackRight,
        SideLeft, SideRight
    };
    ChannelMap chanmap[MAX_OUTPUT_CHANNELS];
    const enum Channel *channels = NULL;
    const char *layout = NULL;
    ALfloat ambiscale = 1.0f;
    size_t count = 0;
    int isfuma;
    int order;
    size_t i;

    switch(device->FmtChans)
    {
        case DevFmtMono:
            layout = "mono";
            channels = mono_chans;
            count = COUNTOF(mono_chans);
            break;
        case DevFmtStereo:
            layout = "stereo";
            channels = stereo_chans;
            count = COUNTOF(stereo_chans);
            break;
        case DevFmtQuad:
            layout = "quad";
            channels = quad_chans;
            count = COUNTOF(quad_chans);
            break;
        case DevFmtX51:
            layout = "surround51";
            channels = surround51_chans;
            count = COUNTOF(surround51_chans);
            break;
        case DevFmtX51Rear:
            layout = "surround51rear";
            channels = surround51rear_chans;
            count = COUNTOF(surround51rear_chans);
            break;
        case DevFmtX61:
            layout = "surround61";
            channels = surround61_chans;
            count = COUNTOF(surround61_chans);
            break;
        case DevFmtX71:
            layout = "surround71";
            channels = surround71_chans;
            count = COUNTOF(surround71_chans);
            break;
        case DevFmtBFormat3D:
            break;
    }

    if(!layout)
        return false;
    else
    {
        char name[32] = {0};
        const char *type;
        char eol;

        snprintf(name, sizeof(name), "%s/type", layout);
        if(!ConfigValueStr(al_string_get_cstr(device->DeviceName), "layouts", name, &type))
            return false;

        if(sscanf(type, " %31[^: ] : %d%c", name, &order, &eol) != 2)
        {
            ERR("Invalid type value '%s' (expected name:order) for layout %s\n", type, layout);
            return false;
        }

        if(strcasecmp(name, "fuma") == 0)
            isfuma = 1;
        else if(strcasecmp(name, "n3d") == 0)
            isfuma = 0;
        else
        {
            ERR("Unhandled type name '%s' (expected FuMa or N3D) for layout %s\n", name, layout);
            return false;
        }

        if(order == 3)
            ambiscale = THIRD_ORDER_SCALE;
        else if(order == 2)
            ambiscale = SECOND_ORDER_SCALE;
        else if(order == 1)
            ambiscale = FIRST_ORDER_SCALE;
        else if(order == 0)
            ambiscale = ZERO_ORDER_SCALE;
        else
        {
            ERR("Unhandled type order %d (expected 0, 1, 2, or 3) for layout %s\n", order, layout);
            return false;
        }
    }

    for(i = 0;i < count;i++)
    {
        float coeffs[MAX_AMBI_COEFFS] = {0.0f};
        const char *channame;
        char chanlayout[32];
        const char *value;
        int props = 0;
        char eol = 0;
        int j;

        chanmap[i].ChanName = channels[i];
        channame = GetLabelFromChannel(channels[i]);

        snprintf(chanlayout, sizeof(chanlayout), "%s/%s", layout, channame);
        if(!ConfigValueStr(al_string_get_cstr(device->DeviceName), "layouts", chanlayout, &value))
        {
            ERR("Missing channel %s\n", channame);
            return false;
        }
        if(order == 3)
            props = sscanf(value, " %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %c",
                &coeffs[0],  &coeffs[1],  &coeffs[2],  &coeffs[3],
                &coeffs[4],  &coeffs[5],  &coeffs[6],  &coeffs[7],
                &coeffs[8],  &coeffs[9],  &coeffs[10], &coeffs[11],
                &coeffs[12], &coeffs[13], &coeffs[14], &coeffs[15],
                &eol
            );
        else if(order == 2)
            props = sscanf(value, " %f %f %f %f %f %f %f %f %f %c",
                &coeffs[0], &coeffs[1], &coeffs[2],
                &coeffs[3], &coeffs[4], &coeffs[5],
                &coeffs[6], &coeffs[7], &coeffs[8],
                &eol
            );
        else if(order == 1)
            props = sscanf(value, " %f %f %f %f %c",
                &coeffs[0], &coeffs[1],
                &coeffs[2], &coeffs[3],
                &eol
            );
        else if(order == 0)
            props = sscanf(value, " %f %c", &coeffs[0], &eol);
        if(props == 0)
        {
            ERR("Failed to parse option %s properties\n", chanlayout);
            return false;
        }

        if(props > (order+1)*(order+1))
        {
            ERR("Excess elements in option %s (expected %d)\n", chanlayout, (order+1)*(order+1));
            return false;
        }

        if(isfuma)
        {
            /* Reorder FuMa -> ACN */
            for(j = 0;j < MAX_AMBI_COEFFS;++j)
                chanmap[i].Config[FuMa2ACN[j]] = coeffs[j];
        }
        else
        {
            /* Rescale N3D -> FuMa */
            for(j = 0;j < MAX_AMBI_COEFFS;++j)
                chanmap[i].Config[j] = coeffs[j] * N3D2FuMaScale[j];
        }
    }
    SetChannelMap(device, chanmap, count, ambiscale);
    return true;
}
Example #14
0
File: alsa.c Project: 9heart/DT3
static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
{
    const char *driver = "default";
    snd_pcm_hw_params_t *p;
    snd_pcm_uframes_t bufferSizeInFrames;
    snd_pcm_uframes_t periodSizeInFrames;
    snd_pcm_format_t format;
    ALuint frameSize;
    alsa_data *data;
    char str[128];
    char *err;
    int i;

    ConfigValueStr("alsa", "capture", &driver);

    if(!allCaptureDevNameMap)
        allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames);

    if(!deviceName)
        deviceName = allCaptureDevNameMap[0].name;
    else
    {
        size_t idx;

        for(idx = 0;idx < numCaptureDevNames;idx++)
        {
            if(allCaptureDevNameMap[idx].name &&
               strcmp(deviceName, allCaptureDevNameMap[idx].name) == 0)
            {
                if(idx > 0)
                {
                    snprintf(str, sizeof(str), "%sCARD=%s,DEV=%d", capture_prefix,
                             allCaptureDevNameMap[idx].card, allCaptureDevNameMap[idx].dev);
                    driver = str;
                }
                break;
            }
        }
        if(idx == numCaptureDevNames)
            return ALC_INVALID_VALUE;
    }

    data = (alsa_data*)calloc(1, sizeof(alsa_data));

    i = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
    if(i < 0)
    {
        ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(i));
        free(data);
        return ALC_INVALID_VALUE;
    }

    format = -1;
    switch(pDevice->FmtType)
    {
        case DevFmtByte:
            format = SND_PCM_FORMAT_S8;
            break;
        case DevFmtUByte:
            format = SND_PCM_FORMAT_U8;
            break;
        case DevFmtShort:
            format = SND_PCM_FORMAT_S16;
            break;
        case DevFmtUShort:
            format = SND_PCM_FORMAT_U16;
            break;
        case DevFmtFloat:
            format = SND_PCM_FORMAT_FLOAT;
            break;
    }

    err = NULL;
    bufferSizeInFrames = maxu(pDevice->UpdateSize*pDevice->NumUpdates,
                              100*pDevice->Frequency/1000);
    periodSizeInFrames = minu(bufferSizeInFrames, 50*pDevice->Frequency/1000);
    snd_pcm_hw_params_malloc(&p);

    if((i=snd_pcm_hw_params_any(data->pcmHandle, p)) < 0)
        err = "any";
    /* set interleaved access */
    if(i >= 0 && (i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
        err = "set access";
    /* set format (implicitly sets sample bits) */
    if(i >= 0 && (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, format)) < 0)
        err = "set format";
    /* set channels (implicitly sets frame bits) */
    if(i >= 0 && (i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, ChannelsFromDevFmt(pDevice->FmtChans))) < 0)
        err = "set channels";
    /* set rate (implicitly constrains period/buffer parameters) */
    if(i >= 0 && (i=snd_pcm_hw_params_set_rate(data->pcmHandle, p, pDevice->Frequency, 0)) < 0)
        err = "set rate near";
    /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
    if(i >= 0 && (i=snd_pcm_hw_params_set_buffer_size_near(data->pcmHandle, p, &bufferSizeInFrames)) < 0)
        err = "set buffer size near";
    /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
    if(i >= 0 && (i=snd_pcm_hw_params_set_period_size_near(data->pcmHandle, p, &periodSizeInFrames, NULL)) < 0)
        err = "set period size near";
    /* install and prepare hardware configuration */
    if(i >= 0 && (i=snd_pcm_hw_params(data->pcmHandle, p)) < 0)
        err = "set params";
    if(i < 0)
    {
        ERR("%s failed: %s\n", err, snd_strerror(i));
        snd_pcm_hw_params_free(p);
        goto error;
    }

    if((i=snd_pcm_hw_params_get_period_size(p, &bufferSizeInFrames, NULL)) < 0)
    {
        ERR("get size failed: %s\n", snd_strerror(i));
        snd_pcm_hw_params_free(p);
        goto error;
    }

    snd_pcm_hw_params_free(p);

    frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);

    data->ring = CreateRingBuffer(frameSize, pDevice->UpdateSize*pDevice->NumUpdates);
    if(!data->ring)
    {
        ERR("ring buffer create failed\n");
        goto error;
    }

    data->size = snd_pcm_frames_to_bytes(data->pcmHandle, bufferSizeInFrames);
    data->buffer = malloc(data->size);
    if(!data->buffer)
    {
        ERR("buffer malloc failed\n");
        goto error;
    }

    pDevice->szDeviceName = strdup(deviceName);

    pDevice->ExtraData = data;
    return ALC_NO_ERROR;

error:
    free(data->buffer);
    DestroyRingBuffer(data->ring);
    snd_pcm_close(data->pcmHandle);
    free(data);

    pDevice->ExtraData = NULL;
    return ALC_INVALID_VALUE;
}