From: Peter Meerwald <p.meerw...@bct-electronic.com>

Reintroduces a cleaned-up version of commit 
30ce3a14e5ae1cd316a18bec95b831c07ac57a1a which
was reverted by 1ce71cbd8206d1be59ac62274ad83cdbe693a96a; for more information 
see
http://thread.gmane.org/gmane.comp.audio.pulseaudio.general/17479/focus=17487

The patch intends to reduce computational load when resampling AND remapping. 
The PA
resampler performs the following steps:

sample format conversion -> remapping -> resampling -> sample format conversion

In case the number of output channels is higher than the number of input 
channels, the
resampler has to be run more often than necessary. E.g. in case of mono to 
4-channel remapping,
the resampler runs on 4 channels separately.

To ímprove this, the PA resampler pipeline is made adaptive:

if out-channels <= in-channels:
  sample format conversion -> remapping -> resampling -> sample format 
conversion
if out-channels > in-channels:
  sample format conversion -> resampling -> remapping -> sample format 
conversion

Signed-off-by: Peter Meerwald <p.meerw...@bct-electronic.com>
---
 src/pulsecore/resampler.c |   38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 466c52f..5a9eebe 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -429,14 +429,30 @@ pa_resampler* pa_resampler_new(
         }
     }
 
-    /* leftover buffer is the buffer before the resampling stage */
-    r->leftover_buf = &r->remap_buf;
-    r->leftover_buf_size = &r->remap_buf_size;
-    r->have_leftover = &r->leftover_in_remap;
+    if (r->o_ss.channels <= r->i_ss.channels) {
+        /* pipeline is: format conv. -> remap -> resample -> format conv. */
+        r->work_channels = r->o_ss.channels;
+
+        /* leftover buffer is remap output buffer (before resampling) */
+        r->leftover_buf = &r->remap_buf;
+        r->leftover_buf_size = &r->remap_buf_size;
+        r->have_leftover = &r->leftover_in_remap;
+    } else {
+        /* pipeline is: format conv. -> resample -> remap -> format conv. */
+        r->work_channels = r->i_ss.channels;
 
-    r->work_channels = r->o_ss.channels;
+        /* leftover buffer is to_work output buffer (before resampling) */
+        r->leftover_buf = &r->to_work_format_buf;
+        r->leftover_buf_size = &r->to_work_format_buf_size;
+        r->have_leftover = &r->leftover_in_to_work;
+    }
     r->w_fz = pa_sample_size_of_format(r->work_format) * r->work_channels;
 
+    pa_log_debug("Resampler:\n  rate %d -> %d (method %s),\n  format %s -> %s 
(intermediate %s),\n  channels %d -> %d (resampling %d)",
+        a->rate, b->rate, pa_resample_method_to_string(r->method),
+        pa_sample_format_to_string(a->format), 
pa_sample_format_to_string(b->format), 
pa_sample_format_to_string(r->work_format),
+        a->channels, b->channels, r->work_channels);
+
     /* initialize implementation */
     if (init_table[method](r) < 0)
         goto fail;
@@ -1349,8 +1365,16 @@ void pa_resampler_run(pa_resampler *r, const pa_memchunk 
*in, pa_memchunk *out)
 
     buf = (pa_memchunk*) in;
     buf = convert_to_work_format(r, buf);
-    buf = remap_channels(r, buf);
-    buf = resample(r, buf);
+
+    /* Try to save resampling effort: if we have more output channels than
+     * input channels, do resampling first, then remapping. */
+    if (r->o_ss.channels <= r->i_ss.channels) {
+        buf = remap_channels(r, buf);
+        buf = resample(r, buf);
+    } else {
+        buf = resample(r, buf);
+        buf = remap_channels(r, buf);
+    }
 
     if (buf->length) {
         buf = convert_from_work_format(r, buf);
-- 
1.7.9.5

_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to