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.
This commit is contained in:
Max Kellermann 2013-11-22 22:50:29 +01:00
parent 87c8953e8e
commit fc7d5b055d
4 changed files with 48 additions and 2 deletions

1
NEWS
View File

@ -7,6 +7,7 @@ ver 0.18.5 (20??/??/??)
- proxy: provide "db_update" in "stats" response
* decoder
- fluidsynth: auto-detect by default
* clip 24 bit data from libsamplerate
* fix ia64, mipsel and other little-endian architectures
* fix build failures due to missing includes
* fix build failure with static libmpdclient

View File

@ -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);
}

View File

@ -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 *

View File

@ -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;
}