[pulseaudio-discuss] [PATCH 2/2] Improve performance of peaks resampler
Maarten Bosmans
mkbosmans at gmail.com
Tue Nov 15 17:04:06 PST 2011
This is mainly achieved by special-casing the common 1ch float case,
which is used by applications such as pavucontrol.
Performance is improved by 35% for a mono 48000->25Hz peaks resampling.
---
src/pulsecore/resampler.c | 37 ++++++++++++++++++++++++++-----------
1 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index cbf5782..dd9c1aa 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -1443,7 +1443,9 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
pa_assert(input);
pa_assert(output);
pa_assert(out_n_frames);
+ pa_assert(r->i_ss.rate >= r->o_ss.rate);
pa_assert(r->i_ss.channels == r->o_ss.channels);
+ pa_assert(r->work_format == PA_SAMPLE_S16NE || r->work_format == PA_SAMPLE_FLOAT32NE);
src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
@@ -1455,19 +1457,34 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
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 * r->w_sz * r->o_ss.channels < pa_memblock_get_length(output->memblock));
+ pa_assert_fp(o_index * r->w_sz * r->o_ss.channels < pa_memblock_get_length(output->memblock));
- if (r->work_format == PA_SAMPLE_S16NE) {
+ /* 1ch float is treated separately, because that is the common case */
+ if (r->o_ss.channels == 1 && r->work_format == PA_SAMPLE_FLOAT32NE) {
+ float *s = (float*) src + i;
+ float *d = (float*) dst + o_index;
+
+ for (; i < i_end && i < in_n_frames; i++) {
+ float n = fabsf(*s++);
+
+ if (n > r->peaks.max_f[0])
+ r->peaks.max_f[0] = n;
+ }
+
+ if (i == i_end) {
+ *d = r->peaks.max_f[0];
+ r->peaks.max_f[0] = 0;
+ o_index++, r->peaks.o_counter++;
+ }
+ } else if (r->work_format == PA_SAMPLE_S16NE) {
int16_t *s = (int16_t*) src + r->i_ss.channels * i;
int16_t *d = (int16_t*) dst + r->o_ss.channels * o_index;
for (; i < i_end && i < in_n_frames; i++)
- for (c = 0; c < r->o_ss.channels; c++, s++) {
- int16_t n;
+ for (c = 0; c < r->o_ss.channels; c++) {
+ int16_t n = abs(*s++);
- n = (int16_t) (*s < 0 ? -*s : *s);
-
- if (PA_UNLIKELY(n > r->peaks.max_i[c]))
+ if (n > r->peaks.max_i[c])
r->peaks.max_i[c] = n;
}
@@ -1482,11 +1499,9 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
float *s = (float*) src + r->i_ss.channels * i;
float *d = (float*) dst + r->o_ss.channels * o_index;
- pa_assert(r->work_format == PA_SAMPLE_FLOAT32NE);
-
for (; i < i_end && i < in_n_frames; i++)
- for (c = 0; c < r->o_ss.channels; c++, s++) {
- float n = fabsf(*s);
+ for (c = 0; c < r->o_ss.channels; c++) {
+ float n = fabsf(*s++);
if (n > r->peaks.max_f[c])
r->peaks.max_f[c] = n;
--
1.7.4.1
More information about the pulseaudio-discuss
mailing list