From a45a211f2ba529bdb2ad5c59be5dfd2602f4f148 Mon Sep 17 00:00:00 2001 From: Paul Giblock Date: Tue, 13 Oct 2009 23:12:33 -0400 Subject: [PATCH] Add Audio-device listing support for alsa-pcm Added a AlsaDeviceListModel, will do the same for other devices as well --- data/themes/default/style.css | 2 +- include/AudioAlsa.h | 27 +++++++++++- src/core/audio/AudioAlsa.cpp | 83 ++++++++++++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 9 deletions(-) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 30091d6fe..de9de28b0 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -107,7 +107,7 @@ trackWidget { /* border-bottom: 1px solid rgb(0, 0, 0);*/ background-color: rgb(0, 0, 0); } -nameLabel, effectLabel, sf2InstrumentView > QLabel { +nameLabel, effectLabel, sf2InstrumentView > QLabel, QComboBox { font-size:10px; } diff --git a/include/AudioAlsa.h b/include/AudioAlsa.h index c2be94ac8..549c9f1e2 100644 --- a/include/AudioAlsa.h +++ b/include/AudioAlsa.h @@ -35,10 +35,11 @@ #include #include "AudioDevice.h" +#include "QAbstractListModel" class lcdSpinBox; -class QLineEdit; +class QComboBox; class AudioAlsa : public AudioDevice, public QThread @@ -54,6 +55,23 @@ public: } static QString probeDevice(); + + + class DeviceListModel : public QAbstractListModel + { + public: + // iface = {"pcm", "rawmidi", "timer", "seq"} + // stream = {SND_PCM_STREAM_CAPTURE, SND_PCM_STREAM_PLAYBACK} + DeviceListModel( const char * _iface, snd_pcm_stream_t stream ); + + int rowCount( const QModelIndex & parent = QModelIndex() ) const; + QVariant data( const QModelIndex & index, + int role = Qt::DisplayRole ) const; + private: + typedef QPair StringPair; + typedef QList DeviceList; + DeviceList m_devices; + }; class setupWidget : public AudioDevice::setupWidget @@ -65,9 +83,14 @@ public: virtual void saveSettings(); private: - QLineEdit * m_device; + QComboBox * m_device; lcdSpinBox * m_channels; + void poo(const QString & s) + { + printf("Got %s\n", qPrintable( s ) ); + } + } ; diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index 145bf88a7..7efbef85f 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -22,7 +22,7 @@ * */ -#include +#include #include #include "AudioAlsa.h" @@ -491,16 +491,87 @@ int AudioAlsa::setSWParams() +AudioAlsa::DeviceListModel::DeviceListModel( + const char * _iface, snd_pcm_stream_t _stream ) +{ + void **hints, **n; + char *name, *descr, *io; + const char *filter; + + if (snd_device_name_hint(-1, _iface, &hints) < 0) + return; + n = hints; + filter = _stream == SND_PCM_STREAM_CAPTURE ? "Input" : "Output"; + while (*n != NULL) { + name = snd_device_name_get_hint(*n, "NAME"); + descr = snd_device_name_get_hint(*n, "DESC"); + io = snd_device_name_get_hint(*n, "IOID"); + + // Filter out non-null or filtered items + if (io != NULL && strcmp(io, filter) != 0) + continue; + + m_devices.append(StringPair(name, descr)); + if (name != NULL) + free(name); + if (descr != NULL) + free(descr); + if (io != NULL) + free(io); + n++; + } + snd_device_name_free_hint(hints); +} + + + +int AudioAlsa::DeviceListModel::rowCount( + const QModelIndex & parent ) const +{ + return m_devices.count(); +} + + + +QVariant AudioAlsa::DeviceListModel::data( + const QModelIndex & index, + int role ) const +{ + switch( role ) + { + case Qt::DisplayRole: + return m_devices.at(index.row()).first; + case Qt::ToolTipRole: + case Qt::StatusTipRole: + return m_devices.at(index.row()).second; + default: + return QVariant(); + }; +} + + + AudioAlsa::setupWidget::setupWidget( QWidget * _parent ) : AudioDevice::setupWidget( AudioAlsa::name(), _parent ) { - m_device = new QLineEdit( AudioAlsa::probeDevice(), this ); - m_device->setGeometry( 10, 20, 160, 20 ); + + m_device = new QComboBox( this ); + m_device->setGeometry( 10, 20, 180, 20 ); + m_device->setModel( + new DeviceListModel( "pcm", SND_PCM_STREAM_PLAYBACK ) ); + m_device->setEditable( true ); + m_device->setInsertPolicy( QComboBox::NoInsert ); + m_device->setEditText( AudioAlsa::probeDevice() ); + + // Why doesn't Qt already do this? + connect( m_device, SIGNAL(currentIndexChanged(const QString &)), + this, SLOT(poo(const QString &)) ); + QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) ); - dev_lbl->setGeometry( 10, 40, 160, 10 ); + dev_lbl->setGeometry( 10, 40, 180, 10 ); lcdSpinBoxModel * m = new lcdSpinBoxModel( /* this */ ); m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); @@ -511,7 +582,7 @@ AudioAlsa::setupWidget::setupWidget( QWidget * _parent ) : m_channels = new lcdSpinBox( 1, this ); m_channels->setModel( m ); m_channels->setLabel( tr( "CHANNELS" ) ); - m_channels->move( 180, 20 ); + m_channels->move( 200, 20 ); } @@ -529,7 +600,7 @@ AudioAlsa::setupWidget::~setupWidget() void AudioAlsa::setupWidget::saveSettings() { configManager::inst()->setValue( "audioalsa", "device", - m_device->text() ); + m_device->currentText() ); configManager::inst()->setValue( "audioalsa", "channels", QString::number( m_channels->value() ) ); }