[pulseaudio-discuss] [PATCH 1/2] Rework the peaks resampler

Maarten Bosmans mkbosmans at gmail.com
Fri Oct 14 02:39:57 PDT 2011


The algorithm was done the same way as the trivial resampler.  But an important
difference between the two is that the trivial resampler can write an output as
soon as the first corresponding input sample is seen, whereas the peaks resampler
must have read all input samples before writing an output sample.
---
 src/pulsecore/resampler.c |   55 ++++++++++++++++++--------------------------
 1 files changed, 23 insertions(+), 32 deletions(-)

diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 3ca0a2f..f061f3d 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -1441,9 +1441,9 @@ static int trivial_init(pa_resampler*r) {
 
 static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
     size_t fz;
-    unsigned o_index;
+    unsigned c, o_index = 0;
+    unsigned i, i_end = 0;
     void *src, *dst;
-    unsigned start = 0;
 
     pa_assert(r);
     pa_assert(input);
@@ -1455,25 +1455,20 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
     src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
     dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
 
-    for (o_index = 0;; o_index++, r->peaks.o_counter++) {
-        unsigned j;
+    i = ((r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate);
+    i = i > r->peaks.i_counter ? i - r->peaks.i_counter : 0;
 
-        j = ((r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate);
-
-        if (j > r->peaks.i_counter)
-            j -= r->peaks.i_counter;
-        else
-            j = 0;
+    while (i_end < in_n_frames) {
+        i_end = (((r->peaks.o_counter+1) * r->i_ss.rate) / r->o_ss.rate);
+        i_end = i_end > r->peaks.i_counter ? i_end - r->peaks.i_counter : 0;
 
         pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
 
         if (r->work_format == PA_SAMPLE_S16NE) {
-            unsigned i, c;
-            int16_t *s = (int16_t*) ((uint8_t*) src + fz * start);
+            int16_t *s = (int16_t*) ((uint8_t*) src + fz * i);
             int16_t *d = (int16_t*) ((uint8_t*) dst + fz * o_index);
 
-            for (i = start; i <= j && i < in_n_frames; i++)
-
+            for (; i < i_end && i < in_n_frames; i++)
                 for (c = 0; c < r->o_ss.channels; c++, s++) {
                     int16_t n;
 
@@ -1483,22 +1478,20 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
                         r->peaks.max_i[c] = n;
                 }
 
-            if (i >= in_n_frames)
-                break;
-
-            for (c = 0; c < r->o_ss.channels; c++, d++) {
-                *d = r->peaks.max_i[c];
-                r->peaks.max_i[c] = 0;
+            if (i == i_end) {
+                for (c = 0; c < r->o_ss.channels; c++, d++) {
+                    *d = r->peaks.max_i[c];
+                    r->peaks.max_i[c] = 0;
+                }
+                o_index++, r->peaks.o_counter++;
             }
-
         } else {
-            unsigned i, c;
-            float *s = (float*) ((uint8_t*) src + fz * start);
+            float *s = (float*) ((uint8_t*) src + fz * i);
             float *d = (float*) ((uint8_t*) dst + fz * o_index);
 
             pa_assert(r->work_format == PA_SAMPLE_FLOAT32NE);
 
-            for (i = start; i <= j && i < in_n_frames; i++)
+            for (; i < i_end && i < in_n_frames; i++)
                 for (c = 0; c < r->o_ss.channels; c++, s++) {
                     float n = fabsf(*s);
 
@@ -1506,16 +1499,14 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
                         r->peaks.max_f[c] = n;
                 }
 
-            if (i >= in_n_frames)
-                break;
-
-            for (c = 0; c < r->o_ss.channels; c++, d++) {
-                *d = r->peaks.max_f[c];
-                r->peaks.max_f[c] = 0;
+            if (i == i_end) {
+                for (c = 0; c < r->o_ss.channels; c++, d++) {
+                    *d = r->peaks.max_f[c];
+                    r->peaks.max_f[c] = 0;
+                }
+                o_index++, r->peaks.o_counter++;
             }
         }
-
-        start = j;
     }
 
     pa_memblock_release(input->memblock);
-- 
1.7.4.1



More information about the pulseaudio-discuss mailing list