Commit f930f37d authored by Jurgen Kramer's avatar Jurgen Kramer Committed by Max Kellermann

Add support for DSD-over-USB version 1.0, remove pre-v1 support

parent 4feb57e8
...@@ -1127,8 +1127,8 @@ systemctl start mpd.socket</programlisting> ...@@ -1127,8 +1127,8 @@ systemctl start mpd.socket</programlisting>
<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 USB according to the <ulink
url="http://www.dcsltd.co.uk/page/assets/DSDoverUSB.pdf">dCS url="http://www.sonore.us/DoP_openStandard_1v1.pdf">pro
suggested standard</ulink> is enabled. This wrapsa posed standard by dCS and others</ulink> is enabled. This wraps
DSD samples in fake 24 bit PCM, and is understood by DSD 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
......
...@@ -24,11 +24,19 @@ ...@@ -24,11 +24,19 @@
G_GNUC_CONST G_GNUC_CONST
static inline uint32_t static inline uint32_t
pcm_two_dsd_to_usb(uint8_t a, uint8_t b) pcm_two_dsd_to_usb_marker1(uint8_t a, uint8_t b)
{ {
return 0xffaa0000 | (a << 8) | b; return 0xff050000 | (a << 8) | b;
} }
G_GNUC_CONST
static inline uint32_t
pcm_two_dsd_to_usb_marker2(uint8_t a, uint8_t b)
{
return 0xfffa0000 | (a << 8) | b;
}
const uint32_t * const uint32_t *
pcm_dsd_to_usb(struct pcm_buffer *buffer, unsigned channels, pcm_dsd_to_usb(struct pcm_buffer *buffer, unsigned channels,
const uint8_t *src, size_t src_size, const uint8_t *src, size_t src_size,
...@@ -53,12 +61,27 @@ pcm_dsd_to_usb(struct pcm_buffer *buffer, unsigned channels, ...@@ -53,12 +61,27 @@ pcm_dsd_to_usb(struct pcm_buffer *buffer, unsigned channels,
uint32_t *const dest0 = pcm_buffer_get(buffer, dest_size), uint32_t *const dest0 = pcm_buffer_get(buffer, dest_size),
*dest = dest0; *dest = dest0;
for (unsigned i = num_frames; i > 0; --i) { for (unsigned i = num_frames / 2; i > 0; --i) {
for (unsigned c = channels; c > 0; --c) {
/* each 24 bit sample has 16 DSD sample bits
plus the magic 0x05 marker */
*dest++ = pcm_two_dsd_to_usb_marker1(src[0], src[channels]);
/* seek the source pointer to the next
channel */
++src;
}
/* skip the second byte of each channel, because we
have already copied it */
src += channels;
for (unsigned c = channels; c > 0; --c) { for (unsigned c = channels; c > 0; --c) {
/* each 24 bit sample has 16 DSD sample bits /* each 24 bit sample has 16 DSD sample bits
plus the magic 0xaa marker */ plus the magic 0xfa marker */
*dest++ = pcm_two_dsd_to_usb(src[0], src[channels]); *dest++ = pcm_two_dsd_to_usb_marker2(src[0], src[channels]);
/* seek the source pointer to the next /* seek the source pointer to the next
channel */ channel */
......
...@@ -30,8 +30,9 @@ struct pcm_buffer; ...@@ -30,8 +30,9 @@ struct pcm_buffer;
/** /**
* 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 dCS suggested standard: * playback over USB, according to the proposed standard by
* http://www.dcsltd.co.uk/page/assets/DSDoverUSB.pdf * dCS and others:
* http://www.sonore.us/DoP_openStandard_1v1.pdf
*/ */
const uint32_t * const uint32_t *
pcm_dsd_to_usb(struct pcm_buffer *buffer, unsigned channels, pcm_dsd_to_usb(struct pcm_buffer *buffer, unsigned channels,
......
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