aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/alsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/alsa.c')
-rw-r--r--Alc/alsa.c228
1 files changed, 94 insertions, 134 deletions
diff --git a/Alc/alsa.c b/Alc/alsa.c
index fd82375b..a8893370 100644
--- a/Alc/alsa.c
+++ b/Alc/alsa.c
@@ -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();
}