From 71b47ae3efc1c683c07ea6d682b0b7d876f35457 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 2 Dec 2013 09:36:56 +0100 Subject: pcm/PcmChannels: use the SampleTraits library --- src/pcm/PcmChannels.cxx | 242 ++++++++++++------------------------------------ 1 file changed, 60 insertions(+), 182 deletions(-) (limited to 'src/pcm') diff --git a/src/pcm/PcmChannels.cxx b/src/pcm/PcmChannels.cxx index 74f9416f9..8f00c01be 100644 --- a/src/pcm/PcmChannels.cxx +++ b/src/pcm/PcmChannels.cxx @@ -20,6 +20,8 @@ #include "config.h" #include "PcmChannels.hxx" #include "PcmBuffer.hxx" +#include "Traits.hxx" +#include "AudioFormat.hxx" #include "util/ConstBuffer.hxx" #include @@ -37,100 +39,89 @@ MonoToStereo(D dest, S src, S end) } -static void -pcm_convert_channels_16_2_to_1(int16_t *gcc_restrict dest, - const int16_t *gcc_restrict src, - const int16_t *gcc_restrict src_end) +template> +static typename Traits::value_type +StereoToMono(typename Traits::value_type _a, + typename Traits::value_type _b) { - while (src < src_end) { - int32_t a = *src++, b = *src++; + typename Traits::long_type a(_a); + typename Traits::long_type b(_b); - *dest++ = (a + b) / 2; - } + return typename Traits::value_type((a + b) / 2); } -static void -pcm_convert_channels_16_n_to_2(int16_t *gcc_restrict dest, - unsigned src_channels, - const int16_t *gcc_restrict src, - const int16_t *gcc_restrict src_end) +template> +static typename Traits::pointer_type +StereoToMono(typename Traits::pointer_type dest, + typename Traits::const_pointer_type src, + typename Traits::const_pointer_type end) { - unsigned c; + while (src != end) { + const auto a = *src++; + const auto b = *src++; - assert(src_channels > 0); + *dest++ = StereoToMono(a, b); + } + + return dest; +} - while (src < src_end) { - int32_t sum = 0; - int16_t value; +template> +static typename Traits::pointer_type +NToStereo(typename Traits::pointer_type dest, + unsigned src_channels, + typename Traits::const_pointer_type src, + typename Traits::const_pointer_type end) +{ + assert((end - src) % src_channels == 0); - for (c = 0; c < src_channels; ++c) + while (src != end) { + typename Traits::long_type sum = *src++; + for (unsigned c = 1; c < src_channels; ++c) sum += *src++; - value = sum / (int)src_channels; - /* XXX this is actually only mono ... */ + typename Traits::value_type value(sum / int(src_channels)); + + /* TODO: this is actually only mono ... */ *dest++ = value; *dest++ = value; } + + return dest; } -ConstBuffer -pcm_convert_channels_16(PcmBuffer &buffer, - unsigned dest_channels, - unsigned src_channels, - ConstBuffer src) +template> +static ConstBuffer +ConvertChannels(PcmBuffer &buffer, + unsigned dest_channels, + unsigned src_channels, + ConstBuffer src) { assert(src.size % src_channels == 0); const size_t dest_size = src.size / src_channels * dest_channels; - int16_t *dest = buffer.GetT(dest_size); + auto dest = buffer.GetT(dest_size); if (src_channels == 1 && dest_channels == 2) MonoToStereo(dest, src.begin(), src.end()); else if (src_channels == 2 && dest_channels == 1) - pcm_convert_channels_16_2_to_1(dest, src.begin(), src.end()); + StereoToMono(dest, src.begin(), src.end()); else if (dest_channels == 2) - pcm_convert_channels_16_n_to_2(dest, src_channels, - src.begin(), src.end()); + NToStereo(dest, src_channels, src.begin(), src.end()); else return nullptr; return { dest, dest_size }; } -static void -pcm_convert_channels_24_2_to_1(int32_t *gcc_restrict dest, - const int32_t *gcc_restrict src, - const int32_t *gcc_restrict src_end) -{ - while (src < src_end) { - int32_t a = *src++, b = *src++; - - *dest++ = (a + b) / 2; - } -} - -static void -pcm_convert_channels_24_n_to_2(int32_t *gcc_restrict dest, - unsigned src_channels, - const int32_t *gcc_restrict src, - const int32_t *gcc_restrict src_end) +ConstBuffer +pcm_convert_channels_16(PcmBuffer &buffer, + unsigned dest_channels, + unsigned src_channels, + ConstBuffer src) { - unsigned c; - - assert(src_channels > 0); - - while (src < src_end) { - int32_t sum = 0; - int32_t value; - - for (c = 0; c < src_channels; ++c) - sum += *src++; - value = sum / (int)src_channels; - - /* XXX this is actually only mono ... */ - *dest++ = value; - *dest++ = value; - } + return ConvertChannels(buffer, dest_channels, + src_channels, src); } ConstBuffer @@ -139,57 +130,8 @@ pcm_convert_channels_24(PcmBuffer &buffer, unsigned src_channels, ConstBuffer src) { - assert(src.size % src_channels == 0); - - size_t dest_size = src.size / src_channels * dest_channels; - int32_t *dest = buffer.GetT(dest_size); - - if (src_channels == 1 && dest_channels == 2) - MonoToStereo(dest, src.begin(), src.end()); - else if (src_channels == 2 && dest_channels == 1) - pcm_convert_channels_24_2_to_1(dest, src.begin(), src.end()); - else if (dest_channels == 2) - pcm_convert_channels_24_n_to_2(dest, src_channels, - src.begin(), src.end()); - else - return nullptr; - - return { dest, dest_size }; -} - -static void -pcm_convert_channels_32_2_to_1(int32_t *gcc_restrict dest, - const int32_t *gcc_restrict src, - const int32_t *gcc_restrict src_end) -{ - while (src < src_end) { - int64_t a = *src++, b = *src++; - - *dest++ = (a + b) / 2; - } -} - -static void -pcm_convert_channels_32_n_to_2(int32_t *dest, - unsigned src_channels, const int32_t *src, - const int32_t *src_end) -{ - unsigned c; - - assert(src_channels > 0); - - while (src < src_end) { - int64_t sum = 0; - int32_t value; - - for (c = 0; c < src_channels; ++c) - sum += *src++; - value = sum / (int64_t)src_channels; - - /* XXX this is actually only mono ... */ - *dest++ = value; - *dest++ = value; - } + return ConvertChannels(buffer, dest_channels, + src_channels, src); } ConstBuffer @@ -198,57 +140,8 @@ pcm_convert_channels_32(PcmBuffer &buffer, unsigned src_channels, ConstBuffer src) { - assert(src.size % src_channels == 0); - - size_t dest_size = src.size / src_channels * dest_channels; - int32_t *dest = buffer.GetT(dest_size); - - if (src_channels == 1 && dest_channels == 2) - MonoToStereo(dest, src.begin(), src.end()); - else if (src_channels == 2 && dest_channels == 1) - pcm_convert_channels_32_2_to_1(dest, src.begin(), src.end()); - else if (dest_channels == 2) - pcm_convert_channels_32_n_to_2(dest, src_channels, - src.begin(), src.end()); - else - return nullptr; - - return { dest, dest_size }; -} - -static void -pcm_convert_channels_float_2_to_1(float *gcc_restrict dest, - const float *gcc_restrict src, - const float *gcc_restrict src_end) -{ - while (src < src_end) { - double a = *src++, b = *src++; - - *dest++ = (a + b) / 2; - } -} - -static void -pcm_convert_channels_float_n_to_2(float *dest, - unsigned src_channels, const float *src, - const float *src_end) -{ - unsigned c; - - assert(src_channels > 0); - - while (src < src_end) { - double sum = 0; - float value; - - for (c = 0; c < src_channels; ++c) - sum += *src++; - value = sum / (double)src_channels; - - /* XXX this is actually only mono ... */ - *dest++ = value; - *dest++ = value; - } + return ConvertChannels(buffer, dest_channels, + src_channels, src); } ConstBuffer @@ -257,21 +150,6 @@ pcm_convert_channels_float(PcmBuffer &buffer, unsigned src_channels, ConstBuffer src) { - assert(src.size % src_channels == 0); - - size_t dest_size = src.size / src_channels * dest_channels; - float *dest = buffer.GetT(dest_size); - - if (src_channels == 1 && dest_channels == 2) - MonoToStereo(dest, src.begin(), src.end()); - else if (src_channels == 2 && dest_channels == 1) - pcm_convert_channels_float_2_to_1(dest, - src.begin(), src.end()); - else if (dest_channels == 2) - pcm_convert_channels_float_n_to_2(dest, src_channels, - src.begin(), src.end()); - else - return nullptr; - - return { dest, dest_size }; + return ConvertChannels(buffer, dest_channels, + src_channels, src); } -- cgit v1.2.3