summaryrefslogtreecommitdiff
path: root/drumgizmo/output
diff options
context:
space:
mode:
authorVolker Fischer <corrados@users.noreply.github.com>2021-02-09 20:32:50 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2021-02-09 20:32:50 +0100
commitfcfaa7affa0ac8afeaf38346226beb30fca09733 (patch)
treeac5982a5865583edf9843097dfd33861b1634e30 /drumgizmo/output
parent3dd3c332414bfbebd69bfd71a4a3198198525eb6 (diff)
Add setting for controlling ALSA periods to output module.
Diffstat (limited to 'drumgizmo/output')
-rw-r--r--drumgizmo/output/alsa.cc35
-rw-r--r--drumgizmo/output/alsa.h1
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;
};