On 13.09.2017 19:53, Kimmo Taskinen wrote:
On 13.09.2017 19:28, michaelvv wrote:
WORKS GREAT BUT THIS IS NOT DSD

Code:
--------------------
wvunpack file.wv -wq -o - | sox -q - -r 176.4k -b 24 -C 0 -t alsa plughw:2
--------------------

This plays it as DSD DoP:

wvunpack -q file.wv --dff -o - | sox -t dff - -r 176400 -t wav -b 24 -e signed --endian little - dop

However it requires SoX from: https://github.com/mansr/sox

And here is a patch for Audio-Scan Wavpack DSD support. Otherwise LMS does not detect Wavpack DSD files correctly.

diff -ruNb Audio-Scan-0.950.2.orig/include/wavpack.h Audio-Scan-0.950.2/include/wavpack.h
--- Audio-Scan-0.950.2.orig/include/wavpack.h	2017-01-04 21:24:52.287475457 +0000
+++ Audio-Scan-0.950.2/include/wavpack.h	2017-01-04 21:26:14.624593442 +0000
@@ -86,6 +86,7 @@
 #define ID_WVC_BITSTREAM        0xb
 #define ID_WVX_BITSTREAM        0xc
 #define ID_CHANNEL_INFO         0xd
+#define ID_DSD_BLOCK            0xe
 
 #define ID_RIFF_HEADER          (ID_OPTIONAL_DATA | 0x1)
 #define ID_RIFF_TRAILER         (ID_OPTIONAL_DATA | 0x2)
@@ -100,5 +101,6 @@
 int _wavpack_parse_block(wvpinfo *wvp);
 int _wavpack_parse_sample_rate(wvpinfo *wvp, uint32_t size);
 int _wavpack_parse_channel_info(wvpinfo *wvp, uint32_t size);
+int _wavpack_parse_dsd_block(wvpinfo *wvp, uint32_t size);
 void _wavpack_skip(wvpinfo *wvp, uint32_t size);
 int _wavpack_parse_old(wvpinfo *wvp);
diff -ruNb Audio-Scan-0.950.2.orig/src/wavpack.c Audio-Scan-0.950.2/src/wavpack.c
--- Audio-Scan-0.950.2.orig/src/wavpack.c	2017-01-04 21:24:52.287475457 +0000
+++ Audio-Scan-0.950.2/src/wavpack.c	2017-01-04 21:24:00.229297653 +0000
@@ -232,6 +232,11 @@
       _wavpack_parse_channel_info(wvp, size);
       break;
       
+    case ID_DSD_BLOCK:
+      DEBUG_TRACE("  Sub-Chunk: ID_DSD_BLOCK (size: %u)\n", size);
+      _wavpack_parse_dsd_block(wvp, size);
+      break;
+
     default: 
       // Skip it
       DEBUG_TRACE("  Sub-Chunk: %x (size: %u) (skipped)\n", id, size);
@@ -257,6 +262,7 @@
   if ( wvp->header->total_samples && wvp->file_size > 0 ) {
     SV **samplerate = my_hv_fetch( wvp->info, "samplerate" );
     if (samplerate != NULL) {      
+      if (wvp->header->flags & 0x80000000) wvp->header->total_samples *= 8; // DSD
       uint32_t song_length_ms = ((wvp->header->total_samples * 1.0) / SvIV(*samplerate)) * 1000;
       my_hv_store( wvp->info, "song_length_ms", newSVuv(song_length_ms) );
       my_hv_store( wvp->info, "bitrate", newSVuv( _bitrate(wvp->file_size - wvp->audio_offset, song_length_ms) ) );
@@ -297,6 +303,27 @@
   return 1;
 }
 
+int
+_wavpack_parse_dsd_block(wvpinfo *wvp, uint32_t size)
+{
+  if (wvp->header->flags & 0x80000000) {
+    unsigned char *bptr = buffer_ptr(wvp->buf);
+    uint32_t samplerate_index = (wvp->header->flags & 0x7800000) >> 23;
+    uint32_t samplerate;
+    if (samplerate_index < 0xF)
+      samplerate = wavpack_sample_rates[samplerate_index] * (1 << bptr[0]) * 8;
+    else
+      samplerate = 64 * 44100; // Default to DSD64 just in case  
+
+    my_hv_store( wvp->info, "samplerate", newSVuv(samplerate) );
+    my_hv_store( wvp->info, "bits_per_sample", newSVuv( 1 ) );
+  }
+  
+  _wavpack_skip(wvp, size);
+
+  return 1;
+}
+
 void
 _wavpack_skip(wvpinfo *wvp, uint32_t size)
 {
_______________________________________________
Squeezecenter mailing list
Squeezecenter@lists.slimdevices.com
http://lists.slimdevices.com/mailman/listinfo/squeezecenter

Reply via email to