From e2a74051dc5c1240aa98395dffea89c3138638bf Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 26 Oct 2017 12:13:00 +0200 Subject: [PATCH] lib/alsa/HwSetup: return effective parameters --- src/lib/alsa/HwSetup.cxx | 27 ++++++++++++++-- src/lib/alsa/HwSetup.hxx | 9 ++++-- src/output/plugins/AlsaOutputPlugin.cxx | 42 ++++++++----------------- 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/lib/alsa/HwSetup.cxx b/src/lib/alsa/HwSetup.cxx index ddb4f72b7..96a40f17f 100644 --- a/src/lib/alsa/HwSetup.cxx +++ b/src/lib/alsa/HwSetup.cxx @@ -176,11 +176,14 @@ SetupSampleFormat(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, return err; } -void -SetupHw(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, +HwResult +SetupHw(snd_pcm_t *pcm, unsigned buffer_time, unsigned period_time, AudioFormat &audio_format, PcmExport::Params ¶ms) { + snd_pcm_hw_params_t *hwparams; + snd_pcm_hw_params_alloca(&hwparams); + int err; unsigned int period_time_ro = period_time; @@ -285,6 +288,26 @@ SetupHw(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, if (err < 0) throw FormatRuntimeError("snd_pcm_hw_params() failed: %s", snd_strerror(-err)); + + HwResult result; + + err = snd_pcm_hw_params_get_format(hwparams, &result.format); + if (err < 0) + throw FormatRuntimeError("snd_pcm_hw_params_get_format() failed: %s", + snd_strerror(-err)); + + err = snd_pcm_hw_params_get_buffer_size(hwparams, &result.buffer_size); + if (err < 0) + throw FormatRuntimeError("snd_pcm_hw_params_get_buffer_size() failed: %s", + snd_strerror(-err)); + + err = snd_pcm_hw_params_get_period_size(hwparams, &result.period_size, + nullptr); + if (err < 0) + throw FormatRuntimeError("snd_pcm_hw_params_get_period_size() failed: %s", + snd_strerror(-err)); + + return result; } } // namespace Alsa diff --git a/src/lib/alsa/HwSetup.hxx b/src/lib/alsa/HwSetup.hxx index fbf6641a9..62cfb7711 100644 --- a/src/lib/alsa/HwSetup.hxx +++ b/src/lib/alsa/HwSetup.hxx @@ -29,6 +29,11 @@ struct AudioFormat; namespace Alsa { +struct HwResult { + snd_pcm_format_t format; + snd_pcm_uframes_t buffer_size, period_size; +}; + /** * Wrapper for snd_pcm_hw_params(). * @@ -38,8 +43,8 @@ namespace Alsa { * by this function * @param params to be modified by this function */ -void -SetupHw(snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, +HwResult +SetupHw(snd_pcm_t *pcm, unsigned buffer_time, unsigned period_time, AudioFormat &audio_format, PcmExport::Params ¶ms); diff --git a/src/output/plugins/AlsaOutputPlugin.cxx b/src/output/plugins/AlsaOutputPlugin.cxx index 68f70672c..4f829fe21 100644 --- a/src/output/plugins/AlsaOutputPlugin.cxx +++ b/src/output/plugins/AlsaOutputPlugin.cxx @@ -392,38 +392,22 @@ inline void AlsaOutput::Setup(AudioFormat &audio_format, PcmExport::Params ¶ms) { - snd_pcm_hw_params_t *hwparams; - snd_pcm_hw_params_alloca(&hwparams); + const auto hw_result = Alsa::SetupHw(pcm, + buffer_time, period_time, + audio_format, params); - Alsa::SetupHw(pcm, hwparams, - buffer_time, period_time, - audio_format, params); - - snd_pcm_format_t format; - if (snd_pcm_hw_params_get_format(hwparams, &format) == 0) - FormatDebug(alsa_output_domain, - "format=%s (%s)", snd_pcm_format_name(format), - snd_pcm_format_description(format)); - - snd_pcm_uframes_t alsa_buffer_size; - int err = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa_buffer_size); - if (err < 0) - throw FormatRuntimeError("snd_pcm_hw_params_get_buffer_size() failed: %s", - snd_strerror(-err)); - - snd_pcm_uframes_t alsa_period_size; - err = snd_pcm_hw_params_get_period_size(hwparams, &alsa_period_size, - nullptr); - if (err < 0) - throw FormatRuntimeError("snd_pcm_hw_params_get_period_size() failed: %s", - snd_strerror(-err)); - - AlsaSetupSw(pcm, alsa_buffer_size - alsa_period_size, - alsa_period_size); + FormatDebug(alsa_output_domain, "format=%s (%s)", + snd_pcm_format_name(hw_result.format), + snd_pcm_format_description(hw_result.format)); FormatDebug(alsa_output_domain, "buffer_size=%u period_size=%u", - (unsigned)alsa_buffer_size, (unsigned)alsa_period_size); + (unsigned)hw_result.buffer_size, + (unsigned)hw_result.period_size); + AlsaSetupSw(pcm, hw_result.buffer_size - hw_result.period_size, + hw_result.period_size); + + auto alsa_period_size = hw_result.period_size; if (alsa_period_size == 0) /* this works around a SIGFPE bug that occurred when an ALSA driver indicated period_size==0; this @@ -435,7 +419,7 @@ AlsaOutput::Setup(AudioFormat &audio_format, period_frames = alsa_period_size; silence = new uint8_t[snd_pcm_frames_to_bytes(pcm, alsa_period_size)]; - snd_pcm_format_set_silence(format, silence, + snd_pcm_format_set_silence(hw_result.format, silence, alsa_period_size * audio_format.channels); }