diff --git a/Makefile.am b/Makefile.am index cdc621d57..e0202b0cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -575,6 +575,7 @@ PCM_LIBS = \ if ENABLE_DSD libpcm_a_SOURCES += \ + src/pcm/Dsd32.cxx src/pcm/Dsd32.hxx \ src/pcm/PcmDsd.cxx src/pcm/PcmDsd.hxx \ src/pcm/dsd2pcm/dsd2pcm.c src/pcm/dsd2pcm/dsd2pcm.h endif diff --git a/src/pcm/Dsd32.cxx b/src/pcm/Dsd32.cxx new file mode 100644 index 000000000..017774ff5 --- /dev/null +++ b/src/pcm/Dsd32.cxx @@ -0,0 +1,62 @@ +/* + * Copyright 2003-2017 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "Dsd32.hxx" +#include "PcmBuffer.hxx" +#include "dsd2pcm/dsd2pcm.h" +#include "util/ConstBuffer.hxx" + +/** + * Construct a 32 bit integer from four bytes. + */ +static constexpr inline uint32_t +Construct32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) +{ + return uint32_t(a) | (uint32_t(b) << 8) | + (uint32_t(c) << 16) | (uint32_t(d) << 24); +} + +static constexpr inline uint32_t +Dsd8To32Sample(const uint8_t *src, unsigned channels) +{ + return Construct32(src[0], src[channels], + src[2 * channels], src[3 * channels]); +} + +ConstBuffer +Dsd8To32(PcmBuffer &buffer, unsigned channels, ConstBuffer _src) +{ + const size_t in_frames = _src.size / channels; + const size_t out_frames = in_frames / 4; + const size_t out_samples = out_frames * channels; + + const uint8_t *src = _src.data; + uint32_t *const dest0 = buffer.GetT(out_samples); + uint32_t *dest = dest0; + + for (size_t i = 0; i < out_frames; ++i) { + for (size_t c = 0; c < channels; ++c) + *dest++ = Dsd8To32Sample(src++, channels); + + src += 3 * channels; + } + + return {dest0, out_samples}; +} diff --git a/src/pcm/Dsd32.hxx b/src/pcm/Dsd32.hxx new file mode 100644 index 000000000..30b1c8ee2 --- /dev/null +++ b/src/pcm/Dsd32.hxx @@ -0,0 +1,36 @@ +/* + * Copyright 2003-2017 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_PCM_DSD_32_HXX +#define MPD_PCM_DSD_32_HXX + +#include "check.h" + +#include + +template struct ConstBuffer; +class PcmBuffer; + +/** + * Convert DSD_U8 to DSD_U32 (native endian). + */ +ConstBuffer +Dsd8To32(PcmBuffer &buffer, unsigned channels, ConstBuffer src); + +#endif diff --git a/src/pcm/PcmDsd.cxx b/src/pcm/PcmDsd.cxx index 541b7196d..5ac2c27bd 100644 --- a/src/pcm/PcmDsd.cxx +++ b/src/pcm/PcmDsd.cxx @@ -71,41 +71,3 @@ PcmDsd::ToFloat(unsigned channels, ConstBuffer src) return { dest, num_samples }; } - -/** - * Construct a 32 bit integer from four bytes. - */ -static constexpr inline uint32_t -Construct32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) -{ - return uint32_t(a) | (uint32_t(b) << 8) | - (uint32_t(c) << 16) | (uint32_t(d) << 24); -} - -static constexpr inline uint32_t -Dsd8To32Sample(const uint8_t *src, unsigned channels) -{ - return Construct32(src[0], src[channels], - src[2 * channels], src[3 * channels]); -} - -ConstBuffer -Dsd8To32(PcmBuffer &buffer, unsigned channels, ConstBuffer _src) -{ - const size_t in_frames = _src.size / channels; - const size_t out_frames = in_frames / 4; - const size_t out_samples = out_frames * channels; - - const uint8_t *src = _src.data; - uint32_t *const dest0 = buffer.GetT(out_samples); - uint32_t *dest = dest0; - - for (size_t i = 0; i < out_frames; ++i) { - for (size_t c = 0; c < channels; ++c) - *dest++ = Dsd8To32Sample(src++, channels); - - src += 3 * channels; - } - - return {dest0, out_samples}; -} diff --git a/src/pcm/PcmDsd.hxx b/src/pcm/PcmDsd.hxx index f26f77f8f..ec6e041f1 100644 --- a/src/pcm/PcmDsd.hxx +++ b/src/pcm/PcmDsd.hxx @@ -48,10 +48,4 @@ public: ConstBuffer src); }; -/** - * Convert DSD_U8 to DSD_U32 (native endian). - */ -ConstBuffer -Dsd8To32(PcmBuffer &buffer, unsigned channels, ConstBuffer src); - #endif diff --git a/src/pcm/PcmExport.cxx b/src/pcm/PcmExport.cxx index 254995d38..1b979106e 100644 --- a/src/pcm/PcmExport.cxx +++ b/src/pcm/PcmExport.cxx @@ -25,6 +25,7 @@ #include "util/ConstBuffer.hxx" #ifdef ENABLE_DSD +#include "Dsd32.hxx" #include "PcmDsd.hxx" #include "PcmDop.hxx" #endif