[pulseaudio-discuss] [PATCH 1/2] alsa-mixer: Implement support for setting element specific upper limits for volume.
From: Tanu Kaskinen ext-tanu.kaski...@nokia.com This feature is mainly useful in embedded systems that have built-in speakers. In such situations the full audio path is known beforehand, so it's possible to know what is the maximum sensible volume, and any higher volume can be disabled. The volume limit is set in path configuration files in the [Element] section, using option volume-limit. The value is the desired maximum volume step of the volume element. --- src/modules/alsa/alsa-mixer.c | 68 +++- src/modules/alsa/alsa-mixer.h |1 + .../alsa/mixer/paths/analog-output.conf.common |1 + 3 files changed, 69 insertions(+), 1 deletions(-) diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 9a7e045..41997a7 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -895,6 +895,9 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann long value = to_alsa_dB(f); int rounding = value 0 ? -1 : +1; +if (e-volume_limit = 0 value (e-max_dB * 100)) +value = e-max_dB * 100; + if (e-direction == PA_ALSA_DIRECTION_OUTPUT) { /* If we call set_playback_volume() without checking first * if the channel is available, ALSA behaves very @@ -1284,6 +1287,7 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { pa_assert(m); pa_assert(e); +pa_assert(e-path); SELEM_INIT(sid, e-alsa_name); @@ -1407,6 +1411,36 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { } } +if (e-volume_limit = 0) { +if (e-volume_limit = e-min_volume || e-volume_limit e-max_volume) +pa_log_warn(Volume limit for element %s of path %s is invalid: %li isn't within the valid range +%li-%li. The volume limit is ignored., +e-alsa_name, e-path-name, e-volume_limit, e-min_volume + 1, e-max_volume); + +else { +e-max_volume = e-volume_limit; + +if (e-has_dB) { +if (e-db_fix) { +e-db_fix-max_step = e-max_volume; +e-max_dB = ((double) e-db_fix-db_values[e-db_fix-max_step - e-db_fix-min_step]) / 100.0; + +} else { +if (e-direction == PA_ALSA_DIRECTION_OUTPUT) +r = snd_mixer_selem_ask_playback_vol_dB(me, e-max_volume, max_dB); +else +r = snd_mixer_selem_ask_capture_vol_dB(me, e-max_volume, max_dB); + +if (r 0) { +pa_log_warn(Failed to get dB value of %s: %s, e-alsa_name, pa_alsa_strerror(r)); +e-has_dB = FALSE; +} else +e-max_dB = ((double) max_dB) / 100.0; +} +} +} +} + if (e-direction == PA_ALSA_DIRECTION_OUTPUT) is_mono = snd_mixer_selem_is_playback_mono(me) 0; else @@ -1530,6 +1564,7 @@ static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, pa_boo e-path = p; e-alsa_name = pa_xstrdup(section); e-direction = p-direction; +e-volume_limit = -1; PA_LLIST_INSERT_AFTER(pa_alsa_element, p-elements, p-last_element, e); @@ -1864,6 +1899,33 @@ static int element_parse_direction_try_other( return 0; } +static int element_parse_volume_limit( +const char *filename, +unsigned line, +const char *section, +const char *lvalue, +const char *rvalue, +void *data, +void *userdata) { + +pa_alsa_path *p = userdata; +pa_alsa_element *e; +uint32_t volume_limit; + +if (!(e = element_get(p, section, TRUE))) { +pa_log([%s:%u] volume-limit makes no sense in '%s', filename, line, section); +return -1; +} + +if (pa_atou(rvalue, volume_limit) 0 || volume_limit LONG_MAX) { +pa_log([%s:%u] Invalid value for volume-limit, filename, line); +return -1; +} + +e-volume_limit = volume_limit; +return 0; +} + static pa_channel_position_mask_t parse_mask(const char *m) { pa_channel_position_mask_t v; @@ -2141,6 +2203,7 @@ pa_alsa_path* pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction) { required-absent, element_parse_required,NULL, NULL }, { direction, element_parse_direction, NULL, NULL }, { direction-try-other,
[pulseaudio-discuss] [PATCH 2/2] alsa-mixer: When figuring out the max_dB of a path, use only channels that are used by the path elements.
Without this, p-max_dB could never be less than 0 dB, because the loop at the end of pa_alsa_path_probe() would reset p-max_dB to 0 as soon as the loop encountered a channel that wasn't touched by any element. --- src/modules/alsa/alsa-mixer.c | 13 + 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 41997a7..3eef5f9 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -2400,6 +2400,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) { pa_alsa_element *e; double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX]; pa_channel_position_t t; +pa_channel_position_mask_t path_volume_channels = 0; pa_assert(p); pa_assert(m); @@ -2436,6 +2437,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) { if (PA_CHANNEL_POSITION_MASK(t) e-merged_mask) { min_dB[t] = e-min_dB; max_dB[t] = e-max_dB; +path_volume_channels |= PA_CHANNEL_POSITION_MASK(t); } p-has_dB = TRUE; @@ -2446,6 +2448,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) { if (PA_CHANNEL_POSITION_MASK(t) e-merged_mask) { min_dB[t] += e-min_dB; max_dB[t] += e-max_dB; +path_volume_channels |= PA_CHANNEL_POSITION_MASK(t); } } else { /* Hmm, there's another element before us @@ -2484,11 +2487,13 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) { p-max_dB = -INFINITY; for (t = 0; t PA_CHANNEL_POSITION_MAX; t++) { -if (p-min_dB min_dB[t]) -p-min_dB = min_dB[t]; +if (path_volume_channels PA_CHANNEL_POSITION_MASK(t)) { +if (p-min_dB min_dB[t]) +p-min_dB = min_dB[t]; -if (p-max_dB max_dB[t]) -p-max_dB = max_dB[t]; +if (p-max_dB max_dB[t]) +p-max_dB = max_dB[t]; +} } return 0; -- 1.7.4.1 ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH] Make pulse compile with clang
As discussed on IRC. This is basically a correctly formatted version of the patch attached to http://pulseaudio.org/ticket/883 with a small improvement in configure.ac added. Maarten 0001-Make-pulse-compile-with-clang.patch Description: Binary data ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] What tests on AMD and ARM are needed for Orc-based optimised volume scaling?
Dear Arun, your commit messages of commit 4cd90d9e [1] says the following. … Since I haven't been able to test on other architectures, the Orc code is only used when MMX/SSE* is present. This can be changed in the future after testing on AMD and ARM machines. What tests need to be performed or what tests did you run to figure out that it works. Thanks, Paul [1] http://git.0pointer.de/?p=pulseaudio.git;a=commit;h=4cd90d9e32ca9a23e3c0f7615974ea0c55ff3e49 signature.asc Description: This is a digitally signed message part ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] What tests on AMD and ARM are needed for Orc-based optimised volume scaling?
Hi Paul, On Thu, 2011-03-10 at 13:02 +0100, Paul Menzel wrote: Dear Arun, your commit messages of commit 4cd90d9e [1] says the following. … Since I haven't been able to test on other architectures, the Orc code is only used when MMX/SSE* is present. This can be changed in the future after testing on AMD and ARM machines. What tests need to be performed or what tests did you run to figure out that it works. Sorry, I should've cleaned up that comment. By AMD, I meant CPUs with 3DNow! but no SSE/MMX support. I don't actually see the 3DNOW flags used at any point other than detection, so there shouldn't be anything to worry about here. On ARM, I actually did a quick test and the Orc performance was significantly worse [1]. I don't think I tested the NEON backend, though. The test is simple - I #define RUN_TEST in each of the svolume_* files that I want to check, bump up the number of iterations to 1 or more, and then load pulseaudio a few times to get a fair measurement (the test generates N random samples and runs the scaling function on them). If you want to try this, you'll also need to adjust the conditional orc initialisation in src/pulsecore/cpu-orc.c. Cheers, Arun [1] The hand-rolled ARM code is faster than the Orc ARM backend because the former uses a single instruction that is available on ARM to do what the Orc function does using multiple instructions. I'd spoken to Orc upstream (David Schleef) about the possibility of having this scaling operation as a basic Orc operation, so that we could generate that instruction on ARM and fallback to the multiple instructions on other architectures. He was amenable to the idea, but I haven't had time to actually hack this together. ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC] Pulseaudio jack sense
Hi, I have some initial code for jack sense implementation, the approach is to listen /dev/input/eventX and pass that data as argument to a new module called module-jack-detect where a thread wakes when the jack has been inserted. Using the current code I'm able to catch jack insertion and removal, next step is to signal PA core when the jack has been inserted so this calls a hook in the PA UCM module to load the ucm configuration for jack. So, I need to send a message to any other interested module but I'm sure how implement it, Can a hook be used to signal PA core? Any suggestions appreciated. Code is available at http://git.slimlogic.co.uk/cgi-bin/cgit.cgi/pulseaudio.git/log/?h=9.20-ucm_module Thanks in advance, Margarita ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC] Pulseaudio jack sense
On 2011-03-10 22:47, Margarita Olaya wrote: Hi, I have some initial code for jack sense implementation, the approach is to listen /dev/input/eventX and pass that data as argument to a new module called module-jack-detect where a thread wakes when the jack has been inserted. Using the current code I'm able to catch jack insertion and removal, next step is to signal PA core when the jack has been inserted so this calls a hook in the PA UCM module to load the ucm configuration for jack. Jack sense is something that we all want, so it's great that someone is working on it. The first tricky thing is to match /dev/input/eventX against the proper card - that is, if you have three cards, all with headphone outputs, you must know which card your event belongs to. Is this solved in your git tree? I had a quick look but couldn't find code for doing that. (You also seem to add threads for all eventX, even those not audio related at all, could this be improved?) So, I need to send a message to any other interested module but I'm sure how implement it, Can a hook be used to signal PA core? The second thing is to figure out what we should really do once we have detected jack insertion or removal. Adding a hook event and let other modules act on that, seems reasonable to me. But we should also add a property to the property list (or something similar?) telling the current state of the jack - and btw, can this be figured out by reading from /dev/input/eventX at startup? -- David Henningsson, Canonical Ltd. http://launchpad.net/~diwic ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss