Re: [pulseaudio-discuss] [PATCH] SSE/MMX/ARM: Fix high frequency noise with unusual number of channels
We have got three confirmations that the patch is working in the bug below, so I believe it can be safely applied to both master and stable-queue. On 2010-10-08 19:00, David Henningsson wrote: I would kindly ask for comments for this patch before applying, just double-check that I thought the right way when fixing this one. BugLink: https://launchpad.net/bugs/445849 In the assembly optimized versions of SSE, a noise could occur when the number of channels were 3,5,6 or 7. For MMX and ARM, this could occur when the number of channels were 3. Signed-off-by: David Henningsson david.hennings...@canonical.com ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss -- 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
Re: [pulseaudio-discuss] [PATCH] SSE/MMX/ARM: Fix high frequency noise with unusual number of channels
'Twas brillig, and David Henningsson at 13/10/10 07:27 did gyre and gimble: We have got three confirmations that the patch is working in the bug below, so I believe it can be safely applied to both master and stable-queue. Great! Would you mind respinning the patch with a couple more inline comments? I'm a little concerned about the lines such as channels = channels == 3 ? 6 : PA_MAX() It will be a bit disconcerting to read this in code without really reading the relevant commit message, so I think a small hint towards why this is done would be good here. Or perhaps create a couple macros instead then document the macro definitions? Whatever you prefer, but I think some hints are needed at the code level. Cheers Col -- Colin Guthrie gmane(at)colin.guthr.ie http://colin.guthr.ie/ Day Job: Tribalogic Limited [http://www.tribalogic.net/] Open Source: Mageia Contributor [http://www.mageia.org/] PulseAudio Hacker [http://www.pulseaudio.org/] Trac Hacker [http://trac.edgewall.org/] ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH] doxygen doc updates
'Twas brillig, and David Fries at 13/10/10 03:38 did gyre and gimble: I fixed some doxygen documentation comment typos and grammar. This also adds for exaple 'See also Audio Streams' in stream_8h.html to the overview for Audio Streams to make it easier to get to the overview of those functions. The patches can also be retrieved by git. git-pull http://spacedout.fries.net/~david/git/pulseaudio dfries_doc Thanks David. Applied with a couple very minor tweaks by me. Documentation updates are always welcome. Thank you very much :) Col -- Colin Guthrie gmane(at)colin.guthr.ie http://colin.guthr.ie/ Day Job: Tribalogic Limited [http://www.tribalogic.net/] Open Source: Mageia Contributor [http://www.mageia.org/] PulseAudio Hacker [http://www.pulseaudio.org/] Trac Hacker [http://trac.edgewall.org/] ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH] bluetooth: Add support for Media API
'Twas brillig, and Colin Guthrie at 11/10/10 14:05 did gyre and gimble: 'Twas brillig, and Luiz Augusto von Dentz at 11/10/10 13:45 did gyre and gimble: The following changes since commit 3de129f3ac8dd6cf51178b266837db4d5e4a1215: introspect: Include whether a stream is corked in the info callback. (2010-10-06 09:17:01 +0100) are available in the git repository at: git://gitorious.org/~vudentz/pulseaudio/vudentzs-clone.git master Luiz Augusto von Dentz (1): bluetooth: Add support for Media API src/modules/bluetooth/bluetooth-util.c | 666 ++- src/modules/bluetooth/bluetooth-util.h | 26 + src/modules/bluetooth/ipc.h | 28 + src/modules/bluetooth/module-bluetooth-device.c | 461 ++-- 4 files changed, 1109 insertions(+), 72 deletions(-) H, I'm not sure the above info is correct... I was able to find this via: git://gitorious.org/pulseaudio/mainline.git But not from your personal clone at the above URL... Strange :s Anyway, I'll try and merge in tonight. I don't know much about the BT side of things but I doubt there will be anything too controversial in there (other than 666 lines changed - very demonic :D) :) OK, I've had a quick review of this and while I'm no expert on this stuff it certainly *looks* vaguely sensible. I'll defer to your more indepth knowledge of bluetooth and push this to git master. My only comment is that there appear to be some fairly generic dbus utility functions in there that may be better suited to dbus-util.{h,c} so they can be reused - perhaps I've misinterpreted this tho', so feel free to ignore this comment if that's the case :D I've not tested at runtime (only compile tested for now), but what would I need to do to see this in action? I have dbus 1.4 here, are there any other requirements or will this just work? Also should we make dbus 1.4 a minimum requirement in configure.ac, or does this fall back gracefully (I see a few ifdefs in there but not 100% sure if this is backwards compatible). Cheers Col -- Colin Guthrie gmane(at)colin.guthr.ie http://colin.guthr.ie/ Day Job: Tribalogic Limited [http://www.tribalogic.net/] Open Source: Mageia Contributor [http://www.mageia.org/] PulseAudio Hacker [http://www.pulseaudio.org/] Trac Hacker [http://trac.edgewall.org/] ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH] SSE/MMX/ARM: Fix high frequency noise with unusual number of channels
On 2010-10-13 09:53, Colin Guthrie wrote: 'Twas brillig, and David Henningsson at 13/10/10 07:27 did gyre and gimble: We have got three confirmations that the patch is working in the bug below, so I believe it can be safely applied to both master and stable-queue. Great! Would you mind respinning the patch with a couple more inline comments? I'm a little concerned about the lines such as channels = channels == 3 ? 6 : PA_MAX() It will be a bit disconcerting to read this in code without really reading the relevant commit message, so I think a small hint towards why this is done would be good here. Thanks for reviewing the patch, I agree that a little clearer comment wouldn't hurt, so here's a revised version. -- David Henningsson, Canonical Ltd. http://launchpad.net/~diwic From 0bde1e26fd9b2b6c1cf3d914ad11347b0d852539 Mon Sep 17 00:00:00 2001 From: David Henningsson david.hennings...@canonical.com Date: Fri, 8 Oct 2010 18:47:00 +0200 Subject: [PATCH] SSE/MMX/ARM: Fix high frequency noise with unusual number of channels In the assembly optimized versions of SSE, a noise could occur when the number of channels were 3,5,6 or 7. For MMX and ARM, this could occur when the number of channels were 3. Signed-off-by: David Henningsson david.hennings...@canonical.com --- src/pulsecore/svolume_arm.c |5 - src/pulsecore/svolume_mmx.c | 14 -- src/pulsecore/svolume_sse.c | 19 +-- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/pulsecore/svolume_arm.c b/src/pulsecore/svolume_arm.c index 5bd1448..fdd8f09 100644 --- a/src/pulsecore/svolume_arm.c +++ b/src/pulsecore/svolume_arm.c @@ -47,7 +47,10 @@ pa_volume_s16ne_arm (int16_t *samples, int32_t *volumes, unsigned channels, unsi { int32_t *ve; -channels = PA_MAX (4U, channels); +/* Channels must be at least 4, and always a multiple of the original number. + * This is also the max amount we overread the volume array, which should + * have enough padding. */ +channels = channels == 3 ? 6 : PA_MAX (4U, channels); ve = volumes + channels; __asm__ __volatile__ ( diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c index e50ebee..a71a39b 100644 --- a/src/pulsecore/svolume_mmx.c +++ b/src/pulsecore/svolume_mmx.c @@ -98,9 +98,10 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi { pa_reg_x86 channel, temp; -/* the max number of samples we process at a time, this is also the max amount - * we overread the volume array, which should have enough padding. */ -channels = PA_MAX (4U, channels); +/* Channels must be at least 4, and always a multiple of the original number. + * This is also the max amount we overread the volume array, which should + * have enough padding. */ +channels = channels == 3 ? 6 : PA_MAX (4U, channels); __asm__ __volatile__ ( xor %3, %3\n\t @@ -164,9 +165,10 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi { pa_reg_x86 channel, temp; -/* the max number of samples we process at a time, this is also the max amount - * we overread the volume array, which should have enough padding. */ -channels = PA_MAX (4U, channels); +/* Channels must be at least 4, and always a multiple of the original number. + * This is also the max amount we overread the volume array, which should + * have enough padding. */ +channels = channels == 3 ? 6 : PA_MAX (4U, channels); __asm__ __volatile__ ( xor %3, %3\n\t diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c index 1cc4e0a..5983164 100644 --- a/src/pulsecore/svolume_sse.c +++ b/src/pulsecore/svolume_sse.c @@ -74,14 +74,19 @@ por %%xmm4, #s1\n\t /* .. | l h | */ \ por %%xmm5, #s2\n\t + +static int channel_overread_table[8] = {8,8,8,12,8,10,12,14}; + static void pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length) { pa_reg_x86 channel, temp; -/* the max number of samples we process at a time, this is also the max amount - * we overread the volume array, which should have enough padding. */ -channels = PA_MAX (8U, channels); +/* Channels must be at least 8 and always a multiple of the original number. + * This is also the max amount we overread the volume array, which should + * have enough padding. */ +if (channels 8) +channels = channel_overread_table[channels]; __asm__ __volatile__ ( xor %3, %3\n\t @@ -159,9 +164,11 @@ pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns { pa_reg_x86 channel, temp; -/* the max number of samples we process at a time, this is also the max amount - * we overread the volume array, which should have enough padding. */ -channels =
Re: [pulseaudio-discuss] accessing native ALSA directly while pulseaudio is running
Ng Oon-Ee ngoo...@gmail.com writes: On Tue, 2010-10-12 at 22:47 +0200, Christoph Groth wrote: Now I wonder, is it possible to have some applications accessing the native ALSA device while pulseaudio is running? Basically, no, the sound-card cannot be shared that way. Perhaps if you use dmix, but apps which use mmap don't play well with that either I think. Now that you mention this, I remember that while I was still using solely ALSA, it was not possible to play sound from other applications while aeolus was running. ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] accessing native ALSA directly while pulseaudio is running
Luke Yelavich them...@ubuntu.com writes: On Wed, Oct 13, 2010 at 09:09:42AM EST, Ng Oon-Ee wrote: On Tue, 2010-10-12 at 22:47 +0200, Christoph Groth wrote: Now I wonder, is it possible to have some applications accessing the native ALSA device while pulseaudio is running? Basically, no, the sound-card cannot be shared that way. Perhaps if you use dmix, but apps which use mmap don't play well with that either I think. Alternatively, there is the PulseAudio dbus hand-off. Jack2 uses dbus to talk to pulse, to request the device. Pulse lets go of the device whilst jack2 uses it, and then grabs it again once jack2 is done. Aeolus can use jack, at least according to the package metadata in front of me for Ubuntu 10.10. You could use jack2, which get the alsa device from Pulse, and use aeolus that way. Thank you for your effort in looking this up, Luke. Indeed, aeolus also works with jack, and I've been thinking of using this to solve the issue. However, I assumed that the only way is to have jack access the hardware with pulseaudio running as a jack client. This does not seem to be a very nice solution, as I do not need jack most of the time. The solution you mention seems to be the way to go. I'll try it out once I have some time. Christoph ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH] bluetooth: Add support for Media API
Hi, On Wed, Oct 13, 2010 at 11:40 AM, Colin Guthrie gm...@colin.guthr.ie wrote: 'Twas brillig, and Colin Guthrie at 11/10/10 14:05 did gyre and gimble: 'Twas brillig, and Luiz Augusto von Dentz at 11/10/10 13:45 did gyre and gimble: The following changes since commit 3de129f3ac8dd6cf51178b266837db4d5e4a1215: introspect: Include whether a stream is corked in the info callback. (2010-10-06 09:17:01 +0100) are available in the git repository at: git://gitorious.org/~vudentz/pulseaudio/vudentzs-clone.git master Luiz Augusto von Dentz (1): bluetooth: Add support for Media API src/modules/bluetooth/bluetooth-util.c | 666 ++- src/modules/bluetooth/bluetooth-util.h | 26 + src/modules/bluetooth/ipc.h | 28 + src/modules/bluetooth/module-bluetooth-device.c | 461 ++-- 4 files changed, 1109 insertions(+), 72 deletions(-) H, I'm not sure the above info is correct... I was able to find this via: git://gitorious.org/pulseaudio/mainline.git But not from your personal clone at the above URL... Strange :s Anyway, I'll try and merge in tonight. I don't know much about the BT side of things but I doubt there will be anything too controversial in there (other than 666 lines changed - very demonic :D) :) OK, I've had a quick review of this and while I'm no expert on this stuff it certainly *looks* vaguely sensible. I'll defer to your more indepth knowledge of bluetooth and push this to git master. My only comment is that there appear to be some fairly generic dbus utility functions in there that may be better suited to dbus-util.{h,c} so they can be reused - perhaps I've misinterpreted this tho', so feel free to ignore this comment if that's the case :D Hmm, I didn't notice there is a dbus-util in pa and yes those can probably be reused so they should be moved there. I've not tested at runtime (only compile tested for now), but what would I need to do to see this in action? I have dbus 1.4 here, are there any other requirements or will this just work? Also should we make dbus 1.4 a minimum requirement in configure.ac, or does this fall back gracefully (I see a few ifdefs in there but not 100% sure if this is backwards compatible). It should just works, for now it has to be enabled in /etc/bluetooth/audio.conf to really start using D-Bus to pass the socket fd, but in case this is not enabled (or the libdbus has no support for fd type) then it just uses the old mechanism. There is a cover letter explaining in details how to enable it, well if it ever went to the ml. I actually did this to avoid build dependency on dbus 1.4 since many distro do not have it yet and iirc Lennart said it has more changes coming for 1.4.1, this should buy us some time to fix any possible bug/regression. -- Luiz Augusto von Dentz Computer Engineer ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH] SSE/MMX/ARM: Fix high frequency noise with unusual number of channels
'Twas brillig, and David Henningsson at 13/10/10 10:18 did gyre and gimble: On 2010-10-13 09:53, Colin Guthrie wrote: 'Twas brillig, and David Henningsson at 13/10/10 07:27 did gyre and gimble: We have got three confirmations that the patch is working in the bug below, so I believe it can be safely applied to both master and stable-queue. Great! Would you mind respinning the patch with a couple more inline comments? I'm a little concerned about the lines such as channels = channels == 3 ? 6 : PA_MAX() It will be a bit disconcerting to read this in code without really reading the relevant commit message, so I think a small hint towards why this is done would be good here. Thanks for reviewing the patch, I agree that a little clearer comment wouldn't hurt, so here's a revised version. Great, thanks. Pushed now to master and s-q. Col -- Colin Guthrie gmane(at)colin.guthr.ie http://colin.guthr.ie/ Day Job: Tribalogic Limited [http://www.tribalogic.net/] Open Source: Mageia Contributor [http://www.mageia.org/] PulseAudio Hacker [http://www.pulseaudio.org/] Trac Hacker [http://trac.edgewall.org/] ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH 5/5] man: sync_volume parameters to manual page
From: Jyri Sarha jyri.sa...@nokia.com Signed-off-by: Jyri Sarha jyri.sa...@nokia.com Reviewed-by: Tanu Kaskinen tanu.kaski...@digia.com --- man/pulse-daemon.conf.5.xml.in | 26 ++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in index b5c9e92..ccc2db7 100644 --- a/man/pulse-daemon.conf.5.xml.in +++ b/man/pulse-daemon.conf.5.xml.in @@ -437,6 +437,32 @@ USA. /section + section name=Default Sync Volume Settings + +pThe flat volume feature sets the sink HW volume according to +highest volume input stream and lowers the lower volume streams +with SW volume. To make this concurrent use of SW and HW volume to +work without a glitch their application needs to be +synchronized. The sink implementation needs to support this +feature in order to these parameters to take effect./p + +option + poptenable-sync-volume=/opt Enable sync volume for the sinks that + support it. This feature is enabled by default./p +/option +option + poptsync-volume-safety-margin-usec=/opt The amount usecs the HW + volume increases are delayed and HW volume decreases are advanced. Defaults + to 8000 usec./p +/option +option + poptsync-volume-extra-delay-usec=/opt The amount usecs the + all HW volume changes are delayed. Negative values are also allowed. + Defaults to 0./p +/option + + /section + section name=Authors pThe PulseAudio Developers lt;@PACKAGE_BUGREPORT@gt;; PulseAudio is available from url href=@PACKAGE_URL@//p /section -- 1.7.0.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH 0/5] HW and SW volume syncronization in IO-thread
From: Jyri Sarha jyri.sa...@nokia.com The first patch in the set gives sink implementor a possibility to synchronize HW and SW volume usage in IO-thread. The remaining patches implement the synchronization for the alsa-sink and add the necessary module parameters and defaults for them in daemon configuration. This code has been tested on Nokia's ARM based Meego platform, on i686 laptop and on amd64 desktop. Tanu Kaskinen has also reviewed the code. To check what this set of patches does, please try following: 1. play white noise in background on low volume: # pacat --fix-rate --volume=1 /dev/urandom 2. play a short transient stream with high volume while the noise plays in background: # dd if=/dev/zero count=200 | pacat --fix-rate --volume=65536 Without these patches on most hardware you hear an annoying snap either in the beginning or the end (sometimes both) of the transient stream. After applying the patch the snap should be gone or at least less audible. With a little fiddling of the parameters it should be possible to get rid of the snap on all hardware. The default parameters work well at least on my Lenovo T60 running Debian Squeeze and they should be good, maybe a bit conservative, for most HW out there. This patch is pretty much mandatory for proper usage of flat volume especially on less powerful HW. Cheers, Jyri ps. This is my second attempt to try to get this functionality in. This second version the patches is improved from the earlier and there is no need locks anymore. I can't think of any more improvements to it, so please let me know if I should still do something to get this integrated. Jyri Sarha (5): core: Add infrastructure for synchronizing HW and SW volume changes alsa: Take syncronized HW volume infra into use for alsa-sink udev-detect: Add sync_volume parameter daemon-conf: Add sync volume parameters to daemon-conf man: sync_volume parameters to manual page man/pulse-daemon.conf.5.xml.in | 26 src/daemon/daemon-conf.c|9 + src/daemon/daemon-conf.h|5 +- src/daemon/daemon.conf.in |4 + src/daemon/main.c |3 + src/modules/alsa/alsa-mixer.c | 117 ++- src/modules/alsa/alsa-mixer.h |9 +- src/modules/alsa/alsa-sink.c| 128 ++-- src/modules/alsa/alsa-source.c |2 +- src/modules/alsa/module-alsa-card.c |4 +- src/modules/alsa/module-alsa-sink.c | 10 +- src/modules/module-udev-detect.c| 18 ++- src/pulse/def.h |7 +- src/pulsecore/core.c|4 + src/pulsecore/core.h|3 + src/pulsecore/sink.c| 281 +-- src/pulsecore/sink.h| 97 ++-- 17 files changed, 672 insertions(+), 55 deletions(-) ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH 3/5] udev-detect: Add sync_volume parameter
From: Jyri Sarha jyri.sa...@nokia.com Signed-off-by: Jyri Sarha jyri.sa...@nokia.com Reviewed-by: Tanu Kaskinen tanu.kaski...@digia.com --- src/modules/module-udev-detect.c | 18 +++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c index f143c28..775094d 100644 --- a/src/modules/module-udev-detect.c +++ b/src/modules/module-udev-detect.c @@ -45,7 +45,8 @@ PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(TRUE); PA_MODULE_USAGE( tsched=enable system timer based scheduling mode? -ignore_dB=ignore dB information from the device?); +ignore_dB=ignore dB information from the device? +sync_volume=syncronize sw and hw voluchanges in IO-thread?); struct device { char *path; @@ -62,6 +63,7 @@ struct userdata { pa_bool_t use_tsched:1; pa_bool_t ignore_dB:1; +pa_bool_t sync_volume:1; struct udev* udev; struct udev_monitor *monitor; @@ -74,6 +76,7 @@ struct userdata { static const char* const valid_modargs[] = { tsched, ignore_dB, +sync_volume, NULL }; @@ -386,12 +389,14 @@ static void card_changed(struct userdata *u, struct udev_device *dev) { namereg_fail=false tsched=%s ignore_dB=%s +sync_volume=%s card_properties=\module-udev-detect.discovered=1\, path_get_card_id(path), n, d-card_name, pa_yes_no(u-use_tsched), -pa_yes_no(u-ignore_dB)); +pa_yes_no(u-ignore_dB), +pa_yes_no(u-sync_volume)); pa_xfree(n); pa_hashmap_put(u-devices, d-path, d); @@ -661,7 +666,8 @@ int pa__init(pa_module *m) { struct udev_enumerate *enumerate = NULL; struct udev_list_entry *item = NULL, *first = NULL; int fd; -pa_bool_t use_tsched = TRUE, ignore_dB = FALSE; +pa_bool_t use_tsched = TRUE, ignore_dB = FALSE, sync_volume = FALSE; + pa_assert(m); @@ -687,6 +693,12 @@ int pa__init(pa_module *m) { } u-ignore_dB = ignore_dB; +if (pa_modargs_get_value_boolean(ma, sync_volume, sync_volume) 0) { +pa_log(Failed to parse sync_volume= argument.); +goto fail; +} +u-sync_volume = sync_volume; + if (!(u-udev = udev_new())) { pa_log(Failed to initialize udev library.); goto fail; -- 1.7.0.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@mail.0pointer.de https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH 4/5] daemon-conf: Add sync volume parameters to daemon-conf
From: Jyri Sarha jyri.sa...@nokia.com Signed-off-by: Jyri Sarha jyri.sa...@nokia.com Reviewed-by: Tanu Kaskinen tanu.kaski...@digia.com --- src/daemon/daemon-conf.c |9 + src/daemon/daemon-conf.h |5 - src/daemon/daemon.conf.in|4 src/daemon/main.c|3 +++ src/modules/alsa/alsa-sink.c |1 + src/modules/module-udev-detect.c |2 +- src/pulsecore/core.c |4 src/pulsecore/core.h |3 +++ src/pulsecore/sink.c |6 ++ 9 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 79dd49a..74e8135 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -89,8 +89,11 @@ static const pa_daemon_conf default_conf = { .no_cpu_limit = TRUE, .disable_shm = FALSE, .lock_memory = FALSE, +.sync_volume = TRUE, .default_n_fragments = 4, .default_fragment_size_msec = 25, +.sync_volume_safety_margin_usec = 8000, +.sync_volume_extra_delay_usec = 0, .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 }, .default_channel_map = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } }, .shm_size = 0 @@ -508,6 +511,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { { enable-shm, pa_config_parse_not_bool, c-disable_shm, NULL }, { flat-volumes, pa_config_parse_bool, c-flat_volumes, 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 }, { scache-idle-time, pa_config_parse_int, c-scache_idle_time, NULL }, { realtime-priority, parse_rtprio, c, NULL }, @@ -523,6 +527,8 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { { default-channel-map,parse_channel_map,ci, NULL }, { default-fragments, parse_fragments, c, NULL }, { default-fragment-size-msec, parse_fragment_size_msec, c, NULL }, +{ sync-volume-safety-margin-usec, pa_config_parse_unsigned, c-sync_volume_safety_margin_usec, NULL }, +{ sync-volume-extra-delay-usec, pa_config_parse_int, c-sync_volume_extra_delay_usec, NULL }, { nice-level, parse_nice_level, c, NULL }, { disable-remixing, pa_config_parse_bool, c-disable_remixing, NULL }, { enable-remixing,pa_config_parse_not_bool, c-disable_remixing, NULL }, @@ -706,6 +712,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) { 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, 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); pa_strbuf_printf(s, scache-idle-time = %i\n, c-scache_idle_time); pa_strbuf_printf(s, dl-search-path = %s\n, pa_strempty(c-dl_search_path)); @@ -722,6 +729,8 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) { pa_strbuf_printf(s, default-channel-map = %s\n, pa_channel_map_snprint(cm, sizeof(cm), c-default_channel_map)); pa_strbuf_printf(s, default-fragments = %u\n, c-default_n_fragments); pa_strbuf_printf(s, default-fragment-size-msec = %u\n, c-default_fragment_size_msec); +pa_strbuf_printf(s, sync-volume-safety-margin-usec = %u\n, c-sync_volume_safety_margin_usec); +pa_strbuf_printf(s, sync-volume-extra-delay-usec = %d\n, c-sync_volume_extra_delay_usec); pa_strbuf_printf(s, shm-size-bytes = %lu\n, (unsigned long) c-shm_size); pa_strbuf_printf(s, log-meta = %s\n, pa_yes_no(c-log_meta)); pa_strbuf_printf(s, log-time = %s\n, pa_yes_no(c-log_time)); diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index 41c3c4b..9fd6aba 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -75,7 +75,8 @@ typedef struct pa_daemon_conf { log_meta, log_time, flat_volumes, -lock_memory; +lock_memory, +sync_volume; pa_server_type_t local_server_type; int exit_idle_time, scache_idle_time, @@ -127,6 +128,8 @@ typedef struct pa_daemon_conf { #endif unsigned default_n_fragments, default_fragment_size_msec; +unsigned sync_volume_safety_margin_usec; +int sync_volume_extra_delay_usec; pa_sample_spec default_sample_spec; pa_channel_map default_channel_map; size_t shm_size; diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in index 5de27ed..9beba85 100644
[pulseaudio-discuss] [PATCH 2/5] alsa: Take syncronized HW volume infra into use for alsa-sink
From: Jyri Sarha jyri.sa...@nokia.com Signed-off-by: Jyri Sarha jyri.sa...@nokia.com Reviewed-by: Tanu Kaskinen tanu.kaski...@digia.com --- src/modules/alsa/alsa-mixer.c | 117 ++-- src/modules/alsa/alsa-mixer.h |9 ++- src/modules/alsa/alsa-sink.c| 127 +++ src/modules/alsa/alsa-source.c |2 +- src/modules/alsa/module-alsa-card.c |4 +- src/modules/alsa/module-alsa-sink.c | 10 ++- 6 files changed, 244 insertions(+), 25 deletions(-) diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 1033bbe..23b22d0 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -243,6 +243,95 @@ int pa_alsa_fdlist_set_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_hand return 0; } +struct pa_alsa_mixer_pdata { +pa_rtpoll *rtpoll; +pa_rtpoll_item *poll_item; +snd_mixer_t *mixer; +}; + + +struct pa_alsa_mixer_pdata *pa_alsa_mixer_pdata_new(void) { +struct pa_alsa_mixer_pdata *pd; + +pd = pa_xnew0(struct pa_alsa_mixer_pdata, 1); + +return pd; +} + +void pa_alsa_mixer_pdata_free(struct pa_alsa_mixer_pdata *pd) { +pa_assert(pd); + +if (pd-poll_item) { +pa_rtpoll_item_free(pd-poll_item); +} + +pa_xfree(pd); +} + +static int rtpoll_work_cb(pa_rtpoll_item *i) { +struct pa_alsa_mixer_pdata *pd; +struct pollfd *p; +unsigned n_fds; +unsigned short revents = 0; +int err; + +pd = pa_rtpoll_item_get_userdata(i); +pa_assert_fp(pd); +pa_assert_fp(i == pd-poll_item); + +p = pa_rtpoll_item_get_pollfd(i, n_fds); + +if ((err = snd_mixer_poll_descriptors_revents(pd-mixer, p, n_fds, revents)) 0) { +pa_log_error(Unable to get poll revent: %s, pa_alsa_strerror(err)); +pa_rtpoll_item_free(i); +return -1; +} + +if (revents) { +snd_mixer_handle_events(pd-mixer); +pa_rtpoll_item_free(i); +pa_alsa_set_mixer_rtpoll(pd, pd-mixer, pd-rtpoll); +} + +return 0; +} + +int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer, pa_rtpoll *rtp) { +pa_rtpoll_item *i; +struct pollfd *p; +int err, n; + +pa_assert(pd); +pa_assert(mixer); +pa_assert(rtp); + +if ((n = snd_mixer_poll_descriptors_count(mixer)) 0) { +pa_log(snd_mixer_poll_descriptors_count() failed: %s, pa_alsa_strerror(n)); +return -1; +} + +i = pa_rtpoll_item_new(rtp, PA_RTPOLL_LATE, (unsigned) n); + +p = pa_rtpoll_item_get_pollfd(i, NULL); + +memset(p, 0, sizeof(struct pollfd) * n); + +if ((err = snd_mixer_poll_descriptors(mixer, p, (unsigned) n)) 0) { +pa_log_error(Unable to get poll descriptors: %s, pa_alsa_strerror(err)); +pa_rtpoll_item_free(i); +return -1; +} + +pd-rtpoll = rtp; +pd-poll_item = i; +pd-mixer = mixer; + +pa_rtpoll_item_set_userdata(i, pd); +pa_rtpoll_item_set_work_callback(i, rtpoll_work_cb); + +return 0; +} + static int prepare_mixer(snd_mixer_t *mixer, const char *dev) { int err; @@ -671,7 +760,8 @@ int pa_alsa_path_get_mute(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t *muted) { return 0; } -static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v) { +static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v, pa_bool_t write_to_hw) { + snd_mixer_selem_id_t *sid; pa_cvolume rv; snd_mixer_elem_t *me; @@ -720,14 +810,26 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann * if the channel is available, ALSA behaves ver * strangely and doesn't fail the call */ if (snd_mixer_selem_has_playback_channel(me, c)) { -if ((r = snd_mixer_selem_set_playback_dB(me, c, value, +1)) = 0) -r = snd_mixer_selem_get_playback_dB(me, c, value); +if (write_to_hw) { +if ((r = snd_mixer_selem_set_playback_dB(me, c, value, +1)) = 0) +r = snd_mixer_selem_get_playback_dB(me, c, value); +} else { +long alsa_val; +if ((r = snd_mixer_selem_ask_playback_dB_vol(me, value, +1, alsa_val)) = 0) +r = snd_mixer_selem_ask_playback_vol_dB(me, alsa_val, value); +} } else r = -1; } else { if (snd_mixer_selem_has_capture_channel(me, c)) { -if ((r = snd_mixer_selem_set_capture_dB(me, c, value, +1)) = 0) -r = snd_mixer_selem_get_capture_dB(me, c, value); +if (write_to_hw) { +if ((r = snd_mixer_selem_set_capture_dB(me, c, value, +1)) = 0) +r =
[pulseaudio-discuss] [PATCH 1/5] core: Add infrastructure for synchronizing HW and SW volume changes
From: Jyri Sarha jyri.sa...@nokia.com To make concurrent use of SW and HW volume glitchles their application needs to be synchronized. For accurate synchronization the HW volume needs to be applied in IO thread. This patch adds infrastructure to delay the applying of HW volume to match with SW volume timing. To avoid synchronization problems this patch moves many of the volume and mute related functions from main thread to IO thread. All these changes become active only if the sync volume flag for a sink has been set. So, for this patch to have any effect it needs to be taken into use by sink implementor. Signed-off-by: Jyri Sarha jyri.sa...@nokia.com Reviewed-by: Tanu Kaskinen tanu.kaski...@digia.com --- src/pulse/def.h |7 +- src/pulsecore/sink.c | 283 -- src/pulsecore/sink.h | 97 +++--- 3 files changed, 361 insertions(+), 26 deletions(-) diff --git a/src/pulse/def.h b/src/pulse/def.h index 80d2a50..aa879b7 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -740,11 +740,15 @@ typedef enum pa_sink_flags { /** The latency can be adjusted dynamically depending on the * needs of the connected streams. \since 0.9.15 */ -PA_SINK_PASSTHROUGH = 0x0100U +PA_SINK_PASSTHROUGH = 0x0100U, /** This sink has support for passthrough mode. The data will be left * as is and not reformatted, resampled, mixed. * \since 0.9.22*/ +PA_SINK_SYNC_VOLUME = 0x0200U, +/** The HW volume changes are syncronized with SW volume. + * \since X.X.XX */ + } pa_sink_flags_t; /** \cond fulldocs */ @@ -757,6 +761,7 @@ typedef enum pa_sink_flags { #define PA_SINK_FLAT_VOLUME PA_SINK_FLAT_VOLUME #define PA_SINK_DYNAMIC_LATENCY PA_SINK_DYNAMIC_LATENCY #define PA_SINK_PASSTHROUGH PA_SINK_PASSTHROUGH +#define PA_SINK_SYNC_VOLUME PA_SINK_SYNC_VOLUME /** \endcond */ diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index ff4cc17..0f2af4f 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -34,6 +34,7 @@ #include pulse/timeval.h #include pulse/util.h #include pulse/i18n.h +#include pulse/rtclock.h #include pulsecore/sink-input.h #include pulsecore/namereg.h @@ -43,6 +44,7 @@ #include pulsecore/log.h #include pulsecore/macro.h #include pulsecore/play-memblockq.h +#include pulsecore/flist.h #include sink.h @@ -51,11 +53,29 @@ #define ABSOLUTE_MIN_LATENCY (500) #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC) #define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC) +#define VOLUME_CHANGE_SAFETY_MARGIN_DEFAULT (8*PA_USEC_PER_MSEC) +#define VOLUME_CHANGE_EXTRA_DELAY_DEFAULT (0*PA_USEC_PER_MSEC) PA_DEFINE_PUBLIC_CLASS(pa_sink, pa_msgobject); +struct pa_sink_volume_change { +pa_usec_t at; +pa_cvolume hw_volume; + +PA_LLIST_FIELDS(pa_sink_volume_change); +}; + +struct sink_message_set_port { +pa_device_port *port; +int ret; +}; + static void sink_free(pa_object *s); +static void pa_sink_volume_change_push(pa_sink *s); +static void pa_sink_volume_change_flush(pa_sink *s); +static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes); + pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) { pa_assert(data); @@ -310,6 +330,12 @@ pa_sink* pa_sink_new( s-thread_info.max_latency = ABSOLUTE_MAX_LATENCY; s-thread_info.fixed_latency = flags PA_SINK_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY; +PA_LLIST_HEAD_INIT(pa_sink_volume_change, s-thread_info.volume_changes); +s-thread_info.volume_changes_tail = NULL; +pa_sw_cvolume_multiply(s-thread_info.current_hw_volume, s-soft_volume, s-real_volume); +s-thread_info.volume_change_safety_margin = VOLUME_CHANGE_SAFETY_MARGIN_DEFAULT; +s-thread_info.volume_change_extra_delay = VOLUME_CHANGE_EXTRA_DELAY_DEFAULT; + /* FIXME: This should probably be moved to pa_sink_put() */ pa_assert_se(pa_idxset_put(core-sinks, s, s-index) = 0); @@ -444,12 +470,17 @@ void pa_sink_put(pa_sink* s) { s-thread_info.soft_volume = s-soft_volume; s-thread_info.soft_muted = s-muted; +pa_sw_cvolume_multiply(s-thread_info.current_hw_volume, s-soft_volume, s-real_volume); pa_assert((s-flags PA_SINK_HW_VOLUME_CTRL) || (s-base_volume == PA_VOLUME_NORM s-flags PA_SINK_DECIBEL_VOLUME)); pa_assert(!(s-flags PA_SINK_DECIBEL_VOLUME) || s-n_volume_steps == PA_VOLUME_NORM+1); pa_assert(!(s-flags PA_SINK_DYNAMIC_LATENCY) == (s-thread_info.fixed_latency != 0)); pa_assert(!(s-flags PA_SINK_LATENCY) == !(s-monitor_source-flags PA_SOURCE_LATENCY)); pa_assert(!(s-flags PA_SINK_DYNAMIC_LATENCY) == !(s-monitor_source-flags PA_SOURCE_DYNAMIC_LATENCY)); +pa_assert(!(s-flags PA_SINK_HW_VOLUME_CTRL) || s-set_volume); +pa_assert(!(s-flags PA_SINK_SYNC_VOLUME) || (s-flags PA_SINK_HW_VOLUME_CTRL)); +pa_assert(!(s-flags PA_SINK_SYNC_VOLUME) || s-write_volume); +pa_assert(!(s-flags PA_SINK_HW_MUTE_CTRL) || s-set_mute);