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