Skip to content

Commit

Permalink
Rewrite of AlsaMixerPlugin to use volume_mapping
Browse files Browse the repository at this point in the history
Changed AlsaMixerPlugin to use the get and set normalized from volume_mapping of alsa-utils/alsamixer
Changed volume_mapping set volume to be for all channels
added volume_mapping files to Makefile.am
  • Loading branch information
TermeHansen committed Jan 4, 2017
1 parent 1e10158 commit 294dcc3
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 88 deletions.
4 changes: 3 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -1378,7 +1378,9 @@ MIXER_API_SRC = \
libmixer_plugins_a_SOURCES = \
src/mixer/plugins/NullMixerPlugin.cxx \
src/mixer/plugins/SoftwareMixerPlugin.cxx \
src/mixer/plugins/SoftwareMixerPlugin.hxx
src/mixer/plugins/volume_mapping.hxx \
src/mixer/plugins/volume_mapping.cxx

libmixer_plugins_a_CPPFLAGS = $(AM_CPPFLAGS) \
$(ALSA_CFLAGS) \
$(PULSE_CFLAGS)
Expand Down
72 changes: 3 additions & 69 deletions src/mixer/plugins/AlsaMixerPlugin.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@
#include "util/Domain.hxx"
#include "util/RuntimeError.hxx"
#include "Log.hxx"
#include "mixer/plugins/volume_mapping.hxx"

#include <algorithm>

#include <alsa/asoundlib.h>

#define VOLUME_MIXER_ALSA_DEFAULT "default"
#define VOLUME_MIXER_ALSA_CONTROL_DEFAULT "PCM"
#define VOLUME_MIXER_ALSA_LOG_DEFAULT "linear"
#define VOLUME_MIXER_ALSA_LOG_PARAM_DEFAULT "1.0"
static constexpr unsigned VOLUME_MIXER_ALSA_INDEX_DEFAULT = 0;

class AlsaMixerMonitor final : MultiSocketMonitor, DeferredMonitor {
Expand Down Expand Up @@ -67,14 +66,9 @@ class AlsaMixer final : public Mixer {
const char *device;
const char *control;
unsigned int index;
const char *scale;
double scale_log_param;

snd_mixer_t *handle;
snd_mixer_elem_t *elem;
long volume_min;
long volume_max;
int volume_set;

AlsaMixerMonitor *monitor;

Expand Down Expand Up @@ -176,10 +170,6 @@ AlsaMixer::Configure(const ConfigBlock &block)
VOLUME_MIXER_ALSA_CONTROL_DEFAULT);
index = block.GetBlockValue("mixer_index",
VOLUME_MIXER_ALSA_INDEX_DEFAULT);
scale = block.GetBlockValue("mixer_scale",
VOLUME_MIXER_ALSA_LOG_DEFAULT);
scale_log_param = atof (block.GetBlockValue("mixer_log_param",
VOLUME_MIXER_ALSA_LOG_PARAM_DEFAULT));
}

static Mixer *
Expand Down Expand Up @@ -236,9 +226,6 @@ AlsaMixer::Setup()
if (elem == nullptr)
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(elem, alsa_mixer_elem_callback);

Expand All @@ -250,8 +237,6 @@ AlsaMixer::Open()
{
int err;

volume_set = -1;

err = snd_mixer_open(&handle, 0);
if (err < 0)
throw FormatRuntimeError("snd_mixer_open() failed: %s",
Expand Down Expand Up @@ -280,8 +265,6 @@ int
AlsaMixer::GetVolume()
{
int err;
int ret;
long level;

assert(handle != nullptr);

Expand All @@ -290,67 +273,18 @@ AlsaMixer::GetVolume()
throw FormatRuntimeError("snd_mixer_handle_events() failed: %s",
snd_strerror(err));

err = snd_mixer_selem_get_playback_volume(elem,
SND_MIXER_SCHN_FRONT_LEFT,
&level);
if (err < 0)
throw FormatRuntimeError("failed to read ALSA volume: %s",
snd_strerror(err));


if ( strcmp( scale, "log") == 0 ) {
ret = scale_log_param*(volume_max-volume_min)*(log(volume_set)/log(100.)-1.)
+ volume_max+0.5;
}
else {
ret = ((volume_set / 100.0) * (volume_max - volume_min)
+ volume_min) + 0.5;
}

if (volume_set > 0 && ret == level) {
ret = volume_set;
}
else if (level == 0) {ret=0;}
else {
if ( strcmp( scale, "log") == 0 ) {
ret = (int)exp(log(100)*(level-volume_max)
/(scale_log_param*(volume_max-volume_min))+log(100));
}
else {
ret = (int)(100 * (((float)(level - volume_min))
/(volume_max - volume_min)) + 0.5);
}
}

return ret;
return (int)100*get_normalized_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT);
}

void
AlsaMixer::SetVolume(unsigned volume)
{
float vol;
long level;
int err;

assert(handle != nullptr);

vol = volume;

volume_set = vol + 0.5;
if (vol == 0) {level=volume_min;}
else {
if ( strcmp( scale, "log") == 0 ) {
level = (long)(scale_log_param*(volume_max-volume_min))*(log(vol)
/log(100.)-1.)+volume_max+0.5;
}
else {
level = (long)(((vol / 100.0) * (volume_max - volume_min)
+ volume_min) + 0.5);
}
level = Clamp(level, volume_min, volume_max);
}
err = set_normalized_playback_volume(elem, 0.01*volume, 1);

err = snd_mixer_selem_set_playback_volume_all(elem, level);
if (err < 0)
throw FormatRuntimeError("failed to set ALSA volume: %s",
snd_strerror(err));
Expand Down
30 changes: 14 additions & 16 deletions src/mixer/plugins/volume_mapping.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@

#define _ISOC99_SOURCE /* lrint() */
#define _GNU_SOURCE /* exp10() */
#include "aconfig.h"
//#include "aconfig.h"
#include <math.h>
#include <stdbool.h>
#include "volume_mapping.h"
#include "volume_mapping.hxx"

#ifdef __UCLIBC__
/* 10^x = 10^(log e^x) = (e^x)^log10 = e^(x * log 10) */
Expand Down Expand Up @@ -77,13 +77,13 @@ static int (* const get_raw[2])(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t
snd_mixer_selem_get_playback_volume,
snd_mixer_selem_get_capture_volume,
};
static int (* const set_dB[2])(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long, int) = {
snd_mixer_selem_set_playback_dB,
snd_mixer_selem_set_capture_dB,
static int (* const set_dB[2])(snd_mixer_elem_t *, long, int) = {
snd_mixer_selem_set_playback_dB_all,
snd_mixer_selem_set_capture_dB_all,
};
static int (* const set_raw[2])(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long) = {
snd_mixer_selem_set_playback_volume,
snd_mixer_selem_set_capture_volume,
static int (* const set_raw[2])(snd_mixer_elem_t *, long) = {
snd_mixer_selem_set_playback_volume_all,
snd_mixer_selem_set_capture_volume_all,
};

static double get_normalized_volume(snd_mixer_elem_t *elem,
Expand Down Expand Up @@ -124,7 +124,6 @@ static double get_normalized_volume(snd_mixer_elem_t *elem,
}

static int set_normalized_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_channel_id_t channel,
double volume,
int dir,
enum ctl_dir ctl_dir)
Expand All @@ -140,20 +139,20 @@ static int set_normalized_volume(snd_mixer_elem_t *elem,
return err;

value = lrint_dir(volume * (max - min), dir) + min;
return set_raw[ctl_dir](elem, channel, value);
return set_raw[ctl_dir](elem, value);
}

if (use_linear_dB_scale(min, max)) {
value = lrint_dir(volume * (max - min), dir) + min;
return set_dB[ctl_dir](elem, channel, value, dir);
return set_dB[ctl_dir](elem, value, dir);
}

if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
min_norm = exp10((min - max) / 6000.0);
volume = volume * (1 - min_norm) + min_norm;
}
value = lrint_dir(6000.0 * log10(volume), dir) + max;
return set_dB[ctl_dir](elem, channel, value, dir);
return set_dB[ctl_dir](elem, value, dir);
}

double get_normalized_playback_volume(snd_mixer_elem_t *elem,
Expand All @@ -168,18 +167,17 @@ double get_normalized_capture_volume(snd_mixer_elem_t *elem,
return get_normalized_volume(elem, channel, CAPTURE);
}


int set_normalized_playback_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_channel_id_t channel,
double volume,
int dir)
{
return set_normalized_volume(elem, channel, volume, dir, PLAYBACK);
return set_normalized_volume(elem, volume, dir, PLAYBACK);
}

int set_normalized_capture_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_channel_id_t channel,
double volume,
int dir)
{
return set_normalized_volume(elem, channel, volume, dir, CAPTURE);
return set_normalized_volume(elem, volume, dir, CAPTURE);
}
2 changes: 0 additions & 2 deletions src/mixer/plugins/volume_mapping.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ double get_normalized_playback_volume(snd_mixer_elem_t *elem,
double get_normalized_capture_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_channel_id_t channel);
int set_normalized_playback_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_channel_id_t channel,
double volume,
int dir);
int set_normalized_capture_volume(snd_mixer_elem_t *elem,
snd_mixer_selem_channel_id_t channel,
double volume,
int dir);

Expand Down

0 comments on commit 294dcc3

Please sign in to comment.