Git commit dcc88734f2122d55300d9007d3968ecccf402bf6 by Trever Fischer. Committed on 26/09/2012 at 04:24. Pushed by tdfischer into branch 'kmix-improvements'. Implement basic ALSA support M +1 -0 src/daemon2/CMakeLists.txt M +8 -3 src/daemon2/backends/ALSA.cpp M +4 -0 src/daemon2/backends/ALSA.h A +102 -0 src/daemon2/backends/ALSAControl.cpp [License: UNKNOWN] = * A +29 -0 src/daemon2/backends/ALSAControl.h [License: UNKNOWN] * The files marked with a * at the end have a non valid license. Please read:= http://techbase.kde.org/Policies/Licensing_Policy and use the headers whic= h are listed at that page. http://commits.kde.org/kmix/dcc88734f2122d55300d9007d3968ecccf402bf6 diff --git a/src/daemon2/CMakeLists.txt b/src/daemon2/CMakeLists.txt index 7513156..905b620 100644 --- a/src/daemon2/CMakeLists.txt +++ b/src/daemon2/CMakeLists.txt @@ -23,6 +23,7 @@ set(kmixd_SRCS Control.cpp = backends/ALSA.cpp + backends/ALSAControl.cpp = backends/PulseAudio.cpp backends/PulseControl.cpp diff --git a/src/daemon2/backends/ALSA.cpp b/src/daemon2/backends/ALSA.cpp index 0a177b4..41a624d 100644 --- a/src/daemon2/backends/ALSA.cpp +++ b/src/daemon2/backends/ALSA.cpp @@ -1,5 +1,5 @@ #include "ALSA.h" -#include +#include "ALSAControl.h" #include = namespace Backends { @@ -11,6 +11,9 @@ ALSA::ALSA(QObject *parent) = ALSA::~ALSA() { + foreach(snd_mixer_t *mixer, m_mixers) { + snd_mixer_close(mixer); + } } = bool ALSA::open() @@ -36,13 +39,15 @@ bool ALSA::open() snd_mixer_elem_t *elem; elem =3D snd_mixer_first_elem(mixer); while (elem) { + qDebug() << "element" << snd_mixer_selem_get_name(elem= ); + Control *control =3D new AlsaControl(Control::Hardware= Output, elem, this); + registerControl(control); elem =3D snd_mixer_elem_next(elem); } - snd_mixer_detach(mixer, devName.toAscii().constData()); } else { qDebug() << "Could not attach mixer to" << devName; } - snd_mixer_close(mixer); + m_mixers << mixer; } else { qDebug() << "Could not open mixer"; } diff --git a/src/daemon2/backends/ALSA.h b/src/daemon2/backends/ALSA.h index 2247b06..922f31e 100644 --- a/src/daemon2/backends/ALSA.h +++ b/src/daemon2/backends/ALSA.h @@ -2,6 +2,8 @@ #define ALSABACKEND_H #include "Backend.h" = +#include + namespace Backends { = class ALSA : public Backend { @@ -10,6 +12,8 @@ public: ALSA(QObject *parent =3D 0); ~ALSA(); bool open(); +private: + QList m_mixers; }; = } diff --git a/src/daemon2/backends/ALSAControl.cpp b/src/daemon2/backends/AL= SAControl.cpp new file mode 100644 index 0000000..ea70379 --- /dev/null +++ b/src/daemon2/backends/ALSAControl.cpp @@ -0,0 +1,102 @@ +#include "ALSAControl.h" + +namespace Backends { + +AlsaControl::AlsaControl(Category category, snd_mixer_elem_t *elem, QObjec= t *parent) + : Control(category, parent) + , m_elem(elem) +{ +} + +AlsaControl::~AlsaControl() +{ +} + +QString AlsaControl::displayName() const +{ + return QString::fromUtf8(snd_mixer_selem_get_name(m_elem)); +} + +QString AlsaControl::iconName() const +{ + return QString(); +} + +typedef struct { + Control::Channel kmix; + snd_mixer_selem_channel_id_t alsa; +} ChannelMap; + +static ChannelMap CMAP[] =3D { + { Control::FrontLeft, SND_MIXER_SCHN_FRONT_LEFT }, + { Control::FrontRight, SND_MIXER_SCHN_FRONT_RIGHT }, + { Control::Center, SND_MIXER_SCHN_FRONT_CENTER }, + { Control::RearLeft, SND_MIXER_SCHN_REAR_LEFT }, + { Control::RearRight, SND_MIXER_SCHN_REAR_RIGHT }, + { Control::Subwoofer, SND_MIXER_SCHN_WOOFER }, + { Control::SideLeft, SND_MIXER_SCHN_SIDE_LEFT }, + { Control::SideRight, SND_MIXER_SCHN_SIDE_RIGHT }, + { Control::RearCenter, SND_MIXER_SCHN_REAR_CENTER }, + { Control::Mono, SND_MIXER_SCHN_MONO }, + { (Control::Channel)-1, (snd_mixer_selem_channel_id_t)-1 } +}; + +snd_mixer_selem_channel_id_t AlsaControl::alsaChannel(Channel c) const +{ + for(ChannelMap *map =3D &CMAP[0];map->kmix !=3D -1;map++) { + if (map->kmix =3D=3D c) + return map->alsa; + } + return SND_MIXER_SCHN_UNKNOWN; +} + +int AlsaControl::channels() const +{ + int channelCount =3D 0; + for(ChannelMap *map =3D &CMAP[0];map->kmix !=3D -1;map++) { + if (snd_mixer_selem_has_playback_channel(m_elem, map->alsa)) + channelCount++; + } + return channelCount; +} + +int AlsaControl::getVolume(Channel c) const +{ + long min; + long max; + long value; + snd_mixer_selem_get_playback_volume_range(m_elem, &min, &max); + snd_mixer_selem_get_playback_volume(m_elem, alsaChannel(c), &value); + return ((value+min)/max)*65536; +} + +void AlsaControl::setVolume(Channel c, int v) +{ +} + +bool AlsaControl::isMuted() const +{ + for(ChannelMap *map =3D &CMAP[0];map->kmix !=3D -1;map++) { + int value; + snd_mixer_selem_get_playback_switch(m_elem, map->alsa, &value); + if (value) + return true; + } + return false; +} + +bool AlsaControl::canMute() const +{ + return snd_mixer_selem_has_playback_switch(m_elem); +} + +void AlsaControl::setMute(bool yes) +{ + for(ChannelMap *map =3D &CMAP[0];map->kmix !=3D -1;map++) { + snd_mixer_selem_set_playback_switch(m_elem, map->alsa, !yes); + } +} + +} + +#include "ALSAControl.moc" diff --git a/src/daemon2/backends/ALSAControl.h b/src/daemon2/backends/ALSA= Control.h new file mode 100644 index 0000000..f92fd62 --- /dev/null +++ b/src/daemon2/backends/ALSAControl.h @@ -0,0 +1,29 @@ +#ifndef ALSACONTROL_H +#define ALSACONTROL_H + +#include "Control.h" +#include + +namespace Backends { + +class AlsaControl : public Control { + Q_OBJECT +public: + AlsaControl(Category category, snd_mixer_elem_t *elem, QObject *parent= =3D 0); + ~AlsaControl(); + QString displayName() const; + QString iconName() const; + int channels() const; + int getVolume(Channel c) const; + void setVolume(Channel c, int v); + bool isMuted() const; + void setMute(bool yes); + bool canMute() const; +private: + snd_mixer_selem_channel_id_t alsaChannel(Channel c) const; + snd_mixer_elem_t *m_elem; +}; + +} + +#endif // ALSACONTROL_H