Ejemplo n.º 1
0
void alc_alsa_probe(int type)
{
    snd_ctl_t *handle;
    int card, err, dev, idx;
    snd_ctl_card_info_t *info;
    snd_pcm_info_t *pcminfo;
    snd_pcm_stream_t stream;
    char name[128];
    ALuint i;

    if(!alsa_handle) alc_alsa_init(NULL);
    if(!alsa_handle) return;

    psnd_ctl_card_info_malloc(&info);
    psnd_pcm_info_malloc(&pcminfo);

    if(type == DEVICE_PROBE)
        AppendDeviceList(alsaDevice);
    else if(type == ALL_DEVICE_PROBE)
    {
        stream = SND_PCM_STREAM_PLAYBACK;
        card = -1;
        if(psnd_card_next(&card) < 0 || card < 0) {
            AL_PRINT("no playback cards found...\n");
            psnd_pcm_info_free(pcminfo);
            psnd_ctl_card_info_free(info);
            return;
        }

        for(i = 0;i < numDevNames;++i)
            free(allDevNameMap[i].name);

        allDevNameMap = realloc(allDevNameMap, sizeof(DevMap) * 1);
        allDevNameMap[0].name = strdup("ALSA Software on default");
        AppendAllDeviceList(allDevNameMap[0].name);

        idx = 1;
        while(card >= 0) {
            sprintf(name, "hw:%d", card);
            if ((err = psnd_ctl_open(&handle, name, 0)) < 0) {
                AL_PRINT("control open (%i): %s\n", card, psnd_strerror(err));
                goto next_card;
            }
            if ((err = psnd_ctl_card_info(handle, info)) < 0) {
                AL_PRINT("control hardware info (%i): %s\n", card, psnd_strerror(err));
                psnd_ctl_close(handle);
                goto next_card;
            }

            dev = -1;
            while(1) {
                const char *cname, *dname;
                void *temp;

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

                psnd_pcm_info_set_device(pcminfo, dev);
                psnd_pcm_info_set_subdevice(pcminfo, 0);
                psnd_pcm_info_set_stream(pcminfo, stream);
                if ((err = psnd_ctl_pcm_info(handle, pcminfo)) < 0) {
                    if (err != -ENOENT)
                        AL_PRINT("control digital audio info (%i): %s\n", card, psnd_strerror(err));
                    continue;
                }

                temp = realloc(allDevNameMap, sizeof(DevMap) * (idx+1));
                if(temp)
                {
                    allDevNameMap = temp;
                    cname = psnd_ctl_card_info_get_name(info);
                    dname = psnd_pcm_info_get_name(pcminfo);
                    snprintf(name, sizeof(name), "ALSA Software on %s [%s] (hw:%d,%d)",
                             cname, dname, card, dev);
                    AppendAllDeviceList(name);
                    allDevNameMap[idx].name = strdup(name);
                    allDevNameMap[idx].card = card;
                    allDevNameMap[idx].dev = dev;
                    idx++;
                }
            }
            psnd_ctl_close(handle);
        next_card:
            if(psnd_card_next(&card) < 0) {
                AL_PRINT("snd_card_next failed\n");
                break;
            }
        }
        numDevNames = idx;
    }
    else if(type == CAPTURE_DEVICE_PROBE)
    {
        stream = SND_PCM_STREAM_CAPTURE;
        card = -1;
        if(psnd_card_next(&card) < 0 || card < 0) {
            AL_PRINT("no capture cards found...\n");
            psnd_pcm_info_free(pcminfo);
            psnd_ctl_card_info_free(info);
            return;
        }

        for(i = 0;i < numCaptureDevNames;++i)
            free(allCaptureDevNameMap[i].name);

        allCaptureDevNameMap = realloc(allCaptureDevNameMap, sizeof(DevMap) * 1);
        allCaptureDevNameMap[0].name = strdup("ALSA Capture on default");
        AppendCaptureDeviceList(allCaptureDevNameMap[0].name);

        idx = 1;
        while (card >= 0) {
            sprintf(name, "hw:%d", card);
            handle = NULL;
            if ((err = psnd_ctl_open(&handle, name, 0)) < 0) {
                AL_PRINT("control open (%i): %s\n", card, psnd_strerror(err));
            }
            if (err >= 0 && (err = psnd_ctl_card_info(handle, info)) < 0) {
                AL_PRINT("control hardware info (%i): %s\n", card, psnd_strerror(err));
            }
            else if (err >= 0)
            {
                dev = -1;
                while(1) {
                    const char *cname, *dname;
                    void *temp;

                    if (psnd_ctl_pcm_next_device(handle, &dev)<0)
                        AL_PRINT("snd_ctl_pcm_next_device failed\n");
                    if (dev < 0)
                        break;
                    psnd_pcm_info_set_device(pcminfo, dev);
                    psnd_pcm_info_set_subdevice(pcminfo, 0);
                    psnd_pcm_info_set_stream(pcminfo, stream);
                    if ((err = psnd_ctl_pcm_info(handle, pcminfo)) < 0) {
                        if (err != -ENOENT)
                            AL_PRINT("control digital audio info (%i): %s\n", card, psnd_strerror(err));
                        continue;
                    }

                    temp = realloc(allCaptureDevNameMap, sizeof(DevMap) * (idx+1));
                    if(temp)
                    {
                        allCaptureDevNameMap = temp;
                        cname = psnd_ctl_card_info_get_name(info);
                        dname = psnd_pcm_info_get_name(pcminfo);
                        snprintf(name, sizeof(name), "ALSA Capture on %s [%s] (hw:%d,%d)",
                                 cname, dname, card, dev);
                        AppendCaptureDeviceList(name);
                        allCaptureDevNameMap[idx].name = strdup(name);
                        allCaptureDevNameMap[idx].card = card;
                        allCaptureDevNameMap[idx].dev = dev;
                        idx++;
                    }
                }
            }
            if(handle) psnd_ctl_close(handle);
            if(psnd_card_next(&card) < 0) {
                AL_PRINT("snd_card_next failed\n");
                break;
            }
        }
        numCaptureDevNames = idx;
    }

    psnd_pcm_info_free(pcminfo);
    psnd_ctl_card_info_free(info);
}
Ejemplo n.º 2
0
static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count)
{
    snd_ctl_t *handle;
    int card, err, dev, idx;
    snd_ctl_card_info_t *info;
    snd_pcm_info_t *pcminfo;
    DevMap *DevList;
    char name[1024];

    psnd_ctl_card_info_malloc(&info);
    psnd_pcm_info_malloc(&pcminfo);

    card = -1;
    if((err=psnd_card_next(&card)) < 0)
        AL_PRINT("Failed to find a card: %s\n", psnd_strerror(err));

    DevList = malloc(sizeof(DevMap) * 1);
    DevList[0].name = strdup("ALSA Default");
    idx = 1;
    while(card >= 0)
    {
        sprintf(name, "hw:%d", card);
        if((err = psnd_ctl_open(&handle, name, 0)) < 0)
        {
            AL_PRINT("control open (%i): %s\n", card, psnd_strerror(err));
            goto next_card;
        }
        if((err = psnd_ctl_card_info(handle, info)) < 0)
        {
            AL_PRINT("control hardware info (%i): %s\n", card, psnd_strerror(err));
            psnd_ctl_close(handle);
            goto next_card;
        }

        dev = -1;
        while(1)
        {
            const char *cname, *dname;
            void *temp;

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

            psnd_pcm_info_set_device(pcminfo, dev);
            psnd_pcm_info_set_subdevice(pcminfo, 0);
            psnd_pcm_info_set_stream(pcminfo, stream);
            if((err = psnd_ctl_pcm_info(handle, pcminfo)) < 0) {
                if(err != -ENOENT)
                    AL_PRINT("control digital audio info (%i): %s\n", card, psnd_strerror(err));
                continue;
            }

            temp = realloc(DevList, sizeof(DevMap) * (idx+1));
            if(temp)
            {
                DevList = temp;
                cname = psnd_ctl_card_info_get_name(info);
                dname = psnd_pcm_info_get_name(pcminfo);
                snprintf(name, sizeof(name), "%s [%s] (hw:%d,%d) via ALSA",
                         cname, dname, card, dev);
                DevList[idx].name = strdup(name);
                DevList[idx].card = card;
                DevList[idx].dev = dev;
                idx++;
            }
        }
        psnd_ctl_close(handle);
    next_card:
        if(psnd_card_next(&card) < 0) {
            AL_PRINT("snd_card_next failed\n");
            break;
        }
    }

    psnd_pcm_info_free(pcminfo);
    psnd_ctl_card_info_free(info);

    *count = idx;
    return DevList;
}