diff options
author | Max Kellermann <max@duempel.org> | 2013-12-02 11:42:19 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2013-12-02 11:42:19 +0100 |
commit | cee1ac150e4176e5485d54a546391be53a6da823 (patch) | |
tree | b20ac0edfafee666c3d304ad9ab38be16c11ffd5 /src/pcm | |
parent | 71b47ae3efc1c683c07ea6d682b0b7d876f35457 (diff) | |
download | mpd-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.cxx | 28 |
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 }; } |