diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2015-08-19 09:43:17 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2015-08-19 09:43:17 +0000 |
| commit | 1ef98753ff23287aaa23e0c35e03719256ea268f (patch) | |
| tree | 11cb2d4f70444fb7cc704e04aca7fe41869778da | |
| parent | 7a8026a4ad54588c131fefbdb5dc3fd118054011 (diff) | |
| download | qmmp-1ef98753ff23287aaa23e0c35e03719256ea268f.tar.gz qmmp-1ef98753ff23287aaa23e0c35e03719256ea268f.tar.bz2 qmmp-1ef98753ff23287aaa23e0c35e03719256ea268f.zip | |
using QSocketNotifier to track alsa volume (patch by Hong Jen Yee)
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5424 90c681e8-e032-0410-971d-27865f9a5e38
| -rw-r--r-- | src/plugins/Output/alsa/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.cpp | 44 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.h | 4 | ||||
| -rw-r--r-- | src/qmmp/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/qmmp/volume.h | 18 | ||||
| -rw-r--r-- | src/qmmp/volumecontrol.cpp | 10 |
6 files changed, 62 insertions, 23 deletions
diff --git a/src/plugins/Output/alsa/CMakeLists.txt b/src/plugins/Output/alsa/CMakeLists.txt index 6406d7e75..7b4e361fb 100644 --- a/src/plugins/Output/alsa/CMakeLists.txt +++ b/src/plugins/Output/alsa/CMakeLists.txt @@ -37,17 +37,12 @@ SET(libalsa_SRCS settingsdialog.cpp ) -SET(libalsa_HDRS - outputalsa.h -) - SET(libalsa_RCCS translations/translations.qrc) QT4_ADD_RESOURCES(libalsa_RCC_SRCS ${libalsa_RCCS}) # user interface - SET(libalsa_UIS settingsdialog.ui ) @@ -58,8 +53,7 @@ QT4_WRAP_UI(libalsa_UIS_H ${libalsa_UIS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) IF(ALSA_FOUND) -ADD_LIBRARY(alsa MODULE ${libalsa_SRCS} ${libalsa_UIS_H} - ${libalsa_RCC_SRCS} ${libalsa_HDRS}) +ADD_LIBRARY(alsa MODULE ${libalsa_SRCS} ${libalsa_UIS_H} ${libalsa_RCC_SRCS}) add_dependencies(alsa qmmp) target_link_libraries(alsa ${QT_LIBRARIES} -lqmmp ${ALSA_LDFLAGS}) install(TARGETS alsa DESTINATION ${LIB_DIR}/qmmp/Output) diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp index 4e6a33b54..69662abfe 100644 --- a/src/plugins/Output/alsa/outputalsa.cpp +++ b/src/plugins/Output/alsa/outputalsa.cpp @@ -18,9 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#include <QDir> #include <QSettings> -#include <QTimer> +#include <QSocketNotifier> #include <stdio.h> #include <stdint.h> @@ -33,6 +32,7 @@ #include <qmmp/statehandler.h> #include "outputalsa.h" + OutputALSA::OutputALSA() : m_inited(false) { QSettings settings(Qmmp::configFile(), QSettings::IniFormat); @@ -425,15 +425,16 @@ void VolumeALSA::setVolume(const VolumeSettings &vol) VolumeSettings VolumeALSA::volume() const { VolumeSettings vol; - if (!pcm_element) - return vol; - - long value = 0; - snd_mixer_handle_events(m_mixer); - snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_LEFT, &value); - vol.left = value; - snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, &value); - vol.right = value; + + if(pcm_element) + { + long value = 0; + snd_mixer_handle_events(m_mixer); + snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_LEFT, &value); + vol.left = value; + snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, &value); + vol.right = value; + } return vol; } @@ -467,10 +468,26 @@ int VolumeALSA::setupMixer(QString card, QString device) return -1; } + // setup socket notifiers to monitor the state changes of the mixer + int n = snd_mixer_poll_descriptors_count(m_mixer); + if(n > 0) + { + struct pollfd* fds = new struct pollfd[n]; + n = snd_mixer_poll_descriptors(m_mixer, fds, n); + for(int i = 0; i < n; ++i) + { + int sock = fds[i].fd; + QSocketNotifier* sn = new QSocketNotifier(sock, QSocketNotifier::Read, this); + connect(sn, SIGNAL(activated(int)), SIGNAL(changed())); + } + delete []fds; + } + qDebug("OutputALSA: setupMixer() success"); return 0; } + void VolumeALSA::parseMixerName(char *str, char **name, int *index) { char *end; @@ -543,3 +560,8 @@ int VolumeALSA::getMixer(snd_mixer_t **mixer, QString card) } return (*mixer != NULL); } + +bool VolumeALSA::hasNotifySignal() const +{ + return true; +} diff --git a/src/plugins/Output/alsa/outputalsa.h b/src/plugins/Output/alsa/outputalsa.h index 074b9ac0a..1e4a0a5f9 100644 --- a/src/plugins/Output/alsa/outputalsa.h +++ b/src/plugins/Output/alsa/outputalsa.h @@ -32,7 +32,6 @@ extern "C" #include <qmmp/output.h> #include <qmmp/volume.h> - class OutputALSA : public Output { public: @@ -72,6 +71,7 @@ private: class VolumeALSA : public Volume { + Q_OBJECT public: VolumeALSA(); virtual ~VolumeALSA(); @@ -79,6 +79,8 @@ public: void setVolume(const VolumeSettings &vol); VolumeSettings volume() const; + bool hasNotifySignal() const; + private: //alsa mixer int setupMixer(QString card, QString device); diff --git a/src/qmmp/CMakeLists.txt b/src/qmmp/CMakeLists.txt index 6ddc9071d..689335656 100644 --- a/src/qmmp/CMakeLists.txt +++ b/src/qmmp/CMakeLists.txt @@ -86,7 +86,6 @@ SET(libqmmp_HDRS inputsourcefactory.h enginefactory.h metadatamanager.h - volume.h output.h channelmap.h channelconverter_p.h diff --git a/src/qmmp/volume.h b/src/qmmp/volume.h index 4ba28da74..bef3133f0 100644 --- a/src/qmmp/volume.h +++ b/src/qmmp/volume.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2012 by Ilya Kotov * + * Copyright (C) 2012-2015 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -21,6 +21,8 @@ #ifndef VOLUME_H #define VOLUME_H +#include <QObject> + /*! @brief The VolumeSettings structure stores volume levels * @author Ilya Kotov <forkotov02@hotmail.ru> */ @@ -42,8 +44,9 @@ struct VolumeSettings /*! @brief The Volume class provides asbtract volume interface * @author Ilya Kotov <forkotov02@hotmail.ru> */ -class Volume +class Volume : public QObject { + Q_OBJECT public: /*! * Destructor. @@ -59,6 +62,17 @@ public: * Returns volume level of the \b channel. */ virtual VolumeSettings volume() const = 0; + /*! + * Returns true if the object supports change notification via + * emitting changed() signal so polling the volume is not needed. + */ + virtual bool hasNotifySignal() const + { + return false; + } + +signals: + void changed(); }; #endif // VOLUME_H diff --git a/src/qmmp/volumecontrol.cpp b/src/qmmp/volumecontrol.cpp index 6cef32747..9770f5101 100644 --- a/src/qmmp/volumecontrol.cpp +++ b/src/qmmp/volumecontrol.cpp @@ -133,7 +133,15 @@ void VolumeControl::reload() if(!QmmpSettings::instance()->useSoftVolume() && Output::currentFactory()) { if((m_volume = Output::currentFactory()->createVolume())) - m_timer->start(150); + { + if(m_volume->hasNotifySignal()) + { + checkVolume(); + connect(m_volume, SIGNAL(changed()), SLOT(checkVolume())); + } + else + m_timer->start(150); // fallback to polling if change notification is not available. + } } if(!m_volume) { |
