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 >