Probe physical devices separately from appending them to the device list

This commit is contained in:
Chris Robinson
2010-03-09 05:44:18 -08:00
parent 1f10195c47
commit 2ba3a88ace
3 changed files with 143 additions and 157 deletions
+94 -134
View File
@@ -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();
}
+5 -1
View File
@@ -522,7 +522,6 @@ static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname,
DeviceList = temp;
snprintf(str, sizeof(str), "DirectSound Software on %s", desc);
AppendAllDeviceList(str);
DeviceList[NumDevices].name = strdup(str);
DeviceList[NumDevices].guid = *guid;
@@ -569,6 +568,11 @@ void alcDSoundProbe(int type)
hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
if(FAILED(hr))
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
else
{
for(i = 0;i < NumDevices;i++)
AppendAllDeviceList(DeviceList[i].name);
}
}
DSoundUnload();
+44 -22
View File
@@ -53,6 +53,29 @@ typedef struct {
static ALCchar **CaptureDeviceList;
static ALuint NumCaptureDevices;
static void ProbeDevices(void)
{
ALuint i;
for(i = 0;i < NumCaptureDevices;i++)
free(CaptureDeviceList[i]);
NumCaptureDevices = waveInGetNumDevs();
CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
for(i = 0;i < NumCaptureDevices;i++)
{
WAVEINCAPS WaveInCaps;
CaptureDeviceList[i] = NULL;
if(waveInGetDevCaps(i, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
{
char name[128];
snprintf(name, sizeof(name), "WaveIn on %s", WaveInCaps.szPname);
CaptureDeviceList[i] = strdup(name);
}
}
}
/*
WaveInProc
@@ -185,19 +208,31 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
ALuint i;
// Find the Device ID matching the deviceName if valid
if (deviceName)
if(deviceName)
{
for(i = 0;i < NumCaptureDevices;i++)
{
if (!strcmp(deviceName, CaptureDeviceList[i]))
if(CaptureDeviceList[i] &&
strcmp(deviceName, CaptureDeviceList[i]) == 0)
{
lDeviceID = i;
break;
}
}
if(i == NumCaptureDevices)
return ALC_FALSE;
}
else
{
for(i = 0;i < NumCaptureDevices;i++)
{
if(CaptureDeviceList[i])
{
lDeviceID = i;
break;
}
}
}
if(i == NumCaptureDevices)
return ALC_FALSE;
pData = calloc(1, sizeof(*pData));
if(!pData)
@@ -443,28 +478,15 @@ void alcWinMMDeinit()
void alcWinMMProbe(int type)
{
ALuint lLoop;
ALuint i;
if(type != CAPTURE_DEVICE_PROBE)
return;
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
free(CaptureDeviceList[lLoop]);
NumCaptureDevices = waveInGetNumDevs();
CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
ProbeDevices();
for(i = 0;i < NumCaptureDevices;i++)
{
WAVEINCAPS WaveInCaps;
if(waveInGetDevCaps(lLoop, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
{
char name[128];
snprintf(name, sizeof(name), "WaveIn on %s", WaveInCaps.szPname);
AppendCaptureDeviceList(name);
CaptureDeviceList[lLoop] = strdup(name);
}
else
CaptureDeviceList[lLoop] = strdup("");
if(CaptureDeviceList[i])
AppendCaptureDeviceList(CaptureDeviceList[i]);
}
}