From 5e4a6e8223ed06abd3768f3646899ec90f038c40 Mon Sep 17 00:00:00 2001 From: Stephen Hurd Date: Thu, 14 Apr 2016 19:04:40 -0700 Subject: [PATCH] ALSA: Add alias support When using ALSA with FreeBSD, the direct snd_device instances are not available, only plugin devices and "default". For programs which use QAudio, this means there are *no* devices enumerated using QAudio::availableDevices(). This patch adds all pcm aliases to the end of the list after the current set of devices are added. v2: - Use more verbose variable names - Remove unneeded variables - constify deviceName v3: - Add #ifdef Q_OS_FREEBSD Change-Id: Iaf4564e23b738c363d1b91174f350665d8c55060 --- src/plugins/alsa/qalsaaudiodeviceinfo.cpp | 54 ++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/plugins/alsa/qalsaaudiodeviceinfo.cpp b/src/plugins/alsa/qalsaaudiodeviceinfo.cpp index 31ad47c..dfd29f6 100644 --- a/src/plugins/alsa/qalsaaudiodeviceinfo.cpp +++ b/src/plugins/alsa/qalsaaudiodeviceinfo.cpp @@ -374,6 +374,58 @@ QList QAlsaAudioDeviceInfo::availableDevices(QAudio::Mode mode) ++n; } snd_device_name_free_hint(hints); + +#ifdef Q_OS_FREEBSD + // Now find aliases... + snd_config_iterator_t pos, next; + snd_config_t *top, *node, *type; + snd_pcm_t *pcm; + snd_pcm_stream_t streamType; + const char *idString; + const char **ignoreId; + static const char *ignore[] = {"hw", "plughw", "plug", "dsnoop", "tee", + "file", "null", "shm", "cards", "rate_convert", NULL}; + + // Populate snd_config... + if (snd_config == NULL) + snd_config_update(); + if (snd_config != NULL) { + switch (mode) { + case QAudio::AudioInput: + streamType = SND_PCM_STREAM_CAPTURE; + break; + case QAudio::AudioOutput: + streamType = SND_PCM_STREAM_PLAYBACK; + break; + default: + goto bad_mode; + } + // Find "pcm" nodes... + if (snd_config_search(snd_config, "pcm", &top) >= 0) { + for (pos = snd_config_iterator_first(top), next = snd_config_iterator_next(pos); + pos != snd_config_iterator_end(top); + pos = next, next = snd_config_iterator_next(pos)) { + node = snd_config_iterator_entry(pos); + if (snd_config_search(node, "type", &type) < 0) + continue; + snd_config_get_id(node, &idString); + for (ignoreId = ignore; *ignoreId; ignoreId++) { + if (strcmp(*ignoreId, idString) == 0) + break; + } + if (*ignoreId) + continue; + // Ensure it's available... + if (snd_pcm_open(&pcm, idString, streamType, 0)) + continue; + snd_pcm_close(pcm); + const QString deviceName = QLatin1String(idString); + devices.append(deviceName.toLocal8Bit().constData()); + } + } + } +bad_mode: +#endif #else int idx = 0; char* name; @@ -384,7 +436,7 @@ QList QAlsaAudioDeviceInfo::availableDevices(QAudio::Mode mode) } #endif - if (devices.size() > 0) + if (devices.size() > 0 && !devices.contains("default")) devices.append("default"); return devices; -- 2.8.1