aboutsummaryrefslogtreecommitdiffstats
path: root/src/pcm
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-12-02 11:42:19 +0100
committerMax Kellermann <max@duempel.org>2013-12-02 11:42:19 +0100
commitcee1ac150e4176e5485d54a546391be53a6da823 (patch)
treeb20ac0edfafee666c3d304ad9ab38be16c11ffd5 /src/pcm
parent71b47ae3efc1c683c07ea6d682b0b7d876f35457 (diff)
downloadmpd-cee1ac150e4176e5485d54a546391be53a6da823.tar.gz
mpd-cee1ac150e4176e5485d54a546391be53a6da823.tar.xz
mpd-cee1ac150e4176e5485d54a546391be53a6da823.zip
pcm/PcmChannels: implement fake N-to-M mapping
This is really just a mono mapper, but the important part is that this library cannot fail anymore.
Diffstat (limited to 'src/pcm')
-rw-r--r--src/pcm/PcmChannels.cxx28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/pcm/PcmChannels.cxx b/src/pcm/PcmChannels.cxx
index 8f00c01be..b90e48580 100644
--- a/src/pcm/PcmChannels.cxx
+++ b/src/pcm/PcmChannels.cxx
@@ -91,6 +91,31 @@ NToStereo(typename Traits::pointer_type dest,
}
template<SampleFormat F, class Traits=SampleTraits<F>>
+static typename Traits::pointer_type
+NToM(typename Traits::pointer_type dest,
+ unsigned dest_channels,
+ unsigned src_channels,
+ typename Traits::const_pointer_type src,
+ typename Traits::const_pointer_type end)
+{
+ assert((end - src) % src_channels == 0);
+
+ while (src != end) {
+ typename Traits::long_type sum = *src++;
+ for (unsigned c = 1; c < src_channels; ++c)
+ sum += *src++;
+
+ typename Traits::value_type value(sum / int(src_channels));
+
+ /* TODO: this is actually only mono ... */
+ for (unsigned c = 0; c < dest_channels; ++c)
+ *dest++ = value;
+ }
+
+ return dest;
+}
+
+template<SampleFormat F, class Traits=SampleTraits<F>>
static ConstBuffer<typename Traits::value_type>
ConvertChannels(PcmBuffer &buffer,
unsigned dest_channels,
@@ -109,7 +134,8 @@ ConvertChannels(PcmBuffer &buffer,
else if (dest_channels == 2)
NToStereo<F>(dest, src_channels, src.begin(), src.end());
else
- return nullptr;
+ NToM<F>(dest, dest_channels,
+ src_channels, src.begin(), src.end());
return { dest, dest_size };
}