[pulseaudio-discuss] [PATCH] volumes: Implement options to bypass the base volume system.
Maarten Bosmans
mkbosmans at gmail.com
Fri Sep 9 00:58:56 PDT 2011
Thanks for the explanation, it's a lot clearer now than when you tried
to do it on IRC.
2011/9/8 Colin Guthrie <colin at mageia.org>:
> When the underlying hardware (typically ALSA) reports that the dB
> volume ranges to to a value >0dB, a 'base volume' is automatically
> added. This system allows the user to utilise the full range of the
> underlying hardware controls (ranging from PA_VOLUME_MIN to
> PA_VOLUME_NORM) but still get informed, via UI clues, as to the point
> the hardware reports as 0dB (i.e. the point at which your sound should
> be unmodified).
Indeed, I just discovered that I also have such hardware (PCM has 12
dB of overhead above 0 dB). Do we have any idea how common this is and
whether most alsa drivers report the dBs correctly now?
I would very much like to have this mode the default (eventually,
probably not pre-1.0), because it seems a lot more useful to me.
> Sadly, this system does not work for some users. Sometimes the range
> where the volume remains below the underlying 0dB point is very small
> (e.g. from 0 to 20%). In this scenario, things are made very awkward for
> users as the active range they typically want to adjust is so small.
>
> Added to the above scenario, if the user has flat volumes enabled they
> will also get this limited range within application volume controls.
>
> This particular scenario has prompted some applications to implement
> their own work arounds to this problem and scale the whole volume range
> they expose to the base volume when flat volumes are enabled. This
> means that the scale the user sees inside the application will be
> different to e.g. the scale given by panel applet volume controls,
> OSD displays+volume keys and full blown mixers GUIs.
>
> This inconsistency in applications is what has prompted this feature.
> It allows users to choose whether or not they want to expose the base
> volume and get the full range of h/w control (as currently), or whether
> they would prefer to honour the 0dB of the underlying h/w and set
> that to our 0dB point (aka 100%). UIs which honour PA_VOLUME_UI_MAX will
> still offer the user some of the additional range their h/w supports
>>0dB.
Is a (disabled by default) per user preference enough to make
applications stop implementing the different volume scale? This looks
like a candidate for paprefs to me.
Perhaps, in order to still expose the whole hw volume in the new mode,
we could make PA_VOLUME_UI_MAX the maximum of the current value and
the maximum hardware volume setting. (ignoring any implementation
difficulties for the moment)
> The behaviour remains unchanged by default and users will have to set
> the feature manually in daemon.conf. The option is split so the user can
> choose to apply it separately for sinks (where the problem is most
> visible) and sources.
As David said, this might not be a good thing for sources. Let me
apply the patch and play with it a bit this weekend.
> ---
> src/daemon/daemon-conf.c | 6 ++++++
> src/daemon/daemon-conf.h | 2 ++
> src/daemon/daemon.conf.in | 2 ++
> src/daemon/main.c | 2 ++
> src/modules/alsa/alsa-sink.c | 17 ++++++++++++-----
> src/modules/alsa/alsa-source.c | 17 ++++++++++++-----
> src/pulsecore/core.h | 2 ++
> 7 files changed, 38 insertions(+), 10 deletions(-)
>
> diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
> index c4ee544..5fb10a0 100644
> --- a/src/daemon/daemon-conf.c
> +++ b/src/daemon/daemon-conf.c
> @@ -71,6 +71,8 @@ static const pa_daemon_conf default_conf = {
> .disallow_module_loading = FALSE,
> .disallow_exit = FALSE,
> .flat_volumes = TRUE,
> + .sink_use_base_volume = TRUE,
> + .source_use_base_volume = TRUE,
> .exit_idle_time = 20,
> .scache_idle_time = 20,
> .auto_log_target = 1,
> @@ -535,6 +537,8 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
> { "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL },
> { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL },
> { "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL },
> + { "sink-use-base-volume", pa_config_parse_bool, &c->sink_use_base_volume, NULL },
> + { "source-use-base-volume", pa_config_parse_bool, &c->source_use_base_volume, NULL },
> { "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL },
> { "enable-sync-volume", pa_config_parse_bool, &c->sync_volume, NULL },
> { "exit-idle-time", pa_config_parse_int, &c->exit_idle_time, NULL },
> @@ -736,6 +740,8 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
> pa_strbuf_printf(s, "cpu-limit = %s\n", pa_yes_no(!c->no_cpu_limit));
> pa_strbuf_printf(s, "enable-shm = %s\n", pa_yes_no(!c->disable_shm));
> pa_strbuf_printf(s, "flat-volumes = %s\n", pa_yes_no(c->flat_volumes));
> + pa_strbuf_printf(s, "sink-use-base-volume = %s\n", pa_yes_no(c->sink_use_base_volume));
> + pa_strbuf_printf(s, "source-use-base-volume = %s\n", pa_yes_no(c->source_use_base_volume));
> pa_strbuf_printf(s, "lock-memory = %s\n", pa_yes_no(c->lock_memory));
> pa_strbuf_printf(s, "enable-sync-volume = %s\n", pa_yes_no(c->sync_volume));
> pa_strbuf_printf(s, "exit-idle-time = %i\n", c->exit_idle_time);
> diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
> index 9fd6aba..e1b7804 100644
> --- a/src/daemon/daemon-conf.h
> +++ b/src/daemon/daemon-conf.h
> @@ -75,6 +75,8 @@ typedef struct pa_daemon_conf {
> log_meta,
> log_time,
> flat_volumes,
> + sink_use_base_volume,
> + source_use_base_volume,
> lock_memory,
> sync_volume;
> pa_server_type_t local_server_type;
> diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
> index 6437f8f..dd80cce 100644
> --- a/src/daemon/daemon.conf.in
> +++ b/src/daemon/daemon.conf.in
> @@ -59,6 +59,8 @@ ifelse(@HAVE_DBUS@, 1, [dnl
> ; enable-lfe-remixing = no
>
> ; flat-volumes = yes
> +; sink-use-base-volume = yes
> +; source-use-base-volume = yes
>
> ifelse(@HAVE_SYS_RESOURCE_H@, 1, [dnl
> ; rlimit-fsize = -1
> diff --git a/src/daemon/main.c b/src/daemon/main.c
> index e7e5238..bcd879e 100644
> --- a/src/daemon/main.c
> +++ b/src/daemon/main.c
> @@ -1029,6 +1029,8 @@ int main(int argc, char *argv[]) {
> c->running_as_daemon = !!conf->daemonize;
> c->disallow_exit = conf->disallow_exit;
> c->flat_volumes = conf->flat_volumes;
> + c->sink_use_base_volume = conf->sink_use_base_volume;
> + c->source_use_base_volume = conf->source_use_base_volume;
> #ifdef HAVE_DBUS
> c->server_type = conf->local_server_type;
> #endif
> diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
> index 7d205bf..dc4bd52 100644
> --- a/src/modules/alsa/alsa-sink.c
> +++ b/src/modules/alsa/alsa-sink.c
> @@ -1284,14 +1284,18 @@ static void sink_set_volume_cb(pa_sink *s) {
> pa_assert(u->mixer_path);
> pa_assert(u->mixer_handle);
>
> - /* Shift up by the base volume */
> - pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
> + if (u->core->sink_use_base_volume)
> + /* Shift up by the base volume */
> + pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
> + else
> + r = s->real_volume;
>
> if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, sync_volume, !sync_volume) < 0)
> return;
>
> - /* Shift down by the base volume, so that 0dB becomes maximum volume */
> - pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
> + if (u->core->sink_use_base_volume)
> + /* Shift down by the base volume, so that 0dB becomes maximum volume */
> + pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
>
> u->hardware_volume = r;
>
> @@ -1421,7 +1425,10 @@ static void mixer_volume_init(struct userdata *u) {
> pa_sink_enable_decibel_volume(u->sink, TRUE);
> pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u->mixer_path->min_dB, u->mixer_path->max_dB);
>
> - u->sink->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
> + if (u->core->sink_use_base_volume)
> + u->sink->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
> + else
> + u->sink->base_volume = PA_VOLUME_NORM;
> u->sink->n_volume_steps = PA_VOLUME_NORM+1;
>
> pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->sink->base_volume));
> diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
> index fa500a1..932db4e 100644
> --- a/src/modules/alsa/alsa-source.c
> +++ b/src/modules/alsa/alsa-source.c
> @@ -1135,14 +1135,18 @@ static void source_set_volume_cb(pa_source *s) {
> pa_assert(u->mixer_path);
> pa_assert(u->mixer_handle);
>
> - /* Shift up by the base volume */
> - pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
> + if (u->core->source_use_base_volume)
> + /* Shift up by the base volume */
> + pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
> + else
> + r = s->real_volume;
>
> if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, sync_volume, !sync_volume) < 0)
> return;
>
> - /* Shift down by the base volume, so that 0dB becomes maximum volume */
> - pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
> + if (u->core->source_use_base_volume)
> + /* Shift down by the base volume, so that 0dB becomes maximum volume */
> + pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
>
> u->hardware_volume = r;
>
> @@ -1272,7 +1276,10 @@ static void mixer_volume_init(struct userdata *u) {
> pa_source_enable_decibel_volume(u->source, TRUE);
> pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u->mixer_path->min_dB, u->mixer_path->max_dB);
>
> - u->source->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
> + if (u->core->source_use_base_volume)
> + u->source->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
> + else
> + u->source->base_volume = PA_VOLUME_NORM;
> u->source->n_volume_steps = PA_VOLUME_NORM+1;
>
> pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->source->base_volume));
> diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
> index d4639e0..1e93f0d 100644
> --- a/src/pulsecore/core.h
> +++ b/src/pulsecore/core.h
> @@ -163,6 +163,8 @@ struct pa_core {
> int exit_idle_time, scache_idle_time;
>
> pa_bool_t flat_volumes:1;
> + pa_bool_t sink_use_base_volume:1;
> + pa_bool_t source_use_base_volume:1;
> pa_bool_t disallow_module_loading:1;
> pa_bool_t disallow_exit:1;
> pa_bool_t running_as_daemon:1;
> --
> 1.7.6
>
> _______________________________________________
> pulseaudio-discuss mailing list
> pulseaudio-discuss at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
>
More information about the pulseaudio-discuss
mailing list