pcm/Dsd2Pcm: add optimized stereo version

This code path is 2% faster.
This commit is contained in:
Max Kellermann 2020-01-14 23:38:46 +01:00
parent ee46150329
commit 235b6980b8
2 changed files with 30 additions and 0 deletions

View File

@ -213,9 +213,27 @@ MultiDsd2Pcm::Translate(unsigned channels, size_t n_frames,
{ {
assert(channels <= per_channel.max_size()); assert(channels <= per_channel.max_size());
if (channels == 2) {
TranslateStereo(n_frames, src, dest);
return;
}
for (unsigned i = 0; i < channels; ++i) { for (unsigned i = 0; i < channels; ++i) {
per_channel[i].Translate(n_frames, per_channel[i].Translate(n_frames,
src++, channels, src++, channels,
dest++, channels); dest++, channels);
} }
} }
inline void
MultiDsd2Pcm::TranslateStereo(size_t n_frames,
const uint8_t *src, float *dest) noexcept
{
size_t ffp = fifopos;
while (n_frames-- > 0) {
*dest++ = per_channel[0].TranslateSample(ffp, *src++);
*dest++ = per_channel[1].TranslateSample(ffp, *src++);
ffp = (ffp + 1) & Dsd2Pcm::FIFOMASK;
}
fifopos = ffp;
}

View File

@ -42,6 +42,8 @@ or implied, of Sebastian Gesemann.
* A "dsd2pcm engine" for one channel. * A "dsd2pcm engine" for one channel.
*/ */
class Dsd2Pcm { class Dsd2Pcm {
friend class MultiDsd2Pcm;
public: public:
/* must be a power of two */ /* must be a power of two */
static constexpr size_t FIFOSIZE = 16; static constexpr size_t FIFOSIZE = 16;
@ -86,14 +88,24 @@ private:
class MultiDsd2Pcm { class MultiDsd2Pcm {
std::array<Dsd2Pcm, MAX_CHANNELS> per_channel; std::array<Dsd2Pcm, MAX_CHANNELS> per_channel;
size_t fifopos = 0;
public: public:
void Reset() noexcept { void Reset() noexcept {
for (auto &i : per_channel) for (auto &i : per_channel)
i.Reset(); i.Reset();
fifopos = 0;
} }
void Translate(unsigned channels, size_t n_frames, void Translate(unsigned channels, size_t n_frames,
const uint8_t *src, float *dest) noexcept; const uint8_t *src, float *dest) noexcept;
private:
/**
* Optimized implementation for the common case.
*/
void TranslateStereo(size_t n_frames,
const uint8_t *src, float *dest) noexcept;
}; };
#endif /* include guard DSD2PCM_H_INCLUDED */ #endif /* include guard DSD2PCM_H_INCLUDED */