[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master-tx, updated. v0.9.16-test5-82-gbe46eaa

Lennart Poettering gitmailer-noreply at 0pointer.de
Sun Aug 23 18:32:49 PDT 2009


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master-tx branch has been updated
      from  57117d4ab75ec858bfa0468d0da0b1465813b4c9 (commit)

- Log -----------------------------------------------------------------
be46eaa i18n: run make update-po
60a3502 Merge commit 'origin/master-tx'
050a3a9 alsa: automatically decrease watermark after a time of stability
80c6937 alsa: increase interval between smoother updates exponentially for alsa sources, following the scheme for sinks
a0f01dd port a few things over to use xmalloc and friends instead of low-level libc malloc/free directly
ab5ac06 Merge commit 'wtay/optimize'
d6fb8d1 udev: check busy status of alsa cards before loading alsa modules and hence initiating profile probing
560da5b udev: process all inotify events queued up, not just the first one in the queue
1a05d67 core: relex validity checks when destructing half-set up source outputs/sink inputs
5b0683d ladspa/remap: handle failing stream moves properly
2595b9d add usergroup-test to .gitignore
aa54298 daemon: don't free script_commands twice
17dc410 core: Remove wrong doc on how to free returned data
601fb63 Solaris: fixed latency (resent)
87d2dde Solaris: use smoother (resent)
44c7aa5 Solaris: build fixes (resent)
b96390f Solaris: bootstrap portability
15eb03a core: Add thread-safe group info functions with dynamic buffers
6076cef remap: make the MMX code pretier
6e5dbed remap: add MMX mono to stereo
e961efc remap: init the do_remap function to NULL
28baa53 remap: allow specialisations to install NULL
ac1f2e0 remap: move remapping code in separate file
a3f4a4f resamples; refactor the channel remapping bits
05fef5f sconv: allow for setting custom functions
c1b6a87 alsa-sink: reduce the amount of smoother updates
f8ffe0d svolume: cleanups
f09b511 whitespace fixes
3cc1278 resampler: avoid some multiplies when we can
aeae567 svolume: add comment
8aa86f5 arm: implement ARM cpu detection
078bde1 x86: keep the cpu flags local
370016c svolume: fix compilation in 32bits
d2389ef sample: manually inline table lookups
548b735 resampler: fix identity check
d04a6e9 resample: fix counters
b4e9942 resample: refactor the channel remapping a little
bd49d43 svolume: add CPU guards around code
951bf1b svolume: add ARM optimized volume scaling
a98fa95 svolume: remove unneeded compare
601e5f1 resampler: cache integer channel_map
25724cd Get rid of liboil
591baac volume: remove ref functions
f24c24c volume: improved comments
a123544 volume: make the benchmark more meaningfull
dcae9a3 svolume: add some comments
e396fe6 cpu-x86: guard header with ifdef
563cb2d main: hook up cpu detection code
a83f552 cpu-x86: add cpu detection code and helpers
5998cf9 svolume: improve SSE and MMX code
7086784 volume_sse: add sse optimisations
08f3e16 volume_mmx: fix mmx code a bit
3a0b012 volume: add first mmx optimized function
2d73f13 samples-util: add padding to volume array
3d00896 sample-util: move volume code to separate file
e71e644 sample-util: move some functions around
5b8b654 sample-utils: coding style cleanup
26839c4 sample-utils: split out functions from case
-----------------------------------------------------------------------

Summary of changes:
 bootstrap.sh                                       |    6 +-
 configure.ac                                       |    6 -
 po/as.po                                           |   30 +-
 po/bn_IN.po                                        |   30 +-
 po/ca.po                                           |   30 +-
 po/cs.po                                           |   30 +-
 po/de.po                                           |   30 +-
 po/de_CH.po                                        |   30 +-
 po/el.po                                           |   30 +-
 po/es.po                                           |  662 +++++++++++++-------
 po/fi.po                                           |   30 +-
 po/fr.po                                           |   30 +-
 po/gu.po                                           |   30 +-
 po/hi.po                                           |   30 +-
 po/it.po                                           |   30 +-
 po/kn.po                                           |   30 +-
 po/ko.po                                           |   30 +-
 po/mr.po                                           |   30 +-
 po/nl.po                                           |   30 +-
 po/or.po                                           |   30 +-
 po/pa.po                                           |   30 +-
 po/pl.po                                           |   30 +-
 po/pt.po                                           |   30 +-
 po/pt_BR.po                                        |   30 +-
 po/sr.po                                           |   30 +-
 po/sr at latin.po                                     |   30 +-
 po/sv.po                                           |   30 +-
 po/ta.po                                           |   30 +-
 po/te.po                                           |   30 +-
 po/uk.po                                           |   30 +-
 po/zh_CN.po                                        |   30 +-
 src/.gitignore                                     |    1 +
 src/Makefile.am                                    |   17 +-
 src/daemon/cmdline.c                               |    5 -
 src/daemon/main.c                                  |    9 +-
 src/modules/alsa/alsa-sink.c                       |  168 ++++--
 src/modules/alsa/alsa-source.c                     |  161 ++++-
 src/modules/module-ladspa-sink.c                   |    7 +-
 src/modules/module-remap-sink.c                    |    7 +-
 src/modules/module-solaris.c                       |  100 ++--
 src/modules/module-udev-detect.c                   |  205 +++++-
 src/pulse/sample.c                                 |   49 +-
 src/pulse/util.c                                   |   52 +-
 src/pulsecore/core-util.c                          |  108 +---
 src/pulsecore/cpu-arm.c                            |  139 ++++
 .../alsa/alsa-source.h => pulsecore/cpu-arm.h}     |   26 +-
 src/pulsecore/cpu-x86.c                            |  122 ++++
 src/pulsecore/cpu-x86.h                            |   68 ++
 src/pulsecore/remap.c                              |  204 ++++++
 src/{modules/oss/oss-util.h => pulsecore/remap.h}  |   31 +-
 src/pulsecore/remap_mmx.c                          |  148 +++++
 src/pulsecore/resampler.c                          |  229 +++-----
 src/pulsecore/rtpoll.c                             |   28 +-
 src/pulsecore/rtpoll.h                             |    4 +
 src/pulsecore/sample-util.c                        |  396 ++----------
 src/pulsecore/sample-util.h                        |    5 +
 src/pulsecore/sconv-s16le.c                        |   42 +-
 src/pulsecore/sconv.c                              |  188 ++++---
 src/pulsecore/sconv.h                              |    6 +
 src/pulsecore/sink-input.c                         |    5 +-
 src/pulsecore/source-output.c                      |    2 -
 src/pulsecore/svolume_arm.c                        |  195 ++++++
 src/pulsecore/svolume_c.c                          |  335 ++++++++++
 src/pulsecore/svolume_mmx.c                        |  313 +++++++++
 src/pulsecore/svolume_sse.c                        |  314 +++++++++
 src/pulsecore/usergroup.c                          |  372 +++++++++++
 src/pulsecore/{creds.h => usergroup.h}             |   37 +-
 src/tests/envelope-test.c                          |    3 -
 src/tests/mix-test.c                               |    3 -
 src/tests/remix-test.c                             |    3 -
 src/tests/resampler-test.c                         |    3 -
 src/tests/usergroup-test.c                         |  161 +++++
 72 files changed, 4170 insertions(+), 1615 deletions(-)
 create mode 100644 src/pulsecore/cpu-arm.c
 copy src/{modules/alsa/alsa-source.h => pulsecore/cpu-arm.h} (60%)
 create mode 100644 src/pulsecore/cpu-x86.c
 create mode 100644 src/pulsecore/cpu-x86.h
 create mode 100644 src/pulsecore/remap.c
 copy src/{modules/oss/oss-util.h => pulsecore/remap.h} (53%)
 create mode 100644 src/pulsecore/remap_mmx.c
 create mode 100644 src/pulsecore/svolume_arm.c
 create mode 100644 src/pulsecore/svolume_c.c
 create mode 100644 src/pulsecore/svolume_mmx.c
 create mode 100644 src/pulsecore/svolume_sse.c
 create mode 100644 src/pulsecore/usergroup.c
 copy src/pulsecore/{creds.h => usergroup.h} (60%)
 create mode 100644 src/tests/usergroup-test.c

-----------------------------------------------------------------------

commit 26839c4b9eb549eebf8db6eae2399ed6fd94efa8
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Tue Aug 11 15:15:57 2009 +0200

    sample-utils: split out functions from case
    
    Move the volume functions out of the switch case and use a table indexed by the
    sample format to find the volume function.

diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index 5b8ccf5..ef43567 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -690,361 +690,381 @@ size_t pa_mix(
     return length;
 }
 
+typedef struct pa_volume_funcs {
+  void (*u8) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*alaw) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*ulaw) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*s16ne) (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*s16re) (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*float32ne) (float *samples, float *volumes, unsigned channels, unsigned length);
+  void (*float32re) (float *samples, float *volumes, unsigned channels, unsigned length);
+  void (*s32ne) (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*s32re) (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*s24ne) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*s24re) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*s24_32ne) (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+  void (*s24_32re) (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
+} pa_volume_funcs;
+
+static void
+pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) *samples - 0x80;
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
+    *samples++ = (uint8_t) (t + 0x80);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-void pa_volume_memchunk(
-        pa_memchunk*c,
-        const pa_sample_spec *spec,
-        const pa_cvolume *volume) {
-
-    void *ptr;
-
-    pa_assert(c);
-    pa_assert(spec);
-    pa_assert(c->length % pa_frame_size(spec) == 0);
-    pa_assert(volume);
-
-    if (pa_memblock_is_silence(c->memblock))
-        return;
-
-    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM))
-        return;
-
-    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_MUTED)) {
-        pa_silence_memchunk(c, spec);
-        return;
-    }
-
-    ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
-
-    switch (spec->format) {
-
-        case PA_SAMPLE_S16NE: {
-            int16_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
-
-            calc_linear_integer_volume(linear, volume);
-
-            e = (int16_t*) ptr + c->length/sizeof(int16_t);
-
-            for (channel = 0, d = ptr; d < e; d++) {
-                int32_t t, hi, lo;
-
-                /* Multiplying the 32bit volume factor with the 16bit
-                 * sample might result in an 48bit value. We want to
-                 * do without 64 bit integers and hence do the
-                 * multiplication independantly for the HI and LO part
-                 * of the volume. */
-
-                hi = linear[channel] >> 16;
-                lo = linear[channel] & 0xFFFF;
-
-                t = (int32_t)(*d);
-                t = ((t * lo) >> 16) + (t * hi);
-                t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-                *d = (int16_t) t;
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S16RE: {
-            int16_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
-
-            calc_linear_integer_volume(linear, volume);
-
-            e = (int16_t*) ptr + c->length/sizeof(int16_t);
-
-            for (channel = 0, d = ptr; d < e; d++) {
-                int32_t t, hi, lo;
+static void
+pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-                hi = linear[channel] >> 16;
-                lo = linear[channel] & 0xFFFF;
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
 
-                t = (int32_t) PA_INT16_SWAP(*d);
-                t = ((t * lo) >> 16) + (t * hi);
-                t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-                *d = PA_INT16_SWAP((int16_t) t);
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
+    t = (int32_t) st_alaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
 
-            break;
-        }
-
-        case PA_SAMPLE_S32NE: {
-            int32_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-            calc_linear_integer_volume(linear, volume);
+static void
+pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-            e = (int32_t*) ptr + c->length/sizeof(int32_t);
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                int64_t t;
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
 
-                t = (int64_t)(*d);
-                t = (t * linear[channel]) >> 16;
-                t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-                *d = (int32_t) t;
+    t = (int32_t) st_ulaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
-
-        case PA_SAMPLE_S32RE: {
-            int32_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
-
-            calc_linear_integer_volume(linear, volume);
-
-            e = (int32_t*) ptr + c->length/sizeof(int32_t);
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                int64_t t;
+static void
+pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-                t = (int64_t) PA_INT32_SWAP(*d);
-                t = (t * linear[channel]) >> 16;
-                t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-                *d = PA_INT32_SWAP((int32_t) t);
+  length /= sizeof (int16_t);
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
 
-        case PA_SAMPLE_S24NE: {
-            uint8_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+    /* Multiplying the 32bit volume factor with the 16bit
+     * sample might result in an 48bit value. We want to
+     * do without 64 bit integers and hence do the
+     * multiplication independantly for the HI and LO part
+     * of the volume. */
 
-            calc_linear_integer_volume(linear, volume);
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
 
-            e = (uint8_t*) ptr + c->length;
+    t = (int32_t)(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (int16_t) t;
 
-            for (channel = 0, d = ptr; d < e; d += 3) {
-                int64_t t;
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-                t = (int64_t)((int32_t) (PA_READ24NE(d) << 8));
-                t = (t * linear[channel]) >> 16;
-                t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-                PA_WRITE24NE(d, ((uint32_t) (int32_t) t) >> 8);
+static void
+pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+  length /= sizeof (int16_t);
 
-        case PA_SAMPLE_S24RE: {
-            uint8_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
 
-            calc_linear_integer_volume(linear, volume);
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
 
-            e = (uint8_t*) ptr + c->length;
+    t = (int32_t) PA_INT16_SWAP(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = PA_INT16_SWAP((int16_t) t);
 
-            for (channel = 0, d = ptr; d < e; d += 3) {
-                int64_t t;
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-                t = (int64_t)((int32_t) (PA_READ24RE(d) << 8));
-                t = (t * linear[channel]) >> 16;
-                t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-                PA_WRITE24RE(d, ((uint32_t) (int32_t) t) >> 8);
+static void
+pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+  length /= sizeof (float);
 
-        case PA_SAMPLE_S24_32NE: {
-            uint32_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+  for (channel = 0; length; length--) {
+    *samples++ *= volumes[channel];
 
-            calc_linear_integer_volume(linear, volume);
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-            e = (uint32_t*) ptr + c->length/sizeof(uint32_t);
+static void
+pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                int64_t t;
+  length /= sizeof (float);
 
-                t = (int64_t) ((int32_t) (*d << 8));
-                t = (t * linear[channel]) >> 16;
-                t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-                *d = ((uint32_t) ((int32_t) t)) >> 8;
+  for (channel = 0; length; length--) {
+    float t;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+    t = PA_FLOAT32_SWAP(*samples);
+    t *= volumes[channel];
+    *samples++ = PA_FLOAT32_SWAP(t);
 
-        case PA_SAMPLE_S24_32RE: {
-            uint32_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-            calc_linear_integer_volume(linear, volume);
+static void
+pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-            e = (uint32_t*) ptr + c->length/sizeof(uint32_t);
+  length /= sizeof (int32_t);
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                int64_t t;
+  for (channel = 0; length; length--) {
+    int64_t t;
 
-                t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*d) << 8));
-                t = (t * linear[channel]) >> 16;
-                t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-                *d = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
+    t = (int64_t)(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = (int32_t) t;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-        case PA_SAMPLE_U8: {
-            uint8_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+static void
+pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-            calc_linear_integer_volume(linear, volume);
+  length /= sizeof (int32_t);
 
-            e = (uint8_t*) ptr + c->length;
+  for (channel = 0; length; length--) {
+    int64_t t;
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                int32_t t, hi, lo;
+    t = (int64_t) PA_INT32_SWAP(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_INT32_SWAP((int32_t) t);
 
-                hi = linear[channel] >> 16;
-                lo = linear[channel] & 0xFFFF;
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-                t = (int32_t) *d - 0x80;
-                t = ((t * lo) >> 16) + (t * hi);
-                t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
-                *d = (uint8_t) (t + 0x80);
+static void
+pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+  e = samples + length;
 
-        case PA_SAMPLE_ULAW: {
-            uint8_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
 
-            calc_linear_integer_volume(linear, volume);
+    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
 
-            e = (uint8_t*) ptr + c->length;
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                int32_t t, hi, lo;
+static void
+pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
 
-                hi = linear[channel] >> 16;
-                lo = linear[channel] & 0xFFFF;
+  e = samples + length;
 
-                t = (int32_t) st_ulaw2linear16(*d);
-                t = ((t * lo) >> 16) + (t * hi);
-                t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-                *d = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
 
-        case PA_SAMPLE_ALAW: {
-            uint8_t *d, *e;
-            unsigned channel;
-            int32_t linear[PA_CHANNELS_MAX];
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-            calc_linear_integer_volume(linear, volume);
+static void
+pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-            e = (uint8_t*) ptr + c->length;
+  length /= sizeof (uint32_t);
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                int32_t t, hi, lo;
+  for (channel = 0; length; length--) {
+    int64_t t;
 
-                hi = linear[channel] >> 16;
-                lo = linear[channel] & 0xFFFF;
+    t = (int64_t) ((int32_t) (*samples << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
 
-                t = (int32_t) st_alaw2linear16(*d);
-                t = ((t * lo) >> 16) + (t * hi);
-                t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-                *d = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-            break;
-        }
+static void
+pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
 
-        case PA_SAMPLE_FLOAT32NE: {
-            float *d;
-            int skip;
-            unsigned n;
-            unsigned channel;
+  length /= sizeof (uint32_t);
 
-            d = ptr;
-            skip = (int) (spec->channels * sizeof(float));
-            n = (unsigned) (c->length/sizeof(float)/spec->channels);
+  for (channel = 0; length; length--) {
+    int64_t t;
 
-            for (channel = 0; channel < spec->channels; channel ++) {
-                float v, *t;
+    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
 
-                if (PA_UNLIKELY(volume->values[channel] == PA_VOLUME_NORM))
-                    continue;
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
 
-                v = (float) pa_sw_volume_to_linear(volume->values[channel]);
-                t = d + channel;
-                oil_scalarmult_f32(t, skip, t, skip, &v, (int) n);
-            }
-            break;
-        }
+typedef void (*pa_do_volume_func) (void *samples, void *volumes, unsigned channels, unsigned length);
+typedef void (*pa_calc_volume_func) (void *volumes, const pa_cvolume *volume);
+
+typedef union {
+  float f;
+  uint32_t i;
+} volume_val;
+
+static pa_calc_volume_func calc_volume_funcs[] =
+{
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_float_volume,
+  (pa_calc_volume_func) calc_linear_float_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume,
+  (pa_calc_volume_func) calc_linear_integer_volume
+};
+
+static pa_do_volume_func do_volume_funcs[] =
+{
+  (pa_do_volume_func) pa_volume_u8_c,
+  (pa_do_volume_func) pa_volume_alaw_c,
+  (pa_do_volume_func) pa_volume_ulaw_c,
+#ifdef WORDS_BIGENDIAN
+  (pa_do_volume_func) pa_volume_s16re_c,
+  (pa_do_volume_func) pa_volume_s16ne_c,
+  (pa_do_volume_func) pa_volume_float32re_c,
+  (pa_do_volume_func) pa_volume_float32ne_c,
+  (pa_do_volume_func) pa_volume_s32re_c,
+  (pa_do_volume_func) pa_volume_s32ne_c,
+  (pa_do_volume_func) pa_volume_s24re_c,
+  (pa_do_volume_func) pa_volume_s24ne_c,
+  (pa_do_volume_func) pa_volume_s24_32re_c
+  (pa_do_volume_func) pa_volume_s24_32ne_c,
+#else
+  (pa_do_volume_func) pa_volume_s16ne_c,
+  (pa_do_volume_func) pa_volume_s16re_c,
+  (pa_do_volume_func) pa_volume_float32ne_c,
+  (pa_do_volume_func) pa_volume_float32re_c,
+  (pa_do_volume_func) pa_volume_s32ne_c,
+  (pa_do_volume_func) pa_volume_s32re_c,
+  (pa_do_volume_func) pa_volume_s24ne_c,
+  (pa_do_volume_func) pa_volume_s24re_c,
+  (pa_do_volume_func) pa_volume_s24_32ne_c,
+  (pa_do_volume_func) pa_volume_s24_32re_c
+#endif
+};
 
-        case PA_SAMPLE_FLOAT32RE: {
-            float *d, *e;
-            unsigned channel;
-            float linear[PA_CHANNELS_MAX];
+void pa_volume_memchunk(
+        pa_memchunk*c,
+        const pa_sample_spec *spec,
+        const pa_cvolume *volume) {
 
-            calc_linear_float_volume(linear, volume);
+    void *ptr;
+    volume_val linear[PA_CHANNELS_MAX];
 
-            e = (float*) ptr + c->length/sizeof(float);
+    pa_assert(c);
+    pa_assert(spec);
+    pa_assert(c->length % pa_frame_size(spec) == 0);
+    pa_assert(volume);
 
-            for (channel = 0, d = ptr; d < e; d++) {
-                float t;
+    if (pa_memblock_is_silence(c->memblock))
+        return;
 
-                t = PA_FLOAT32_SWAP(*d);
-                t *= linear[channel];
-                *d = PA_FLOAT32_SWAP(t);
+    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM))
+        return;
 
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
+    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_MUTED)) {
+        pa_silence_memchunk(c, spec);
+        return;
+    }
 
-            break;
-        }
+    if (spec->format < 0 || spec->format > PA_SAMPLE_MAX) {
+      pa_log_warn(" Unable to change volume of format %s.", pa_sample_format_to_string(spec->format));
+      return;
+    }
 
+    ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
 
-        default:
-            pa_log_warn(" Unable to change volume of format %s.", pa_sample_format_to_string(spec->format));
-            /* If we cannot change the volume, we just don't do it */
-    }
+    calc_volume_funcs[spec->format] ((void *)linear, volume);
+    do_volume_funcs[spec->format] (ptr, (void *)linear, spec->channels, c->length);
 
     pa_memblock_release(c->memblock);
 }

commit 5b8b6544e205237d41bc502a7fd9f79051af78ec
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Tue Aug 11 16:25:44 2009 +0200

    sample-utils: coding style cleanup
    
    Make the coding style match the rest of pulseaudio more.
    Remove some liboil functions, they seem unoptimized and likely slower than our
    handrolled versions here.

diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index ef43567..0d4e01e 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -30,9 +30,6 @@
 #include <stdio.h>
 #include <errno.h>
 
-#include <liboil/liboilfuncs.h>
-#include <liboil/liboil.h>
-
 #include <pulse/timeval.h>
 
 #include <pulsecore/log.h>
@@ -977,59 +974,50 @@ pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, un
   }
 }
 
-typedef void (*pa_do_volume_func) (void *samples, void *volumes, unsigned channels, unsigned length);
-typedef void (*pa_calc_volume_func) (void *volumes, const pa_cvolume *volume);
+typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned channels, unsigned length);
+typedef void (*pa_calc_volume_func_t) (void *volumes, const pa_cvolume *volume);
 
 typedef union {
   float f;
   uint32_t i;
 } volume_val;
 
-static pa_calc_volume_func calc_volume_funcs[] =
-{
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_float_volume,
-  (pa_calc_volume_func) calc_linear_float_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume,
-  (pa_calc_volume_func) calc_linear_integer_volume
+typedef struct pa_sample_func_t {
+  pa_calc_volume_func_t  calc_volume;
+  pa_do_volume_func_t    do_volume;
+} pa_sample_func_t;
+
+static const pa_calc_volume_func_t calc_volume_table[] = {
+  [PA_SAMPLE_U8]        = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_ALAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_ULAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S16LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S16BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_FLOAT32LE] = (pa_calc_volume_func_t) calc_linear_float_volume,
+  [PA_SAMPLE_FLOAT32BE] = (pa_calc_volume_func_t) calc_linear_float_volume,
+  [PA_SAMPLE_S32LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S32BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24_32LE]  = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24_32BE]  = (pa_calc_volume_func_t) calc_linear_integer_volume
 };
 
-static pa_do_volume_func do_volume_funcs[] =
+static pa_do_volume_func_t do_volume_table[] =
 {
-  (pa_do_volume_func) pa_volume_u8_c,
-  (pa_do_volume_func) pa_volume_alaw_c,
-  (pa_do_volume_func) pa_volume_ulaw_c,
-#ifdef WORDS_BIGENDIAN
-  (pa_do_volume_func) pa_volume_s16re_c,
-  (pa_do_volume_func) pa_volume_s16ne_c,
-  (pa_do_volume_func) pa_volume_float32re_c,
-  (pa_do_volume_func) pa_volume_float32ne_c,
-  (pa_do_volume_func) pa_volume_s32re_c,
-  (pa_do_volume_func) pa_volume_s32ne_c,
-  (pa_do_volume_func) pa_volume_s24re_c,
-  (pa_do_volume_func) pa_volume_s24ne_c,
-  (pa_do_volume_func) pa_volume_s24_32re_c
-  (pa_do_volume_func) pa_volume_s24_32ne_c,
-#else
-  (pa_do_volume_func) pa_volume_s16ne_c,
-  (pa_do_volume_func) pa_volume_s16re_c,
-  (pa_do_volume_func) pa_volume_float32ne_c,
-  (pa_do_volume_func) pa_volume_float32re_c,
-  (pa_do_volume_func) pa_volume_s32ne_c,
-  (pa_do_volume_func) pa_volume_s32re_c,
-  (pa_do_volume_func) pa_volume_s24ne_c,
-  (pa_do_volume_func) pa_volume_s24re_c,
-  (pa_do_volume_func) pa_volume_s24_32ne_c,
-  (pa_do_volume_func) pa_volume_s24_32re_c
-#endif
+  [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
+  [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
+  [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
+  [PA_SAMPLE_S16NE]     = (pa_do_volume_func_t) pa_volume_s16ne_c,
+  [PA_SAMPLE_S16RE]     = (pa_do_volume_func_t) pa_volume_s16re_c,
+  [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
+  [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
+  [PA_SAMPLE_S32NE]     = (pa_do_volume_func_t) pa_volume_s32ne_c,
+  [PA_SAMPLE_S32RE]     = (pa_do_volume_func_t) pa_volume_s32re_c,
+  [PA_SAMPLE_S24NE]     = (pa_do_volume_func_t) pa_volume_s24ne_c,
+  [PA_SAMPLE_S24RE]     = (pa_do_volume_func_t) pa_volume_s24re_c,
+  [PA_SAMPLE_S24_32NE]  = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
+  [PA_SAMPLE_S24_32RE]  = (pa_do_volume_func_t) pa_volume_s24_32re_c
 };
 
 void pa_volume_memchunk(
@@ -1063,8 +1051,8 @@ void pa_volume_memchunk(
 
     ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
 
-    calc_volume_funcs[spec->format] ((void *)linear, volume);
-    do_volume_funcs[spec->format] (ptr, (void *)linear, spec->channels, c->length);
+    calc_volume_table[spec->format] ((void *)linear, volume);
+    do_volume_table[spec->format] (ptr, (void *)linear, spec->channels, c->length);
 
     pa_memblock_release(c->memblock);
 }
@@ -1110,7 +1098,7 @@ void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, u
         d = (uint8_t*) dst + c * ss;
 
         for (j = 0; j < n; j ++) {
-            oil_memcpy(d, s, (int) ss);
+            memcpy(d, s, (int) ss);
             s = (uint8_t*) s + ss;
             d = (uint8_t*) d + fs;
         }
@@ -1138,7 +1126,7 @@ void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss,
         d = dst[c];
 
         for (j = 0; j < n; j ++) {
-            oil_memcpy(d, s, (int) ss);
+            memcpy(d, s, (int) ss);
             s = (uint8_t*) s + fs;
             d = (uint8_t*) d + ss;
         }
@@ -1247,10 +1235,15 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo
     s = src; d = dst;
 
     if (format == PA_SAMPLE_FLOAT32NE) {
+        for (; n > 0; n--) {
+            float f;
 
-        float minus_one = -1.0, plus_one = 1.0;
-        oil_clip_f32(d, (int) dstr, s, (int) sstr, (int) n, &minus_one, &plus_one);
+	    f = *s;
+            *d = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);
 
+            s = (const float*) ((const uint8_t*) s + sstr);
+            d = (float*) ((uint8_t*) d + dstr);
+	}
     } else {
         pa_assert(format == PA_SAMPLE_FLOAT32RE);
 

commit e71e644eb668b6336dd48d2730839aa3e9f7278e
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Tue Aug 11 16:43:46 2009 +0200

    sample-util: move some functions around
    
    Move some stuff around before splitting it into a separate file.

diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index 0d4e01e..f8a4c70 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -975,17 +975,34 @@ pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, un
 }
 
 typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned channels, unsigned length);
-typedef void (*pa_calc_volume_func_t) (void *volumes, const pa_cvolume *volume);
+
+typedef struct pa_sample_func_t {
+  pa_do_volume_func_t    do_volume;
+} pa_sample_func_t;
+
+static pa_do_volume_func_t do_volume_table[] =
+{
+  [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
+  [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
+  [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
+  [PA_SAMPLE_S16NE]     = (pa_do_volume_func_t) pa_volume_s16ne_c,
+  [PA_SAMPLE_S16RE]     = (pa_do_volume_func_t) pa_volume_s16re_c,
+  [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
+  [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
+  [PA_SAMPLE_S32NE]     = (pa_do_volume_func_t) pa_volume_s32ne_c,
+  [PA_SAMPLE_S32RE]     = (pa_do_volume_func_t) pa_volume_s32re_c,
+  [PA_SAMPLE_S24NE]     = (pa_do_volume_func_t) pa_volume_s24ne_c,
+  [PA_SAMPLE_S24RE]     = (pa_do_volume_func_t) pa_volume_s24re_c,
+  [PA_SAMPLE_S24_32NE]  = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
+  [PA_SAMPLE_S24_32RE]  = (pa_do_volume_func_t) pa_volume_s24_32re_c
+};
 
 typedef union {
   float f;
   uint32_t i;
 } volume_val;
 
-typedef struct pa_sample_func_t {
-  pa_calc_volume_func_t  calc_volume;
-  pa_do_volume_func_t    do_volume;
-} pa_sample_func_t;
+typedef void (*pa_calc_volume_func_t) (void *volumes, const pa_cvolume *volume);
 
 static const pa_calc_volume_func_t calc_volume_table[] = {
   [PA_SAMPLE_U8]        = (pa_calc_volume_func_t) calc_linear_integer_volume,
@@ -1003,23 +1020,6 @@ static const pa_calc_volume_func_t calc_volume_table[] = {
   [PA_SAMPLE_S24_32BE]  = (pa_calc_volume_func_t) calc_linear_integer_volume
 };
 
-static pa_do_volume_func_t do_volume_table[] =
-{
-  [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
-  [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
-  [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
-  [PA_SAMPLE_S16NE]     = (pa_do_volume_func_t) pa_volume_s16ne_c,
-  [PA_SAMPLE_S16RE]     = (pa_do_volume_func_t) pa_volume_s16re_c,
-  [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
-  [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
-  [PA_SAMPLE_S32NE]     = (pa_do_volume_func_t) pa_volume_s32ne_c,
-  [PA_SAMPLE_S32RE]     = (pa_do_volume_func_t) pa_volume_s32re_c,
-  [PA_SAMPLE_S24NE]     = (pa_do_volume_func_t) pa_volume_s24ne_c,
-  [PA_SAMPLE_S24RE]     = (pa_do_volume_func_t) pa_volume_s24re_c,
-  [PA_SAMPLE_S24_32NE]  = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
-  [PA_SAMPLE_S24_32RE]  = (pa_do_volume_func_t) pa_volume_s24_32re_c
-};
-
 void pa_volume_memchunk(
         pa_memchunk*c,
         const pa_sample_spec *spec,

commit 3d008961c095cf8d41d2c61d13d446c98c892136
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Tue Aug 11 17:10:44 2009 +0200

    sample-util: move volume code to separate file
    
    Move the volume code into a separate file with the reference C implementations.
    Add a function to retrieve the volume function and one to install a new one.

diff --git a/src/Makefile.am b/src/Makefile.am
index 17011cd..fc5d39f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -825,6 +825,7 @@ libpulsecore_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/resampler.c pulsecore/resampler.h \
 		pulsecore/rtpoll.c pulsecore/rtpoll.h \
 		pulsecore/sample-util.c pulsecore/sample-util.h \
+		pulsecore/svolume_c.c \
 		pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
 		pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
 		pulsecore/sconv.c pulsecore/sconv.h \
diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index f8a4c70..0bbd519 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -687,316 +687,6 @@ size_t pa_mix(
     return length;
 }
 
-typedef struct pa_volume_funcs {
-  void (*u8) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*alaw) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*ulaw) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*s16ne) (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*s16re) (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*float32ne) (float *samples, float *volumes, unsigned channels, unsigned length);
-  void (*float32re) (float *samples, float *volumes, unsigned channels, unsigned length);
-  void (*s32ne) (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*s32re) (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*s24ne) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*s24re) (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*s24_32ne) (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-  void (*s24_32re) (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length);
-} pa_volume_funcs;
-
-static void
-pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) *samples - 0x80;
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
-    *samples++ = (uint8_t) (t + 0x80);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) st_alaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) st_ulaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int16_t);
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    /* Multiplying the 32bit volume factor with the 16bit
-     * sample might result in an 48bit value. We want to
-     * do without 64 bit integers and hence do the
-     * multiplication independantly for the HI and LO part
-     * of the volume. */
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t)(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (int16_t) t;
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int16_t);
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) PA_INT16_SWAP(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = PA_INT16_SWAP((int16_t) t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (float);
-
-  for (channel = 0; length; length--) {
-    *samples++ *= volumes[channel];
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (float);
-
-  for (channel = 0; length; length--) {
-    float t;
-
-    t = PA_FLOAT32_SWAP(*samples);
-    t *= volumes[channel];
-    *samples++ = PA_FLOAT32_SWAP(t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t)(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = (int32_t) t;
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) PA_INT32_SWAP(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_INT32_SWAP((int32_t) t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-  uint8_t *e;
-
-  e = samples + length;
-
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
-
-    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-  uint8_t *e;
-
-  e = samples + length;
-
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
-
-    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (uint32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) ((int32_t) (*samples << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (uint32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned channels, unsigned length);
-
-typedef struct pa_sample_func_t {
-  pa_do_volume_func_t    do_volume;
-} pa_sample_func_t;
-
-static pa_do_volume_func_t do_volume_table[] =
-{
-  [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
-  [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
-  [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
-  [PA_SAMPLE_S16NE]     = (pa_do_volume_func_t) pa_volume_s16ne_c,
-  [PA_SAMPLE_S16RE]     = (pa_do_volume_func_t) pa_volume_s16re_c,
-  [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
-  [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
-  [PA_SAMPLE_S32NE]     = (pa_do_volume_func_t) pa_volume_s32ne_c,
-  [PA_SAMPLE_S32RE]     = (pa_do_volume_func_t) pa_volume_s32re_c,
-  [PA_SAMPLE_S24NE]     = (pa_do_volume_func_t) pa_volume_s24ne_c,
-  [PA_SAMPLE_S24RE]     = (pa_do_volume_func_t) pa_volume_s24re_c,
-  [PA_SAMPLE_S24_32NE]  = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
-  [PA_SAMPLE_S24_32RE]  = (pa_do_volume_func_t) pa_volume_s24_32re_c
-};
-
 typedef union {
   float f;
   uint32_t i;
@@ -1027,6 +717,7 @@ void pa_volume_memchunk(
 
     void *ptr;
     volume_val linear[PA_CHANNELS_MAX];
+    pa_do_volume_func_t do_volume;
 
     pa_assert(c);
     pa_assert(spec);
@@ -1051,8 +742,11 @@ void pa_volume_memchunk(
 
     ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
 
+    do_volume = pa_get_volume_func (spec->format);
+    pa_assert(do_volume);
+    
     calc_volume_table[spec->format] ((void *)linear, volume);
-    do_volume_table[spec->format] (ptr, (void *)linear, spec->channels, c->length);
+    do_volume (ptr, (void *)linear, spec->channels, c->length);
 
     pa_memblock_release(c->memblock);
 }
diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h
index 6a306c1..278b88b 100644
--- a/src/pulsecore/sample-util.h
+++ b/src/pulsecore/sample-util.h
@@ -86,6 +86,12 @@ void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn);
 
 void pa_memchunk_sine(pa_memchunk *c, pa_mempool *pool, unsigned rate, unsigned freq);
 
+typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned channels, unsigned length);
+
+pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f);
+void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func);
+
+
 #define PA_CHANNEL_POSITION_MASK_LEFT                                   \
     (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT)           \
      | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_LEFT)          \
diff --git a/src/pulsecore/svolume_c.c b/src/pulsecore/svolume_c.c
new file mode 100644
index 0000000..2148a57
--- /dev/null
+++ b/src/pulsecore/svolume_c.c
@@ -0,0 +1,335 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2006 Pierre Ossman <ossman at cendio.se> for Cendio AB
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <pulsecore/macro.h>
+#include <pulsecore/g711.h>
+#include <pulsecore/core-util.h>
+
+#include "sample-util.h"
+#include "endianmacros.h"
+
+static void
+pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) *samples - 0x80;
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
+    *samples++ = (uint8_t) (t + 0x80);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) st_alaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) st_ulaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int16_t);
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    /* Multiplying the 32bit volume factor with the 16bit
+     * sample might result in an 48bit value. We want to
+     * do without 64 bit integers and hence do the
+     * multiplication independantly for the HI and LO part
+     * of the volume. */
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t)(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (int16_t) t;
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int16_t);
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) PA_INT16_SWAP(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = PA_INT16_SWAP((int16_t) t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (float);
+
+  for (channel = 0; length; length--) {
+    *samples++ *= volumes[channel];
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (float);
+
+  for (channel = 0; length; length--) {
+    float t;
+
+    t = PA_FLOAT32_SWAP(*samples);
+    t *= volumes[channel];
+    *samples++ = PA_FLOAT32_SWAP(t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t)(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = (int32_t) t;
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) PA_INT32_SWAP(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_INT32_SWAP((int32_t) t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
+
+  e = samples + length;
+
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
+
+    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
+
+  e = samples + length;
+
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
+
+    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (uint32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) ((int32_t) (*samples << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (uint32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static pa_do_volume_func_t do_volume_table[] =
+{
+  [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
+  [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
+  [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
+  [PA_SAMPLE_S16NE]     = (pa_do_volume_func_t) pa_volume_s16ne_c,
+  [PA_SAMPLE_S16RE]     = (pa_do_volume_func_t) pa_volume_s16re_c,
+  [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
+  [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
+  [PA_SAMPLE_S32NE]     = (pa_do_volume_func_t) pa_volume_s32ne_c,
+  [PA_SAMPLE_S32RE]     = (pa_do_volume_func_t) pa_volume_s32re_c,
+  [PA_SAMPLE_S24NE]     = (pa_do_volume_func_t) pa_volume_s24ne_c,
+  [PA_SAMPLE_S24RE]     = (pa_do_volume_func_t) pa_volume_s24re_c,
+  [PA_SAMPLE_S24_32NE]  = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
+  [PA_SAMPLE_S24_32RE]  = (pa_do_volume_func_t) pa_volume_s24_32re_c
+};
+
+pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f) {
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return do_volume_table[f];
+}
+
+void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func) {
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    do_volume_table[f] = func;
+}

commit 2d73f13567ad03efe798d07eda87fa776b0505f2
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 12 17:03:30 2009 +0200

    samples-util: add padding to volume array
    
    Pad the volume array with a copy of the start. We'll need this later to be able
    to write optimized functions.

diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index 0bbd519..677f914 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -103,24 +103,36 @@ void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) {
     return p;
 }
 
+#define VOLUME_PADDING 32
+
 static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
-    unsigned channel;
+    unsigned channel, nchannels, padding;
 
     pa_assert(linear);
     pa_assert(volume);
 
-    for (channel = 0; channel < volume->channels; channel++)
+    nchannels = volume->channels;
+
+    for (channel = 0; channel < nchannels; channel++)
         linear[channel] = (int32_t) lrint(pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);
+
+    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
+        linear[channel] = linear[padding];
 }
 
 static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
-    unsigned channel;
+    unsigned channel, nchannels, padding;
 
     pa_assert(linear);
     pa_assert(volume);
 
-    for (channel = 0; channel < volume->channels; channel++)
+    nchannels = volume->channels;
+
+    for (channel = 0; channel < nchannels; channel++)
         linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);
+
+    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
+        linear[channel] = linear[padding];
 }
 
 static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
@@ -716,7 +728,7 @@ void pa_volume_memchunk(
         const pa_cvolume *volume) {
 
     void *ptr;
-    volume_val linear[PA_CHANNELS_MAX];
+    volume_val linear[PA_CHANNELS_MAX + VOLUME_PADDING];
     pa_do_volume_func_t do_volume;
 
     pa_assert(c);

commit 3a0b012ee016e2fe40f49c72da119cb89d2ba312
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 12 17:08:41 2009 +0200

    volume: add first mmx optimized function
    
    Add code for an mmx optimized version of s16ne volume scaling. Install the
    custom function.

diff --git a/src/Makefile.am b/src/Makefile.am
index fc5d39f..e7a9900 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -826,6 +826,7 @@ libpulsecore_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/rtpoll.c pulsecore/rtpoll.h \
 		pulsecore/sample-util.c pulsecore/sample-util.h \
 		pulsecore/svolume_c.c \
+		pulsecore/svolume_mmx.c \
 		pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
 		pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
 		pulsecore/sconv.c pulsecore/sconv.h \
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 8521e72..e3c395f 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -821,6 +821,8 @@ int main(int argc, char *argv[]) {
 
     pa_memtrap_install();
 
+    pa_volume_func_init_mmx();
+
     pa_assert_se(mainloop = pa_mainloop_new());
 
     if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h
index 278b88b..00b9ae0 100644
--- a/src/pulsecore/sample-util.h
+++ b/src/pulsecore/sample-util.h
@@ -91,6 +91,7 @@ typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned chan
 pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f);
 void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func);
 
+void pa_volume_func_init_mmx(void);
 
 #define PA_CHANNEL_POSITION_MASK_LEFT                                   \
     (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT)           \
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
new file mode 100644
index 0000000..9f49a62
--- /dev/null
+++ b/src/pulsecore/svolume_mmx.c
@@ -0,0 +1,424 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <alloca.h>
+
+#include <pulsecore/random.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/g711.h>
+#include <pulsecore/core-util.h>
+
+#include "sample-util.h"
+#include "endianmacros.h"
+
+#if 0
+static void
+pa_volume_u8_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) *samples - 0x80;
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
+    *samples++ = (uint8_t) (t + 0x80);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_alaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) st_alaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_ulaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) st_ulaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+#endif
+
+static void
+pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  int64_t channel, temp;
+
+  /* the max number of samples we process at a time */
+  channels = MAX (4, channels);
+
+#define VOLUME_32x16(s,v)                  /* v1_h    | v1_l    | v0_h    | v0_l      */    \
+      " pxor %%mm4, %%mm4            \n\t"                                                  \
+      " punpcklwd %%mm4, "#s"        \n\t" /* 0       |  p1     | 0       | p0        */    \
+      " pcmpgtw "#s", %%mm4          \n\t" /* select sign from sample                 */    \
+      " pand "#v", %%mm4             \n\t" /* extract correction factors              */    \
+      " movq "#s", %%mm5             \n\t"                                                  \
+      " pmulhuw "#v", "#s"           \n\t" /*   0     | p1*v1lh |    0    | p0*v0lh   */    \
+      " psubd %%mm4, "#s"            \n\t" /* sign correction                         */    \
+      " psrld $16, "#v"              \n\t" /*  0      | v1h     |  0      | v0h       */    \
+      " pmaddwd %%mm5, "#v"          \n\t" /*      p1 * v1h     |      p0 * v0h       */    \
+      " paddd "#s", "#v"             \n\t" /*      p1 * v1      |      p0 * v0        */    \
+      " packssdw "#v", "#v"          \n\t" /* p0*v0   | p1*v1   | p0*v0   | p1*v1     */         
+
+#define MOD_ADD(a,b) \
+      " add "#a", %3                 \n\t" \
+      " mov %3, %4                   \n\t" \
+      " sub %5, %4                   \n\t" \
+      " cmp %3, "#b"                 \n\t" \
+      " cmovae %4, %3                \n\t" 
+
+  __asm__ __volatile__ (
+    " xor %3, %3                    \n\t"
+    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 2f                         \n\t" 
+
+    " movd (%1, %3, 4), %%mm0       \n\t" /* do odd samples */
+    " movw (%0), %%ax               \n\t" 
+    " movd %%eax, %%mm1             \n\t" 
+    VOLUME_32x16 (%%mm1, %%mm0)
+    " movd %%mm0, %%eax             \n\t" 
+    " movw %%ax, (%0)               \n\t" 
+    " add $2, %0                    \n\t"
+    MOD_ADD ($1, %5)
+    " dec %2                        \n\t"
+
+    "2:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 4f                         \n\t" 
+
+    "3:                             \n\t" /* do samples in pairs of 2 */
+    " movq (%1, %3, 4), %%mm0       \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
+    " movd (%0), %%mm1              \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    VOLUME_32x16 (%%mm1, %%mm0)
+    " movd %%mm0, (%0)              \n\t" 
+    " add $4, %0                    \n\t"
+    MOD_ADD ($2, %5)
+    " dec %2                        \n\t"
+
+    "4:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+    " cmp $0, %2                    \n\t"
+    " je 6f                         \n\t"
+
+    "5:                             \n\t" /* do samples in pairs of 4 */
+    " movq (%1, %3, 4), %%mm0       \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
+    " movq 8(%1, %3, 4), %%mm2      \n\t" /* v3_h  | v3_l  | v2_h  | v2_l      */
+    " movd (%0), %%mm1              \n\t" /*  X    |  X    |  p1   |  p0       */
+    " movd 4(%0), %%mm3             \n\t" /*  X    |  X    |  p3   |  p2       */
+    VOLUME_32x16 (%%mm1, %%mm0)
+    VOLUME_32x16 (%%mm3, %%mm2)
+    " movd %%mm0, (%0)              \n\t" 
+    " movd %%mm2, 4(%0)              \n\t" 
+    " add $8, %0                    \n\t"
+    MOD_ADD ($4, %5)
+    " dec %2                        \n\t"
+    " jne 5b                        \n\t"
+
+    "6:                             \n\t"
+    " emms                          \n\t"
+
+    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((int64_t)channel), "=r" (temp)
+    : "r" ((int64_t)channels)
+    : "rax", "cc"
+  );
+}
+
+#if 0
+static void
+pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int16_t);
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) PA_INT16_SWAP(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = PA_INT16_SWAP((int16_t) t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_float32ne_mmx (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (float);
+
+  for (channel = 0; length; length--) {
+    *samples++ *= volumes[channel];
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_float32re_mmx (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (float);
+
+  for (channel = 0; length; length--) {
+    float t;
+
+    t = PA_FLOAT32_SWAP(*samples);
+    t *= volumes[channel];
+    *samples++ = PA_FLOAT32_SWAP(t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s32ne_mmx (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t)(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = (int32_t) t;
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s32re_mmx (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) PA_INT32_SWAP(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_INT32_SWAP((int32_t) t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24ne_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
+
+  e = samples + length;
+
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
+
+    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24re_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
+
+  e = samples + length;
+
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
+
+    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24_32ne_mmx (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (uint32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) ((int32_t) (*samples << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24_32re_mmx (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (uint32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+#endif
+
+#undef RUN_TEST
+
+#ifdef RUN_TEST
+#define CHANNELS 1
+#define SAMPLES 1021
+#define TIMES 1000
+
+static void run_test (void) {
+  int16_t samples[SAMPLES];
+  int16_t samples_ref[SAMPLES];
+  int16_t samples_orig[SAMPLES];
+  int32_t volumes[CHANNELS];
+  int i, j;
+  pa_do_volume_func_t func;
+
+  func = pa_get_volume_func (PA_SAMPLE_S16NE);
+
+  printf ("checking\n");
+
+  for (j = 0; j < TIMES; j++) {
+    pa_random (samples, sizeof (samples));
+    memcpy (samples_ref, samples, sizeof (samples));
+    memcpy (samples_orig, samples, sizeof (samples));
+
+    for (i = 0; i < CHANNELS; i++) {
+      volumes[i] = rand() >> 15;
+    }
+
+    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
+    func (samples_ref, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
+
+    for (i = 0; i < SAMPLES; i++) {
+      if (samples[i] != samples_ref[i]) {
+        printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
+  		      samples_orig[i], volumes[i % CHANNELS]);
+      }
+#if 0
+      else
+        printf ("%d: %04x == %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
+  		      samples_orig[i], volumes[i % CHANNELS]);
+#endif
+    }
+  }
+}
+#endif
+
+void pa_volume_func_init_mmx (void) {
+  pa_log_info("Initialising MMX optimized functions.");
+
+#ifdef RUN_TEST
+  run_test ();
+#endif
+
+  pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_mmx);
+}

commit 08f3e16c84fabca9c6789440f98ff8dca62eb81a
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 12 20:43:37 2009 +0200

    volume_mmx: fix mmx code a bit

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 9f49a62..6dcc26c 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -104,14 +104,15 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 {
   int64_t channel, temp;
 
-  /* the max number of samples we process at a time */
+  /* 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 = MAX (4, channels);
 
 #define VOLUME_32x16(s,v)                  /* v1_h    | v1_l    | v0_h    | v0_l      */    \
       " pxor %%mm4, %%mm4            \n\t"                                                  \
       " punpcklwd %%mm4, "#s"        \n\t" /* 0       |  p1     | 0       | p0        */    \
       " pcmpgtw "#s", %%mm4          \n\t" /* select sign from sample                 */    \
-      " pand "#v", %%mm4             \n\t" /* extract correction factors              */    \
+      " pand "#v", %%mm4             \n\t" /* extract sign correction factors         */    \
       " movq "#s", %%mm5             \n\t"                                                  \
       " pmulhuw "#v", "#s"           \n\t" /*   0     | p1*v1lh |    0    | p0*v0lh   */    \
       " psubd %%mm4, "#s"            \n\t" /* sign correction                         */    \
@@ -123,8 +124,8 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 #define MOD_ADD(a,b) \
       " add "#a", %3                 \n\t" \
       " mov %3, %4                   \n\t" \
-      " sub %5, %4                   \n\t" \
-      " cmp %3, "#b"                 \n\t" \
+      " sub "#b", %4                 \n\t" \
+      " cmp "#b", %3                 \n\t" \
       " cmovae %4, %3                \n\t" 
 
   __asm__ __volatile__ (
@@ -135,14 +136,13 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " je 2f                         \n\t" 
 
     " movd (%1, %3, 4), %%mm0       \n\t" /* do odd samples */
-    " movw (%0), %%ax               \n\t" 
-    " movd %%eax, %%mm1             \n\t" 
+    " movw (%0), %4                 \n\t" 
+    " movd %4, %%mm1                \n\t" 
     VOLUME_32x16 (%%mm1, %%mm0)
-    " movd %%mm0, %%eax             \n\t" 
-    " movw %%ax, (%0)               \n\t" 
+    " movd %%mm0, %4                \n\t" 
+    " movw %4, (%0)                 \n\t" 
     " add $2, %0                    \n\t"
     MOD_ADD ($1, %5)
-    " dec %2                        \n\t"
 
     "2:                             \n\t"
     " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
@@ -156,7 +156,6 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " movd %%mm0, (%0)              \n\t" 
     " add $4, %0                    \n\t"
     MOD_ADD ($2, %5)
-    " dec %2                        \n\t"
 
     "4:                             \n\t"
     " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
@@ -180,9 +179,9 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     "6:                             \n\t"
     " emms                          \n\t"
 
-    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((int64_t)channel), "=r" (temp)
+    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((int64_t)channel), "=&r" (temp)
     : "r" ((int64_t)channels)
-    : "rax", "cc"
+    : "cc"
   );
 }
 
@@ -370,7 +369,7 @@ pa_volume_s24_32re_mmx (uint32_t *samples, int32_t *volumes, unsigned channels,
 #undef RUN_TEST
 
 #ifdef RUN_TEST
-#define CHANNELS 1
+#define CHANNELS 2
 #define SAMPLES 1021
 #define TIMES 1000
 
@@ -378,25 +377,32 @@ static void run_test (void) {
   int16_t samples[SAMPLES];
   int16_t samples_ref[SAMPLES];
   int16_t samples_orig[SAMPLES];
-  int32_t volumes[CHANNELS];
-  int i, j;
+  int32_t volumes[CHANNELS + 16];
+  int i, j, padding;
   pa_do_volume_func_t func;
 
   func = pa_get_volume_func (PA_SAMPLE_S16NE);
 
-  printf ("checking\n");
+  printf ("checking %d\n", sizeof (samples));
 
   for (j = 0; j < TIMES; j++) {
+    /*
+    for (i = 0; i < SAMPLES; i++) {
+      samples[i] samples_ref[i] = samples_orig[i] = rand() >> 16;
+    }
+    */
+
     pa_random (samples, sizeof (samples));
     memcpy (samples_ref, samples, sizeof (samples));
     memcpy (samples_orig, samples, sizeof (samples));
 
-    for (i = 0; i < CHANNELS; i++) {
+    for (i = 0; i < CHANNELS; i++)
       volumes[i] = rand() >> 15;
-    }
+    for (padding = 0; padding < 16; padding++, i++)
+      volumes[i] = volumes[padding];
 
-    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
-    func (samples_ref, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
+    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
+    func (samples_ref, volumes, CHANNELS, sizeof (samples));
 
     for (i = 0; i < SAMPLES; i++) {
       if (samples[i] != samples_ref[i]) {

commit 7086784573e9e6c92d4c34404f18891c2d19872a
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 12 20:44:12 2009 +0200

    volume_sse: add sse optimisations

diff --git a/src/Makefile.am b/src/Makefile.am
index e7a9900..b692e4a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -826,7 +826,7 @@ libpulsecore_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/rtpoll.c pulsecore/rtpoll.h \
 		pulsecore/sample-util.c pulsecore/sample-util.h \
 		pulsecore/svolume_c.c \
-		pulsecore/svolume_mmx.c \
+		pulsecore/svolume_mmx.c pulsecore/svolume_sse.c \
 		pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
 		pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
 		pulsecore/sconv.c pulsecore/sconv.h \
diff --git a/src/daemon/main.c b/src/daemon/main.c
index e3c395f..3c5f7f9 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -822,6 +822,7 @@ int main(int argc, char *argv[]) {
     pa_memtrap_install();
 
     pa_volume_func_init_mmx();
+    pa_volume_func_init_sse();
 
     pa_assert_se(mainloop = pa_mainloop_new());
 
diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h
index 00b9ae0..563dbb6 100644
--- a/src/pulsecore/sample-util.h
+++ b/src/pulsecore/sample-util.h
@@ -92,6 +92,7 @@ pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f);
 void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func);
 
 void pa_volume_func_init_mmx(void);
+void pa_volume_func_init_sse(void);
 
 #define PA_CHANNEL_POSITION_MASK_LEFT                                   \
     (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT)           \
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
new file mode 100644
index 0000000..2d4c541
--- /dev/null
+++ b/src/pulsecore/svolume_sse.c
@@ -0,0 +1,437 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <alloca.h>
+
+#include <pulsecore/random.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/g711.h>
+#include <pulsecore/core-util.h>
+
+#include "sample-util.h"
+#include "endianmacros.h"
+
+#if 0
+static void
+pa_volume_u8_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) *samples - 0x80;
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
+    *samples++ = (uint8_t) (t + 0x80);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_alaw_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) st_alaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_ulaw_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) st_ulaw2linear16(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+#endif
+
+static void
+pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  int64_t channel;
+  int64_t 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 = MAX (8, channels);
+
+#define VOLUME_32x16(s,v)                  /* v1_h    | v1_l    | v0_h    | v0_l      */    \
+      " pxor %%xmm4, %%xmm4          \n\t"                                                  \
+      " punpcklwd %%xmm4, "#s"       \n\t" /* 0       |  p1     | 0       | p0        */    \
+      " pcmpgtw "#s", %%xmm4         \n\t" /* select sign from sample                 */    \
+      " pand "#v", %%xmm4            \n\t" /* extract sign correction factors         */    \
+      " movdqa "#s", %%xmm5          \n\t"                                                  \
+      " pmulhuw "#v", "#s"           \n\t" /*   0     | p1*v1lh |    0    | p0*v0lh   */    \
+      " psubd %%xmm4, "#s"           \n\t" /* sign correction                         */    \
+      " psrld $16, "#v"              \n\t" /*  0      | v1h     |  0      | v0h       */    \
+      " pmaddwd %%xmm5, "#v"         \n\t" /*      p1 * v1h     |      p0 * v0h       */    \
+      " paddd "#s", "#v"             \n\t" /*      p1 * v1      |      p0 * v0        */    \
+      " packssdw "#v", "#v"          \n\t" /* p0*v0   | p1*v1   | p0*v0   | p1*v1     */         
+
+#define MOD_ADD(a,b) \
+      " add "#a", %3                 \n\t" \
+      " mov %3, %4                   \n\t" \
+      " sub "#b", %4                 \n\t" \
+      " cmp "#b", %3                 \n\t" \
+      " cmovae %4, %3                \n\t" 
+
+  __asm__ __volatile__ (
+    " xor %3, %3                    \n\t"
+    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 2f                         \n\t" 
+
+    " movd (%1, %3, 4), %%xmm0      \n\t" /* do odd sample */
+    " movw (%0), %4                 \n\t" 
+    " movd %4, %%xmm1               \n\t" 
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    " movd %%xmm0, %4               \n\t" 
+    " movw %4, (%0)                 \n\t" 
+    " add $2, %0                    \n\t"
+    MOD_ADD ($1, %5)
+
+    "2:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 4f                         \n\t" 
+
+    "3:                             \n\t" /* do samples in pairs of 2 */
+    " movq (%1, %3, 4), %%xmm0      \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
+    " movd (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    " movd %%xmm0, (%0)             \n\t" 
+    " add $4, %0                    \n\t"
+    MOD_ADD ($2, %5)
+
+    "4:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 6f                         \n\t" 
+
+    "5:                             \n\t" /* do samples in pairs of 4 */
+    " movdqa (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
+    " movq (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    " movq %%xmm0, (%0)             \n\t" 
+    " add $8, %0                    \n\t"
+    MOD_ADD ($4, %5)
+
+    "6:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 8 samples at a time */
+    " cmp $0, %2                    \n\t"
+    " je 8f                         \n\t"
+
+    "7:                             \n\t" /* do samples in pairs of 8 */
+    " movdqa (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
+    " movdqa 16(%1, %3, 4), %%xmm2  \n\t" /* v3_h  | v3_l  | v2_h  | v2_l      */
+    " movq (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */
+    " movq 8(%0), %%xmm3            \n\t" /*  X    |  X    |  p3   |  p2       */
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    VOLUME_32x16 (%%xmm3, %%xmm2)
+    " movq %%xmm0, (%0)             \n\t" 
+    " movq %%xmm2, 8(%0)            \n\t" 
+    " add $16, %0                   \n\t"
+    MOD_ADD ($8, %5)
+    " dec %2                        \n\t"
+    " jne 7b                        \n\t"
+    "8:                             \n\t"
+
+    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
+    : "r" ((int64_t)channels)
+    : "cc"
+  );
+}
+
+#if 0
+static void
+pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int16_t);
+
+  for (channel = 0; length; length--) {
+    int32_t t, hi, lo;
+
+    hi = volumes[channel] >> 16;
+    lo = volumes[channel] & 0xFFFF;
+
+    t = (int32_t) PA_INT16_SWAP(*samples);
+    t = ((t * lo) >> 16) + (t * hi);
+    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+    *samples++ = PA_INT16_SWAP((int16_t) t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_float32ne_sse (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (float);
+
+  for (channel = 0; length; length--) {
+    *samples++ *= volumes[channel];
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_float32re_sse (float *samples, float *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (float);
+
+  for (channel = 0; length; length--) {
+    float t;
+
+    t = PA_FLOAT32_SWAP(*samples);
+    t *= volumes[channel];
+    *samples++ = PA_FLOAT32_SWAP(t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s32ne_sse (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t)(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = (int32_t) t;
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s32re_sse (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (int32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) PA_INT32_SWAP(*samples);
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_INT32_SWAP((int32_t) t);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24ne_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
+
+  e = samples + length;
+
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
+
+    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24re_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+  uint8_t *e;
+
+  e = samples + length;
+
+  for (channel = 0; samples < e; samples += 3) {
+    int64_t t;
+
+    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24_32ne_sse (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (uint32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) ((int32_t) (*samples << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+
+static void
+pa_volume_s24_32re_sse (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  unsigned channel;
+
+  length /= sizeof (uint32_t);
+
+  for (channel = 0; length; length--) {
+    int64_t t;
+
+    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
+    t = (t * volumes[channel]) >> 16;
+    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
+
+    if (PA_UNLIKELY(++channel >= channels))
+      channel = 0;
+  }
+}
+#endif
+
+#undef RUN_TEST
+
+#ifdef RUN_TEST
+#define CHANNELS 2
+#define SAMPLES 1021
+#define TIMES 1000
+
+static void run_test (void) {
+  int16_t samples[SAMPLES];
+  int16_t samples_ref[SAMPLES];
+  int16_t samples_orig[SAMPLES];
+  int32_t volumes[CHANNELS + 16];
+  int i, j, padding;
+  pa_do_volume_func_t func;
+
+  func = pa_get_volume_func (PA_SAMPLE_S16NE);
+
+  printf ("checking %d\n", sizeof (samples));
+
+  for (j = 0; j < TIMES; j++) {
+    pa_random (samples, sizeof (samples));
+    memcpy (samples_ref, samples, sizeof (samples));
+    memcpy (samples_orig, samples, sizeof (samples));
+
+    for (i = 0; i < CHANNELS; i++)
+      volumes[i] = rand() >> 15;
+
+    for (padding = 0; padding < 16; padding++, i++)
+      volumes[i] = volumes[padding];
+
+    pa_volume_s16ne_sse (samples, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
+    func (samples_ref, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
+
+    for (i = 0; i < SAMPLES; i++) {
+      if (samples[i] != samples_ref[i]) {
+        printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
+  		      samples_orig[i], volumes[i % CHANNELS]);
+      }
+#if 0
+      else
+        printf ("%d: %04x == %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
+  		      samples_orig[i], volumes[i % CHANNELS]);
+#endif
+    }
+  }
+}
+#endif
+
+void pa_volume_func_init_sse (void) {
+  pa_log_info("Initialising SSE optimized functions.");
+
+#ifdef RUN_TEST
+  run_test ();
+#endif
+
+  pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_sse);
+}

commit 5998cf99b08d448dd5158ed6229262aa67ea4a66
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 13 13:45:01 2009 +0200

    svolume: improve SSE and MMX code

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 6dcc26c..3c22945 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -99,6 +99,46 @@ pa_volume_ulaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsig
 }
 #endif
 
+#define VOLUME_32x16(s,v)                  /* .. |   vh  |   vl  | */                   \
+      " pxor  %%mm4, %%mm4           \n\t" /* .. |    0  |    0  | */                   \
+      " punpcklwd %%mm4, "#s"        \n\t" /* .. |    0  |   p0  | */                   \
+      " pcmpgtw "#v", %%mm4          \n\t" /* .. |    0  | s(vl) | */                   \
+      " pand "#s", %%mm4             \n\t" /* .. |    0  |  (p0) |  (vl >> 15) & p */   \
+      " movq %%mm6, %%mm5            \n\t" /* .. |  ffff |   0   | */                   \
+      " pand "#v", %%mm5             \n\t" /* .. |   vh  |   0   | */                   \
+      " por %%mm5, %%mm4             \n\t" /* .. |   vh  |  (p0) | */                   \
+      " pmulhw "#s", "#v"            \n\t" /* .. |    0  | vl*p0 | */                   \
+      " paddw %%mm4, "#v"            \n\t" /* .. |   vh  | vl*p0 | vh + sign correct */ \
+      " pslld $16, "#s"              \n\t" /* .. |   p0  |    0  | */                   \
+      " por %%mm7, "#s"              \n\t" /* .. |   p0  |    1  | */                   \
+      " pmaddwd "#s", "#v"           \n\t" /* .. |    p0 * v0    | */                   \
+      " packssdw "#v", "#v"          \n\t" /* .. | p1*v1 | p0*v0 | */
+
+#define MOD_ADD(a,b) \
+      " add "#a", %3                 \n\t" \
+      " mov %3, %4                   \n\t" \
+      " sub "#b", %4                 \n\t" \
+      " cmp "#b", %3                 \n\t" \
+      " cmovae %4, %3                \n\t" 
+
+/* swap 16 bits */
+#define SWAP_16(s) \
+      " movq "#s", %%mm4             \n\t" /* .. |  h  l |  */ \
+      " psrlw $8, %%mm4              \n\t" /* .. |  0  h |  */ \
+      " psllw $8, "#s"               \n\t" /* .. |  l  0 |  */ \
+      " por %%mm4, "#s"              \n\t" /* .. |  l  h |  */
+
+/* swap 2 registers 16 bits for better pairing */
+#define SWAP_16_2(s1,s2) \
+      " movq "#s1", %%mm4            \n\t" /* .. |  h  l |  */ \
+      " movq "#s2", %%mm5            \n\t"                     \
+      " psrlw $8, %%mm4              \n\t" /* .. |  0  h |  */ \
+      " psrlw $8, %%mm5              \n\t"                     \
+      " psllw $8, "#s1"              \n\t" /* .. |  l  0 |  */ \
+      " psllw $8, "#s2"              \n\t"                     \
+      " por %%mm4, "#s1"             \n\t" /* .. |  l  h |  */ \
+      " por %%mm5, "#s2"             \n\t"
+
 static void
 pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
@@ -108,38 +148,22 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
    * we overread the volume array, which should have enough padding. */
   channels = MAX (4, channels);
 
-#define VOLUME_32x16(s,v)                  /* v1_h    | v1_l    | v0_h    | v0_l      */    \
-      " pxor %%mm4, %%mm4            \n\t"                                                  \
-      " punpcklwd %%mm4, "#s"        \n\t" /* 0       |  p1     | 0       | p0        */    \
-      " pcmpgtw "#s", %%mm4          \n\t" /* select sign from sample                 */    \
-      " pand "#v", %%mm4             \n\t" /* extract sign correction factors         */    \
-      " movq "#s", %%mm5             \n\t"                                                  \
-      " pmulhuw "#v", "#s"           \n\t" /*   0     | p1*v1lh |    0    | p0*v0lh   */    \
-      " psubd %%mm4, "#s"            \n\t" /* sign correction                         */    \
-      " psrld $16, "#v"              \n\t" /*  0      | v1h     |  0      | v0h       */    \
-      " pmaddwd %%mm5, "#v"          \n\t" /*      p1 * v1h     |      p0 * v0h       */    \
-      " paddd "#s", "#v"             \n\t" /*      p1 * v1      |      p0 * v0        */    \
-      " packssdw "#v", "#v"          \n\t" /* p0*v0   | p1*v1   | p0*v0   | p1*v1     */         
-
-#define MOD_ADD(a,b) \
-      " add "#a", %3                 \n\t" \
-      " mov %3, %4                   \n\t" \
-      " sub "#b", %4                 \n\t" \
-      " cmp "#b", %3                 \n\t" \
-      " cmovae %4, %3                \n\t" 
-
   __asm__ __volatile__ (
     " xor %3, %3                    \n\t"
     " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+    " pcmpeqw %%mm6, %%mm6          \n\t" /* .. |  ffff |  ffff | */
+    " pcmpeqw %%mm7, %%mm7          \n\t" /* .. |  ffff |  ffff | */
+    " pslld  $16, %%mm6             \n\t" /* .. |  ffff |     0 | */
+    " psrld  $31, %%mm7             \n\t" /* .. |     0 |     1 | */
 
     " test $1, %2                   \n\t" /* check for odd samples */
     " je 2f                         \n\t" 
 
-    " movd (%1, %3, 4), %%mm0       \n\t" /* do odd samples */
-    " movw (%0), %4                 \n\t" 
+    " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
+    " movw (%0), %4                 \n\t" /*     ..  |  p0   | */
     " movd %4, %%mm1                \n\t" 
     VOLUME_32x16 (%%mm1, %%mm0)
-    " movd %%mm0, %4                \n\t" 
+    " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
     " movw %4, (%0)                 \n\t" 
     " add $2, %0                    \n\t"
     MOD_ADD ($1, %5)
@@ -149,11 +173,11 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " test $1, %2                   \n\t" /* check for odd samples */
     " je 4f                         \n\t" 
 
-    "3:                             \n\t" /* do samples in pairs of 2 */
-    " movq (%1, %3, 4), %%mm0       \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
-    " movd (%0), %%mm1              \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    "3:                             \n\t" /* do samples in groups of 2 */
+    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */ 
     VOLUME_32x16 (%%mm1, %%mm0)
-    " movd %%mm0, (%0)              \n\t" 
+    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
     " add $4, %0                    \n\t"
     MOD_ADD ($2, %5)
 
@@ -162,15 +186,15 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " cmp $0, %2                    \n\t"
     " je 6f                         \n\t"
 
-    "5:                             \n\t" /* do samples in pairs of 4 */
-    " movq (%1, %3, 4), %%mm0       \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
-    " movq 8(%1, %3, 4), %%mm2      \n\t" /* v3_h  | v3_l  | v2_h  | v2_l      */
-    " movd (%0), %%mm1              \n\t" /*  X    |  X    |  p1   |  p0       */
-    " movd 4(%0), %%mm3             \n\t" /*  X    |  X    |  p3   |  p2       */
+    "5:                             \n\t" /* do samples in groups of 4 */
+    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */ 
+    " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
+    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
+    " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
     VOLUME_32x16 (%%mm1, %%mm0)
     VOLUME_32x16 (%%mm3, %%mm2)
-    " movd %%mm0, (%0)              \n\t" 
-    " movd %%mm2, 4(%0)              \n\t" 
+    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
+    " movd %%mm2, 4(%0)             \n\t" /* | p3*v3 | p2*v2 | */
     " add $8, %0                    \n\t"
     MOD_ADD ($4, %5)
     " dec %2                        \n\t"
@@ -185,30 +209,83 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
   );
 }
 
-#if 0
 static void
 pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+  int64_t channel, temp;
 
-  length /= sizeof (int16_t);
+  /* 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 = MAX (4, channels);
 
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
+  __asm__ __volatile__ (
+    " xor %3, %3                    \n\t"
+    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+    " pcmpeqw %%mm6, %%mm6          \n\t" /* .. |  ffff |  ffff | */
+    " pcmpeqw %%mm7, %%mm7          \n\t" /* .. |  ffff |  ffff | */
+    " pslld  $16, %%mm6             \n\t" /* .. |  ffff |     0 | */
+    " psrld  $31, %%mm7             \n\t" /* .. |     0 |     1 | */
 
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 2f                         \n\t" 
 
-    t = (int32_t) PA_INT16_SWAP(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = PA_INT16_SWAP((int16_t) t);
+    " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
+    " movw (%0), %4                 \n\t" /*     ..  |  p0   | */
+    " rorw $8, %4                   \n\t"
+    " movd %4, %%mm1                \n\t" 
+    VOLUME_32x16 (%%mm1, %%mm0)
+    " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
+    " rorw $8, %4                   \n\t"
+    " movw %4, (%0)                 \n\t" 
+    " add $2, %0                    \n\t"
+    MOD_ADD ($1, %5)
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+    "2:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 4f                         \n\t" 
+
+    "3:                             \n\t" /* do samples in groups of 2 */
+    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */ 
+    SWAP_16 (%%mm1)
+    VOLUME_32x16 (%%mm1, %%mm0)
+    SWAP_16 (%%mm0)
+    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
+    " add $4, %0                    \n\t"
+    MOD_ADD ($2, %5)
+
+    "4:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+    " cmp $0, %2                    \n\t"
+    " je 6f                         \n\t"
+
+    "5:                             \n\t" /* do samples in groups of 4 */
+    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */ 
+    " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
+    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
+    " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
+    SWAP_16_2 (%%mm1, %%mm3)
+    VOLUME_32x16 (%%mm1, %%mm0)
+    VOLUME_32x16 (%%mm3, %%mm2)
+    SWAP_16_2 (%%mm0, %%mm2)
+    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
+    " movd %%mm2, 4(%0)             \n\t" /* | p3*v3 | p2*v2 | */
+    " add $8, %0                    \n\t"
+    MOD_ADD ($4, %5)
+    " dec %2                        \n\t"
+    " jne 5b                        \n\t"
+
+    "6:                             \n\t"
+    " emms                          \n\t"
+
+    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((int64_t)channel), "=&r" (temp)
+    : "r" ((int64_t)channels)
+    : "cc"
+  );
 }
 
+#if 0
 static void
 pa_volume_float32ne_mmx (float *samples, float *volumes, unsigned channels, unsigned length)
 {
@@ -366,42 +443,37 @@ pa_volume_s24_32re_mmx (uint32_t *samples, int32_t *volumes, unsigned channels,
 }
 #endif
 
-#undef RUN_TEST
+#define RUN_TEST
 
 #ifdef RUN_TEST
 #define CHANNELS 2
 #define SAMPLES 1021
 #define TIMES 1000
+#define PADDING 16
 
 static void run_test (void) {
   int16_t samples[SAMPLES];
   int16_t samples_ref[SAMPLES];
   int16_t samples_orig[SAMPLES];
-  int32_t volumes[CHANNELS + 16];
+  int32_t volumes[CHANNELS + PADDING];
   int i, j, padding;
   pa_do_volume_func_t func;
 
-  func = pa_get_volume_func (PA_SAMPLE_S16NE);
+  func = pa_get_volume_func (PA_SAMPLE_S16RE);
 
-  printf ("checking %d\n", sizeof (samples));
+  printf ("checking MMX %d\n", sizeof (samples));
 
   for (j = 0; j < TIMES; j++) {
-    /*
-    for (i = 0; i < SAMPLES; i++) {
-      samples[i] samples_ref[i] = samples_orig[i] = rand() >> 16;
-    }
-    */
-
     pa_random (samples, sizeof (samples));
     memcpy (samples_ref, samples, sizeof (samples));
     memcpy (samples_orig, samples, sizeof (samples));
 
     for (i = 0; i < CHANNELS; i++)
-      volumes[i] = rand() >> 15;
-    for (padding = 0; padding < 16; padding++, i++)
+      volumes[i] = rand() >> 1;
+    for (padding = 0; padding < PADDING; padding++, i++)
       volumes[i] = volumes[padding];
 
-    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
+    pa_volume_s16re_mmx (samples, volumes, CHANNELS, sizeof (samples));
     func (samples_ref, volumes, CHANNELS, sizeof (samples));
 
     for (i = 0; i < SAMPLES; i++) {
@@ -409,11 +481,6 @@ static void run_test (void) {
         printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
   		      samples_orig[i], volumes[i % CHANNELS]);
       }
-#if 0
-      else
-        printf ("%d: %04x == %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
-  		      samples_orig[i], volumes[i % CHANNELS]);
-#endif
     }
   }
 }
@@ -427,4 +494,5 @@ void pa_volume_func_init_mmx (void) {
 #endif
 
   pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_mmx);
+  pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_mmx);
 }
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 2d4c541..ff583a0 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -99,6 +99,44 @@ pa_volume_ulaw_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsig
 }
 #endif
 
+#define VOLUME_32x16(s,v)                  /* .. |   vh  |   vl  | */                   \
+      " pxor %%xmm4, %%xmm4          \n\t" /* .. |    0  |    0  | */                   \
+      " punpcklwd %%xmm4, "#s"       \n\t" /* .. |    0  |   p0  | */                   \
+      " pcmpgtw "#s", %%xmm4         \n\t" /* .. |    0  | s(p0) | */                   \
+      " pand "#v", %%xmm4            \n\t" /* .. |    0  |  (vl) | */                   \
+      " movdqa "#s", %%xmm5          \n\t"                                              \
+      " pmulhuw "#v", "#s"           \n\t" /* .. |    0  | vl*p0 | */                   \
+      " psubd %%xmm4, "#s"           \n\t" /* .. |    0  | vl*p0 | + sign correct */    \
+      " psrld $16, "#v"              \n\t" /* .. |   p0  |    0  | */                   \
+      " pmaddwd %%xmm5, "#v"         \n\t" /* .. |    p0 * vh    | */                   \
+      " paddd "#s", "#v"             \n\t" /* .. |    p0 * v0    | */                   \
+      " packssdw "#v", "#v"          \n\t" /* .. | p1*v1 | p0*v0 | */         
+
+#define MOD_ADD(a,b) \
+      " add "#a", %3                 \n\t" /* channel += inc           */ \
+      " mov %3, %4                   \n\t"                                \
+      " sub "#b", %4                 \n\t" /* tmp = channel - channels */ \
+      " cmp "#b", %3                 \n\t" /* if (channel >= channels) */ \
+      " cmovae %4, %3                \n\t" /*   channel = tmp          */
+
+/* swap 16 bits */
+#define SWAP_16(s) \
+      " movdqa "#s", %%xmm4          \n\t" /* .. |  h  l |  */ \
+      " psrlw $8, %%xmm4             \n\t" /* .. |  0  h |  */ \
+      " psllw $8, "#s"               \n\t" /* .. |  l  0 |  */ \
+      " por %%xmm4, "#s"             \n\t" /* .. |  l  h |  */
+
+/* swap 2 registers 16 bits for better pairing */
+#define SWAP_16_2(s1,s2) \
+      " movdqa "#s1", %%xmm4         \n\t" /* .. |  h  l |  */ \
+      " movdqa "#s2", %%xmm5         \n\t"                     \
+      " psrlw $8, %%xmm4             \n\t" /* .. |  0  h |  */ \
+      " psrlw $8, %%xmm5             \n\t"                     \
+      " psllw $8, "#s1"              \n\t" /* .. |  l  0 |  */ \
+      " psllw $8, "#s2"              \n\t"                     \
+      " por %%xmm4, "#s1"            \n\t" /* .. |  l  h |  */ \
+      " por %%xmm5, "#s2"            \n\t"
+
 static void
 pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
@@ -109,25 +147,83 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
    * we overread the volume array, which should have enough padding. */
   channels = MAX (8, channels);
 
-#define VOLUME_32x16(s,v)                  /* v1_h    | v1_l    | v0_h    | v0_l      */    \
-      " pxor %%xmm4, %%xmm4          \n\t"                                                  \
-      " punpcklwd %%xmm4, "#s"       \n\t" /* 0       |  p1     | 0       | p0        */    \
-      " pcmpgtw "#s", %%xmm4         \n\t" /* select sign from sample                 */    \
-      " pand "#v", %%xmm4            \n\t" /* extract sign correction factors         */    \
-      " movdqa "#s", %%xmm5          \n\t"                                                  \
-      " pmulhuw "#v", "#s"           \n\t" /*   0     | p1*v1lh |    0    | p0*v0lh   */    \
-      " psubd %%xmm4, "#s"           \n\t" /* sign correction                         */    \
-      " psrld $16, "#v"              \n\t" /*  0      | v1h     |  0      | v0h       */    \
-      " pmaddwd %%xmm5, "#v"         \n\t" /*      p1 * v1h     |      p0 * v0h       */    \
-      " paddd "#s", "#v"             \n\t" /*      p1 * v1      |      p0 * v0        */    \
-      " packssdw "#v", "#v"          \n\t" /* p0*v0   | p1*v1   | p0*v0   | p1*v1     */         
+  __asm__ __volatile__ (
+    " xor %3, %3                    \n\t"
+    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
 
-#define MOD_ADD(a,b) \
-      " add "#a", %3                 \n\t" \
-      " mov %3, %4                   \n\t" \
-      " sub "#b", %4                 \n\t" \
-      " cmp "#b", %3                 \n\t" \
-      " cmovae %4, %3                \n\t" 
+    " test $1, %2                   \n\t" /* check for odd samples */
+    " je 2f                         \n\t" 
+
+    " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
+    " movw (%0), %4                 \n\t" /*     ..  |   p0  | */
+    " movd %4, %%xmm1               \n\t" 
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
+    " movw %4, (%0)                 \n\t" 
+    " add $2, %0                    \n\t"
+    MOD_ADD ($1, %5)
+
+    "2:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+    " test $1, %2                   \n\t" 
+    " je 4f                         \n\t" 
+
+    "3:                             \n\t" /* do samples in groups of 2 */
+    " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+    " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    " movd %%xmm0, (%0)             \n\t" /*              .. | p1*v1 | p0*v0 | */
+    " add $4, %0                    \n\t"
+    MOD_ADD ($2, %5)
+
+    "4:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+    " test $1, %2                   \n\t" 
+    " je 6f                         \n\t" 
+
+    "5:                             \n\t" /* do samples in groups of 4 */
+    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
+    " add $8, %0                    \n\t"
+    MOD_ADD ($4, %5)
+
+    "6:                             \n\t"
+    " sar $1, %2                    \n\t" /* prepare for processing 8 samples at a time */
+    " cmp $0, %2                    \n\t"
+    " je 8f                         \n\t"
+
+    "7:                             \n\t" /* do samples in groups of 8 */
+    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+    " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
+    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
+    " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
+    VOLUME_32x16 (%%xmm1, %%xmm0)
+    VOLUME_32x16 (%%xmm3, %%xmm2)
+    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
+    " movq %%xmm2, 8(%0)            \n\t" /*              .. | p7*v7 .. p4*v4 | */
+    " add $16, %0                   \n\t"
+    MOD_ADD ($8, %5)
+    " dec %2                        \n\t"
+    " jne 7b                        \n\t"
+    "8:                             \n\t"
+
+    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
+    : "r" ((int64_t)channels)
+    : "cc"
+  );
+}
+
+static void
+pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  int64_t channel;
+  int64_t 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 = MAX (8, channels);
 
   __asm__ __volatile__ (
     " xor %3, %3                    \n\t"
@@ -138,9 +234,11 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 
     " movd (%1, %3, 4), %%xmm0      \n\t" /* do odd sample */
     " movw (%0), %4                 \n\t" 
+    " rorw $8, %4                   \n\t" 
     " movd %4, %%xmm1               \n\t" 
     VOLUME_32x16 (%%xmm1, %%xmm0)
     " movd %%xmm0, %4               \n\t" 
+    " rorw $8, %4                   \n\t" 
     " movw %4, (%0)                 \n\t" 
     " add $2, %0                    \n\t"
     MOD_ADD ($1, %5)
@@ -153,7 +251,9 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     "3:                             \n\t" /* do samples in pairs of 2 */
     " movq (%1, %3, 4), %%xmm0      \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
     " movd (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    SWAP_16 (%%xmm1)
     VOLUME_32x16 (%%xmm1, %%xmm0)
+    SWAP_16 (%%xmm0)
     " movd %%xmm0, (%0)             \n\t" 
     " add $4, %0                    \n\t"
     MOD_ADD ($2, %5)
@@ -164,9 +264,11 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " je 6f                         \n\t" 
 
     "5:                             \n\t" /* do samples in pairs of 4 */
-    " movdqa (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
+    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
     " movq (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    SWAP_16 (%%xmm1)
     VOLUME_32x16 (%%xmm1, %%xmm0)
+    SWAP_16 (%%xmm0)
     " movq %%xmm0, (%0)             \n\t" 
     " add $8, %0                    \n\t"
     MOD_ADD ($4, %5)
@@ -177,12 +279,14 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " je 8f                         \n\t"
 
     "7:                             \n\t" /* do samples in pairs of 8 */
-    " movdqa (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
-    " movdqa 16(%1, %3, 4), %%xmm2  \n\t" /* v3_h  | v3_l  | v2_h  | v2_l      */
+    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
+    " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* v3_h  | v3_l  | v2_h  | v2_l      */
     " movq (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */
     " movq 8(%0), %%xmm3            \n\t" /*  X    |  X    |  p3   |  p2       */
+    SWAP_16_2 (%%xmm1, %%xmm3)
     VOLUME_32x16 (%%xmm1, %%xmm0)
     VOLUME_32x16 (%%xmm3, %%xmm2)
+    SWAP_16_2 (%%xmm0, %%xmm2)
     " movq %%xmm0, (%0)             \n\t" 
     " movq %%xmm2, 8(%0)            \n\t" 
     " add $16, %0                   \n\t"
@@ -199,29 +303,6 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 
 #if 0
 static void
-pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int16_t);
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) PA_INT16_SWAP(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = PA_INT16_SWAP((int16_t) t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
 pa_volume_float32ne_sse (float *samples, float *volumes, unsigned channels, unsigned length)
 {
   unsigned channel;
@@ -378,24 +459,25 @@ pa_volume_s24_32re_sse (uint32_t *samples, int32_t *volumes, unsigned channels,
 }
 #endif
 
-#undef RUN_TEST
+#define RUN_TEST
 
 #ifdef RUN_TEST
 #define CHANNELS 2
 #define SAMPLES 1021
 #define TIMES 1000
+#define PADDING 16
 
 static void run_test (void) {
   int16_t samples[SAMPLES];
   int16_t samples_ref[SAMPLES];
   int16_t samples_orig[SAMPLES];
-  int32_t volumes[CHANNELS + 16];
+  int32_t volumes[CHANNELS + PADDING];
   int i, j, padding;
   pa_do_volume_func_t func;
 
-  func = pa_get_volume_func (PA_SAMPLE_S16NE);
+  func = pa_get_volume_func (PA_SAMPLE_S16RE);
 
-  printf ("checking %d\n", sizeof (samples));
+  printf ("checking SSE %d\n", sizeof (samples));
 
   for (j = 0; j < TIMES; j++) {
     pa_random (samples, sizeof (samples));
@@ -403,12 +485,11 @@ static void run_test (void) {
     memcpy (samples_orig, samples, sizeof (samples));
 
     for (i = 0; i < CHANNELS; i++)
-      volumes[i] = rand() >> 15;
-
-    for (padding = 0; padding < 16; padding++, i++)
+      volumes[i] = rand() >> 1;
+    for (padding = 0; padding < PADDING; padding++, i++)
       volumes[i] = volumes[padding];
 
-    pa_volume_s16ne_sse (samples, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
+    pa_volume_s16re_sse (samples, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
     func (samples_ref, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
 
     for (i = 0; i < SAMPLES; i++) {
@@ -416,11 +497,6 @@ static void run_test (void) {
         printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
   		      samples_orig[i], volumes[i % CHANNELS]);
       }
-#if 0
-      else
-        printf ("%d: %04x == %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
-  		      samples_orig[i], volumes[i % CHANNELS]);
-#endif
     }
   }
 }
@@ -434,4 +510,5 @@ void pa_volume_func_init_sse (void) {
 #endif
 
   pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_sse);
+  pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_sse);
 }

commit a83f5524fbf2f0fa861d2fae6973f0f42e8c9c25
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 13 17:11:43 2009 +0200

    cpu-x86: add cpu detection code and helpers
    
    Add CPU detection code and various macros and typdefs to make it easier to write
    64 and 32 bit code.

diff --git a/src/Makefile.am b/src/Makefile.am
index b692e4a..4e90d79 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -825,6 +825,7 @@ libpulsecore_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/resampler.c pulsecore/resampler.h \
 		pulsecore/rtpoll.c pulsecore/rtpoll.h \
 		pulsecore/sample-util.c pulsecore/sample-util.h \
+		pulsecore/cpu-x86.c \
 		pulsecore/svolume_c.c \
 		pulsecore/svolume_mmx.c pulsecore/svolume_sse.c \
 		pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
diff --git a/src/pulsecore/cpu-x86.c b/src/pulsecore/cpu-x86.c
new file mode 100644
index 0000000..2da31c9
--- /dev/null
+++ b/src/pulsecore/cpu-x86.c
@@ -0,0 +1,122 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk> 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+
+#include <pulsecore/log.h>
+
+#include "cpu-x86.h"
+
+#if defined (__i386__) || defined (__amd64__)
+static void
+get_cpuid (uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
+{
+  __asm__ __volatile__ (
+      "  push %%"PA_REG_b"   \n\t"
+      "  cpuid               \n\t"
+      "  mov %%ebx, %%esi    \n\t"
+      "  pop %%"PA_REG_b"    \n\t"
+
+      : "=a" (*a), "=S" (*b), "=c" (*c), "=d" (*d)
+      : "0" (op));
+}
+#endif
+
+static pa_cpu_x86_flag_t pa_cpu_x86_flags;
+
+void pa_cpu_init_x86 (void) {
+#if defined (__i386__) || defined (__amd64__)
+    uint32_t eax, ebx, ecx, edx;
+    uint32_t level;
+
+    /* get standard level */
+    get_cpuid (0x00000000, &level, &ebx, &ecx, &edx);
+    if (level >= 1) {
+        get_cpuid (0x00000001, &eax, &ebx, &ecx, &edx);
+
+        if (edx & (1<<23))
+          pa_cpu_x86_flags |= PA_CPU_X86_MMX;
+
+        if (edx & (1<<25))
+          pa_cpu_x86_flags |= PA_CPU_X86_SSE;
+
+        if (edx & (1<<26))
+          pa_cpu_x86_flags |= PA_CPU_X86_SSE2;
+
+        if (ecx & (1<<0))
+          pa_cpu_x86_flags |= PA_CPU_X86_SSE3;
+
+        if (ecx & (1<<9))
+          pa_cpu_x86_flags |= PA_CPU_X86_SSSE3;
+
+        if (ecx & (1<<19))
+          pa_cpu_x86_flags |= PA_CPU_X86_SSE4_1;
+
+        if (ecx & (1<<20))
+          pa_cpu_x86_flags |= PA_CPU_X86_SSE4_2;
+    }
+
+    /* get extended level */
+    get_cpuid (0x80000000, &level, &ebx, &ecx, &edx);
+    if (level >= 0x80000001) {
+        get_cpuid (0x80000001, &eax, &ebx, &ecx, &edx);
+
+        if (edx & (1<<22))
+          pa_cpu_x86_flags |= PA_CPU_X86_MMXEXT;
+
+        if (edx & (1<<23))
+          pa_cpu_x86_flags |= PA_CPU_X86_MMX;
+
+        if (edx & (1<<30))
+          pa_cpu_x86_flags |= PA_CPU_X86_3DNOWEXT;
+
+        if (edx & (1<<31))
+          pa_cpu_x86_flags |= PA_CPU_X86_3DNOW;
+    }
+
+    pa_log_info ("CPU flags: %s%s%s%s%s%s%s%s%s%s",
+	  (pa_cpu_x86_flags & PA_CPU_X86_MMX) ? "MMX " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_SSE) ? "SSE " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
+	  (pa_cpu_x86_flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
+
+    /* activate various optimisations */
+    if (pa_cpu_x86_flags & PA_CPU_X86_MMX) {
+        pa_volume_func_init_mmx (pa_cpu_x86_flags);
+    }
+    if (pa_cpu_x86_flags & PA_CPU_X86_SSE) {
+	pa_volume_func_init_sse (pa_cpu_x86_flags);
+    }
+#else
+    pa_cpu_x86_flags = 0;
+#endif
+}
diff --git a/src/pulsecore/cpu-x86.h b/src/pulsecore/cpu-x86.h
new file mode 100644
index 0000000..8158ea7
--- /dev/null
+++ b/src/pulsecore/cpu-x86.h
@@ -0,0 +1,61 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk> 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <stdint.h>
+
+typedef enum pa_cpu_x86_flag {
+    PA_CPU_X86_MMX       = (1 << 0),
+    PA_CPU_X86_MMXEXT    = (1 << 1),
+    PA_CPU_X86_SSE       = (1 << 2),
+    PA_CPU_X86_SSE2      = (1 << 3),
+    PA_CPU_X86_SSE3      = (1 << 4),
+    PA_CPU_X86_SSSE3     = (1 << 5),
+    PA_CPU_X86_SSE4_1    = (1 << 6),
+    PA_CPU_X86_SSE4_2    = (1 << 7),
+    PA_CPU_X86_3DNOW     = (1 << 8),
+    PA_CPU_X86_3DNOWEXT  = (1 << 9)
+} pa_cpu_x86_flag_t;
+
+void pa_cpu_init_x86 (void);
+
+
+#if defined (__i386__)
+typedef int32_t pa_reg_x86;
+#define PA_REG_a "eax"
+#define PA_REG_b "ebx"
+#define PA_REG_c "ecx"
+#define PA_REG_d "edx"
+#define PA_REG_D "edi"
+#define PA_REG_S "esi"
+#elif defined (__amd64__)
+typedef int64_t pa_reg_x86;
+#define PA_REG_a "rax"
+#define PA_REG_b "rbx"
+#define PA_REG_c "rcx"
+#define PA_REG_d "rdx"
+#define PA_REG_D "rdi"
+#define PA_REG_S "rsi"
+#endif
+
+/* some optimized functions */
+void pa_volume_func_init_mmx(pa_cpu_x86_flag_t flags);
+void pa_volume_func_init_sse(pa_cpu_x86_flag_t flags);

commit 563cb2dea9f7f73180e2b8cc8d45b0df9358c936
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 13 17:12:44 2009 +0200

    main: hook up cpu detection code
    
    Add CPU detection code to activate the various optimisations.
    Move some method definitions around.
    Use compatibility macros when we can.

diff --git a/src/daemon/main.c b/src/daemon/main.c
index 3c5f7f9..774b4e9 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -95,6 +95,7 @@
 #ifdef HAVE_DBUS
 #include <pulsecore/dbus-shared.h>
 #endif
+#include <pulsecore/cpu-x86.h>
 
 #include "cmdline.h"
 #include "cpulimit.h"
@@ -821,8 +822,7 @@ int main(int argc, char *argv[]) {
 
     pa_memtrap_install();
 
-    pa_volume_func_init_mmx();
-    pa_volume_func_init_sse();
+    pa_cpu_init_x86();
 
     pa_assert_se(mainloop = pa_mainloop_new());
 
diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h
index 563dbb6..34df5cf 100644
--- a/src/pulsecore/sample-util.h
+++ b/src/pulsecore/sample-util.h
@@ -91,9 +91,6 @@ typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned chan
 pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f);
 void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func);
 
-void pa_volume_func_init_mmx(void);
-void pa_volume_func_init_sse(void);
-
 #define PA_CHANNEL_POSITION_MASK_LEFT                                   \
     (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT)           \
      | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_LEFT)          \
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 3c22945..e56f7c3 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -31,6 +31,8 @@
 #include <pulsecore/g711.h>
 #include <pulsecore/core-util.h>
 
+#include "cpu-x86.h"
+
 #include "sample-util.h"
 #include "endianmacros.h"
 
@@ -142,7 +144,7 @@ pa_volume_ulaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsig
 static void
 pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  int64_t channel, temp;
+  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. */
@@ -203,8 +205,8 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     "6:                             \n\t"
     " emms                          \n\t"
 
-    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((int64_t)channel), "=&r" (temp)
-    : "r" ((int64_t)channels)
+    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
+    : "r" ((pa_reg_x86)channels)
     : "cc"
   );
 }
@@ -212,7 +214,7 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 static void
 pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  int64_t channel, temp;
+  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. */
@@ -279,8 +281,8 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     "6:                             \n\t"
     " emms                          \n\t"
 
-    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((int64_t)channel), "=&r" (temp)
-    : "r" ((int64_t)channels)
+    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
+    : "r" ((pa_reg_x86)channels)
     : "cc"
   );
 }
@@ -443,7 +445,7 @@ pa_volume_s24_32re_mmx (uint32_t *samples, int32_t *volumes, unsigned channels,
 }
 #endif
 
-#define RUN_TEST
+#undef RUN_TEST
 
 #ifdef RUN_TEST
 #define CHANNELS 2
@@ -486,7 +488,7 @@ static void run_test (void) {
 }
 #endif
 
-void pa_volume_func_init_mmx (void) {
+void pa_volume_func_init_mmx (pa_cpu_x86_flag_t flags) {
   pa_log_info("Initialising MMX optimized functions.");
 
 #ifdef RUN_TEST
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index ff583a0..b60471a 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -31,6 +31,8 @@
 #include <pulsecore/g711.h>
 #include <pulsecore/core-util.h>
 
+#include "cpu-x86.h"
+
 #include "sample-util.h"
 #include "endianmacros.h"
 
@@ -140,8 +142,7 @@ pa_volume_ulaw_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsig
 static void
 pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  int64_t channel;
-  int64_t temp;
+  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. */
@@ -210,7 +211,7 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     "8:                             \n\t"
 
     : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
-    : "r" ((int64_t)channels)
+    : "r" ((pa_reg_x86)channels)
     : "cc"
   );
 }
@@ -218,8 +219,7 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 static void
 pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  int64_t channel;
-  int64_t temp;
+  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. */
@@ -296,7 +296,7 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     "8:                             \n\t"
 
     : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
-    : "r" ((int64_t)channels)
+    : "r" ((pa_reg_x86)channels)
     : "cc"
   );
 }
@@ -459,7 +459,7 @@ pa_volume_s24_32re_sse (uint32_t *samples, int32_t *volumes, unsigned channels,
 }
 #endif
 
-#define RUN_TEST
+#undef RUN_TEST
 
 #ifdef RUN_TEST
 #define CHANNELS 2
@@ -502,7 +502,7 @@ static void run_test (void) {
 }
 #endif
 
-void pa_volume_func_init_sse (void) {
+void pa_volume_func_init_sse (pa_cpu_x86_flag_t flags) {
   pa_log_info("Initialising SSE optimized functions.");
 
 #ifdef RUN_TEST

commit e396fe67fb3b0acec40c2334c426bcb284163d20
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 13 17:22:39 2009 +0200

    cpu-x86: guard header with ifdef

diff --git a/src/pulsecore/cpu-x86.h b/src/pulsecore/cpu-x86.h
index 8158ea7..07e630e 100644
--- a/src/pulsecore/cpu-x86.h
+++ b/src/pulsecore/cpu-x86.h
@@ -1,3 +1,6 @@
+#ifndef foocpux86hfoo
+#define foocpux86hfoo
+
 /***
   This file is part of PulseAudio.
 
@@ -59,3 +62,5 @@ typedef int64_t pa_reg_x86;
 /* some optimized functions */
 void pa_volume_func_init_mmx(pa_cpu_x86_flag_t flags);
 void pa_volume_func_init_sse(pa_cpu_x86_flag_t flags);
+
+#endif /* foocpux86hfoo */

commit dcae9a3113d1ce30e330c97dd5a81fec4e272bed
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Fri Aug 14 13:12:30 2009 +0200

    svolume: add some comments

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index e56f7c3..b36fe94 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -101,6 +101,22 @@ pa_volume_ulaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsig
 }
 #endif
 
+/* in s: 2 int16_t samples
+ * in v: 2 int32_t volumes, fixed point 16:16
+ * out s: contains scaled and clamped int16_t samples.
+ *
+ * We calculate the high 32 bits of a 32x16 multiply which we then
+ * clamp to 16 bits. The calulcation is:
+ *
+ *  vl = (v & 0xffff)
+ *  vh = (v >> 16)
+ *  s = ((s * vl) >> 16) + (s * vh);
+ *
+ * For the first multiply we have to do a sign correction as we need to
+ * multiply a signed int with an unsigned int. Hacker's delight 8-3 gives a
+ * simple formula to correct the sign of the high word after the signed
+ * multiply.
+ */
 #define VOLUME_32x16(s,v)                  /* .. |   vh  |   vl  | */                   \
       " pxor  %%mm4, %%mm4           \n\t" /* .. |    0  |    0  | */                   \
       " punpcklwd %%mm4, "#s"        \n\t" /* .. |    0  |   p0  | */                   \
@@ -116,6 +132,8 @@ pa_volume_ulaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsig
       " pmaddwd "#s", "#v"           \n\t" /* .. |    p0 * v0    | */                   \
       " packssdw "#v", "#v"          \n\t" /* .. | p1*v1 | p0*v0 | */
 
+/* approximately advances %3 = (%3 + a) % b. This function requires that
+ * a <= b. */
 #define MOD_ADD(a,b) \
       " add "#a", %3                 \n\t" \
       " mov %3, %4                   \n\t" \

commit a1235446a733164f00a96688784913172456a34e
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Fri Aug 14 15:19:26 2009 +0200

    volume: make the benchmark more meaningfull
    
    MMX is about 6x faster, SSE around 15x on my machine.

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index b36fe94..9ad7dea 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -24,8 +24,7 @@
 #include <config.h>
 #endif
 
-#include <alloca.h>
-
+#include <pulse/timeval.h>
 #include <pulsecore/random.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/g711.h>
@@ -478,31 +477,45 @@ static void run_test (void) {
   int32_t volumes[CHANNELS + PADDING];
   int i, j, padding;
   pa_do_volume_func_t func;
+  struct timeval start, stop;
 
-  func = pa_get_volume_func (PA_SAMPLE_S16RE);
-
-  printf ("checking MMX %d\n", sizeof (samples));
+  func = pa_get_volume_func (PA_SAMPLE_S16NE);
 
-  for (j = 0; j < TIMES; j++) {
-    pa_random (samples, sizeof (samples));
-    memcpy (samples_ref, samples, sizeof (samples));
-    memcpy (samples_orig, samples, sizeof (samples));
+  printf ("checking MMX %zd\n", sizeof (samples));
 
-    for (i = 0; i < CHANNELS; i++)
-      volumes[i] = rand() >> 1;
-    for (padding = 0; padding < PADDING; padding++, i++)
-      volumes[i] = volumes[padding];
+  pa_random (samples, sizeof (samples));
+  memcpy (samples_ref, samples, sizeof (samples));
+  memcpy (samples_orig, samples, sizeof (samples));
 
-    pa_volume_s16re_mmx (samples, volumes, CHANNELS, sizeof (samples));
-    func (samples_ref, volumes, CHANNELS, sizeof (samples));
+  for (i = 0; i < CHANNELS; i++)
+    volumes[i] = rand() >> 1;
+  for (padding = 0; padding < PADDING; padding++, i++)
+    volumes[i] = volumes[padding];
 
-    for (i = 0; i < SAMPLES; i++) {
-      if (samples[i] != samples_ref[i]) {
-        printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
-  		      samples_orig[i], volumes[i % CHANNELS]);
-      }
+  func (samples_ref, volumes, CHANNELS, sizeof (samples));
+  pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
+  for (i = 0; i < SAMPLES; i++) {
+    if (samples[i] != samples_ref[i]) {
+      printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+          samples_orig[i], volumes[i % CHANNELS]);
     }
   }
+
+  pa_gettimeofday(&start);
+  for (j = 0; j < TIMES; j++) {
+    memcpy (samples, samples_orig, sizeof (samples));
+    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
+  }
+  pa_gettimeofday(&stop);
+  pa_log_info("MMX: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+
+  pa_gettimeofday(&start);
+  for (j = 0; j < TIMES; j++) {
+    memcpy (samples_ref, samples_orig, sizeof (samples));
+    func (samples_ref, volumes, CHANNELS, sizeof (samples));
+  }
+  pa_gettimeofday(&stop);
+  pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
 }
 #endif
 
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index b60471a..8138c6c 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -24,8 +24,7 @@
 #include <config.h>
 #endif
 
-#include <alloca.h>
-
+#include <pulse/timeval.h>
 #include <pulsecore/random.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/g711.h>
@@ -459,7 +458,7 @@ pa_volume_s24_32re_sse (uint32_t *samples, int32_t *volumes, unsigned channels,
 }
 #endif
 
-#undef RUN_TEST
+#define RUN_TEST
 
 #ifdef RUN_TEST
 #define CHANNELS 2
@@ -474,31 +473,45 @@ static void run_test (void) {
   int32_t volumes[CHANNELS + PADDING];
   int i, j, padding;
   pa_do_volume_func_t func;
+  struct timeval start, stop;
 
-  func = pa_get_volume_func (PA_SAMPLE_S16RE);
+  func = pa_get_volume_func (PA_SAMPLE_S16NE);
 
-  printf ("checking SSE %d\n", sizeof (samples));
+  printf ("checking SSE %zd\n", sizeof (samples));
 
-  for (j = 0; j < TIMES; j++) {
-    pa_random (samples, sizeof (samples));
-    memcpy (samples_ref, samples, sizeof (samples));
-    memcpy (samples_orig, samples, sizeof (samples));
-
-    for (i = 0; i < CHANNELS; i++)
-      volumes[i] = rand() >> 1;
-    for (padding = 0; padding < PADDING; padding++, i++)
-      volumes[i] = volumes[padding];
-
-    pa_volume_s16re_sse (samples, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
-    func (samples_ref, volumes, CHANNELS, SAMPLES * sizeof (int16_t));
-
-    for (i = 0; i < SAMPLES; i++) {
-      if (samples[i] != samples_ref[i]) {
-        printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i], 
-  		      samples_orig[i], volumes[i % CHANNELS]);
-      }
+  pa_random (samples, sizeof (samples));
+  memcpy (samples_ref, samples, sizeof (samples));
+  memcpy (samples_orig, samples, sizeof (samples));
+
+  for (i = 0; i < CHANNELS; i++)
+    volumes[i] = rand() >> 1;
+  for (padding = 0; padding < PADDING; padding++, i++)
+    volumes[i] = volumes[padding];
+
+  func (samples_ref, volumes, CHANNELS, sizeof (samples));
+  pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
+  for (i = 0; i < SAMPLES; i++) {
+    if (samples[i] != samples_ref[i]) {
+      printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+              samples_orig[i], volumes[i % CHANNELS]);
     }
   }
+
+  pa_gettimeofday(&start);
+  for (j = 0; j < TIMES; j++) {
+    memcpy (samples, samples_orig, sizeof (samples));
+    pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
+  }
+  pa_gettimeofday(&stop);
+  pa_log_info("SSE: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+
+  pa_gettimeofday(&start);
+  for (j = 0; j < TIMES; j++) {
+    memcpy (samples_ref, samples_orig, sizeof (samples));
+    func (samples_ref, volumes, CHANNELS, sizeof (samples));
+  }
+  pa_gettimeofday(&stop);
+  pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
 }
 #endif
 

commit f24c24c14b6614cf19ee916886c8b02384bac435
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Fri Aug 14 15:41:32 2009 +0200

    volume: improved comments

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 9ad7dea..d4fcedf 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -196,7 +196,7 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
     " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */ 
     VOLUME_32x16 (%%mm1, %%mm0)
-    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
+    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
     " add $4, %0                    \n\t"
     MOD_ADD ($2, %5)
 
@@ -212,8 +212,8 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
     VOLUME_32x16 (%%mm1, %%mm0)
     VOLUME_32x16 (%%mm3, %%mm2)
-    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
-    " movd %%mm2, 4(%0)             \n\t" /* | p3*v3 | p2*v2 | */
+    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
+    " movd %%mm2, 4(%0)             \n\t" /*              .. | p3*v3 | p2*v2 | */
     " add $8, %0                    \n\t"
     MOD_ADD ($4, %5)
     " dec %2                        \n\t"
@@ -270,7 +270,7 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     SWAP_16 (%%mm1)
     VOLUME_32x16 (%%mm1, %%mm0)
     SWAP_16 (%%mm0)
-    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
+    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
     " add $4, %0                    \n\t"
     MOD_ADD ($2, %5)
 
@@ -288,8 +288,8 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     VOLUME_32x16 (%%mm1, %%mm0)
     VOLUME_32x16 (%%mm3, %%mm2)
     SWAP_16_2 (%%mm0, %%mm2)
-    " movd %%mm0, (%0)              \n\t" /* | p1*v1 | p0*v0 | */
-    " movd %%mm2, 4(%0)             \n\t" /* | p3*v3 | p2*v2 | */
+    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
+    " movd %%mm2, 4(%0)             \n\t" /*              .. | p3*v3 | p2*v2 | */
     " add $8, %0                    \n\t"
     MOD_ADD ($4, %5)
     " dec %2                        \n\t"
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 8138c6c..d95fa9d 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -231,12 +231,12 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " test $1, %2                   \n\t" /* check for odd samples */
     " je 2f                         \n\t" 
 
-    " movd (%1, %3, 4), %%xmm0      \n\t" /* do odd sample */
-    " movw (%0), %4                 \n\t" 
+    " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
+    " movw (%0), %4                 \n\t" /*     ..  |   p0  | */
     " rorw $8, %4                   \n\t" 
     " movd %4, %%xmm1               \n\t" 
     VOLUME_32x16 (%%xmm1, %%xmm0)
-    " movd %%xmm0, %4               \n\t" 
+    " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
     " rorw $8, %4                   \n\t" 
     " movw %4, (%0)                 \n\t" 
     " add $2, %0                    \n\t"
@@ -244,31 +244,34 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 
     "2:                             \n\t"
     " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
-    " test $1, %2                   \n\t" /* check for odd samples */
+    " test $1, %2                   \n\t"
     " je 4f                         \n\t" 
 
-    "3:                             \n\t" /* do samples in pairs of 2 */
-    " movq (%1, %3, 4), %%xmm0      \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
-    " movd (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    "3:                             \n\t" /* do samples in groups of 2 */
+    " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+    " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
     SWAP_16 (%%xmm1)
     VOLUME_32x16 (%%xmm1, %%xmm0)
     SWAP_16 (%%xmm0)
-    " movd %%xmm0, (%0)             \n\t" 
+    " movd %%xmm0, (%0)             \n\t" /*              .. | p1*v1 | p0*v0 | */
     " add $4, %0                    \n\t"
     MOD_ADD ($2, %5)
 
     "4:                             \n\t"
     " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
-    " test $1, %2                   \n\t" /* check for odd samples */
+    " test $1, %2                   \n\t"
     " je 6f                         \n\t" 
 
-    "5:                             \n\t" /* do samples in pairs of 4 */
-    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
-    " movq (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */ 
+    /* FIXME, we can do aligned access of the volume values if we can guarantee
+     * that the array is 16 bytes aligned, we probably have to do the odd values
+     * after this then. */
+    "5:                             \n\t" /* do samples in groups of 4 */
+    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
     SWAP_16 (%%xmm1)
     VOLUME_32x16 (%%xmm1, %%xmm0)
     SWAP_16 (%%xmm0)
-    " movq %%xmm0, (%0)             \n\t" 
+    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
     " add $8, %0                    \n\t"
     MOD_ADD ($4, %5)
 
@@ -277,17 +280,17 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " cmp $0, %2                    \n\t"
     " je 8f                         \n\t"
 
-    "7:                             \n\t" /* do samples in pairs of 8 */
-    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* v1_h  | v1_l  | v0_h  | v0_l      */
-    " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* v3_h  | v3_l  | v2_h  | v2_l      */
-    " movq (%0), %%xmm1             \n\t" /*  X    |  X    |  p1   |  p0       */
-    " movq 8(%0), %%xmm3            \n\t" /*  X    |  X    |  p3   |  p2       */
+    "7:                             \n\t" /* do samples in groups of 8 */
+    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+    " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
+    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
+    " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
     SWAP_16_2 (%%xmm1, %%xmm3)
     VOLUME_32x16 (%%xmm1, %%xmm0)
     VOLUME_32x16 (%%xmm3, %%xmm2)
     SWAP_16_2 (%%xmm0, %%xmm2)
-    " movq %%xmm0, (%0)             \n\t" 
-    " movq %%xmm2, 8(%0)            \n\t" 
+    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
+    " movq %%xmm2, 8(%0)            \n\t" /*              .. | p7*v7 .. p4*v4 | */
     " add $16, %0                   \n\t"
     MOD_ADD ($8, %5)
     " dec %2                        \n\t"
@@ -458,7 +461,7 @@ pa_volume_s24_32re_sse (uint32_t *samples, int32_t *volumes, unsigned channels,
 }
 #endif
 
-#define RUN_TEST
+#undef RUN_TEST
 
 #ifdef RUN_TEST
 #define CHANNELS 2

commit 591baacba5913de32e6556a71a8300d25addbec4
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Fri Aug 14 15:48:10 2009 +0200

    volume: remove ref functions

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index d4fcedf..ad53927 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -35,71 +35,6 @@
 #include "sample-util.h"
 #include "endianmacros.h"
 
-#if 0
-static void
-pa_volume_u8_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) *samples - 0x80;
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
-    *samples++ = (uint8_t) (t + 0x80);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_alaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) st_alaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_ulaw_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) st_ulaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-#endif
-
 /* in s: 2 int16_t samples
  * in v: 2 int32_t volumes, fixed point 16:16
  * out s: contains scaled and clamped int16_t samples.
@@ -304,164 +239,6 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
   );
 }
 
-#if 0
-static void
-pa_volume_float32ne_mmx (float *samples, float *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (float);
-
-  for (channel = 0; length; length--) {
-    *samples++ *= volumes[channel];
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_float32re_mmx (float *samples, float *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (float);
-
-  for (channel = 0; length; length--) {
-    float t;
-
-    t = PA_FLOAT32_SWAP(*samples);
-    t *= volumes[channel];
-    *samples++ = PA_FLOAT32_SWAP(t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s32ne_mmx (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t)(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = (int32_t) t;
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s32re_mmx (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) PA_INT32_SWAP(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_INT32_SWAP((int32_t) t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24ne_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-  uint8_t *e;
-
-  e = samples + length;
-
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
-
-    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24re_mmx (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-  uint8_t *e;
-
-  e = samples + length;
-
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
-
-    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24_32ne_mmx (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (uint32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) ((int32_t) (*samples << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24_32re_mmx (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (uint32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-#endif
-
 #undef RUN_TEST
 
 #ifdef RUN_TEST
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index d95fa9d..b0a6e0d 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -35,71 +35,6 @@
 #include "sample-util.h"
 #include "endianmacros.h"
 
-#if 0
-static void
-pa_volume_u8_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) *samples - 0x80;
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
-    *samples++ = (uint8_t) (t + 0x80);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_alaw_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) st_alaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_ulaw_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
-
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
-
-    t = (int32_t) st_ulaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-#endif
-
 #define VOLUME_32x16(s,v)                  /* .. |   vh  |   vl  | */                   \
       " pxor %%xmm4, %%xmm4          \n\t" /* .. |    0  |    0  | */                   \
       " punpcklwd %%xmm4, "#s"       \n\t" /* .. |    0  |   p0  | */                   \
@@ -303,164 +238,6 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
   );
 }
 
-#if 0
-static void
-pa_volume_float32ne_sse (float *samples, float *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (float);
-
-  for (channel = 0; length; length--) {
-    *samples++ *= volumes[channel];
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_float32re_sse (float *samples, float *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (float);
-
-  for (channel = 0; length; length--) {
-    float t;
-
-    t = PA_FLOAT32_SWAP(*samples);
-    t *= volumes[channel];
-    *samples++ = PA_FLOAT32_SWAP(t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s32ne_sse (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t)(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = (int32_t) t;
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s32re_sse (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (int32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) PA_INT32_SWAP(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_INT32_SWAP((int32_t) t);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24ne_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-  uint8_t *e;
-
-  e = samples + length;
-
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
-
-    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24re_sse (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-  uint8_t *e;
-
-  e = samples + length;
-
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
-
-    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24_32ne_sse (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (uint32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) ((int32_t) (*samples << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-
-static void
-pa_volume_s24_32re_sse (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-  unsigned channel;
-
-  length /= sizeof (uint32_t);
-
-  for (channel = 0; length; length--) {
-    int64_t t;
-
-    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
-
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
-}
-#endif
-
 #undef RUN_TEST
 
 #ifdef RUN_TEST

commit 25724cdd40283a00e6edd9449d0f3cf16823b41b
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Fri Aug 14 19:45:39 2009 +0200

    Get rid of liboil
    
    Get rid of the liboil dependency and reimplement the liboil functions with an
    equivalent C implementation. Note that most of these functions are deprecated in
    liboil and that none of them had  any optimisations. We can further specialize
    our handrolled versions for some extra speedups.

diff --git a/configure.ac b/configure.ac
index 05312d3..40455e1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -941,12 +941,6 @@ AC_SUBST(AVAHI_LIBS)
 AC_SUBST(HAVE_AVAHI)
 AM_CONDITIONAL([HAVE_AVAHI], [test "x$HAVE_AVAHI" = x1])
 
-### LIBOIL ####
-
-PKG_CHECK_MODULES(LIBOIL, [ liboil-0.3 >= 0.3.0 ])
-AC_SUBST(LIBOIL_CFLAGS)
-AC_SUBST(LIBOIL_LIBS)
-
 ### JACK (optional) ####
 
 AC_ARG_ENABLE([jack],
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 774b4e9..31e434d 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -39,8 +39,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include <liboil/liboil.h>
-
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 #endif
@@ -863,8 +861,6 @@ int main(int argc, char *argv[]) {
     win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
 #endif
 
-    oil_init();
-
     if (!conf->no_cpu_limit)
         pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
 
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 59e0a0c..a3c17f8 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -31,9 +31,6 @@
 
 #include <speex/speex_resampler.h>
 
-#include <liboil/liboilfuncs.h>
-#include <liboil/liboil.h>
-
 #include <pulse/xmalloc.h>
 #include <pulsecore/sconv.h>
 #include <pulsecore/log.h>
@@ -1045,33 +1042,46 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)
     return &r->buf1;
 }
 
-static void vectoradd_s16_with_fraction(
-        int16_t *d, int dstr,
-        const int16_t *s1, int sstr1,
-        const int16_t *s2, int sstr2,
-        int n,
-        float s3, float s4) {
+static void vectoradd_f32(
+        float *d, int dstr,
+        const float *s, int sstr,
+        int n, float s4) {
 
-    int32_t i3, i4;
+    for (; n > 0; n--) {
+        *d = (float) (*d + (s4 * *s));
 
-    i3 = (int32_t) (s3 * 0x10000);
-    i4 = (int32_t) (s4 * 0x10000);
+        s = (const float*) ((const uint8_t*) s + sstr);
+        d = (float*) ((uint8_t*) d + dstr);
+    }
+}
+
+static void vectoradd_s16(
+        int16_t *d, int dstr,
+        const int16_t *s, int sstr,
+        int n) {
 
     for (; n > 0; n--) {
-        int32_t a, b;
+        *d = (int16_t) (*d + *s);
 
-        a = *s1;
-        b = *s2;
+        s = (const int16_t*) ((const uint8_t*) s + sstr);
+        d = (int16_t*) ((uint8_t*) d + dstr);
+    }
+}
 
-        a = (a * i3) / 0x10000;
-        b = (b * i4) / 0x10000;
+static void vectoradd_s16_with_fraction(
+        int16_t *d, int dstr,
+        const int16_t *s, int sstr,
+        int n, float s4) {
 
-        *d = (int16_t) (a + b);
+    int32_t i4;
 
-        s1 = (const int16_t*) ((const uint8_t*) s1 + sstr1);
-        s2 = (const int16_t*) ((const uint8_t*) s2 + sstr2);
-        d = (int16_t*) ((uint8_t*) d + dstr);
+    i4 = (int32_t) (s4 * 0x10000);
+
+    for (; n > 0; n--) {
+        *d = (int16_t) (*d + (((int32_t)*s * i4) >> 16));
 
+        s = (const int16_t*) ((const uint8_t*) s + sstr);
+        d = (int16_t*) ((uint8_t*) d + dstr);
     }
 }
 
@@ -1125,12 +1135,11 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
                     if (r->map_table[oc][ic] <= 0.0)
                         continue;
 
-                    oil_vectoradd_f32(
-                            (float*) dst + oc, o_skip,
+                    vectoradd_f32(
                             (float*) dst + oc, o_skip,
                             (float*) src + ic, i_skip,
                             (int) n_frames,
-                            &one, &r->map_table[oc][ic]);
+                            r->map_table[oc][ic]);
                 }
             }
 
@@ -1147,23 +1156,19 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
                         continue;
 
                     if (r->map_table[oc][ic] >= 1.0) {
-                        static const int16_t one = 1;
 
-                        oil_vectoradd_s16(
-                                (int16_t*) dst + oc, o_skip,
+                        vectoradd_s16(
                                 (int16_t*) dst + oc, o_skip,
                                 (int16_t*) src + ic, i_skip,
-                                (int) n_frames,
-                                &one, &one);
+                                (int) n_frames);
 
                     } else
 
                         vectoradd_s16_with_fraction(
                                 (int16_t*) dst + oc, o_skip,
-                                (int16_t*) dst + oc, o_skip,
                                 (int16_t*) src + ic, i_skip,
                                 (int) n_frames,
-                                1.0f, r->map_table[oc][ic]);
+                                r->map_table[oc][ic]);
                 }
             }
 
@@ -1469,7 +1474,7 @@ static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned
 
         pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
 
-        oil_memcpy((uint8_t*) dst + fz * o_index,
+        memcpy((uint8_t*) dst + fz * o_index,
                    (uint8_t*) src + fz * j, (int) fz);
     }
 
diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c
index 43b8cb3..0fefdf1 100644
--- a/src/pulsecore/sconv-s16le.c
+++ b/src/pulsecore/sconv-s16le.c
@@ -28,8 +28,6 @@
 #include <inttypes.h>
 #include <stdio.h>
 
-#include <liboil/liboilfuncs.h>
-
 #include <pulsecore/sconv.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/log.h>
@@ -86,17 +84,13 @@ void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {
     pa_assert(b);
 
 #if SWAP_WORDS == 1
-
     for (; n > 0; n--) {
         int16_t s = *(a++);
         *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF;
     }
-
 #else
-{
-    static const double add = 0, factor = 1.0/0x7FFF;
-    oil_scaleconv_f32_s16(b, a, (int) n, &add, &factor);
-}
+    for (; n > 0; n--)
+        *(b++) = ((float) (*(a++)))/(float) 0x7FFF;
 #endif
 }
 
@@ -105,17 +99,13 @@ void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {
     pa_assert(b);
 
 #if SWAP_WORDS == 1
-
     for (; n > 0; n--) {
         int32_t s = *(a++);
         *(b++) = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
     }
-
 #else
-{
-    static const double add = 0, factor = 1.0/0x7FFFFFFF;
-    oil_scaleconv_f32_s32(b, a, (int) n, &add, &factor);
-}
+    for (; n > 0; n--)
+        *(b++) = (float) (((double) (*(a++)))/0x7FFFFFFF);
 #endif
 }
 
@@ -124,7 +114,6 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
     pa_assert(b);
 
 #if SWAP_WORDS == 1
-
     for (; n > 0; n--) {
         int16_t s;
         float v = *(a++);
@@ -133,12 +122,13 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
         s = (int16_t) lrintf(v * 0x7FFF);
         *(b++) = INT16_TO(s);
     }
-
 #else
-{
-    static const double add = 0, factor = 0x7FFF;
-    oil_scaleconv_s16_f32(b, a, (int) n, &add, &factor);
-}
+    for (; n > 0; n--) {
+        float v = *(a++);
+
+        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
+        *(b++) = (int16_t) lrintf(v * 0x7FFF);
+    }
 #endif
 }
 
@@ -147,7 +137,6 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
     pa_assert(b);
 
 #if SWAP_WORDS == 1
-
     for (; n > 0; n--) {
         int32_t s;
         float v = *(a++);
@@ -156,12 +145,13 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
         *(b++) = INT32_TO(s);
     }
-
 #else
-{
-    static const double add = 0, factor = 0x7FFFFFFF;
-    oil_scaleconv_s32_f32(b, a, (int) n, &add, &factor);
-}
+    for (; n > 0; n--) {
+        float v = *(a++);
+
+        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
+        *(b++) = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
+    }
 #endif
 }
 
diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c
index d89f428..937bf5d 100644
--- a/src/pulsecore/sconv.c
+++ b/src/pulsecore/sconv.c
@@ -27,9 +27,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <liboil/liboilfuncs.h>
-#include <liboil/liboil.h>
-
 #include <pulsecore/g711.h>
 #include <pulsecore/macro.h>
 
@@ -41,32 +38,31 @@
 
 /* u8 */
 static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) {
-    static const double add = -1, factor = 1.0/128.0;
-
     pa_assert(a);
     pa_assert(b);
 
-    oil_scaleconv_f32_u8(b, a, (int) n, &add, &factor);
+    for (; n > 0; n--, a++, b++)
+        *b = (*a * 1.0/128.0) - 1.0;
 }
 
 static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) {
-    static const double add = 128, factor = 127.0;
-
     pa_assert(a);
     pa_assert(b);
 
-    oil_scaleconv_u8_f32(b, a, (int) n, &add, &factor);
+    for (; n > 0; n--, a++, b++) {
+        float v;
+        v = (*a * 127.0) + 128.0;
+	v = PA_CLAMP_UNLIKELY (v, 0.0, 255.0);
+	*b = rint (v);
+    }
 }
 
 static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {
-    static const int16_t add = -0x80, factor = 0x100;
-
     pa_assert(a);
     pa_assert(b);
 
-    oil_conv_s16_u8(b, 2, a, 1, (int) n);
-    oil_scalaradd_s16(b, 2, b, 2, &add, (int) n);
-    oil_scalarmult_s16(b, 2, b, 2, &factor, (int) n);
+    for (; n > 0; n--, a++, b++)
+        *b = (((int16_t)*a) - 128) << 8;
 }
 
 static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
@@ -84,7 +80,7 @@ static void float32ne_to_float32ne(unsigned n, const float *a, float *b) {
     pa_assert(a);
     pa_assert(b);
 
-    oil_memcpy(b, a, (int) (sizeof(float) * n));
+    memcpy(b, a, (int) (sizeof(float) * n));
 }
 
 static void float32re_to_float32ne(unsigned n, const float *a, float *b) {
@@ -101,7 +97,7 @@ static void s16ne_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {
     pa_assert(a);
     pa_assert(b);
 
-    oil_memcpy(b, a, (int) (sizeof(int16_t) * n));
+    memcpy(b, a, (int) (sizeof(int16_t) * n));
 }
 
 static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {
diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c
index 3af3044..9382040 100644
--- a/src/tests/envelope-test.c
+++ b/src/tests/envelope-test.c
@@ -34,8 +34,6 @@
 #include <pulsecore/memblock.h>
 #include <pulsecore/sample-util.h>
 
-#include <liboil/liboil.h>
-
 const pa_envelope_def ramp_down = {
     .n_points = 2,
     .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },
@@ -202,7 +200,6 @@ int main(int argc, char *argv[]) {
         .values = { PA_VOLUME_NORM, PA_VOLUME_NORM/2 }
     };
 
-    oil_init();
     pa_log_set_level(PA_LOG_DEBUG);
 
     pa_assert_se(pool = pa_mempool_new(FALSE, 0));
diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c
index f9f76da..457c4ac 100644
--- a/src/tests/mix-test.c
+++ b/src/tests/mix-test.c
@@ -32,8 +32,6 @@
 #include <pulsecore/memblock.h>
 #include <pulsecore/sample-util.h>
 
-#include <liboil/liboil.h>
-
 static float swap_float(float a) {
     uint32_t *b = (uint32_t*) &a;
     *b = PA_UINT32_SWAP(*b);
@@ -211,7 +209,6 @@ int main(int argc, char *argv[]) {
     pa_sample_spec a;
     pa_cvolume v;
 
-    oil_init();
     pa_log_set_level(PA_LOG_DEBUG);
 
     pa_assert_se(pool = pa_mempool_new(FALSE, 0));
diff --git a/src/tests/remix-test.c b/src/tests/remix-test.c
index 9d110d6..4990bf9 100644
--- a/src/tests/remix-test.c
+++ b/src/tests/remix-test.c
@@ -32,8 +32,6 @@
 #include <pulsecore/memblock.h>
 #include <pulsecore/sample-util.h>
 
-#include <liboil/liboil.h>
-
 int main(int argc, char *argv[]) {
 
     static const pa_channel_map maps[] = {
@@ -55,7 +53,6 @@ int main(int argc, char *argv[]) {
     unsigned i, j;
     pa_mempool *pool;
 
-    oil_init();
     pa_log_set_level(PA_LOG_DEBUG);
 
     pa_assert_se(pool = pa_mempool_new(FALSE, 0));
diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c
index 7236265..82198b5 100644
--- a/src/tests/resampler-test.c
+++ b/src/tests/resampler-test.c
@@ -32,8 +32,6 @@
 #include <pulsecore/memblock.h>
 #include <pulsecore/sample-util.h>
 
-#include <liboil/liboil.h>
-
 static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
     void *d;
     unsigned i;
@@ -248,7 +246,6 @@ int main(int argc, char *argv[]) {
     pa_sample_spec a, b;
     pa_cvolume v;
 
-    oil_init();
     pa_log_set_level(PA_LOG_DEBUG);
 
     pa_assert_se(pool = pa_mempool_new(FALSE, 0));

commit 601e5f1867065912e1740e2408a948ca818f6c59
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Mon Aug 17 11:35:47 2009 +0200

    resampler: cache integer channel_map
    
    Calculate and cache an integer version of the channel map so that we don't have
    to regenerate it when dealing with s16 samples.

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index a3c17f8..e3473ac 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -61,7 +61,8 @@ struct pa_resampler {
     pa_convert_func_t to_work_format_func;
     pa_convert_func_t from_work_format_func;
 
-    float map_table[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
+    float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
+    int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
     pa_bool_t map_required;
 
     void (*impl_free)(pa_resampler *r);
@@ -587,7 +588,8 @@ static void calc_map_table(pa_resampler *r) {
     if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || (!(r->flags & PA_RESAMPLER_NO_REMAP) && !pa_channel_map_equal(&r->i_cm, &r->o_cm)))))
         return;
 
-    memset(r->map_table, 0, sizeof(r->map_table));
+    memset(r->map_table_f, 0, sizeof(r->map_table_f));
+    memset(r->map_table_i, 0, sizeof(r->map_table_i));
     memset(ic_connected, 0, sizeof(ic_connected));
     remix = (r->flags & (PA_RESAMPLER_NO_REMAP|PA_RESAMPLER_NO_REMIX)) == 0;
 
@@ -602,7 +604,7 @@ static void calc_map_table(pa_resampler *r) {
                 /* We shall not do any remapping. Hence, just check by index */
 
                 if (ic == oc)
-                    r->map_table[oc][ic] = 1.0;
+                    r->map_table_f[oc][ic] = 1.0;
 
                 continue;
             }
@@ -611,7 +613,7 @@ static void calc_map_table(pa_resampler *r) {
                 /* We shall not do any remixing. Hence, just check by name */
 
                 if (a == b)
-                    r->map_table[oc][ic] = 1.0;
+                    r->map_table_f[oc][ic] = 1.0;
 
                 continue;
             }
@@ -686,7 +688,7 @@ static void calc_map_table(pa_resampler *r) {
              */
 
             if (a == b || a == PA_CHANNEL_POSITION_MONO || b == PA_CHANNEL_POSITION_MONO) {
-                r->map_table[oc][ic] = 1.0;
+                r->map_table_f[oc][ic] = 1.0;
 
                 oc_connected = TRUE;
                 ic_connected[ic] = TRUE;
@@ -711,7 +713,7 @@ static void calc_map_table(pa_resampler *r) {
                 if (n > 0)
                     for (ic = 0; ic < r->i_ss.channels; ic++)
                         if (on_left(r->i_cm.map[ic])) {
-                            r->map_table[oc][ic] = 1.0f / (float) n;
+                            r->map_table_f[oc][ic] = 1.0f / (float) n;
                             ic_connected[ic] = TRUE;
                         }
 
@@ -732,7 +734,7 @@ static void calc_map_table(pa_resampler *r) {
                 if (n > 0)
                     for (ic = 0; ic < r->i_ss.channels; ic++)
                         if (on_right(r->i_cm.map[ic])) {
-                            r->map_table[oc][ic] = 1.0f / (float) n;
+                            r->map_table_f[oc][ic] = 1.0f / (float) n;
                             ic_connected[ic] = TRUE;
                         }
 
@@ -753,7 +755,7 @@ static void calc_map_table(pa_resampler *r) {
                 if (n > 0) {
                     for (ic = 0; ic < r->i_ss.channels; ic++)
                         if (on_center(r->i_cm.map[ic])) {
-                            r->map_table[oc][ic] = 1.0f / (float) n;
+                            r->map_table_f[oc][ic] = 1.0f / (float) n;
                             ic_connected[ic] = TRUE;
                         }
                 } else {
@@ -770,7 +772,7 @@ static void calc_map_table(pa_resampler *r) {
                     if (n > 0)
                         for (ic = 0; ic < r->i_ss.channels; ic++)
                             if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
-                                r->map_table[oc][ic] = 1.0f / (float) n;
+                                r->map_table_f[oc][ic] = 1.0f / (float) n;
                                 ic_connected[ic] = TRUE;
                             }
 
@@ -787,9 +789,9 @@ static void calc_map_table(pa_resampler *r) {
                 for (ic = 0; ic < r->i_ss.channels; ic++) {
 
                     if (!(r->flags & PA_RESAMPLER_NO_LFE))
-                        r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
+                        r->map_table_f[oc][ic] = 1.0f / (float) r->i_ss.channels;
                     else
-                        r->map_table[oc][ic] = 0;
+                        r->map_table_f[oc][ic] = 0;
 
                     /* Please note that a channel connected to LFE
                      * doesn't really count as connected. */
@@ -836,12 +838,12 @@ static void calc_map_table(pa_resampler *r) {
                 for (ic = 0; ic < r->i_ss.channels; ic++) {
 
                     if (ic_connected[ic]) {
-                        r->map_table[oc][ic] *= .9f;
+                        r->map_table_f[oc][ic] *= .9f;
                         continue;
                     }
 
                     if (on_left(r->i_cm.map[ic]))
-                        r->map_table[oc][ic] = .1f / (float) ic_unconnected_left;
+                        r->map_table_f[oc][ic] = .1f / (float) ic_unconnected_left;
                 }
             }
         }
@@ -861,12 +863,12 @@ static void calc_map_table(pa_resampler *r) {
                 for (ic = 0; ic < r->i_ss.channels; ic++) {
 
                     if (ic_connected[ic]) {
-                        r->map_table[oc][ic] *= .9f;
+                        r->map_table_f[oc][ic] *= .9f;
                         continue;
                     }
 
                     if (on_right(r->i_cm.map[ic]))
-                        r->map_table[oc][ic] = .1f / (float) ic_unconnected_right;
+                        r->map_table_f[oc][ic] = .1f / (float) ic_unconnected_right;
                 }
             }
         }
@@ -887,12 +889,12 @@ static void calc_map_table(pa_resampler *r) {
                 for (ic = 0; ic < r->i_ss.channels; ic++)  {
 
                     if (ic_connected[ic]) {
-                        r->map_table[oc][ic] *= .9f;
+                        r->map_table_f[oc][ic] *= .9f;
                         continue;
                     }
 
                     if (on_center(r->i_cm.map[ic])) {
-                        r->map_table[oc][ic] = .1f / (float) ic_unconnected_center;
+                        r->map_table_f[oc][ic] = .1f / (float) ic_unconnected_center;
                         mixed_in = TRUE;
                     }
                 }
@@ -950,7 +952,7 @@ static void calc_map_table(pa_resampler *r) {
                     for (ic = 0; ic < r->i_ss.channels; ic++)  {
 
                         if (ic_connected[ic]) {
-                            r->map_table[oc][ic] *= .75f;
+                            r->map_table_f[oc][ic] *= .75f;
                             continue;
                         }
 
@@ -958,7 +960,7 @@ static void calc_map_table(pa_resampler *r) {
                             continue;
 
                         if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
-                            r->map_table[oc][ic] = .375f / (float) ncenter[oc];
+                            r->map_table_f[oc][ic] = .375f / (float) ncenter[oc];
                     }
                 }
             }
@@ -975,11 +977,14 @@ static void calc_map_table(pa_resampler *r) {
                     continue;
 
                 for (oc = 0; oc < r->o_ss.channels; oc++)
-                    r->map_table[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
+                    r->map_table_f[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
             }
         }
     }
-
+    /* make an 16:16 int version of the matrix */
+    for (oc = 0; oc < r->o_ss.channels; oc++)
+        for (ic = 0; ic < r->i_ss.channels; ic++)
+            r->map_table_i[oc][ic] = (int32_t) (r->map_table_f[oc][ic] * 0x10000);
 
     s = pa_strbuf_new();
 
@@ -996,7 +1001,7 @@ static void calc_map_table(pa_resampler *r) {
         pa_strbuf_printf(s, "O%02u |", oc);
 
         for (ic = 0; ic < r->i_ss.channels; ic++)
-            pa_strbuf_printf(s, " %1.3f", r->map_table[oc][ic]);
+            pa_strbuf_printf(s, " %1.3f", r->map_table_f[oc][ic]);
 
         pa_strbuf_puts(s, "\n");
     }
@@ -1071,11 +1076,7 @@ static void vectoradd_s16(
 static void vectoradd_s16_with_fraction(
         int16_t *d, int dstr,
         const int16_t *s, int sstr,
-        int n, float s4) {
-
-    int32_t i4;
-
-    i4 = (int32_t) (s4 * 0x10000);
+        int n, int32_t i4) {
 
     for (; n > 0; n--) {
         *d = (int16_t) (*d + (((int32_t)*s * i4) >> 16));
@@ -1128,18 +1129,17 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
 
             for (oc = 0; oc < r->o_ss.channels; oc++) {
                 unsigned ic;
-                static const float one = 1.0;
 
                 for (ic = 0; ic < r->i_ss.channels; ic++) {
 
-                    if (r->map_table[oc][ic] <= 0.0)
+                    if (r->map_table_f[oc][ic] <= 0.0)
                         continue;
 
                     vectoradd_f32(
                             (float*) dst + oc, o_skip,
                             (float*) src + ic, i_skip,
                             (int) n_frames,
-                            r->map_table[oc][ic]);
+                            r->map_table_f[oc][ic]);
                 }
             }
 
@@ -1152,10 +1152,10 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
 
                 for (ic = 0; ic < r->i_ss.channels; ic++) {
 
-                    if (r->map_table[oc][ic] <= 0.0)
+                    if (r->map_table_f[oc][ic] <= 0.0)
                         continue;
 
-                    if (r->map_table[oc][ic] >= 1.0) {
+                    if (r->map_table_f[oc][ic] >= 1.0) {
 
                         vectoradd_s16(
                                 (int16_t*) dst + oc, o_skip,
@@ -1168,7 +1168,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
                                 (int16_t*) dst + oc, o_skip,
                                 (int16_t*) src + ic, i_skip,
                                 (int) n_frames,
-                                r->map_table[oc][ic]);
+                                r->map_table_i[oc][ic]);
                 }
             }
 

commit a98fa950d2f04e2ba4d4a470296a081e1050f76d
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 15:56:44 2009 +0200

    svolume: remove unneeded compare
    
    We don't need the compare because the sub operation already set the right flags
    for us.

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index ad53927..5243b44 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -72,7 +72,6 @@
       " add "#a", %3                 \n\t" \
       " mov %3, %4                   \n\t" \
       " sub "#b", %4                 \n\t" \
-      " cmp "#b", %3                 \n\t" \
       " cmovae %4, %3                \n\t" 
 
 /* swap 16 bits */
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index b0a6e0d..98f828c 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -52,8 +52,7 @@
       " add "#a", %3                 \n\t" /* channel += inc           */ \
       " mov %3, %4                   \n\t"                                \
       " sub "#b", %4                 \n\t" /* tmp = channel - channels */ \
-      " cmp "#b", %3                 \n\t" /* if (channel >= channels) */ \
-      " cmovae %4, %3                \n\t" /*   channel = tmp          */
+      " cmovae %4, %3                \n\t" /* if (tmp >= 0) channel = tmp  */
 
 /* swap 16 bits */
 #define SWAP_16(s) \

commit 951bf1b28d25a93b99cbe074a46b8313a9e5f9f0
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 16:09:14 2009 +0200

    svolume: add ARM optimized volume scaling

diff --git a/src/Makefile.am b/src/Makefile.am
index 4e90d79..eca68b1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -825,8 +825,8 @@ libpulsecore_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/resampler.c pulsecore/resampler.h \
 		pulsecore/rtpoll.c pulsecore/rtpoll.h \
 		pulsecore/sample-util.c pulsecore/sample-util.h \
-		pulsecore/cpu-x86.c \
-		pulsecore/svolume_c.c \
+		pulsecore/cpu-arm.c pulsecore/cpu-x86.c \
+		pulsecore/svolume_c.c pulsecore/svolume_arm.c\
 		pulsecore/svolume_mmx.c pulsecore/svolume_sse.c \
 		pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
 		pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 31e434d..ec8ff40 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -93,6 +93,7 @@
 #ifdef HAVE_DBUS
 #include <pulsecore/dbus-shared.h>
 #endif
+#include <pulsecore/cpu-arm.h>
 #include <pulsecore/cpu-x86.h>
 
 #include "cmdline.h"
@@ -821,6 +822,7 @@ int main(int argc, char *argv[]) {
     pa_memtrap_install();
 
     pa_cpu_init_x86();
+    pa_cpu_init_arm();
 
     pa_assert_se(mainloop = pa_mainloop_new());
 
diff --git a/src/pulsecore/cpu-arm.c b/src/pulsecore/cpu-arm.c
new file mode 100644
index 0000000..75646fe
--- /dev/null
+++ b/src/pulsecore/cpu-arm.c
@@ -0,0 +1,43 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk> 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+
+#include <pulsecore/log.h>
+
+#include "cpu-arm.h"
+
+static pa_cpu_arm_flag_t pa_cpu_arm_flags;
+
+void pa_cpu_init_arm (void) {
+#if defined (__arm__)
+    pa_cpu_arm_flags = 0;
+   
+    pa_log ("ARM init\n");
+
+    pa_volume_func_init_arm (pa_cpu_arm_flags);
+#endif /* defined (__arm__) */
+}
diff --git a/src/pulsecore/cpu-arm.h b/src/pulsecore/cpu-arm.h
new file mode 100644
index 0000000..1a0ac27
--- /dev/null
+++ b/src/pulsecore/cpu-arm.h
@@ -0,0 +1,39 @@
+#ifndef foocpuarmhfoo
+#define foocpuarmhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk> 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <stdint.h>
+
+typedef enum pa_cpu_arm_flag {
+    PA_CPU_ARM_V6       = (1 << 0),
+    PA_CPU_ARM_NEON     = (1 << 1),
+    PA_CPU_ARM_VFP      = (1 << 2)
+} pa_cpu_arm_flag_t;
+
+void pa_cpu_init_arm (void);
+
+/* some optimized functions */
+void pa_volume_func_init_arm(pa_cpu_arm_flag_t flags);
+
+#endif /* foocpuarmhfoo */
diff --git a/src/pulsecore/svolume_arm.c b/src/pulsecore/svolume_arm.c
new file mode 100644
index 0000000..7e25a13
--- /dev/null
+++ b/src/pulsecore/svolume_arm.c
@@ -0,0 +1,195 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/timeval.h>
+#include <pulsecore/random.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/g711.h>
+#include <pulsecore/core-util.h>
+
+#include "cpu-arm.h"
+
+#include "sample-util.h"
+#include "endianmacros.h"
+
+#if defined (__arm__)
+
+#define MOD_INC() \
+    " subs  r0, r6, %2              \n\t" \
+    " addcs r0, %1                  \n\t" \
+    " movcs r6, r0                  \n\t" 
+
+static void
+pa_volume_s16ne_arm (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
+{
+  int32_t *ve;
+
+  channels = MAX (4, channels);
+  ve = volumes + channels;
+
+  __asm__ __volatile__ (
+    " mov r6, %1                      \n\t"
+    " mov %3, %3, LSR #1              \n\t" /* length /= sizeof (int16_t) */
+    " tst %3, #1                      \n\t" /* check for odd samples */
+    " beq  2f                         \n\t"
+
+    "1:                               \n\t"
+    " ldr  r0, [r6], #4               \n\t" /* odd samples volumes */
+    " ldrh r2, [%0]                   \n\t" 
+
+    " smulwb r0, r0, r2               \n\t"
+    " ssat r0, #16, r0                \n\t"
+    
+    " strh r0, [%0], #2               \n\t"
+
+    MOD_INC()
+
+    "2:                               \n\t"
+    " mov %3, %3, LSR #1              \n\t" 
+    " tst %3, #1                      \n\t" /* check for odd samples */
+    " beq  4f                         \n\t" 
+
+    "3:                               \n\t"
+    " ldrd r2, [r6], #8               \n\t" /* 2 samples at a time */
+    " ldr  r0, [%0]                   \n\t"
+
+    " smulwt r2, r2, r0               \n\t"
+    " smulwb r3, r3, r0               \n\t"
+
+    " ssat r2, #16, r2                \n\t"
+    " ssat r3, #16, r3                \n\t"
+    
+    " pkhbt r0, r3, r2, LSL #16       \n\t"
+    " str  r0, [%0], #4               \n\t"
+
+    MOD_INC()
+
+    "4:                               \n\t"
+    " movs %3, %3, LSR #1             \n\t" 
+    " beq  6f                         \n\t" 
+
+    "5:                               \n\t"
+    " ldrd r2, [r6], #8               \n\t" /* 4 samples at a time */
+    " ldrd r4, [r6], #8               \n\t"
+    " ldrd r0, [%0]                   \n\t"
+
+    " smulwt r2, r2, r0               \n\t"
+    " smulwb r3, r3, r0               \n\t"
+    " smulwt r4, r4, r1               \n\t"
+    " smulwb r5, r5, r1               \n\t"
+
+    " ssat r2, #16, r2                \n\t"
+    " ssat r3, #16, r3                \n\t"
+    " ssat r4, #16, r4                \n\t"
+    " ssat r5, #16, r5                \n\t"
+    
+    " pkhbt r0, r3, r2, LSL #16       \n\t"
+    " pkhbt r1, r5, r4, LSL #16       \n\t"
+    " strd  r0, [%0], #8              \n\t"
+
+    MOD_INC()
+    
+    " subs %3, %3, #1                 \n\t"
+    " bne 5b                          \n\t"
+    "6:                               \n\t"
+
+    : "+r" (samples), "+r" (volumes), "+r" (ve), "+r" (length)
+    :
+    : "r6", "r5", "r4", "r3", "r2", "r1", "r0", "cc"
+  );
+}
+
+#undef RUN_TEST
+
+#ifdef RUN_TEST
+#define CHANNELS 2
+#define SAMPLES 1023
+#define TIMES 1000
+#define PADDING 16
+
+static void run_test (void) {
+  int16_t samples[SAMPLES];
+  int16_t samples_ref[SAMPLES];
+  int16_t samples_orig[SAMPLES];
+  int32_t volumes[CHANNELS + PADDING];
+  int i, j, padding;
+  pa_do_volume_func_t func;
+  struct timeval start, stop;
+
+  func = pa_get_volume_func (PA_SAMPLE_S16NE);
+
+  printf ("checking ARM %zd\n", sizeof (samples));
+
+  pa_random (samples, sizeof (samples));
+  memcpy (samples_ref, samples, sizeof (samples));
+  memcpy (samples_orig, samples, sizeof (samples));
+
+  for (i = 0; i < CHANNELS; i++)
+    volumes[i] = rand() >> 1;
+  for (padding = 0; padding < PADDING; padding++, i++)
+    volumes[i] = volumes[padding];
+
+  func (samples_ref, volumes, CHANNELS, sizeof (samples));
+  pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
+  for (i = 0; i < SAMPLES; i++) {
+    if (samples[i] != samples_ref[i]) {
+      printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+          samples_orig[i], volumes[i % CHANNELS]);
+    }
+  }
+
+  pa_gettimeofday(&start);
+  for (j = 0; j < TIMES; j++) {
+    memcpy (samples, samples_orig, sizeof (samples));
+    pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
+  }
+  pa_gettimeofday(&stop);
+  pa_log_info("ARM: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+
+  pa_gettimeofday(&start);
+  for (j = 0; j < TIMES; j++) {
+    memcpy (samples_ref, samples_orig, sizeof (samples));
+    func (samples_ref, volumes, CHANNELS, sizeof (samples));
+  }
+  pa_gettimeofday(&stop);
+  pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+}
+#endif
+
+#endif /* defined (__arm__) */
+
+
+void pa_volume_func_init_arm (pa_cpu_arm_flag_t flags) {
+#if defined (__arm__)
+  pa_log_info("Initialising ARM optimized functions.");
+
+#ifdef RUN_TEST
+  run_test ();
+#endif
+
+  pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_arm);
+#endif /* defined (__arm__) */
+}

commit bd49d43bd387758f151c56b7ed1643ecb72c0258
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 16:09:48 2009 +0200

    svolume: add CPU guards around code
    
    Mark code that should only be compiled on x86 CPUs with proper defines.

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 5243b44..fb4c82c 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -35,6 +35,7 @@
 #include "sample-util.h"
 #include "endianmacros.h"
 
+#if defined (__i386__) || defined (__amd64__)
 /* in s: 2 int16_t samples
  * in v: 2 int32_t volumes, fixed point 16:16
  * out s: contains scaled and clamped int16_t samples.
@@ -295,7 +296,11 @@ static void run_test (void) {
 }
 #endif
 
+#endif /* defined (__i386__) || defined (__amd64__) */
+
+
 void pa_volume_func_init_mmx (pa_cpu_x86_flag_t flags) {
+#if defined (__i386__) || defined (__amd64__)
   pa_log_info("Initialising MMX optimized functions.");
 
 #ifdef RUN_TEST
@@ -304,4 +309,5 @@ void pa_volume_func_init_mmx (pa_cpu_x86_flag_t flags) {
 
   pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_mmx);
   pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_mmx);
+#endif /* defined (__i386__) || defined (__amd64__) */
 }
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 98f828c..141c466 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -35,6 +35,8 @@
 #include "sample-util.h"
 #include "endianmacros.h"
 
+#if defined (__i386__) || defined (__amd64__)
+
 #define VOLUME_32x16(s,v)                  /* .. |   vh  |   vl  | */                   \
       " pxor %%xmm4, %%xmm4          \n\t" /* .. |    0  |    0  | */                   \
       " punpcklwd %%xmm4, "#s"       \n\t" /* .. |    0  |   p0  | */                   \
@@ -293,8 +295,10 @@ static void run_test (void) {
   pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
 }
 #endif
+#endif /* defined (__i386__) || defined (__amd64__) */
 
 void pa_volume_func_init_sse (pa_cpu_x86_flag_t flags) {
+#if defined (__i386__) || defined (__amd64__)
   pa_log_info("Initialising SSE optimized functions.");
 
 #ifdef RUN_TEST
@@ -303,4 +307,5 @@ void pa_volume_func_init_sse (pa_cpu_x86_flag_t flags) {
 
   pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_sse);
   pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_sse);
+#endif /* defined (__i386__) || defined (__amd64__) */
 }

commit b4e9942c2f3929b4baf4b53b0561102af7845269
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 16:15:18 2009 +0200

    resample: refactor the channel remapping a little
    
    Factor out the channel remap matrix code into a separate function.
    Keep a pointer to the channel remapping function so we can install custom
    functions.
    Catch the common mono->stereo remapping case and install a custom, more
    optimized function.

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index e3473ac..4fb03ce 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -44,6 +44,11 @@
 /* Number of samples of extra space we allow the resamplers to return */
 #define EXTRA_FRAMES 128
 
+typedef void (*pa_do_remap_func_t) (pa_resampler *r, void *d, const void *s, unsigned n);
+
+static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src, unsigned n);
+static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, unsigned n);
+
 struct pa_resampler {
     pa_resample_method_t method;
     pa_resample_flags_t flags;
@@ -64,6 +69,7 @@ struct pa_resampler {
     float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
     int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
     pa_bool_t map_required;
+    pa_do_remap_func_t do_remap;
 
     void (*impl_free)(pa_resampler *r);
     void (*impl_update_rates)(pa_resampler *r);
@@ -1008,6 +1014,17 @@ static void calc_map_table(pa_resampler *r) {
 
     pa_log_debug("Channel matrix:\n%s", t = pa_strbuf_tostring_free(s));
     pa_xfree(t);
+
+    /* find some common channel remappings, fall back to full matrix operation. */
+    if (r->i_ss.channels == 1 && r->o_ss.channels == 2 &&
+            r->map_table_i[0][0] == 1.0 && r->map_table_i[1][0] == 1.0) {
+        r->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo;;
+        pa_log_debug("Using mono to stereo remapping");
+    } else {
+        r->do_remap = (pa_do_remap_func_t) remap_channels_matrix;
+        pa_log_debug("Using generic matrix remapping");
+    }
+
 }
 
 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
@@ -1047,49 +1064,111 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)
     return &r->buf1;
 }
 
-static void vectoradd_f32(
-        float *d, int dstr,
-        const float *s, int sstr,
-        int n, float s4) {
+static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, unsigned n) {
+  
+    switch (r->work_format) {
+        case PA_SAMPLE_FLOAT32NE:
+        {
+            float *d, *s;
+
+	    d = (float *) dst;
+	    s = (float *) src;
+
+            for (; n > 0; n--) {
+                *d++ = *s;
+                *d++ = *s++;
+            }
+	    break;
+	}
+        case PA_SAMPLE_S16NE:
+        {
+            int16_t *d, *s;
 
-    for (; n > 0; n--) {
-        *d = (float) (*d + (s4 * *s));
+	    d = (int16_t *) dst;
+	    s = (int16_t *) src;
 
-        s = (const float*) ((const uint8_t*) s + sstr);
-        d = (float*) ((uint8_t*) d + dstr);
+            for (; n > 0; n--) {
+                *d++ = *s;
+                *d++ = *s++;
+            }
+	    break;
+	}
+        default:
+            pa_assert_not_reached();
     }
 }
 
-static void vectoradd_s16(
-        int16_t *d, int dstr,
-        const int16_t *s, int sstr,
-        int n) {
+static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src, unsigned n) {
+    unsigned oc;
+    unsigned n_ic, n_oc;
 
-    for (; n > 0; n--) {
-        *d = (int16_t) (*d + *s);
+    n_ic = r->i_ss.channels;
+    n_oc = r->o_ss.channels;
 
-        s = (const int16_t*) ((const uint8_t*) s + sstr);
-        d = (int16_t*) ((uint8_t*) d + dstr);
-    }
-}
+    memset(dst, 0, r->buf2.length);
 
-static void vectoradd_s16_with_fraction(
-        int16_t *d, int dstr,
-        const int16_t *s, int sstr,
-        int n, int32_t i4) {
+    switch (r->work_format) {
+        case PA_SAMPLE_FLOAT32NE:
+        {
+            float *d, *s;
 
-    for (; n > 0; n--) {
-        *d = (int16_t) (*d + (((int32_t)*s * i4) >> 16));
+            for (oc = 0; oc < n_oc; oc++) {
+                unsigned ic;
 
-        s = (const int16_t*) ((const uint8_t*) s + sstr);
-        d = (int16_t*) ((uint8_t*) d + dstr);
+                for (ic = 0; ic < n_ic; ic++) {
+                    float vol;
+
+		    vol = r->map_table_f[oc][ic];
+
+                    if (vol <= 0.0)
+                        continue;
+
+                    d = (float *)dst + oc;
+                    s = (float *)src + ic;
+
+                    for (; n > 0; n--, s += n_ic, d += n_oc)
+                        *d += *s * vol;
+                }
+            }
+
+            break;
+	}
+        case PA_SAMPLE_S16NE:
+        {
+            int16_t *d, *s;
+
+            for (oc = 0; oc < n_oc; oc++) {
+                unsigned ic;
+
+                for (ic = 0; ic < n_ic; ic++) {
+                    int32_t vol;
+
+		    vol = r->map_table_i[oc][ic];
+
+                    if (vol <= 0)
+                        continue;
+
+                    d = (int16_t *)dst + oc;
+                    s = (int16_t *)src + ic;
+
+                    if (vol >= 0x10000) {
+                        for (; n > 0; n--, s += n_ic, d += n_oc)
+                            *d += *s;
+                    } else {
+                        for (; n > 0; n--, s += n_ic, d += n_oc)
+                            *d = (int16_t) (*d + (((int32_t)*s * vol) >> 16));
+		    }
+                }
+            }
+            break;
+	}
+        default:
+            pa_assert_not_reached();
     }
 }
 
 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
     unsigned in_n_samples, out_n_samples, n_frames;
-    int i_skip, o_skip;
-    unsigned oc;
     void *src, *dst;
 
     pa_assert(r);
@@ -1119,70 +1198,12 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
     src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
     dst = pa_memblock_acquire(r->buf2.memblock);
 
-    memset(dst, 0, r->buf2.length);
-
-    o_skip = (int) (r->w_sz * r->o_ss.channels);
-    i_skip = (int) (r->w_sz * r->i_ss.channels);
-
-    switch (r->work_format) {
-        case PA_SAMPLE_FLOAT32NE:
-
-            for (oc = 0; oc < r->o_ss.channels; oc++) {
-                unsigned ic;
-
-                for (ic = 0; ic < r->i_ss.channels; ic++) {
-
-                    if (r->map_table_f[oc][ic] <= 0.0)
-                        continue;
-
-                    vectoradd_f32(
-                            (float*) dst + oc, o_skip,
-                            (float*) src + ic, i_skip,
-                            (int) n_frames,
-                            r->map_table_f[oc][ic]);
-                }
-            }
-
-            break;
-
-        case PA_SAMPLE_S16NE:
-
-            for (oc = 0; oc < r->o_ss.channels; oc++) {
-                unsigned ic;
-
-                for (ic = 0; ic < r->i_ss.channels; ic++) {
-
-                    if (r->map_table_f[oc][ic] <= 0.0)
-                        continue;
-
-                    if (r->map_table_f[oc][ic] >= 1.0) {
-
-                        vectoradd_s16(
-                                (int16_t*) dst + oc, o_skip,
-                                (int16_t*) src + ic, i_skip,
-                                (int) n_frames);
-
-                    } else
-
-                        vectoradd_s16_with_fraction(
-                                (int16_t*) dst + oc, o_skip,
-                                (int16_t*) src + ic, i_skip,
-                                (int) n_frames,
-                                r->map_table_i[oc][ic]);
-                }
-            }
-
-            break;
-
-        default:
-            pa_assert_not_reached();
-    }
+    pa_assert (r->do_remap);
+    r->do_remap (r, dst, src, n_frames);
 
     pa_memblock_release(input->memblock);
     pa_memblock_release(r->buf2.memblock);
 
-    r->buf2.length = out_n_samples * r->w_sz;
-
     return &r->buf2;
 }
 

commit d04a6e935f8352a4ffd93cb1aeddac8f605a099a
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 16:23:55 2009 +0200

    resample: fix counters

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 4fb03ce..cc57b54 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -1099,7 +1099,7 @@ static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, un
 }
 
 static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src, unsigned n) {
-    unsigned oc;
+    unsigned oc, i;
     unsigned n_ic, n_oc;
 
     n_ic = r->i_ss.channels;
@@ -1126,7 +1126,7 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                     d = (float *)dst + oc;
                     s = (float *)src + ic;
 
-                    for (; n > 0; n--, s += n_ic, d += n_oc)
+                    for (i = n; i > 0; i--, s += n_ic, d += n_oc)
                         *d += *s * vol;
                 }
             }
@@ -1152,10 +1152,10 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                     s = (int16_t *)src + ic;
 
                     if (vol >= 0x10000) {
-                        for (; n > 0; n--, s += n_ic, d += n_oc)
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
                             *d += *s;
                     } else {
-                        for (; n > 0; n--, s += n_ic, d += n_oc)
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
                             *d = (int16_t) (*d + (((int32_t)*s * vol) >> 16));
 		    }
                 }

commit 548b735ccf8474ebe60137375cdda4e58582efc3
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 17:24:23 2009 +0200

    resampler: fix identity check
    
    Fix the identity matrix check for mono to stereo.
    Help the compiler generate better code for the C implementation of the channel
    remapping code.

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index cc57b54..2256516 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -1017,7 +1017,7 @@ static void calc_map_table(pa_resampler *r) {
 
     /* find some common channel remappings, fall back to full matrix operation. */
     if (r->i_ss.channels == 1 && r->o_ss.channels == 2 &&
-            r->map_table_i[0][0] == 1.0 && r->map_table_i[1][0] == 1.0) {
+            r->map_table_f[0][0] >= 1.0 && r->map_table_f[1][0] >= 1.0) {
         r->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo;;
         pa_log_debug("Using mono to stereo remapping");
     } else {
@@ -1074,10 +1074,8 @@ static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, un
 	    d = (float *) dst;
 	    s = (float *) src;
 
-            for (; n > 0; n--) {
-                *d++ = *s;
-                *d++ = *s++;
-            }
+            for (; n > 0; n--, s++, d += 2)
+                d[0] = d[1] = *s;
 	    break;
 	}
         case PA_SAMPLE_S16NE:
@@ -1087,10 +1085,8 @@ static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, un
 	    d = (int16_t *) dst;
 	    s = (int16_t *) src;
 
-            for (; n > 0; n--) {
-                *d++ = *s;
-                *d++ = *s++;
-            }
+            for (; n > 0; n--, s++, d += 2)
+                d[0] = d[1] = *s;
 	    break;
 	}
         default:
@@ -1156,7 +1152,7 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                             *d += *s;
                     } else {
                         for (i = n; i > 0; i--, s += n_ic, d += n_oc)
-                            *d = (int16_t) (*d + (((int32_t)*s * vol) >> 16));
+                            *d += (int16_t) (((int32_t)*s * vol) >> 16);
 		    }
                 }
             }

commit d2389ef96e21825bb4e945f6c71b5bd27c5fa2b4
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 17:27:17 2009 +0200

    sample: manually inline table lookups
    
    Manually inline some table lookups to avoid excessive calls to
    pa_sample_spec_valid().

diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index d5d38ed..9698d8a 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -36,28 +36,27 @@
 
 #include "sample.h"
 
-size_t pa_sample_size_of_format(pa_sample_format_t f) {
-
-    static const size_t table[] = {
-        [PA_SAMPLE_U8] = 1,
-        [PA_SAMPLE_ULAW] = 1,
-        [PA_SAMPLE_ALAW] = 1,
-        [PA_SAMPLE_S16LE] = 2,
-        [PA_SAMPLE_S16BE] = 2,
-        [PA_SAMPLE_FLOAT32LE] = 4,
-        [PA_SAMPLE_FLOAT32BE] = 4,
-        [PA_SAMPLE_S32LE] = 4,
-        [PA_SAMPLE_S32BE] = 4,
-        [PA_SAMPLE_S24LE] = 3,
-        [PA_SAMPLE_S24BE] = 3,
-        [PA_SAMPLE_S24_32LE] = 4,
-        [PA_SAMPLE_S24_32BE] = 4
-    };
+static const size_t size_table[] = {
+    [PA_SAMPLE_U8] = 1,
+    [PA_SAMPLE_ULAW] = 1,
+    [PA_SAMPLE_ALAW] = 1,
+    [PA_SAMPLE_S16LE] = 2,
+    [PA_SAMPLE_S16BE] = 2,
+    [PA_SAMPLE_FLOAT32LE] = 4,
+    [PA_SAMPLE_FLOAT32BE] = 4,
+    [PA_SAMPLE_S32LE] = 4,
+    [PA_SAMPLE_S32BE] = 4,
+    [PA_SAMPLE_S24LE] = 3,
+    [PA_SAMPLE_S24BE] = 3,
+    [PA_SAMPLE_S24_32LE] = 4,
+    [PA_SAMPLE_S24_32BE] = 4
+};
 
+size_t pa_sample_size_of_format(pa_sample_format_t f) {
     pa_assert(f >= 0);
     pa_assert(f < PA_SAMPLE_MAX);
 
-    return table[f];
+    return size_table[f];
 }
 
 size_t pa_sample_size(const pa_sample_spec *spec) {
@@ -65,35 +64,35 @@ size_t pa_sample_size(const pa_sample_spec *spec) {
     pa_assert(spec);
     pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
-    return pa_sample_size_of_format(spec->format);
+    return size_table[spec->format];
 }
 
 size_t pa_frame_size(const pa_sample_spec *spec) {
     pa_assert(spec);
     pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
-    return pa_sample_size(spec) * spec->channels;
+    return size_table[spec->format] * spec->channels;
 }
 
 size_t pa_bytes_per_second(const pa_sample_spec *spec) {
     pa_assert(spec);
     pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
-    return spec->rate*pa_frame_size(spec);
+    return spec->rate * size_table[spec->format] * spec->channels;
 }
 
 pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) {
     pa_assert(spec);
     pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
-    return (((pa_usec_t) (length / pa_frame_size(spec)) * PA_USEC_PER_SEC) / spec->rate);
+    return (((pa_usec_t) (length / (size_table[spec->format] * spec->channels)) * PA_USEC_PER_SEC) / spec->rate);
 }
 
 size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) {
     pa_assert(spec);
     pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
 
-    return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * pa_frame_size(spec);
+    return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * (size_table[spec->format] * spec->channels);
 }
 
 pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec) {
@@ -109,12 +108,12 @@ pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec) {
 int pa_sample_spec_valid(const pa_sample_spec *spec) {
     pa_assert(spec);
 
-    if (spec->rate <= 0 ||
+    if (PA_UNLIKELY (spec->rate <= 0 ||
         spec->rate > PA_RATE_MAX ||
         spec->channels <= 0 ||
         spec->channels > PA_CHANNELS_MAX ||
         spec->format >= PA_SAMPLE_MAX ||
-        spec->format < 0)
+        spec->format < 0))
         return 0;
 
     return 1;

commit 370016c0e73236830513a9ea9c16366c15bd30a2
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 18:52:28 2009 +0200

    svolume: fix compilation in 32bits

diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index fb4c82c..86af76d 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -114,11 +114,11 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " je 2f                         \n\t" 
 
     " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %4                 \n\t" /*     ..  |  p0   | */
+    " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
     " movd %4, %%mm1                \n\t" 
     VOLUME_32x16 (%%mm1, %%mm0)
     " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
-    " movw %4, (%0)                 \n\t" 
+    " movw %w4, (%0)                \n\t" 
     " add $2, %0                    \n\t"
     MOD_ADD ($1, %5)
 
@@ -184,13 +184,13 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " je 2f                         \n\t" 
 
     " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %4                 \n\t" /*     ..  |  p0   | */
-    " rorw $8, %4                   \n\t"
+    " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
+    " rorw $8, %w4                  \n\t"
     " movd %4, %%mm1                \n\t" 
     VOLUME_32x16 (%%mm1, %%mm0)
     " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
-    " rorw $8, %4                   \n\t"
-    " movw %4, (%0)                 \n\t" 
+    " rorw $8, %w4                  \n\t"
+    " movw %w4, (%0)                \n\t" 
     " add $2, %0                    \n\t"
     MOD_ADD ($1, %5)
 
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 141c466..0054d30 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -91,11 +91,11 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " je 2f                         \n\t" 
 
     " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %4                 \n\t" /*     ..  |   p0  | */
+    " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
     " movd %4, %%xmm1               \n\t" 
     VOLUME_32x16 (%%xmm1, %%xmm0)
     " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
-    " movw %4, (%0)                 \n\t" 
+    " movw %w4, (%0)                \n\t" 
     " add $2, %0                    \n\t"
     MOD_ADD ($1, %5)
 
@@ -168,13 +168,13 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " je 2f                         \n\t" 
 
     " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %4                 \n\t" /*     ..  |   p0  | */
-    " rorw $8, %4                   \n\t" 
+    " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
+    " rorw $8, %w4                  \n\t" 
     " movd %4, %%xmm1               \n\t" 
     VOLUME_32x16 (%%xmm1, %%xmm0)
     " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
-    " rorw $8, %4                   \n\t" 
-    " movw %4, (%0)                 \n\t" 
+    " rorw $8, %w4                  \n\t" 
+    " movw %w4, (%0)                \n\t" 
     " add $2, %0                    \n\t"
     MOD_ADD ($1, %5)
 

commit 078bde1b49a11f6c76e47fea19f9d920a45ce3f1
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 19:50:42 2009 +0200

    x86: keep the cpu flags local

diff --git a/src/pulsecore/cpu-x86.c b/src/pulsecore/cpu-x86.c
index 2da31c9..453ecf5 100644
--- a/src/pulsecore/cpu-x86.c
+++ b/src/pulsecore/cpu-x86.c
@@ -45,12 +45,11 @@ get_cpuid (uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
 }
 #endif
 
-static pa_cpu_x86_flag_t pa_cpu_x86_flags;
-
 void pa_cpu_init_x86 (void) {
 #if defined (__i386__) || defined (__amd64__)
     uint32_t eax, ebx, ecx, edx;
     uint32_t level;
+    pa_cpu_x86_flag_t flags = 0;
 
     /* get standard level */
     get_cpuid (0x00000000, &level, &ebx, &ecx, &edx);
@@ -58,25 +57,25 @@ void pa_cpu_init_x86 (void) {
         get_cpuid (0x00000001, &eax, &ebx, &ecx, &edx);
 
         if (edx & (1<<23))
-          pa_cpu_x86_flags |= PA_CPU_X86_MMX;
+          flags |= PA_CPU_X86_MMX;
 
         if (edx & (1<<25))
-          pa_cpu_x86_flags |= PA_CPU_X86_SSE;
+          flags |= PA_CPU_X86_SSE;
 
         if (edx & (1<<26))
-          pa_cpu_x86_flags |= PA_CPU_X86_SSE2;
+          flags |= PA_CPU_X86_SSE2;
 
         if (ecx & (1<<0))
-          pa_cpu_x86_flags |= PA_CPU_X86_SSE3;
+          flags |= PA_CPU_X86_SSE3;
 
         if (ecx & (1<<9))
-          pa_cpu_x86_flags |= PA_CPU_X86_SSSE3;
+          flags |= PA_CPU_X86_SSSE3;
 
         if (ecx & (1<<19))
-          pa_cpu_x86_flags |= PA_CPU_X86_SSE4_1;
+          flags |= PA_CPU_X86_SSE4_1;
 
         if (ecx & (1<<20))
-          pa_cpu_x86_flags |= PA_CPU_X86_SSE4_2;
+          flags |= PA_CPU_X86_SSE4_2;
     }
 
     /* get extended level */
@@ -85,38 +84,36 @@ void pa_cpu_init_x86 (void) {
         get_cpuid (0x80000001, &eax, &ebx, &ecx, &edx);
 
         if (edx & (1<<22))
-          pa_cpu_x86_flags |= PA_CPU_X86_MMXEXT;
+          flags |= PA_CPU_X86_MMXEXT;
 
         if (edx & (1<<23))
-          pa_cpu_x86_flags |= PA_CPU_X86_MMX;
+          flags |= PA_CPU_X86_MMX;
 
         if (edx & (1<<30))
-          pa_cpu_x86_flags |= PA_CPU_X86_3DNOWEXT;
+          flags |= PA_CPU_X86_3DNOWEXT;
 
         if (edx & (1<<31))
-          pa_cpu_x86_flags |= PA_CPU_X86_3DNOW;
+          flags |= PA_CPU_X86_3DNOW;
     }
 
     pa_log_info ("CPU flags: %s%s%s%s%s%s%s%s%s%s",
-	  (pa_cpu_x86_flags & PA_CPU_X86_MMX) ? "MMX " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_SSE) ? "SSE " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
-	  (pa_cpu_x86_flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
+	  (flags & PA_CPU_X86_MMX) ? "MMX " : "",
+	  (flags & PA_CPU_X86_SSE) ? "SSE " : "",
+	  (flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
+	  (flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
+	  (flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
+	  (flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
+	  (flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
+	  (flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
+	  (flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
+	  (flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
 
     /* activate various optimisations */
-    if (pa_cpu_x86_flags & PA_CPU_X86_MMX) {
-        pa_volume_func_init_mmx (pa_cpu_x86_flags);
+    if (flags & PA_CPU_X86_MMX) {
+        pa_volume_func_init_mmx (flags);
     }
-    if (pa_cpu_x86_flags & PA_CPU_X86_SSE) {
-	pa_volume_func_init_sse (pa_cpu_x86_flags);
+    if (flags & PA_CPU_X86_SSE) {
+	pa_volume_func_init_sse (flags);
     }
-#else
-    pa_cpu_x86_flags = 0;
-#endif
+#endif /* defined (__i386__) || defined (__amd64__) */
 }

commit 8aa86f5247103432faf660cba33f5ce80fbbc2c7
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 19:51:11 2009 +0200

    arm: implement ARM cpu detection

diff --git a/src/pulsecore/cpu-arm.c b/src/pulsecore/cpu-arm.c
index 75646fe..93ad389 100644
--- a/src/pulsecore/cpu-arm.c
+++ b/src/pulsecore/cpu-arm.c
@@ -25,19 +25,116 @@
 #endif
 
 #include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
+#include <pulse/xmalloc.h>
 #include <pulsecore/log.h>
 
 #include "cpu-arm.h"
 
-static pa_cpu_arm_flag_t pa_cpu_arm_flags;
+#if defined (__arm__) && defined (__linux__)
+
+#define MAX_BUFFER	4096
+static char *
+get_cpuinfo_line (char *cpuinfo, const char *tag) {
+    char *line, *end, *colon;
+
+    if (!(line = strstr (cpuinfo, tag)))
+        return NULL;
+     
+    if (!(end = strchr (line, '\n')))
+        return NULL;
+
+    if (!(colon = strchr (line, ':')))
+        return NULL;
+
+    if (++colon >= end)
+        return NULL;
+
+    return pa_xstrndup (colon, end - colon);
+}
+
+static char *get_cpuinfo(void) {
+    char *cpuinfo;
+    int n, fd;
+
+    if (!(cpuinfo = malloc(MAX_BUFFER)))
+         return NULL;
+
+    if ((fd = open("/proc/cpuinfo", O_RDONLY)) < 0) {
+        free (cpuinfo);
+        return NULL;
+    }
+
+    if ((n = read(fd, cpuinfo, MAX_BUFFER-1)) < 0) {
+        free (cpuinfo);
+        close (fd);
+        return NULL;
+    }
+    cpuinfo[n] = 0;
+    close (fd);
+
+    return cpuinfo;
+}
+#endif /* defined (__arm__) && defined (__linux__) */
 
 void pa_cpu_init_arm (void) {
 #if defined (__arm__)
-    pa_cpu_arm_flags = 0;
-   
-    pa_log ("ARM init\n");
+#if defined (__linux__)
+    char *cpuinfo, *line;
+    int arch;
+    pa_cpu_arm_flag_t flags = 0;
+
+    /* We need to read the CPU flags from /proc/cpuinfo because there is no user
+     * space support to get the CPU features. This only works on linux AFAIK. */
+    if (!(cpuinfo = get_cpuinfo ())) {
+        pa_log ("Can't read cpuinfo");
+        return;
+    }
+
+    /* get the CPU architecture */
+    if ((line = get_cpuinfo_line (cpuinfo, "CPU architecture"))) {
+        arch = strtoul (line, NULL, 0);
+        if (arch >= 6)
+            flags |= PA_CPU_ARM_V6;
+        if (arch >= 7)
+            flags |= PA_CPU_ARM_V7;
+
+        free (line);
+    }
+    /* get the CPU features */
+    if ((line = get_cpuinfo_line (cpuinfo, "Features"))) {
+	  char *state = NULL, *current;
+
+	  while ((current = pa_split_spaces (line, &state))) {
+              if (!strcmp (current, "vfp")) 
+                  flags |= PA_CPU_ARM_VFP;
+	      else if (!strcmp (current, "edsp")) 
+                  flags |= PA_CPU_ARM_EDSP;
+	      else if (!strcmp (current, "neon")) 
+                  flags |= PA_CPU_ARM_NEON;
+	      else if (!strcmp (current, "vfpv3")) 
+                  flags |= PA_CPU_ARM_VFPV3;
+
+              free (current);
+	  }
+    }
+    free (cpuinfo);
+
+    pa_log_info ("CPU flags: %s%s%s%s%s%s",
+          (flags & PA_CPU_ARM_V6) ? "V6 " : "",
+          (flags & PA_CPU_ARM_V7) ? "V7 " : "",
+          (flags & PA_CPU_ARM_VFP) ? "VFP " : "",
+          (flags & PA_CPU_ARM_EDSP) ? "EDSP " : "",
+          (flags & PA_CPU_ARM_NEON) ? "NEON " : "",
+          (flags & PA_CPU_ARM_VFPV3) ? "VFPV3 " : "");
+#else /* defined (__linux__) */
+    pa_log ("ARM cpu features not yet supported on this OS");
+#endif /* defined (__linux__) */
 
-    pa_volume_func_init_arm (pa_cpu_arm_flags);
+    if (flags & PA_CPU_ARM_V6)
+        pa_volume_func_init_arm (flags);
 #endif /* defined (__arm__) */
 }
diff --git a/src/pulsecore/cpu-arm.h b/src/pulsecore/cpu-arm.h
index 1a0ac27..3ccd070 100644
--- a/src/pulsecore/cpu-arm.h
+++ b/src/pulsecore/cpu-arm.h
@@ -27,8 +27,11 @@
 
 typedef enum pa_cpu_arm_flag {
     PA_CPU_ARM_V6       = (1 << 0),
-    PA_CPU_ARM_NEON     = (1 << 1),
-    PA_CPU_ARM_VFP      = (1 << 2)
+    PA_CPU_ARM_V7       = (1 << 1),
+    PA_CPU_ARM_VFP      = (1 << 2),
+    PA_CPU_ARM_EDSP     = (1 << 3),
+    PA_CPU_ARM_NEON     = (1 << 4),
+    PA_CPU_ARM_VFPV3    = (1 << 5)
 } pa_cpu_arm_flag_t;
 
 void pa_cpu_init_arm (void);

commit aeae567f8861d2f068ebd0f054cd9d0aa6a7fe95
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 20:00:28 2009 +0200

    svolume: add comment

diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 0054d30..5979f7c 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -117,6 +117,9 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
     " test $1, %2                   \n\t" 
     " je 6f                         \n\t" 
 
+    /* FIXME, we can do aligned access of the volume values if we can guarantee
+     * that the array is 16 bytes aligned, we probably have to do the odd values
+     * after this then. */
     "5:                             \n\t" /* do samples in groups of 4 */
     " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
     " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */

commit 3cc1278dcf44c9fb93bfd2725a2f75de1958cf23
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Wed Aug 19 20:47:48 2009 +0200

    resampler: avoid some multiplies when we can

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 2256516..43771dc 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -1122,8 +1122,13 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                     d = (float *)dst + oc;
                     s = (float *)src + ic;
 
-                    for (i = n; i > 0; i--, s += n_ic, d += n_oc)
-                        *d += *s * vol;
+		    if (vol >= 1.0) {
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
+                            *d += *s;
+		    } else { 
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
+                            *d += *s * vol;
+		    }
                 }
             }
 

commit f09b51198f43d79b22cb92b5223d01a7ab339d9f
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 10:56:20 2009 +0200

    whitespace fixes

diff --git a/src/pulsecore/cpu-arm.c b/src/pulsecore/cpu-arm.c
index 93ad389..5a994b7 100644
--- a/src/pulsecore/cpu-arm.c
+++ b/src/pulsecore/cpu-arm.c
@@ -36,14 +36,14 @@
 
 #if defined (__arm__) && defined (__linux__)
 
-#define MAX_BUFFER	4096
+#define MAX_BUFFER  4096
 static char *
 get_cpuinfo_line (char *cpuinfo, const char *tag) {
     char *line, *end, *colon;
 
     if (!(line = strstr (cpuinfo, tag)))
         return NULL;
-     
+
     if (!(end = strchr (line, '\n')))
         return NULL;
 
@@ -106,20 +106,20 @@ void pa_cpu_init_arm (void) {
     }
     /* get the CPU features */
     if ((line = get_cpuinfo_line (cpuinfo, "Features"))) {
-	  char *state = NULL, *current;
-
-	  while ((current = pa_split_spaces (line, &state))) {
-              if (!strcmp (current, "vfp")) 
-                  flags |= PA_CPU_ARM_VFP;
-	      else if (!strcmp (current, "edsp")) 
-                  flags |= PA_CPU_ARM_EDSP;
-	      else if (!strcmp (current, "neon")) 
-                  flags |= PA_CPU_ARM_NEON;
-	      else if (!strcmp (current, "vfpv3")) 
-                  flags |= PA_CPU_ARM_VFPV3;
-
-              free (current);
-	  }
+        char *state = NULL, *current;
+
+        while ((current = pa_split_spaces (line, &state))) {
+            if (!strcmp (current, "vfp"))
+                flags |= PA_CPU_ARM_VFP;
+            else if (!strcmp (current, "edsp"))
+                flags |= PA_CPU_ARM_EDSP;
+            else if (!strcmp (current, "neon"))
+                flags |= PA_CPU_ARM_NEON;
+            else if (!strcmp (current, "vfpv3"))
+                flags |= PA_CPU_ARM_VFPV3;
+
+            free (current);
+        }
     }
     free (cpuinfo);
 
diff --git a/src/pulsecore/cpu-x86.c b/src/pulsecore/cpu-x86.c
index 453ecf5..0457199 100644
--- a/src/pulsecore/cpu-x86.c
+++ b/src/pulsecore/cpu-x86.c
@@ -2,7 +2,7 @@
   This file is part of PulseAudio.
 
   Copyright 2004-2006 Lennart Poettering
-  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk> 
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk>
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
@@ -34,14 +34,15 @@
 static void
 get_cpuid (uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
 {
-  __asm__ __volatile__ (
-      "  push %%"PA_REG_b"   \n\t"
-      "  cpuid               \n\t"
-      "  mov %%ebx, %%esi    \n\t"
-      "  pop %%"PA_REG_b"    \n\t"
-
-      : "=a" (*a), "=S" (*b), "=c" (*c), "=d" (*d)
-      : "0" (op));
+    __asm__ __volatile__ (
+        "  push %%"PA_REG_b"   \n\t"
+        "  cpuid               \n\t"
+        "  mov %%ebx, %%esi    \n\t"
+        "  pop %%"PA_REG_b"    \n\t"
+
+        : "=a" (*a), "=S" (*b), "=c" (*c), "=d" (*d)
+        : "0" (op)
+    );
 }
 #endif
 
@@ -97,23 +98,23 @@ void pa_cpu_init_x86 (void) {
     }
 
     pa_log_info ("CPU flags: %s%s%s%s%s%s%s%s%s%s",
-	  (flags & PA_CPU_X86_MMX) ? "MMX " : "",
-	  (flags & PA_CPU_X86_SSE) ? "SSE " : "",
-	  (flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
-	  (flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
-	  (flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
-	  (flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
-	  (flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
-	  (flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
-	  (flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
-	  (flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
+    (flags & PA_CPU_X86_MMX) ? "MMX " : "",
+    (flags & PA_CPU_X86_SSE) ? "SSE " : "",
+    (flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
+    (flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
+    (flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
+    (flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
+    (flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
+    (flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
+    (flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
+    (flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
 
     /* activate various optimisations */
-    if (flags & PA_CPU_X86_MMX) {
+    if (flags & PA_CPU_X86_MMX)
         pa_volume_func_init_mmx (flags);
-    }
-    if (flags & PA_CPU_X86_SSE) {
-	pa_volume_func_init_sse (flags);
-    }
+
+    if (flags & PA_CPU_X86_SSE)
+        pa_volume_func_init_sse (flags);
+
 #endif /* defined (__i386__) || defined (__amd64__) */
 }
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 43771dc..5a6c398 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -1065,30 +1065,53 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)
 }
 
 static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, unsigned n) {
-  
+    unsigned i;
+
     switch (r->work_format) {
         case PA_SAMPLE_FLOAT32NE:
         {
             float *d, *s;
 
-	    d = (float *) dst;
-	    s = (float *) src;
+            d = (float *) dst;
+            s = (float *) src;
 
-            for (; n > 0; n--, s++, d += 2)
-                d[0] = d[1] = *s;
-	    break;
-	}
+            for (i = n >> 2; i; i--) {
+                d[0] = d[1] = s[0];
+                d[2] = d[3] = s[1];
+                d[4] = d[5] = s[2];
+                d[6] = d[7] = s[3];
+                s += 4;
+                d += 8;
+            }
+            for (i = n & 3; i; i--) {
+                d[0] = d[1] = s[0];
+                s++;
+                d += 2;
+            }
+            break;
+        }
         case PA_SAMPLE_S16NE:
         {
             int16_t *d, *s;
 
-	    d = (int16_t *) dst;
-	    s = (int16_t *) src;
+            d = (int16_t *) dst;
+            s = (int16_t *) src;
 
-            for (; n > 0; n--, s++, d += 2)
-                d[0] = d[1] = *s;
-	    break;
-	}
+            for (i = n >> 2; i; i--) {
+                d[0] = d[1] = s[0];
+                d[2] = d[3] = s[1];
+                d[4] = d[5] = s[2];
+                d[6] = d[7] = s[3];
+                s += 4;
+                d += 8;
+            }
+            for (i = n & 3; i; i--) {
+                d[0] = d[1] = s[0];
+                s++;
+                d += 2;
+            }
+            break;
+        }
         default:
             pa_assert_not_reached();
     }
@@ -1114,7 +1137,7 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                 for (ic = 0; ic < n_ic; ic++) {
                     float vol;
 
-		    vol = r->map_table_f[oc][ic];
+                    vol = r->map_table_f[oc][ic];
 
                     if (vol <= 0.0)
                         continue;
@@ -1122,18 +1145,18 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                     d = (float *)dst + oc;
                     s = (float *)src + ic;
 
-		    if (vol >= 1.0) {
+                    if (vol >= 1.0) {
                         for (i = n; i > 0; i--, s += n_ic, d += n_oc)
                             *d += *s;
-		    } else { 
+                    } else {
                         for (i = n; i > 0; i--, s += n_ic, d += n_oc)
                             *d += *s * vol;
-		    }
+                    }
                 }
             }
 
             break;
-	}
+        }
         case PA_SAMPLE_S16NE:
         {
             int16_t *d, *s;
@@ -1144,7 +1167,7 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                 for (ic = 0; ic < n_ic; ic++) {
                     int32_t vol;
 
-		    vol = r->map_table_i[oc][ic];
+		                vol = r->map_table_i[oc][ic];
 
                     if (vol <= 0)
                         continue;
@@ -1158,11 +1181,11 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                     } else {
                         for (i = n; i > 0; i--, s += n_ic, d += n_oc)
                             *d += (int16_t) (((int32_t)*s * vol) >> 16);
-		    }
+		                }
                 }
             }
             break;
-	}
+        }
         default:
             pa_assert_not_reached();
     }
diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index 677f914..6e97e5a 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -752,12 +752,13 @@ void pa_volume_memchunk(
       return;
     }
 
-    ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
-
     do_volume = pa_get_volume_func (spec->format);
     pa_assert(do_volume);
-    
+
     calc_volume_table[spec->format] ((void *)linear, volume);
+
+    ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
+
     do_volume (ptr, (void *)linear, spec->channels, c->length);
 
     pa_memblock_release(c->memblock);
@@ -944,12 +945,12 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo
         for (; n > 0; n--) {
             float f;
 
-	    f = *s;
+            f = *s;
             *d = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);
 
             s = (const float*) ((const uint8_t*) s + sstr);
             d = (float*) ((uint8_t*) d + dstr);
-	}
+        }
     } else {
         pa_assert(format == PA_SAMPLE_FLOAT32RE);
 
diff --git a/src/pulsecore/svolume_arm.c b/src/pulsecore/svolume_arm.c
index 7e25a13..0d39d10 100644
--- a/src/pulsecore/svolume_arm.c
+++ b/src/pulsecore/svolume_arm.c
@@ -40,86 +40,86 @@
 #define MOD_INC() \
     " subs  r0, r6, %2              \n\t" \
     " addcs r0, %1                  \n\t" \
-    " movcs r6, r0                  \n\t" 
+    " movcs r6, r0                  \n\t"
 
 static void
 pa_volume_s16ne_arm (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  int32_t *ve;
-
-  channels = MAX (4, channels);
-  ve = volumes + channels;
-
-  __asm__ __volatile__ (
-    " mov r6, %1                      \n\t"
-    " mov %3, %3, LSR #1              \n\t" /* length /= sizeof (int16_t) */
-    " tst %3, #1                      \n\t" /* check for odd samples */
-    " beq  2f                         \n\t"
-
-    "1:                               \n\t"
-    " ldr  r0, [r6], #4               \n\t" /* odd samples volumes */
-    " ldrh r2, [%0]                   \n\t" 
-
-    " smulwb r0, r0, r2               \n\t"
-    " ssat r0, #16, r0                \n\t"
-    
-    " strh r0, [%0], #2               \n\t"
-
-    MOD_INC()
-
-    "2:                               \n\t"
-    " mov %3, %3, LSR #1              \n\t" 
-    " tst %3, #1                      \n\t" /* check for odd samples */
-    " beq  4f                         \n\t" 
-
-    "3:                               \n\t"
-    " ldrd r2, [r6], #8               \n\t" /* 2 samples at a time */
-    " ldr  r0, [%0]                   \n\t"
-
-    " smulwt r2, r2, r0               \n\t"
-    " smulwb r3, r3, r0               \n\t"
-
-    " ssat r2, #16, r2                \n\t"
-    " ssat r3, #16, r3                \n\t"
-    
-    " pkhbt r0, r3, r2, LSL #16       \n\t"
-    " str  r0, [%0], #4               \n\t"
-
-    MOD_INC()
-
-    "4:                               \n\t"
-    " movs %3, %3, LSR #1             \n\t" 
-    " beq  6f                         \n\t" 
-
-    "5:                               \n\t"
-    " ldrd r2, [r6], #8               \n\t" /* 4 samples at a time */
-    " ldrd r4, [r6], #8               \n\t"
-    " ldrd r0, [%0]                   \n\t"
-
-    " smulwt r2, r2, r0               \n\t"
-    " smulwb r3, r3, r0               \n\t"
-    " smulwt r4, r4, r1               \n\t"
-    " smulwb r5, r5, r1               \n\t"
-
-    " ssat r2, #16, r2                \n\t"
-    " ssat r3, #16, r3                \n\t"
-    " ssat r4, #16, r4                \n\t"
-    " ssat r5, #16, r5                \n\t"
-    
-    " pkhbt r0, r3, r2, LSL #16       \n\t"
-    " pkhbt r1, r5, r4, LSL #16       \n\t"
-    " strd  r0, [%0], #8              \n\t"
-
-    MOD_INC()
-    
-    " subs %3, %3, #1                 \n\t"
-    " bne 5b                          \n\t"
-    "6:                               \n\t"
-
-    : "+r" (samples), "+r" (volumes), "+r" (ve), "+r" (length)
-    :
-    : "r6", "r5", "r4", "r3", "r2", "r1", "r0", "cc"
-  );
+    int32_t *ve;
+
+    channels = MAX (4, channels);
+    ve = volumes + channels;
+
+    __asm__ __volatile__ (
+        " mov r6, %1                      \n\t"
+        " mov %3, %3, LSR #1              \n\t" /* length /= sizeof (int16_t) */
+        " tst %3, #1                      \n\t" /* check for odd samples */
+        " beq  2f                         \n\t"
+
+        "1:                               \n\t"
+        " ldr  r0, [r6], #4               \n\t" /* odd samples volumes */
+        " ldrh r2, [%0]                   \n\t"
+
+        " smulwb r0, r0, r2               \n\t"
+        " ssat r0, #16, r0                \n\t"
+
+        " strh r0, [%0], #2               \n\t"
+
+        MOD_INC()
+
+        "2:                               \n\t"
+        " mov %3, %3, LSR #1              \n\t"
+        " tst %3, #1                      \n\t" /* check for odd samples */
+        " beq  4f                         \n\t"
+
+        "3:                               \n\t"
+        " ldrd r2, [r6], #8               \n\t" /* 2 samples at a time */
+        " ldr  r0, [%0]                   \n\t"
+
+        " smulwt r2, r2, r0               \n\t"
+        " smulwb r3, r3, r0               \n\t"
+
+        " ssat r2, #16, r2                \n\t"
+        " ssat r3, #16, r3                \n\t"
+
+        " pkhbt r0, r3, r2, LSL #16       \n\t"
+        " str  r0, [%0], #4               \n\t"
+
+        MOD_INC()
+
+        "4:                               \n\t"
+        " movs %3, %3, LSR #1             \n\t"
+        " beq  6f                         \n\t"
+
+        "5:                               \n\t"
+        " ldrd r2, [r6], #8               \n\t" /* 4 samples at a time */
+        " ldrd r4, [r6], #8               \n\t"
+        " ldrd r0, [%0]                   \n\t"
+
+        " smulwt r2, r2, r0               \n\t"
+        " smulwb r3, r3, r0               \n\t"
+        " smulwt r4, r4, r1               \n\t"
+        " smulwb r5, r5, r1               \n\t"
+
+        " ssat r2, #16, r2                \n\t"
+        " ssat r3, #16, r3                \n\t"
+        " ssat r4, #16, r4                \n\t"
+        " ssat r5, #16, r5                \n\t"
+
+        " pkhbt r0, r3, r2, LSL #16       \n\t"
+        " pkhbt r1, r5, r4, LSL #16       \n\t"
+        " strd  r0, [%0], #8              \n\t"
+
+        MOD_INC()
+
+        " subs %3, %3, #1                 \n\t"
+        " bne 5b                          \n\t"
+        "6:                               \n\t"
+
+        : "+r" (samples), "+r" (volumes), "+r" (ve), "+r" (length)
+        :
+        : "r6", "r5", "r4", "r3", "r2", "r1", "r0", "cc"
+    );
 }
 
 #undef RUN_TEST
@@ -131,51 +131,51 @@ pa_volume_s16ne_arm (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 #define PADDING 16
 
 static void run_test (void) {
-  int16_t samples[SAMPLES];
-  int16_t samples_ref[SAMPLES];
-  int16_t samples_orig[SAMPLES];
-  int32_t volumes[CHANNELS + PADDING];
-  int i, j, padding;
-  pa_do_volume_func_t func;
-  struct timeval start, stop;
-
-  func = pa_get_volume_func (PA_SAMPLE_S16NE);
-
-  printf ("checking ARM %zd\n", sizeof (samples));
-
-  pa_random (samples, sizeof (samples));
-  memcpy (samples_ref, samples, sizeof (samples));
-  memcpy (samples_orig, samples, sizeof (samples));
-
-  for (i = 0; i < CHANNELS; i++)
-    volumes[i] = rand() >> 1;
-  for (padding = 0; padding < PADDING; padding++, i++)
-    volumes[i] = volumes[padding];
-
-  func (samples_ref, volumes, CHANNELS, sizeof (samples));
-  pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
-  for (i = 0; i < SAMPLES; i++) {
-    if (samples[i] != samples_ref[i]) {
-      printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
-          samples_orig[i], volumes[i % CHANNELS]);
-    }
-  }
+    int16_t samples[SAMPLES];
+    int16_t samples_ref[SAMPLES];
+    int16_t samples_orig[SAMPLES];
+    int32_t volumes[CHANNELS + PADDING];
+    int i, j, padding;
+    pa_do_volume_func_t func;
+    struct timeval start, stop;
 
-  pa_gettimeofday(&start);
-  for (j = 0; j < TIMES; j++) {
-    memcpy (samples, samples_orig, sizeof (samples));
-    pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
-  }
-  pa_gettimeofday(&stop);
-  pa_log_info("ARM: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    func = pa_get_volume_func (PA_SAMPLE_S16NE);
+
+    printf ("checking ARM %zd\n", sizeof (samples));
+
+    pa_random (samples, sizeof (samples));
+    memcpy (samples_ref, samples, sizeof (samples));
+    memcpy (samples_orig, samples, sizeof (samples));
+
+    for (i = 0; i < CHANNELS; i++)
+        volumes[i] = rand() >> 1;
+    for (padding = 0; padding < PADDING; padding++, i++)
+        volumes[i] = volumes[padding];
 
-  pa_gettimeofday(&start);
-  for (j = 0; j < TIMES; j++) {
-    memcpy (samples_ref, samples_orig, sizeof (samples));
     func (samples_ref, volumes, CHANNELS, sizeof (samples));
-  }
-  pa_gettimeofday(&stop);
-  pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
+    for (i = 0; i < SAMPLES; i++) {
+        if (samples[i] != samples_ref[i]) {
+            printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+                  samples_orig[i], volumes[i % CHANNELS]);
+        }
+    }
+
+    pa_gettimeofday(&start);
+    for (j = 0; j < TIMES; j++) {
+        memcpy (samples, samples_orig, sizeof (samples));
+        pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
+    }
+    pa_gettimeofday(&stop);
+    pa_log_info("ARM: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+
+    pa_gettimeofday(&start);
+    for (j = 0; j < TIMES; j++) {
+        memcpy (samples_ref, samples_orig, sizeof (samples));
+        func (samples_ref, volumes, CHANNELS, sizeof (samples));
+    }
+    pa_gettimeofday(&stop);
+    pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
 }
 #endif
 
@@ -184,12 +184,12 @@ static void run_test (void) {
 
 void pa_volume_func_init_arm (pa_cpu_arm_flag_t flags) {
 #if defined (__arm__)
-  pa_log_info("Initialising ARM optimized functions.");
+    pa_log_info("Initialising ARM optimized functions.");
 
 #ifdef RUN_TEST
-  run_test ();
+    run_test ();
 #endif
 
-  pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_arm);
+    pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_arm);
 #endif /* defined (__arm__) */
 }
diff --git a/src/pulsecore/svolume_c.c b/src/pulsecore/svolume_c.c
index 2148a57..5fc052b 100644
--- a/src/pulsecore/svolume_c.c
+++ b/src/pulsecore/svolume_c.c
@@ -35,289 +35,289 @@
 static void
 pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
+    for (channel = 0; length; length--) {
+        int32_t t, hi, lo;
 
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
+        hi = volumes[channel] >> 16;
+        lo = volumes[channel] & 0xFFFF;
 
-    t = (int32_t) *samples - 0x80;
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
-    *samples++ = (uint8_t) (t + 0x80);
+        t = (int32_t) *samples - 0x80;
+        t = ((t * lo) >> 16) + (t * hi);
+        t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
+        *samples++ = (uint8_t) (t + 0x80);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
+    for (channel = 0; length; length--) {
+        int32_t t, hi, lo;
 
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
+        hi = volumes[channel] >> 16;
+        lo = volumes[channel] & 0xFFFF;
 
-    t = (int32_t) st_alaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
+        t = (int32_t) st_alaw2linear16(*samples);
+        t = ((t * lo) >> 16) + (t * hi);
+        t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+        *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
+    for (channel = 0; length; length--) {
+        int32_t t, hi, lo;
 
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
+        hi = volumes[channel] >> 16;
+        lo = volumes[channel] & 0xFFFF;
 
-    t = (int32_t) st_ulaw2linear16(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
+        t = (int32_t) st_ulaw2linear16(*samples);
+        t = ((t * lo) >> 16) + (t * hi);
+        t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+        *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (int16_t);
+    length /= sizeof (int16_t);
 
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
+    for (channel = 0; length; length--) {
+        int32_t t, hi, lo;
 
-    /* Multiplying the 32bit volume factor with the 16bit
-     * sample might result in an 48bit value. We want to
-     * do without 64 bit integers and hence do the
-     * multiplication independantly for the HI and LO part
-     * of the volume. */
+        /* Multiplying the 32bit volume factor with the 16bit
+         * sample might result in an 48bit value. We want to
+         * do without 64 bit integers and hence do the
+         * multiplication independantly for the HI and LO part
+         * of the volume. */
 
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
+        hi = volumes[channel] >> 16;
+        lo = volumes[channel] & 0xFFFF;
 
-    t = (int32_t)(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = (int16_t) t;
+        t = (int32_t)(*samples);
+        t = ((t * lo) >> 16) + (t * hi);
+        t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+        *samples++ = (int16_t) t;
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (int16_t);
+    length /= sizeof (int16_t);
 
-  for (channel = 0; length; length--) {
-    int32_t t, hi, lo;
+    for (channel = 0; length; length--) {
+        int32_t t, hi, lo;
 
-    hi = volumes[channel] >> 16;
-    lo = volumes[channel] & 0xFFFF;
+        hi = volumes[channel] >> 16;
+        lo = volumes[channel] & 0xFFFF;
 
-    t = (int32_t) PA_INT16_SWAP(*samples);
-    t = ((t * lo) >> 16) + (t * hi);
-    t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
-    *samples++ = PA_INT16_SWAP((int16_t) t);
+        t = (int32_t) PA_INT16_SWAP(*samples);
+        t = ((t * lo) >> 16) + (t * hi);
+        t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
+        *samples++ = PA_INT16_SWAP((int16_t) t);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (float);
+    length /= sizeof (float);
 
-  for (channel = 0; length; length--) {
-    *samples++ *= volumes[channel];
+    for (channel = 0; length; length--) {
+        *samples++ *= volumes[channel];
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (float);
+    length /= sizeof (float);
 
-  for (channel = 0; length; length--) {
-    float t;
+    for (channel = 0; length; length--) {
+        float t;
 
-    t = PA_FLOAT32_SWAP(*samples);
-    t *= volumes[channel];
-    *samples++ = PA_FLOAT32_SWAP(t);
+        t = PA_FLOAT32_SWAP(*samples);
+        t *= volumes[channel];
+        *samples++ = PA_FLOAT32_SWAP(t);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (int32_t);
+    length /= sizeof (int32_t);
 
-  for (channel = 0; length; length--) {
-    int64_t t;
+    for (channel = 0; length; length--) {
+        int64_t t;
 
-    t = (int64_t)(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = (int32_t) t;
+        t = (int64_t)(*samples);
+        t = (t * volumes[channel]) >> 16;
+        t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+        *samples++ = (int32_t) t;
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (int32_t);
+    length /= sizeof (int32_t);
 
-  for (channel = 0; length; length--) {
-    int64_t t;
+    for (channel = 0; length; length--) {
+        int64_t t;
 
-    t = (int64_t) PA_INT32_SWAP(*samples);
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_INT32_SWAP((int32_t) t);
+        t = (int64_t) PA_INT32_SWAP(*samples);
+        t = (t * volumes[channel]) >> 16;
+        t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+        *samples++ = PA_INT32_SWAP((int32_t) t);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
-  uint8_t *e;
+    unsigned channel;
+    uint8_t *e;
 
-  e = samples + length;
+    e = samples + length;
 
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
+    for (channel = 0; samples < e; samples += 3) {
+        int64_t t;
 
-    t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
+        t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
+        t = (t * volumes[channel]) >> 16;
+        t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+        PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
-  uint8_t *e;
+    unsigned channel;
+    uint8_t *e;
 
-  e = samples + length;
+    e = samples + length;
 
-  for (channel = 0; samples < e; samples += 3) {
-    int64_t t;
+    for (channel = 0; samples < e; samples += 3) {
+        int64_t t;
 
-    t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
+        t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
+        t = (t * volumes[channel]) >> 16;
+        t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+        PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (uint32_t);
+    length /= sizeof (uint32_t);
 
-  for (channel = 0; length; length--) {
-    int64_t t;
+    for (channel = 0; length; length--) {
+        int64_t t;
 
-    t = (int64_t) ((int32_t) (*samples << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
+        t = (int64_t) ((int32_t) (*samples << 8));
+        t = (t * volumes[channel]) >> 16;
+        t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+        *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static void
 pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
 {
-  unsigned channel;
+    unsigned channel;
 
-  length /= sizeof (uint32_t);
+    length /= sizeof (uint32_t);
 
-  for (channel = 0; length; length--) {
-    int64_t t;
+    for (channel = 0; length; length--) {
+        int64_t t;
 
-    t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
-    t = (t * volumes[channel]) >> 16;
-    t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
-    *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
+        t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
+        t = (t * volumes[channel]) >> 16;
+        t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
+        *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
 
-    if (PA_UNLIKELY(++channel >= channels))
-      channel = 0;
-  }
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
 }
 
 static pa_do_volume_func_t do_volume_table[] =
 {
-  [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
-  [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
-  [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
-  [PA_SAMPLE_S16NE]     = (pa_do_volume_func_t) pa_volume_s16ne_c,
-  [PA_SAMPLE_S16RE]     = (pa_do_volume_func_t) pa_volume_s16re_c,
-  [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
-  [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
-  [PA_SAMPLE_S32NE]     = (pa_do_volume_func_t) pa_volume_s32ne_c,
-  [PA_SAMPLE_S32RE]     = (pa_do_volume_func_t) pa_volume_s32re_c,
-  [PA_SAMPLE_S24NE]     = (pa_do_volume_func_t) pa_volume_s24ne_c,
-  [PA_SAMPLE_S24RE]     = (pa_do_volume_func_t) pa_volume_s24re_c,
-  [PA_SAMPLE_S24_32NE]  = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
-  [PA_SAMPLE_S24_32RE]  = (pa_do_volume_func_t) pa_volume_s24_32re_c
+    [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
+    [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
+    [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
+    [PA_SAMPLE_S16NE]     = (pa_do_volume_func_t) pa_volume_s16ne_c,
+    [PA_SAMPLE_S16RE]     = (pa_do_volume_func_t) pa_volume_s16re_c,
+    [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
+    [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
+    [PA_SAMPLE_S32NE]     = (pa_do_volume_func_t) pa_volume_s32ne_c,
+    [PA_SAMPLE_S32RE]     = (pa_do_volume_func_t) pa_volume_s32re_c,
+    [PA_SAMPLE_S24NE]     = (pa_do_volume_func_t) pa_volume_s24ne_c,
+    [PA_SAMPLE_S24RE]     = (pa_do_volume_func_t) pa_volume_s24re_c,
+    [PA_SAMPLE_S24_32NE]  = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
+    [PA_SAMPLE_S24_32RE]  = (pa_do_volume_func_t) pa_volume_s24_32re_c
 };
 
 pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f) {
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 86af76d..7e24268 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -73,7 +73,7 @@
       " add "#a", %3                 \n\t" \
       " mov %3, %4                   \n\t" \
       " sub "#b", %4                 \n\t" \
-      " cmovae %4, %3                \n\t" 
+      " cmovae %4, %3                \n\t"
 
 /* swap 16 bits */
 #define SWAP_16(s) \
@@ -96,147 +96,147 @@
 static void
 pa_volume_s16ne_mmx (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 = MAX (4, channels);
-
-  __asm__ __volatile__ (
-    " xor %3, %3                    \n\t"
-    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
-    " pcmpeqw %%mm6, %%mm6          \n\t" /* .. |  ffff |  ffff | */
-    " pcmpeqw %%mm7, %%mm7          \n\t" /* .. |  ffff |  ffff | */
-    " pslld  $16, %%mm6             \n\t" /* .. |  ffff |     0 | */
-    " psrld  $31, %%mm7             \n\t" /* .. |     0 |     1 | */
-
-    " test $1, %2                   \n\t" /* check for odd samples */
-    " je 2f                         \n\t" 
-
-    " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
-    " movd %4, %%mm1                \n\t" 
-    VOLUME_32x16 (%%mm1, %%mm0)
-    " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
-    " movw %w4, (%0)                \n\t" 
-    " add $2, %0                    \n\t"
-    MOD_ADD ($1, %5)
-
-    "2:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
-    " test $1, %2                   \n\t" /* check for odd samples */
-    " je 4f                         \n\t" 
-
-    "3:                             \n\t" /* do samples in groups of 2 */
-    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
-    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */ 
-    VOLUME_32x16 (%%mm1, %%mm0)
-    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
-    " add $4, %0                    \n\t"
-    MOD_ADD ($2, %5)
-
-    "4:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
-    " cmp $0, %2                    \n\t"
-    " je 6f                         \n\t"
-
-    "5:                             \n\t" /* do samples in groups of 4 */
-    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */ 
-    " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
-    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
-    " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
-    VOLUME_32x16 (%%mm1, %%mm0)
-    VOLUME_32x16 (%%mm3, %%mm2)
-    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
-    " movd %%mm2, 4(%0)             \n\t" /*              .. | p3*v3 | p2*v2 | */
-    " add $8, %0                    \n\t"
-    MOD_ADD ($4, %5)
-    " dec %2                        \n\t"
-    " jne 5b                        \n\t"
-
-    "6:                             \n\t"
-    " emms                          \n\t"
-
-    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
-    : "r" ((pa_reg_x86)channels)
-    : "cc"
-  );
+    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 = MAX (4, channels);
+
+    __asm__ __volatile__ (
+        " xor %3, %3                    \n\t"
+        " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+        " pcmpeqw %%mm6, %%mm6          \n\t" /* .. |  ffff |  ffff | */
+        " pcmpeqw %%mm7, %%mm7          \n\t" /* .. |  ffff |  ffff | */
+        " pslld  $16, %%mm6             \n\t" /* .. |  ffff |     0 | */
+        " psrld  $31, %%mm7             \n\t" /* .. |     0 |     1 | */
+
+        " test $1, %2                   \n\t" /* check for odd samples */
+        " je 2f                         \n\t"
+
+        " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
+        " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
+        " movd %4, %%mm1                \n\t"
+        VOLUME_32x16 (%%mm1, %%mm0)
+        " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
+        " movw %w4, (%0)                \n\t"
+        " add $2, %0                    \n\t"
+        MOD_ADD ($1, %5)
+
+        "2:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+        " test $1, %2                   \n\t" /* check for odd samples */
+        " je 4f                         \n\t"
+
+        "3:                             \n\t" /* do samples in groups of 2 */
+        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
+        VOLUME_32x16 (%%mm1, %%mm0)
+        " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
+        " add $4, %0                    \n\t"
+        MOD_ADD ($2, %5)
+
+        "4:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+        " cmp $0, %2                    \n\t"
+        " je 6f                         \n\t"
+
+        "5:                             \n\t" /* do samples in groups of 4 */
+        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
+        " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
+        " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
+        VOLUME_32x16 (%%mm1, %%mm0)
+        VOLUME_32x16 (%%mm3, %%mm2)
+        " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
+        " movd %%mm2, 4(%0)             \n\t" /*              .. | p3*v3 | p2*v2 | */
+        " add $8, %0                    \n\t"
+        MOD_ADD ($4, %5)
+        " dec %2                        \n\t"
+        " jne 5b                        \n\t"
+
+        "6:                             \n\t"
+        " emms                          \n\t"
+
+        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
+        : "r" ((pa_reg_x86)channels)
+        : "cc"
+    );
 }
 
 static void
 pa_volume_s16re_mmx (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 = MAX (4, channels);
-
-  __asm__ __volatile__ (
-    " xor %3, %3                    \n\t"
-    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
-    " pcmpeqw %%mm6, %%mm6          \n\t" /* .. |  ffff |  ffff | */
-    " pcmpeqw %%mm7, %%mm7          \n\t" /* .. |  ffff |  ffff | */
-    " pslld  $16, %%mm6             \n\t" /* .. |  ffff |     0 | */
-    " psrld  $31, %%mm7             \n\t" /* .. |     0 |     1 | */
-
-    " test $1, %2                   \n\t" /* check for odd samples */
-    " je 2f                         \n\t" 
-
-    " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
-    " rorw $8, %w4                  \n\t"
-    " movd %4, %%mm1                \n\t" 
-    VOLUME_32x16 (%%mm1, %%mm0)
-    " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
-    " rorw $8, %w4                  \n\t"
-    " movw %w4, (%0)                \n\t" 
-    " add $2, %0                    \n\t"
-    MOD_ADD ($1, %5)
-
-    "2:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
-    " test $1, %2                   \n\t" /* check for odd samples */
-    " je 4f                         \n\t" 
-
-    "3:                             \n\t" /* do samples in groups of 2 */
-    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
-    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */ 
-    SWAP_16 (%%mm1)
-    VOLUME_32x16 (%%mm1, %%mm0)
-    SWAP_16 (%%mm0)
-    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
-    " add $4, %0                    \n\t"
-    MOD_ADD ($2, %5)
-
-    "4:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
-    " cmp $0, %2                    \n\t"
-    " je 6f                         \n\t"
-
-    "5:                             \n\t" /* do samples in groups of 4 */
-    " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */ 
-    " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
-    " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
-    " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
-    SWAP_16_2 (%%mm1, %%mm3)
-    VOLUME_32x16 (%%mm1, %%mm0)
-    VOLUME_32x16 (%%mm3, %%mm2)
-    SWAP_16_2 (%%mm0, %%mm2)
-    " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
-    " movd %%mm2, 4(%0)             \n\t" /*              .. | p3*v3 | p2*v2 | */
-    " add $8, %0                    \n\t"
-    MOD_ADD ($4, %5)
-    " dec %2                        \n\t"
-    " jne 5b                        \n\t"
-
-    "6:                             \n\t"
-    " emms                          \n\t"
-
-    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
-    : "r" ((pa_reg_x86)channels)
-    : "cc"
-  );
+    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 = MAX (4, channels);
+
+    __asm__ __volatile__ (
+        " xor %3, %3                    \n\t"
+        " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+        " pcmpeqw %%mm6, %%mm6          \n\t" /* .. |  ffff |  ffff | */
+        " pcmpeqw %%mm7, %%mm7          \n\t" /* .. |  ffff |  ffff | */
+        " pslld  $16, %%mm6             \n\t" /* .. |  ffff |     0 | */
+        " psrld  $31, %%mm7             \n\t" /* .. |     0 |     1 | */
+
+        " test $1, %2                   \n\t" /* check for odd samples */
+        " je 2f                         \n\t"
+
+        " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
+        " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
+        " rorw $8, %w4                  \n\t"
+        " movd %4, %%mm1                \n\t"
+        VOLUME_32x16 (%%mm1, %%mm0)
+        " movd %%mm0, %4                \n\t" /*     ..  | p0*v0 | */
+        " rorw $8, %w4                  \n\t"
+        " movw %w4, (%0)                \n\t"
+        " add $2, %0                    \n\t"
+        MOD_ADD ($1, %5)
+
+        "2:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+        " test $1, %2                   \n\t" /* check for odd samples */
+        " je 4f                         \n\t"
+
+        "3:                             \n\t" /* do samples in groups of 2 */
+        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
+        SWAP_16 (%%mm1)
+        VOLUME_32x16 (%%mm1, %%mm0)
+        SWAP_16 (%%mm0)
+        " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
+        " add $4, %0                    \n\t"
+        MOD_ADD ($2, %5)
+
+        "4:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+        " cmp $0, %2                    \n\t"
+        " je 6f                         \n\t"
+
+        "5:                             \n\t" /* do samples in groups of 4 */
+        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
+        " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
+        " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
+        SWAP_16_2 (%%mm1, %%mm3)
+        VOLUME_32x16 (%%mm1, %%mm0)
+        VOLUME_32x16 (%%mm3, %%mm2)
+        SWAP_16_2 (%%mm0, %%mm2)
+        " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
+        " movd %%mm2, 4(%0)             \n\t" /*              .. | p3*v3 | p2*v2 | */
+        " add $8, %0                    \n\t"
+        MOD_ADD ($4, %5)
+        " dec %2                        \n\t"
+        " jne 5b                        \n\t"
+
+        "6:                             \n\t"
+        " emms                          \n\t"
+
+        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
+        : "r" ((pa_reg_x86)channels)
+        : "cc"
+    );
 }
 
 #undef RUN_TEST
@@ -248,51 +248,51 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 #define PADDING 16
 
 static void run_test (void) {
-  int16_t samples[SAMPLES];
-  int16_t samples_ref[SAMPLES];
-  int16_t samples_orig[SAMPLES];
-  int32_t volumes[CHANNELS + PADDING];
-  int i, j, padding;
-  pa_do_volume_func_t func;
-  struct timeval start, stop;
-
-  func = pa_get_volume_func (PA_SAMPLE_S16NE);
-
-  printf ("checking MMX %zd\n", sizeof (samples));
-
-  pa_random (samples, sizeof (samples));
-  memcpy (samples_ref, samples, sizeof (samples));
-  memcpy (samples_orig, samples, sizeof (samples));
-
-  for (i = 0; i < CHANNELS; i++)
-    volumes[i] = rand() >> 1;
-  for (padding = 0; padding < PADDING; padding++, i++)
-    volumes[i] = volumes[padding];
-
-  func (samples_ref, volumes, CHANNELS, sizeof (samples));
-  pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
-  for (i = 0; i < SAMPLES; i++) {
-    if (samples[i] != samples_ref[i]) {
-      printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
-          samples_orig[i], volumes[i % CHANNELS]);
-    }
-  }
+    int16_t samples[SAMPLES];
+    int16_t samples_ref[SAMPLES];
+    int16_t samples_orig[SAMPLES];
+    int32_t volumes[CHANNELS + PADDING];
+    int i, j, padding;
+    pa_do_volume_func_t func;
+    struct timeval start, stop;
 
-  pa_gettimeofday(&start);
-  for (j = 0; j < TIMES; j++) {
-    memcpy (samples, samples_orig, sizeof (samples));
-    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
-  }
-  pa_gettimeofday(&stop);
-  pa_log_info("MMX: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    func = pa_get_volume_func (PA_SAMPLE_S16NE);
+
+    printf ("checking MMX %zd\n", sizeof (samples));
+
+    pa_random (samples, sizeof (samples));
+    memcpy (samples_ref, samples, sizeof (samples));
+    memcpy (samples_orig, samples, sizeof (samples));
+
+    for (i = 0; i < CHANNELS; i++)
+        volumes[i] = rand() >> 1;
+    for (padding = 0; padding < PADDING; padding++, i++)
+        volumes[i] = volumes[padding];
 
-  pa_gettimeofday(&start);
-  for (j = 0; j < TIMES; j++) {
-    memcpy (samples_ref, samples_orig, sizeof (samples));
     func (samples_ref, volumes, CHANNELS, sizeof (samples));
-  }
-  pa_gettimeofday(&stop);
-  pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
+    for (i = 0; i < SAMPLES; i++) {
+        if (samples[i] != samples_ref[i]) {
+            printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+                  samples_orig[i], volumes[i % CHANNELS]);
+        }
+    }
+
+    pa_gettimeofday(&start);
+    for (j = 0; j < TIMES; j++) {
+        memcpy (samples, samples_orig, sizeof (samples));
+        pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
+    }
+    pa_gettimeofday(&stop);
+    pa_log_info("MMX: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+
+    pa_gettimeofday(&start);
+    for (j = 0; j < TIMES; j++) {
+        memcpy (samples_ref, samples_orig, sizeof (samples));
+        func (samples_ref, volumes, CHANNELS, sizeof (samples));
+    }
+    pa_gettimeofday(&stop);
+    pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
 }
 #endif
 
@@ -301,13 +301,13 @@ static void run_test (void) {
 
 void pa_volume_func_init_mmx (pa_cpu_x86_flag_t flags) {
 #if defined (__i386__) || defined (__amd64__)
-  pa_log_info("Initialising MMX optimized functions.");
+    pa_log_info("Initialising MMX optimized functions.");
 
 #ifdef RUN_TEST
-  run_test ();
+    run_test ();
 #endif
 
-  pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_mmx);
-  pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_mmx);
+    pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_mmx);
+    pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_mmx);
 #endif /* defined (__i386__) || defined (__amd64__) */
 }
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 5979f7c..b5e3687 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -48,7 +48,7 @@
       " psrld $16, "#v"              \n\t" /* .. |   p0  |    0  | */                   \
       " pmaddwd %%xmm5, "#v"         \n\t" /* .. |    p0 * vh    | */                   \
       " paddd "#s", "#v"             \n\t" /* .. |    p0 * v0    | */                   \
-      " packssdw "#v", "#v"          \n\t" /* .. | p1*v1 | p0*v0 | */         
+      " packssdw "#v", "#v"          \n\t" /* .. | p1*v1 | p0*v0 | */
 
 #define MOD_ADD(a,b) \
       " add "#a", %3                 \n\t" /* channel += inc           */ \
@@ -77,169 +77,169 @@
 static void
 pa_volume_s16ne_sse (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 = MAX (8, channels);
-
-  __asm__ __volatile__ (
-    " xor %3, %3                    \n\t"
-    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
-
-    " test $1, %2                   \n\t" /* check for odd samples */
-    " je 2f                         \n\t" 
-
-    " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
-    " movd %4, %%xmm1               \n\t" 
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
-    " movw %w4, (%0)                \n\t" 
-    " add $2, %0                    \n\t"
-    MOD_ADD ($1, %5)
-
-    "2:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
-    " test $1, %2                   \n\t" 
-    " je 4f                         \n\t" 
-
-    "3:                             \n\t" /* do samples in groups of 2 */
-    " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
-    " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    " movd %%xmm0, (%0)             \n\t" /*              .. | p1*v1 | p0*v0 | */
-    " add $4, %0                    \n\t"
-    MOD_ADD ($2, %5)
-
-    "4:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
-    " test $1, %2                   \n\t" 
-    " je 6f                         \n\t" 
-
-    /* FIXME, we can do aligned access of the volume values if we can guarantee
-     * that the array is 16 bytes aligned, we probably have to do the odd values
-     * after this then. */
-    "5:                             \n\t" /* do samples in groups of 4 */
-    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
-    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
-    " add $8, %0                    \n\t"
-    MOD_ADD ($4, %5)
-
-    "6:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 8 samples at a time */
-    " cmp $0, %2                    \n\t"
-    " je 8f                         \n\t"
-
-    "7:                             \n\t" /* do samples in groups of 8 */
-    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
-    " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
-    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
-    " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    VOLUME_32x16 (%%xmm3, %%xmm2)
-    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
-    " movq %%xmm2, 8(%0)            \n\t" /*              .. | p7*v7 .. p4*v4 | */
-    " add $16, %0                   \n\t"
-    MOD_ADD ($8, %5)
-    " dec %2                        \n\t"
-    " jne 7b                        \n\t"
-    "8:                             \n\t"
-
-    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
-    : "r" ((pa_reg_x86)channels)
-    : "cc"
-  );
+    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 = MAX (8, channels);
+
+    __asm__ __volatile__ (
+        " xor %3, %3                    \n\t"
+        " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+
+        " test $1, %2                   \n\t" /* check for odd samples */
+        " je 2f                         \n\t"
+
+        " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
+        " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
+        " movd %4, %%xmm1               \n\t"
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
+        " movw %w4, (%0)                \n\t"
+        " add $2, %0                    \n\t"
+        MOD_ADD ($1, %5)
+
+        "2:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+        " test $1, %2                   \n\t"
+        " je 4f                         \n\t"
+
+        "3:                             \n\t" /* do samples in groups of 2 */
+        " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        " movd %%xmm0, (%0)             \n\t" /*              .. | p1*v1 | p0*v0 | */
+        " add $4, %0                    \n\t"
+        MOD_ADD ($2, %5)
+
+        "4:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+        " test $1, %2                   \n\t"
+        " je 6f                         \n\t"
+
+        /* FIXME, we can do aligned access of the volume values if we can guarantee
+         * that the array is 16 bytes aligned, we probably have to do the odd values
+         * after this then. */
+        "5:                             \n\t" /* do samples in groups of 4 */
+        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
+        " add $8, %0                    \n\t"
+        MOD_ADD ($4, %5)
+
+        "6:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 8 samples at a time */
+        " cmp $0, %2                    \n\t"
+        " je 8f                         \n\t"
+
+        "7:                             \n\t" /* do samples in groups of 8 */
+        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
+        " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
+        " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        VOLUME_32x16 (%%xmm3, %%xmm2)
+        " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
+        " movq %%xmm2, 8(%0)            \n\t" /*              .. | p7*v7 .. p4*v4 | */
+        " add $16, %0                   \n\t"
+        MOD_ADD ($8, %5)
+        " dec %2                        \n\t"
+        " jne 7b                        \n\t"
+        "8:                             \n\t"
+
+        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
+        : "r" ((pa_reg_x86)channels)
+        : "cc"
+    );
 }
 
 static void
 pa_volume_s16re_sse (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 = MAX (8, channels);
-
-  __asm__ __volatile__ (
-    " xor %3, %3                    \n\t"
-    " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
-
-    " test $1, %2                   \n\t" /* check for odd samples */
-    " je 2f                         \n\t" 
-
-    " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
-    " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
-    " rorw $8, %w4                  \n\t" 
-    " movd %4, %%xmm1               \n\t" 
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
-    " rorw $8, %w4                  \n\t" 
-    " movw %w4, (%0)                \n\t" 
-    " add $2, %0                    \n\t"
-    MOD_ADD ($1, %5)
-
-    "2:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
-    " test $1, %2                   \n\t"
-    " je 4f                         \n\t" 
-
-    "3:                             \n\t" /* do samples in groups of 2 */
-    " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
-    " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
-    SWAP_16 (%%xmm1)
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    SWAP_16 (%%xmm0)
-    " movd %%xmm0, (%0)             \n\t" /*              .. | p1*v1 | p0*v0 | */
-    " add $4, %0                    \n\t"
-    MOD_ADD ($2, %5)
-
-    "4:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
-    " test $1, %2                   \n\t"
-    " je 6f                         \n\t" 
-
-    /* FIXME, we can do aligned access of the volume values if we can guarantee
-     * that the array is 16 bytes aligned, we probably have to do the odd values
-     * after this then. */
-    "5:                             \n\t" /* do samples in groups of 4 */
-    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
-    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
-    SWAP_16 (%%xmm1)
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    SWAP_16 (%%xmm0)
-    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
-    " add $8, %0                    \n\t"
-    MOD_ADD ($4, %5)
-
-    "6:                             \n\t"
-    " sar $1, %2                    \n\t" /* prepare for processing 8 samples at a time */
-    " cmp $0, %2                    \n\t"
-    " je 8f                         \n\t"
-
-    "7:                             \n\t" /* do samples in groups of 8 */
-    " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
-    " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
-    " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
-    " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
-    SWAP_16_2 (%%xmm1, %%xmm3)
-    VOLUME_32x16 (%%xmm1, %%xmm0)
-    VOLUME_32x16 (%%xmm3, %%xmm2)
-    SWAP_16_2 (%%xmm0, %%xmm2)
-    " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
-    " movq %%xmm2, 8(%0)            \n\t" /*              .. | p7*v7 .. p4*v4 | */
-    " add $16, %0                   \n\t"
-    MOD_ADD ($8, %5)
-    " dec %2                        \n\t"
-    " jne 7b                        \n\t"
-    "8:                             \n\t"
-
-    : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
-    : "r" ((pa_reg_x86)channels)
-    : "cc"
-  );
+    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 = MAX (8, channels);
+
+    __asm__ __volatile__ (
+        " xor %3, %3                    \n\t"
+        " sar $1, %2                    \n\t" /* length /= sizeof (int16_t) */
+
+        " test $1, %2                   \n\t" /* check for odd samples */
+        " je 2f                         \n\t"
+
+        " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
+        " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
+        " rorw $8, %w4                  \n\t"
+        " movd %4, %%xmm1               \n\t"
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        " movd %%xmm0, %4               \n\t" /*     ..  | p0*v0 | */
+        " rorw $8, %w4                  \n\t"
+        " movw %w4, (%0)                \n\t"
+        " add $2, %0                    \n\t"
+        MOD_ADD ($1, %5)
+
+        "2:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 2 samples at a time */
+        " test $1, %2                   \n\t"
+        " je 4f                         \n\t"
+
+        "3:                             \n\t" /* do samples in groups of 2 */
+        " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
+        SWAP_16 (%%xmm1)
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        SWAP_16 (%%xmm0)
+        " movd %%xmm0, (%0)             \n\t" /*              .. | p1*v1 | p0*v0 | */
+        " add $4, %0                    \n\t"
+        MOD_ADD ($2, %5)
+
+        "4:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 4 samples at a time */
+        " test $1, %2                   \n\t"
+        " je 6f                         \n\t"
+
+        /* FIXME, we can do aligned access of the volume values if we can guarantee
+         * that the array is 16 bytes aligned, we probably have to do the odd values
+         * after this then. */
+        "5:                             \n\t" /* do samples in groups of 4 */
+        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
+        SWAP_16 (%%xmm1)
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        SWAP_16 (%%xmm0)
+        " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
+        " add $8, %0                    \n\t"
+        MOD_ADD ($4, %5)
+
+        "6:                             \n\t"
+        " sar $1, %2                    \n\t" /* prepare for processing 8 samples at a time */
+        " cmp $0, %2                    \n\t"
+        " je 8f                         \n\t"
+
+        "7:                             \n\t" /* do samples in groups of 8 */
+        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
+        " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
+        " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
+        SWAP_16_2 (%%xmm1, %%xmm3)
+        VOLUME_32x16 (%%xmm1, %%xmm0)
+        VOLUME_32x16 (%%xmm3, %%xmm2)
+        SWAP_16_2 (%%xmm0, %%xmm2)
+        " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
+        " movq %%xmm2, 8(%0)            \n\t" /*              .. | p7*v7 .. p4*v4 | */
+        " add $16, %0                   \n\t"
+        MOD_ADD ($8, %5)
+        " dec %2                        \n\t"
+        " jne 7b                        \n\t"
+        "8:                             \n\t"
+
+        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
+        : "r" ((pa_reg_x86)channels)
+        : "cc"
+    );
 }
 
 #undef RUN_TEST
@@ -251,64 +251,64 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 #define PADDING 16
 
 static void run_test (void) {
-  int16_t samples[SAMPLES];
-  int16_t samples_ref[SAMPLES];
-  int16_t samples_orig[SAMPLES];
-  int32_t volumes[CHANNELS + PADDING];
-  int i, j, padding;
-  pa_do_volume_func_t func;
-  struct timeval start, stop;
-
-  func = pa_get_volume_func (PA_SAMPLE_S16NE);
-
-  printf ("checking SSE %zd\n", sizeof (samples));
-
-  pa_random (samples, sizeof (samples));
-  memcpy (samples_ref, samples, sizeof (samples));
-  memcpy (samples_orig, samples, sizeof (samples));
-
-  for (i = 0; i < CHANNELS; i++)
-    volumes[i] = rand() >> 1;
-  for (padding = 0; padding < PADDING; padding++, i++)
-    volumes[i] = volumes[padding];
-
-  func (samples_ref, volumes, CHANNELS, sizeof (samples));
-  pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
-  for (i = 0; i < SAMPLES; i++) {
-    if (samples[i] != samples_ref[i]) {
-      printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
-              samples_orig[i], volumes[i % CHANNELS]);
-    }
-  }
+    int16_t samples[SAMPLES];
+    int16_t samples_ref[SAMPLES];
+    int16_t samples_orig[SAMPLES];
+    int32_t volumes[CHANNELS + PADDING];
+    int i, j, padding;
+    pa_do_volume_func_t func;
+    struct timeval start, stop;
 
-  pa_gettimeofday(&start);
-  for (j = 0; j < TIMES; j++) {
-    memcpy (samples, samples_orig, sizeof (samples));
-    pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
-  }
-  pa_gettimeofday(&stop);
-  pa_log_info("SSE: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    func = pa_get_volume_func (PA_SAMPLE_S16NE);
+
+    printf ("checking SSE %zd\n", sizeof (samples));
+
+    pa_random (samples, sizeof (samples));
+    memcpy (samples_ref, samples, sizeof (samples));
+    memcpy (samples_orig, samples, sizeof (samples));
+
+    for (i = 0; i < CHANNELS; i++)
+        volumes[i] = rand() >> 1;
+    for (padding = 0; padding < PADDING; padding++, i++)
+        volumes[i] = volumes[padding];
 
-  pa_gettimeofday(&start);
-  for (j = 0; j < TIMES; j++) {
-    memcpy (samples_ref, samples_orig, sizeof (samples));
     func (samples_ref, volumes, CHANNELS, sizeof (samples));
-  }
-  pa_gettimeofday(&stop);
-  pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
+    for (i = 0; i < SAMPLES; i++) {
+        if (samples[i] != samples_ref[i]) {
+            printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+                      samples_orig[i], volumes[i % CHANNELS]);
+        }
+    }
+
+    pa_gettimeofday(&start);
+    for (j = 0; j < TIMES; j++) {
+        memcpy (samples, samples_orig, sizeof (samples));
+        pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
+    }
+    pa_gettimeofday(&stop);
+    pa_log_info("SSE: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+
+    pa_gettimeofday(&start);
+    for (j = 0; j < TIMES; j++) {
+        memcpy (samples_ref, samples_orig, sizeof (samples));
+        func (samples_ref, volumes, CHANNELS, sizeof (samples));
+    }
+    pa_gettimeofday(&stop);
+    pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
 }
 #endif
 #endif /* defined (__i386__) || defined (__amd64__) */
 
 void pa_volume_func_init_sse (pa_cpu_x86_flag_t flags) {
 #if defined (__i386__) || defined (__amd64__)
-  pa_log_info("Initialising SSE optimized functions.");
+    pa_log_info("Initialising SSE optimized functions.");
 
 #ifdef RUN_TEST
-  run_test ();
+    run_test ();
 #endif
 
-  pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_sse);
-  pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_sse);
+    pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_sse);
+    pa_set_volume_func (PA_SAMPLE_S16RE,     (pa_do_volume_func_t) pa_volume_s16re_sse);
 #endif /* defined (__i386__) || defined (__amd64__) */
 }

commit f8ffe0dabcedf56437c00feb895d7d7229971ba0
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 12:30:48 2009 +0200

    svolume: cleanups
    
    Use PA_MAX
    Use pa_rtclock_now() for benchmarks

diff --git a/src/pulsecore/svolume_arm.c b/src/pulsecore/svolume_arm.c
index 0d39d10..5bd1448 100644
--- a/src/pulsecore/svolume_arm.c
+++ b/src/pulsecore/svolume_arm.c
@@ -47,7 +47,7 @@ pa_volume_s16ne_arm (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 {
     int32_t *ve;
 
-    channels = MAX (4, channels);
+    channels = PA_MAX (4U, channels);
     ve = volumes + channels;
 
     __asm__ __volatile__ (
@@ -137,7 +137,7 @@ static void run_test (void) {
     int32_t volumes[CHANNELS + PADDING];
     int i, j, padding;
     pa_do_volume_func_t func;
-    struct timeval start, stop;
+    pa_usec_t start, stop;
 
     func = pa_get_volume_func (PA_SAMPLE_S16NE);
 
@@ -161,21 +161,21 @@ static void run_test (void) {
         }
     }
 
-    pa_gettimeofday(&start);
+    start = pa_rtclock_now();
     for (j = 0; j < TIMES; j++) {
         memcpy (samples, samples_orig, sizeof (samples));
         pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
     }
-    pa_gettimeofday(&stop);
-    pa_log_info("ARM: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    stop = pa_rtclock_now();
+    pa_log_info("ARM: %llu usec.", (long long unsigned int) (stop - start));
 
-    pa_gettimeofday(&start);
+    start = pa_rtclock_now();
     for (j = 0; j < TIMES; j++) {
         memcpy (samples_ref, samples_orig, sizeof (samples));
         func (samples_ref, volumes, CHANNELS, sizeof (samples));
     }
-    pa_gettimeofday(&stop);
-    pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    stop = pa_rtclock_now();
+    pa_log_info("ref: %llu usec.", (long long unsigned int) (stop - start));
 }
 #endif
 
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 7e24268..8510b0c 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -100,7 +100,7 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 
     /* 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 = MAX (4, channels);
+    channels = PA_MAX (4U, channels);
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -170,7 +170,7 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 
     /* 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 = MAX (4, channels);
+    channels = PA_MAX (4U, channels);
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -254,7 +254,7 @@ static void run_test (void) {
     int32_t volumes[CHANNELS + PADDING];
     int i, j, padding;
     pa_do_volume_func_t func;
-    struct timeval start, stop;
+    pa_usec_t start, stop;
 
     func = pa_get_volume_func (PA_SAMPLE_S16NE);
 
@@ -278,21 +278,21 @@ static void run_test (void) {
         }
     }
 
-    pa_gettimeofday(&start);
+    start = pa_rtclock_now();
     for (j = 0; j < TIMES; j++) {
         memcpy (samples, samples_orig, sizeof (samples));
         pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
     }
-    pa_gettimeofday(&stop);
-    pa_log_info("MMX: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    stop = pa_rtclock_now();
+    pa_log_info("MMX: %llu usec.", (long long unsigned int)(stop - start));
 
-    pa_gettimeofday(&start);
+    start = pa_rtclock_now();
     for (j = 0; j < TIMES; j++) {
         memcpy (samples_ref, samples_orig, sizeof (samples));
         func (samples_ref, volumes, CHANNELS, sizeof (samples));
     }
-    pa_gettimeofday(&stop);
-    pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    stop = pa_rtclock_now();
+    pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
 }
 #endif
 
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index b5e3687..54af4a5 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -81,7 +81,7 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 
     /* 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 = MAX (8, channels);
+    channels = PA_MAX (8U, channels);
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -161,7 +161,7 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
 
     /* 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 = MAX (8, channels);
+    channels = PA_MAX (8U, channels);
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -257,7 +257,7 @@ static void run_test (void) {
     int32_t volumes[CHANNELS + PADDING];
     int i, j, padding;
     pa_do_volume_func_t func;
-    struct timeval start, stop;
+    pa_usec_t start, stop;
 
     func = pa_get_volume_func (PA_SAMPLE_S16NE);
 
@@ -281,21 +281,21 @@ static void run_test (void) {
         }
     }
 
-    pa_gettimeofday(&start);
+    start = pa_rtclock_now();
     for (j = 0; j < TIMES; j++) {
         memcpy (samples, samples_orig, sizeof (samples));
         pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
     }
-    pa_gettimeofday(&stop);
-    pa_log_info("SSE: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    stop = pa_rtclock_now();
+    pa_log_info("SSE: %llu usec.", (long long unsigned int)(stop - start));
 
-    pa_gettimeofday(&start);
+    start = pa_rtclock_now();
     for (j = 0; j < TIMES; j++) {
         memcpy (samples_ref, samples_orig, sizeof (samples));
         func (samples_ref, volumes, CHANNELS, sizeof (samples));
     }
-    pa_gettimeofday(&stop);
-    pa_log_info("ref: %llu usec.", (long long unsigned int)pa_timeval_diff (&stop, &start));
+    stop = pa_rtclock_now();
+    pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
 }
 #endif
 #endif /* defined (__i386__) || defined (__amd64__) */

commit c1b6a87b27b569cda135da05b53cc98aa9ca37cb
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 13:40:27 2009 +0200

    alsa-sink: reduce the amount of smoother updates
    
    Exponentially increase the amount of time between smoother updates. We start
    with a 2ms interval and increase up to 200ms intervals.
    Smoother updates and the resulting linear regression take a fair amount of CPU
    so we want to reduce the amount of updates.

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index e3707ae..c369472 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -68,6 +68,9 @@
 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)               /* 10ms -- Sleep at least 10ms on each iteration */
 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)               /* 4ms  -- Wakeup at least this long before the buffer runs empty*/
 
+#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)                /* 2ms -- min smoother update interval */
+#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)              /* 200ms -- max smoother update inteval */
+
 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100)  /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */
 
 struct userdata {
@@ -115,6 +118,8 @@ struct userdata {
     pa_smoother *smoother;
     uint64_t write_count;
     uint64_t since_start;
+    pa_usec_t smoother_interval;
+    pa_usec_t last_smoother_update;
 
     pa_reserve_wrapper *reserve;
     pa_hook_slot *reserve_slot;
@@ -723,17 +728,27 @@ static void update_smoother(struct userdata *u) {
         now1 = pa_timespec_load(&htstamp);
     }
 
+    /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
+    if (now1 <= 0)
+        now1 = pa_rtclock_now();
+
+    /* check if the time since the last update is bigger than the interval */
+    if (u->last_smoother_update > 0) {
+        if (u->last_smoother_update + u->smoother_interval > now1)
+            return;
+    }
+
     position = (int64_t) u->write_count - ((int64_t) delay * (int64_t) u->frame_size);
 
     if (PA_UNLIKELY(position < 0))
         position = 0;
 
-    /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
-    if (now1 <= 0)
-        now1 = pa_rtclock_now();
-
     now2 = pa_bytes_to_usec((uint64_t) position, &u->sink->sample_spec);
 
+    u->last_smoother_update = now1;
+    /* exponentially increase the update interval up to the MAX limit */
+    u->smoother_interval = PA_MIN (u->smoother_interval * 2, SMOOTHER_MAX_INTERVAL);
+
     pa_smoother_put(u->smoother, now1, now2);
 }
 
@@ -906,6 +921,8 @@ static int unsuspend(struct userdata *u) {
 
     u->write_count = 0;
     pa_smoother_reset(u->smoother, pa_rtclock_now(), TRUE);
+    u->smoother_interval = SMOOTHER_MIN_INTERVAL;
+    u->last_smoother_update = 0;
 
     u->first = TRUE;
     u->since_start = 0;
@@ -1622,6 +1639,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
             5,
             pa_rtclock_now(),
             TRUE);
+    u->smoother_interval = SMOOTHER_MIN_INTERVAL;
 
     dev_id = pa_modargs_get_value(
             ma, "device_id",

commit 05fef5f551ac7f295d2f2cb74642cb359be1b12d
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 15:50:02 2009 +0200

    sconv: allow for setting custom functions
    
    Add methods to override the default conversion functions.

diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c
index 937bf5d..d06d698 100644
--- a/src/pulsecore/sconv.c
+++ b/src/pulsecore/sconv.c
@@ -184,98 +184,130 @@ static void alaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
         *b = st_13linear2alaw(*a >> 3);
 }
 
+static pa_convert_func_t to_float32ne_table[] = {
+    [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_to_float32ne,
+    [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_to_float32ne,
+    [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_to_float32ne,
+    [PA_SAMPLE_S16LE]     = (pa_convert_func_t) pa_sconv_s16le_to_float32ne,
+    [PA_SAMPLE_S16BE]     = (pa_convert_func_t) pa_sconv_s16be_to_float32ne,
+    [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_to_float32ne,
+    [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_to_float32ne,
+    [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_to_float32ne,
+    [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_to_float32ne,
+    [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_to_float32ne,
+    [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_to_float32ne,
+    [PA_SAMPLE_FLOAT32NE] = (pa_convert_func_t) float32ne_to_float32ne,
+    [PA_SAMPLE_FLOAT32RE] = (pa_convert_func_t) float32re_to_float32ne,
+};
+
 pa_convert_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f) {
 
-    static const pa_convert_func_t table[] = {
-        [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_to_float32ne,
-        [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_to_float32ne,
-        [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_to_float32ne,
-        [PA_SAMPLE_S16LE]     = (pa_convert_func_t) pa_sconv_s16le_to_float32ne,
-        [PA_SAMPLE_S16BE]     = (pa_convert_func_t) pa_sconv_s16be_to_float32ne,
-        [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_to_float32ne,
-        [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_to_float32ne,
-        [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_to_float32ne,
-        [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_to_float32ne,
-        [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_to_float32ne,
-        [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_to_float32ne,
-        [PA_SAMPLE_FLOAT32NE] = (pa_convert_func_t) float32ne_to_float32ne,
-        [PA_SAMPLE_FLOAT32RE] = (pa_convert_func_t) float32re_to_float32ne,
-    };
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return to_float32ne_table[f];
+}
+
+void pa_set_convert_to_float32ne_function(pa_sample_format_t f, pa_convert_func_t func) {
 
     pa_assert(f >= 0);
     pa_assert(f < PA_SAMPLE_MAX);
 
-    return table[f];
+    to_float32ne_table[f] = func;
 }
 
+static pa_convert_func_t from_float32ne_table[] = {
+    [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_from_float32ne,
+    [PA_SAMPLE_S16LE]     = (pa_convert_func_t) pa_sconv_s16le_from_float32ne,
+    [PA_SAMPLE_S16BE]     = (pa_convert_func_t) pa_sconv_s16be_from_float32ne,
+    [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_from_float32ne,
+    [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_from_float32ne,
+    [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_from_float32ne,
+    [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_from_float32ne,
+    [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_from_float32ne,
+    [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_from_float32ne,
+    [PA_SAMPLE_FLOAT32NE] = (pa_convert_func_t) float32ne_to_float32ne,
+    [PA_SAMPLE_FLOAT32RE] = (pa_convert_func_t) float32re_to_float32ne,
+    [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_from_float32ne,
+    [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_from_float32ne
+};
+
 pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) {
 
-    static const pa_convert_func_t table[] = {
-        [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_from_float32ne,
-        [PA_SAMPLE_S16LE]     = (pa_convert_func_t) pa_sconv_s16le_from_float32ne,
-        [PA_SAMPLE_S16BE]     = (pa_convert_func_t) pa_sconv_s16be_from_float32ne,
-        [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_from_float32ne,
-        [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_from_float32ne,
-        [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_from_float32ne,
-        [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_from_float32ne,
-        [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_from_float32ne,
-        [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_from_float32ne,
-        [PA_SAMPLE_FLOAT32NE] = (pa_convert_func_t) float32ne_to_float32ne,
-        [PA_SAMPLE_FLOAT32RE] = (pa_convert_func_t) float32re_to_float32ne,
-        [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_from_float32ne,
-        [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_from_float32ne
-    };
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return from_float32ne_table[f];
+}
+
+void pa_set_convert_from_float32ne_function(pa_sample_format_t f, pa_convert_func_t func) {
 
     pa_assert(f >= 0);
     pa_assert(f < PA_SAMPLE_MAX);
 
-    return table[f];
+    from_float32ne_table[f] = func;
 }
 
+static pa_convert_func_t to_s16ne_table[] = {
+    [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_to_s16ne,
+    [PA_SAMPLE_S16NE]     = (pa_convert_func_t) s16ne_to_s16ne,
+    [PA_SAMPLE_S16RE]     = (pa_convert_func_t) s16re_to_s16ne,
+    [PA_SAMPLE_FLOAT32BE] = (pa_convert_func_t) pa_sconv_float32be_to_s16ne,
+    [PA_SAMPLE_FLOAT32LE] = (pa_convert_func_t) pa_sconv_float32le_to_s16ne,
+    [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_to_s16ne,
+    [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_to_s16ne,
+    [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_to_s16ne,
+    [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_to_s16ne,
+    [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_to_s16ne,
+    [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_to_s16ne,
+    [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_to_s16ne,
+    [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_to_s16ne
+};
+
 pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f) {
 
-    static const pa_convert_func_t table[] = {
-        [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_to_s16ne,
-        [PA_SAMPLE_S16NE]     = (pa_convert_func_t) s16ne_to_s16ne,
-        [PA_SAMPLE_S16RE]     = (pa_convert_func_t) s16re_to_s16ne,
-        [PA_SAMPLE_FLOAT32BE] = (pa_convert_func_t) pa_sconv_float32be_to_s16ne,
-        [PA_SAMPLE_FLOAT32LE] = (pa_convert_func_t) pa_sconv_float32le_to_s16ne,
-        [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_to_s16ne,
-        [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_to_s16ne,
-        [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_to_s16ne,
-        [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_to_s16ne,
-        [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_to_s16ne,
-        [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_to_s16ne,
-        [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_to_s16ne,
-        [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_to_s16ne
-    };
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return to_s16ne_table[f];
+}
+
+void pa_set_convert_to_s16ne_function(pa_sample_format_t f, pa_convert_func_t func) {
 
     pa_assert(f >= 0);
     pa_assert(f < PA_SAMPLE_MAX);
 
-    return table[f];
+    to_s16ne_table[f] = func;
 }
 
+static pa_convert_func_t from_s16ne_table[] = {
+    [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_from_s16ne,
+    [PA_SAMPLE_S16NE]     = (pa_convert_func_t) s16ne_to_s16ne,
+    [PA_SAMPLE_S16RE]     = (pa_convert_func_t) s16re_to_s16ne,
+    [PA_SAMPLE_FLOAT32BE] = (pa_convert_func_t) pa_sconv_float32be_from_s16ne,
+    [PA_SAMPLE_FLOAT32LE] = (pa_convert_func_t) pa_sconv_float32le_from_s16ne,
+    [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_from_s16ne,
+    [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_from_s16ne,
+    [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_from_s16ne,
+    [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_from_s16ne,
+    [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_from_s16ne,
+    [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_from_s16ne,
+    [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_from_s16ne,
+    [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_from_s16ne,
+};
+
 pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f) {
 
-    static const pa_convert_func_t table[] = {
-        [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_from_s16ne,
-        [PA_SAMPLE_S16NE]     = (pa_convert_func_t) s16ne_to_s16ne,
-        [PA_SAMPLE_S16RE]     = (pa_convert_func_t) s16re_to_s16ne,
-        [PA_SAMPLE_FLOAT32BE] = (pa_convert_func_t) pa_sconv_float32be_from_s16ne,
-        [PA_SAMPLE_FLOAT32LE] = (pa_convert_func_t) pa_sconv_float32le_from_s16ne,
-        [PA_SAMPLE_S32BE]     = (pa_convert_func_t) pa_sconv_s32be_from_s16ne,
-        [PA_SAMPLE_S32LE]     = (pa_convert_func_t) pa_sconv_s32le_from_s16ne,
-        [PA_SAMPLE_S24BE]     = (pa_convert_func_t) pa_sconv_s24be_from_s16ne,
-        [PA_SAMPLE_S24LE]     = (pa_convert_func_t) pa_sconv_s24le_from_s16ne,
-        [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) pa_sconv_s24_32be_from_s16ne,
-        [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) pa_sconv_s24_32le_from_s16ne,
-        [PA_SAMPLE_ALAW]      = (pa_convert_func_t) alaw_from_s16ne,
-        [PA_SAMPLE_ULAW]      = (pa_convert_func_t) ulaw_from_s16ne,
-    };
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return from_s16ne_table[f];
+}
+
+void pa_set_convert_from_s16ne_function(pa_sample_format_t f, pa_convert_func_t func) {
 
     pa_assert(f >= 0);
     pa_assert(f < PA_SAMPLE_MAX);
 
-    return table[f];
+    from_s16ne_table[f] = func;
 }
diff --git a/src/pulsecore/sconv.h b/src/pulsecore/sconv.h
index b00a16a..cd93755 100644
--- a/src/pulsecore/sconv.h
+++ b/src/pulsecore/sconv.h
@@ -33,4 +33,10 @@ pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) P
 pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f) PA_GCC_PURE;
 pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f) PA_GCC_PURE;
 
+void pa_set_convert_to_float32ne_function(pa_sample_format_t f, pa_convert_func_t func);
+void pa_set_convert_from_float32ne_function(pa_sample_format_t f, pa_convert_func_t func);
+
+void pa_set_convert_to_s16ne_function(pa_sample_format_t f, pa_convert_func_t func);
+void pa_set_convert_from_s16ne_function(pa_sample_format_t f, pa_convert_func_t func);
+
 #endif

commit a3f4a4f6ba741a996442d7a80cc3e267fab705fb
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 17:54:45 2009 +0200

    resamples; refactor the channel remapping bits
    
    Move the channel remapping bits into a separate structure. We'll make this
    structure global so that optimized versions can use it to perform the channel
    remapping.

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 5a6c398..0d8ca01 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -44,10 +44,20 @@
 /* Number of samples of extra space we allow the resamplers to return */
 #define EXTRA_FRAMES 128
 
-typedef void (*pa_do_remap_func_t) (pa_resampler *r, void *d, const void *s, unsigned n);
+typedef struct pa_remap pa_remap_t;
 
-static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src, unsigned n);
-static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, unsigned n);
+typedef void (*pa_do_remap_func_t) (pa_remap_t *m, void *d, const void *s, unsigned n);
+
+struct pa_remap {
+    pa_sample_format_t *format;
+    pa_sample_spec *i_ss, *o_ss;
+    float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
+    int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
+    pa_do_remap_func_t do_remap;
+};
+
+static void remap_channels_matrix (pa_remap_t *m, void *dst, const void *src, unsigned n);
+static void remap_mono_to_stereo(pa_remap_t *m, void *dst, const void *src, unsigned n);
 
 struct pa_resampler {
     pa_resample_method_t method;
@@ -66,10 +76,8 @@ struct pa_resampler {
     pa_convert_func_t to_work_format_func;
     pa_convert_func_t from_work_format_func;
 
-    float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
-    int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
+    pa_remap_t remap;
     pa_bool_t map_required;
-    pa_do_remap_func_t do_remap;
 
     void (*impl_free)(pa_resampler *r);
     void (*impl_update_rates)(pa_resampler *r);
@@ -218,6 +226,11 @@ pa_resampler* pa_resampler_new(
     r->i_ss = *a;
     r->o_ss = *b;
 
+    /* set up the remap structure */
+    r->remap.i_ss = &r->i_ss;
+    r->remap.o_ss = &r->o_ss;
+    r->remap.format = &r->work_format;
+
     if (am)
         r->i_cm = *am;
     else if (!pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT))
@@ -584,33 +597,41 @@ static int front_rear_side(pa_channel_position_t p) {
 
 static void calc_map_table(pa_resampler *r) {
     unsigned oc, ic;
+    unsigned n_oc, n_ic;
     pa_bool_t ic_connected[PA_CHANNELS_MAX];
     pa_bool_t remix;
     pa_strbuf *s;
     char *t;
+    pa_remap_t *m;
 
     pa_assert(r);
 
     if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || (!(r->flags & PA_RESAMPLER_NO_REMAP) && !pa_channel_map_equal(&r->i_cm, &r->o_cm)))))
         return;
 
-    memset(r->map_table_f, 0, sizeof(r->map_table_f));
-    memset(r->map_table_i, 0, sizeof(r->map_table_i));
+    m = &r->remap;
+
+    n_oc = r->o_ss.channels;
+    n_ic = r->i_ss.channels;
+
+    memset(m->map_table_f, 0, sizeof(m->map_table_f));
+    memset(m->map_table_i, 0, sizeof(m->map_table_i));
+
     memset(ic_connected, 0, sizeof(ic_connected));
     remix = (r->flags & (PA_RESAMPLER_NO_REMAP|PA_RESAMPLER_NO_REMIX)) == 0;
 
-    for (oc = 0; oc < r->o_ss.channels; oc++) {
+    for (oc = 0; oc < n_oc; oc++) {
         pa_bool_t oc_connected = FALSE;
         pa_channel_position_t b = r->o_cm.map[oc];
 
-        for (ic = 0; ic < r->i_ss.channels; ic++) {
+        for (ic = 0; ic < n_ic; ic++) {
             pa_channel_position_t a = r->i_cm.map[ic];
 
             if (r->flags & PA_RESAMPLER_NO_REMAP) {
                 /* We shall not do any remapping. Hence, just check by index */
 
                 if (ic == oc)
-                    r->map_table_f[oc][ic] = 1.0;
+                    m->map_table_f[oc][ic] = 1.0;
 
                 continue;
             }
@@ -619,7 +640,7 @@ static void calc_map_table(pa_resampler *r) {
                 /* We shall not do any remixing. Hence, just check by name */
 
                 if (a == b)
-                    r->map_table_f[oc][ic] = 1.0;
+                    m->map_table_f[oc][ic] = 1.0;
 
                 continue;
             }
@@ -694,7 +715,7 @@ static void calc_map_table(pa_resampler *r) {
              */
 
             if (a == b || a == PA_CHANNEL_POSITION_MONO || b == PA_CHANNEL_POSITION_MONO) {
-                r->map_table_f[oc][ic] = 1.0;
+                m->map_table_f[oc][ic] = 1.0;
 
                 oc_connected = TRUE;
                 ic_connected[ic] = TRUE;
@@ -712,14 +733,14 @@ static void calc_map_table(pa_resampler *r) {
                 /* We are not connected and on the left side, let's
                  * average all left side input channels. */
 
-                for (ic = 0; ic < r->i_ss.channels; ic++)
+                for (ic = 0; ic < n_ic; ic++)
                     if (on_left(r->i_cm.map[ic]))
                         n++;
 
                 if (n > 0)
-                    for (ic = 0; ic < r->i_ss.channels; ic++)
+                    for (ic = 0; ic < n_ic; ic++)
                         if (on_left(r->i_cm.map[ic])) {
-                            r->map_table_f[oc][ic] = 1.0f / (float) n;
+                            m->map_table_f[oc][ic] = 1.0f / (float) n;
                             ic_connected[ic] = TRUE;
                         }
 
@@ -733,14 +754,14 @@ static void calc_map_table(pa_resampler *r) {
                 /* We are not connected and on the right side, let's
                  * average all right side input channels. */
 
-                for (ic = 0; ic < r->i_ss.channels; ic++)
+                for (ic = 0; ic < n_ic; ic++)
                     if (on_right(r->i_cm.map[ic]))
                         n++;
 
                 if (n > 0)
-                    for (ic = 0; ic < r->i_ss.channels; ic++)
+                    for (ic = 0; ic < n_ic; ic++)
                         if (on_right(r->i_cm.map[ic])) {
-                            r->map_table_f[oc][ic] = 1.0f / (float) n;
+                            m->map_table_f[oc][ic] = 1.0f / (float) n;
                             ic_connected[ic] = TRUE;
                         }
 
@@ -754,14 +775,14 @@ static void calc_map_table(pa_resampler *r) {
                 /* We are not connected and at the center. Let's
                  * average all center input channels. */
 
-                for (ic = 0; ic < r->i_ss.channels; ic++)
+                for (ic = 0; ic < n_ic; ic++)
                     if (on_center(r->i_cm.map[ic]))
                         n++;
 
                 if (n > 0) {
-                    for (ic = 0; ic < r->i_ss.channels; ic++)
+                    for (ic = 0; ic < n_ic; ic++)
                         if (on_center(r->i_cm.map[ic])) {
-                            r->map_table_f[oc][ic] = 1.0f / (float) n;
+                            m->map_table_f[oc][ic] = 1.0f / (float) n;
                             ic_connected[ic] = TRUE;
                         }
                 } else {
@@ -771,14 +792,14 @@ static void calc_map_table(pa_resampler *r) {
 
                     n = 0;
 
-                    for (ic = 0; ic < r->i_ss.channels; ic++)
+                    for (ic = 0; ic < n_ic; ic++)
                         if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic]))
                             n++;
 
                     if (n > 0)
-                        for (ic = 0; ic < r->i_ss.channels; ic++)
+                        for (ic = 0; ic < n_ic; ic++)
                             if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
-                                r->map_table_f[oc][ic] = 1.0f / (float) n;
+                                m->map_table_f[oc][ic] = 1.0f / (float) n;
                                 ic_connected[ic] = TRUE;
                             }
 
@@ -792,12 +813,12 @@ static void calc_map_table(pa_resampler *r) {
                 /* We are not connected and an LFE. Let's average all
                  * channels for LFE. */
 
-                for (ic = 0; ic < r->i_ss.channels; ic++) {
+                for (ic = 0; ic < n_ic; ic++) {
 
                     if (!(r->flags & PA_RESAMPLER_NO_LFE))
-                        r->map_table_f[oc][ic] = 1.0f / (float) r->i_ss.channels;
+                        m->map_table_f[oc][ic] = 1.0f / (float) n_ic;
                     else
-                        r->map_table_f[oc][ic] = 0;
+                        m->map_table_f[oc][ic] = 0;
 
                     /* Please note that a channel connected to LFE
                      * doesn't really count as connected. */
@@ -813,7 +834,7 @@ static void calc_map_table(pa_resampler *r) {
             ic_unconnected_center = 0,
             ic_unconnected_lfe = 0;
 
-        for (ic = 0; ic < r->i_ss.channels; ic++) {
+        for (ic = 0; ic < n_ic; ic++) {
             pa_channel_position_t a = r->i_cm.map[ic];
 
             if (ic_connected[ic])
@@ -836,20 +857,20 @@ static void calc_map_table(pa_resampler *r) {
              * the left side by .9 and add in our averaged unconnected
              * channels multplied by .1 */
 
-            for (oc = 0; oc < r->o_ss.channels; oc++) {
+            for (oc = 0; oc < n_oc; oc++) {
 
                 if (!on_left(r->o_cm.map[oc]))
                     continue;
 
-                for (ic = 0; ic < r->i_ss.channels; ic++) {
+                for (ic = 0; ic < n_ic; ic++) {
 
                     if (ic_connected[ic]) {
-                        r->map_table_f[oc][ic] *= .9f;
+                        m->map_table_f[oc][ic] *= .9f;
                         continue;
                     }
 
                     if (on_left(r->i_cm.map[ic]))
-                        r->map_table_f[oc][ic] = .1f / (float) ic_unconnected_left;
+                        m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_left;
                 }
             }
         }
@@ -861,20 +882,20 @@ static void calc_map_table(pa_resampler *r) {
              * the right side by .9 and add in our averaged unconnected
              * channels multplied by .1 */
 
-            for (oc = 0; oc < r->o_ss.channels; oc++) {
+            for (oc = 0; oc < n_oc; oc++) {
 
                 if (!on_right(r->o_cm.map[oc]))
                     continue;
 
-                for (ic = 0; ic < r->i_ss.channels; ic++) {
+                for (ic = 0; ic < n_ic; ic++) {
 
                     if (ic_connected[ic]) {
-                        r->map_table_f[oc][ic] *= .9f;
+                        m->map_table_f[oc][ic] *= .9f;
                         continue;
                     }
 
                     if (on_right(r->i_cm.map[ic]))
-                        r->map_table_f[oc][ic] = .1f / (float) ic_unconnected_right;
+                        m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_right;
                 }
             }
         }
@@ -887,20 +908,20 @@ static void calc_map_table(pa_resampler *r) {
              * the center side by .9 and add in our averaged unconnected
              * channels multplied by .1 */
 
-            for (oc = 0; oc < r->o_ss.channels; oc++) {
+            for (oc = 0; oc < n_oc; oc++) {
 
                 if (!on_center(r->o_cm.map[oc]))
                     continue;
 
-                for (ic = 0; ic < r->i_ss.channels; ic++)  {
+                for (ic = 0; ic < n_ic; ic++)  {
 
                     if (ic_connected[ic]) {
-                        r->map_table_f[oc][ic] *= .9f;
+                        m->map_table_f[oc][ic] *= .9f;
                         continue;
                     }
 
                     if (on_center(r->i_cm.map[ic])) {
-                        r->map_table_f[oc][ic] = .1f / (float) ic_unconnected_center;
+                        m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_center;
                         mixed_in = TRUE;
                     }
                 }
@@ -918,7 +939,7 @@ static void calc_map_table(pa_resampler *r) {
                    it into left and right. Using .375 and 0.75 as
                    factors. */
 
-                for (ic = 0; ic < r->i_ss.channels; ic++) {
+                for (ic = 0; ic < n_ic; ic++) {
 
                     if (ic_connected[ic])
                         continue;
@@ -926,7 +947,7 @@ static void calc_map_table(pa_resampler *r) {
                     if (!on_center(r->i_cm.map[ic]))
                         continue;
 
-                    for (oc = 0; oc < r->o_ss.channels; oc++) {
+                    for (oc = 0; oc < n_oc; oc++) {
 
                         if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
                             continue;
@@ -937,7 +958,7 @@ static void calc_map_table(pa_resampler *r) {
                         }
                     }
 
-                    for (oc = 0; oc < r->o_ss.channels; oc++) {
+                    for (oc = 0; oc < n_oc; oc++) {
 
                         if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
                             continue;
@@ -947,7 +968,7 @@ static void calc_map_table(pa_resampler *r) {
                     }
                 }
 
-                for (oc = 0; oc < r->o_ss.channels; oc++) {
+                for (oc = 0; oc < n_oc; oc++) {
 
                     if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
                         continue;
@@ -955,10 +976,10 @@ static void calc_map_table(pa_resampler *r) {
                     if (ncenter[oc] <= 0)
                         continue;
 
-                    for (ic = 0; ic < r->i_ss.channels; ic++)  {
+                    for (ic = 0; ic < n_ic; ic++)  {
 
                         if (ic_connected[ic]) {
-                            r->map_table_f[oc][ic] *= .75f;
+                            m->map_table_f[oc][ic] *= .75f;
                             continue;
                         }
 
@@ -966,7 +987,7 @@ static void calc_map_table(pa_resampler *r) {
                             continue;
 
                         if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
-                            r->map_table_f[oc][ic] = .375f / (float) ncenter[oc];
+                            m->map_table_f[oc][ic] = .375f / (float) ncenter[oc];
                     }
                 }
             }
@@ -977,37 +998,37 @@ static void calc_map_table(pa_resampler *r) {
             /* OK, so there is an unconnected LFE channel. Let's mix
              * it into all channels, with factor 0.375 */
 
-            for (ic = 0; ic < r->i_ss.channels; ic++)  {
+            for (ic = 0; ic < n_ic; ic++)  {
 
                 if (!on_lfe(r->i_cm.map[ic]))
                     continue;
 
-                for (oc = 0; oc < r->o_ss.channels; oc++)
-                    r->map_table_f[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
+                for (oc = 0; oc < n_oc; oc++)
+                    m->map_table_f[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
             }
         }
     }
     /* make an 16:16 int version of the matrix */
-    for (oc = 0; oc < r->o_ss.channels; oc++)
-        for (ic = 0; ic < r->i_ss.channels; ic++)
-            r->map_table_i[oc][ic] = (int32_t) (r->map_table_f[oc][ic] * 0x10000);
+    for (oc = 0; oc < n_oc; oc++)
+        for (ic = 0; ic < n_ic; ic++)
+            m->map_table_i[oc][ic] = (int32_t) (m->map_table_f[oc][ic] * 0x10000);
 
     s = pa_strbuf_new();
 
     pa_strbuf_printf(s, "     ");
-    for (ic = 0; ic < r->i_ss.channels; ic++)
+    for (ic = 0; ic < n_ic; ic++)
         pa_strbuf_printf(s, "  I%02u ", ic);
     pa_strbuf_puts(s, "\n    +");
 
-    for (ic = 0; ic < r->i_ss.channels; ic++)
+    for (ic = 0; ic < n_ic; ic++)
         pa_strbuf_printf(s, "------");
     pa_strbuf_puts(s, "\n");
 
-    for (oc = 0; oc < r->o_ss.channels; oc++) {
+    for (oc = 0; oc < n_oc; oc++) {
         pa_strbuf_printf(s, "O%02u |", oc);
 
-        for (ic = 0; ic < r->i_ss.channels; ic++)
-            pa_strbuf_printf(s, " %1.3f", r->map_table_f[oc][ic]);
+        for (ic = 0; ic < n_ic; ic++)
+            pa_strbuf_printf(s, " %1.3f", m->map_table_f[oc][ic]);
 
         pa_strbuf_puts(s, "\n");
     }
@@ -1016,13 +1037,13 @@ static void calc_map_table(pa_resampler *r) {
     pa_xfree(t);
 
     /* find some common channel remappings, fall back to full matrix operation. */
-    if (r->i_ss.channels == 1 && r->o_ss.channels == 2 &&
-            r->map_table_f[0][0] >= 1.0 && r->map_table_f[1][0] >= 1.0) {
-        r->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo;;
-        pa_log_debug("Using mono to stereo remapping");
+    if (n_ic == 1 && n_oc == 2 &&
+            m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
+        m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo;;
+        pa_log_info("Using mono to stereo remapping");
     } else {
-        r->do_remap = (pa_do_remap_func_t) remap_channels_matrix;
-        pa_log_debug("Using generic matrix remapping");
+        m->do_remap = (pa_do_remap_func_t) remap_channels_matrix;
+        pa_log_info("Using generic matrix remapping");
     }
 
 }
@@ -1064,10 +1085,10 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)
     return &r->buf1;
 }
 
-static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, unsigned n) {
+static void remap_mono_to_stereo(pa_remap_t *m, void *dst, const void *src, unsigned n) {
     unsigned i;
 
-    switch (r->work_format) {
+    switch (*m->format) {
         case PA_SAMPLE_FLOAT32NE:
         {
             float *d, *s;
@@ -1117,27 +1138,26 @@ static void remap_mono_to_stereo(pa_resampler *r, void *dst, const void *src, un
     }
 }
 
-static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src, unsigned n) {
-    unsigned oc, i;
+static void remap_channels_matrix (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+    unsigned oc, ic, i;
     unsigned n_ic, n_oc;
 
-    n_ic = r->i_ss.channels;
-    n_oc = r->o_ss.channels;
+    n_ic = m->i_ss->channels;
+    n_oc = m->o_ss->channels;
 
-    memset(dst, 0, r->buf2.length);
-
-    switch (r->work_format) {
+    switch (*m->format) {
         case PA_SAMPLE_FLOAT32NE:
         {
             float *d, *s;
 
+            memset(dst, 0, n * sizeof (float) * n_oc);
+
             for (oc = 0; oc < n_oc; oc++) {
-                unsigned ic;
 
                 for (ic = 0; ic < n_ic; ic++) {
                     float vol;
 
-                    vol = r->map_table_f[oc][ic];
+                    vol = m->map_table_f[oc][ic];
 
                     if (vol <= 0.0)
                         continue;
@@ -1161,13 +1181,14 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
         {
             int16_t *d, *s;
 
+            memset(dst, 0, n * sizeof (int16_t) * n_oc);
+
             for (oc = 0; oc < n_oc; oc++) {
-                unsigned ic;
 
                 for (ic = 0; ic < n_ic; ic++) {
                     int32_t vol;
 
-		                vol = r->map_table_i[oc][ic];
+                    vol = m->map_table_i[oc][ic];
 
                     if (vol <= 0)
                         continue;
@@ -1181,7 +1202,7 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
                     } else {
                         for (i = n; i > 0; i--, s += n_ic, d += n_oc)
                             *d += (int16_t) (((int32_t)*s * vol) >> 16);
-		                }
+                    }
                 }
             }
             break;
@@ -1194,6 +1215,7 @@ static void remap_channels_matrix (pa_resampler *r, void *dst, const void *src,
 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
     unsigned in_n_samples, out_n_samples, n_frames;
     void *src, *dst;
+    pa_remap_t *remap;
 
     pa_assert(r);
     pa_assert(input);
@@ -1222,8 +1244,10 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
     src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
     dst = pa_memblock_acquire(r->buf2.memblock);
 
-    pa_assert (r->do_remap);
-    r->do_remap (r, dst, src, n_frames);
+    remap = &r->remap;
+
+    pa_assert (remap->do_remap);
+    remap->do_remap (remap, dst, src, n_frames);
 
     pa_memblock_release(input->memblock);
     pa_memblock_release(r->buf2.memblock);

commit ac1f2e0a2e0707636aabd48baa57c124a877f834
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 18:23:42 2009 +0200

    remap: move remapping code in separate file
    
    Move the remapping code into a separate file. Have functions to install custom
    init functions that can install optimized versions, when they want.

diff --git a/src/Makefile.am b/src/Makefile.am
index eca68b1..b818c3e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -822,6 +822,7 @@ libpulsecore_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/object.c pulsecore/object.h \
 		pulsecore/play-memblockq.c pulsecore/play-memblockq.h \
 		pulsecore/play-memchunk.c pulsecore/play-memchunk.h \
+		pulsecore/remap.c pulsecore/remap.h \
 		pulsecore/resampler.c pulsecore/resampler.h \
 		pulsecore/rtpoll.c pulsecore/rtpoll.h \
 		pulsecore/sample-util.c pulsecore/sample-util.h \
diff --git a/src/pulsecore/remap.c b/src/pulsecore/remap.c
new file mode 100644
index 0000000..2e93afc
--- /dev/null
+++ b/src/pulsecore/remap.c
@@ -0,0 +1,197 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <pulse/sample.h>
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+
+#include "remap.h"
+
+static void remap_mono_to_stereo_c (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+    unsigned i;
+
+    switch (*m->format) {
+        case PA_SAMPLE_FLOAT32NE:
+        {
+            float *d, *s;
+
+            d = (float *) dst;
+            s = (float *) src;
+
+            for (i = n >> 2; i; i--) {
+                d[0] = d[1] = s[0];
+                d[2] = d[3] = s[1];
+                d[4] = d[5] = s[2];
+                d[6] = d[7] = s[3];
+                s += 4;
+                d += 8;
+            }
+            for (i = n & 3; i; i--) {
+                d[0] = d[1] = s[0];
+                s++;
+                d += 2;
+            }
+            break;
+        }
+        case PA_SAMPLE_S16NE:
+        {
+            int16_t *d, *s;
+
+            d = (int16_t *) dst;
+            s = (int16_t *) src;
+
+            for (i = n >> 2; i; i--) {
+                d[0] = d[1] = s[0];
+                d[2] = d[3] = s[1];
+                d[4] = d[5] = s[2];
+                d[6] = d[7] = s[3];
+                s += 4;
+                d += 8;
+            }
+            for (i = n & 3; i; i--) {
+                d[0] = d[1] = s[0];
+                s++;
+                d += 2;
+            }
+            break;
+        }
+        default:
+            pa_assert_not_reached();
+    }
+}
+
+static void remap_channels_matrix_c (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+    unsigned oc, ic, i;
+    unsigned n_ic, n_oc;
+
+    n_ic = m->i_ss->channels;
+    n_oc = m->o_ss->channels;
+
+    switch (*m->format) {
+        case PA_SAMPLE_FLOAT32NE:
+        {
+            float *d, *s;
+
+            memset(dst, 0, n * sizeof (float) * n_oc);
+
+            for (oc = 0; oc < n_oc; oc++) {
+
+                for (ic = 0; ic < n_ic; ic++) {
+                    float vol;
+
+                    vol = m->map_table_f[oc][ic];
+
+                    if (vol <= 0.0)
+                        continue;
+
+                    d = (float *)dst + oc;
+                    s = (float *)src + ic;
+
+                    if (vol >= 1.0) {
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
+                            *d += *s;
+                    } else {
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
+                            *d += *s * vol;
+                    }
+                }
+            }
+
+            break;
+        }
+        case PA_SAMPLE_S16NE:
+        {
+            int16_t *d, *s;
+
+            memset(dst, 0, n * sizeof (int16_t) * n_oc);
+
+            for (oc = 0; oc < n_oc; oc++) {
+
+                for (ic = 0; ic < n_ic; ic++) {
+                    int32_t vol;
+
+                    vol = m->map_table_i[oc][ic];
+
+                    if (vol <= 0)
+                        continue;
+
+                    d = (int16_t *)dst + oc;
+                    s = (int16_t *)src + ic;
+
+                    if (vol >= 0x10000) {
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
+                            *d += *s;
+                    } else {
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
+                            *d += (int16_t) (((int32_t)*s * vol) >> 16);
+                    }
+                }
+            }
+            break;
+        }
+        default:
+            pa_assert_not_reached();
+    }
+}
+
+/* set the function that will execute the remapping based on the matrices */
+static void init_remap_c (pa_remap_t *m) {
+    unsigned n_oc, n_ic;
+
+    n_oc = m->o_ss->channels;
+    n_ic = m->i_ss->channels;
+
+    /* find some common channel remappings, fall back to full matrix operation. */
+    if (n_ic == 1 && n_oc == 2 &&
+            m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
+        m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_c;
+        pa_log_info("Using mono to stereo remapping");
+    } else {
+        m->do_remap = (pa_do_remap_func_t) remap_channels_matrix_c;
+        pa_log_info("Using generic matrix remapping");
+    }
+}
+
+
+/* default C implementation */
+static pa_init_remap_func_t remap_func = init_remap_c;
+
+void pa_init_remap (pa_remap_t *m) {
+    pa_assert (remap_func);
+
+    /* just call the installed remap init functions */
+    remap_func (m);
+}
+
+pa_init_remap_func_t pa_get_init_remap_func(void) {
+    return remap_func;
+}
+
+void pa_set_init_remap_func(pa_init_remap_func_t func) {
+    remap_func = func;
+}
diff --git a/src/pulsecore/remap.h b/src/pulsecore/remap.h
new file mode 100644
index 0000000..32a67cd
--- /dev/null
+++ b/src/pulsecore/remap.h
@@ -0,0 +1,48 @@
+#ifndef fooremapfoo
+#define fooremapfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulse/sample.h>
+
+typedef struct pa_remap pa_remap_t;
+
+typedef void (*pa_do_remap_func_t) (pa_remap_t *m, void *d, const void *s, unsigned n);
+
+struct pa_remap {
+    pa_sample_format_t *format;
+    pa_sample_spec *i_ss, *o_ss;
+    float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
+    int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
+    pa_do_remap_func_t do_remap;
+};
+
+void pa_init_remap (pa_remap_t *m);
+
+/* custom installation of init functions */
+typedef void (*pa_init_remap_func_t) (pa_remap_t *m);
+
+pa_init_remap_func_t pa_get_init_remap_func(void);
+void pa_set_init_remap_func(pa_init_remap_func_t func);
+
+#endif /* fooremapfoo */
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 0d8ca01..f1bfa15 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -40,25 +40,11 @@
 #include "ffmpeg/avcodec.h"
 
 #include "resampler.h"
+#include "remap.h"
 
 /* Number of samples of extra space we allow the resamplers to return */
 #define EXTRA_FRAMES 128
 
-typedef struct pa_remap pa_remap_t;
-
-typedef void (*pa_do_remap_func_t) (pa_remap_t *m, void *d, const void *s, unsigned n);
-
-struct pa_remap {
-    pa_sample_format_t *format;
-    pa_sample_spec *i_ss, *o_ss;
-    float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
-    int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
-    pa_do_remap_func_t do_remap;
-};
-
-static void remap_channels_matrix (pa_remap_t *m, void *dst, const void *src, unsigned n);
-static void remap_mono_to_stereo(pa_remap_t *m, void *dst, const void *src, unsigned n);
-
 struct pa_resampler {
     pa_resample_method_t method;
     pa_resample_flags_t flags;
@@ -1036,16 +1022,8 @@ static void calc_map_table(pa_resampler *r) {
     pa_log_debug("Channel matrix:\n%s", t = pa_strbuf_tostring_free(s));
     pa_xfree(t);
 
-    /* find some common channel remappings, fall back to full matrix operation. */
-    if (n_ic == 1 && n_oc == 2 &&
-            m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
-        m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo;;
-        pa_log_info("Using mono to stereo remapping");
-    } else {
-        m->do_remap = (pa_do_remap_func_t) remap_channels_matrix;
-        pa_log_info("Using generic matrix remapping");
-    }
-
+    /* initialize the remapping function */
+    pa_init_remap (m);
 }
 
 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
@@ -1085,133 +1063,6 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)
     return &r->buf1;
 }
 
-static void remap_mono_to_stereo(pa_remap_t *m, void *dst, const void *src, unsigned n) {
-    unsigned i;
-
-    switch (*m->format) {
-        case PA_SAMPLE_FLOAT32NE:
-        {
-            float *d, *s;
-
-            d = (float *) dst;
-            s = (float *) src;
-
-            for (i = n >> 2; i; i--) {
-                d[0] = d[1] = s[0];
-                d[2] = d[3] = s[1];
-                d[4] = d[5] = s[2];
-                d[6] = d[7] = s[3];
-                s += 4;
-                d += 8;
-            }
-            for (i = n & 3; i; i--) {
-                d[0] = d[1] = s[0];
-                s++;
-                d += 2;
-            }
-            break;
-        }
-        case PA_SAMPLE_S16NE:
-        {
-            int16_t *d, *s;
-
-            d = (int16_t *) dst;
-            s = (int16_t *) src;
-
-            for (i = n >> 2; i; i--) {
-                d[0] = d[1] = s[0];
-                d[2] = d[3] = s[1];
-                d[4] = d[5] = s[2];
-                d[6] = d[7] = s[3];
-                s += 4;
-                d += 8;
-            }
-            for (i = n & 3; i; i--) {
-                d[0] = d[1] = s[0];
-                s++;
-                d += 2;
-            }
-            break;
-        }
-        default:
-            pa_assert_not_reached();
-    }
-}
-
-static void remap_channels_matrix (pa_remap_t *m, void *dst, const void *src, unsigned n) {
-    unsigned oc, ic, i;
-    unsigned n_ic, n_oc;
-
-    n_ic = m->i_ss->channels;
-    n_oc = m->o_ss->channels;
-
-    switch (*m->format) {
-        case PA_SAMPLE_FLOAT32NE:
-        {
-            float *d, *s;
-
-            memset(dst, 0, n * sizeof (float) * n_oc);
-
-            for (oc = 0; oc < n_oc; oc++) {
-
-                for (ic = 0; ic < n_ic; ic++) {
-                    float vol;
-
-                    vol = m->map_table_f[oc][ic];
-
-                    if (vol <= 0.0)
-                        continue;
-
-                    d = (float *)dst + oc;
-                    s = (float *)src + ic;
-
-                    if (vol >= 1.0) {
-                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
-                            *d += *s;
-                    } else {
-                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
-                            *d += *s * vol;
-                    }
-                }
-            }
-
-            break;
-        }
-        case PA_SAMPLE_S16NE:
-        {
-            int16_t *d, *s;
-
-            memset(dst, 0, n * sizeof (int16_t) * n_oc);
-
-            for (oc = 0; oc < n_oc; oc++) {
-
-                for (ic = 0; ic < n_ic; ic++) {
-                    int32_t vol;
-
-                    vol = m->map_table_i[oc][ic];
-
-                    if (vol <= 0)
-                        continue;
-
-                    d = (int16_t *)dst + oc;
-                    s = (int16_t *)src + ic;
-
-                    if (vol >= 0x10000) {
-                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
-                            *d += *s;
-                    } else {
-                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
-                            *d += (int16_t) (((int32_t)*s * vol) >> 16);
-                    }
-                }
-            }
-            break;
-        }
-        default:
-            pa_assert_not_reached();
-    }
-}
-
 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
     unsigned in_n_samples, out_n_samples, n_frames;
     void *src, *dst;

commit 28baa53d55fa51d5fbbb1be54db3581fc3d151dd
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 18:29:02 2009 +0200

    remap: allow specialisations to install NULL
    
    Fallback to the default C implementation when the remap init function did not
    set a function.

diff --git a/src/pulsecore/remap.c b/src/pulsecore/remap.c
index 2e93afc..108df90 100644
--- a/src/pulsecore/remap.c
+++ b/src/pulsecore/remap.c
@@ -186,6 +186,11 @@ void pa_init_remap (pa_remap_t *m) {
 
     /* just call the installed remap init functions */
     remap_func (m);
+
+    if (m->do_remap == NULL) {
+        /* nothing was installed, fallback to C versions */
+        init_remap_c (m);
+    }
 }
 
 pa_init_remap_func_t pa_get_init_remap_func(void) {

commit e961efc130481ff4c5a053eb03dd3ec4d513c615
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 18:32:51 2009 +0200

    remap: init the do_remap function to NULL

diff --git a/src/pulsecore/remap.c b/src/pulsecore/remap.c
index 108df90..a0fc85b 100644
--- a/src/pulsecore/remap.c
+++ b/src/pulsecore/remap.c
@@ -184,11 +184,13 @@ static pa_init_remap_func_t remap_func = init_remap_c;
 void pa_init_remap (pa_remap_t *m) {
     pa_assert (remap_func);
 
-    /* just call the installed remap init functions */
+    m->do_remap = NULL;
+
+    /* call the installed remap init function */
     remap_func (m);
 
     if (m->do_remap == NULL) {
-        /* nothing was installed, fallback to C versions */
+        /* nothing was installed, fallback to C version */
         init_remap_c (m);
     }
 }

commit 6e5dbed51ee508759ed8b5adabc998ba8faf4774
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 19:46:06 2009 +0200

    remap: add MMX mono to stereo

diff --git a/src/Makefile.am b/src/Makefile.am
index b818c3e..ab91be8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -823,6 +823,7 @@ libpulsecore_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/play-memblockq.c pulsecore/play-memblockq.h \
 		pulsecore/play-memchunk.c pulsecore/play-memchunk.h \
 		pulsecore/remap.c pulsecore/remap.h \
+		pulsecore/remap_mmx.c \
 		pulsecore/resampler.c pulsecore/resampler.h \
 		pulsecore/rtpoll.c pulsecore/rtpoll.h \
 		pulsecore/sample-util.c pulsecore/sample-util.h \
diff --git a/src/pulsecore/cpu-x86.c b/src/pulsecore/cpu-x86.c
index 0457199..bc093ec 100644
--- a/src/pulsecore/cpu-x86.c
+++ b/src/pulsecore/cpu-x86.c
@@ -110,8 +110,10 @@ void pa_cpu_init_x86 (void) {
     (flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
 
     /* activate various optimisations */
-    if (flags & PA_CPU_X86_MMX)
+    if (flags & PA_CPU_X86_MMX) {
         pa_volume_func_init_mmx (flags);
+        pa_remap_func_init_mmx (flags);
+    }
 
     if (flags & PA_CPU_X86_SSE)
         pa_volume_func_init_sse (flags);
diff --git a/src/pulsecore/cpu-x86.h b/src/pulsecore/cpu-x86.h
index 07e630e..b11ef6e 100644
--- a/src/pulsecore/cpu-x86.h
+++ b/src/pulsecore/cpu-x86.h
@@ -63,4 +63,6 @@ typedef int64_t pa_reg_x86;
 void pa_volume_func_init_mmx(pa_cpu_x86_flag_t flags);
 void pa_volume_func_init_sse(pa_cpu_x86_flag_t flags);
 
+void pa_remap_func_init_mmx(pa_cpu_x86_flag_t flags);
+
 #endif /* foocpux86hfoo */
diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c
new file mode 100644
index 0000000..6690cfa
--- /dev/null
+++ b/src/pulsecore/remap_mmx.c
@@ -0,0 +1,174 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <pulse/sample.h>
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+
+#include "cpu-x86.h"
+#include "remap.h"
+
+#define LOAD_SAMPLES                                   \
+                " movq (%1), %%mm0              \n\t"  \
+                " movq 8(%1), %%mm2             \n\t"  \
+                " movq 16(%1), %%mm4            \n\t"  \
+                " movq 24(%1), %%mm6            \n\t"  \
+                " movq %%mm0, %%mm1             \n\t"  \
+                " movq %%mm2, %%mm3             \n\t"  \
+                " movq %%mm4, %%mm5             \n\t"  \
+                " movq %%mm6, %%mm7             \n\t"
+
+#define UNPACK_SAMPLES(s)                              \
+                " punpckl"#s" %%mm0, %%mm0      \n\t"  \
+                " punpckh"#s" %%mm1, %%mm1      \n\t"  \
+                " punpckl"#s" %%mm2, %%mm2      \n\t"  \
+                " punpckh"#s" %%mm3, %%mm3      \n\t"  \
+                " punpckl"#s" %%mm4, %%mm4      \n\t"  \
+                " punpckh"#s" %%mm5, %%mm5      \n\t"  \
+                " punpckl"#s" %%mm6, %%mm6      \n\t"  \
+                " punpckh"#s" %%mm7, %%mm7      \n\t"  \
+
+#define STORE_SAMPLES                                  \
+                " movq %%mm0, (%0)              \n\t"  \
+                " movq %%mm1, 8(%0)             \n\t"  \
+                " movq %%mm2, 16(%0)            \n\t"  \
+                " movq %%mm3, 24(%0)            \n\t"  \
+                " movq %%mm4, 32(%0)            \n\t"  \
+                " movq %%mm5, 40(%0)            \n\t"  \
+                " movq %%mm6, 48(%0)            \n\t"  \
+                " movq %%mm7, 56(%0)            \n\t"  \
+                " add $32, %1                   \n\t"  \
+                " add $64, %0                   \n\t"
+
+#define HANDLE_SINGLE(s)                               \
+                " movd (%1), %%mm0              \n\t"  \
+                " movq %%mm0, %%mm1             \n\t"  \
+                " punpckl"#s" %%mm0, %%mm0      \n\t"  \
+                " movq %%mm0, (%0)              \n\t"  \
+                " add $4, %1                    \n\t"  \
+                " add $8, %0                    \n\t"
+
+static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+    pa_reg_x86 temp;
+
+    switch (*m->format) {
+        case PA_SAMPLE_FLOAT32NE:
+        {
+            __asm__ __volatile__ (
+                " mov %3, %2                    \n\t"
+                " sar $3, %2                    \n\t" /* prepare for processing 8 samples at a time */
+                " cmp $0, %2                    \n\t"
+                " je 2f                         \n\t"
+
+                "1:                             \n\t" /* do samples in groups of 8 */
+                LOAD_SAMPLES
+                UNPACK_SAMPLES(dq)
+                STORE_SAMPLES
+                " dec %2                        \n\t"
+                " jne 1b                        \n\t"
+
+                "2:                             \n\t"
+                " mov %3, %2                    \n\t"
+                " and $7, %2                    \n\t" /* prepare for processing the remaining samples */
+                " je 4f                         \n\t"
+
+                "3:                             \n\t"
+                HANDLE_SINGLE(dq)
+                " dec %2                        \n\t"
+                " jne 3b                        \n\t"
+
+                "4:                             \n\t"
+                " emms                          \n\t"
+
+                : "+r" (dst), "+r" (src), "=&r" (temp)
+                : "r" ((pa_reg_x86)n)
+                : "cc"
+            );
+            break;
+        }
+        case PA_SAMPLE_S16NE:
+        {
+            __asm__ __volatile__ (
+                " mov %3, %2                    \n\t"
+                " sar $3, %2                    \n\t" /* prepare for processing 8 samples at a time */
+                " cmp $0, %2                    \n\t"
+                " je 2f                         \n\t"
+
+                "1:                             \n\t" /* do samples in groups of 16 */
+                LOAD_SAMPLES
+                UNPACK_SAMPLES(wd)
+                STORE_SAMPLES
+                " dec %2                        \n\t"
+                " jne 1b                        \n\t"
+
+                "2:                             \n\t"
+                " mov %3, %2                    \n\t"
+                " and $7, %2                    \n\t" /* prepare for processing the remaining samples */
+                " je 4f                         \n\t"
+
+                "3:                             \n\t"
+                HANDLE_SINGLE(wd)
+                " dec %2                        \n\t"
+                " jne 3b                        \n\t"
+
+                "4:                             \n\t"
+                " emms                          \n\t"
+
+                : "+r" (dst), "+r" (src), "=&r" (temp)
+                : "r" ((pa_reg_x86)n)
+                : "cc"
+            );
+            break;
+        }
+        default:
+            pa_assert_not_reached();
+    }
+}
+
+/* set the function that will execute the remapping based on the matrices */
+static void init_remap_mmx (pa_remap_t *m) {
+    unsigned n_oc, n_ic;
+
+    n_oc = m->o_ss->channels;
+    n_ic = m->i_ss->channels;
+
+    /* find some common channel remappings, fall back to full matrix operation. */
+    if (n_ic == 1 && n_oc == 2 &&
+            m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
+        m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_mmx;
+        pa_log_info("Using MMX mono to stereo remapping");
+    }
+}
+
+void pa_remap_func_init_mmx (pa_cpu_x86_flag_t flags) {
+#if defined (__i386__) || defined (__amd64__)
+    pa_log_info("Initialising MMX optimized remappers.");
+
+    pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_mmx);
+#endif /* defined (__i386__) || defined (__amd64__) */
+}

commit 6076cef2092391d8b46aa84f86857cffebce4583
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Thu Aug 20 20:00:50 2009 +0200

    remap: make the MMX code pretier

diff --git a/src/pulsecore/remap_mmx.c b/src/pulsecore/remap_mmx.c
index 6690cfa..bfcae6c 100644
--- a/src/pulsecore/remap_mmx.c
+++ b/src/pulsecore/remap_mmx.c
@@ -73,6 +73,28 @@
                 " add $4, %1                    \n\t"  \
                 " add $8, %0                    \n\t"
 
+#define MONO_TO_STEREO(s)                               \
+                " mov %3, %2                    \n\t"   \
+                " sar $3, %2                    \n\t"   \
+                " cmp $0, %2                    \n\t"   \
+                " je 2f                         \n\t"   \
+                "1:                             \n\t"   \
+                LOAD_SAMPLES                            \
+                UNPACK_SAMPLES(s)                       \
+                STORE_SAMPLES                           \
+                " dec %2                        \n\t"   \
+                " jne 1b                        \n\t"   \
+                "2:                             \n\t"   \
+                " mov %3, %2                    \n\t"   \
+                " and $7, %2                    \n\t"   \
+                " je 4f                         \n\t"   \
+                "3:                             \n\t"   \
+                HANDLE_SINGLE(s)                        \
+                " dec %2                        \n\t"   \
+                " jne 3b                        \n\t"   \
+                "4:                             \n\t"   \
+                " emms                          \n\t"
+
 static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) {
     pa_reg_x86 temp;
 
@@ -80,31 +102,7 @@ static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src,
         case PA_SAMPLE_FLOAT32NE:
         {
             __asm__ __volatile__ (
-                " mov %3, %2                    \n\t"
-                " sar $3, %2                    \n\t" /* prepare for processing 8 samples at a time */
-                " cmp $0, %2                    \n\t"
-                " je 2f                         \n\t"
-
-                "1:                             \n\t" /* do samples in groups of 8 */
-                LOAD_SAMPLES
-                UNPACK_SAMPLES(dq)
-                STORE_SAMPLES
-                " dec %2                        \n\t"
-                " jne 1b                        \n\t"
-
-                "2:                             \n\t"
-                " mov %3, %2                    \n\t"
-                " and $7, %2                    \n\t" /* prepare for processing the remaining samples */
-                " je 4f                         \n\t"
-
-                "3:                             \n\t"
-                HANDLE_SINGLE(dq)
-                " dec %2                        \n\t"
-                " jne 3b                        \n\t"
-
-                "4:                             \n\t"
-                " emms                          \n\t"
-
+                MONO_TO_STEREO(dq) /* do doubles to quads */
                 : "+r" (dst), "+r" (src), "=&r" (temp)
                 : "r" ((pa_reg_x86)n)
                 : "cc"
@@ -114,31 +112,7 @@ static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src,
         case PA_SAMPLE_S16NE:
         {
             __asm__ __volatile__ (
-                " mov %3, %2                    \n\t"
-                " sar $3, %2                    \n\t" /* prepare for processing 8 samples at a time */
-                " cmp $0, %2                    \n\t"
-                " je 2f                         \n\t"
-
-                "1:                             \n\t" /* do samples in groups of 16 */
-                LOAD_SAMPLES
-                UNPACK_SAMPLES(wd)
-                STORE_SAMPLES
-                " dec %2                        \n\t"
-                " jne 1b                        \n\t"
-
-                "2:                             \n\t"
-                " mov %3, %2                    \n\t"
-                " and $7, %2                    \n\t" /* prepare for processing the remaining samples */
-                " je 4f                         \n\t"
-
-                "3:                             \n\t"
-                HANDLE_SINGLE(wd)
-                " dec %2                        \n\t"
-                " jne 3b                        \n\t"
-
-                "4:                             \n\t"
-                " emms                          \n\t"
-
+                MONO_TO_STEREO(wd) /* do words to doubles */
                 : "+r" (dst), "+r" (src), "=&r" (temp)
                 : "r" ((pa_reg_x86)n)
                 : "cc"

commit 15eb03a5b39f8c54328caa7516a7870bf977db40
Author: Ted Percival <ted at midg3t.net>
Date:   Fri Aug 21 16:02:57 2009 -0600

    core: Add thread-safe group info functions with dynamic buffers
    
    Provides getgrgid, getgrnam, getpwuid & getpwnam replacements that are
    thread safe (a la getgrgid_r() and friends) that internally
    handle allocating big-enough buffers to avoid ERANGE errors
    on large users or groups.

diff --git a/src/Makefile.am b/src/Makefile.am
index fd44099..73c0db5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -280,7 +280,8 @@ TESTS = \
 		proplist-test \
 		lock-autospawn-test \
 		prioq-test \
-		sigbus-test
+		sigbus-test \
+		usergroup-test
 
 TESTS_BINARIES = \
 		mainloop-test \
@@ -318,7 +319,8 @@ TESTS_BINARIES = \
 		stripnul \
 		lock-autospawn-test \
 		prioq-test \
-		sigbus-test
+		sigbus-test \
+		usergroup-test
 
 if HAVE_SIGXCPU
 #TESTS += \
@@ -557,6 +559,11 @@ alsa_time_test_LDADD = $(AM_LDADD)
 alsa_time_test_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
 alsa_time_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(ASOUNDLIB_LIBS)
 
+usergroup_test_SOURCES = tests/usergroup-test.c
+usergroup_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINORMICRO@.la
+usergroup_test_CFLAGS = $(AM_CFLAGS)
+usergroup_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+
 ###################################
 #         Common library          #
 ###################################
@@ -621,6 +628,7 @@ libpulsecommon_ at PA_MAJORMINORMICRO@_la_SOURCES = \
 		pulsecore/tagstruct.c pulsecore/tagstruct.h \
 		pulsecore/time-smoother.c pulsecore/time-smoother.h \
 		pulsecore/tokenizer.c pulsecore/tokenizer.h \
+		pulsecore/usergroup.c pulsecore/usergroup.h \
 		pulsecore/sndfile-util.c pulsecore/sndfile-util.h \
 		pulsecore/winsock.h
 
diff --git a/src/pulse/util.c b/src/pulse/util.c
index 6f1e40a..9440f5d 100644
--- a/src/pulse/util.c
+++ b/src/pulse/util.c
@@ -61,38 +61,40 @@
 #include <pulsecore/log.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/usergroup.h>
 
 #include "util.h"
 
 char *pa_get_user_name(char *s, size_t l) {
     const char *p;
+    char *name = NULL;
+#ifdef OS_IS_WIN32
     char buf[1024];
+#endif
 
 #ifdef HAVE_PWD_H
-    struct passwd pw, *r;
+    struct passwd *r;
 #endif
 
     pa_assert(s);
     pa_assert(l > 0);
 
-    if (!(p = (getuid() == 0 ? "root" : NULL)) &&
-        !(p = getenv("USER")) &&
-        !(p = getenv("LOGNAME")) &&
-        !(p = getenv("USERNAME"))) {
+    if ((p = (getuid() == 0 ? "root" : NULL)) ||
+        (p = getenv("USER")) ||
+        (p = getenv("LOGNAME")) ||
+        (p = getenv("USERNAME")))
+    {
+        name = pa_strlcpy(s, p, l);
+    } else {
 #ifdef HAVE_PWD_H
 
-#ifdef HAVE_GETPWUID_R
-        if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
-#else
-        /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
-            * that do not support getpwuid_r. */
-        if ((r = getpwuid(getuid())) == NULL) {
-#endif
+        if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
             pa_snprintf(s, l, "%lu", (unsigned long) getuid());
             return s;
         }
 
-        p = r->pw_name;
+        name = pa_strlcpy(s, r->pw_name, l);
+        pa_getpwuid_free(r);
 
 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
         DWORD size = sizeof(buf);
@@ -102,7 +104,7 @@ char *pa_get_user_name(char *s, size_t l) {
             return NULL;
         }
 
-        p = buf;
+        name = pa_strlcpy(s, buf, l);
 
 #else /* HAVE_PWD_H */
 
@@ -110,7 +112,7 @@ char *pa_get_user_name(char *s, size_t l) {
 #endif /* HAVE_PWD_H */
     }
 
-    return pa_strlcpy(s, p, l);
+    return name;
 }
 
 char *pa_get_host_name(char *s, size_t l) {
@@ -126,11 +128,10 @@ char *pa_get_host_name(char *s, size_t l) {
 }
 
 char *pa_get_home_dir(char *s, size_t l) {
-    char *e;
+    char *e, *dir;
 
 #ifdef HAVE_PWD_H
-    char buf[1024];
-    struct passwd pw, *r;
+    struct passwd *r;
 #endif
 
     pa_assert(s);
@@ -143,22 +144,19 @@ char *pa_get_home_dir(char *s, size_t l) {
         return pa_strlcpy(s, e, l);
 
 #ifdef HAVE_PWD_H
-
     errno = 0;
-#ifdef HAVE_GETPWUID_R
-    if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
-#else
-    /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
-        * that do not support getpwuid_r. */
-    if ((r = getpwuid(getuid())) == NULL) {
-#endif
+    if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
         if (!errno)
             errno = ENOENT;
 
         return NULL;
     }
 
-    return pa_strlcpy(s, r->pw_dir, l);
+    dir = pa_strlcpy(s, r->pw_dir, l);
+
+    pa_getpwuid_free(r);
+
+    return dir;
 #else /* HAVE_PWD_H */
 
     errno = ENOENT;
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 843c837..0eb32cc 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -115,6 +115,7 @@
 #include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/strbuf.h>
+#include <pulsecore/usergroup.h>
 
 #include "core-util.h"
 
@@ -969,42 +970,24 @@ fail:
 
 /* Check whether the specified GID and the group name match */
 static int is_group(gid_t gid, const char *name) {
-    struct group group, *result = NULL;
-    long n;
-    void *data;
+    struct group *group = NULL;
     int r = -1;
 
-#ifdef HAVE_GETGRGID_R
-
-#ifdef _SC_GETGR_R_SIZE_MAX
-    n = sysconf(_SC_GETGR_R_SIZE_MAX);
-#else
-    n = -1;
-#endif
-    if (n <= 0)
-        n = 512;
-
-    data = pa_xmalloc((size_t) n);
-
-    if ((errno = getgrgid_r(gid, &group, data, (size_t) n, &result)) || !result)
-#else
     errno = 0;
-    if (!(result = getgrgid(gid)))
-#endif
+    if (!(group = pa_getgrgid_malloc(gid)))
     {
         if (!errno)
             errno = ENOENT;
 
-        pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
+        pa_log("pa_getgrgid_malloc(%u): %s", gid, pa_cstrerror(errno));
 
         goto finish;
     }
 
-    r = strcmp(name, result->gr_name) == 0;
+    r = strcmp(name, group->gr_name) == 0;
 
 finish:
-
-    pa_xfree(data);
+    pa_getgrgid_free(group);
 
     return r;
 }
@@ -1053,69 +1036,37 @@ finish:
 
 /* Check whether the specifc user id is a member of the specified group */
 int pa_uid_in_group(uid_t uid, const char *name) {
-    char *g_buf = NULL, *p_buf = NULL;
-    long g_n, p_n;
-    struct group grbuf, *gr = NULL;
+    struct group *group = NULL;
     char **i;
     int r = -1;
 
-#ifdef HAVE_GETGRNAM_R
-
-#ifdef _SC_GETGR_R_SIZE_MAX
-    g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
-#else
-    g_n = -1;
-#endif
-    if (g_n <= 0)
-        g_n = 512;
-
-    g_buf = pa_xmalloc((size_t) g_n);
-
-    if ((errno = getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr)) != 0 || !gr)
-#else
     errno = 0;
-    if (!(gr = getgrnam(name)))
-#endif
+    if (!(group = pa_getgrnam_malloc(name)))
     {
         if (!errno)
             errno = ENOENT;
         goto finish;
     }
 
-#ifdef HAVE_GETPWNAM_R
-
-#ifdef _SC_GETPW_R_SIZE_MAX
-    p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
-#else
-    p_n = -1;
-#endif
-    if (p_n <= 0)
-        p_n = 512;
-
-    p_buf = pa_xmalloc((size_t) p_n);
-#endif
-
     r = 0;
-    for (i = gr->gr_mem; *i; i++) {
-        struct passwd pwbuf, *pw = NULL;
+    for (i = group->gr_mem; *i; i++) {
+        struct passwd *pw = NULL;
 
-#ifdef HAVE_GETPWNAM_R
-        if ((errno = getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw)) != 0 || !pw)
-#else
         errno = 0;
-        if (!(pw = getpwnam(*i)))
-#endif
+        if (!(pw = pa_getpwnam_malloc(*i)))
             continue;
 
-        if (pw->pw_uid == uid) {
+        if (pw->pw_uid == uid)
             r = 1;
+
+        pa_getpwnam_free(pw);
+
+        if (r == 1)
             break;
-        }
     }
 
 finish:
-    pa_xfree(g_buf);
-    pa_xfree(p_buf);
+    pa_getgrnam_free(group);
 
     return r;
 }
@@ -1123,27 +1074,10 @@ finish:
 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
 gid_t pa_get_gid_of_group(const char *name) {
     gid_t ret = (gid_t) -1;
-    char *g_buf = NULL;
-    long g_n;
-    struct group grbuf, *gr = NULL;
-
-#ifdef HAVE_GETGRNAM_R
-
-#ifdef _SC_GETGR_R_SIZE_MAX
-    g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
-#else
-    g_n = -1;
-#endif
-    if (g_n <= 0)
-        g_n = 512;
-
-    g_buf = pa_xmalloc((size_t) g_n);
+    struct group *gr = NULL;
 
-    if ((errno = getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr)) != 0 || !gr)
-#else
     errno = 0;
-    if (!(gr = getgrnam(name)))
-#endif
+    if (!(gr = pa_getgrnam_malloc(name)))
     {
         if (!errno)
             errno = ENOENT;
@@ -1153,7 +1087,7 @@ gid_t pa_get_gid_of_group(const char *name) {
     ret = gr->gr_gid;
 
 finish:
-    pa_xfree(g_buf);
+    pa_getgrnam_free(gr);
     return ret;
 }
 
diff --git a/src/pulsecore/usergroup.c b/src/pulsecore/usergroup.c
new file mode 100644
index 0000000..bf686b7
--- /dev/null
+++ b/src/pulsecore/usergroup.c
@@ -0,0 +1,376 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Ted Percival
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#include <pulse/xmalloc.h>
+#include <pulsecore/macro.h>
+
+#include "usergroup.h"
+
+#ifdef HAVE_GRP_H
+
+/* Returns a suitable starting size for a getgrnam_r() or getgrgid_r() buffer,
+   plus the size of a struct group.
+ */
+static size_t starting_getgr_buflen(void) {
+    size_t full_size;
+    long n;
+#ifdef _SC_GETGR_R_SIZE_MAX
+    n = sysconf(_SC_GETGR_R_SIZE_MAX);
+#else
+    n = -1;
+#endif
+    if (n <= 0)
+        n = 512;
+
+    full_size = (size_t) n + sizeof(struct group);
+
+    if (full_size < (size_t) n) /* check for integer overflow */
+        return (size_t) n;
+
+    return full_size;
+}
+
+/* Returns a suitable starting size for a getpwnam_r() or getpwuid_r() buffer,
+   plus the size of a struct passwd.
+ */
+static size_t starting_getpw_buflen(void) {
+    long n;
+    size_t full_size;
+
+#ifdef _SC_GETPW_R_SIZE_MAX
+    n = sysconf(_SC_GETPW_R_SIZE_MAX);
+#else
+    n = -1;
+#endif
+    if (n <= 0)
+        n = 512;
+
+    full_size = (size_t) n + sizeof(struct passwd);
+
+    if (full_size < (size_t) n) /* check for integer overflow */
+        return (size_t) n;
+
+    return full_size;
+}
+
+/* Given a memory allocation (*bufptr) and its length (*buflenptr),
+   double the size of the allocation, updating the given buffer and length
+   arguments. This function should be used in conjunction with the pa_*alloc
+   and pa_xfree functions.
+
+   Unlike realloc(), this function does *not* retain the original buffer's
+   contents.
+
+   Returns 0 on success, nonzero on error. The error cause is indicated by
+   errno.
+ */
+static int expand_buffer_trashcontents(void **bufptr, size_t *buflenptr) {
+    size_t newlen;
+
+    if (!bufptr || !*bufptr || !buflenptr) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    newlen = *buflenptr * 2;
+
+    if (newlen < *buflenptr) {
+        errno = EOVERFLOW;
+        return -1;
+    }
+
+    /* Don't bother retaining memory contents; free & alloc anew */
+    pa_xfree(*bufptr);
+
+    *bufptr = pa_xmalloc(newlen);
+    *buflenptr = newlen;
+
+    return 0;
+}
+
+#ifdef HAVE_GETGRGID_R
+/* Thread-safe getgrgid() replacement.
+   Returned value should be freed using pa_getgrgid_free() when the caller is
+   finished with the returned group data.
+
+   API is the same as getgrgid(), errors are indicated by a NULL return;
+   consult errno for the error cause (zero it before calling).
+   The returned value must be freed using pa_xfree().
+ */
+struct group *pa_getgrgid_malloc(gid_t gid) {
+    size_t buflen, getgr_buflen;
+    int err;
+    void *buf;
+    void *getgr_buf;
+    struct group *result = NULL;
+
+    buflen = starting_getgr_buflen();
+    buf = pa_xmalloc(buflen);
+
+    getgr_buflen = buflen - sizeof(struct group);
+    getgr_buf = (char *)buf + sizeof(struct group);
+
+    while ((err = getgrgid_r(gid, (struct group *)buf, getgr_buf,
+                    getgr_buflen, &result)) == ERANGE)
+    {
+        if (expand_buffer_trashcontents(&buf, &buflen))
+            break;
+
+        getgr_buflen = buflen - sizeof(struct group);
+        getgr_buf = (char *)buf + sizeof(struct group);
+    }
+
+    if (err || !result) {
+        result = NULL;
+        if (buf) {
+            pa_xfree(buf);
+            buf = NULL;
+        }
+    }
+
+    pa_assert(result == buf || result == NULL);
+
+    return result;
+}
+
+void pa_getgrgid_free(struct group *grp) {
+    pa_xfree(grp);
+}
+
+#else /* !HAVE_GETGRGID_R */
+
+struct group *pa_getgrgid_malloc(gid_t gid) {
+    return getgrgid(gid);
+}
+
+void pa_getgrgid_free(struct group *grp) {
+    /* nothing */
+    return;
+}
+
+#endif /* !HAVE_GETGRGID_R */
+
+#ifdef HAVE_GETGRNAM_R
+/* Thread-safe getgrnam() function.
+   Returned value should be freed using pa_getgrnam_free() when the caller is
+   finished with the returned group data.
+
+   API is the same as getgrnam(), errors are indicated by a NULL return;
+   consult errno for the error cause (zero it before calling).
+   The returned value must be freed using pa_xfree().
+ */
+struct group *pa_getgrnam_malloc(const char *name) {
+    size_t buflen, getgr_buflen;
+    int err;
+    void *buf;
+    void *getgr_buf;
+    struct group *result = NULL;
+
+    buflen = starting_getgr_buflen();
+    buf = pa_xmalloc(buflen);
+
+    getgr_buflen = buflen - sizeof(struct group);
+    getgr_buf = (char *)buf + sizeof(struct group);
+
+    while ((err = getgrnam_r(name, (struct group *)buf, getgr_buf,
+                    getgr_buflen, &result)) == ERANGE)
+    {
+        if (expand_buffer_trashcontents(&buf, &buflen))
+            break;
+
+        getgr_buflen = buflen - sizeof(struct group);
+        getgr_buf = (char *)buf + sizeof(struct group);
+    }
+
+    if (err || !result) {
+        result = NULL;
+        if (buf) {
+            pa_xfree(buf);
+            buf = NULL;
+        }
+    }
+
+    pa_assert(result == buf || result == NULL);
+
+    return result;
+}
+
+void pa_getgrnam_free(struct group *group) {
+    pa_xfree(group);
+}
+
+#else /* !HAVE_GETGRNAM_R */
+
+struct group *pa_getgrnam_malloc(const char *name) {
+    return getgrnam(name);
+}
+
+void pa_getgrnam_free(struct group *group) {
+    /* nothing */
+    return;
+}
+
+#endif /* HAVE_GETGRNAM_R */
+
+#endif /* HAVE_GRP_H */
+
+#ifdef HAVE_PWD_H
+
+#ifdef HAVE_GETPWNAM_R
+/* Thread-safe getpwnam() function.
+   Returned value should be freed using pa_getpwnam_free() when the caller is
+   finished with the returned passwd data.
+
+   API is the same as getpwnam(), errors are indicated by a NULL return;
+   consult errno for the error cause (zero it before calling).
+   The returned value must be freed using pa_xfree().
+ */
+struct passwd *pa_getpwnam_malloc(const char *name) {
+    size_t buflen, getpw_buflen;
+    int err;
+    void *buf;
+    void *getpw_buf;
+    struct passwd *result = NULL;
+
+    buflen = starting_getpw_buflen();
+    buf = pa_xmalloc(buflen);
+
+    getpw_buflen = buflen - sizeof(struct passwd);
+    getpw_buf = (char *)buf + sizeof(struct passwd);
+
+    while ((err = getpwnam_r(name, (struct passwd *)buf, getpw_buf,
+                    getpw_buflen, &result)) == ERANGE)
+    {
+        if (expand_buffer_trashcontents(&buf, &buflen))
+            break;
+
+        getpw_buflen = buflen - sizeof(struct passwd);
+        getpw_buf = (char *)buf + sizeof(struct passwd);
+    }
+
+    if (err || !result) {
+        result = NULL;
+        if (buf) {
+            pa_xfree(buf);
+            buf = NULL;
+        }
+    }
+
+    pa_assert(result == buf || result == NULL);
+
+    return result;
+}
+
+void pa_getpwnam_free(struct passwd *passwd) {
+    pa_xfree(passwd);
+}
+
+#else /* !HAVE_GETPWNAM_R */
+
+struct passwd *pa_getpwnam_malloc(const char *name) {
+    return getpwnam(name);
+}
+
+void pa_getpwnam_free(struct passwd *passwd) {
+    /* nothing */
+    return;
+}
+
+#endif /* !HAVE_GETPWNAM_R */
+
+#ifdef HAVE_GETPWUID_R
+/* Thread-safe getpwuid() function.
+   Returned value should be freed using pa_getpwuid_free() when the caller is
+   finished with the returned group data.
+
+   API is the same as getpwuid(), errors are indicated by a NULL return;
+   consult errno for the error cause (zero it before calling).
+   The returned value must be freed using pa_xfree().
+ */
+struct passwd *pa_getpwuid_malloc(uid_t uid) {
+    size_t buflen, getpw_buflen;
+    int err;
+    void *buf;
+    void *getpw_buf;
+    struct passwd *result = NULL;
+
+    buflen = starting_getpw_buflen();
+    buf = pa_xmalloc(buflen);
+
+    getpw_buflen = buflen - sizeof(struct passwd);
+    getpw_buf = (char *)buf + sizeof(struct passwd);
+
+    while ((err = getpwuid_r(uid, (struct passwd *)buf, getpw_buf,
+                    getpw_buflen, &result)) == ERANGE)
+    {
+        if (expand_buffer_trashcontents(&buf, &buflen))
+            break;
+
+        getpw_buflen = buflen - sizeof(struct passwd);
+        getpw_buf = (char *)buf + sizeof(struct passwd);
+    }
+
+    if (err || !result) {
+        result = NULL;
+        if (buf) {
+            pa_xfree(buf);
+            buf = NULL;
+        }
+    }
+
+    pa_assert(result == buf || result == NULL);
+
+    return result;
+}
+
+void pa_getpwuid_free(struct passwd *passwd) {
+    pa_xfree(passwd);
+}
+
+#else /* !HAVE_GETPWUID_R */
+
+struct passwd *pa_getpwuid_malloc(uid_t uid) {
+    return getpwuid(uid);
+}
+
+void pa_getpwuid_free(struct passwd *passwd) {
+    /* nothing */
+    return;
+}
+
+#endif /* !HAVE_GETPWUID_R */
+
+#endif /* HAVE_PWD_H */
diff --git a/src/pulsecore/usergroup.h b/src/pulsecore/usergroup.h
new file mode 100644
index 0000000..1c09163
--- /dev/null
+++ b/src/pulsecore/usergroup.h
@@ -0,0 +1,51 @@
+#ifndef foousergrouphfoo
+#define foousergrouphfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Ted Percival
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <sys/types.h>
+
+#ifndef PACKAGE
+#error "Please include config.h before including this file!"
+#endif
+
+#ifdef HAVE_GRP_H
+
+struct group *pa_getgrgid_malloc(gid_t gid);
+void pa_getgrgid_free(struct group *grp);
+
+struct group *pa_getgrnam_malloc(const char *name);
+void pa_getgrnam_free(struct group *group);
+
+#endif /* HAVE_GRP_H */
+
+#ifdef HAVE_PWD_H
+
+struct passwd *pa_getpwuid_malloc(uid_t uid);
+void pa_getpwuid_free(struct passwd *passwd);
+
+struct passwd *pa_getpwnam_malloc(const char *name);
+void pa_getpwnam_free(struct passwd *passwd);
+
+#endif /* HAVE_PWD_H */
+
+#endif /* foousergrouphfoo */
diff --git a/src/tests/usergroup-test.c b/src/tests/usergroup-test.c
new file mode 100644
index 0000000..a48b016
--- /dev/null
+++ b/src/tests/usergroup-test.c
@@ -0,0 +1,161 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Ted Percival
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+
+#include <pulsecore/usergroup.h>
+
+static int load_reference_structs(struct group **gr, struct passwd **pw) {
+    setpwent();
+    *pw = getpwent();
+    endpwent();
+
+    setgrent();
+    *gr = getgrent();
+    endgrent();
+
+    return (*gr && *pw) ? 0 : 1;
+}
+
+static int compare_group(const struct group *a, const struct group *b) {
+    char **amem, **bmem;
+
+    if (strcmp(a->gr_name, b->gr_name)) {
+        fprintf(stderr, "Group name mismatch: [%s] [%s]\n",
+                a->gr_name, b->gr_name);
+        return 1;
+    }
+
+    if (strcmp(a->gr_passwd, b->gr_passwd)) {
+        fprintf(stderr, "Group password mismatch: [%s] [%s]\n",
+                a->gr_passwd, b->gr_passwd);
+        return 1;
+    }
+
+    if (a->gr_gid != b->gr_gid) {
+        fprintf(stderr, "Gid mismatch: [%lu] [%lu]\n",
+                (unsigned long) a->gr_gid, (unsigned long) b->gr_gid);
+        return 1;
+    }
+
+    /* XXX: Assuming the group ordering is identical. */
+    for (amem = a->gr_mem, bmem = b->gr_mem; *amem && *bmem; ++amem, ++bmem) {
+        if (strcmp(*amem, *bmem)) {
+            fprintf(stderr, "Group member mismatch: [%s] [%s]\n",
+                    *amem, *bmem);
+            return 1;
+        }
+    }
+
+    if (*amem || *bmem) {
+        fprintf(stderr, "Mismatched group count\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static int compare_passwd(const struct passwd *a, const struct passwd *b) {
+    if (strcmp(a->pw_name, b->pw_name)) {
+        fprintf(stderr, "pw_name mismatch: [%s] [%s]\n", a->pw_name, b->pw_name);
+        return 1;
+    }
+
+    if (strcmp(a->pw_passwd, b->pw_passwd)) {
+        fprintf(stderr, "pw_passwd mismatch: [%s] [%s]\n", a->pw_passwd, b->pw_passwd);
+        return 1;
+    }
+
+    if (a->pw_uid != b->pw_uid) {
+        fprintf(stderr, "pw_uid mismatch: [%lu] [%lu]\n",
+		(unsigned long) a->pw_uid, (unsigned long) b->pw_uid);
+        return 1;
+    }
+
+    if (a->pw_gid != b->pw_gid) {
+        fprintf(stderr, "pw_gid mismatch: [%lu] [%lu]\n",
+		(unsigned long) a->pw_gid, (unsigned long) b->pw_gid);
+        return 1;
+    }
+
+    if (strcmp(a->pw_gecos, b->pw_gecos)) {
+        fprintf(stderr, "pw_gecos mismatch: [%s] [%s]\n", a->pw_gecos, b->pw_gecos);
+        return 1;
+    }
+
+    if (strcmp(a->pw_dir, b->pw_dir)) {
+        fprintf(stderr, "pw_dir mismatch: [%s] [%s]\n", a->pw_dir, b->pw_dir);
+        return 1;
+    }
+
+    if (strcmp(a->pw_shell, b->pw_shell)) {
+        fprintf(stderr, "pw_shell mismatch: [%s] [%s]\n", a->pw_shell, b->pw_shell);
+        return 1;
+    }
+
+    return 0;
+}
+
+int main(int argc, char *argv[]) {
+    struct group *gr;
+    struct passwd *pw;
+    int err;
+    struct group *reference_group = NULL;
+    struct passwd *reference_passwd = NULL;
+
+    err = load_reference_structs(&reference_group, &reference_passwd);
+    if (err)
+        return 77;
+
+    errno = 0;
+    gr = pa_getgrgid_malloc(reference_group->gr_gid);
+    if (compare_group(reference_group, gr))
+        return 1;
+    pa_getgrgid_free(gr);
+
+    errno = 0;
+    gr = pa_getgrnam_malloc(reference_group->gr_name);
+    if (compare_group(reference_group, gr))
+        return 1;
+    pa_getgrnam_free(gr);
+
+    errno = 0;
+    pw = pa_getpwuid_malloc(reference_passwd->pw_uid);
+    if (compare_passwd(reference_passwd, pw))
+        return 1;
+    pa_getpwuid_free(pw);
+
+    errno = 0;
+    pw = pa_getpwnam_malloc(reference_passwd->pw_name);
+    if (compare_passwd(reference_passwd, pw))
+        return 1;
+    pa_getpwnam_free(pw);
+
+    return 0;
+}

commit b96390fc9878db5c244256545f36fa14ea1f5276
Author: Finn Thain <fthain at telegraphics.com.au>
Date:   Fri Aug 21 18:13:11 2009 +1000

    Solaris: bootstrap portability
    
    On Fri, 21 Aug 2009, Colin Guthrie wrote:
    
    >
    > Just put an echo statement in there too. Should cover the bases for everyone.
    
    Something like this?

diff --git a/bootstrap.sh b/bootstrap.sh
index 970e884..c7c8582 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -47,9 +47,9 @@ case $(uname) in
 esac
 
 if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then
-    echo "Activating pre-commit hook."
-    cp -pv  .git/hooks/pre-commit.sample .git/hooks/pre-commit
-    chmod -v +x  .git/hooks/pre-commit
+    cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
+    chmod +x .git/hooks/pre-commit && \
+    echo "Activated pre-commit hook."
 fi
 
 if [ -f .tarball-version ]; then

commit 44c7aa55e25334901769b82355c12dee91cb3629
Author: Finn Thain <fthain at telegraphics.com.au>
Date:   Fri Aug 21 13:15:38 2009 +1000

    Solaris: build fixes (resent)
    
    Fix bit rot due to recent flat volume changes.

diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c
index 0920d25..2c878c2 100644
--- a/src/modules/module-solaris.c
+++ b/src/modules/module-solaris.c
@@ -479,7 +479,7 @@ static void sink_set_volume(pa_sink *s) {
     if (u->fd >= 0) {
         AUDIO_INITINFO(&info);
 
-        info.play.gain = pa_cvolume_max(&s->virtual_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
+        info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
         assert(info.play.gain <= AUDIO_MAX_GAIN);
 
         if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
@@ -501,8 +501,7 @@ static void sink_get_volume(pa_sink *s) {
         if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
         else
-            pa_cvolume_set(&s->virtual_volume, s->sample_spec.channels,
-                info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
+            pa_cvolume_set(&s->real_volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
     }
 }
 
@@ -515,7 +514,7 @@ static void source_set_volume(pa_source *s) {
     if (u->fd >= 0) {
         AUDIO_INITINFO(&info);
 
-        info.play.gain = pa_cvolume_max(&s->virtual_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
+        info.play.gain = pa_cvolume_max(&s->volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
         assert(info.play.gain <= AUDIO_MAX_GAIN);
 
         if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
@@ -537,8 +536,7 @@ static void source_get_volume(pa_source *s) {
         if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
         else
-            pa_cvolume_set(&s->virtual_volume, s->sample_spec.channels,
-                info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
+            pa_cvolume_set(&s->volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
     }
 }
 
@@ -797,7 +795,7 @@ static void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void
     pa_log_debug("caught signal");
 
     if (u->sink) {
-        pa_sink_get_volume(u->sink, TRUE, FALSE);
+        pa_sink_get_volume(u->sink, TRUE);
         pa_sink_get_mute(u->sink, TRUE);
     }
 

commit 87d2dded9b90331943a6c7b9d8d9b1ac100b6689
Author: Finn Thain <fthain at telegraphics.com.au>
Date:   Fri Aug 21 13:17:03 2009 +1000

    Solaris: use smoother (resent)
    
    Make use of the smoother, just in case.

diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c
index 2c878c2..3bf7c4b 100644
--- a/src/modules/module-solaris.c
+++ b/src/modules/module-solaris.c
@@ -60,6 +60,7 @@
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/thread.h>
+#include <pulsecore/time-smoother.h>
 
 #include "module-solaris-symdef.h"
 
@@ -110,6 +111,8 @@ struct userdata {
     uint32_t prev_playback_samples, prev_record_samples;
 
     int32_t minimum_request;
+
+    pa_smoother *smoother;
 };
 
 static const char* const valid_modargs[] = {
@@ -145,7 +148,12 @@ static uint64_t get_playback_buffered_bytes(struct userdata *u) {
 
     /* Handle wrap-around of the device's sample counter, which is a uint_32. */
     if (u->prev_playback_samples > info.play.samples) {
-        /* Unfortunately info.play.samples can sometimes go backwards, even before it wraps! */
+        /*
+         * Unfortunately info.play.samples can sometimes go backwards, even before it wraps!
+         * The bug seems to be absent on Solaris x86 nv117 with audio810 driver, at least on this (UP) machine.
+         * The bug is present on a different (SMP) machine running Solaris x86 nv103 with audioens driver.
+         * An earlier revision of this file mentions the same bug independently (unknown configuration).
+         */
         if (u->prev_playback_samples + info.play.samples < 240000) {
             ++u->play_samples_msw;
         } else {
@@ -155,6 +163,8 @@ static uint64_t get_playback_buffered_bytes(struct userdata *u) {
     u->prev_playback_samples = info.play.samples;
     played_bytes = (((uint64_t)u->play_samples_msw << 32) + info.play.samples) * u->frame_size;
 
+    pa_smoother_put(u->smoother, pa_rtclock_now(), pa_bytes_to_usec(played_bytes, &u->sink->sample_spec));
+
     return u->written_bytes - played_bytes;
 }
 
@@ -387,6 +397,8 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 
                     pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state));
 
+                    pa_smoother_pause(u->smoother, pa_rtclock_now());
+
                     if (!u->source || u->source_suspended) {
                         if (suspend(u) < 0)
                             return -1;
@@ -398,6 +410,8 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
                 case PA_SINK_RUNNING:
 
                     if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
+                        pa_smoother_resume(u->smoother, pa_rtclock_now(), TRUE);
+
                         if (!u->source || u->source_suspended) {
                             if (unsuspend(u) < 0)
                                 return -1;
@@ -604,11 +618,13 @@ static void thread_func(void *userdata) {
 
     pa_thread_mq_install(&u->thread_mq);
 
+    pa_smoother_set_time_offset(u->smoother, pa_rtclock_now());
+
     for (;;) {
         /* Render some data and write it to the dsp */
 
         if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
-            pa_usec_t xtime0;
+            pa_usec_t xtime0, ysleep_interval, xsleep_interval;
             uint64_t buffered_bytes;
 
             if (u->sink->thread_info.rewind_requested)
@@ -627,6 +643,8 @@ static void thread_func(void *userdata) {
                 info.play.error = 0;
                 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
                     pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
+
+                pa_smoother_reset(u->smoother, pa_rtclock_now(), TRUE);
             }
 
             for (;;) {
@@ -689,7 +707,9 @@ static void thread_func(void *userdata) {
                 }
             }
 
-            pa_rtpoll_set_timer_absolute(u->rtpoll, xtime0 + pa_bytes_to_usec(buffered_bytes / 2, &u->sink->sample_spec));
+            ysleep_interval = pa_bytes_to_usec(buffered_bytes / 2, &u->sink->sample_spec);
+            xsleep_interval = pa_smoother_translate(u->smoother, xtime0, ysleep_interval);
+            pa_rtpoll_set_timer_absolute(u->rtpoll, xtime0 + PA_MIN(xsleep_interval, ysleep_interval));
         } else
             pa_rtpoll_set_timer_disabled(u->rtpoll);
 
@@ -836,6 +856,9 @@ int pa__init(pa_module *m) {
 
     u = pa_xnew0(struct userdata, 1);
 
+    if (!(u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC * 2, TRUE, TRUE, 10, pa_rtclock_now(), TRUE)))
+        goto fail;
+
     /*
      * For a process (or several processes) to use the same audio device for both
      * record and playback at the same time, the device's mixer must be enabled.
@@ -1073,6 +1096,9 @@ void pa__done(pa_module *m) {
     if (u->fd >= 0)
         close(u->fd);
 
+    if (u->smoother)
+        pa_smoother_free(u->smoother);
+
     pa_xfree(u->device_name);
 
     pa_xfree(u);

commit 601fb63b0160d3d76083d07dcc1201a123031915
Author: Finn Thain <fthain at telegraphics.com.au>
Date:   Fri Aug 21 13:18:40 2009 +1000

    Solaris: fixed latency (resent)
    
    Set a fixed latency based on the given buffer size, which is constrained to
    the 128 KB limit on buffered writes. Also fix an error path.

diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c
index 3bf7c4b..71f1407 100644
--- a/src/modules/module-solaris.c
+++ b/src/modules/module-solaris.c
@@ -136,6 +136,9 @@ static const char* const valid_modargs[] = {
 #define MAX_RENDER_HZ   (300)
 /* This render rate limit imposes a minimum latency, but without it we waste too much CPU time. */
 
+#define MAX_BUFFER_SIZE (128 * 1024)
+/* An attempt to buffer more than 128 KB causes write() to fail with errno == EAGAIN. */
+
 static uint64_t get_playback_buffered_bytes(struct userdata *u) {
     audio_info_t info;
     uint64_t played_bytes;
@@ -651,6 +654,7 @@ static void thread_func(void *userdata) {
                 void *p;
                 ssize_t w;
                 size_t len;
+                int write_type = 1;
 
                 /*
                  * Since we cannot modify the size of the output buffer we fake it
@@ -668,38 +672,31 @@ static void thread_func(void *userdata) {
                     break;
 
                 if (u->memchunk.length < len)
-                    pa_sink_render(u->sink, u->sink->thread_info.max_request, &u->memchunk);
+                    pa_sink_render(u->sink, len - u->memchunk.length, &u->memchunk);
+
+                len = PA_MIN(u->memchunk.length, len);
 
                 p = pa_memblock_acquire(u->memchunk.memblock);
-                w = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, NULL);
+                w = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, len, &write_type);
                 pa_memblock_release(u->memchunk.memblock);
 
                 if (w <= 0) {
-                    switch (errno) {
-                        case EINTR:
-                            continue;
-                        case EAGAIN:
-                            /* If the buffer_size is too big, we get EAGAIN. Avoiding that limit by trial and error
-                             * is not ideal, but I don't know how to get the system to tell me what the limit is.
-                             */
-                            u->buffer_size = u->buffer_size * 18 / 25;
-                            u->buffer_size -= u->buffer_size % u->frame_size;
-                            u->buffer_size = PA_MAX(u->buffer_size, 2 * u->minimum_request);
-                            pa_sink_set_max_request_within_thread(u->sink, u->buffer_size);
-                            pa_sink_set_max_rewind_within_thread(u->sink, u->buffer_size);
-                            pa_log("EAGAIN. Buffer size is now %u bytes (%llu buffered)", u->buffer_size, buffered_bytes);
-                            break;
-                        default:
-                            pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno));
-                            goto fail;
+                    if (errno == EINTR) {
+                        continue;
+                    } else if (errno == EAGAIN) {
+                        /* We may have realtime priority so yield the CPU to ensure that fd can become writable again. */
+                        pa_log_debug("EAGAIN with %llu bytes buffered.", buffered_bytes);
+                        break;
+                    } else {
+                        pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno));
+                        goto fail;
                     }
                 } else {
                     pa_assert(w % u->frame_size == 0);
 
                     u->written_bytes += w;
-                    u->memchunk.length -= w;
-
                     u->memchunk.index += w;
+                    u->memchunk.length -= w;
                     if (u->memchunk.length <= 0) {
                         pa_memblock_unref(u->memchunk.memblock);
                         pa_memchunk_reset(&u->memchunk);
@@ -830,7 +827,7 @@ int pa__init(pa_module *m) {
     pa_channel_map map;
     pa_modargs *ma = NULL;
     uint32_t buffer_length_msec;
-    int fd;
+    int fd = -1;
     pa_sink_new_data sink_new_data;
     pa_source_new_data source_new_data;
     char const *name;
@@ -882,7 +879,13 @@ int pa__init(pa_module *m) {
     }
     u->buffer_size = pa_usec_to_bytes(1000 * buffer_length_msec, &ss);
     if (u->buffer_size < 2 * u->minimum_request) {
-        pa_log("supplied buffer size argument is too small");
+        pa_log("buffer_length argument cannot be smaller than %u",
+               (unsigned)(pa_bytes_to_usec(2 * u->minimum_request, &ss) / 1000));
+        goto fail;
+    }
+    if (u->buffer_size > MAX_BUFFER_SIZE) {
+        pa_log("buffer_length argument cannot be greater than %u",
+               (unsigned)(pa_bytes_to_usec(MAX_BUFFER_SIZE, &ss) / 1000));
         goto fail;
     }
 
@@ -945,6 +948,7 @@ int pa__init(pa_module *m) {
 
         pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
         pa_source_set_rtpoll(u->source, u->rtpoll);
+        pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &u->source->sample_spec));
 
         u->source->get_volume = source_get_volume;
         u->source->set_volume = source_set_volume;
@@ -987,15 +991,15 @@ int pa__init(pa_module *m) {
 
         pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
         pa_sink_set_rtpoll(u->sink, u->rtpoll);
+        pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->buffer_size, &u->sink->sample_spec));
+        pa_sink_set_max_request(u->sink, u->buffer_size);
+        pa_sink_set_max_rewind(u->sink, u->buffer_size);
 
         u->sink->get_volume = sink_get_volume;
         u->sink->set_volume = sink_set_volume;
         u->sink->get_mute = sink_get_mute;
         u->sink->set_mute = sink_set_mute;
         u->sink->refresh_volume = u->sink->refresh_muted = TRUE;
-
-        pa_sink_set_max_request(u->sink, u->buffer_size);
-        pa_sink_set_max_rewind(u->sink, u->buffer_size);
     } else
         u->sink = NULL;
 

commit 17dc410e8874d38ce7a9882245360314a8251e06
Author: Ted Percival <ted at midg3t.net>
Date:   Fri Aug 21 17:05:41 2009 -0600

    core: Remove wrong doc on how to free returned data

diff --git a/src/pulsecore/usergroup.c b/src/pulsecore/usergroup.c
index bf686b7..71b13bc 100644
--- a/src/pulsecore/usergroup.c
+++ b/src/pulsecore/usergroup.c
@@ -128,7 +128,6 @@ static int expand_buffer_trashcontents(void **bufptr, size_t *buflenptr) {
 
    API is the same as getgrgid(), errors are indicated by a NULL return;
    consult errno for the error cause (zero it before calling).
-   The returned value must be freed using pa_xfree().
  */
 struct group *pa_getgrgid_malloc(gid_t gid) {
     size_t buflen, getgr_buflen;
@@ -190,7 +189,6 @@ void pa_getgrgid_free(struct group *grp) {
 
    API is the same as getgrnam(), errors are indicated by a NULL return;
    consult errno for the error cause (zero it before calling).
-   The returned value must be freed using pa_xfree().
  */
 struct group *pa_getgrnam_malloc(const char *name) {
     size_t buflen, getgr_buflen;
@@ -256,7 +254,6 @@ void pa_getgrnam_free(struct group *group) {
 
    API is the same as getpwnam(), errors are indicated by a NULL return;
    consult errno for the error cause (zero it before calling).
-   The returned value must be freed using pa_xfree().
  */
 struct passwd *pa_getpwnam_malloc(const char *name) {
     size_t buflen, getpw_buflen;
@@ -318,7 +315,6 @@ void pa_getpwnam_free(struct passwd *passwd) {
 
    API is the same as getpwuid(), errors are indicated by a NULL return;
    consult errno for the error cause (zero it before calling).
-   The returned value must be freed using pa_xfree().
  */
 struct passwd *pa_getpwuid_malloc(uid_t uid) {
     size_t buflen, getpw_buflen;

commit aa5429805f88bcade639e5e8667b79a07ec104b6
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Aug 22 03:16:47 2009 +0200

    daemon: don't free script_commands twice

diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c
index 3ebc927..f6cdcdc 100644
--- a/src/daemon/cmdline.c
+++ b/src/daemon/cmdline.c
@@ -385,11 +385,6 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
     pa_xfree(conf->script_commands);
     conf->script_commands = pa_strbuf_tostring_free(buf);
 
-    if (conf->script_commands) {
-        pa_xfree(conf->script_commands);
-        conf->script_commands = NULL;
-    }
-
     *d = optind;
 
     return 0;

commit 2595b9d98569e62f4d375ced1d3f7c7af34efa74
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Aug 22 03:17:24 2009 +0200

    add usergroup-test to .gitignore

diff --git a/src/.gitignore b/src/.gitignore
index 8233152..6cd173c 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,3 +1,4 @@
+usergroup-test
 sigbus-test
 TAGS
 alsa-time-test

commit 5b0683d6cd103a7a91bc2e88bcc9f77750d10c25
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Aug 22 04:03:31 2009 +0200

    ladspa/remap: handle failing stream moves properly

diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c
index 233f90c..aa28f7f 100644
--- a/src/modules/module-ladspa-sink.c
+++ b/src/modules/module-ladspa-sink.c
@@ -418,8 +418,11 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
-    pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-    pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+    if (dest) {
+        pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
+        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+    } else
+        pa_sink_set_asyncmsgq(u->sink, NULL);
 }
 
 /* Called from main context */
diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c
index 0b4fdc9..becff55 100644
--- a/src/modules/module-remap-sink.c
+++ b/src/modules/module-remap-sink.c
@@ -302,8 +302,11 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
-    pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
-    pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+    if (dest) {
+        pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
+        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+    } else
+        pa_sink_set_asyncmsgq(u->sink, NULL);
 }
 
 int pa__init(pa_module*m) {

commit 1a05d67f07fb4bfa6e419791cf5609d608f536cd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Aug 22 04:04:23 2009 +0200

    core: relex validity checks when destructing half-set up source outputs/sink inputs

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 4137a42..0ad95e6 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -487,7 +487,10 @@ static void sink_input_free(pa_object *o) {
 
     pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
 
-    pa_assert(!i->thread_info.attached);
+    /* Side note: this function must be able to destruct properly any
+     * kind of sink input in any state, even those which are
+     * "half-moved" or are connected to sinks that have no asyncmsgq
+     * and are hence half-destructed themselves! */
 
     if (i->thread_info.render_memblockq)
         pa_memblockq_free(i->thread_info.render_memblockq);
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index b029861..4373340 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -359,8 +359,6 @@ static void source_output_free(pa_object* mo) {
 
     pa_log_info("Freeing output %u \"%s\"", o->index, pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME)));
 
-    pa_assert(!o->thread_info.attached);
-
     if (o->thread_info.delay_memblockq)
         pa_memblockq_free(o->thread_info.delay_memblockq);
 

commit 560da5b0a1386c2a158d69b6ba0ef99c0f03bbf4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Aug 22 21:59:17 2009 +0200

    udev: process all inotify events queued up, not just the first one in the queue

diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c
index 1d67c0c..5513634 100644
--- a/src/modules/module-udev-detect.c
+++ b/src/modules/module-udev-detect.c
@@ -325,6 +325,7 @@ static void inotify_cb(
 
     for (;;) {
         ssize_t r;
+        struct inotify_event *event;
 
         pa_zero(buf);
         if ((r = pa_read(fd, &buf, sizeof(buf), &type)) <= 0) {
@@ -336,23 +337,44 @@ static void inotify_cb(
             goto fail;
         }
 
-        /* From udev we get the guarantee that the control
-         * device's ACL is changes last. To avoid races when ACLs
-         * are changed we hence watch only the control device */
-        if (((buf.e.mask & IN_ATTRIB) && pa_startswith(buf.e.name, "controlC")))
-            PA_HASHMAP_FOREACH(d, u->devices, state)
-                if (control_node_belongs_to_device(d, buf.e.name))
-                    d->need_verify = TRUE;
-
-        /* ALSA doesn't really give us any guarantee on the closing
-         * order, so let's simply hope */
-        if (((buf.e.mask & IN_CLOSE_WRITE) && pa_startswith(buf.e.name, "pcmC")))
-            PA_HASHMAP_FOREACH(d, u->devices, state)
-                if (pcm_node_belongs_to_device(d, buf.e.name))
-                    d->need_verify = TRUE;
-
-        if ((buf.e.mask & (IN_DELETE_SELF|IN_MOVE_SELF)))
-            deleted = TRUE;
+        event = &buf.e;
+        while (r > 0) {
+            size_t len;
+
+            if ((size_t) r < sizeof(struct inotify_event)) {
+                pa_log("read() too short.");
+                goto fail;
+            }
+
+            len = sizeof(struct inotify_event) + event->len;
+
+            if ((size_t) r < len) {
+                pa_log("Payload missing.");
+                goto fail;
+            }
+
+            /* From udev we get the guarantee that the control
+             * device's ACL is changed last. To avoid races when ACLs
+             * are changed we hence watch only the control device */
+            if (((event->mask & IN_ATTRIB) && pa_startswith(event->name, "controlC")))
+                PA_HASHMAP_FOREACH(d, u->devices, state)
+                    if (control_node_belongs_to_device(d, event->name))
+                        d->need_verify = TRUE;
+
+            /* ALSA doesn't really give us any guarantee on the closing
+             * order, so let's simply hope */
+            if (((event->mask & IN_CLOSE_WRITE) && pa_startswith(event->name, "pcmC")))
+                PA_HASHMAP_FOREACH(d, u->devices, state)
+                    if (pcm_node_belongs_to_device(d, event->name))
+                        d->need_verify = TRUE;
+
+            /* /dev/snd/ might have been removed */
+            if ((event->mask & (IN_DELETE_SELF|IN_MOVE_SELF)))
+                deleted = TRUE;
+
+            event = (struct inotify_event*) ((uint8_t*) event + len);
+            r -= len;
+        }
     }
 
     PA_HASHMAP_FOREACH(d, u->devices, state)

commit d6fb8d10819bebc1cee203de7330cceeafde9fed
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Aug 22 23:10:45 2009 +0200

    udev: check busy status of alsa cards before loading alsa modules and hence initiating profile probing

diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c
index 5513634..b41b9c0 100644
--- a/src/modules/module-udev-detect.c
+++ b/src/modules/module-udev-detect.c
@@ -25,6 +25,7 @@
 
 #include <errno.h>
 #include <limits.h>
+#include <dirent.h>
 #include <sys/inotify.h>
 #include <libudev.h>
 
@@ -45,8 +46,7 @@ PA_MODULE_USAGE(
 
 struct device {
     char *path;
-    pa_bool_t accessible:1;
-    pa_bool_t need_verify:1;
+    pa_bool_t need_verify;
     char *card_name;
     char *args;
     uint32_t module;
@@ -99,34 +99,150 @@ static const char *path_get_card_id(const char *path) {
     return e + 5;
 }
 
+static pa_bool_t is_card_busy(const char *id) {
+    char *card_path = NULL, *pcm_path = NULL, *sub_status = NULL;
+    DIR *card_dir = NULL, *pcm_dir = NULL;
+    FILE *status_file = NULL;
+    size_t len;
+    struct dirent *space = NULL, *de;
+    pa_bool_t busy = FALSE;
+    int r;
+
+    pa_assert(id);
+
+    card_path = pa_sprintf_malloc("/proc/asound/card%s", id);
+
+    if (!(card_dir = opendir(card_path))) {
+        pa_log_warn("Failed to open %s: %s", card_path, pa_cstrerror(errno));
+        goto fail;
+    }
+
+    len = offsetof(struct dirent, d_name) + fpathconf(dirfd(card_dir), _PC_NAME_MAX) + 1;
+    space = pa_xmalloc(len);
+
+    for (;;) {
+        de = NULL;
+
+        if ((r = readdir_r(card_dir, space, &de)) != 0) {
+            pa_log_warn("readdir_r() failed: %s", pa_cstrerror(r));
+            goto fail;
+        }
+
+        if (!de)
+            break;
+
+        if (!pa_startswith(de->d_name, "pcm"))
+            continue;
+
+        pa_xfree(pcm_path);
+        pcm_path = pa_sprintf_malloc("%s/%s", card_path, de->d_name);
+
+        if (pcm_dir)
+            closedir(pcm_dir);
+
+        if (!(pcm_dir = opendir(pcm_path))) {
+            pa_log_warn("Failed to open %s: %s", pcm_path, pa_cstrerror(errno));
+            continue;
+        }
+
+        for (;;) {
+            char line[32];
+
+            if ((r = readdir_r(pcm_dir, space, &de)) != 0) {
+                pa_log_warn("readdir_r() failed: %s", pa_cstrerror(r));
+                goto fail;
+            }
+
+            if (!de)
+                break;
+
+            if (!pa_startswith(de->d_name, "sub"))
+                continue;
+
+            pa_xfree(sub_status);
+            sub_status = pa_sprintf_malloc("%s/%s/status", pcm_path, de->d_name);
+
+            if (status_file)
+                fclose(status_file);
+
+            if (!(status_file = fopen(sub_status, "r"))) {
+                pa_log_warn("Failed to open %s: %s", sub_status, pa_cstrerror(errno));
+                continue;
+            }
+
+            if (!(fgets(line, sizeof(line)-1, status_file))) {
+                pa_log_warn("Failed to read from %s: %s", sub_status, pa_cstrerror(errno));
+                continue;
+            }
+
+            if (!pa_streq(line, "closed\n")) {
+                busy = TRUE;
+                break;
+            }
+        }
+    }
+
+fail:
+
+    pa_xfree(card_path);
+    pa_xfree(pcm_path);
+    pa_xfree(sub_status);
+    pa_xfree(space);
+
+    if (card_dir)
+        closedir(card_dir);
+
+    if (pcm_dir)
+        closedir(pcm_dir);
+
+    if (status_file)
+        fclose(status_file);
+
+    return busy;
+}
+
 static void verify_access(struct userdata *u, struct device *d) {
     char *cd;
     pa_card *card;
+    pa_bool_t accessible;
 
     pa_assert(u);
     pa_assert(d);
 
     cd = pa_sprintf_malloc("%s/snd/controlC%s", udev_get_dev_path(u->udev), path_get_card_id(d->path));
-    d->accessible = access(cd, R_OK|W_OK) >= 0;
+    accessible = access(cd, R_OK|W_OK) >= 0;
+    pa_log_debug("%s is accessible: %s", cd, pa_yes_no(accessible));
 
-    pa_log_info("%s is accessible: %s", cd, pa_yes_no(d->accessible));
     pa_xfree(cd);
 
     if (d->module == PA_INVALID_INDEX) {
 
-        /* If we not loaded, try to load */
+        /* If we are not loaded, try to load */
 
-        if (d->accessible) {
+        if (accessible) {
             pa_module *m;
-
-            pa_log_debug("Loading module-alsa-card with arguments '%s'", d->args);
-            m = pa_module_load(u->core, "module-alsa-card", d->args);
-
-            if (m) {
-                d->module = m->index;
-                pa_log_info("Card %s (%s) module loaded.", d->path, d->card_name);
-            } else
-                pa_log_info("Card %s (%s) failed to load module.", d->path, d->card_name);
+            pa_bool_t busy;
+
+            /* Check if any of the PCM devices that belong to this
+             * card are currently busy. If they are, don't try to load
+             * right now, to make sure the probing phase can
+             * successfully complete. When the current user of the
+             * device closes it we will get another notification via
+             * inotify and can then recheck. */
+
+            busy = is_card_busy(path_get_card_id(d->path));
+            pa_log_debug("%s is busy: %s", d->path, pa_yes_no(busy));
+
+            if (!busy) {
+                pa_log_debug("Loading module-alsa-card with arguments '%s'", d->args);
+                m = pa_module_load(u->core, "module-alsa-card", d->args);
+
+                if (m) {
+                    d->module = m->index;
+                    pa_log_info("Card %s (%s) module loaded.", d->path, d->card_name);
+                } else
+                    pa_log_info("Card %s (%s) failed to load module.", d->path, d->card_name);
+            }
         }
 
     } else {
@@ -135,7 +251,7 @@ static void verify_access(struct userdata *u, struct device *d) {
          * accessible boolean */
 
         if ((card = pa_namereg_get(u->core, d->card_name, PA_NAMEREG_CARD)))
-            pa_card_suspend(card, !d->accessible, PA_SUSPEND_SESSION);
+            pa_card_suspend(card, !accessible, PA_SUSPEND_SESSION);
     }
 }
 
@@ -160,7 +276,6 @@ static void card_changed(struct userdata *u, struct udev_device *dev) {
 
     d = pa_xnew0(struct device, 1);
     d->path = pa_xstrdup(path);
-    d->accessible = TRUE;
     d->module = PA_INVALID_INDEX;
 
     if (!(t = udev_device_get_property_value(dev, "PULSE_NAME")))

commit ab5ac06ac76c3afbbd99bce2840329dd74756a73
Merge: d6fb8d1 6076cef
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Aug 23 00:06:35 2009 +0200

    Merge commit 'wtay/optimize'


commit a0f01ddc951694e1d13f44dc3a5d0d3fb2daa142
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Aug 23 21:49:37 2009 +0200

    port a few things over to use xmalloc and friends instead of low-level libc malloc/free directly

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 0eb32cc..1c8c678 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -2223,7 +2223,7 @@ int pa_close_all(int except_fd, ...) {
     va_end(ap);
 
     r = pa_close_allv(p);
-    free(p);
+    pa_xfree(p);
 
     return r;
 }
diff --git a/src/pulsecore/cpu-arm.c b/src/pulsecore/cpu-arm.c
index 5a994b7..453b784 100644
--- a/src/pulsecore/cpu-arm.c
+++ b/src/pulsecore/cpu-arm.c
@@ -2,7 +2,7 @@
   This file is part of PulseAudio.
 
   Copyright 2004-2006 Lennart Poettering
-  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk> 
+  Copyright 2009 Wim Taymans <wim.taymans at collabora.co.uk>
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
@@ -60,21 +60,20 @@ static char *get_cpuinfo(void) {
     char *cpuinfo;
     int n, fd;
 
-    if (!(cpuinfo = malloc(MAX_BUFFER)))
-         return NULL;
+    cpuinfo = pa_xmalloc(MAX_BUFFER);
 
     if ((fd = open("/proc/cpuinfo", O_RDONLY)) < 0) {
-        free (cpuinfo);
+        pa_xfree(cpuinfo);
         return NULL;
     }
 
-    if ((n = read(fd, cpuinfo, MAX_BUFFER-1)) < 0) {
-        free (cpuinfo);
-        close (fd);
+    if ((n = pa_read(fd, cpuinfo, MAX_BUFFER-1)) < 0) {
+        pa_xfree(cpuinfo);
+        pa_close(fd);
         return NULL;
     }
     cpuinfo[n] = 0;
-    close (fd);
+    pa_close(fd);
 
     return cpuinfo;
 }
@@ -102,7 +101,7 @@ void pa_cpu_init_arm (void) {
         if (arch >= 7)
             flags |= PA_CPU_ARM_V7;
 
-        free (line);
+        pa_xfree(line);
     }
     /* get the CPU features */
     if ((line = get_cpuinfo_line (cpuinfo, "Features"))) {
@@ -118,10 +117,10 @@ void pa_cpu_init_arm (void) {
             else if (!strcmp (current, "vfpv3"))
                 flags |= PA_CPU_ARM_VFPV3;
 
-            free (current);
+            pa_xfree(current);
         }
     }
-    free (cpuinfo);
+    pa_xfree(cpuinfo);
 
     pa_log_info ("CPU flags: %s%s%s%s%s%s",
           (flags & PA_CPU_ARM_V6) ? "V6 " : "",

commit 80c693730365c1a375a5c0e781f38e7f165b37bf
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Aug 23 22:34:42 2009 +0200

    alsa: increase interval between smoother updates exponentially for alsa sources, following the scheme for sinks

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index c369472..b99ed78 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -733,10 +733,9 @@ static void update_smoother(struct userdata *u) {
         now1 = pa_rtclock_now();
 
     /* check if the time since the last update is bigger than the interval */
-    if (u->last_smoother_update > 0) {
+    if (u->last_smoother_update > 0)
         if (u->last_smoother_update + u->smoother_interval > now1)
             return;
-    }
 
     position = (int64_t) u->write_count - ((int64_t) delay * (int64_t) u->frame_size);
 
@@ -745,11 +744,11 @@ static void update_smoother(struct userdata *u) {
 
     now2 = pa_bytes_to_usec((uint64_t) position, &u->sink->sample_spec);
 
+    pa_smoother_put(u->smoother, now1, now2);
+
     u->last_smoother_update = now1;
     /* exponentially increase the update interval up to the MAX limit */
     u->smoother_interval = PA_MIN (u->smoother_interval * 2, SMOOTHER_MAX_INTERVAL);
-
-    pa_smoother_put(u->smoother, now1, now2);
 }
 
 static pa_usec_t sink_get_latency(struct userdata *u) {
@@ -927,7 +926,6 @@ static int unsuspend(struct userdata *u) {
     u->first = TRUE;
     u->since_start = 0;
 
-
     pa_log_info("Resumed successfully...");
 
     return 0;
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 7da3755..336027a 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -65,6 +65,9 @@
 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)          /* 10ms */
 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)          /* 4ms */
 
+#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)           /* 2ms */
+#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)         /* 200ms */
+
 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100)
 
 struct userdata {
@@ -108,6 +111,8 @@ struct userdata {
 
     pa_smoother *smoother;
     uint64_t read_count;
+    pa_usec_t smoother_interval;
+    pa_usec_t last_smoother_update;
 
     pa_reserve_wrapper *reserve;
     pa_hook_slot *reserve_slot;
@@ -691,15 +696,23 @@ static void update_smoother(struct userdata *u) {
         now1 = pa_timespec_load(&htstamp);
     }
 
-    position = u->read_count + ((uint64_t) delay * (uint64_t) u->frame_size);
-
     /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
     if (now1 <= 0)
         now1 = pa_rtclock_now();
 
+    /* check if the time since the last update is bigger than the interval */
+    if (u->last_smoother_update > 0)
+        if (u->last_smoother_update + u->smoother_interval > now1)
+            return;
+
+    position = u->read_count + ((uint64_t) delay * (uint64_t) u->frame_size);
     now2 = pa_bytes_to_usec(position, &u->source->sample_spec);
 
     pa_smoother_put(u->smoother, now1, now2);
+
+    u->last_smoother_update = now1;
+    /* exponentially increase the update interval up to the MAX limit */
+    u->smoother_interval = PA_MIN (u->smoother_interval * 2, SMOOTHER_MAX_INTERVAL);
 }
 
 static pa_usec_t source_get_latency(struct userdata *u) {
@@ -862,6 +875,8 @@ static int unsuspend(struct userdata *u) {
 
     u->read_count = 0;
     pa_smoother_reset(u->smoother, pa_rtclock_now(), TRUE);
+    u->smoother_interval = SMOOTHER_MIN_INTERVAL;
+    u->last_smoother_update = 0;
 
     pa_log_info("Resumed successfully...");
 
@@ -1469,6 +1484,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
             5,
             pa_rtclock_now(),
             FALSE);
+    u->smoother_interval = SMOOTHER_MIN_INTERVAL;
 
     dev_id = pa_modargs_get_value(
             ma, "device_id",

commit 050a3a99e1d151b4f55c89f82073ef33f3399646
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Aug 24 03:26:56 2009 +0200

    alsa: automatically decrease watermark after a time of stability

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index b99ed78..07d5388 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -62,14 +62,21 @@
 /* #define DEBUG_TIMING */
 
 #define DEFAULT_DEVICE "default"
-#define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC)            /* 2s   -- Overall buffer size */
-#define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC)       /* 20ms -- Fill up when only this much is left in the buffer */
-#define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC)          /* 10ms -- On underrun, increase watermark by this */
-#define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)               /* 10ms -- Sleep at least 10ms on each iteration */
-#define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)               /* 4ms  -- Wakeup at least this long before the buffer runs empty*/
 
-#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)                /* 2ms -- min smoother update interval */
-#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)              /* 200ms -- max smoother update inteval */
+#define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC)             /* 2s    -- Overall buffer size */
+#define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC)        /* 20ms  -- Fill up when only this much is left in the buffer */
+
+#define TSCHED_WATERMARK_INC_STEP_USEC (10*PA_USEC_PER_MSEC)       /* 10ms  -- On underrun, increase watermark by this */
+#define TSCHED_WATERMARK_DEC_STEP_USEC (5*PA_USEC_PER_MSEC)        /* 5ms   -- When everything's great, decrease watermark by this */
+#define TSCHED_WATERMARK_VERIFY_AFTER_USEC (20*PA_USEC_PER_SEC)    /* 20s   -- How long after a drop out recheck if things are good now */
+#define TSCHED_WATERMARK_INC_THRESHOLD_USEC (1*PA_USEC_PER_MSEC)   /* 3ms   -- If the buffer level ever below this theshold, increase the watermark */
+#define TSCHED_WATERMARK_DEC_THRESHOLD_USEC (100*PA_USEC_PER_MSEC) /* 100ms -- If the buffer level didn't drop below this theshold in the verification time, decrease the watermark */
+
+#define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)                /* 10ms  -- Sleep at least 10ms on each iteration */
+#define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)                /* 4ms   -- Wakeup at least this long before the buffer runs empty*/
+
+#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)                 /* 2ms   -- min smoother update interval */
+#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)               /* 200ms -- max smoother update inteval */
 
 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100)  /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */
 
@@ -99,7 +106,12 @@ struct userdata {
         hwbuf_unused,
         min_sleep,
         min_wakeup,
-        watermark_step;
+        watermark_inc_step,
+        watermark_dec_step,
+        watermark_inc_threshold,
+        watermark_dec_threshold;
+
+    pa_usec_t watermark_dec_not_before;
 
     unsigned nfragments;
     pa_memchunk memchunk;
@@ -248,6 +260,7 @@ static void fix_min_sleep_wakeup(struct userdata *u) {
     size_t max_use, max_use_2;
 
     pa_assert(u);
+    pa_assert(u->use_tsched);
 
     max_use = u->hwbuf_size - u->hwbuf_unused;
     max_use_2 = pa_frame_align(max_use/2, &u->sink->sample_spec);
@@ -262,6 +275,7 @@ static void fix_min_sleep_wakeup(struct userdata *u) {
 static void fix_tsched_watermark(struct userdata *u) {
     size_t max_use;
     pa_assert(u);
+    pa_assert(u->use_tsched);
 
     max_use = u->hwbuf_size - u->hwbuf_unused;
 
@@ -272,7 +286,7 @@ static void fix_tsched_watermark(struct userdata *u) {
         u->tsched_watermark = u->min_wakeup;
 }
 
-static void adjust_after_underrun(struct userdata *u) {
+static void increase_watermark(struct userdata *u) {
     size_t old_watermark;
     pa_usec_t old_min_latency, new_min_latency;
 
@@ -281,31 +295,64 @@ static void adjust_after_underrun(struct userdata *u) {
 
     /* First, just try to increase the watermark */
     old_watermark = u->tsched_watermark;
-    u->tsched_watermark = PA_MIN(u->tsched_watermark * 2, u->tsched_watermark + u->watermark_step);
+    u->tsched_watermark = PA_MIN(u->tsched_watermark * 2, u->tsched_watermark + u->watermark_inc_step);
     fix_tsched_watermark(u);
 
     if (old_watermark != u->tsched_watermark) {
-        pa_log_notice("Increasing wakeup watermark to %0.2f ms",
-                      (double) pa_bytes_to_usec(u->tsched_watermark, &u->sink->sample_spec) / PA_USEC_PER_MSEC);
+        pa_log_info("Increasing wakeup watermark to %0.2f ms",
+                    (double) pa_bytes_to_usec(u->tsched_watermark, &u->sink->sample_spec) / PA_USEC_PER_MSEC);
         return;
     }
 
     /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
     old_min_latency = u->sink->thread_info.min_latency;
-    new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_STEP_USEC);
+    new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_INC_STEP_USEC);
     new_min_latency = PA_MIN(new_min_latency, u->sink->thread_info.max_latency);
 
     if (old_min_latency != new_min_latency) {
-        pa_log_notice("Increasing minimal latency to %0.2f ms",
-                      (double) new_min_latency / PA_USEC_PER_MSEC);
+        pa_log_info("Increasing minimal latency to %0.2f ms",
+                    (double) new_min_latency / PA_USEC_PER_MSEC);
 
         pa_sink_set_latency_range_within_thread(u->sink, new_min_latency, u->sink->thread_info.max_latency);
-        return;
     }
 
     /* When we reach this we're officialy fucked! */
 }
 
+static void decrease_watermark(struct userdata *u) {
+    size_t old_watermark;
+    pa_usec_t now;
+
+    pa_assert(u);
+    pa_assert(u->use_tsched);
+
+    now = pa_rtclock_now();
+
+    if (u->watermark_dec_not_before <= 0)
+        goto restart;
+
+    if (u->watermark_dec_not_before > now)
+        return;
+
+    old_watermark = u->tsched_watermark;
+
+    if (u->tsched_watermark < u->watermark_dec_step)
+        u->tsched_watermark = u->tsched_watermark / 2;
+    else
+        u->tsched_watermark = PA_MAX(u->tsched_watermark / 2, u->tsched_watermark - u->watermark_dec_step);
+
+    fix_tsched_watermark(u);
+
+    if (old_watermark != u->tsched_watermark)
+        pa_log_info("Decreasing wakeup watermark to %0.2f ms",
+                    (double) pa_bytes_to_usec(u->tsched_watermark, &u->sink->sample_spec) / PA_USEC_PER_MSEC);
+
+    /* We don't change the latency range*/
+
+restart:
+    u->watermark_dec_not_before = now + TSCHED_WATERMARK_VERIFY_AFTER_USEC;
+}
+
 static void hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*process_usec) {
     pa_usec_t usec, wm;
 
@@ -313,6 +360,7 @@ static void hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*p
     pa_assert(process_usec);
 
     pa_assert(u);
+    pa_assert(u->use_tsched);
 
     usec = pa_sink_get_requested_latency_within_thread(u->sink);
 
@@ -360,7 +408,7 @@ static int try_recover(struct userdata *u, const char *call, int err) {
     return 0;
 }
 
-static size_t check_left_to_play(struct userdata *u, size_t n_bytes) {
+static size_t check_left_to_play(struct userdata *u, size_t n_bytes, pa_bool_t on_timeout) {
     size_t left_to_play;
 
     /* We use <= instead of < for this check here because an underrun
@@ -368,34 +416,55 @@ static size_t check_left_to_play(struct userdata *u, size_t n_bytes) {
      * it is removed from the buffer. This is particularly important
      * when block transfer is used. */
 
-    if (n_bytes <= u->hwbuf_size) {
+    if (n_bytes <= u->hwbuf_size)
         left_to_play = u->hwbuf_size - n_bytes;
+    else {
+
+        /* We got a dropout. What a mess! */
+        left_to_play = 0;
 
 #ifdef DEBUG_TIMING
-        pa_log_debug("%0.2f ms left to play", (double) pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) / PA_USEC_PER_MSEC);
+        PA_DEBUG_TRAP;
 #endif
 
-    } else {
-        left_to_play = 0;
+        if (!u->first && !u->after_rewind)
+            if (pa_log_ratelimit())
+                pa_log_info("Underrun!");
+    }
 
 #ifdef DEBUG_TIMING
-        PA_DEBUG_TRAP;
+    pa_log_debug("%0.2f ms left to play; inc threshold = %0.2f ms; dec threshold = %0.2f ms",
+                 (double) pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) / PA_USEC_PER_MSEC,
+                 (double) pa_bytes_to_usec(u->watermark_inc_threshold, &u->sink->sample_spec) / PA_USEC_PER_MSEC,
+                 (double) pa_bytes_to_usec(u->watermark_dec_threshold, &u->sink->sample_spec) / PA_USEC_PER_MSEC);
 #endif
 
+    if (u->use_tsched) {
+        pa_bool_t reset_not_before = TRUE;
+
         if (!u->first && !u->after_rewind) {
+            if (left_to_play < u->watermark_inc_threshold)
+                increase_watermark(u);
+            else if (left_to_play > u->watermark_dec_threshold) {
+                reset_not_before = FALSE;
 
-            if (pa_log_ratelimit())
-                pa_log_info("Underrun!");
+                /* We decrease the watermark only if have actually
+                 * been woken up by a timeout. If something else woke
+                 * us up it's too easy to fulfill the deadlines... */
 
-            if (u->use_tsched)
-                adjust_after_underrun(u);
+                if (on_timeout)
+                    decrease_watermark(u);
+            }
         }
+
+        if (reset_not_before)
+            u->watermark_dec_not_before = 0;
     }
 
     return left_to_play;
 }
 
-static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
+static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled, pa_bool_t on_timeout) {
     pa_bool_t work_done = TRUE;
     pa_usec_t max_sleep_usec = 0, process_usec = 0;
     size_t left_to_play;
@@ -430,7 +499,8 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
         pa_log_debug("avail: %lu", (unsigned long) n_bytes);
 #endif
 
-        left_to_play = check_left_to_play(u, n_bytes);
+        left_to_play = check_left_to_play(u, n_bytes, on_timeout);
+        on_timeout = FALSE;
 
         if (u->use_tsched)
 
@@ -565,7 +635,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
     return work_done ? 1 : 0;
 }
 
-static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
+static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled, pa_bool_t on_timeout) {
     pa_bool_t work_done = FALSE;
     pa_usec_t max_sleep_usec = 0, process_usec = 0;
     size_t left_to_play;
@@ -591,7 +661,8 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
         }
 
         n_bytes = (size_t) n * u->frame_size;
-        left_to_play = check_left_to_play(u, n_bytes);
+        left_to_play = check_left_to_play(u, n_bytes, on_timeout);
+        on_timeout = FALSE;
 
         if (u->use_tsched)
 
@@ -1278,15 +1349,16 @@ static void thread_func(void *userdata) {
         if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
             int work_done;
             pa_usec_t sleep_usec = 0;
+            pa_bool_t on_timeout = pa_rtpoll_timer_elapsed(u->rtpoll);
 
             if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
                 if (process_rewind(u) < 0)
                         goto fail;
 
             if (u->use_mmap)
-                work_done = mmap_write(u, &sleep_usec, revents & POLLOUT);
+                work_done = mmap_write(u, &sleep_usec, revents & POLLOUT, on_timeout);
             else
-                work_done = unix_write(u, &sleep_usec, revents & POLLOUT);
+                work_done = unix_write(u, &sleep_usec, revents & POLLOUT, on_timeout);
 
             if (work_done < 0)
                 goto fail;
@@ -1787,7 +1859,6 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
     u->nfragments = nfrags;
     u->hwbuf_size = u->fragment_size * nfrags;
-    u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->sink->sample_spec);
     pa_cvolume_mute(&u->hardware_volume, u->sink->sample_spec.channels);
 
     pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
@@ -1798,7 +1869,13 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     pa_sink_set_max_rewind(u->sink, u->hwbuf_size);
 
     if (u->use_tsched) {
-        u->watermark_step = pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC, &u->sink->sample_spec);
+        u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->sink->sample_spec);
+
+        u->watermark_inc_step = pa_usec_to_bytes(TSCHED_WATERMARK_INC_STEP_USEC, &u->sink->sample_spec);
+        u->watermark_dec_step = pa_usec_to_bytes(TSCHED_WATERMARK_DEC_STEP_USEC, &u->sink->sample_spec);
+
+        u->watermark_inc_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_INC_THRESHOLD_USEC, &u->sink->sample_spec);
+        u->watermark_dec_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_DEC_THRESHOLD_USEC, &u->sink->sample_spec);
 
         fix_min_sleep_wakeup(u);
         fix_tsched_watermark(u);
@@ -1812,6 +1889,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     } else
         pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->hwbuf_size, &ss));
 
+
     reserve_update(u);
 
     if (update_sw_params(u) < 0)
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 336027a..165b2e3 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -59,14 +59,22 @@
 /* #define DEBUG_TIMING */
 
 #define DEFAULT_DEVICE "default"
-#define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC)       /* 2s */
-#define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC)  /* 20ms */
-#define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC)     /* 10ms */
-#define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)          /* 10ms */
-#define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)          /* 4ms */
 
-#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)           /* 2ms */
-#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)         /* 200ms */
+#define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC)             /* 2s */
+#define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC)        /* 20ms */
+
+#define TSCHED_WATERMARK_INC_STEP_USEC (10*PA_USEC_PER_MSEC)       /* 10ms  */
+#define TSCHED_WATERMARK_DEC_STEP_USEC (5*PA_USEC_PER_MSEC)        /* 5ms */
+#define TSCHED_WATERMARK_VERIFY_AFTER_USEC (20*PA_USEC_PER_SEC)    /* 20s */
+#define TSCHED_WATERMARK_INC_THRESHOLD_USEC (1*PA_USEC_PER_MSEC)   /* 3ms */
+#define TSCHED_WATERMARK_DEC_THRESHOLD_USEC (100*PA_USEC_PER_MSEC) /* 100ms */
+#define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC)           /* 10ms */
+
+#define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)                /* 10ms */
+#define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)                /* 4ms */
+
+#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)                 /* 2ms */
+#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)               /* 200ms */
 
 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100)
 
@@ -96,7 +104,12 @@ struct userdata {
         hwbuf_unused,
         min_sleep,
         min_wakeup,
-        watermark_step;
+        watermark_inc_step,
+        watermark_dec_step,
+        watermark_inc_threshold,
+        watermark_dec_threshold;
+
+    pa_usec_t watermark_dec_not_before;
 
     unsigned nfragments;
 
@@ -241,6 +254,7 @@ static int reserve_monitor_init(struct userdata *u, const char *dname) {
 static void fix_min_sleep_wakeup(struct userdata *u) {
     size_t max_use, max_use_2;
     pa_assert(u);
+    pa_assert(u->use_tsched);
 
     max_use = u->hwbuf_size - u->hwbuf_unused;
     max_use_2 = pa_frame_align(max_use/2, &u->source->sample_spec);
@@ -255,6 +269,7 @@ static void fix_min_sleep_wakeup(struct userdata *u) {
 static void fix_tsched_watermark(struct userdata *u) {
     size_t max_use;
     pa_assert(u);
+    pa_assert(u->use_tsched);
 
     max_use = u->hwbuf_size - u->hwbuf_unused;
 
@@ -265,7 +280,7 @@ static void fix_tsched_watermark(struct userdata *u) {
         u->tsched_watermark = u->min_wakeup;
 }
 
-static void adjust_after_overrun(struct userdata *u) {
+static void increase_watermark(struct userdata *u) {
     size_t old_watermark;
     pa_usec_t old_min_latency, new_min_latency;
 
@@ -274,36 +289,72 @@ static void adjust_after_overrun(struct userdata *u) {
 
     /* First, just try to increase the watermark */
     old_watermark = u->tsched_watermark;
-    u->tsched_watermark = PA_MIN(u->tsched_watermark * 2, u->tsched_watermark + u->watermark_step);
-
+    u->tsched_watermark = PA_MIN(u->tsched_watermark * 2, u->tsched_watermark + u->watermark_inc_step);
     fix_tsched_watermark(u);
 
     if (old_watermark != u->tsched_watermark) {
-        pa_log_notice("Increasing wakeup watermark to %0.2f ms",
-                      (double) pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec) / PA_USEC_PER_MSEC);
+        pa_log_info("Increasing wakeup watermark to %0.2f ms",
+                    (double) pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec) / PA_USEC_PER_MSEC);
         return;
     }
 
     /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
     old_min_latency = u->source->thread_info.min_latency;
-    new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_STEP_USEC);
+    new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_INC_STEP_USEC);
     new_min_latency = PA_MIN(new_min_latency, u->source->thread_info.max_latency);
 
     if (old_min_latency != new_min_latency) {
-        pa_log_notice("Increasing minimal latency to %0.2f ms",
-                      (double) new_min_latency / PA_USEC_PER_MSEC);
+        pa_log_info("Increasing minimal latency to %0.2f ms",
+                    (double) new_min_latency / PA_USEC_PER_MSEC);
 
         pa_source_set_latency_range_within_thread(u->source, new_min_latency, u->source->thread_info.max_latency);
-        return;
     }
 
     /* When we reach this we're officialy fucked! */
 }
 
+static void decrease_watermark(struct userdata *u) {
+    size_t old_watermark;
+    pa_usec_t now;
+
+    pa_assert(u);
+    pa_assert(u->use_tsched);
+
+    now = pa_rtclock_now();
+
+    if (u->watermark_dec_not_before <= 0)
+        goto restart;
+
+    if (u->watermark_dec_not_before > now)
+        return;
+
+    old_watermark = u->tsched_watermark;
+
+    if (u->tsched_watermark < u->watermark_dec_step)
+        u->tsched_watermark = u->tsched_watermark / 2;
+    else
+        u->tsched_watermark = PA_MAX(u->tsched_watermark / 2, u->tsched_watermark - u->watermark_dec_step);
+
+    fix_tsched_watermark(u);
+
+    if (old_watermark != u->tsched_watermark)
+        pa_log_info("Decreasing wakeup watermark to %0.2f ms",
+                    (double) pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec) / PA_USEC_PER_MSEC);
+
+    /* We don't change the latency range*/
+
+restart:
+    u->watermark_dec_not_before = now + TSCHED_WATERMARK_VERIFY_AFTER_USEC;
+}
+
 static pa_usec_t hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*process_usec) {
     pa_usec_t wm, usec;
 
+    pa_assert(sleep_usec);
+    pa_assert(process_usec);
+
     pa_assert(u);
+    pa_assert(u->use_tsched);
 
     usec = pa_source_get_requested_latency_within_thread(u->source);
 
@@ -352,7 +403,7 @@ static int try_recover(struct userdata *u, const char *call, int err) {
     return 0;
 }
 
-static size_t check_left_to_record(struct userdata *u, size_t n_bytes) {
+static size_t check_left_to_record(struct userdata *u, size_t n_bytes, pa_bool_t on_timeout) {
     size_t left_to_record;
     size_t rec_space = u->hwbuf_size - u->hwbuf_unused;
 
@@ -361,14 +412,11 @@ static size_t check_left_to_record(struct userdata *u, size_t n_bytes) {
      * it is removed from the buffer. This is particularly important
      * when block transfer is used. */
 
-    if (n_bytes <= rec_space) {
+    if (n_bytes <= rec_space)
         left_to_record = rec_space - n_bytes;
+    else {
 
-#ifdef DEBUG_TIMING
-        pa_log_debug("%0.2f ms left to record", (double) pa_bytes_to_usec(left_to_record, &u->source->sample_spec) / PA_USEC_PER_MSEC);
-#endif
-
-    } else {
+        /* We got a dropout. What a mess! */
         left_to_record = 0;
 
 #ifdef DEBUG_TIMING
@@ -377,15 +425,36 @@ static size_t check_left_to_record(struct userdata *u, size_t n_bytes) {
 
         if (pa_log_ratelimit())
             pa_log_info("Overrun!");
+    }
 
-        if (u->use_tsched)
-            adjust_after_overrun(u);
+#ifdef DEBUG_TIMING
+    pa_log_debug("%0.2f ms left to record", (double) pa_bytes_to_usec(left_to_record, &u->source->sample_spec) / PA_USEC_PER_MSEC);
+#endif
+
+    if (u->use_tsched) {
+        pa_bool_t reset_not_before = TRUE;
+
+        if (left_to_record < u->watermark_inc_threshold)
+            increase_watermark(u);
+        else if (left_to_record > u->watermark_dec_threshold) {
+            reset_not_before = FALSE;
+
+            /* We decrease the watermark only if have actually been
+             * woken up by a timeout. If something else woke us up
+             * it's too easy to fulfill the deadlines... */
+
+            if (on_timeout)
+                decrease_watermark(u);
+        }
+
+        if (reset_not_before)
+            u->watermark_dec_not_before = 0;
     }
 
     return left_to_record;
 }
 
-static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
+static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled, pa_bool_t on_timeout) {
     pa_bool_t work_done = FALSE;
     pa_usec_t max_sleep_usec = 0, process_usec = 0;
     size_t left_to_record;
@@ -417,7 +486,8 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
         pa_log_debug("avail: %lu", (unsigned long) n_bytes);
 #endif
 
-        left_to_record = check_left_to_record(u, n_bytes);
+        left_to_record = check_left_to_record(u, n_bytes, on_timeout);
+        on_timeout = FALSE;
 
         if (u->use_tsched)
             if (!polled &&
@@ -543,7 +613,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
     return work_done ? 1 : 0;
 }
 
-static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
+static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled, pa_bool_t on_timeout) {
     int work_done = FALSE;
     pa_usec_t max_sleep_usec = 0, process_usec = 0;
     size_t left_to_record;
@@ -570,7 +640,8 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
         }
 
         n_bytes = (size_t) n * u->frame_size;
-        left_to_record = check_left_to_record(u, n_bytes);
+        left_to_record = check_left_to_record(u, n_bytes, on_timeout);
+        on_timeout = FALSE;
 
         if (u->use_tsched)
             if (!polled &&
@@ -1158,11 +1229,12 @@ static void thread_func(void *userdata) {
         if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
             int work_done;
             pa_usec_t sleep_usec = 0;
+            pa_bool_t on_timeout = pa_rtpoll_timer_elapsed(u->rtpoll);
 
             if (u->use_mmap)
-                work_done = mmap_read(u, &sleep_usec, revents & POLLIN);
+                work_done = mmap_read(u, &sleep_usec, revents & POLLIN, on_timeout);
             else
-                work_done = unix_read(u, &sleep_usec, revents & POLLIN);
+                work_done = unix_read(u, &sleep_usec, revents & POLLIN, on_timeout);
 
             if (work_done < 0)
                 goto fail;
@@ -1632,7 +1704,6 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
     u->nfragments = nfrags;
     u->hwbuf_size = u->fragment_size * nfrags;
-    u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->source->sample_spec);
     pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels);
 
     pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
@@ -1640,7 +1711,13 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
                 (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC);
 
     if (u->use_tsched) {
-        u->watermark_step = pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC, &u->source->sample_spec);
+        u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->source->sample_spec);
+
+        u->watermark_inc_step = pa_usec_to_bytes(TSCHED_WATERMARK_INC_STEP_USEC, &u->source->sample_spec);
+        u->watermark_dec_step = pa_usec_to_bytes(TSCHED_WATERMARK_DEC_STEP_USEC, &u->source->sample_spec);
+
+        u->watermark_inc_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_INC_THRESHOLD_USEC, &u->source->sample_spec);
+        u->watermark_dec_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_DEC_THRESHOLD_USEC, &u->source->sample_spec);
 
         fix_min_sleep_wakeup(u);
         fix_tsched_watermark(u);
diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c
index 42708a8..666cbc9 100644
--- a/src/pulsecore/rtpoll.c
+++ b/src/pulsecore/rtpoll.c
@@ -63,6 +63,7 @@ struct pa_rtpoll {
     pa_bool_t running:1;
     pa_bool_t rebuild_needed:1;
     pa_bool_t quit:1;
+    pa_bool_t timer_elapsed:1;
 
 #ifdef DEBUG_TIMING
     pa_usec_t timestamp;
@@ -94,26 +95,14 @@ PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree);
 pa_rtpoll *pa_rtpoll_new(void) {
     pa_rtpoll *p;
 
-    p = pa_xnew(pa_rtpoll, 1);
+    p = pa_xnew0(pa_rtpoll, 1);
 
     p->n_pollfd_alloc = 32;
     p->pollfd = pa_xnew(struct pollfd, p->n_pollfd_alloc);
     p->pollfd2 = pa_xnew(struct pollfd, p->n_pollfd_alloc);
-    p->n_pollfd_used = 0;
-
-    pa_zero(p->next_elapse);
-    p->timer_enabled = FALSE;
-
-    p->running = FALSE;
-    p->scan_for_dead = FALSE;
-    p->rebuild_needed = FALSE;
-    p->quit = FALSE;
-
-    PA_LLIST_HEAD_INIT(pa_rtpoll_item, p->items);
 
 #ifdef DEBUG_TIMING
     p->timestamp = pa_rtclock_now();
-    p->slept = p->awake = 0;
 #endif
 
     return p;
@@ -229,6 +218,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
     pa_assert(!p->running);
 
     p->running = TRUE;
+    p->timer_elapsed = FALSE;
 
     /* First, let's do some work */
     for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) {
@@ -286,7 +276,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
     if (p->rebuild_needed)
         rtpoll_rebuild(p);
 
-    memset(&timeout, 0, sizeof(timeout));
+    pa_zero(timeout);
 
     /* Calculate timeout */
     if (wait_op && !p->quit && p->timer_enabled) {
@@ -314,9 +304,11 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
         r = ppoll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? &ts : NULL, NULL);
     }
 #else
-        r = poll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);
+    r = poll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);
 #endif
 
+    p->timer_elapsed = r == 0;
+
 #ifdef DEBUG_TIMING
     {
         pa_usec_t now = pa_rtclock_now();
@@ -628,3 +620,9 @@ void pa_rtpoll_quit(pa_rtpoll *p) {
 
     p->quit = TRUE;
 }
+
+pa_bool_t pa_rtpoll_timer_elapsed(pa_rtpoll *p) {
+    pa_assert(p);
+
+    return p->timer_elapsed;
+}
diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h
index d2d69ca..b2a87fc 100644
--- a/src/pulsecore/rtpoll.h
+++ b/src/pulsecore/rtpoll.h
@@ -73,6 +73,10 @@ void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, pa_usec_t usec);
 void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec);
 void pa_rtpoll_set_timer_disabled(pa_rtpoll *p);
 
+/* Return TRUE when the elapsed timer was the reason for
+ * the last pa_rtpoll_run() invocation to finish */
+pa_bool_t pa_rtpoll_timer_elapsed(pa_rtpoll *p);
+
 /* A new fd wakeup item for pa_rtpoll */
 pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds);
 void pa_rtpoll_item_free(pa_rtpoll_item *i);

commit 60a350209ded62b9c2d1d948d3e71d2982477566
Merge: 050a3a9 57117d4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Aug 24 03:31:03 2009 +0200

    Merge commit 'origin/master-tx'


commit be46eaa5b6324d84c5ecbed5dd72dec1c87e0cb1
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Aug 24 03:32:48 2009 +0200

    i18n: run make update-po

diff --git a/po/as.po b/po/as.po
index f1b1b14..79d5a45 100644
--- a/po/as.po
+++ b/po/as.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pulseaudio.as\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-08 12:35+0530\n"
 "Last-Translator: Amitakhya Phukan <aphukan at fedoraproject.org>\n"
 "Language-Team: Assamese <fedora-trans-as at redhat.com>\n"
@@ -357,28 +357,28 @@ msgstr ""
 "শ্ৰীমান, আপোনাৰ কাৰ্ণেল পূৰণি! high-resolution timer সক্ৰিয় থকা Linux ক আজি "
 "উপদেশ দিয়া হয়!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ব্যৰ্থ ।"
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "ডেমন আৰম্ভ কৰিবলৈ ব্যৰ্থ ।"
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "তুলি লোৱা মডিউল নোহোৱাকে ডেমন আৰম্ভ কৰা হৈছে, কোনো কাম সঞ্চালন কৰা সম্ভৱ নহয় ।"
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "ডেমন আৰম্ভ কৰা সম্পূৰ্ণ ।"
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "ডেমন বন্ধ কৰাৰ প্ৰক্ৰিয়া আৰম্ভ কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "ডেমন বন্ধ কৰা হৈছে ।"
 
@@ -930,7 +930,7 @@ msgstr "ওপৰত পিছত বাওঁফালে"
 msgid "Top Rear Right"
 msgstr "ওপৰত পিছত সোঁফালে"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1060,27 +1060,27 @@ msgstr "অনুপস্থিত বাস্তবায়ন"
 msgid "Client forked"
 msgstr "গ্ৰাহক ফৰ্ক কৰা হৈছে"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2232,7 +2232,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn লক প্ৰয়োগ কৰিবলৈ ব্যৰ্থ ।"
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2248,7 +2248,7 @@ msgstr ""
 "POLLOUT নিৰ্ধাৰিত হোৱাৰি পিছতো আমি উথিলো -- কিন্তু তাৰ পিছৰ snd_pcm_avail() এ ০ "
 "দিলে বা অন্য এটা মান < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/bn_IN.po b/po/bn_IN.po
index bd16b9c..0023264 100644
--- a/po/bn_IN.po
+++ b/po/bn_IN.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-08 16:21+0530\n"
 "Last-Translator: Runa Bhattacharjee <runab at fedoraproject.org>\n"
 "Language-Team: Bengali INDIA <fedora-trans-bn_in at redhat.com>\n"
@@ -359,28 +359,28 @@ msgid ""
 "resolution timers enabled!"
 msgstr "উচ্চ-রেসোলিউশনের নতুন টাইমার সহ Linux সক্রিয় করা বাঞ্ছনীয়!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ব্যর্থ।"
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "ডেমন আরম্ভ করতে ব্যর্থ।"
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "লোড করা মডিউল বিনা ডেমন আরম্ভ করা হয়েছে এবং কোনো কর্ম সঞ্চালন করা সম্ভব নয়।"
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "ডেমন আরম্ভ করা হয়েছে।"
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "ডেমন বন্ধ করার প্রক্রিয়া আরম্ভ করা হয়েছে।"
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "ডেমন বন্ধ করা হয়েছে।"
 
@@ -941,7 +941,7 @@ msgstr "উপরে পিছনে বাঁদিকে"
 msgid "Top Rear Right"
 msgstr "উপরে পিছনে ডানদিকে"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1071,27 +1071,27 @@ msgstr "অনুপস্থিত বাস্তবায়ন"
 msgid "Client forked"
 msgstr "ক্লায়েন্ট ফর্ক করা হয়েছে"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f গিবিবাইট"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f মিবিবাইট"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f কিবিবাইট"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u বাইট"
@@ -2244,7 +2244,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn লক প্রয়োগ করতে ব্যর্থ।"
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2261,7 +2261,7 @@ msgstr ""
 "POLLOUT set দ্বারা চেতাবনী সৃষ্টি হয়েছে -- পরবর্তী snd_pcm_avail() থেকে 0 অথবা < "
 "min_avail-র থেকে কম অন্য একটি মান প্রাপ্ত হয়েছে।"
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/ca.po b/po/ca.po
index 167501d..2384da2 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -23,7 +23,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-07-18 11:40+0100\n"
 "Last-Translator: Tomàs Bigordà <t0mynoker at gmail.com>\n"
 "Language-Team: Catalan <fedora at softcatala.net>\n"
@@ -394,27 +394,27 @@ msgstr ""
 "Es recomana la utilització d'un nucli amb els temporitzadors d'alta "
 "resolució habilitats."
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "S'ha produït un error en pa_core_new()."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "S'ha produït un error en inicialitzar el dimoni."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "El dimoni s'ha iniciat sense cap mòdul carregat, no funcionarà."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "S'ha completat la inicialització del dimoni."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "S'ha iniciat l'aturada del dimoni."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "S'ha aturat el dimoni."
 
@@ -979,7 +979,7 @@ msgstr "Superior posterior esquerra"
 msgid "Top Rear Right"
 msgstr "Superior posterior dreta"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1109,27 +1109,27 @@ msgstr "Manca la implementació"
 msgid "Client forked"
 msgstr "Client bifurcat"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2304,7 +2304,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "No s'ha pogut accedir al bloqueig d'autospawn."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2321,7 +2321,7 @@ msgstr ""
 "Ens han aixecat amb POLLOUT activat -- tanmateix una crida posterior a "
 "snd_pcm_avail() ha retornat 0 o un altre valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/cs.po b/po/cs.po
index 13a5134..2c8966d 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-08-17 01:58+0200\n"
 "Last-Translator: Petr Kovar <pknbe at volny.cz>\n"
 "Language-Team: Czech <translation-team-cs at lists.sourceforge.net>\n"
@@ -371,27 +371,27 @@ msgstr ""
 "Sorry, vole, kernel error! Tip šéfkuchaře na dnešní den zní: Linux se "
 "zapnutými časovači o vysokém rozlišení."
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() selhalo."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Selhalo spuštění démona."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Spuštění démona bez jakýchkoliv nahraných modulů, běh bude odmítnut."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Spuštění démona dokončeno."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Vypínání démona spuštěno."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Démon ukončen."
 
@@ -947,7 +947,7 @@ msgstr "Horní zadní levý"
 msgid "Top Rear Right"
 msgstr "Horní zadní pravý"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1077,27 +1077,27 @@ msgstr "Scházející implementace"
 msgid "Client forked"
 msgstr "Klient rozvětven"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2232,7 +2232,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Nelze přistoupit k zámku automatického spouštění."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2249,7 +2249,7 @@ msgstr ""
 "Probudilo nás nastavení POLLOUT - nicméně následné snd_pcm_avail() vrátilo 0 "
 "či jinou hodnotu < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/de.po b/po/de.po
index ef9454c..3e76469 100644
--- a/po/de.po
+++ b/po/de.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-18 12:43+0100\n"
 "Last-Translator: Fabian Affolter <fab at fedoraproject.org>\n"
 "Language-Team: German <fedora-trans-de at redhat.com>\n"
@@ -361,27 +361,27 @@ msgid ""
 "resolution timers enabled!"
 msgstr "Der Chefkoch empfiehlt: Linux mit aktivierten hochauslösenden Timern!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() fehlgeschlagen."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Konnte Daemon nicht initialisieren."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Daemon verweigert Ausführung, da keine Module geladen."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Start des Daemons abgeschlossen."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Herunterfahren des Daemon gestartet."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Daemon beendet."
 
@@ -930,7 +930,7 @@ msgstr "Oben Hinten Links"
 msgid "Top Rear Right"
 msgstr "Oben Hinten Rechts"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1060,27 +1060,27 @@ msgstr "Fehlende Implementation"
 msgid "Client forked"
 msgstr "Client geteilt"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2222,7 +2222,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Fehler beim Zugriff auf Autostart -Sperre."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2233,7 +2233,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/de_CH.po b/po/de_CH.po
index 507df74..9933836 100644
--- a/po/de_CH.po
+++ b/po/de_CH.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-18 12:55+0100\n"
 "Last-Translator: Fabian Affolter <fab at fedoraproject.org>\n"
 "Language-Team: German <fedora-trans-de at redhat.com>\n"
@@ -363,27 +363,27 @@ msgid ""
 "resolution timers enabled!"
 msgstr "Der Chefkoch empfiehlt: Linux mit aktivierten hochauslösenden Timern!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() fehlgeschlagen."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Konnte Daemon nicht initialisieren."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Daemon verweigert Ausführung, da keine Module geladen."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Start des Daemons abgeschlossen."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Herunterfahren des Daemon gestartet."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Daemon beendet."
 
@@ -933,7 +933,7 @@ msgstr "Oben Hinten Links"
 msgid "Top Rear Right"
 msgstr "Oben Hinten Rechts"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1064,27 +1064,27 @@ msgstr "Fehlende Implementation"
 msgid "Client forked"
 msgstr "Client geforket"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2229,7 +2229,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Fehler beim Zugriff auf Autostart -Sperre."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2247,7 +2247,7 @@ msgstr ""
 "von snd_pcm_avail() liefert 0 oder einen anderen Wert zurück, der < "
 "min_avail ist."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/el.po b/po/el.po
index e4bb39f..f6482e7 100644
--- a/po/el.po
+++ b/po/el.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: el\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2008-08-22 19:40+0300\n"
 "Last-Translator: Dimitris Glezos <dimitris at glezos.com>\n"
 "Language-Team: Greek <fedora-trans-el at redhat.com>\n"
@@ -346,27 +346,27 @@ msgstr ""
 "Δικέ μου, ο πυρήνας σου είναι για τα μπάζα! Η πρόταση του σεφ σήμερα είναι "
 "Linux με ενεργοποιημένα τα high-resolution timers!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr ""
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr ""
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr ""
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr ""
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr ""
 
@@ -844,7 +844,7 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -974,27 +974,27 @@ msgstr ""
 msgid "Client forked"
 msgstr ""
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr ""
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr ""
@@ -1930,7 +1930,7 @@ msgstr ""
 msgid "Cannot access autospawn lock."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -1941,7 +1941,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/es.po b/po/es.po
index 6c30752..001295e 100644
--- a/po/es.po
+++ b/po/es.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PulseAudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-23 08:44+0000\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-08-23 09:50-0300\n"
 "Last-Translator: Domingo Becker <domingobecker at gmail.com>\n"
 "Language-Team: Fedora Spanish <fedora-trans-es at redhat.com>\n"
@@ -17,8 +17,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "X-Poedit-Language: Spanish\n"
 
-#: ../src/modules/alsa/alsa-util.c:775
-#: ../src/pulsecore/sink.c:2676
+#: ../src/modules/alsa/alsa-util.c:775 ../src/pulsecore/sink.c:2676
 #, c-format
 msgid "%s %s"
 msgstr "%s %s"
@@ -26,37 +25,60 @@ msgstr "%s %s"
 #: ../src/modules/alsa/alsa-util.c:1023
 #, c-format
 msgid ""
-"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
+"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
+"ms).\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
 msgstr ""
-"snd_pcm_avail() devolvió un valor que es excepcionalmente grande: %lu bytes (%lu ms).\n"
-"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, informe ésto a los desarrolladores de ALSA."
+"snd_pcm_avail() devolvió un valor que es excepcionalmente grande: %lu bytes "
+"(%lu ms).\n"
+"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
+"informe ésto a los desarrolladores de ALSA."
 
 #: ../src/modules/alsa/alsa-util.c:1064
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%lu ms).\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
+"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
+"lu ms).\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
 msgstr ""
-"snd_pcm_delay() devolvió un valor que es excepcionalmente grande: %li bytes (%s%lu ms).\n"
-"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, informe ésto a los desarrolladores de ALSA."
+"snd_pcm_delay() devolvió un valor que es excepcionalmente grande: %li bytes "
+"(%s%lu ms).\n"
+"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
+"informe ésto a los desarrolladores de ALSA."
 
 #: ../src/modules/alsa/alsa-util.c:1111
 #, c-format
 msgid ""
-"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
+"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
+"(%lu ms).\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
 msgstr ""
-"snd_pcm_mmap_begin() devolvió un valor que es excepcionalmente grande: %lu bytes (%lu ms).\n"
-"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, informe ésto a los desarrolladores de ALSA."
+"snd_pcm_mmap_begin() devolvió un valor que es excepcionalmente grande: %lu "
+"bytes (%lu ms).\n"
+"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
+"informe ésto a los desarrolladores de ALSA."
 
 #: ../src/modules/module-ladspa-sink.c:49
 msgid "Virtual LADSPA sink"
 msgstr "Sumidero virtual LADSPA"
 
 #: ../src/modules/module-ladspa-sink.c:53
-msgid "sink_name=<name for the sink> sink_properties=<properties for the sink> master=<name of sink to filter> format=<sample format> rate=<sample rate> channels=<number of channels> channel_map=<channel map> plugin=<ladspa plugin name> label=<ladspa plugin label> control=<comma seperated list of input control values>"
-msgstr "sink_name=<nombre para el sumidero> sink_properties=<propiedades para el sumidero> master=<nombre del sumidero a filtrar> format=<formato de ejemplo> rate=<tasa de ejemplo> channels=<cantidad de canaless> channel_map=<mapeo de canales> plugin=<nombre del complemento ladspa> label=<etiqueta del complemento ladspa> control=<lista separada por comas de valores de control de entrada>"
+msgid ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"input control values>"
+msgstr ""
+"sink_name=<nombre para el sumidero> sink_properties=<propiedades para el "
+"sumidero> master=<nombre del sumidero a filtrar> format=<formato de ejemplo> "
+"rate=<tasa de ejemplo> channels=<cantidad de canaless> channel_map=<mapeo de "
+"canales> plugin=<nombre del complemento ladspa> label=<etiqueta del "
+"complemento ladspa> control=<lista separada por comas de valores de control "
+"de entrada>"
 
 #: ../src/pulsecore/sink.c:2660
 msgid "Internal Audio"
@@ -112,8 +134,7 @@ msgstr "GID del usuario '%s' y del grupo '%s' no son similares."
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "El directorio de inicio del usuario '%s' no es '%s', ignorando."
 
-#: ../src/daemon/main.c:208
-#: ../src/daemon/main.c:213
+#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Falló al crear '%s': %s"
@@ -165,8 +186,12 @@ msgid "Failed to kill daemon: %s"
 msgstr "No se ha podido detener el demonio: %s"
 
 #: ../src/daemon/main.c:561
-msgid "This program is not intended to be run as root (unless --system is specified)."
-msgstr "Este programa no tiene por qué ser ejecutado como root (a menos que --system sea especificado)."
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Este programa no tiene por qué ser ejecutado como root (a menos que --system "
+"sea especificado)."
 
 #: ../src/daemon/main.c:563
 msgid "Root privileges required."
@@ -178,19 +203,24 @@ msgstr "--start no está soportado para las instancias del sistema."
 
 #: ../src/daemon/main.c:573
 msgid "Running in system mode, but --disallow-exit not set!"
-msgstr "Ejecutándose en modo de sistema, ¡pero no se ha configurado --disallow-exit! "
+msgstr ""
+"Ejecutándose en modo de sistema, ¡pero no se ha configurado --disallow-exit! "
 
 #: ../src/daemon/main.c:576
 msgid "Running in system mode, but --disallow-module-loading not set!"
-msgstr "Ejecutándose en modo de sistema, ¡pero no se ha configurado --disallow-module-loading!"
+msgstr ""
+"Ejecutándose en modo de sistema, ¡pero no se ha configurado --disallow-"
+"module-loading!"
 
 #: ../src/daemon/main.c:579
 msgid "Running in system mode, forcibly disabling SHM mode!"
-msgstr "Ejecutándose en modo de sistema, ¡desactivando forzadamente el modo SHM!"
+msgstr ""
+"Ejecutándose en modo de sistema, ¡desactivando forzadamente el modo SHM!"
 
 #: ../src/daemon/main.c:584
 msgid "Running in system mode, forcibly disabling exit idle time!"
-msgstr "Ejecutándose en modo de sistema, ¡desactivando forzadamente exit idle time!"
+msgstr ""
+"Ejecutándose en modo de sistema, ¡desactivando forzadamente exit idle time!"
 
 #: ../src/daemon/main.c:611
 msgid "Failed to acquire stdio."
@@ -206,8 +236,7 @@ msgstr "Falló el pipe: %s"
 msgid "fork() failed: %s"
 msgstr "Falló el fork(): %s"
 
-#: ../src/daemon/main.c:636
-#: ../src/utils/pacat.c:505
+#: ../src/daemon/main.c:636 ../src/utils/pacat.c:505
 #, c-format
 msgid "read() failed: %s"
 msgstr "Falló la operación read(): %s"
@@ -319,13 +348,20 @@ msgstr "Ejecutándose en modo de sistema: %s"
 
 #: ../src/daemon/main.c:782
 msgid ""
-"OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
-"If you do it nonetheless then it's your own fault if things don't work as expected.\n"
-"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."
+"OK, so you are running PA in system mode. Please note that you most likely "
+"shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as "
+"expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
+"explanation why system mode is usually a bad idea."
 msgstr ""
-"Bien, o sea que está ejecutando PA en modo de sistema. Por favor entienda que, en general, no debería estar haciéndolo.\n"
-"Si insiste en seguir utilizando este modo, será debido a su propio accionar que las cosas no funcionen como se esperaba.\n"
-"Por favor lea http://pulseaudio.org/wiki/WhatIsWrongWithSystemMod para obtener una explicación acerca de por qué es una mala idea utilizar el  modo sistema."
+"Bien, o sea que está ejecutando PA en modo de sistema. Por favor entienda "
+"que, en general, no debería estar haciéndolo.\n"
+"Si insiste en seguir utilizando este modo, será debido a su propio accionar "
+"que las cosas no funcionen como se esperaba.\n"
+"Por favor lea http://pulseaudio.org/wiki/WhatIsWrongWithSystemMod para "
+"obtener una explicación acerca de por qué es una mala idea utilizar el  modo "
+"sistema."
 
 #: ../src/daemon/main.c:799
 msgid "pa_pid_file_create() failed."
@@ -333,33 +369,41 @@ msgstr "Ha fallado pa_pid_file_create()."
 
 #: ../src/daemon/main.c:809
 msgid "Fresh high-resolution timers available! Bon appetit!"
-msgstr "¡Existen cronómetros de alta resolución fresquitos y disponibles! ¡Bon appetit!"
+msgstr ""
+"¡Existen cronómetros de alta resolución fresquitos y disponibles! ¡Bon "
+"appetit!"
 
 #: ../src/daemon/main.c:811
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
-msgstr "¡Amigo, su kernel deja mucho que desear! ¡El plato que hoy recomienda el chef es Linux con cronómetros de alta resolución activados!  "
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"¡Amigo, su kernel deja mucho que desear! ¡El plato que hoy recomienda el "
+"chef es Linux con cronómetros de alta resolución activados!  "
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "Falló pa_core_new()."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Fallo al intentar iniciar el demonio."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
-msgstr "El demonio se ha iniciado sin ningún módulo cargado, y por ello se niega a funcionar."
+msgstr ""
+"El demonio se ha iniciado sin ningún módulo cargado, y por ello se niega a "
+"funcionar."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "El demonio se inició completamente."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Comienza a apagarse el demonio."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "El demonio se ha apagado."
 
@@ -374,37 +418,48 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
-"      --check                           Check for a running daemon (only returns exit code)\n"
+"      --check                           Check for a running daemon (only "
+"returns exit code)\n"
 "\n"
 "OPTIONS:\n"
 "      --system[=BOOL]                   Run as system-wide instance\n"
 "  -D, --daemonize[=BOOL]                Daemonize after startup\n"
 "      --fail[=BOOL]                     Quit when startup fails\n"
 "      --high-priority[=BOOL]            Try to set high nice level\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
-"      --log-meta[=BOOL]                 Include code location in log messages\n"
+"      --log-meta[=BOOL]                 Include code location in log "
+"messages\n"
 "      --log-time[=BOOL]                 Include timestamps in log messages\n"
 "      --log-backtrace=FRAMES            Include a backtrace in log messages\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"
+"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"shared\n"
 "                                        objects (plugins)\n"
 "      --resample-method=METHOD          Use the specified resampling method\n"
 "                                        (See --dump-resample-methods for\n"
@@ -415,10 +470,12 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
@@ -429,50 +486,78 @@ msgstr ""
 "  -h, --help                            Muestra esta ayuda\n"
 "      --version                         Muestra la versión\n"
 "      --dump-conf                       Vuelca la configuración por defecto\n"
-"      --dump-modules                    Vuelca una lista de múdulos disponibles\n"
-"      --dump-resample-methods           Vuelca los métodos disponibles de remuestreo\n"
-"      --cleanup-shm                     Limpia los segmentos de memoria compartidos\n"
-"      --start                           Inicia el demonio, si es que aún no está funcionando\n"
+"      --dump-modules                    Vuelca una lista de múdulos "
+"disponibles\n"
+"      --dump-resample-methods           Vuelca los métodos disponibles de "
+"remuestreo\n"
+"      --cleanup-shm                     Limpia los segmentos de memoria "
+"compartidos\n"
+"      --start                           Inicia el demonio, si es que aún no "
+"está funcionando\n"
 "  -k  --kill                            Detiene a un demonio funcionando\n"
-"      --check                           Verifica qué demonios están funcionando\n"
+"      --check                           Verifica qué demonios están "
+"funcionando\n"
 "\n"
 "OPCIONES:\n"
-"      --system[=BOOL]                   Se ejecuta como unica instancia a nivel del sistema\n"
-"  -D, --daemonize[=BOOL]                Se convierte en demonio luego de iniciarse\n"
+"      --system[=BOOL]                   Se ejecuta como unica instancia a "
+"nivel del sistema\n"
+"  -D, --daemonize[=BOOL]                Se convierte en demonio luego de "
+"iniciarse\n"
 "      --fail[=BOOL]                     Se cierra cuando falla el inicio\n"
-"      --high-priority[=BOOL]            Trata de establecer un nivel de nice alto\n"
-"                                        (sólo disponible como root, cuando el SUID o\n"
+"      --high-priority[=BOOL]            Trata de establecer un nivel de nice "
+"alto\n"
+"                                        (sólo disponible como root, cuando "
+"el SUID o\n"
 "                                        con RLIMIT_NICE) elevado\n"
-"      --realtime[=BOOL]                 Trata de activar planificación en tiempo real\n"
-"                                        (sólo disponible como root, cuando el SUID o\n"
+"      --realtime[=BOOL]                 Trata de activar planificación en "
+"tiempo real\n"
+"                                        (sólo disponible como root, cuando "
+"el SUID o\n"
 "                                        con RLIMIT_RTPRIO) elevado\n"
-"      --disallow-module-loading[=BOOL]  No permite la carga/descarga del módulo por el usuario\n"
+"      --disallow-module-loading[=BOOL]  No permite la carga/descarga del "
+"módulo por el usuario\n"
 "                                        después que se haya iniciado\n"
-"      --disallow-exit[=BOOL]            No permite la petición del usuario de abandonar el programa\n"
-"      --exit-idle-time=SECS             Desactiva un demonio cuando está ocioso y\n"
-"                                        ha transcurrido esta cantidad de tiempo\n"
-"      --module-idle-time=SECS           Descarga modulos que se han cargado automáticamente cuando están ociosos y\n"
-"                                        ha transcurrido esta cantidad de tiempo\n"
-"      --scache-idle-time=SECS           Descarga muestras cargadas automáticamente cuando están\n"
-"                                        ociosos y ha transcurrido esta cantidad de tiempo\n"
-"      --log-level[=LEVEL]               Aumenta o define el grado de salida a utilizar\n"
+"      --disallow-exit[=BOOL]            No permite la petición del usuario "
+"de abandonar el programa\n"
+"      --exit-idle-time=SECS             Desactiva un demonio cuando está "
+"ocioso y\n"
+"                                        ha transcurrido esta cantidad de "
+"tiempo\n"
+"      --module-idle-time=SECS           Descarga modulos que se han cargado "
+"automáticamente cuando están ociosos y\n"
+"                                        ha transcurrido esta cantidad de "
+"tiempo\n"
+"      --scache-idle-time=SECS           Descarga muestras cargadas "
+"automáticamente cuando están\n"
+"                                        ociosos y ha transcurrido esta "
+"cantidad de tiempo\n"
+"      --log-level[=LEVEL]               Aumenta o define el grado de salida "
+"a utilizar\n"
 "  -v                                    Aumenta el grado de salida\n"
 "      --log-target={auto,syslog,stderr} Especifica el destino del log\n"
-"  -p, --dl-search-path=PATH             Establece la ruta de búsqueda (search path) para complementos\n"
+"  -p, --dl-search-path=PATH             Establece la ruta de búsqueda "
+"(search path) para complementos\n"
 "                                        (plugins) compartidos\n"
-"      --resample-method=METHOD          Utiliza un método de remuestreo específico\n"
-"                                        (Ver en --dump-resample-methods los valores posibles)\n"
+"      --resample-method=METHOD          Utiliza un método de remuestreo "
+"específico\n"
+"                                        (Ver en --dump-resample-methods los "
+"valores posibles)\n"
 "      --use-pid-file[=BOOL]             Crea el archivo PID\n"
-"      --no-cpu-limit[=BOOL]             No instala un limitador de carga de CPU en\n"
+"      --no-cpu-limit[=BOOL]             No instala un limitador de carga de "
+"CPU en\n"
 "                                        plataformas que lo soporten.\n"
-"      --disable-shm[=BOOL]              Deshabilita el soporte para memoria compartida.\n"
+"      --disable-shm[=BOOL]              Deshabilita el soporte para memoria "
+"compartida.\n"
 "\n"
 "SCRIPT DE INICIO:\n"
-"  -L, --load=\"ARGUMENTOS DEL MODULO\"  Carga el módulo complemento con los parámetros dados\n"
+"  -L, --load=\"ARGUMENTOS DEL MODULO\"  Carga el módulo complemento con los "
+"parámetros dados\n"
 "  -F, --file=FILENAME                   Ejecuta el script especificado\n"
-"  -C                                    Abre una línea de comando en el TTY actual después de iniciar\n"
+"  -C                                    Abre una línea de comando en el TTY "
+"actual después de iniciar\n"
 "\n"
-"  -n                                    No carga el archivo script predeterminado\n"
+"  -n                                    No carga el archivo script "
+"predeterminado\n"
 
 #: ../src/daemon/cmdline.c:247
 msgid "--daemonize expects boolean argument"
@@ -483,8 +568,13 @@ msgid "--fail expects boolean argument"
 msgstr "--fail espera un argumento booleano"
 
 #: ../src/daemon/cmdline.c:264
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
-msgstr "--log-level espera un argumento en el nivel del log (ya sea numérico, que caiga en el rango de 0..4; ya sea uno de debug, info, notice, warn, o error). "
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+"--log-level espera un argumento en el nivel del log (ya sea numérico, que "
+"caiga en el rango de 0..4; ya sea uno de debug, info, notice, warn, o "
+"error). "
 
 #: ../src/daemon/cmdline.c:276
 msgid "--high-priority expects boolean argument"
@@ -646,8 +736,12 @@ msgid "Failed to open configuration file: %s"
 msgstr "No se pudo abrir el archivo de configuración: %s"
 
 #: ../src/daemon/daemon-conf.c:562
-msgid "The specified default channel map has a different number of channels than the specified default number of channels."
-msgstr "El mapa de canal predeterminado especificado tiene un número de canales distinto al especificado como predeterminado."
+msgid ""
+"The specified default channel map has a different number of channels than "
+"the specified default number of channels."
+msgstr ""
+"El mapa de canal predeterminado especificado tiene un número de canales "
+"distinto al especificado como predeterminado."
 
 #: ../src/daemon/daemon-conf.c:638
 #, c-format
@@ -666,8 +760,7 @@ msgstr "Sistema de Sonido PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Iniciar el Sistema de Sonido PulseAudio"
 
-#: ../src/pulse/channelmap.c:105
-#: ../src/pulse/channelmap.c:757
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
 
@@ -871,12 +964,9 @@ msgstr "Posterior izquierdo superior"
 msgid "Top Rear Right"
 msgstr "Posterior derecho superior"
 
-#: ../src/pulse/channelmap.c:484
-#: ../src/pulse/sample.c:171
-#: ../src/pulse/volume.c:285
-#: ../src/pulse/volume.c:311
-#: ../src/pulse/volume.c:331
-#: ../src/pulse/volume.c:361
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
+#: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
+#: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
 msgstr "(inválido)"
 
@@ -1004,33 +1094,32 @@ msgstr "Falta implementación"
 msgid "Client forked"
 msgstr "Cliente iniciado"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() falló"
 
@@ -1090,8 +1179,7 @@ msgstr "pa_stream_write() falló: %s"
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() falló: %s"
 
-#: ../src/utils/pacat.c:237
-#: ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() falló: %s"
@@ -1235,29 +1323,48 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n"
-"                                        s24-32le, s24-32be (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
-"      --property=PROPERTY=VALUE         Set the specified property to the specified value.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
@@ -1270,33 +1377,56 @@ msgstr ""
 "  -r, --record                          Crea una conexión para grabar\n"
 "  -p, --playback                        Create a connection for playback\n"
 "\n"
-"  -v, --verbose                         Habilita operaciones con vocabulario más detallado\n"
+"  -v, --verbose                         Habilita operaciones con vocabulario "
+"más detallado\n"
 "\n"
-"  -s, --server=SERVER                   El nombre del servidor con el que conectarse\n"
-"  -d, --device=DEVICE                   El nombre del sumidero/fuente a la que conectarse\n"
-"  -n, --client-name=NAME                Cómo llamar a este cliente en el servidor\n"
-"      --stream-name=NAME                Cómo llamar a este flujo en el servidor\n"
-"      --volume=VOLUME                   Especifica el salida inicial (linear) de volumen dentro del rango 0...65536\n"
-"      --rate=SAMPLERATE                 Tasa de muestra en Hz (establecida en 44100 por defecto)\n"
-"      --format=SAMPLEFORMAT             El tipo de ejemplo, alguno entre s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be (establecido en s16ne por defecto)\n"
-"      --channels=CHANNELS               La cantidad de canales, 1 para mono, 2 para stereo\n"
+"  -s, --server=SERVER                   El nombre del servidor con el que "
+"conectarse\n"
+"  -d, --device=DEVICE                   El nombre del sumidero/fuente a la "
+"que conectarse\n"
+"  -n, --client-name=NAME                Cómo llamar a este cliente en el "
+"servidor\n"
+"      --stream-name=NAME                Cómo llamar a este flujo en el "
+"servidor\n"
+"      --volume=VOLUME                   Especifica el salida inicial "
+"(linear) de volumen dentro del rango 0...65536\n"
+"      --rate=SAMPLERATE                 Tasa de muestra en Hz (establecida "
+"en 44100 por defecto)\n"
+"      --format=SAMPLEFORMAT             El tipo de ejemplo, alguno entre "
+"s16le, s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(establecido en s16ne por defecto)\n"
+"      --channels=CHANNELS               La cantidad de canales, 1 para mono, "
+"2 para stereo\n"
 "                                        (establecido en 2 por defecto)\n"
-"      --channel-map=CHANNELMAP          Mapeo de canales a ser usado en lugar del establecido por defecto\n"
-"      --fix-format                      Obtener el formato de ejemplo desde el sumidero al que el flujo\n"
+"      --channel-map=CHANNELMAP          Mapeo de canales a ser usado en "
+"lugar del establecido por defecto\n"
+"      --fix-format                      Obtener el formato de ejemplo desde "
+"el sumidero al que el flujo\n"
 "                                        se ha conectado.\n"
-"      --fix-rate                        Obtiene la tasa de ejemplo desde el destino al que el flujo\n"
+"      --fix-rate                        Obtiene la tasa de ejemplo desde el "
+"destino al que el flujo\n"
 "                                        se ha conectado.\n"
-"      --fix-channels                    Obtener el mapa y la cantidad de canales\n"
-"                                        desde el sumidero al que el flujo se ha conectado.\n"
-"      --no-remix                        No realiza un upmix o un downmix de los canales.\n"
-"      --no-remap                        Mapea canales por índices en lugar de por nombres.\n"
-"      --latency=BYTES                   Solicita la latencia especificada en bytes.\n"
-"      --process-time=BYTES              Solicita los procesos de tiempo por pedido especificados en bytes.\n"
-"      --property=PROPERTY=VALUE         Estabelce la propiedad especificada al valor especificado.\n"
-"      --raw                             Graba/reproduce datos PCM con formato raw.\n"
-"      --file-format=FFORMAT             Graba/reproduce datos PCM formateados.\n"
-"      --list-file-formats               Muestra una lista con los formatos de archivo disponibles.\n"
+"      --fix-channels                    Obtener el mapa y la cantidad de "
+"canales\n"
+"                                        desde el sumidero al que el flujo se "
+"ha conectado.\n"
+"      --no-remix                        No realiza un upmix o un downmix de "
+"los canales.\n"
+"      --no-remap                        Mapea canales por índices en lugar "
+"de por nombres.\n"
+"      --latency=BYTES                   Solicita la latencia especificada en "
+"bytes.\n"
+"      --process-time=BYTES              Solicita los procesos de tiempo por "
+"pedido especificados en bytes.\n"
+"      --property=PROPERTY=VALUE         Estabelce la propiedad especificada "
+"al valor especificado.\n"
+"      --raw                             Graba/reproduce datos PCM con "
+"formato raw.\n"
+"      --file-format=FFORMAT             Graba/reproduce datos PCM "
+"formateados.\n"
+"      --list-file-formats               Muestra una lista con los formatos "
+"de archivo disponibles.\n"
 
 #: ../src/utils/pacat.c:727
 #, c-format
@@ -1371,8 +1501,12 @@ msgid "Failed to open audio file."
 msgstr "Falló al abrir el archivo de sonido."
 
 #: ../src/utils/pacat.c:956
-msgid "Warning: specified sample specification will be overwritten with specification from file."
-msgstr "Aviso: el ejemplo de especificación indicado será sobreescrito con las especificaciones del archivo."
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
+msgstr ""
+"Aviso: el ejemplo de especificación indicado será sobreescrito con las "
+"especificaciones del archivo."
 
 #: ../src/utils/pacat.c:959
 msgid "Failed to determine sample specification from file."
@@ -1392,8 +1526,11 @@ msgstr "Aviso: Faló al escribir el mapeo del canal en el archivo."
 
 #: ../src/utils/pacat.c:1005
 #, c-format
-msgid "Opening a %s stream with sample specification '%s' and channel map '%s'."
-msgstr "Abriendo un flujo %s con especificación de muestra '%s' y mapeo de canal '%s'."
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr ""
+"Abriendo un flujo %s con especificación de muestra '%s' y mapeo de canal '%"
+"s'."
 
 #: ../src/utils/pacat.c:1006
 msgid "recording"
@@ -1415,8 +1552,7 @@ msgstr "io_new() falló."
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() falló."
 
-#: ../src/utils/pacat.c:1066
-#: ../src/utils/pactl.c:1122
+#: ../src/utils/pacat.c:1066 ../src/utils/pactl.c:1122
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() falló: %s"
@@ -1454,14 +1590,12 @@ msgstr "Error al continuar: %s\n"
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "AVISO: El servidor de sonido no es local, no se suspende.\n"
 
-#: ../src/utils/pasuspender.c:159
-#: ../src/utils/pactl.c:814
+#: ../src/utils/pasuspender.c:159 ../src/utils/pactl.c:814
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Error en la conexión: %s\n"
 
-#: ../src/utils/pasuspender.c:176
-#: ../src/utils/pactl.c:820
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:820
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Hay SIGINT, saliendo.\n"
@@ -1478,14 +1612,16 @@ msgid ""
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 "%s [opciones] ... \n"
 "\n"
 "  -h, --help                            Muestra esta ayuda\n"
 "      --version                         Muestra la versión\n"
-"  -s, --server=SERVER                   El nombre del servidor con el que conectarse\n"
+"  -s, --server=SERVER                   El nombre del servidor con el que "
+"conectarse\n"
 "\n"
 
 #: ../src/utils/pasuspender.c:248
@@ -1499,20 +1635,17 @@ msgstr ""
 "Compilado con libpulse %s\n"
 "Linkeado con libpulse %s\n"
 
-#: ../src/utils/pasuspender.c:277
-#: ../src/utils/pactl.c:1104
+#: ../src/utils/pasuspender.c:277 ../src/utils/pactl.c:1104
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
 msgstr "pa_mainloop_new() falló.\n"
 
-#: ../src/utils/pasuspender.c:290
-#: ../src/utils/pactl.c:1116
+#: ../src/utils/pasuspender.c:290 ../src/utils/pactl.c:1116
 #, c-format
 msgid "pa_context_new() failed.\n"
 msgstr "pa_context_new() falló.\n"
 
-#: ../src/utils/pasuspender.c:298
-#: ../src/utils/pactl.c:1127
+#: ../src/utils/pasuspender.c:298 ../src/utils/pactl.c:1127
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() falló.\n"
@@ -1530,7 +1663,9 @@ msgstr "Actualmente en uso: %u bloques conteniendo %s bytes en total.\n"
 #: ../src/utils/pactl.c:137
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
-msgstr "Ubicados durante a lo largo del tiempo: %u bloques conteniendo %s bytes en total.\n"
+msgstr ""
+"Ubicados durante a lo largo del tiempo: %u bloques conteniendo %s bytes en "
+"total.\n"
 
 #: ../src/utils/pactl.c:140
 #, c-format
@@ -1609,14 +1744,12 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:261
-#: ../src/utils/pactl.c:353
+#: ../src/utils/pactl.c:261 ../src/utils/pactl.c:353
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPuertos:\n"
 
-#: ../src/utils/pactl.c:267
-#: ../src/utils/pactl.c:359
+#: ../src/utils/pactl.c:267 ../src/utils/pactl.c:359
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tPuerto Activo: %s\n"
@@ -1665,18 +1798,10 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:338
-#: ../src/utils/pactl.c:394
-#: ../src/utils/pactl.c:429
-#: ../src/utils/pactl.c:466
-#: ../src/utils/pactl.c:525
-#: ../src/utils/pactl.c:526
-#: ../src/utils/pactl.c:536
-#: ../src/utils/pactl.c:580
-#: ../src/utils/pactl.c:581
-#: ../src/utils/pactl.c:587
-#: ../src/utils/pactl.c:630
-#: ../src/utils/pactl.c:631
+#: ../src/utils/pactl.c:338 ../src/utils/pactl.c:394 ../src/utils/pactl.c:429
+#: ../src/utils/pactl.c:466 ../src/utils/pactl.c:525 ../src/utils/pactl.c:526
+#: ../src/utils/pactl.c:536 ../src/utils/pactl.c:580 ../src/utils/pactl.c:581
+#: ../src/utils/pactl.c:587 ../src/utils/pactl.c:630 ../src/utils/pactl.c:631
 #: ../src/utils/pactl.c:638
 msgid "n/a"
 msgstr "n/a"
@@ -1800,7 +1925,8 @@ msgstr ""
 #: ../src/utils/pactl.c:547
 #, c-format
 msgid "Failed to get source output information: %s\n"
-msgstr "Error al intentar obtener información acerca de la salida de la fuenta: %s\n"
+msgstr ""
+"Error al intentar obtener información acerca de la salida de la fuenta: %s\n"
 
 #: ../src/utils/pactl.c:567
 #, c-format
@@ -1867,8 +1993,7 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:646
-#: ../src/utils/pactl.c:656
+#: ../src/utils/pactl.c:646 ../src/utils/pactl.c:656
 #, c-format
 msgid "Failure: %s\n"
 msgstr "Falla: %s\n"
@@ -1904,8 +2029,10 @@ msgid ""
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
 msgstr ""
 "%s [opciones] stat\n"
 "%s [opciones] list\n"
@@ -1926,8 +2053,10 @@ msgstr ""
 "  -h, --help                            Muestra esta ayuda\n"
 "      --version                         Muestra la versión\n"
 "\n"
-"  -s, --server=SERVER                   El nombre del servidor al que conectarse\n"
-"  -n, --client-name=NAME                El nombre de este cliente en el servidor\n"
+"  -s, --server=SERVER                   El nombre del servidor al que "
+"conectarse\n"
+"  -n, --client-name=NAME                El nombre de este cliente en el "
+"servidor\n"
 
 #: ../src/utils/pactl.c:880
 #, c-format
@@ -1959,7 +2088,9 @@ msgstr "Error al intentar determinar especificación de ejemplo del archivo.\n"
 
 #: ../src/utils/pactl.c:951
 msgid "Warning: Failed to determine sample specification from file.\n"
-msgstr "Aviso: Fallo al intentar determinar especificación de ejemplo desde el archivo.\n"
+msgstr ""
+"Aviso: Fallo al intentar determinar especificación de ejemplo desde el "
+"archivo.\n"
 
 #: ../src/utils/pactl.c:961
 msgid "You have to specify a sample name to play\n"
@@ -1971,11 +2102,13 @@ msgstr "Debe especificar un nombre de muestra para ser eliminado\n"
 
 #: ../src/utils/pactl.c:982
 msgid "You have to specify a sink input index and a sink\n"
-msgstr "Debe especificar un índice para las entradas del destino y un destino\n"
+msgstr ""
+"Debe especificar un índice para las entradas del destino y un destino\n"
 
 #: ../src/utils/pactl.c:992
 msgid "You have to specify a source output index and a source\n"
-msgstr "Debe especificar un índice para las salidas de la fuente, y una fuente\n"
+msgstr ""
+"Debe especificar un índice para las salidas de la fuente, y una fuente\n"
 
 #: ../src/utils/pactl.c:1007
 msgid "You have to specify a module name and arguments.\n"
@@ -1986,12 +2119,20 @@ msgid "You have to specify a module index\n"
 msgstr "Debe especificar un índice de módulo\n"
 
 #: ../src/utils/pactl.c:1037
-msgid "You may not specify more than one sink. You have to specify a boolean value.\n"
-msgstr "No puede especificar más de un sumidero. Tiene que especificar un valor booleano.\n"
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean "
+"value.\n"
+msgstr ""
+"No puede especificar más de un sumidero. Tiene que especificar un valor "
+"booleano.\n"
 
 #: ../src/utils/pactl.c:1050
-msgid "You may not specify more than one source. You have to specify a boolean value.\n"
-msgstr "No puede especificar más de una fuente. Tiene que especificar un valor booleano.\n"
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value.\n"
+msgstr ""
+"No puede especificar más de una fuente. Tiene que especificar un valor "
+"booleano.\n"
 
 #: ../src/utils/pactl.c:1062
 msgid "You have to specify a card name/index and a profile name\n"
@@ -2016,14 +2157,17 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
 "%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
 "\n"
-" -d    Muestra los datos actuales de PulseAudio asociados en un display X11 (por defecto)\n"
+" -d    Muestra los datos actuales de PulseAudio asociados en un display X11 "
+"(por defecto)\n"
 " -e    Exporta los datos locales de PulseAudio a un display X11\n"
-" -i    Importa los datos de PulseAudio de un display X11 hacia las variables del entorno local y el archivo de cookies.\n"
+" -i    Importa los datos de PulseAudio de un display X11 hacia las variables "
+"del entorno local y el archivo de cookies.\n"
 " -r    Elimina todo dato de PulseAudio de un display X11\n"
 
 #: ../src/utils/pax11publish.c:94
@@ -2088,7 +2232,9 @@ msgstr "Aún no se ha implementado.\n"
 
 #: ../src/utils/pacmd.c:69
 msgid "No PulseAudio daemon running, or not running as session daemon."
-msgstr "El demonio PulseAudio no está ejecutándose, o no se está ejecutando como un demonio de sesión."
+msgstr ""
+"El demonio PulseAudio no está ejecutándose, o no se está ejecutando como un "
+"demonio de sesión."
 
 #: ../src/utils/pacmd.c:74
 #, c-format
@@ -2113,46 +2259,53 @@ msgstr "El demonio no responde."
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171
-#: ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207
-#: ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136
-#: ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
 msgid "Cannot access autospawn lock."
 msgstr "No se puede acceder al candado de autogeneración."
 
-#: ../src/modules/alsa/alsa-sink.c:451
-#: ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
-"ALSA woke us up to write new data to the device, but there was actually nothing to write!\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
-"We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."
+"ALSA woke us up to write new data to the device, but there was actually "
+"nothing to write!\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers.\n"
+"We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
+"returned 0 or another value < min_avail."
 msgstr ""
-"ALSA nos despertó para escribir nuevos datos al dispositivo, ¡pero en realidad no hay nada para escribir!\n"
-"Probablemente sea un error en el controlador ALSA '%s'. Por favor, informe esto a los desarrolladores de ALSA.\n"
-"Nos despertaron con POLLOUT puesto -- sin embargo, una llamada a snd_pcm_avail() devolvió 0 u otro valor < min_avail."
+"ALSA nos despertó para escribir nuevos datos al dispositivo, ¡pero en "
+"realidad no hay nada para escribir!\n"
+"Probablemente sea un error en el controlador ALSA '%s'. Por favor, informe "
+"esto a los desarrolladores de ALSA.\n"
+"Nos despertaron con POLLOUT puesto -- sin embargo, una llamada a "
+"snd_pcm_avail() devolvió 0 u otro valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431
-#: ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
-"ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
-"We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."
+"ALSA woke us up to read new data from the device, but there was actually "
+"nothing to read!\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers.\n"
+"We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
+"returned 0 or another value < min_avail."
 msgstr ""
-"ALSA nos despertó para leer nuevos datos desde el dispositivo, ¡pero en realidad no hay nada para leer!\n"
-"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, informe esto a los desarrolladores de ALSA.\n"
-"Nos despertaron con POLLIN puesto -- sin embargo, una llamada a snd_pcm_avail() devolvió 0 u otro valor < min_avail."
+"ALSA nos despertó para leer nuevos datos desde el dispositivo, ¡pero en "
+"realidad no hay nada para leer!\n"
+"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
+"informe esto a los desarrolladores de ALSA.\n"
+"Nos despertaron con POLLIN puesto -- sin embargo, una llamada a snd_pcm_avail"
+"() devolvió 0 u otro valor < min_avail."
 
 #: ../src/modules/alsa/module-alsa-card.c:152
 #: ../src/modules/bluetooth/module-bluetooth-device.c:2070
@@ -2173,65 +2326,90 @@ msgstr "Servidor de Sonido PulseAudio"
 
 #~ msgid "select(): %s"
 #~ msgstr "select(): %s"
+
 #~ msgid "Cannot connect to system bus: %s"
 #~ msgstr "No se puede conectar al bus del sistema: %s"
+
 #~ msgid "Cannot get caller from PID: %s"
 #~ msgstr "No se puede obtener el llamador desde el PID: %s"
+
 #~ msgid "Cannot set UID on caller object."
 #~ msgstr "No se puede poner UID en el objeto llamador."
+
 #~ msgid "Failed to get CK session."
 #~ msgstr "Falló al obtener sesión CK."
+
 #~ msgid "Cannot set UID on session object."
 #~ msgstr "No se puede poner UID en el objeto de sesión."
+
 #~ msgid "Cannot allocate PolKitAction."
 #~ msgstr "No se puede asignar PolKitAction."
+
 #~ msgid "Cannot set action_id"
 #~ msgstr "No se pudo poner action_id"
+
 #~ msgid "Cannot allocate PolKitContext."
 #~ msgstr "No se pudo asignar PolKitContext."
+
 #~ msgid "Cannot initialize PolKitContext: %s"
 #~ msgstr "No se pudo inicializar PolKitContext: %s"
+
 #~ msgid "Could not determine whether caller is authorized: %s"
 #~ msgstr "No se pudo determinar si el llamador está autorizado: %s"
+
 #~ msgid "Cannot obtain auth: %s"
 #~ msgstr "No se pudo obtener auth: %s"
+
 #~ msgid "PolicyKit responded with '%s'"
 #~ msgstr "PolicyKit respondió con '%s'"
+
 #~ msgid ""
 #~ "High-priority scheduling (negative Unix nice level) for the PulseAudio "
 #~ "daemon"
 #~ msgstr ""
 #~ "Planificación de alta prioridad (nivel Unix negativo) para el demonio "
 #~ "PulseAudio"
+
 #~ msgid "Real-time scheduling for the PulseAudio daemon"
 #~ msgstr "Planificación de tiempo real para el demonio de PulseAudio."
+
 #~ msgid ""
 #~ "System policy prevents PulseAudio from acquiring high-priority scheduling."
 #~ msgstr ""
 #~ "Las políticas del sistema impidieron a PulseAudio adquirir la "
 #~ "planificación de alta prioridad."
+
 #~ msgid ""
 #~ "System policy prevents PulseAudio from acquiring real-time scheduling."
 #~ msgstr ""
 #~ "Las políticas del sistema impidieron a PulseAudio adquirir la "
 #~ "planificación de tiempo real."
+
 #~ msgid "read() failed: %s\n"
 #~ msgstr "read() falló: %s\n"
+
 #~ msgid "pa_context_connect() failed: %s\n"
 #~ msgstr "pa_context_connect() falló: %s\n"
+
 #~ msgid "We're in the group '%s', allowing high-priority scheduling."
 #~ msgstr ""
 #~ "Estamos en el grupo '%s', permitiendo planificación de prioridad alta."
+
 #~ msgid "We're in the group '%s', allowing real-time scheduling."
 #~ msgstr "Estamos en el grupo '%s', permitiendo planificación en tiempo real."
+
 #~ msgid "PolicyKit grants us acquire-high-priority privilege."
 #~ msgstr "PolicyKit garantiza que se obtenga el privilegio de alta prioridad."
+
 #~ msgid "PolicyKit refuses acquire-high-priority privilege."
 #~ msgstr "PolicyKit se niega a dar acceso al privilegio de alta prioridad."
+
 #~ msgid "PolicyKit grants us acquire-real-time privilege."
 #~ msgstr "PolicyKit garantiza el acceso al privilegio de tiempo real."
+
 #~ msgid "PolicyKit refuses acquire-real-time privilege."
 #~ msgstr "PolicyKit se niega a dar acceso al privilegio de tiempo real."
+
 #~ msgid ""
 #~ "Called SUID root and real-time and/or high-priority scheduling was "
 #~ "requested in the configuration. However, we lack the necessary "
@@ -2253,61 +2431,86 @@ msgstr "Servidor de Sonido PulseAudio"
 #~ "adquiera los privilegios apropiados en PolicyKit, o hágase miembro de '%"
 #~ "s', o aumente los límites del recurso RLIMIT_NICE/RLIMIT_RTPRIO para este "
 #~ "usuario."
+
 #~ msgid ""
 #~ "High-priority scheduling enabled in configuration but not allowed by "
 #~ "policy."
 #~ msgstr ""
 #~ "Está habilitadada la planificación de prioridad alta, pero no están "
 #~ "permitidas por la política."
+
 #~ msgid "Successfully increased RLIMIT_RTPRIO"
 #~ msgstr "RLIMIT_RTPRIO incrementado en forma exitosa"
+
 #~ msgid "RLIMIT_RTPRIO failed: %s"
 #~ msgstr "Fallo en RLIMIT_RTPRIO: %s"
+
 #~ msgid "Giving up CAP_NICE"
 #~ msgstr "Abandonando CAP_NICE"
+
 #~ msgid ""
 #~ "Real-time scheduling enabled in configuration but not allowed by policy."
 #~ msgstr ""
 #~ "Está habilitada la planificación en tiempo real, pero no está permitido "
 #~ "por la política."
+
 #~ msgid "Limited capabilities successfully to CAP_SYS_NICE."
 #~ msgstr "Capacidades limitadas con éxito para CAP_SYS_NICE-"
+
 #~ msgid "time_new() failed.\n"
 #~ msgstr "time_new() falló.\n"
+
 #~ msgid "Analog Mono"
 #~ msgstr "Mono Analógico"
+
 #~ msgid "Analog Stereo"
 #~ msgstr "Estéreo Analógico"
+
 #~ msgid "Digital Stereo (IEC958)"
 #~ msgstr "Estéreo Digital (IEC958)"
+
 #~ msgid "Digital Stereo (HDMI)"
 #~ msgstr "Estéreo Digital (HDMI)"
+
 #~ msgid "Analog Surround 4.0"
 #~ msgstr "Análogo Envolvente 4.0"
+
 #~ msgid "Digital Surround 4.0 (IEC958/AC3)"
 #~ msgstr "Digital Envolvente 4.0 (IEC9588/AC3)"
+
 #~ msgid "Analog Surround 4.1"
 #~ msgstr "Análogo Envolvente 4.1"
+
 #~ msgid "Analog Surround 5.0"
 #~ msgstr "Análogo Envolvente 5.0"
+
 #~ msgid "Analog Surround 5.1"
 #~ msgstr "Análogo Envolvente 5.1"
+
 #~ msgid "Digital Surround 5.1 (IEC958/AC3)"
 #~ msgstr "Digital Envolvente 5.1 (IEC958/AC3)"
+
 #~ msgid "Analog Surround 7.1"
 #~ msgstr "Análogo Envolvénte 7.1"
+
 #~ msgid "Output %s + Input %s"
 #~ msgstr "Salida %s + Entrada %s"
+
 #~ msgid "Output %s"
 #~ msgstr "Salida %s"
+
 #~ msgid "Input %s"
 #~ msgstr "Entrada %s"
+
 #~ msgid "Stream successfully created\n"
 #~ msgstr "Se ha creado el flujo exitosamente\n"
+
 #~ msgid "Stream errror: %s\n"
 #~ msgstr "Error de flujo: %s\n"
+
 #~ msgid "Connection established.\n"
 #~ msgstr "Conección establecida.\n"
+
 #~ msgid ""
 #~ "%s [options] [FILE]\n"
 #~ "\n"
@@ -2348,6 +2551,7 @@ msgstr "Servidor de Sonido PulseAudio"
 #~ "(linear)en el rango de 0...65536\n"
 #~ "      --channel-map=CHANNELMAP          Establece el mapa del canal para "
 #~ "el uso\n"
+
 #~ msgid ""
 #~ "paplay %s\n"
 #~ "Compiled with libpulse %s\n"
@@ -2356,12 +2560,16 @@ msgstr "Servidor de Sonido PulseAudio"
 #~ "paplay %s\n"
 #~ "Compilado con libpulse %s\n"
 #~ "Linked con libpulse %s\n"
+
 #~ msgid "Invalid channel map\n"
 #~ msgstr "Mapa de canal inválido\n"
+
 #~ msgid "Failed to open file '%s'\n"
 #~ msgstr "Error al intentar abrir el archivo '%s'\n"
+
 #~ msgid "Channel map doesn't match file.\n"
 #~ msgstr "El mapa del canal no se corresponde con el archivo.\n"
+
 #~ msgid "Using sample spec '%s'\n"
 #~ msgstr "Utilizando especificaciones de muestra '%s'\n"
 
@@ -2380,6 +2588,7 @@ msgstr "Servidor de Sonido PulseAudio"
 #, fuzzy
 #~ msgid "--log-time boolean argument"
 #~ msgstr "--disallow-exit argumento booleano"
+
 #~ msgid ""
 #~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
 #~ "For enabling real-time scheduling please acquire the appropriate "
@@ -2388,21 +2597,27 @@ msgstr "Servidor de Sonido PulseAudio"
 #~ "' y PolicyKit se niega a darnos privilegios. Abandonando SUID de nuevo.\n"
 #~ "Para permitir planificación en tiempo real, por favor adquiera los "
 #~ "privilegios de PolicyKit adecuados, o forme parte de '"
+
 #~ msgid ""
 #~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this "
 #~ "user."
 #~ msgstr ""
 #~ "', o incremente los límites del recurso RLIMIT_NICE/RLIMIT_RTPRIO para "
 #~ "ese usuario. "
+
 #~ msgid "Default sink name (%s) does not exist in name register."
 #~ msgstr ""
 #~ "El nombre de destino por defecto (%s) no existe en el registro de nombres."
+
 #~ msgid "Buffer overrun, dropping incoming data\n"
 #~ msgstr "Búfer desbordado, abandonando datos entrantes\n"
+
 #~ msgid "pa_stream_drop() failed: %s\n"
 #~ msgstr "pa_stream_drop() falló: %s\n"
+
 #~ msgid "muted"
 #~ msgstr "mudo"
+
 #~ msgid ""
 #~ "*** Autoload Entry #%u ***\n"
 #~ "Name: %s\n"
@@ -2415,8 +2630,9 @@ msgstr "Servidor de Sonido PulseAudio"
 #~ "Tipo: %s\n"
 #~ "Módulo: %s\n"
 #~ "Argumento: %s\n"
+
 #~ msgid "sink"
 #~ msgstr "destino"
+
 #~ msgid "source"
 #~ msgstr "fuente"
-
diff --git a/po/fi.po b/po/fi.po
index 51f591c..b6c7c9b 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: git trunk\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-05 16:24+0300\n"
 "Last-Translator: Ville-Pekka Vainio <vpivaini at cs.helsinki.fi>\n"
 "Language-Team: Finnish <laatu at lokalisointi.org>\n"
@@ -365,29 +365,29 @@ msgstr ""
 "Hei, ytimesi on kehno! Linux korkean tarkkuuden ajastimien tuella on hyvin "
 "suositeltava!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() epäonnistui."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Taustaprosessin alustus epäonnistui."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "Taustaprosessin käynnistys ilman ladattavia moduuleita, kieltäydytään "
 "toiminnasta."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Taustaprosessin käynnistys valmis."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Taustaprosessin sulkeminen käynnistetty."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Taustaprosessi lopetettu."
 
@@ -953,7 +953,7 @@ msgstr "Vasen ylä taka"
 msgid "Top Rear Right"
 msgstr "Oikea ylä taka"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1083,27 +1083,27 @@ msgstr "Puuttuva toteutus"
 msgid "Client forked"
 msgstr "Asiakasohjelma haarautui"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %u kan. %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2255,7 +2255,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Automaattisen käynnistyksen lukkoa ei voida käyttää."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2272,7 +2272,7 @@ msgstr ""
 "asetettuna,  snd_pcm_avail() palautti kuitenkin 0 tai jonkin muun arvon, "
 "joka on < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/fr.po b/po/fr.po
index ba6122b..b8c2ba7 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio trunk\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-26 17:22+0200\n"
 "Last-Translator: Corentin Perard <corentin.perard at gmail.com>\n"
 "Language-Team: French <fedora-trans-fr at redhat.com>\n"
@@ -372,27 +372,27 @@ msgstr ""
 "Eh mec, ton noyau il pue ! La recommandation d'aujourd'hui du patron est "
 "d'activer les horloges à haute résolution sur ton Linux."
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "Échec de pa_core_new()."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Échec lors de l'initialisation du démon"
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Démarrage du démon sans aucun module chargé : refus de fonctionner."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Démarrage du démon effectué."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Fermeture du démon initiée."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Démon terminé."
 
@@ -963,7 +963,7 @@ msgstr "Arrière gauche haut"
 msgid "Top Rear Right"
 msgstr "Arrière droit haut"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1093,27 +1093,27 @@ msgstr "Implantation manquante"
 msgid "Client forked"
 msgstr "Le client s'est divisé (Client forked)"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f Gio"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f Mio"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f Kio"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2294,7 +2294,7 @@ msgstr "write() : %s"
 msgid "Cannot access autospawn lock."
 msgstr "Impossible d'accèder au verrou autonome."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2311,7 +2311,7 @@ msgstr ""
 "le jeu POLLOUT -- cependant un snd_pcm_avail() ultérieur a retourné 0 ou une "
 "autre valeur < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/gu.po b/po/gu.po
index f454c3f..53f3df3 100644
--- a/po/gu.po
+++ b/po/gu.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-07 14:27+0530\n"
 "Last-Translator: Sweta Kothari <swkothar at redhat.com>\n"
 "Language-Team: Gujarati\n"
@@ -361,27 +361,27 @@ msgstr ""
 "મિત્ર, તમારુ કર્નલમાં ગડબડ છે! રસોઇયાનું આજે ભલામણ એ સક્રિય થયેલ high-resolution "
 "ટાઇમરો સાથે Linux નું છે!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() નિષ્ફળ."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "ડિમનને શરૂ કરવામાં નિષ્ફળ."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "કોઇપણ લોડ થયેલ મોડ્યુલો વગર ડિમનને શરૂ કરો, કામ કરવા માટે ફરી શરૂ કરી રહ્યા છે."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "ડિમન પારંભ કરવાનું સમાપ્ત છે."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "ડિમનને બંધ કરવાનું પ્રારંભ થયેલ છે."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "ડિમનનો અંત આવેલ છે."
 
@@ -931,7 +931,7 @@ msgstr "ઉપર રિઅર ડાબે"
 msgid "Top Rear Right"
 msgstr "ઉપર રિઅર જમણે"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1061,27 +1061,27 @@ msgstr "ગુમ થયેલ અમલીકરણ"
 msgid "Client forked"
 msgstr "ક્લાઇન્ટમાં ફાટા પડેલ છે"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2232,7 +2232,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn તાળાને દાખલ કરી શકાતુ નથી."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2249,7 +2249,7 @@ msgstr ""
 "POLLOUT સુયોજન સાથે આપણે જાગેલ હતા -- છતાંપણ ના પછીનું snd_pcm_avail() ને 0 પાછો મળે "
 "છે અથવા બીજી કિંમત < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/hi.po b/po/hi.po
index d784e71..a2327fd 100644
--- a/po/hi.po
+++ b/po/hi.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-06-08 12:01+0530\n"
 "Last-Translator: Rajesh Ranjan <rajesh672 at gmail.com>\n"
 "Language-Team: Hindi <hindi.sf.net>\n"
@@ -360,27 +360,27 @@ msgid ""
 msgstr ""
 "आपका कर्नेल बुरी स्थिति में है! सलाह है कि उच्च विभेदन युक्त लिनक्स सक्रिय किया जाना चाहिए!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() विफल."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "डेमॉन आरंभ करने में विफल."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "बिना लोड मॉड्यूल के डेमॉन आरंभ, काम करने से अस्वीकार कर रहा है."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "डेमॉन आरंभन पूर्ण."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "डेमॉन बन्द किया जाना आरंभ."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "डेमॉन अवरोधित."
 
@@ -932,7 +932,7 @@ msgstr "ऊपर पश्च बायाँ"
 msgid "Top Rear Right"
 msgstr "ऊपर पश्च दायाँ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1062,27 +1062,27 @@ msgstr "अनुपस्थित कार्यान्वयन"
 msgid "Client forked"
 msgstr "क्लाएंट विभाजित"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2238,7 +2238,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn लॉक की पहुँच नहीं ले सकता है."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2255,7 +2255,7 @@ msgstr ""
 "हमें POLLOUT सेट के साथ तैयार किया गया है  -- हालांकि परवर्ती snd_pcm_avail() ने 0 या "
 "दूसरा मान < min_avail दिया."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/it.po b/po/it.po
index de337c2..9a6c99e 100644
--- a/po/it.po
+++ b/po/it.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-20 22:34+0200\n"
 "Last-Translator: mario_santagiuliana <mario at marionline.it>\n"
 "Language-Team: Italian <fedora-trans-it at redhat.com>\n"
@@ -372,27 +372,27 @@ msgstr ""
 "Hey, questo kernel è andato a male! Lo chef oggi raccomanda Linux con i "
 "timer high-resolution abilitati!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() non riuscita."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Inizializzazione del demone non riuscita."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Avvio del demone senza alcun modulo caricato, rifiuta di lavorare."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Completato l'avvio del demone."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Iniziato l'arresto del demone."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Demone terminato."
 
@@ -981,7 +981,7 @@ msgstr "Superiore posteriore sinistro"
 msgid "Top Rear Right"
 msgstr "Superiore posteriore destro"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1111,27 +1111,27 @@ msgstr "Implementazione mancante"
 msgid "Client forked"
 msgstr "Fork del client"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s ch %u %u Hz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2323,7 +2323,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Impossibile accedere al lock di autospawn."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2340,7 +2340,7 @@ msgstr ""
 "Ci si è alzati con impostato POLLOUT -- come sempre un subsequent "
 "snd_pcm_avail() ritorna 0 o un altro valore < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/kn.po b/po/kn.po
index 53705a9..c2f632c 100644
--- a/po/kn.po
+++ b/po/kn.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-07 11:13+0530\n"
 "Last-Translator: Shankar Prasad <svenkate at redhat.com>\n"
 "Language-Team: Kannada <en at li.org>\n"
@@ -366,27 +366,27 @@ msgstr ""
 "ಮಹಾಶಯರೆ, ನಿಮ್ಮ ಕರ್ನಲ್ ಕೊಳೆತುಹೋಗಿದೆ! ಅತ್ಯುತ್ತಮ ರೆಸಲ್ಯೂಶನ್ ಟೈಮರ್ ಅನ್ನು ಶಕ್ತಗೊಳಿಸಲಾದ "
 "ಲಿನಕ್ಸನ್ನು ಬಳಸುವಂತೆ ಅಡುಗೆಯವರು ಸಲಹೆ ಮಾಡುತ್ತಿದ್ದಾರೆ!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "ಡೀಮನ್ ಅನ್ನು ಆರಂಭಿಸಲು ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ಲೋಡ್ ಮಾಡಲಾದ ಯಾವುದೆ ಡೀಮನ್ ಇಲ್ಲದೆ ಆರಂಭಗೊಂಡಿದೆ, ಕೆಲಸ ಮಾಡಲು ನಿರಾಕರಿಸಿದೆ."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "ಡೀಮನ್ ಆರಂಭಗೊಳಿಕೆ ಪೂರ್ಣಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "ಡೀಮನ್ ಸ್ಥಗಿತಗೊಳಿಕೆಯನ್ನು ಆರಂಭಿಸಲಾಗಿದೆ."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "ಡೀಮನ್ ಅನ್ನು ಅಂತ್ಯಗೊಳಿಸಲಾಗಿದೆ."
 
@@ -943,7 +943,7 @@ msgstr "ಮೇಲಿನ ಹಿಂಬದಿಯ ಎಡಭಾಗ"
 msgid "Top Rear Right"
 msgstr "ಮೇಲಿನ ಹಿಂಬದಿಯ ಬಲಭಾಗ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1073,27 +1073,27 @@ msgstr "ಅನ್ವಯಿಸುವಿಕೆಯು ಕಾಣಿಸುತ್ತ
 msgid "Client forked"
 msgstr "ಕ್ಲೈಂಟ್ ಅನ್ನು ಫೋರ್ಕ್ ಮಾಡಲಾಗಿದೆ"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2248,7 +2248,7 @@ msgstr "ಬರೆ(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "ಸ್ವಯಂಹೆಚ್ಚಿಸುವಿಕೆಯ ಲಾಕ್ ಅನ್ನು ನಿಲುಕಿಸಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಿಲ್ಲ."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2263,7 +2263,7 @@ msgstr ""
 "ವಿಕಸನಗಾರರ ಗಮನಕ್ಕೆ ತನ್ನಿ.POLLOUT ಸೆಟ್‌ನಿಂದ ನಾವು ಎಚ್ಚೆತ್ತುಗೊಂಡಿದ್ದೇವೆ -- ಆದರೆ ನಂತರದ "
 "snd_pcm_avail() 0 ಅಥವ min_avail ಕ್ಕಿಂತ ಚಿಕ್ಕದಾದ ಇನ್ನೊಂದು ಮೌಲ್ಯವನ್ನು ಮರಳಿಸಿದೆ."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/ko.po b/po/ko.po
index bcb746f..80f64e2 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -344,27 +344,27 @@ msgid ""
 "resolution timers enabled!"
 msgstr ""
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr ""
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr ""
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr ""
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr ""
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr ""
 
@@ -842,7 +842,7 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -972,27 +972,27 @@ msgstr ""
 msgid "Client forked"
 msgstr ""
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr ""
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr ""
@@ -1928,7 +1928,7 @@ msgstr ""
 msgid "Cannot access autospawn lock."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -1939,7 +1939,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/mr.po b/po/mr.po
index 2538adc..2fd9d36 100644
--- a/po/mr.po
+++ b/po/mr.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-06 13:43+0530\n"
 "Last-Translator: Sandeep Shedmake <sandeep.shedmake at gmail.com>\n"
 "Language-Team: marathi\n"
@@ -357,27 +357,27 @@ msgstr ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() अपयशी."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "डिमन प्रारंभ करण्यास अपयशी."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "विना विभाग दाखल केल्यास डिमन प्रारंभ झाले, कार्य करण्यास नकार."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "डिमन स्टार्टअप पूर्ण झाले."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "डिमन पूर्णपणे बंद करण्यास प्रारंभ केले."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "डिमन नष्ट केले."
 
@@ -929,7 +929,7 @@ msgstr "वरील पाठीमागचे डावे"
 msgid "Top Rear Right"
 msgstr "वरील पाठीमागचे उजवे"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1059,27 +1059,27 @@ msgstr "लागू केले आहे असे आढळले नाह
 msgid "Client forked"
 msgstr "क्लाऐंट विभाजीत केले"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2235,7 +2235,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn कुलूप करीता प्रवेश प्राप्य अशक्य."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2250,7 +2250,7 @@ msgstr ""
 "POLLOUT द्वारे सज्ज होणे शक्य आहे -- तरी परस्पर snd_pcm_avail() ने 0 पूरविले किंवा इतर "
 "मूल्य < min_avail असावे."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/nl.po b/po/nl.po
index e9be937..a569f3e 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-15 21:04+0200\n"
 "Last-Translator: Geert Warrink <geert.warrink at onsnet.nu>\n"
 "Language-Team: Dutch <nl at li.org>\n"
@@ -362,27 +362,27 @@ msgstr ""
 "Kerel, je kernel stinkt! De aanbeveling van de chef is vandaag Linux met "
 "aangezette high-resolution timers!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() mislukte."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Initialiseren van de daemon mislukte."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Daemon opgestart zonder geladen modules, dat werkt niet."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Daemon opstarten is klaar."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Daemon afsluiten is begonnen."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Daemon is afgesloten."
 
@@ -941,7 +941,7 @@ msgstr "boven achter links"
 msgid "Top Rear Right"
 msgstr "boven achter rechts"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1071,27 +1071,27 @@ msgstr "Implementatie ontbreekt"
 msgid "Client forked"
 msgstr "Client afgesplitst"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2035,7 +2035,7 @@ msgstr ""
 msgid "Cannot access autospawn lock."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2046,7 +2046,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/or.po b/po/or.po
index 359b8e8..be2b013 100644
--- a/po/or.po
+++ b/po/or.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-09 13:16+0530\n"
 "Last-Translator: Manoj Kumar Giri <mgiri at redhat.com>\n"
 "Language-Team: Oriya <oriya-it at googlegroups.com>\n"
@@ -367,27 +367,27 @@ msgstr ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "ଡେମନକୁ ଆରମ୍ଭ କରିବାରେ ବିଫଳ।"
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ଧାରଣ ହୋଇଥିବା ଏକକାଂଶଗୁଡ଼ିକ ବିନା ଡେମନ ଆରମ୍ଭ ହୋଇଛି, କାର୍ଯ୍ୟ କରିବାକୁ ବାରଣ କରୁଅଛି।"
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "ଡେମନ ଆରମ୍ଭ ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି।"
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "ଡେମନ ବନ୍ଦକୁ ଆରମ୍ଭ କରାଯାଇଛି।"
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "ଡେମନକୁ ସମାପ୍ତ କରାଯାଇଛି।"
 
@@ -938,7 +938,7 @@ msgstr "ଉପର ପଛ ବାମ ପାଖ"
 msgid "Top Rear Right"
 msgstr "ଉପର ପଛ ଡ଼ାହାଣ ପାଖ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1068,27 +1068,27 @@ msgstr "ଅନୁପସ୍ଥିତ ପ୍ରୟୋଗ"
 msgid "Client forked"
 msgstr "ଗ୍ରାହକ ଶାଖାଯୁକ୍ତ ହୋଇଛି"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2239,7 +2239,7 @@ msgstr "ଲେଖନ୍ତୁ(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn ଅପରିବର୍ତ୍ତନୀୟତାକୁ ଅଭିଗମ୍ୟ କରିହେଉ ନାହିଁ"
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2256,7 +2256,7 @@ msgstr ""
 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/pa.po b/po/pa.po
index bbda78f..ac5dc78 100644
--- a/po/pa.po
+++ b/po/pa.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pa\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-06-06 07:38+0530\n"
 "Last-Translator: A S Alam <aalam at users.sf.net>\n"
 "Language-Team: American English <punjabi-users at lists.sf.net>\n"
@@ -354,27 +354,27 @@ msgid ""
 msgstr ""
 "ਮਿੱਤਰਾ, ਤੇਰਾ ਕਰਨਲ ਪੁਰਾਣਾ ਹੈ! ਚੀਫ ਦੀ ਅੱਜ ਦੀ ਸਿਫਾਰਸ਼ ਹਾਈ-ਰੈਜ਼ੋਲੂਸ਼ਨ ਟਾਈਮਰ ਯੋਗ ਨਾਲ ਲੀਨਕਸ ਹੈ!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ।"
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂਆਤੀ ਬਿਨਾਂ ਕਿਸੇ ਲੋਡ ਕੀਤੇ ਮੈਡਿਊਲ, ਕੰਮ ਕਰਨ ਤੋਂ ਰੋਕ ਰਿਹਾ ਹੈ।"
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂਆਤੀ ਮੁਕੰਮਲ।"
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "ਡੈਮਨ ਬੰਦ ਕਰਨਾ ਸ਼ੁਰੂ ਹੋ ਗਿਆ।"
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "ਡੈਮਨ ਬੰਦ ਹੋ ਗਿਆ।"
 
@@ -924,7 +924,7 @@ msgstr "ਉੱਤੇ ਪਿੱਛੇ ਖੱਬੇ"
 msgid "Top Rear Right"
 msgstr "ਉੱਤੇ ਪਿੱਛੇ ਸੱਜੇ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1054,27 +1054,27 @@ msgstr "ਗੈਰ-ਮੌਜੂਦ ਨਿਰਧਾਰਨ"
 msgid "Client forked"
 msgstr "ਕਲਾਇਟ ਅੱਡ ਕੀਤਾ"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2226,7 +2226,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn ਲਾਕ ਵਰਤ ਨਹੀਂ ਸਕਦਾ।"
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2243,7 +2243,7 @@ msgstr ""
 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/pl.po b/po/pl.po
index af6cc1a..d3f9139 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -5,7 +5,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pl\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-08-22 12:12+0200\n"
 "Last-Translator: Piotr DrÄ…g <piotrdrag at gmail.com>\n"
 "Language-Team: Polish <pl at li.org>\n"
@@ -371,27 +371,27 @@ msgstr ""
 "Koleś, twoje jądro śmierdzi! Szef kuchni poleca dzisiaj Linuksa w włączonymi "
 "zegarami o wysokiej rozdzielczości!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() nie powiodło się."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Zainicjowanie demona nie powiodło się."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Uruchamianie demona bez żadnych wczytanych modułów, odmawianie pracy."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Zakończono uruchamianie demona."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Zainicjowano wyłączenie demona."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Demon został zniszczony."
 
@@ -951,7 +951,7 @@ msgstr "Górny tylny lewy"
 msgid "Top Rear Right"
 msgstr "Górny tylny prawy"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1081,27 +1081,27 @@ msgstr "Brak implementacji"
 msgid "Client forked"
 msgstr "Rozdzielono klienta"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2247,7 +2247,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Nie można uzyskać dostępu do blokady automatycznego wznawiania."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2264,7 +2264,7 @@ msgstr ""
 "Wybudzono za pomocą ustawienia POLLOUT - ale jednoczesne wywołanie "
 "snd_pcm_avail() zwróciło zero lub inną wartość < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/pt.po b/po/pt.po
index 005fbd1..1c81058 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Rui Gouveia <rui.gouveia at globaltek.pt>\n"
 "Language-Team: pt <fedora-trans-pt at redhat.com>\n"
@@ -361,27 +361,27 @@ msgstr ""
 "Oh pá, o teu kernel não presta! O prato do dia recomendado é Linux com "
 "timers de alta resolução activos!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() falhou."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Falha ao inicializar serviço."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Serviço arrancou sem módulos carregados. A recusar trabalhar."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Arranque do serviço completo."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Encerramento do serviço iniciado."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Serviço terminado."
 
@@ -946,7 +946,7 @@ msgstr "Topo Traseira Esquerda"
 msgid "Top Rear Right"
 msgstr "Topo Traseira Direita"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1076,27 +1076,27 @@ msgstr "Implementação em falta"
 msgid "Client forked"
 msgstr "Cliente efectuou um fork"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2063,7 +2063,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Impossível aceder ao lock \"autospawn\"."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2080,7 +2080,7 @@ msgstr ""
 "Fomos acordados pelo conjunto POLLOUT -- contudo uma chamada a seguir de "
 "snd_pcm_avail() retornou 0 ou outro valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 3a56e0e..fe19b9c 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-08-21 11:25-0300\n"
 "Last-Translator: Igor Pires Soares <igor at projetofedora.org>\n"
 "Language-Team: Brazilian-Portuguese <fedora-trans-pt_br at redhat.com>\n"
@@ -378,28 +378,28 @@ msgstr ""
 "Cara, teu kernel fede! A recomendação do chef hoje é Linux com timers de "
 "alta resolução habilitados!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() falhou."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Falha em iniciar o daemon."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "O Daemon iniciou sem qualquer módulo carregado, recusando-se a trabalhar."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "A partida dos Daemon está completa."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "O encerramento do Daemon foi iniciado."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Daemon terminado."
 
@@ -960,7 +960,7 @@ msgstr "Posterior Superior Esquerdo"
 msgid "Top Rear Right"
 msgstr "Posterior Superior Direito"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1090,27 +1090,27 @@ msgstr "Implementação faltando"
 msgid "Client forked"
 msgstr "Cliente bifurcado"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2265,7 +2265,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Não foi possível acessar a trava de autogeração."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2282,7 +2282,7 @@ msgstr ""
 "Nós fomos acordados com o conjunto POLLOUT -- entretanto, a snd_pcm_avail() "
 "subseqüente retornou 0 ou outro valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/sr.po b/po/sr.po
index e038089..f8badd2 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-07 23:02+0100\n"
 "Last-Translator: Miloš Komarčević <kmilos at gmail.com>\n"
 "Language-Team: Serbian <fedora-trans-sr at redhat.com>\n"
@@ -366,27 +366,27 @@ msgstr ""
 "Ваше језгро није добро подешено за pulseaudio! Препоручује Вам се да "
 "користите Linux језгро са омогућеним бројачима високе резолуције."
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "Неуспела функција pa_core_new()."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Неуспешно покретање демона."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Демон је покренут без иједног учитаног модула, одбија да ради."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Покретање демона успешно."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Покренуто гашење демона."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Рад демона је прекинут."
 
@@ -947,7 +947,7 @@ msgstr "Горњи позадински леви"
 msgid "Top Rear Right"
 msgstr "Горњи позадински десни"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1078,27 +1078,27 @@ msgstr "Није одрађено"
 msgid "Client forked"
 msgstr "Клијент израчван"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2249,7 +2249,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Није могуће приступити датотеци закључавања за самоумножавање."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2266,7 +2266,7 @@ msgstr ""
 "Пробуђени смо са постављеним POLLOUT-ом -- али следећи snd_pcm_avail() је "
 "вратио 0 или неку другу вредност мању од min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/sr at latin.po b/po/sr at latin.po
index b2aa721..5c0b164 100644
--- a/po/sr at latin.po
+++ b/po/sr at latin.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-07 23:02+0100\n"
 "Last-Translator: Miloš Komarčević <kmilos at gmail.com>\n"
 "Language-Team: Serbian <fedora-trans-sr at redhat.com>\n"
@@ -367,27 +367,27 @@ msgstr ""
 "Vaše jezgro nije dobro podešeno za pulseaudio! Preporučuje Vam se da "
 "koristite Linux jezgro sa omogućenim brojačima visoke rezolucije."
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "Neuspela funkcija pa_core_new()."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Neuspešno pokretanje demona."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Demon je pokrenut bez ijednog učitanog modula, odbija da radi."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Pokretanje demona uspešno."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Pokrenuto gašenje demona."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Rad demona je prekinut."
 
@@ -948,7 +948,7 @@ msgstr "Gornji pozadinski levi"
 msgid "Top Rear Right"
 msgstr "Gornji pozadinski desni"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1079,27 +1079,27 @@ msgstr "Nije odrađeno"
 msgid "Client forked"
 msgstr "Klijent izračvan"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2251,7 +2251,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Nije moguće pristupiti datoteci zaključavanja za samoumnožavanje."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2268,7 +2268,7 @@ msgstr ""
 "Probuđeni smo sa postavljenim POLLOUT-om -- ali sledeći snd_pcm_avail() je "
 "vratio 0 ili neku drugu vrednost manju od min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/sv.po b/po/sv.po
index e9d0dae..fb6299b 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2008-09-05 18:24+0100\n"
 "Last-Translator: Daniel Nylander <po at danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
@@ -348,27 +348,27 @@ msgid ""
 "resolution timers enabled!"
 msgstr ""
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() misslyckades."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr ""
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr ""
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr ""
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr ""
 
@@ -850,7 +850,7 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 #, fuzzy
@@ -981,27 +981,27 @@ msgstr ""
 msgid "Client forked"
 msgstr ""
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr ""
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr ""
@@ -1956,7 +1956,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -1967,7 +1967,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/ta.po b/po/ta.po
index 7dba18d..82bdeb2 100644
--- a/po/ta.po
+++ b/po/ta.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-12 05:02+0530\n"
 "Last-Translator: I. Felix <ifelix at redhat.com>\n"
 "Language-Team: Tamil <fedora-trans-ta at redhat.com>\n"
@@ -377,27 +377,27 @@ msgstr ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() தோல்வியுற்றது."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "டோமோனை ஆரம்பிப்பதில் தோல்வி."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "டீமான் துவக்கம் எந்த தொகுதிகளும் ஏற்றப்படாமல், வேலையை நிராகரிக்கிறது."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "டோமோன் துவக்குவது முடிவடைந்தது."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "டோமோன் பணிநிறுத்தம் முனைகிறது."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "டோமோன் நீக்கப்பட்டுது."
 
@@ -949,7 +949,7 @@ msgstr "மேலே பின் இடது"
 msgid "Top Rear Right"
 msgstr "மேலே பின் வலது"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1079,27 +1079,27 @@ msgstr "விடுபட்ட செயல்பாடு"
 msgid "Client forked"
 msgstr "கிளையன் நீக்கப்பட்டது"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2257,7 +2257,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "autospawn பூட்டை அணுக முடியவில்லை."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2268,7 +2268,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/te.po b/po/te.po
index 0325273..02f2e8b 100644
--- a/po/te.po
+++ b/po/te.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.te\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-08 18:21+0530\n"
 "Last-Translator: Krishna Babu K <kkrothap at redhat.com>\n"
 "Language-Team: Telugu <en at li.org>\n"
@@ -357,27 +357,27 @@ msgid ""
 "resolution timers enabled!"
 msgstr "మిత్రమా, నీ కెర్నల్ చెడిపోయింది! అధిక-తీవ్రత కాలసూచకిలను చేతనము చేయమని సూచించడమైనది!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() విఫలమైంది."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "డెమోన్ సిద్దముచేయుటకు విఫలమైంది."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ఏవిధమైన మాడ్యూళ్ళు లోడవకుండా డెమోన్ ప్రారంభము, పనిచేయుటకు తిరస్కరించబడింది."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "డెమోన్ ప్రారంభము పూర్తైనది."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "డెమోన్ మూసివేత సిద్దముచేయబడింది."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "డెమోన్ అంతముచేయబడింది."
 
@@ -929,7 +929,7 @@ msgstr "పైన వెనుక ఎడమవైపు"
 msgid "Top Rear Right"
 msgstr "పైన వెనుక కుడివైపున"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1059,27 +1059,27 @@ msgstr "తప్పిపోయిన యింప్లిమెంటేష
 msgid "Client forked"
 msgstr "కక్షిదారి పోర్క్ చేసిన"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2233,7 +2233,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "ఆటోస్పాన్ తాళంను యాక్సిస్ చేయలేదు."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2249,7 +2249,7 @@ msgstr ""
 "మనము POLLOUT అమర్పు ద్వారా జాగరూక పరచబడినాము -- ఏమైనప్పటికి snd_pcm_avail() అనునది 0 ను "
 "యిస్తుంది లేదా వేరొక విలువ < min_avail యిస్తుంది."
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/uk.po b/po/uk.po
index 76fcbcb..53757e7 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-18 11:13+0300\n"
 "Last-Translator: Yuri Chornoivan <yurchor at ukr.net>\n"
 "Language-Team: Ukrainian <translation at linux.org.ua>\n"
@@ -370,29 +370,29 @@ msgstr ""
 "Чувак, твоє ядро — лайно! Круті пацани рекомендують Linux з увімкненими "
 "високоточними таймерами!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "Спроба виконання pa_core_new() зазнала невдачі."
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "Не вдалося ініціалізувати фонову службу."
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "Запуск фонової служби без жодного завантаженого модуля, служба не буде "
 "працездатною."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "Запуск фонової служби завершено."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "Ініційовано завершення роботи фонової служби."
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "Виконання фонової служби перервано."
 
@@ -961,7 +961,7 @@ msgstr "Верхній задній лівий"
 msgid "Top Rear Right"
 msgstr "Верхній задній правий"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1091,27 +1091,27 @@ msgstr "Відсутня реалізація"
 msgid "Client forked"
 msgstr "Клієнт розгалужено"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uкан. %uГц"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f ГБ"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f МБ"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f кБ"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u Б"
@@ -2272,7 +2272,7 @@ msgstr "write(): %s"
 msgid "Cannot access autospawn lock."
 msgstr "Не вдалося зняти блокування автоматичного розгалуження."
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2283,7 +2283,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 6e64c82..55cb5c9 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-08-22 00:08+0200\n"
+"POT-Creation-Date: 2009-08-24 03:31+0200\n"
 "PO-Revision-Date: 2009-04-06 10:26+1000\n"
 "Last-Translator: Leah Liu <lliu at redhat.com>\n"
 "Language-Team: Simplified Chinese <zh at li.org>\n"
@@ -354,27 +354,27 @@ msgid ""
 "resolution timers enabled!"
 msgstr "老兄,你的内核真臭!现在流行的是启用了高分辩率计分器的Linux!"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:832
 msgid "pa_core_new() failed."
 msgstr "pa_core_new()失败。"
 
-#: ../src/daemon/main.c:891
+#: ../src/daemon/main.c:892
 msgid "Failed to initialize daemon."
 msgstr "后台程序初始化失败。"
 
-#: ../src/daemon/main.c:896
+#: ../src/daemon/main.c:897
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "后台程序启动未加载任何模块,拒绝工作。"
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:914
 msgid "Daemon startup complete."
 msgstr "后台程序启动完成。"
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:920
 msgid "Daemon shutdown initiated."
 msgstr "开始关闭后台程序。"
 
-#: ../src/daemon/main.c:941
+#: ../src/daemon/main.c:942
 msgid "Daemon terminated."
 msgstr "后台程序已终止。"
 
@@ -908,7 +908,7 @@ msgstr "上左后"
 msgid "Top Rear Right"
 msgstr "上右后"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:171
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
 #: ../src/pulse/volume.c:285 ../src/pulse/volume.c:311
 #: ../src/pulse/volume.c:331 ../src/pulse/volume.c:361
 msgid "(invalid)"
@@ -1038,27 +1038,27 @@ msgstr "缺少部署"
 msgid "Client forked"
 msgstr "客户端分支"
 
-#: ../src/pulse/sample.c:173
+#: ../src/pulse/sample.c:172
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:185
+#: ../src/pulse/sample.c:184
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:187
+#: ../src/pulse/sample.c:186
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:189
+#: ../src/pulse/sample.c:188
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:191
+#: ../src/pulse/sample.c:190
 #, c-format
 msgid "%u B"
 msgstr "%u B"
@@ -2192,7 +2192,7 @@ msgstr "write():%s"
 msgid "Cannot access autospawn lock."
 msgstr "不能访问autospawn锁。"
 
-#: ../src/modules/alsa/alsa-sink.c:451 ../src/modules/alsa/alsa-sink.c:608
+#: ../src/modules/alsa/alsa-sink.c:526 ../src/modules/alsa/alsa-sink.c:684
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2208,7 +2208,7 @@ msgstr ""
 "提醒我们设置 POLLOUT -- 但结果是 snd_pcm_avail() 返回 0 或者另一个小于最小可"
 "用值的数值。"
 
-#: ../src/modules/alsa/alsa-source.c:431 ../src/modules/alsa/alsa-source.c:580
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "

-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list