aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2015-08-19 09:43:17 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2015-08-19 09:43:17 +0000
commit1ef98753ff23287aaa23e0c35e03719256ea268f (patch)
tree11cb2d4f70444fb7cc704e04aca7fe41869778da
parent7a8026a4ad54588c131fefbdb5dc3fd118054011 (diff)
downloadqmmp-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.txt8
-rw-r--r--src/plugins/Output/alsa/outputalsa.cpp44
-rw-r--r--src/plugins/Output/alsa/outputalsa.h4
-rw-r--r--src/qmmp/CMakeLists.txt1
-rw-r--r--src/qmmp/volume.h18
-rw-r--r--src/qmmp/volumecontrol.cpp10
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)
{