From fcfaa7affa0ac8afeaf38346226beb30fca09733 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 9 Feb 2021 20:32:50 +0100 Subject: Add setting for controlling ALSA periods to output module. --- drumgizmo/output/alsa.cc | 35 ++++++++++++++++++++++++++++++++++- drumgizmo/output/alsa.h | 1 + 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drumgizmo/output/alsa.cc b/drumgizmo/output/alsa.cc index 465b006..db7932b 100644 --- a/drumgizmo/output/alsa.cc +++ b/drumgizmo/output/alsa.cc @@ -58,6 +58,7 @@ AlsaOutputEngine::AlsaOutputEngine() , dev{"default"} , srate{44100} , frames{32} + , periods{3} { } @@ -104,6 +105,9 @@ bool AlsaOutputEngine::init(const Channels& channels) value = snd_pcm_hw_params_set_period_size_near(handle, params, &frames, 0); AlsaInitError::test(value, "snd_pcm_hw_params_set_period_size_near"); + value = + snd_pcm_hw_params_set_periods_near(handle, params, &periods, 0); + AlsaInitError::test(value, "snd_pcm_hw_params_set_periods_near"); value = snd_pcm_hw_params(handle, params); AlsaInitError::test(value, "snd_pcm_hw_params"); } @@ -140,6 +144,19 @@ void AlsaOutputEngine::setParm(const std::string& parm, const std::string& value << "\n"; } } + else if(parm == "periods") + { + // try to apply number of periods + try + { + periods = std::stoi(value); + } + catch(...) + { + std::cerr << "[AlsaOutputEngine] Invalid number of periods " << value + << "\n"; + } + } else if(parm == "srate") { try @@ -184,7 +201,23 @@ void AlsaOutputEngine::run(int ch, sample_t* samples, size_t nsamples) void AlsaOutputEngine::post(size_t nsamples) { // Write the interleaved buffer to the soundcard - snd_pcm_writei(handle, data.data(), nsamples); + snd_pcm_sframes_t value = snd_pcm_writei(handle, data.data(), nsamples); + + if(value == -EPIPE) // under-run + { + snd_pcm_prepare(handle); + } + else if(value == -ESTRPIPE) + { + while((value = snd_pcm_resume(handle)) == -EAGAIN) + { + sleep(1); // wait until the suspend flag is released + } + if(value < 0) + { + snd_pcm_prepare(handle); + } + } } size_t AlsaOutputEngine::getBufferSize() const diff --git a/drumgizmo/output/alsa.h b/drumgizmo/output/alsa.h index 7a7a315..96baf44 100644 --- a/drumgizmo/output/alsa.h +++ b/drumgizmo/output/alsa.h @@ -62,4 +62,5 @@ private: std::string dev; unsigned int srate; // samplerate snd_pcm_uframes_t frames; + unsigned int periods; }; -- cgit v1.2.3