summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-12-02 09:36:56 +0100
committerMax Kellermann <max@duempel.org>2013-12-02 11:28:54 +0100
commit71b47ae3efc1c683c07ea6d682b0b7d876f35457 (patch)
tree0f5c1e30bff743cc6151fe1188b1e2af704dffb8
parent36e3fda554921ef4024cfb6c61f0ba981b7c963c (diff)
pcm/PcmChannels: use the SampleTraits library
-rw-r--r--src/pcm/PcmChannels.cxx242
1 files changed, 60 insertions, 182 deletions
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 <assert.h>
@@ -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<SampleFormat F, class Traits=SampleTraits<F>>
+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<SampleFormat F, class Traits=SampleTraits<F>>
+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<F, Traits>(a, b);
+ }
+
+ return dest;
+}
- while (src < src_end) {
- int32_t sum = 0;
- int16_t value;
+template<SampleFormat F, class Traits=SampleTraits<F>>
+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<int16_t>
-pcm_convert_channels_16(PcmBuffer &buffer,
- unsigned dest_channels,
- unsigned src_channels,
- ConstBuffer<int16_t> src)
+template<SampleFormat F, class Traits=SampleTraits<F>>
+static ConstBuffer<typename Traits::value_type>
+ConvertChannels(PcmBuffer &buffer,
+ unsigned dest_channels,
+ unsigned src_channels,
+ ConstBuffer<typename Traits::value_type> src)
{
assert(src.size % src_channels == 0);
const size_t dest_size = src.size / src_channels * dest_channels;
- int16_t *dest = buffer.GetT<int16_t>(dest_size);
+ auto dest = buffer.GetT<typename Traits::value_type>(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<F>(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<F>(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<int16_t>
+pcm_convert_channels_16(PcmBuffer &buffer,
+ unsigned dest_channels,
+ unsigned src_channels,
+ ConstBuffer<int16_t> 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<SampleFormat::S16>(buffer, dest_channels,
+ src_channels, src);
}
ConstBuffer<int32_t>
@@ -139,57 +130,8 @@ pcm_convert_channels_24(PcmBuffer &buffer,
unsigned src_channels,
ConstBuffer<int32_t> src)
{
- assert(src.size % src_channels == 0);
-
- size_t dest_size = src.size / src_channels * dest_channels;
- int32_t *dest = buffer.GetT<int32_t>(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<SampleFormat::S24_P32>(buffer, dest_channels,
+ src_channels, src);
}
ConstBuffer<int32_t>
@@ -198,57 +140,8 @@ pcm_convert_channels_32(PcmBuffer &buffer,
unsigned src_channels,
ConstBuffer<int32_t> src)
{
- assert(src.size % src_channels == 0);
-
- size_t dest_size = src.size / src_channels * dest_channels;
- int32_t *dest = buffer.GetT<int32_t>(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<SampleFormat::S32>(buffer, dest_channels,
+ src_channels, src);
}
ConstBuffer<float>
@@ -257,21 +150,6 @@ pcm_convert_channels_float(PcmBuffer &buffer,
unsigned src_channels,
ConstBuffer<float> src)
{
- assert(src.size % src_channels == 0);
-
- size_t dest_size = src.size / src_channels * dest_channels;
- float *dest = buffer.GetT<float>(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<SampleFormat::FLOAT>(buffer, dest_channels,
+ src_channels, src);
}