diff options
Diffstat (limited to 'Alc/alsa.c')
-rw-r--r-- | Alc/alsa.c | 228 |
1 files changed, 94 insertions, 134 deletions
@@ -228,6 +228,92 @@ void alsa_unload(void) alsa_handle = NULL; } +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[128]; + + 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((stream == SND_PCM_STREAM_PLAYBACK) ? + "ALSA Software on default" : + "ALSA Capture on 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), "ALSA %s on %s [%s] (hw:%d,%d)", + ((stream == SND_PCM_STREAM_PLAYBACK) ? + "Software" : "Capture"), 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; +} + static int xrun_recovery(snd_pcm_t *handle, int err) { @@ -970,161 +1056,35 @@ void alc_alsa_deinit(void) 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_load()) return; - 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)); - if(type == DEVICE_PROBE) AppendDeviceList(alsaDevice); else if(type == ALL_DEVICE_PROBE) { - stream = SND_PCM_STREAM_PLAYBACK; - 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); + free(allDevNameMap); + allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames); - 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; + for(i = 0;i < numDevNames;++i) + AppendAllDeviceList(allDevNameMap[i].name); } else if(type == CAPTURE_DEVICE_PROBE) { - stream = SND_PCM_STREAM_CAPTURE; - 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); + free(allCaptureDevNameMap); + allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); - 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; + for(i = 0;i < numCaptureDevNames;++i) + AppendCaptureDeviceList(allCaptureDevNameMap[i].name); } - psnd_pcm_info_free(pcminfo); - psnd_ctl_card_info_free(info); - alsa_unload(); } |