pcm/Interleave: add optimization for 32 bit samples

Move code from the "vorbis" decoder.
This commit is contained in:
Max Kellermann 2015-06-22 14:45:59 +02:00
parent fdf92c5f3b
commit 69476b4f21
3 changed files with 51 additions and 12 deletions

View File

@ -24,6 +24,7 @@
#include "../DecoderAPI.hxx" #include "../DecoderAPI.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "OggCodec.hxx" #include "OggCodec.hxx"
#include "pcm/Interleave.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Macros.hxx" #include "util/Macros.hxx"
#include "CheckAudioFormat.hxx" #include "CheckAudioFormat.hxx"
@ -181,13 +182,8 @@ static void
vorbis_interleave(float *dest, const float *const*src, vorbis_interleave(float *dest, const float *const*src,
unsigned nframes, unsigned channels) unsigned nframes, unsigned channels)
{ {
for (const float *const*src_end = src + channels; PcmInterleaveFloat(dest, ConstBuffer<const float *>(src, channels),
src != src_end; ++src, ++dest) { nframes);
float *gcc_restrict d = dest;
for (const float *gcc_restrict s = *src, *s_end = s + nframes;
s != s_end; ++s, d += channels)
*d = *s;
}
} }
#endif #endif

View File

@ -20,7 +20,6 @@
#include "config.h" #include "config.h"
#include "Interleave.hxx" #include "Interleave.hxx"
#include <stdint.h>
#include <string.h> #include <string.h>
static void static void
@ -37,13 +36,37 @@ 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 void
PcmInterleave(void *gcc_restrict dest, PcmInterleave(void *gcc_restrict dest,
ConstBuffer<const void *> src, ConstBuffer<const void *> src,
size_t n_frames, size_t sample_size) size_t n_frames, size_t sample_size)
{ {
GenericPcmInterleave((uint8_t *)dest, switch (sample_size) {
ConstBuffer<const uint8_t *>((const uint8_t *const*)src.data, case 4:
src.size), PcmInterleave32((int32_t *)dest,
n_frames, sample_size); 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);
}
} }

View File

@ -24,6 +24,8 @@
#include "Compiler.h" #include "Compiler.h"
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
#include <stdint.h>
/** /**
* Interleave planar PCM samples from #src to #dest. * Interleave planar PCM samples from #src to #dest.
*/ */
@ -31,4 +33,22 @@ void
PcmInterleave(void *gcc_restrict dest, ConstBuffer<const void *> src, PcmInterleave(void *gcc_restrict dest, ConstBuffer<const void *> src,
size_t n_frames, size_t sample_size); 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 #endif