diff options
author | Volker Fischer <corrados@users.noreply.github.com> | 2021-02-09 20:32:50 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2021-02-09 20:32:50 +0100 |
commit | fcfaa7affa0ac8afeaf38346226beb30fca09733 (patch) | |
tree | ac5982a5865583edf9843097dfd33861b1634e30 /drumgizmo | |
parent | 3dd3c332414bfbebd69bfd71a4a3198198525eb6 (diff) |
Add setting for controlling ALSA periods to output module.
Diffstat (limited to 'drumgizmo')
-rw-r--r-- | drumgizmo/output/alsa.cc | 35 | ||||
-rw-r--r-- | drumgizmo/output/alsa.h | 1 |
2 files changed, 35 insertions, 1 deletions
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; }; |