output/alsa, pcm: rename "DSD over USB" to "DoP"

The standard has been renamed since the early draft that was
implemented in MPD.
This commit is contained in:
Max Kellermann 2014-08-31 16:12:26 +02:00
parent 6e04d66a35
commit e5a28bfd8d
10 changed files with 60 additions and 59 deletions

View File

@ -465,7 +465,7 @@ libpcm_a_SOURCES = \
src/pcm/PcmConvert.cxx src/pcm/PcmConvert.hxx \ src/pcm/PcmConvert.cxx src/pcm/PcmConvert.hxx \
src/pcm/dsd2pcm/dsd2pcm.c src/pcm/dsd2pcm/dsd2pcm.h \ src/pcm/dsd2pcm/dsd2pcm.c src/pcm/dsd2pcm/dsd2pcm.h \
src/pcm/PcmDsd.cxx src/pcm/PcmDsd.hxx \ src/pcm/PcmDsd.cxx src/pcm/PcmDsd.hxx \
src/pcm/PcmDsdUsb.cxx src/pcm/PcmDsdUsb.hxx \ src/pcm/PcmDop.cxx src/pcm/PcmDop.hxx \
src/pcm/Volume.cxx src/pcm/Volume.hxx \ src/pcm/Volume.cxx src/pcm/Volume.hxx \
src/pcm/PcmMix.cxx src/pcm/PcmMix.hxx \ src/pcm/PcmMix.cxx src/pcm/PcmMix.hxx \
src/pcm/PcmChannels.cxx src/pcm/PcmChannels.hxx \ src/pcm/PcmChannels.cxx src/pcm/PcmChannels.hxx \

1
NEWS
View File

@ -55,6 +55,7 @@ ver 0.19 (not yet released)
- shine: new encoder plugin - shine: new encoder plugin
* output * output
- alsa: support native DSD playback - alsa: support native DSD playback
- alsa: rename "DSD over USB" to "DoP"
* threads: * threads:
- the update thread runs at "idle" priority - the update thread runs at "idle" priority
- the output thread runs at "real-time" priority - the output thread runs at "real-time" priority

View File

@ -1991,15 +1991,15 @@ systemctl start mpd.socket</programlisting>
</row> </row>
<row> <row>
<entry> <entry>
<varname>dsd_usb</varname> <varname>dop</varname>
<parameter>yes|no</parameter> <parameter>yes|no</parameter>
</entry> </entry>
<entry> <entry>
If set to <parameter>yes</parameter>, then DSD over If set to <parameter>yes</parameter>, then DSD over
USB according to the <ulink PCM according to the <ulink
url="http://www.sonore.us/DoP_openStandard_1v1.pdf">pro url="http://dsd-guide.com/dop-open-standard">DoP
posed standard by dCS and others</ulink> is enabled. This wraps standard others</ulink> is enabled. This wraps DSD
DSD samples in fake 24 bit PCM, and is understood by samples in fake 24 bit PCM, and is understood by
some DSD capable products, but may be harmful to some DSD capable products, but may be harmful to
other hardware. Therefore, the default is other hardware. Therefore, the default is
<parameter>no</parameter> and you can enable the <parameter>no</parameter> and you can enable the

View File

@ -62,12 +62,11 @@ struct AlsaOutput {
bool use_mmap; bool use_mmap;
/** /**
* Enable DSD over USB according to the dCS suggested * Enable DSD over PCM according to the DoP standard standard?
* standard?
* *
* @see http://www.dcsltd.co.uk/page/assets/DSDoverUSB.pdf * @see http://dsd-guide.com/dop-open-standard
*/ */
bool dsd_usb; bool dop;
/** libasound's buffer_time setting (in microseconds) */ /** libasound's buffer_time setting (in microseconds) */
unsigned int buffer_time; unsigned int buffer_time;
@ -153,7 +152,9 @@ AlsaOutput::Configure(const config_param &param, Error &error)
use_mmap = param.GetBlockValue("use_mmap", false); use_mmap = param.GetBlockValue("use_mmap", false);
dsd_usb = param.GetBlockValue("dsd_usb", false); dop = param.GetBlockValue("dop", false) ||
/* legacy name from MPD 0.18 and older: */
param.GetBlockValue("dsd_usb", false);
buffer_time = param.GetBlockValue("buffer_time", buffer_time = param.GetBlockValue("buffer_time",
MPD_ALSA_BUFFER_TIME_US); MPD_ALSA_BUFFER_TIME_US);
@ -639,34 +640,34 @@ alsa_setup_dsd(AlsaOutput *ad, const AudioFormat audio_format,
bool *shift8_r, bool *packed_r, bool *reverse_endian_r, bool *shift8_r, bool *packed_r, bool *reverse_endian_r,
Error &error) Error &error)
{ {
assert(ad->dsd_usb); assert(ad->dop);
assert(audio_format.format == SampleFormat::DSD); assert(audio_format.format == SampleFormat::DSD);
/* pass 24 bit to alsa_setup() */ /* pass 24 bit to alsa_setup() */
AudioFormat usb_format = audio_format; AudioFormat dop_format = audio_format;
usb_format.format = SampleFormat::S24_P32; dop_format.format = SampleFormat::S24_P32;
usb_format.sample_rate /= 2; dop_format.sample_rate /= 2;
const AudioFormat check = usb_format; const AudioFormat check = dop_format;
if (!alsa_setup(ad, usb_format, packed_r, reverse_endian_r, error)) if (!alsa_setup(ad, dop_format, packed_r, reverse_endian_r, error))
return false; return false;
/* if the device allows only 32 bit, shift all DSD-over-USB /* if the device allows only 32 bit, shift all DoP
samples left by 8 bit and leave the lower 8 bit cleared; samples left by 8 bit and leave the lower 8 bit cleared;
the DSD-over-USB documentation does not specify whether the DSD-over-USB documentation does not specify whether
this is legal, but there is anecdotical evidence that this this is legal, but there is anecdotical evidence that this
is possible (and the only option for some devices) */ is possible (and the only option for some devices) */
*shift8_r = usb_format.format == SampleFormat::S32; *shift8_r = dop_format.format == SampleFormat::S32;
if (usb_format.format == SampleFormat::S32) if (dop_format.format == SampleFormat::S32)
usb_format.format = SampleFormat::S24_P32; dop_format.format = SampleFormat::S24_P32;
if (usb_format != check) { if (dop_format != check) {
/* no bit-perfect playback, which is required /* no bit-perfect playback, which is required
for DSD over USB */ for DSD over USB */
error.Format(alsa_output_domain, error.Format(alsa_output_domain,
"Failed to configure DSD-over-USB on ALSA device \"%s\"", "Failed to configure DSD-over-PCM on ALSA device \"%s\"",
alsa_device(ad)); alsa_device(ad));
delete[] ad->silence; delete[] ad->silence;
return false; return false;
@ -681,9 +682,9 @@ alsa_setup_or_dsd(AlsaOutput *ad, AudioFormat &audio_format,
{ {
bool shift8 = false, packed, reverse_endian; bool shift8 = false, packed, reverse_endian;
const bool dsd_usb = ad->dsd_usb && const bool dop = ad->dop &&
audio_format.format == SampleFormat::DSD; audio_format.format == SampleFormat::DSD;
const bool success = dsd_usb const bool success = dop
? alsa_setup_dsd(ad, audio_format, ? alsa_setup_dsd(ad, audio_format,
&shift8, &packed, &reverse_endian, &shift8, &packed, &reverse_endian,
error) error)
@ -694,7 +695,7 @@ alsa_setup_or_dsd(AlsaOutput *ad, AudioFormat &audio_format,
ad->pcm_export->Open(audio_format.format, ad->pcm_export->Open(audio_format.format,
audio_format.channels, audio_format.channels,
dsd_usb, shift8, packed, reverse_endian); dop, shift8, packed, reverse_endian);
return true; return true;
} }

View File

@ -18,7 +18,7 @@
*/ */
#include "config.h" #include "config.h"
#include "PcmDsdUsb.hxx" #include "PcmDop.hxx"
#include "PcmBuffer.hxx" #include "PcmBuffer.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
@ -27,20 +27,20 @@
constexpr constexpr
static inline uint32_t static inline uint32_t
pcm_two_dsd_to_usb_marker1(uint8_t a, uint8_t b) pcm_two_dsd_to_dop_marker1(uint8_t a, uint8_t b)
{ {
return 0xff050000 | (a << 8) | b; return 0xff050000 | (a << 8) | b;
} }
constexpr constexpr
static inline uint32_t static inline uint32_t
pcm_two_dsd_to_usb_marker2(uint8_t a, uint8_t b) pcm_two_dsd_to_dop_marker2(uint8_t a, uint8_t b)
{ {
return 0xfffa0000 | (a << 8) | b; return 0xfffa0000 | (a << 8) | b;
} }
ConstBuffer<uint32_t> ConstBuffer<uint32_t>
pcm_dsd_to_usb(PcmBuffer &buffer, unsigned channels, pcm_dsd_to_dop(PcmBuffer &buffer, unsigned channels,
ConstBuffer<uint8_t> _src) ConstBuffer<uint8_t> _src)
{ {
assert(audio_valid_channel_count(channels)); assert(audio_valid_channel_count(channels));
@ -65,7 +65,7 @@ pcm_dsd_to_usb(PcmBuffer &buffer, unsigned channels,
/* each 24 bit sample has 16 DSD sample bits /* each 24 bit sample has 16 DSD sample bits
plus the magic 0x05 marker */ plus the magic 0x05 marker */
*dest++ = pcm_two_dsd_to_usb_marker1(src[0], src[channels]); *dest++ = pcm_two_dsd_to_dop_marker1(src[0], src[channels]);
/* seek the source pointer to the next /* seek the source pointer to the next
channel */ channel */
@ -80,7 +80,7 @@ pcm_dsd_to_usb(PcmBuffer &buffer, unsigned channels,
/* each 24 bit sample has 16 DSD sample bits /* each 24 bit sample has 16 DSD sample bits
plus the magic 0xfa marker */ plus the magic 0xfa marker */
*dest++ = pcm_two_dsd_to_usb_marker2(src[0], src[channels]); *dest++ = pcm_two_dsd_to_dop_marker2(src[0], src[channels]);
/* seek the source pointer to the next /* seek the source pointer to the next
channel */ channel */

View File

@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef MPD_PCM_DSD_USB_HXX #ifndef MPD_PCM_DOP_HXX
#define MPD_PCM_DSD_USB_HXX #define MPD_PCM_DOP_HXX
#include "check.h" #include "check.h"
@ -30,12 +30,11 @@ template<typename T> struct ConstBuffer;
/** /**
* Pack DSD 1 bit samples into (padded) 24 bit PCM samples for * Pack DSD 1 bit samples into (padded) 24 bit PCM samples for
* playback over USB, according to the proposed standard by * playback over USB, according to the DoP standard:
* dCS and others: * http://dsd-guide.com/dop-open-standard
* http://www.sonore.us/DoP_openStandard_1v1.pdf
*/ */
ConstBuffer<uint32_t> ConstBuffer<uint32_t>
pcm_dsd_to_usb(PcmBuffer &buffer, unsigned channels, pcm_dsd_to_dop(PcmBuffer &buffer, unsigned channels,
ConstBuffer<uint8_t> src); ConstBuffer<uint8_t> src);
#endif #endif

View File

@ -19,7 +19,7 @@
#include "config.h" #include "config.h"
#include "PcmExport.hxx" #include "PcmExport.hxx"
#include "PcmDsdUsb.hxx" #include "PcmDop.hxx"
#include "PcmPack.hxx" #include "PcmPack.hxx"
#include "util/ByteReverse.hxx" #include "util/ByteReverse.hxx"
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
@ -28,15 +28,15 @@
void void
PcmExport::Open(SampleFormat sample_format, unsigned _channels, PcmExport::Open(SampleFormat sample_format, unsigned _channels,
bool _dsd_usb, bool _shift8, bool _pack, bool _reverse_endian) bool _dop, bool _shift8, bool _pack, bool _reverse_endian)
{ {
assert(audio_valid_sample_format(sample_format)); assert(audio_valid_sample_format(sample_format));
assert(!_dsd_usb || audio_valid_channel_count(_channels)); assert(!_dop || audio_valid_channel_count(_channels));
channels = _channels; channels = _channels;
dsd_usb = _dsd_usb && sample_format == SampleFormat::DSD; dop = _dop && sample_format == SampleFormat::DSD;
if (dsd_usb) if (dop)
/* after the conversion to DSD-over-USB, the DSD /* after the conversion to DoP, the DSD
samples are stuffed inside fake 24 bit samples */ samples are stuffed inside fake 24 bit samples */
sample_format = SampleFormat::S24_P32; sample_format = SampleFormat::S24_P32;
@ -64,7 +64,7 @@ PcmExport::GetFrameSize(const AudioFormat &audio_format) const
/* packed 24 bit samples (3 bytes per sample) */ /* packed 24 bit samples (3 bytes per sample) */
return audio_format.channels * 3; return audio_format.channels * 3;
if (dsd_usb) if (dop)
/* the DSD-over-USB draft says that DSD 1-bit samples /* the DSD-over-USB draft says that DSD 1-bit samples
are enclosed within 24 bit samples, and MPD's are enclosed within 24 bit samples, and MPD's
representation of 24 bit is padded to 32 bit (4 representation of 24 bit is padded to 32 bit (4
@ -77,8 +77,8 @@ PcmExport::GetFrameSize(const AudioFormat &audio_format) const
ConstBuffer<void> ConstBuffer<void>
PcmExport::Export(ConstBuffer<void> data) PcmExport::Export(ConstBuffer<void> data)
{ {
if (dsd_usb) if (dop)
data = pcm_dsd_to_usb(dsd_buffer, channels, data = pcm_dsd_to_dop(dop_buffer, channels,
ConstBuffer<uint8_t>::FromVoid(data)) ConstBuffer<uint8_t>::FromVoid(data))
.ToVoid(); .ToVoid();
@ -125,8 +125,8 @@ PcmExport::CalcSourceSize(size_t size) const
/* 32 bit to 24 bit conversion (4 to 3 bytes) */ /* 32 bit to 24 bit conversion (4 to 3 bytes) */
size = (size / 3) * 4; size = (size / 3) * 4;
if (dsd_usb) if (dop)
/* DSD over USB doubles the transport size */ /* DoP doubles the transport size */
size /= 2; size /= 2;
return size; return size;

View File

@ -35,11 +35,11 @@ template<typename T> struct ConstBuffer;
struct PcmExport { struct PcmExport {
/** /**
* The buffer is used to convert DSD samples to the * The buffer is used to convert DSD samples to the
* DSD-over-USB format. * DoP format.
* *
* @see #dsd_usb * @see #dop
*/ */
PcmBuffer dsd_buffer; PcmBuffer dop_buffer;
/** /**
* The buffer is used to pack samples, removing padding. * The buffer is used to pack samples, removing padding.
@ -61,11 +61,11 @@ struct PcmExport {
uint8_t channels; uint8_t channels;
/** /**
* Convert DSD to DSD-over-USB? Input format must be * Convert DSD to DSD-over-PCM (DoP)? Input format must be
* SampleFormat::DSD and output format must be * SampleFormat::DSD and output format must be
* SampleFormat::S24_P32. * SampleFormat::S24_P32.
*/ */
bool dsd_usb; bool dop;
/** /**
* Convert (padded) 24 bit samples to 32 bit by shifting 8 * Convert (padded) 24 bit samples to 32 bit by shifting 8
@ -93,10 +93,10 @@ struct PcmExport {
* *
* This function cannot fail. * This function cannot fail.
* *
* @param channels the number of channels; ignored unless dsd_usb is set * @param channels the number of channels; ignored unless dop is set
*/ */
void Open(SampleFormat sample_format, unsigned channels, void Open(SampleFormat sample_format, unsigned channels,
bool dsd_usb, bool shift8, bool pack, bool reverse_endian); bool dop, bool shift8, bool pack, bool reverse_endian);
/** /**
* Calculate the size of one output frame. * Calculate the size of one output frame.

View File

@ -108,14 +108,14 @@ class PcmExportTest : public CppUnit::TestFixture {
CPPUNIT_TEST(TestShift8); CPPUNIT_TEST(TestShift8);
CPPUNIT_TEST(TestPack24); CPPUNIT_TEST(TestPack24);
CPPUNIT_TEST(TestReverseEndian); CPPUNIT_TEST(TestReverseEndian);
CPPUNIT_TEST(TestDsdUsb); CPPUNIT_TEST(TestDop);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
public: public:
void TestShift8(); void TestShift8();
void TestPack24(); void TestPack24();
void TestReverseEndian(); void TestReverseEndian();
void TestDsdUsb(); void TestDop();
}; };
#endif #endif

View File

@ -106,7 +106,7 @@ PcmExportTest::TestReverseEndian()
} }
void void
PcmExportTest::TestDsdUsb() PcmExportTest::TestDop()
{ {
static constexpr uint8_t src[] = { static constexpr uint8_t src[] = {
0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67,