Thanks for the explanation, it's a lot clearer now than when you tried to do it on IRC.
2011/9/8 Colin Guthrie <[email protected]>: > 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss > _______________________________________________ pulseaudio-discuss mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
