diff options
-rw-r--r-- | doc/plugins.rst | 2 | ||||
-rw-r--r-- | src/mixer/plugins/PulseMixerPlugin.cxx | 38 |
2 files changed, 34 insertions, 6 deletions
diff --git a/doc/plugins.rst b/doc/plugins.rst index 0e09b35ab..5b39069cb 100644 --- a/doc/plugins.rst +++ b/doc/plugins.rst @@ -935,6 +935,8 @@ The pulse plugin connects to a `PulseAudio <http://www.freedesktop.org/wiki/Soft - Sets the host name of the PulseAudio server. By default, :program:`MPD` connects to the local PulseAudio server. * - **sink NAME** - Specifies the name of the PulseAudio sink :program:`MPD` should play on. + * - **scale FACTOR** + - Specifies a linear scaling coefficient (ranging from 0.5 to 5.0) to apply when adjusting volume through :program:`MPD`. For example, chosing a factor equal to ``"0.7"`` means that setting the volume to 100 in :program:`MPD` will set the PulseAudio volume to 70%, and a factor equal to ``"3.5"`` means that volume 100 in :program:`MPD` corresponds to a 350% PulseAudio volume. recorder ~~~~~~~~ diff --git a/src/mixer/plugins/PulseMixerPlugin.cxx b/src/mixer/plugins/PulseMixerPlugin.cxx index f04369fe2..d2bfb2444 100644 --- a/src/mixer/plugins/PulseMixerPlugin.cxx +++ b/src/mixer/plugins/PulseMixerPlugin.cxx @@ -24,6 +24,9 @@ #include "mixer/MixerInternal.hxx" #include "mixer/Listener.hxx" #include "output/plugins/PulseOutputPlugin.hxx" +#include "util/NumberParser.hxx" +#include "util/RuntimeError.hxx" +#include "config/Block.hxx" #include <pulse/context.h> #include <pulse/introspect.h> @@ -39,11 +42,14 @@ class PulseMixer final : public Mixer { bool online; struct pa_cvolume volume; + float volume_scale_factor; public: - PulseMixer(PulseOutput &_output, MixerListener &_listener) + PulseMixer(PulseOutput &_output, MixerListener &_listener, + double _volume_scale_factor) :Mixer(pulse_mixer_plugin, _listener), - output(_output), online(false) + output(_output), online(false), + volume_scale_factor(_volume_scale_factor) { } @@ -159,13 +165,30 @@ pulse_mixer_on_change(PulseMixer &pm, pm.Update(context, stream); } +static float +parse_volume_scale_factor(const char *value) { + if (value == nullptr) + return 1.0; + + char *endptr; + float factor = ParseFloat(value, &endptr); + + if (*endptr != '\0' || factor < 0.5 || factor > 5.0) + throw FormatRuntimeError("scale \"%s\" is not a number in the " + "range 0.5 to 5.0", + value); + + return factor; +} + static Mixer * pulse_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao, MixerListener &listener, - gcc_unused const ConfigBlock &block) + const ConfigBlock &block) { PulseOutput &po = (PulseOutput &)ao; - PulseMixer *pm = new PulseMixer(po, listener); + float scale = parse_volume_scale_factor(block.GetBlockValue("scale")); + PulseMixer *pm = new PulseMixer(po, listener, scale); pulse_output_set_mixer(po, *pm); @@ -191,8 +214,9 @@ PulseMixer::GetVolume() int PulseMixer::GetVolumeInternal() { + pa_volume_t max_pa_volume = volume_scale_factor * PA_VOLUME_NORM; return online ? - (int)((100 * (pa_cvolume_avg(&volume) + 1)) / PA_VOLUME_NORM) + (int)((100 * (pa_cvolume_avg(&volume) + 1)) / max_pa_volume) : -1; } @@ -204,9 +228,11 @@ PulseMixer::SetVolume(unsigned new_volume) if (!online) throw std::runtime_error("disconnected"); + pa_volume_t max_pa_volume = volume_scale_factor * PA_VOLUME_NORM; + struct pa_cvolume cvolume; pa_cvolume_set(&cvolume, volume.channels, - (new_volume * PA_VOLUME_NORM + 50) / 100); + (new_volume * max_pa_volume + 50) / 100); pulse_output_set_volume(output, &cvolume); volume = cvolume; } |