From 45d27a52f17be05f5269d7dc37f380ed595196e7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 22 Nov 2013 23:00:39 +0100 Subject: PcmUtils: add function PcmClampN() --- src/pcm/PcmUtils.hxx | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/pcm') diff --git a/src/pcm/PcmUtils.hxx b/src/pcm/PcmUtils.hxx index 108ba85ae..febe12d7b 100644 --- a/src/pcm/PcmUtils.hxx +++ b/src/pcm/PcmUtils.hxx @@ -63,4 +63,16 @@ PcmClamp(U x) return T(x); } +/** + * Check if the values in this buffer are within the range of the + * provided bit size, and clamps them whenever necessary. + */ +template +static inline void +PcmClampN(T *dest, const U *src, unsigned n) +{ + while (n-- > 0) + *dest++ = PcmClamp(*src++); +} + #endif -- cgit v1.2.3 From 87c8953e8ed660b59ea2452b4d3a431785c47495 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 22 Nov 2013 22:50:43 +0100 Subject: PcmResample: un-inline Resample24() --- src/pcm/PcmResample.cxx | 12 ++++++++++++ src/pcm/PcmResample.hxx | 8 +------- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src/pcm') diff --git a/src/pcm/PcmResample.cxx b/src/pcm/PcmResample.cxx index e2ce095d1..df37826ba 100644 --- a/src/pcm/PcmResample.cxx +++ b/src/pcm/PcmResample.cxx @@ -148,3 +148,15 @@ PcmResampler::Resample32(unsigned channels, unsigned src_rate, src_rate, src_buffer, src_size, dest_rate, dest_size_r); } + +const int32_t * +PcmResampler::Resample24(unsigned channels, unsigned src_rate, + const int32_t *src_buffer, size_t src_size, + unsigned dest_rate, size_t *dest_size_r, + Error &error_r) +{ + /* reuse the 32 bit code - the resampler code doesn't care if + the upper 8 bits are actually used */ + return Resample32(channels, src_rate, src_buffer, src_size, + dest_rate, dest_size_r, error_r); +} diff --git a/src/pcm/PcmResample.hxx b/src/pcm/PcmResample.hxx index 8a740744a..e839d6ecd 100644 --- a/src/pcm/PcmResample.hxx +++ b/src/pcm/PcmResample.hxx @@ -124,13 +124,7 @@ struct PcmResampler { const int32_t *Resample24(unsigned channels, unsigned src_rate, const int32_t *src_buffer, size_t src_size, unsigned dest_rate, size_t *dest_size_r, - Error &error_r) - { - /* reuse the 32 bit code - the resampler code doesn't care if - the upper 8 bits are actually used */ - return Resample32(channels, src_rate, src_buffer, src_size, - dest_rate, dest_size_r, error_r); - } + Error &error_r); }; bool -- cgit v1.2.3 From fc7d5b055d98306af0c882282902a23e963f026d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 22 Nov 2013 22:50:29 +0100 Subject: PcmResampleLibsamplerate: clip 24 bit data Using pcm_resample_lsr_32() for 24 bit samples works, but may cause 24 bit overflows. This commit makes 24 bit a special case with explicit clipping. --- src/pcm/PcmResample.cxx | 15 +++++++++++++-- src/pcm/PcmResampleInternal.hxx | 9 +++++++++ src/pcm/PcmResampleLibsamplerate.cxx | 25 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) (limited to 'src/pcm') diff --git a/src/pcm/PcmResample.cxx b/src/pcm/PcmResample.cxx index df37826ba..01f269ea9 100644 --- a/src/pcm/PcmResample.cxx +++ b/src/pcm/PcmResample.cxx @@ -155,8 +155,19 @@ PcmResampler::Resample24(unsigned channels, unsigned src_rate, unsigned dest_rate, size_t *dest_size_r, Error &error_r) { +#ifdef HAVE_LIBSAMPLERATE + if (pcm_resample_lsr_enabled()) + return pcm_resample_lsr_24(this, channels, + src_rate, src_buffer, src_size, + dest_rate, dest_size_r, + error_r); +#else + (void)error_r; +#endif + /* reuse the 32 bit code - the resampler code doesn't care if the upper 8 bits are actually used */ - return Resample32(channels, src_rate, src_buffer, src_size, - dest_rate, dest_size_r, error_r); + return pcm_resample_fallback_32(this, channels, + src_rate, src_buffer, src_size, + dest_rate, dest_size_r); } diff --git a/src/pcm/PcmResampleInternal.hxx b/src/pcm/PcmResampleInternal.hxx index 59bb2f5df..5090c13d1 100644 --- a/src/pcm/PcmResampleInternal.hxx +++ b/src/pcm/PcmResampleInternal.hxx @@ -69,6 +69,15 @@ pcm_resample_lsr_32(PcmResampler *state, unsigned dest_rate, size_t *dest_size_r, Error &error); +const int32_t * +pcm_resample_lsr_24(PcmResampler *state, + unsigned channels, + unsigned src_rate, + const int32_t *src_buffer, + size_t src_size, + unsigned dest_rate, size_t *dest_size_r, + Error &error); + #endif const int16_t * diff --git a/src/pcm/PcmResampleLibsamplerate.cxx b/src/pcm/PcmResampleLibsamplerate.cxx index 1986e8821..9eac2d545 100644 --- a/src/pcm/PcmResampleLibsamplerate.cxx +++ b/src/pcm/PcmResampleLibsamplerate.cxx @@ -19,6 +19,7 @@ #include "config.h" #include "PcmResampleInternal.hxx" +#include "PcmUtils.hxx" #include "util/ASCII.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -283,3 +284,27 @@ pcm_resample_lsr_32(PcmResampler *state, return dest_buffer; } + +const int32_t * +pcm_resample_lsr_24(PcmResampler *state, + unsigned channels, + unsigned src_rate, + const int32_t *src_buffer, size_t src_size, + unsigned dest_rate, size_t *dest_size_r, + Error &error) +{ + const auto result = pcm_resample_lsr_32(state, channels, + src_rate, src_buffer, src_size, + dest_rate, dest_size_r, + error); + if (result != nullptr) + /* src_float_to_int_array() clamps for 32 bit + integers; now make sure everything's fine for 24 + bit */ + /* TODO: eliminate the 32 bit clamp to reduce overhead */ + PcmClampN(const_cast(result), + result, + *dest_size_r / sizeof(*result)); + + return result; +} -- cgit v1.2.3