diff --git a/src/pcm/Dop.cxx b/src/pcm/Dop.cxx index 8120e200c..0ad6271d6 100644 --- a/src/pcm/Dop.cxx +++ b/src/pcm/Dop.cxx @@ -18,7 +18,6 @@ */ #include "Dop.hxx" -#include "Buffer.hxx" #include "ChannelDefs.hxx" #include "util/ConstBuffer.hxx" @@ -78,9 +77,16 @@ DsdToDop(uint32_t *dest, const uint8_t *src, } } +void +DsdToDopConverter::Open(unsigned _channels) noexcept +{ + assert(audio_valid_channel_count(_channels)); + + channels = _channels; +} + ConstBuffer -pcm_dsd_to_dop(PcmBuffer &buffer, unsigned channels, - ConstBuffer src) noexcept +DsdToDopConverter::Convert(ConstBuffer src) noexcept { assert(audio_valid_channel_count(channels)); assert(src.size % channels == 0); diff --git a/src/pcm/Dop.hxx b/src/pcm/Dop.hxx index 3bd089fe7..c1806b8c9 100644 --- a/src/pcm/Dop.hxx +++ b/src/pcm/Dop.hxx @@ -20,9 +20,10 @@ #ifndef MPD_PCM_DOP_HXX #define MPD_PCM_DOP_HXX +#include "Buffer.hxx" + #include -class PcmBuffer; template struct ConstBuffer; /** @@ -30,8 +31,18 @@ template struct ConstBuffer; * playback over USB, according to the DoP standard: * http://dsd-guide.com/dop-open-standard */ -ConstBuffer -pcm_dsd_to_dop(PcmBuffer &buffer, unsigned channels, - ConstBuffer src) noexcept; +class DsdToDopConverter { + unsigned channels; + + PcmBuffer buffer; + +public: + void Open(unsigned _channels) noexcept; + + void Reset() noexcept { + } + + ConstBuffer Convert(ConstBuffer src) noexcept; +}; #endif diff --git a/src/pcm/Export.cxx b/src/pcm/Export.cxx index 38bd5241d..fb77f43f8 100644 --- a/src/pcm/Export.cxx +++ b/src/pcm/Export.cxx @@ -61,10 +61,13 @@ PcmExport::Open(SampleFormat sample_format, unsigned _channels, sample_format = SampleFormat::S32; dop = params.dop && sample_format == SampleFormat::DSD; - if (dop) + if (dop) { + dop_converter.Open(_channels); + /* after the conversion to DoP, the DSD samples are stuffed inside fake 24 bit samples */ sample_format = SampleFormat::S24_P32; + } #endif shift8 = params.shift8 && sample_format == SampleFormat::S24_P32; @@ -84,6 +87,15 @@ PcmExport::Open(SampleFormat sample_format, unsigned _channels, } } +void +PcmExport::Reset() noexcept +{ +#ifdef ENABLE_DSD + if (dop) + dop_converter.Reset(); +#endif +} + size_t PcmExport::GetFrameSize(const AudioFormat &audio_format) const noexcept { @@ -168,8 +180,7 @@ PcmExport::Export(ConstBuffer data) noexcept .ToVoid(); if (dop) - data = pcm_dsd_to_dop(dop_buffer, channels, - ConstBuffer::FromVoid(data)) + data = dop_converter.Convert(ConstBuffer::FromVoid(data)) .ToVoid(); #endif diff --git a/src/pcm/Export.hxx b/src/pcm/Export.hxx index 8dfee34b6..91c50e2dc 100644 --- a/src/pcm/Export.hxx +++ b/src/pcm/Export.hxx @@ -24,6 +24,10 @@ #include "Buffer.hxx" #include "config.h" +#ifdef ENABLE_DSD +#include "Dop.hxx" +#endif + template struct ConstBuffer; struct AudioFormat; @@ -49,12 +53,9 @@ class PcmExport { PcmBuffer dsd_buffer; /** - * The buffer is used to convert DSD samples to the - * DoP format. - * * @see #dop */ - PcmBuffer dop_buffer; + DsdToDopConverter dop_converter; #endif /** @@ -167,8 +168,7 @@ public: /** * Reset the filter's state, e.g. drop/flush buffers. */ - void Reset() noexcept { - } + void Reset() noexcept; /** * Calculate the size of one output frame.