Commit fc7d5b05 authored by Max Kellermann's avatar Max Kellermann

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.
parent 87c8953e
...@@ -7,6 +7,7 @@ ver 0.18.5 (20??/??/??) ...@@ -7,6 +7,7 @@ ver 0.18.5 (20??/??/??)
- proxy: provide "db_update" in "stats" response - proxy: provide "db_update" in "stats" response
* decoder * decoder
- fluidsynth: auto-detect by default - fluidsynth: auto-detect by default
* clip 24 bit data from libsamplerate
* fix ia64, mipsel and other little-endian architectures * fix ia64, mipsel and other little-endian architectures
* fix build failures due to missing includes * fix build failures due to missing includes
* fix build failure with static libmpdclient * fix build failure with static libmpdclient
......
...@@ -155,8 +155,19 @@ PcmResampler::Resample24(unsigned channels, unsigned src_rate, ...@@ -155,8 +155,19 @@ PcmResampler::Resample24(unsigned channels, unsigned src_rate,
unsigned dest_rate, size_t *dest_size_r, unsigned dest_rate, size_t *dest_size_r,
Error &error_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 /* reuse the 32 bit code - the resampler code doesn't care if
the upper 8 bits are actually used */ the upper 8 bits are actually used */
return Resample32(channels, src_rate, src_buffer, src_size, return pcm_resample_fallback_32(this, channels,
dest_rate, dest_size_r, error_r); src_rate, src_buffer, src_size,
dest_rate, dest_size_r);
} }
...@@ -69,6 +69,15 @@ pcm_resample_lsr_32(PcmResampler *state, ...@@ -69,6 +69,15 @@ pcm_resample_lsr_32(PcmResampler *state,
unsigned dest_rate, size_t *dest_size_r, unsigned dest_rate, size_t *dest_size_r,
Error &error); 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 #endif
const int16_t * const int16_t *
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "PcmResampleInternal.hxx" #include "PcmResampleInternal.hxx"
#include "PcmUtils.hxx"
#include "util/ASCII.hxx" #include "util/ASCII.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
...@@ -283,3 +284,27 @@ pcm_resample_lsr_32(PcmResampler *state, ...@@ -283,3 +284,27 @@ pcm_resample_lsr_32(PcmResampler *state,
return dest_buffer; 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment