Moves the probing code for available devices into the ALSA driver

This commit is contained in:
Michael Gregorius
2015-06-27 16:42:17 +02:00
parent 79cae31b5b
commit 27653b713b
4 changed files with 193 additions and 180 deletions

View File

@@ -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<DeviceInfo> 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();

View File

@@ -31,6 +31,8 @@
#include "AudioDeviceSetupWidget.h"
#include "AudioAlsa.h"
#include <vector>
@@ -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<DeviceInfo> &deviceInfos);
private:
QComboBox * m_deviceComboBox;
QLineEdit * m_device;
LcdSpinBox * m_channels;
int m_selectedDevice;
typedef std::vector<DeviceInfo> DeviceInfoCollection;
DeviceInfoCollection m_deviceInfos;
AudioAlsa::DeviceInfoCollection m_deviceInfos;
} ;
#endif

View File

@@ -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 )
{

View File

@@ -38,151 +38,12 @@
#include <iostream>
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<DeviceInfo> &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<uint>(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();
}