Commit 925b5954 authored by Max Kellermann's avatar Max Kellermann

pcm/Dsd2Pcm: add integer-only implementation

parent dca79938
...@@ -31,6 +31,7 @@ or implied, of Sebastian Gesemann. ...@@ -31,6 +31,7 @@ or implied, of Sebastian Gesemann.
*/ */
#include "Dsd2Pcm.hxx" #include "Dsd2Pcm.hxx"
#include "Traits.hxx"
#include "util/bit_reverse.h" #include "util/bit_reverse.h"
#include "util/GenerateArray.hxx" #include "util/GenerateArray.hxx"
...@@ -150,6 +151,29 @@ GenerateCtable(int t) noexcept ...@@ -150,6 +151,29 @@ GenerateCtable(int t) noexcept
static constexpr auto ctables = GenerateArray<CTABLES>(GenerateCtable); static constexpr auto ctables = GenerateArray<CTABLES>(GenerateCtable);
template<typename Traits=SampleTraits<SampleFormat::S24_P32>>
static constexpr auto
CalculateCtableS24Value(size_t i, size_t j) noexcept
{
return typename Traits::value_type(ctables[i][j] * Traits::MAX);
}
struct GenerateCtableS24Value {
size_t i;
constexpr auto operator()(size_t j) const noexcept {
return CalculateCtableS24Value(i, j);
}
};
static constexpr auto
GenerateCtableS24(size_t i) noexcept
{
return GenerateArray<256>(GenerateCtableS24Value{i});
}
static constexpr auto ctables_s24 = GenerateArray<CTABLES>(GenerateCtableS24);
void void
Dsd2Pcm::Reset() noexcept Dsd2Pcm::Reset() noexcept
{ {
...@@ -191,6 +215,25 @@ Dsd2Pcm::TranslateSample(size_t ffp, uint8_t src) noexcept ...@@ -191,6 +215,25 @@ Dsd2Pcm::TranslateSample(size_t ffp, uint8_t src) noexcept
return CalcOutputSample(ffp); return CalcOutputSample(ffp);
} }
inline int32_t
Dsd2Pcm::CalcOutputSampleS24(size_t ffp) const noexcept
{
int32_t acc = 0;
for (size_t i = 0; i < CTABLES; ++i) {
uint8_t bite1 = fifo[(ffp -i) & FIFOMASK];
uint8_t bite2 = fifo[(ffp-(CTABLES*2-1)+i) & FIFOMASK];
acc += ctables_s24[i][bite1] + ctables_s24[i][bite2];
}
return acc;
}
inline int32_t
Dsd2Pcm::TranslateSampleS24(size_t ffp, uint8_t src) noexcept
{
ApplySample(ffp, src);
return CalcOutputSampleS24(ffp);
}
void void
Dsd2Pcm::Translate(size_t samples, Dsd2Pcm::Translate(size_t samples,
const uint8_t *gcc_restrict src, ptrdiff_t src_stride, const uint8_t *gcc_restrict src, ptrdiff_t src_stride,
...@@ -208,6 +251,22 @@ Dsd2Pcm::Translate(size_t samples, ...@@ -208,6 +251,22 @@ Dsd2Pcm::Translate(size_t samples,
} }
void void
Dsd2Pcm::TranslateS24(size_t samples,
const uint8_t *gcc_restrict src, ptrdiff_t src_stride,
int32_t *dst, ptrdiff_t dst_stride) noexcept
{
size_t ffp = fifopos;
while (samples-- > 0) {
uint8_t bite1 = *src;
src += src_stride;
*dst = TranslateSampleS24(ffp, bite1);
dst += dst_stride;
ffp = (ffp + 1) & FIFOMASK;
}
fifopos = ffp;
}
void
MultiDsd2Pcm::Translate(unsigned channels, size_t n_frames, MultiDsd2Pcm::Translate(unsigned channels, size_t n_frames,
const uint8_t *src, float *dest) noexcept const uint8_t *src, float *dest) noexcept
{ {
...@@ -237,3 +296,34 @@ MultiDsd2Pcm::TranslateStereo(size_t n_frames, ...@@ -237,3 +296,34 @@ MultiDsd2Pcm::TranslateStereo(size_t n_frames,
} }
fifopos = ffp; fifopos = ffp;
} }
void
MultiDsd2Pcm::TranslateS24(unsigned channels, size_t n_frames,
const uint8_t *src, int32_t *dest) noexcept
{
assert(channels <= per_channel.max_size());
if (channels == 2) {
TranslateStereoS24(n_frames, src, dest);
return;
}
for (unsigned i = 0; i < channels; ++i) {
per_channel[i].TranslateS24(n_frames,
src++, channels,
dest++, channels);
}
}
inline void
MultiDsd2Pcm::TranslateStereoS24(size_t n_frames,
const uint8_t *src, int32_t *dest) noexcept
{
size_t ffp = fifopos;
while (n_frames-- > 0) {
*dest++ = per_channel[0].TranslateSampleS24(ffp, *src++);
*dest++ = per_channel[1].TranslateSampleS24(ffp, *src++);
ffp = (ffp + 1) & Dsd2Pcm::FIFOMASK;
}
fifopos = ffp;
}
...@@ -79,10 +79,17 @@ public: ...@@ -79,10 +79,17 @@ public:
const uint8_t *src, ptrdiff_t src_stride, const uint8_t *src, ptrdiff_t src_stride,
float *dst, ptrdiff_t dst_stride) noexcept; float *dst, ptrdiff_t dst_stride) noexcept;
void TranslateS24(size_t samples,
const uint8_t *src, ptrdiff_t src_stride,
int32_t *dst, ptrdiff_t dst_stride) noexcept;
private: private:
void ApplySample(size_t ffp, uint8_t src) noexcept; void ApplySample(size_t ffp, uint8_t src) noexcept;
float CalcOutputSample(size_t ffp) const noexcept; float CalcOutputSample(size_t ffp) const noexcept;
float TranslateSample(size_t ffp, uint8_t src) noexcept; float TranslateSample(size_t ffp, uint8_t src) noexcept;
int32_t CalcOutputSampleS24(size_t ffp) const noexcept;
int32_t TranslateSampleS24(size_t ffp, uint8_t src) noexcept;
}; };
class MultiDsd2Pcm { class MultiDsd2Pcm {
...@@ -100,12 +107,18 @@ public: ...@@ -100,12 +107,18 @@ public:
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;
void TranslateS24(unsigned channels, size_t n_frames,
const uint8_t *src, int32_t *dest) noexcept;
private: private:
/** /**
* Optimized implementation for the common case. * Optimized implementation for the common case.
*/ */
void TranslateStereo(size_t n_frames, void TranslateStereo(size_t n_frames,
const uint8_t *src, float *dest) noexcept; const uint8_t *src, float *dest) noexcept;
void TranslateStereoS24(size_t n_frames,
const uint8_t *src, int32_t *dest) noexcept;
}; };
#endif /* include guard DSD2PCM_H_INCLUDED */ #endif /* include guard DSD2PCM_H_INCLUDED */
......
...@@ -38,3 +38,19 @@ PcmDsd::ToFloat(unsigned channels, ConstBuffer<uint8_t> src) noexcept ...@@ -38,3 +38,19 @@ PcmDsd::ToFloat(unsigned channels, ConstBuffer<uint8_t> src) noexcept
dsd2pcm.Translate(channels, num_frames, src.data, dest); dsd2pcm.Translate(channels, num_frames, src.data, dest);
return { dest, num_samples }; return { dest, num_samples };
} }
ConstBuffer<int32_t>
PcmDsd::ToS24(unsigned channels, ConstBuffer<uint8_t> src) noexcept
{
assert(!src.IsNull());
assert(!src.empty());
assert(src.size % channels == 0);
const size_t num_samples = src.size;
const size_t num_frames = src.size / channels;
auto *dest = buffer.GetT<int32_t>(num_samples);
dsd2pcm.TranslateS24(channels, num_frames, src.data, dest);
return { dest, num_samples };
}
...@@ -42,6 +42,9 @@ public: ...@@ -42,6 +42,9 @@ public:
ConstBuffer<float> ToFloat(unsigned channels, ConstBuffer<float> ToFloat(unsigned channels,
ConstBuffer<uint8_t> src) noexcept; ConstBuffer<uint8_t> src) noexcept;
ConstBuffer<int32_t> ToS24(unsigned channels,
ConstBuffer<uint8_t> src) noexcept;
}; };
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment