From 2b43ceb6c68e93feff830d2946abc8dc8f069421 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 11 Jan 2017 10:06:27 +0100 Subject: [PATCH] pcm/Export: DSD_U32 quarters the sample rate DSD_U32 packs four bytes instead of one large "sample", thus the sample rate is one quarter of the input sample rate. This fixes a rather critical DSD_U32 playback problem. --- NEWS | 2 ++ src/pcm/PcmExport.cxx | 12 ++++++++++++ test/test_pcm_export.cxx | 3 +++ 3 files changed, 17 insertions(+) diff --git a/NEWS b/NEWS index 510aff088..a25e79d97 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ ver 0.20.2 (not yet released) * decoder - flac: add options "probesize" and "analyzeduration" +* output + - alsa: fix the DSD_U32 sample rate ver 0.20.1 (2017/01/09) * input diff --git a/src/pcm/PcmExport.cxx b/src/pcm/PcmExport.cxx index 25cf8dbd5..ed8ab1707 100644 --- a/src/pcm/PcmExport.cxx +++ b/src/pcm/PcmExport.cxx @@ -101,12 +101,24 @@ PcmExport::GetFrameSize(const AudioFormat &audio_format) const unsigned PcmExport::Params::CalcOutputSampleRate(unsigned sample_rate) const { +#ifdef ENABLE_DSD + if (dsd_u32) + /* DSD_U32 combines four 8-bit "samples" in one 32-bit + "sample" */ + sample_rate /= 4; +#endif + return sample_rate; } unsigned PcmExport::Params::CalcInputSampleRate(unsigned sample_rate) const { +#ifdef ENABLE_DSD + if (dsd_u32) + sample_rate *= 4; +#endif + return sample_rate; } diff --git a/test/test_pcm_export.cxx b/test/test_pcm_export.cxx index 2c2e32013..5dded1367 100644 --- a/test/test_pcm_export.cxx +++ b/test/test_pcm_export.cxx @@ -146,6 +146,9 @@ PcmExportTest::TestDsdU32() PcmExport::Params params; params.dsd_u32 = true; + CPPUNIT_ASSERT_EQUAL(params.CalcOutputSampleRate(705600u), 176400u); + CPPUNIT_ASSERT_EQUAL(params.CalcInputSampleRate(176400u), 705600u); + PcmExport e; e.Open(SampleFormat::DSD, 2, params);