Commit 12e9b7ea authored by Max Kellermann's avatar Max Kellermann

PcmFormat: move definitions to struct SampleTraits

parent de1261ba
...@@ -25,12 +25,47 @@ ...@@ -25,12 +25,47 @@
#include <type_traits> #include <type_traits>
template<typename S> template<SampleFormat F>
struct DefaultSampleBits { struct SampleTraits {};
typedef decltype(*S()) T;
typedef typename std::remove_reference<T>::type U;
static constexpr auto value = sizeof(U) * 8; template<>
struct SampleTraits<SampleFormat::S8> {
typedef int8_t value_type;
typedef value_type *pointer_type;
typedef const value_type *const_pointer_type;
static constexpr size_t SAMPLE_SIZE = sizeof(value_type);
static constexpr unsigned BITS = sizeof(value_type) * 8;
};
template<>
struct SampleTraits<SampleFormat::S16> {
typedef int16_t value_type;
typedef value_type *pointer_type;
typedef const value_type *const_pointer_type;
static constexpr size_t SAMPLE_SIZE = sizeof(value_type);
static constexpr unsigned BITS = sizeof(value_type) * 8;
};
template<>
struct SampleTraits<SampleFormat::S32> {
typedef int32_t value_type;
typedef value_type *pointer_type;
typedef const value_type *const_pointer_type;
static constexpr size_t SAMPLE_SIZE = sizeof(value_type);
static constexpr unsigned BITS = sizeof(value_type) * 8;
};
template<>
struct SampleTraits<SampleFormat::S24_P32> {
typedef int32_t value_type;
typedef value_type *pointer_type;
typedef const value_type *const_pointer_type;
static constexpr size_t SAMPLE_SIZE = sizeof(value_type);
static constexpr unsigned BITS = 24;
}; };
static void static void
...@@ -55,30 +90,32 @@ pcm_convert_32_to_16(PcmDither &dither, ...@@ -55,30 +90,32 @@ pcm_convert_32_to_16(PcmDither &dither,
dither.Dither32To16(out, in, in_end); dither.Dither32To16(out, in, in_end);
} }
template<typename S, unsigned bits=DefaultSampleBits<S>::value> template<SampleFormat F, class Traits=SampleTraits<F>>
static void static void
ConvertFromFloat(S dest, const float *src, const float *end) ConvertFromFloat(typename Traits::pointer_type dest,
const float *src, const float *end)
{ {
typedef decltype(*S()) T; constexpr auto bits = Traits::BITS;
typedef typename std::remove_reference<T>::type U;
const float factor = 1 << (bits - 1); const float factor = 1 << (bits - 1);
while (src != end) { while (src != end) {
int sample(*src++ * factor); int sample(*src++ * factor);
*dest++ = PcmClamp<U, int, bits>(sample); *dest++ = PcmClamp<typename Traits::value_type, int, bits>(sample);
} }
} }
template<typename S, unsigned bits=DefaultSampleBits<S>::value> template<SampleFormat F, class Traits=SampleTraits<F>>
static void static void
ConvertFromFloat(S dest, const float *src, size_t size) ConvertFromFloat(typename Traits::pointer_type dest,
const float *src, size_t size)
{ {
ConvertFromFloat<S, bits>(dest, src, pcm_end_pointer(src, size)); ConvertFromFloat<F, Traits>(dest, src,
pcm_end_pointer(src, size));
} }
template<typename S, unsigned bits=sizeof(S)*8> template<SampleFormat F, class Traits=SampleTraits<F>>
static S * static typename Traits::pointer_type
AllocateFromFloat(PcmBuffer &buffer, const float *src, size_t src_size, AllocateFromFloat(PcmBuffer &buffer, const float *src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
...@@ -86,9 +123,9 @@ AllocateFromFloat(PcmBuffer &buffer, const float *src, size_t src_size, ...@@ -86,9 +123,9 @@ AllocateFromFloat(PcmBuffer &buffer, const float *src, size_t src_size,
assert(src_size % src_sample_size == 0); assert(src_size % src_sample_size == 0);
const size_t num_samples = src_size / src_sample_size; const size_t num_samples = src_size / src_sample_size;
*dest_size_r = num_samples * sizeof(S); *dest_size_r = num_samples * sizeof(typename Traits::value_type);
S *dest = (S *)buffer.Get(*dest_size_r); auto dest = (typename Traits::pointer_type)buffer.Get(*dest_size_r);
ConvertFromFloat<S *, bits>(dest, src, src_size); ConvertFromFloat<F, Traits>(dest, src, src_size);
return dest; return dest;
} }
...@@ -136,7 +173,8 @@ pcm_allocate_float_to_16(PcmBuffer &buffer, ...@@ -136,7 +173,8 @@ pcm_allocate_float_to_16(PcmBuffer &buffer,
const float *src, size_t src_size, const float *src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
return AllocateFromFloat<int16_t>(buffer, src, src_size, dest_size_r); return AllocateFromFloat<SampleFormat::S16>(buffer, src, src_size,
dest_size_r);
} }
const int16_t * const int16_t *
...@@ -240,8 +278,8 @@ pcm_allocate_float_to_24(PcmBuffer &buffer, ...@@ -240,8 +278,8 @@ pcm_allocate_float_to_24(PcmBuffer &buffer,
const float *src, size_t src_size, const float *src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
return AllocateFromFloat<int32_t, 24>(buffer, src, src_size, return AllocateFromFloat<SampleFormat::S24_P32>(buffer, src, src_size,
dest_size_r); dest_size_r);
} }
const int32_t * const int32_t *
...@@ -395,35 +433,39 @@ pcm_convert_to_32(PcmBuffer &buffer, ...@@ -395,35 +433,39 @@ pcm_convert_to_32(PcmBuffer &buffer,
return NULL; return NULL;
} }
template<typename S, unsigned bits=DefaultSampleBits<S>::value> template<SampleFormat F, class Traits=SampleTraits<F>>
static void static void
ConvertToFloat(float *dest, S src, S end) ConvertToFloat(float *dest,
typename Traits::const_pointer_type src,
typename Traits::const_pointer_type end)
{ {
constexpr float factor = 0.5 / (1 << (bits - 2)); constexpr float factor = 0.5 / (1 << (Traits::BITS - 2));
while (src != end) while (src != end)
*dest++ = float(*src++) * factor; *dest++ = float(*src++) * factor;
} }
template<typename S, unsigned bits=DefaultSampleBits<S>::value> template<SampleFormat F, class Traits=SampleTraits<F>>
static void static void
ConvertToFloat(float *dest, S src, size_t size) ConvertToFloat(float *dest,
typename Traits::const_pointer_type src, size_t size)
{ {
ConvertToFloat<S, bits>(dest, src, pcm_end_pointer(src, size)); ConvertToFloat<F, Traits>(dest, src, pcm_end_pointer(src, size));
} }
template<typename S, unsigned bits=DefaultSampleBits<S>::value> template<SampleFormat F, class Traits=SampleTraits<F>>
static float * static float *
AllocateToFloat(PcmBuffer &buffer, S src, size_t src_size, AllocateToFloat(PcmBuffer &buffer,
typename Traits::const_pointer_type src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
constexpr size_t src_sample_size = sizeof(*S()); constexpr size_t src_sample_size = Traits::SAMPLE_SIZE;
assert(src_size % src_sample_size == 0); assert(src_size % src_sample_size == 0);
const size_t num_samples = src_size / src_sample_size; const size_t num_samples = src_size / src_sample_size;
*dest_size_r = num_samples * sizeof(float); *dest_size_r = num_samples * sizeof(float);
float *dest = (float *)buffer.Get(*dest_size_r); float *dest = (float *)buffer.Get(*dest_size_r);
ConvertToFloat<S, bits>(dest, src, src_size); ConvertToFloat<F, Traits>(dest, src, src_size);
return dest; return dest;
} }
...@@ -432,7 +474,8 @@ pcm_allocate_8_to_float(PcmBuffer &buffer, ...@@ -432,7 +474,8 @@ pcm_allocate_8_to_float(PcmBuffer &buffer,
const int8_t *src, size_t src_size, const int8_t *src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
return AllocateToFloat(buffer, src, src_size, dest_size_r); return AllocateToFloat<SampleFormat::S8>(buffer, src, src_size,
dest_size_r);
} }
static float * static float *
...@@ -440,7 +483,8 @@ pcm_allocate_16_to_float(PcmBuffer &buffer, ...@@ -440,7 +483,8 @@ pcm_allocate_16_to_float(PcmBuffer &buffer,
const int16_t *src, size_t src_size, const int16_t *src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
return AllocateToFloat(buffer, src, src_size, dest_size_r); return AllocateToFloat<SampleFormat::S16>(buffer, src, src_size,
dest_size_r);
} }
static float * static float *
...@@ -448,8 +492,8 @@ pcm_allocate_24p32_to_float(PcmBuffer &buffer, ...@@ -448,8 +492,8 @@ pcm_allocate_24p32_to_float(PcmBuffer &buffer,
const int32_t *src, size_t src_size, const int32_t *src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
return AllocateToFloat<decltype(src), 24> return AllocateToFloat<SampleFormat::S24_P32>(buffer, src, src_size,
(buffer, src, src_size, dest_size_r); dest_size_r);
} }
static float * static float *
...@@ -457,7 +501,8 @@ pcm_allocate_32_to_float(PcmBuffer &buffer, ...@@ -457,7 +501,8 @@ pcm_allocate_32_to_float(PcmBuffer &buffer,
const int32_t *src, size_t src_size, const int32_t *src, size_t src_size,
size_t *dest_size_r) size_t *dest_size_r)
{ {
return AllocateToFloat(buffer, src, src_size, dest_size_r); return AllocateToFloat<SampleFormat::S32>(buffer, src, src_size,
dest_size_r);
} }
const float * const float *
......
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