diff --git a/include/AudioAlsa.h b/include/AudioAlsa.h index a916ad8da..c051e6eae 100644 --- a/include/AudioAlsa.h +++ b/include/AudioAlsa.h @@ -39,6 +39,46 @@ class AudioAlsa : public AudioDevice, public QThread { + // Public classes and enums +public: + /** + * @brief Contains the relevant information about available ALSA devices + */ + class DeviceInfo + { + public: + DeviceInfo(int cardNumber, int deviceNumber, + QString const & cardName, QString const & pcmName, + QString const & cardId, QString const & pcmId) : + m_cardNumber(cardNumber), + m_deviceNumber(deviceNumber), + m_cardName(cardName), + m_pcmName(pcmName), + m_cardId(cardId), + m_pcmId(pcmId) + {} + ~DeviceInfo() {} + + int getCardNumber() const { return m_cardNumber; } + int getDeviceNumber() const { return m_deviceNumber; } + QString const & getCardName() const { return m_cardName; } + QString const & getPcmName() const { return m_pcmName; } + QString const & getCardId() const { return m_cardId; } + QString const & getPcmId() const { return m_pcmId; } + + QString getHWString() const { return QString("hw:%1,%2").arg(m_cardNumber).arg(m_deviceNumber); } + + private: + int m_cardNumber; + int m_deviceNumber; + QString m_cardName; + QString m_pcmName; + QString m_cardId; + QString m_pcmId; + }; + + typedef std::vector DeviceInfoCollection; + public: AudioAlsa( bool & _success_ful, Mixer* mixer ); virtual ~AudioAlsa(); @@ -51,6 +91,8 @@ public: static QString probeDevice(); + static DeviceInfoCollection getAvailableDevices(); + private: virtual void startProcessing(); virtual void stopProcessing(); diff --git a/include/AudioAlsaSetupWidget.h b/include/AudioAlsaSetupWidget.h index 0e2f9b69c..f9224eaca 100644 --- a/include/AudioAlsaSetupWidget.h +++ b/include/AudioAlsaSetupWidget.h @@ -31,6 +31,8 @@ #include "AudioDeviceSetupWidget.h" +#include "AudioAlsa.h" + #include @@ -52,50 +54,13 @@ public: public slots: void onCurrentIndexChanged(int index); -private: - class DeviceInfo - { - public: - DeviceInfo(int cardNumber, int deviceNumber, - QString const & cardName, QString const & pcmName, - QString const & cardId, QString const & pcmId) : - m_cardNumber(cardNumber), - m_deviceNumber(deviceNumber), - m_cardName(cardName), - m_pcmName(pcmName), - m_cardId(cardId), - m_pcmId(pcmId) - {} - ~DeviceInfo() {} - - int getCardNumber() const { return m_cardNumber; } - int getDeviceNumber() const { return m_deviceNumber; } - QString const & getCardName() const { return m_cardName; } - QString const & getPcmName() const { return m_pcmName; } - QString const & getCardId() const { return m_cardId; } - QString const & getPcmId() const { return m_pcmId; } - - QString getHWString() const { return QString("hw:%1,%2").arg(m_cardNumber).arg(m_deviceNumber); } - - private: - int m_cardNumber; - int m_deviceNumber; - QString m_cardName; - QString m_pcmName; - QString m_cardId; - QString m_pcmId; - }; - - void populateDeviceInfos(std::vector &deviceInfos); - private: QComboBox * m_deviceComboBox; QLineEdit * m_device; LcdSpinBox * m_channels; int m_selectedDevice; - typedef std::vector DeviceInfoCollection; - DeviceInfoCollection m_deviceInfos; + AudioAlsa::DeviceInfoCollection m_deviceInfos; } ; #endif diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index 830effe2b..13ee39ab9 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -141,6 +141,151 @@ QString AudioAlsa::probeDevice() +// TODO Test code. Delete! +void device_list(void) +{ + snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; + snd_ctl_t *handle; + int card, err, dev, idx; + snd_ctl_card_info_t *info; + snd_pcm_info_t *pcminfo; + snd_ctl_card_info_alloca(&info); + snd_pcm_info_alloca(&pcminfo); + + card = -1; + if (snd_card_next(&card) < 0 || card < 0) { + return; + } + std::cout << "**** List of " << snd_pcm_stream_name(stream) << " Hardware Devices ****\n"; + + while (card >= 0) { + char name[32]; + sprintf(name, "hw:%d", card); + if ((err = snd_ctl_open(&handle, name, 0)) < 0) { + // TODO Error handling + //error("control open (%i): %s", card, snd_strerror(err)); + goto next_card; + } + if ((err = snd_ctl_card_info(handle, info)) < 0) { + // TODO Error handling + //error("control hardware info (%i): %s", card, snd_strerror(err)); + snd_ctl_close(handle); + goto next_card; + } + dev = -1; + while (1) { + unsigned int count; + if (snd_ctl_pcm_next_device(handle, &dev)<0) + // TODO Error handling + //error("snd_ctl_pcm_next_device"); + std::cerr << "snd_ctl_pcm_next_device"; + if (dev < 0) + break; + snd_pcm_info_set_device(pcminfo, dev); + snd_pcm_info_set_subdevice(pcminfo, 0); + snd_pcm_info_set_stream(pcminfo, stream); + if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { + if (err != -ENOENT) + // TODO Error handling + //error("control digital audio info (%i): %s", card, snd_strerror(err)); + std::cerr << "Error\n"; + continue; + } + //std::cout << "card " << card << ": " << snd_ctl_card_info_get_id(info) << " [" << snd_ctl_card_info_get_name(info) << "], device " << dev << + // ": " << snd_pcm_info_get_id(pcminfo) << " [" << snd_pcm_info_get_name(pcminfo) << "]\n"; + std::cout << "card hw" << card << ":" << dev << " - " << "[" << snd_ctl_card_info_get_name(info) << "/" << snd_pcm_info_get_name(pcminfo) << "], " << + snd_ctl_card_info_get_id(info) << "," << snd_pcm_info_get_id(pcminfo) << "\n"; + + count = snd_pcm_info_get_subdevices_count(pcminfo); + std::cout << " Subdevices: " << snd_pcm_info_get_subdevices_avail(pcminfo) << "/" << count << std::endl; + for (idx = 0; idx < (int)count; idx++) { + snd_pcm_info_set_subdevice(pcminfo, idx); + if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { + // TODO Error handling + //error("control digital audio playback info (%i): %s", card, snd_strerror(err)); + std::cerr << "Error\n"; + } else { + std::cout << " Subdevice #" << idx << ": " << snd_pcm_info_get_subdevice_name(pcminfo) << std::endl; + } + } + } + snd_ctl_close(handle); +next_card: + if (snd_card_next(&card) < 0) { + // TODO Error handling + //error("snd_card_next"); + break; + } + } +} + + + + +AudioAlsa::DeviceInfoCollection AudioAlsa::getAvailableDevices() +{ + DeviceInfoCollection deviceInfos; + + snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; + snd_ctl_t *handle; + snd_ctl_card_info_t *info; + snd_pcm_info_t *pcminfo; + + // Allocate memory for the info structs + snd_ctl_card_info_alloca(&info); + snd_pcm_info_alloca(&pcminfo); + + int card = -1; + + while (!snd_card_next(&card) && card >= 0) + { + std::cout << "Card: " << card << " found!" << std::endl; + + char name[32]; + sprintf(name, "hw:%d", card); + + if (snd_ctl_open(&handle, name, 0) < 0) + { + std::cerr << "Error opening ALSA card " << name << std::endl; + continue; + } + if (snd_ctl_card_info(handle, info) < 0) + { + snd_ctl_close(handle); + std::cerr << "Could not retrieve info for ALSA card " << name << std::endl; + continue; + } + + int dev = -1; + + while (!snd_ctl_pcm_next_device(handle, &dev) && dev >= 0) + { + snd_pcm_info_set_device(pcminfo, dev); + snd_pcm_info_set_subdevice(pcminfo, 0); + snd_pcm_info_set_stream(pcminfo, stream); + if (!snd_ctl_pcm_info(handle, pcminfo)) + { + QString cardName(snd_ctl_card_info_get_name(info)); + QString pcmName(snd_pcm_info_get_name(pcminfo)); + QString cardId(snd_ctl_card_info_get_id(info)); + QString pcmId(snd_pcm_info_get_id(pcminfo)); + + DeviceInfo currentDevice(card, dev, cardName, pcmName, cardId, pcmId); + deviceInfos.push_back(currentDevice); + + std::cout << "card hw" << card << ":" << dev << " - " << "[" << snd_ctl_card_info_get_name(info) << " | " << snd_pcm_info_get_name(pcminfo) << "], " << + snd_ctl_card_info_get_id(info) << ", " << snd_pcm_info_get_id(pcminfo) << std::endl; + } + } + + snd_ctl_close(handle); + } + + return deviceInfos; +} + + + int AudioAlsa::handleError( int _err ) { diff --git a/src/gui/AudioAlsaSetupWidget.cpp b/src/gui/AudioAlsaSetupWidget.cpp index 7f74bcecf..8eea54777 100644 --- a/src/gui/AudioAlsaSetupWidget.cpp +++ b/src/gui/AudioAlsaSetupWidget.cpp @@ -38,151 +38,12 @@ #include -void device_list(void) -{ - snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; - snd_ctl_t *handle; - int card, err, dev, idx; - snd_ctl_card_info_t *info; - snd_pcm_info_t *pcminfo; - snd_ctl_card_info_alloca(&info); - snd_pcm_info_alloca(&pcminfo); - - card = -1; - if (snd_card_next(&card) < 0 || card < 0) { - return; - } - std::cout << "**** List of " << snd_pcm_stream_name(stream) << " Hardware Devices ****\n"; - - while (card >= 0) { - char name[32]; - sprintf(name, "hw:%d", card); - if ((err = snd_ctl_open(&handle, name, 0)) < 0) { - // TODO Error handling - //error("control open (%i): %s", card, snd_strerror(err)); - goto next_card; - } - if ((err = snd_ctl_card_info(handle, info)) < 0) { - // TODO Error handling - //error("control hardware info (%i): %s", card, snd_strerror(err)); - snd_ctl_close(handle); - goto next_card; - } - dev = -1; - while (1) { - unsigned int count; - if (snd_ctl_pcm_next_device(handle, &dev)<0) - // TODO Error handling - //error("snd_ctl_pcm_next_device"); - std::cerr << "snd_ctl_pcm_next_device"; - if (dev < 0) - break; - snd_pcm_info_set_device(pcminfo, dev); - snd_pcm_info_set_subdevice(pcminfo, 0); - snd_pcm_info_set_stream(pcminfo, stream); - if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { - if (err != -ENOENT) - // TODO Error handling - //error("control digital audio info (%i): %s", card, snd_strerror(err)); - std::cerr << "Error\n"; - continue; - } - //std::cout << "card " << card << ": " << snd_ctl_card_info_get_id(info) << " [" << snd_ctl_card_info_get_name(info) << "], device " << dev << - // ": " << snd_pcm_info_get_id(pcminfo) << " [" << snd_pcm_info_get_name(pcminfo) << "]\n"; - std::cout << "card hw" << card << ":" << dev << " - " << "[" << snd_ctl_card_info_get_name(info) << "/" << snd_pcm_info_get_name(pcminfo) << "], " << - snd_ctl_card_info_get_id(info) << "," << snd_pcm_info_get_id(pcminfo) << "\n"; - - count = snd_pcm_info_get_subdevices_count(pcminfo); - std::cout << " Subdevices: " << snd_pcm_info_get_subdevices_avail(pcminfo) << "/" << count << std::endl; - for (idx = 0; idx < (int)count; idx++) { - snd_pcm_info_set_subdevice(pcminfo, idx); - if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { - // TODO Error handling - //error("control digital audio playback info (%i): %s", card, snd_strerror(err)); - std::cerr << "Error\n"; - } else { - std::cout << " Subdevice #" << idx << ": " << snd_pcm_info_get_subdevice_name(pcminfo) << std::endl; - } - } - } - snd_ctl_close(handle); -next_card: - if (snd_card_next(&card) < 0) { - // TODO Error handling - //error("snd_card_next"); - break; - } - } -} - - - -void AudioAlsaSetupWidget::populateDeviceInfos(std::vector &deviceInfos) -{ - snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; - snd_ctl_t *handle; - snd_ctl_card_info_t *info; - snd_pcm_info_t *pcminfo; - - // Allocate memory for the info structs - snd_ctl_card_info_alloca(&info); - snd_pcm_info_alloca(&pcminfo); - - int card = -1; - - while (!snd_card_next(&card) && card >= 0) - { - std::cout << "Card: " << card << " found!" << std::endl; - - char name[32]; - sprintf(name, "hw:%d", card); - - if (snd_ctl_open(&handle, name, 0) < 0) - { - std::cerr << "Error opening ALSA card " << name << std::endl; - continue; - } - if (snd_ctl_card_info(handle, info) < 0) - { - snd_ctl_close(handle); - std::cerr << "Could not retrieve info for ALSA card " << name << std::endl; - continue; - } - - int dev = -1; - - while (!snd_ctl_pcm_next_device(handle, &dev) && dev >= 0) - { - snd_pcm_info_set_device(pcminfo, dev); - snd_pcm_info_set_subdevice(pcminfo, 0); - snd_pcm_info_set_stream(pcminfo, stream); - if (!snd_ctl_pcm_info(handle, pcminfo)) - { - QString cardName(snd_ctl_card_info_get_name(info)); - QString pcmName(snd_pcm_info_get_name(pcminfo)); - QString cardId(snd_ctl_card_info_get_id(info)); - QString pcmId(snd_pcm_info_get_id(pcminfo)); - - DeviceInfo currentDevice(card, dev, cardName, pcmName, cardId, pcmId); - deviceInfos.push_back(currentDevice); - - std::cout << "card hw" << card << ":" << dev << " - " << "[" << snd_ctl_card_info_get_name(info) << "/" << snd_pcm_info_get_name(pcminfo) << "], " << - snd_ctl_card_info_get_id(info) << "," << snd_pcm_info_get_id(pcminfo) << std::endl; - } - } - - snd_ctl_close(handle); - } -} - - - AudioAlsaSetupWidget::AudioAlsaSetupWidget( QWidget * _parent ) : AudioDeviceSetupWidget( AudioAlsa::name(), _parent ), m_selectedDevice(-1) { - populateDeviceInfos(m_deviceInfos); + m_deviceInfos = AudioAlsa::getAvailableDevices(); QString deviceText = ConfigManager::inst()->value( "audioalsa", "device" ); @@ -192,7 +53,7 @@ AudioAlsaSetupWidget::AudioAlsaSetupWidget( QWidget * _parent ) : m_deviceComboBox = new QComboBox(this); for (size_t i = 0; i < m_deviceInfos.size(); ++i) { - DeviceInfo const & currentDeviceInfo = m_deviceInfos[i]; + AudioAlsa::DeviceInfo const & currentDeviceInfo = m_deviceInfos[i]; QString comboBoxText = currentDeviceInfo.getHWString() + " [" + currentDeviceInfo.getCardName() + " | " + currentDeviceInfo.getPcmName() + "]"; m_deviceComboBox->addItem(comboBoxText, QVariant(static_cast(i))); m_deviceComboBox->setItemData(i, comboBoxText, Qt::ToolTipRole); @@ -247,7 +108,7 @@ void AudioAlsaSetupWidget::saveSettings() if (m_selectedDevice != -1) { - DeviceInfo const & selectedDevice = m_deviceInfos[m_selectedDevice]; + AudioAlsa::DeviceInfo const & selectedDevice = m_deviceInfos[m_selectedDevice]; deviceText = selectedDevice.getHWString(); }