From 21fb7eea82b988358d5f48c2dadbf701c40608a2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 28 Feb 2016 09:54:20 +0100 Subject: [PATCH] output/alsa: probe DSD_U32 if DSD_U8 fails See http://bugs.musicpd.org/view.php?id=4485 --- NEWS | 1 + src/output/plugins/AlsaOutputPlugin.cxx | 31 ++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b5d5ccc22..9c761fd6f 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,7 @@ ver 0.20 (not yet released) * output - alsa: fix multi-channel order - alsa: remove option "use_mmap" + - alsa: support DSD_U32 - jack: reduce CPU usage - pulse: set channel map to WAVE-EX - recorder: record tags diff --git a/src/output/plugins/AlsaOutputPlugin.cxx b/src/output/plugins/AlsaOutputPlugin.cxx index c5a9e5732..28a7324a8 100644 --- a/src/output/plugins/AlsaOutputPlugin.cxx +++ b/src/output/plugins/AlsaOutputPlugin.cxx @@ -24,6 +24,7 @@ #include "mixer/MixerList.hxx" #include "pcm/PcmExport.hxx" #include "config/ConfigError.hxx" +#include "system/ByteOrder.hxx" #include "util/Manual.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -403,6 +404,34 @@ AlsaTryFormatOrByteSwap(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, return err; } +/** + * Attempts to configure the specified sample format. On DSD_U8 + * failure, attempt to switch to DSD_U32. + */ +static int +AlsaTryFormatDsd(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, + snd_pcm_format_t fmt, PcmExport::Params ¶ms) +{ + int err = AlsaTryFormatOrByteSwap(pcm, hwparams, fmt, params); + +#if defined(ENABLE_DSD) && defined(HAVE_ALSA_DSD_U32) + if (err == 0) + params.dsd_u32 = false; + + if (err == -EINVAL && fmt == SND_PCM_FORMAT_DSD_U8) { + /* attempt to switch to DSD_U32 */ + fmt = IsLittleEndian() + ? SND_PCM_FORMAT_DSD_U32_LE + : SND_PCM_FORMAT_DSD_U32_BE; + err = AlsaTryFormatOrByteSwap(pcm, hwparams, fmt, params); + if (err == 0) + params.dsd_u32 = true; + } +#endif + + return err; +} + static int AlsaTryFormat(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, SampleFormat sample_format, @@ -412,7 +441,7 @@ AlsaTryFormat(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, if (alsa_format == SND_PCM_FORMAT_UNKNOWN) return -EINVAL; - return AlsaTryFormatOrByteSwap(pcm, hwparams, alsa_format, params); + return AlsaTryFormatDsd(pcm, hwparams, alsa_format, params); } /**