diff --git a/NEWS b/NEWS index 2a6c5c439..658ca8c5f 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ ver 0.19.2 (not yet released) - ffmpeg: recognize MIME type audio/aacp * output - fix memory leak after filter initialization error + - fall back to PCM if given DSD sample rate is not supported * fix assertion failure on unsupported PCM conversion * auto-disable plugins that require GLib when --disable-glib is used diff --git a/src/output/OutputThread.cxx b/src/output/OutputThread.cxx index 54664bb65..2ec0670c1 100644 --- a/src/output/OutputThread.cxx +++ b/src/output/OutputThread.cxx @@ -22,6 +22,7 @@ #include "OutputAPI.hxx" #include "Domain.hxx" #include "pcm/PcmMix.hxx" +#include "pcm/Domain.hxx" #include "notify.hxx" #include "filter/FilterInternal.hxx" #include "filter/plugins/ConvertFilterPlugin.hxx" @@ -165,6 +166,10 @@ AudioOutput::Open() out_audio_format.ApplyMask(config_audio_format); mutex.unlock(); + + const AudioFormat retry_audio_format = out_audio_format; + + retry_without_dsd: success = ao_plugin_open(this, out_audio_format, error); mutex.lock(); @@ -189,6 +194,31 @@ AudioOutput::Open() mutex.unlock(); ao_plugin_close(this); + + if (error.IsDomain(pcm_domain) && + out_audio_format.format == SampleFormat::DSD) { + /* if the audio output supports DSD, but not + the given sample rate, it asks MPD to + resample; resampling DSD however is not + implemented; our last resort is to give up + DSD and fall back to PCM */ + + // TODO: clean up this workaround + + FormatError(output_domain, "Retrying without DSD"); + + out_audio_format = retry_audio_format; + out_audio_format.format = SampleFormat::FLOAT; + + /* clear the Error to allow reusing it */ + error.Clear(); + + /* sorry for the "goto" - this is a workaround + for the stable branch that should be as + unintrusive as possible */ + goto retry_without_dsd; + } + CloseFilter(); mutex.lock();