Rewrite of AlsaMixerPlugin to use volume_mapping

Changed AlsaMixerPlugin to use the get and set normalized functions from volume_mapping of alsa-utils/alsamixer
Changed volume_mapping set volume to be for all channels and not per channel
added volume_mapping files to Makefile.am
This commit is contained in:
TermeHansen 2017-01-05 12:09:13 +01:00 committed by Max Kellermann
parent 8a32ee30a5
commit 3aa9f8af18
2 changed files with 9 additions and 42 deletions

2
NEWS
View File

@ -1,4 +1,6 @@
ver 0.20.1 (not yet released) ver 0.20.1 (not yet released)
* mixer
- alsa: normalize displayed volume according to human perception
* fix crash with volume_normalization enabled * fix crash with volume_normalization enabled
ver 0.20 (2017/01/04) ver 0.20 (2017/01/04)

View File

@ -25,15 +25,18 @@
#include "event/DeferredMonitor.hxx" #include "event/DeferredMonitor.hxx"
#include "util/ASCII.hxx" #include "util/ASCII.hxx"
#include "util/ReusableArray.hxx" #include "util/ReusableArray.hxx"
#include "util/Clamp.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "util/RuntimeError.hxx" #include "util/RuntimeError.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <algorithm> extern "C" {
#include "volume_mapping.h"
}
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <math.h>
#define VOLUME_MIXER_ALSA_DEFAULT "default" #define VOLUME_MIXER_ALSA_DEFAULT "default"
#define VOLUME_MIXER_ALSA_CONTROL_DEFAULT "PCM" #define VOLUME_MIXER_ALSA_CONTROL_DEFAULT "PCM"
static constexpr unsigned VOLUME_MIXER_ALSA_INDEX_DEFAULT = 0; static constexpr unsigned VOLUME_MIXER_ALSA_INDEX_DEFAULT = 0;
@ -68,9 +71,6 @@ class AlsaMixer final : public Mixer {
snd_mixer_t *handle; snd_mixer_t *handle;
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
long volume_min;
long volume_max;
int volume_set;
AlsaMixerMonitor *monitor; AlsaMixerMonitor *monitor;
@ -228,9 +228,6 @@ AlsaMixer::Setup()
if (elem == nullptr) if (elem == nullptr)
throw FormatRuntimeError("no such mixer control: %s", control); throw FormatRuntimeError("no such mixer control: %s", control);
snd_mixer_selem_get_playback_volume_range(elem, &volume_min,
&volume_max);
snd_mixer_elem_set_callback_private(elem, this); snd_mixer_elem_set_callback_private(elem, this);
snd_mixer_elem_set_callback(elem, alsa_mixer_elem_callback); snd_mixer_elem_set_callback(elem, alsa_mixer_elem_callback);
@ -242,8 +239,6 @@ AlsaMixer::Open()
{ {
int err; int err;
volume_set = -1;
err = snd_mixer_open(&handle, 0); err = snd_mixer_open(&handle, 0);
if (err < 0) if (err < 0)
throw FormatRuntimeError("snd_mixer_open() failed: %s", throw FormatRuntimeError("snd_mixer_open() failed: %s",
@ -272,8 +267,6 @@ int
AlsaMixer::GetVolume() AlsaMixer::GetVolume()
{ {
int err; int err;
int ret;
long level;
assert(handle != nullptr); assert(handle != nullptr);
@ -282,43 +275,15 @@ AlsaMixer::GetVolume()
throw FormatRuntimeError("snd_mixer_handle_events() failed: %s", throw FormatRuntimeError("snd_mixer_handle_events() failed: %s",
snd_strerror(err)); snd_strerror(err));
err = snd_mixer_selem_get_playback_volume(elem, return lrint(100 * get_normalized_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT));
SND_MIXER_SCHN_FRONT_LEFT,
&level);
if (err < 0)
throw FormatRuntimeError("failed to read ALSA volume: %s",
snd_strerror(err));
ret = ((volume_set / 100.0) * (volume_max - volume_min)
+ volume_min) + 0.5;
if (volume_set > 0 && ret == level) {
ret = volume_set;
} else {
ret = (int)(100 * (((float)(level - volume_min)) /
(volume_max - volume_min)) + 0.5);
}
return ret;
} }
void void
AlsaMixer::SetVolume(unsigned volume) AlsaMixer::SetVolume(unsigned volume)
{ {
float vol;
long level;
int err;
assert(handle != nullptr); assert(handle != nullptr);
vol = volume; int err = set_normalized_playback_volume(elem, 0.01*volume, 1);
volume_set = vol + 0.5;
level = (long)(((vol / 100.0) * (volume_max - volume_min) +
volume_min) + 0.5);
level = Clamp(level, volume_min, volume_max);
err = snd_mixer_selem_set_playback_volume_all(elem, level);
if (err < 0) if (err < 0)
throw FormatRuntimeError("failed to set ALSA volume: %s", throw FormatRuntimeError("failed to set ALSA volume: %s",
snd_strerror(err)); snd_strerror(err));