mixer/pulse: Add a new 'scale' parameter to allow volumes above 100
Closes GH-479.
This commit is contained in:
parent
c0f57b8a8b
commit
110e6d026b
@ -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.
|
- Sets the host name of the PulseAudio server. By default, :program:`MPD` connects to the local PulseAudio server.
|
||||||
* - **sink NAME**
|
* - **sink NAME**
|
||||||
- Specifies the name of the PulseAudio sink :program:`MPD` should play on.
|
- 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
|
recorder
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
#include "mixer/MixerInternal.hxx"
|
#include "mixer/MixerInternal.hxx"
|
||||||
#include "mixer/Listener.hxx"
|
#include "mixer/Listener.hxx"
|
||||||
#include "output/plugins/PulseOutputPlugin.hxx"
|
#include "output/plugins/PulseOutputPlugin.hxx"
|
||||||
|
#include "util/NumberParser.hxx"
|
||||||
|
#include "util/RuntimeError.hxx"
|
||||||
|
#include "config/Block.hxx"
|
||||||
|
|
||||||
#include <pulse/context.h>
|
#include <pulse/context.h>
|
||||||
#include <pulse/introspect.h>
|
#include <pulse/introspect.h>
|
||||||
@ -39,11 +42,14 @@ class PulseMixer final : public Mixer {
|
|||||||
|
|
||||||
bool online;
|
bool online;
|
||||||
struct pa_cvolume volume;
|
struct pa_cvolume volume;
|
||||||
|
float volume_scale_factor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PulseMixer(PulseOutput &_output, MixerListener &_listener)
|
PulseMixer(PulseOutput &_output, MixerListener &_listener,
|
||||||
|
double _volume_scale_factor)
|
||||||
:Mixer(pulse_mixer_plugin, _listener),
|
: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);
|
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 *
|
static Mixer *
|
||||||
pulse_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
|
pulse_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
|
||||||
MixerListener &listener,
|
MixerListener &listener,
|
||||||
gcc_unused const ConfigBlock &block)
|
const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
PulseOutput &po = (PulseOutput &)ao;
|
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);
|
pulse_output_set_mixer(po, *pm);
|
||||||
|
|
||||||
@ -191,8 +214,9 @@ PulseMixer::GetVolume()
|
|||||||
int
|
int
|
||||||
PulseMixer::GetVolumeInternal()
|
PulseMixer::GetVolumeInternal()
|
||||||
{
|
{
|
||||||
|
pa_volume_t max_pa_volume = volume_scale_factor * PA_VOLUME_NORM;
|
||||||
return online ?
|
return online ?
|
||||||
(int)((100 * (pa_cvolume_avg(&volume) + 1)) / PA_VOLUME_NORM)
|
(int)((100 * (pa_cvolume_avg(&volume) + 1)) / max_pa_volume)
|
||||||
: -1;
|
: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,9 +228,11 @@ PulseMixer::SetVolume(unsigned new_volume)
|
|||||||
if (!online)
|
if (!online)
|
||||||
throw std::runtime_error("disconnected");
|
throw std::runtime_error("disconnected");
|
||||||
|
|
||||||
|
pa_volume_t max_pa_volume = volume_scale_factor * PA_VOLUME_NORM;
|
||||||
|
|
||||||
struct pa_cvolume cvolume;
|
struct pa_cvolume cvolume;
|
||||||
pa_cvolume_set(&cvolume, volume.channels,
|
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);
|
pulse_output_set_volume(output, &cvolume);
|
||||||
volume = cvolume;
|
volume = cvolume;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user