From 3fe353545b6a632407fbb9bdc9934598e3cc49c0 Mon Sep 17 00:00:00 2001 From: Paul Giblock Date: Sun, 25 Oct 2009 16:17:12 -0400 Subject: [PATCH] Alsa and OSS Device hints This should resolve the remaining issues. OSS has auto-complete with the filesystem. Alsa has an editable combobox for PCM and MIDI-raw. The DEVICE box for Alsa MIDI-seq should be obsoleted --- include/AlsaDeviceListModel.h | 62 +++++++++++++ include/AudioAlsa.h | 18 ---- include/MidiAlsaRaw.h | 4 +- src/core/audio/AlsaDeviceListModel.cpp | 120 +++++++++++++++++++++++++ src/core/audio/AudioAlsa.cpp | 71 +-------------- src/core/midi/MidiAlsaRaw.cpp | 15 +++- src/core/midi/MidiAlsaSeq.cpp | 2 +- 7 files changed, 199 insertions(+), 93 deletions(-) create mode 100644 include/AlsaDeviceListModel.h create mode 100644 src/core/audio/AlsaDeviceListModel.cpp diff --git a/include/AlsaDeviceListModel.h b/include/AlsaDeviceListModel.h new file mode 100644 index 000000000..457ab587a --- /dev/null +++ b/include/AlsaDeviceListModel.h @@ -0,0 +1,62 @@ +/* + * AlsaDeviceListModel - allows quick access to a list of alsa devices + * + * Copyright (c) 2009 Paul Giblock + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _ALSA_DEVICE_LIST_MODEL +#define _ALSA_DEVICE_LIST_MODEL + +#include "lmmsconfig.h" + +#ifdef LMMS_HAVE_ALSA + +#include +#include "QAbstractListModel" + + +class AlsaDeviceListModel : public QAbstractListModel +{ +public: + AlsaDeviceListModel( + snd_rawmidi_stream_t _stream, QObject * _parent ); + + AlsaDeviceListModel( + snd_pcm_stream_t _stream, QObject * _parent ); + + AlsaDeviceListModel( QObject * _parent ); + +protected: + void init( const char * _iface, const char * _filter ); + + 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; +}; + + +#endif // LMMS_HAVE_ALSA + +#endif diff --git a/include/AudioAlsa.h b/include/AudioAlsa.h index 549c9f1e2..6e194cf77 100644 --- a/include/AudioAlsa.h +++ b/include/AudioAlsa.h @@ -35,7 +35,6 @@ #include #include "AudioDevice.h" -#include "QAbstractListModel" class lcdSpinBox; @@ -57,23 +56,6 @@ 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 { public: diff --git a/include/MidiAlsaRaw.h b/include/MidiAlsaRaw.h index ea439eeeb..2fb7fbd98 100644 --- a/include/MidiAlsaRaw.h +++ b/include/MidiAlsaRaw.h @@ -37,7 +37,7 @@ struct pollfd; -class QLineEdit; +class QComboBox; class MidiAlsaRaw : public MidiClientRaw , public QThread @@ -65,7 +65,7 @@ public: virtual void saveSettings(); private: - QLineEdit * m_device; + QComboBox * m_device; } ; diff --git a/src/core/audio/AlsaDeviceListModel.cpp b/src/core/audio/AlsaDeviceListModel.cpp new file mode 100644 index 000000000..8cd7ae0a4 --- /dev/null +++ b/src/core/audio/AlsaDeviceListModel.cpp @@ -0,0 +1,120 @@ +/* + * AlsaDeviceListModel - allows quick access to a list of alsa devices + * + * Copyright (c) 2009 Paul Giblock + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include + +#include "AlsaDeviceListModel.h" + +#ifdef LMMS_HAVE_ALSA + +AlsaDeviceListModel::AlsaDeviceListModel( + snd_rawmidi_stream_t _stream, + QObject * _parent ) : + QAbstractListModel( _parent ) +{ + init( "rawmidi", SND_RAWMIDI_STREAM_INPUT ? + "Input" : + "Output" ); +} + + + +AlsaDeviceListModel::AlsaDeviceListModel( + snd_pcm_stream_t _stream, + QObject * _parent ) : + QAbstractListModel( _parent ) +{ + init( "pcm", SND_PCM_STREAM_CAPTURE ? + "Input" : + "Output" ); +} + + +AlsaDeviceListModel::AlsaDeviceListModel( + QObject * _parent ) : + QAbstractListModel( _parent ) +{ + init( "seq", NULL); +} + + +void AlsaDeviceListModel::init( + const char * _iface, + const char * _filter) +{ + void **hints, **n; + char *name, *descr, *io; + + if (snd_device_name_hint(-1, _iface, &hints) < 0) + return; + + n = hints; + 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 || _filter == NULL || strcmp(io, _filter) == 0) + 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 AlsaDeviceListModel::rowCount( + const QModelIndex & parent ) const +{ + return m_devices.count(); +} + + + +QVariant AlsaDeviceListModel::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(); + }; +} + + +#endif // LMMS_HAVE_ALSA diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index 7efbef85f..b119e619a 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -29,6 +29,7 @@ #ifdef LMMS_HAVE_ALSA +#include "AlsaDeviceListModel.h" #include "endian_handling.h" #include "config_mgr.h" #include "engine.h" @@ -491,84 +492,18 @@ 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 QComboBox( this ); m_device->setGeometry( 10, 20, 180, 20 ); - m_device->setModel( - new DeviceListModel( "pcm", SND_PCM_STREAM_PLAYBACK ) ); + m_device->setModel( new AlsaDeviceListModel( + SND_PCM_STREAM_PLAYBACK, this ) ); 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, 180, 10 ); diff --git a/src/core/midi/MidiAlsaRaw.cpp b/src/core/midi/MidiAlsaRaw.cpp index 7d8fcbad7..9f2da008d 100644 --- a/src/core/midi/MidiAlsaRaw.cpp +++ b/src/core/midi/MidiAlsaRaw.cpp @@ -23,8 +23,9 @@ */ #include -#include +#include +#include "AlsaDeviceListModel.h" #include "MidiAlsaRaw.h" #include "config_mgr.h" #include "gui_templates.h" @@ -179,8 +180,14 @@ void MidiAlsaRaw::run() MidiAlsaRaw::setupWidget::setupWidget( QWidget * _parent ) : MidiClientRaw::setupWidget( MidiAlsaRaw::name(), _parent ) { - m_device = new QLineEdit( MidiAlsaRaw::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 AlsaDeviceListModel( + SND_RAWMIDI_STREAM_INPUT, + this ) ); + m_device->setEditable( true ); + m_device->setInsertPolicy( QComboBox::NoInsert ); + m_device->setEditText( MidiAlsaRaw::probeDevice() ); QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) ); @@ -200,7 +207,7 @@ MidiAlsaRaw::setupWidget::~setupWidget() void MidiAlsaRaw::setupWidget::saveSettings() { configManager::inst()->setValue( "MidiAlsaRaw", "Device", - m_device->text() ); + m_device->currentText() ); } diff --git a/src/core/midi/MidiAlsaSeq.cpp b/src/core/midi/MidiAlsaSeq.cpp index 4521f9c22..db3bd4e92 100644 --- a/src/core/midi/MidiAlsaSeq.cpp +++ b/src/core/midi/MidiAlsaSeq.cpp @@ -669,7 +669,7 @@ MidiAlsaSeq::setupWidget::setupWidget( QWidget * _parent ) : MidiClient::setupWidget( MidiAlsaSeq::name(), _parent ) { m_device = new QLineEdit( MidiAlsaSeq::probeDevice(), this ); - m_device->setGeometry( 10, 20, 160, 20 ); + m_device->setGeometry( 10, 20, 180, 20 ); QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) );