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 "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

View File

@ -20,7 +20,6 @@
#include "config.h"
#include "Interleave.hxx"
#include <stdint.h>
#include <string.h>
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
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);
}
}

View File

@ -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