aboutsummaryrefslogtreecommitdiffstats
path: root/src/pcm
diff options
context:
space:
mode:
Diffstat (limited to 'src/pcm')
-rw-r--r--src/pcm/PcmResample.cxx23
-rw-r--r--src/pcm/PcmResample.hxx8
-rw-r--r--src/pcm/PcmResampleInternal.hxx9
-rw-r--r--src/pcm/PcmResampleLibsamplerate.cxx25
-rw-r--r--src/pcm/PcmUtils.hxx12
5 files changed, 70 insertions, 7 deletions
diff --git a/src/pcm/PcmResample.cxx b/src/pcm/PcmResample.cxx
index 318181e15..b30e01407 100644
--- a/src/pcm/PcmResample.cxx
+++ b/src/pcm/PcmResample.cxx
@@ -148,3 +148,26 @@ 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)
+{
+#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 pcm_resample_fallback_32(buffer, channels,
+ src_rate, src_buffer, src_size,
+ dest_rate, dest_size_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
diff --git a/src/pcm/PcmResampleInternal.hxx b/src/pcm/PcmResampleInternal.hxx
index 4219b22ed..94cef94ff 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<int32_t, int32_t, 24>(const_cast<int32_t *>(result),
+ result,
+ *dest_size_r / sizeof(*result));
+
+ return result;
+}
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<typename T, typename U, unsigned bits>
+static inline void
+PcmClampN(T *dest, const U *src, unsigned n)
+{
+ while (n-- > 0)
+ *dest++ = PcmClamp<T, U, bits>(*src++);
+}
+
#endif