diff options
author | Max Kellermann <max@duempel.org> | 2015-06-22 14:45:59 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2015-06-22 16:32:06 +0200 |
commit | 69476b4f2193546cb72c3def9679136a182adfe3 (patch) | |
tree | 56010536b8b36071c87583cb5e5817b02c9bdab1 | |
parent | fdf92c5f3b05c874ba6ae74bb0e1477f1b3ca77f (diff) | |
download | mpd-69476b4f2193546cb72c3def9679136a182adfe3.tar.gz mpd-69476b4f2193546cb72c3def9679136a182adfe3.tar.xz mpd-69476b4f2193546cb72c3def9679136a182adfe3.zip |
pcm/Interleave: add optimization for 32 bit samples
Move code from the "vorbis" decoder.
-rw-r--r-- | src/decoder/plugins/VorbisDecoderPlugin.cxx | 10 | ||||
-rw-r--r-- | src/pcm/Interleave.cxx | 33 | ||||
-rw-r--r-- | src/pcm/Interleave.hxx | 20 |
3 files changed, 51 insertions, 12 deletions
diff --git a/src/decoder/plugins/VorbisDecoderPlugin.cxx b/src/decoder/plugins/VorbisDecoderPlugin.cxx index c6377b9ab..d7069a2f4 100644 --- a/src/decoder/plugins/VorbisDecoderPlugin.cxx +++ b/src/decoder/plugins/VorbisDecoderPlugin.cxx @@ -24,6 +24,7 @@ #include "../DecoderAPI.hxx" #include "input/InputStream.hxx" #include "OggCodec.hxx" +#include "pcm/Interleave.hxx" #include "util/Error.hxx" #include "util/Macros.hxx" #include "CheckAudioFormat.hxx" @@ -181,13 +182,8 @@ static void vorbis_interleave(float *dest, const float *const*src, unsigned nframes, unsigned channels) { - for (const float *const*src_end = src + channels; - src != src_end; ++src, ++dest) { - float *gcc_restrict d = dest; - for (const float *gcc_restrict s = *src, *s_end = s + nframes; - s != s_end; ++s, d += channels) - *d = *s; - } + PcmInterleaveFloat(dest, ConstBuffer<const float *>(src, channels), + nframes); } #endif diff --git a/src/pcm/Interleave.cxx b/src/pcm/Interleave.cxx index 14ca53434..8f8f152c5 100644 --- a/src/pcm/Interleave.cxx +++ b/src/pcm/Interleave.cxx @@ -20,7 +20,6 @@ #include "config.h" #include "Interleave.hxx" -#include <stdint.h> #include <string.h> static void @@ -38,12 +37,36 @@ GenericPcmInterleave(uint8_t *gcc_restrict dest, } void +PcmInterleave32(int32_t *gcc_restrict dest, + const ConstBuffer<const int32_t *> src, + size_t n_frames) +{ + for (const auto *s : src) { + auto *d = dest++; + + for (const auto *const s_end = s + n_frames; + s != s_end; ++s, d += src.size) + *d = *s; + } +} + +void PcmInterleave(void *gcc_restrict dest, ConstBuffer<const void *> src, size_t n_frames, size_t sample_size) { - GenericPcmInterleave((uint8_t *)dest, - ConstBuffer<const uint8_t *>((const uint8_t *const*)src.data, - src.size), - n_frames, sample_size); + switch (sample_size) { + case 4: + PcmInterleave32((int32_t *)dest, + ConstBuffer<const int32_t *>((const int32_t *const*)src.data, + src.size), + n_frames); + break; + + default: + GenericPcmInterleave((uint8_t *)dest, + ConstBuffer<const uint8_t *>((const uint8_t *const*)src.data, + src.size), + n_frames, sample_size); + } } diff --git a/src/pcm/Interleave.hxx b/src/pcm/Interleave.hxx index 76f1a6216..3cb117d80 100644 --- a/src/pcm/Interleave.hxx +++ b/src/pcm/Interleave.hxx @@ -24,6 +24,8 @@ #include "Compiler.h" #include "util/ConstBuffer.hxx" +#include <stdint.h> + /** * Interleave planar PCM samples from #src to #dest. */ @@ -31,4 +33,22 @@ void PcmInterleave(void *gcc_restrict dest, ConstBuffer<const void *> src, size_t n_frames, size_t sample_size); +/** + * A variant of PcmInterleave() that assumes 32 bit samples (4 bytes + * per sample). + */ +void +PcmInterleave32(int32_t *gcc_restrict dest, ConstBuffer<const int32_t *> src, + size_t n_frames); + +static inline void +PcmInterleaveFloat(float *gcc_restrict dest, ConstBuffer<const float *> src, + size_t n_frames) +{ + PcmInterleave32((int32_t *)dest, + ConstBuffer<const int32_t *>((const int32_t *const*)src.data, + src.size), + n_frames); +} + #endif |