diff options
author | Max Kellermann <max@duempel.org> | 2012-03-20 01:01:12 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2012-03-22 01:14:51 +0100 |
commit | 81208d78acb260c7c2e6debc765042dd5e98f862 (patch) | |
tree | 32993048254599ac9d5dfb26a0ac182863d5db73 /src/pcm_convert.c | |
parent | da8b01771ff425dd30dca1cb8a8fe943d2ecc90b (diff) | |
download | mpd-81208d78acb260c7c2e6debc765042dd5e98f862.tar.gz mpd-81208d78acb260c7c2e6debc765042dd5e98f862.tar.xz mpd-81208d78acb260c7c2e6debc765042dd5e98f862.zip |
pcm_dsd: implement DSD to 24 bit USB conversion
Implements the dCS suggested standard:
http://www.dcsltd.co.uk/page/assets/DSDoverUSB.pdf
Diffstat (limited to 'src/pcm_convert.c')
-rw-r--r-- | src/pcm_convert.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/pcm_convert.c b/src/pcm_convert.c index 03172b613..f19a95223 100644 --- a/src/pcm_convert.c +++ b/src/pcm_convert.c @@ -22,6 +22,7 @@ #include "pcm_channels.h" #include "pcm_format.h" #include "pcm_pack.h" +#include "pcm_dsd_usb.h" #include "audio_format.h" #include "glib_compat.h" @@ -325,6 +326,40 @@ pcm_convert(struct pcm_convert_state *state, size_t *dest_size_r, GError **error_r) { + struct audio_format usb_format; + + if (src_format->format == SAMPLE_FORMAT_DSD && + dest_format->format == SAMPLE_FORMAT_DSD_OVER_USB) { + size_t u_size; + const uint32_t *u = pcm_dsd_to_usb(&state->dsd.buffer, + src_format->channels, + src, src_size, + &u_size); + if (u == NULL) { + g_set_error_literal(error_r, pcm_convert_quark(), 0, + "DSD to USB conversion failed"); + return NULL; + } + + usb_format = *src_format; + usb_format.format = SAMPLE_FORMAT_DSD_OVER_USB; + + /* each DSD-over-USB sample contains 2 DSD bytes (16 + DSD bits), which means the sample rate must be + halved; this is not the real 1 bit sample rate, but + MPD's point of view */ + usb_format.sample_rate = usb_format.sample_rate / 2; + + if (audio_format_equals(&usb_format, dest_format)) { + *dest_size_r = u_size; + return u; + } + + src_format = &usb_format; + src = u; + src_size = u_size; + } + struct audio_format float_format; if (src_format->format == SAMPLE_FORMAT_DSD) { size_t f_size; |