This part of the new decoder actually packs the raw DSD
data into 'DSD-over-USB' format.
---
src/dsdnative/dsdnative.c | 211
+++++++++++++++++++++++++++++++++++++++++++++
src/dsdnative/dsdnative.h | 39 ++++++++
2 files changed, 250 insertions(+), 0 deletions(-)
create mode 100644 src/dsdnative/dsdnative.c
create mode 100644 src/dsdnative/dsdnative.h
Jurgen
diff --git a/src/dsdnative/dsdnative.c b/src/dsdnative/dsdnative.c
new file mode 100644
index 0000000..0e5c9ee
--- /dev/null
+++ b/src/dsdnative/dsdnative.c
@@ -0,0 +1,211 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "dsdnative.h"
+
+/* 09-Dec-11 Jurgen Kramer
+ * dsd2pcm.c converted to output native DSD (packed according to dCS spec) instead of PCM
+ * Tested with Mytek Stereo192-DSD DAC (using Linux snd-dice firewire driver)
+ * 24-bit dCS spec will be put in SAMPLE_FORMAT_S32
+ *
+ * 22-Jan-12 Jurgen Kramer
+ * Add support for DSF (Sony) format
+ */
+
+/* Currently only stereo streams are supported */
+
+/* translate DSF formatted stream to DSD-over-PCM
+ *
+ * DSF format uses a interleaved channel format in
+ * 4096 byte blocks
+ *
+ * E.g. for stereo files:
+ * block 1: 4096 bytes left channel data
+ * block 2: 4096 bytes right channel data
+ * block 3: 4096 bytes left channel data
+ * block 4 ...
+ *
+ * Last blocks are padded with zeros if not completely used
+ *
+ */
+
+extern void dsdnative_translate_dsf(
+ size_t samples,
+ const unsigned char *src, unsigned char *dst, unsigned int dsdsampleformat, uint32_t dsdiff_dsf_bitssample )
+{
+ unsigned char left1, left2, right1, right2;
+ int i;
+ static unsigned char bitreverse[256];
+
+ if ( dsdiff_dsf_bitssample == 1) /* 1 = LSB first, 8 = MSB first, DSD-over-USB wants MSB first */
+ {
+ int t,e,m;
+ for (t=0, e=0; t<256; ++t) /* Create bitreverse table */
+ {
+ bitreverse[t] = e;
+ for (m=128; m && !((e^=m)&m); m>>=1)
+ ;
+ }
+ }
+
+ /* DSD packed sample format dCS spec (24-bit):
+ * 0xAA LSB left --- MSB left -> 24-bits
+ * 0xAA LSB Right ---MSB Right -> 24-bits
+ */
+
+ while ( samples > 0)
+ {
+ /* Process data for the left channel */
+
+ for (i=0; i<2048; i++)
+ {
+ left1 = ( *src ++ );
+ left2 = ( *src ++ );
+
+ if ( dsdiff_dsf_bitssample == 1) /* bitreverse needed? */
+ {
+ left1 = bitreverse[left1];
+ left2 = bitreverse[left2];
+ }
+
+ if (dsdsampleformat == 24)
+ {
+ ( *dst ++ )= left2;
+ ( *dst ++ )= left1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ }
+ else
+ {
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ ( *dst ++ )= left2;
+ ( *dst ++ )= left1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ }
+ dst += (ptrdiff_t) 4;
+ samples -= 2;
+ }
+
+ dst -= (ptrdiff_t) 16380;
+
+ /* Process data for the right channel */
+
+ for (i=0; i<2048; i++)
+ {
+ right1 = ( *src ++ );
+ right2 = ( *src ++ );
+
+ if ( dsdiff_dsf_bitssample == 1)
+ {
+ right1 = bitreverse[right1];
+ right2 = bitreverse[right2];
+ }
+
+ if (dsdsampleformat == 24)
+ {
+ ( *dst ++ )= right2;
+ ( *dst ++ )= right1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ }
+ else
+ {
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ ( *dst ++ )= right2;
+ ( *dst ++ )= right1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ }
+ dst += (ptrdiff_t) 4;
+ samples -= 2;
+ }
+ dst -= (ptrdiff_t) 4;
+ }
+}
+
+/* translate DFF formatted stream to DSD-over-PCM */
+
+extern void dsdnative_translate_dff(
+ size_t samples,
+ const unsigned char *src, unsigned char *dst, unsigned int dsdsampleformat )
+{
+ unsigned char left1, left2, right1, right2;
+
+ /* DSD packed sample format dCS spec (24-bit):
+ * 0xAA LSB left --- MSB left -> 24-bits
+ * 0xAA LSB Right ---MSB Right -> 24-bits
+ */
+
+ while (samples > 0)
+ {
+ if (samples == 2) /* Process last two samples */
+ {
+ left1 = ( *src ++ );
+ right1 = ( *src ++ );
+
+ if (dsdsampleformat == 24)
+ {
+ /* This 'works' for SAMPLE_FORMAT_S24_P32 when converted back to SAMPLE_FORMAT_S32 by mpd */
+ ( *dst ++ )= 0x00;
+ ( *dst ++ )= left1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+
+ ( *dst ++ )= 0x00;
+ ( *dst ++ )= right1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ }
+ else
+ {
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ ( *dst ++ )= 0x00; /* Last 2 samples: no left2 sample */
+ ( *dst ++ )= left1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ ( *dst ++ )= 0x00; /* Last 2 samples: no right2 sample */
+ ( *dst ++ )= right1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ }
+ samples = 0;
+
+ }
+ else
+ {
+ left1 = ( *src ++ );
+ right1 = ( *src ++ );
+ left2 = ( *src ++ );
+ right2 = ( *src ++ );
+
+ if (dsdsampleformat == 24)
+ {
+ /* This 'works' for SAMPLE_FORMAT_S24_P32 when convert back to SAMPLE_FORMAT_S32 by mpd */
+
+ ( *dst ++ )= left2;
+ ( *dst ++ )= left1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+
+ ( *dst ++ )= right2;
+ ( *dst ++ )= right1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ }
+ else
+ {
+ ( *dst ++ )= 0x00; /* Ignored byte, leave at 0x00 */
+ ( *dst ++ )= left2;
+ ( *dst ++ )= left1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+
+ ( *dst ++ )= 0x00; /* Ignore byte, leave at 0x00 */
+ ( *dst ++ )= right2;
+ ( *dst ++ )= right1;
+ ( *dst ++ )= 0xAA; /* Must stay here for DAC to lock to DSD! */
+ }
+ samples = samples - 4;
+ }
+ }
+
+}
+
diff --git a/src/dsdnative/dsdnative.h b/src/dsdnative/dsdnative.h
new file mode 100644
index 0000000..1aa4ab5
--- /dev/null
+++ b/src/dsdnative/dsdnative.h
@@ -0,0 +1,39 @@
+#ifndef DSDNATIVE_H_INCLUDED
+#define DSDNATIVE_H_INCLUDED
+
+#include <stddef.h>
+#include <string.h>
+
+#include <stdint.h> /* for uint32_t */
+
+/**
+ * "translates" a stream of octets to a stream
+ * of packed DSD formatted pcm
+ *
+ * @param samples -- number of octets/samples to "translate"
+ * @param src -- pointer to first octet (input)
+ * @param dst -- pointer to first sample(output)
+ * @param dsdsampleformat -- 32 or 24-bit output sample format
+ * Version for handling DFF (Philips) format
+ */
+extern void dsdnative_translate_dff(size_t samples,
+ const unsigned char *src, unsigned char *dst, unsigned int dsdsampleformat );
+
+/**
+ * "translates" a stream of octets to a stream
+ * of packed DSD formatted pcm
+ *
+ * @param samples -- number of octets/samples to "translate"
+ * @param src -- pointer to first octet (input)
+ * @param dst -- pointer to first 32-bits sample(output)
+ * @param dsdsampleformat -- 32 or 24-bit output sample format
+ * @param dsdiff_dsf_bitssample -- 1 = LSB, 8 = MSB
+ *
+ * Version for handling DSF (Sony) format
+ */
+
+extern void dsdnative_translate_dsf(size_t samples,
+ const unsigned char *src, unsigned char *dst, unsigned int dsdsampleformat, uint32_t dsdiff_dsf_bitssample );
+
+#endif /* include guard DSDNATIVE_H_INCLUDED */
+
--
1.7.6.5
------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
_______________________________________________
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team