* how to handle buffer underrun in a softsynth
@ 2011-11-28 16:06 Henning Thielemann
2011-11-28 20:16 ` Clemens Ladisch
0 siblings, 1 reply; 4+ messages in thread
From: Henning Thielemann @ 2011-11-28 16:06 UTC (permalink / raw)
To: alsa-devel
I have written a software synthesizer in Haskell that fetches MIDI events
from ALSA sequencer and plays the rendered signal via ALSA pcm. However it
cannot cope correctly with buffer underruns.
I tried to learn the correct way from the miniFMsynth example of
http://alsamodular.sourceforge.net/alsa_programming_howto.html
however this program floods my terminal with buffer underrun messages
without even being connected to any MIDI event source. This is independent
from how large I choose the BUFSIZE constant.
I use:
$ pkg-config --modversion alsa
1.0.14
Also, as far as I understand, that program allows to start notes only at
block boundaries. This way it can ignore the timestamps of the incoming
events. But this is crucial for me: I want to allow large blocksizes
and thus I must allow notes to start anywhere inside a block.
Now when I detect a buffer underrun on writing a block to an ALSA pcm
sink, I like to know the time gap in order to adjust the timestamps of the
incoming MIDI events.
My question in short is: Is there an example software synthesizer as
simple as miniFMsynth, that works (on my machine), supports note start
within a block and copes with buffer underruns in a reasonable way? If no
working example, is there some documentation on how this is intended to
work?
Thank you for your help
Henning
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: how to handle buffer underrun in a softsynth 2011-11-28 16:06 how to handle buffer underrun in a softsynth Henning Thielemann @ 2011-11-28 20:16 ` Clemens Ladisch 2011-11-29 8:39 ` Henning Thielemann 0 siblings, 1 reply; 4+ messages in thread From: Clemens Ladisch @ 2011-11-28 20:16 UTC (permalink / raw) To: Henning Thielemann; +Cc: alsa-devel Henning Thielemann wrote: > I have written a software synthesizer in Haskell that fetches MIDI events > from ALSA sequencer and plays the rendered signal via ALSA pcm. However it > cannot cope correctly with buffer underruns. > ... > Now when I detect a buffer underrun on writing a block to an ALSA pcm > sink, I like to know the time gap in order to adjust the timestamps of the > incoming MIDI events. The sample clock is usually not synchronized with any other clock, so you won't be able to get a very exact measurement. However, there is a different way to approach this problem: just disable underruns. :) Set the stop_threshold to the same value as the boundary, and ALSA will no longer stop the device when an underrun happens.¹ This means that you'll have to write some data more quickly than normally to catch up², but the overall timing of the samples will not be affected. ¹ The device will still stop on fatal errors such as an unplugged USB device. ² Or, if you detect this case, just use snd_pcm_forward(); the samples that are 'too late' won't be played anyway. Regards, Clemens ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: how to handle buffer underrun in a softsynth 2011-11-28 20:16 ` Clemens Ladisch @ 2011-11-29 8:39 ` Henning Thielemann 2011-11-29 10:46 ` Clemens Ladisch 0 siblings, 1 reply; 4+ messages in thread From: Henning Thielemann @ 2011-11-29 8:39 UTC (permalink / raw) To: alsa-devel [-- Attachment #1: Type: TEXT/PLAIN, Size: 2063 bytes --] On Mon, 28 Nov 2011, Clemens Ladisch wrote: > Henning Thielemann wrote: >> I have written a software synthesizer in Haskell that fetches MIDI events >> from ALSA sequencer and plays the rendered signal via ALSA pcm. However it >> cannot cope correctly with buffer underruns. >> ... >> Now when I detect a buffer underrun on writing a block to an ALSA pcm >> sink, I like to know the time gap in order to adjust the timestamps of the >> incoming MIDI events. > > The sample clock is usually not synchronized with any other clock, so > you won't be able to get a very exact measurement. That's something I worry about, too. However I must somehow map timestamps of ALSA sequencer events to sample counts in order to let notes start within a sample block. JACK claims to synchronize everything and it runs on top of ALSA - how does it manage synchronization between MIDI and PCM? > However, there is a different way to approach this problem: just disable > underruns. :) Set the stop_threshold to the same value as the boundary, > and ALSA will no longer stop the device when an underrun happens.¹ This > means that you'll have to write some data more quickly than normally to > catch up², but the overall timing of the samples will not be affected. Ok, I am still uncertain whether this solves my problem. I think about how I can decrease processor load if I detect a buffer underrun. My idea was the following: Say, I have a blocksize of 10ms and got some events A, B, C, ... from the ALSA sequencer: 1ms: A, 7ms: B, 13ms: C, 19ms: D, 25ms: E, 31ms: F Now, when I encounter a buffer underrun, I want instead to render according to: 1ms: A, 7ms: B, 10ms: C, 10ms: D, 15ms: E, 21ms: F and play a 10ms pause at timestamp 10ms. That is I do not want to drop events (this might introduce inconsistencies) but I could save rendering a block and this way catch up with the emission of sample blocks. How can I detect a buffer underrun when I disabled underrun detection? Regards, Henning [-- Attachment #2: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: how to handle buffer underrun in a softsynth 2011-11-29 8:39 ` Henning Thielemann @ 2011-11-29 10:46 ` Clemens Ladisch 0 siblings, 0 replies; 4+ messages in thread From: Clemens Ladisch @ 2011-11-29 10:46 UTC (permalink / raw) To: alsa-devel Henning Thielemann wrote: > I must somehow map timestamps of ALSA sequencer events to sample > counts in order to let notes start within a sample block. JACK claims > to synchronize everything and it runs on top of ALSA - how does it > manage synchronization between MIDI and PCM? It takes timestamps whenever ALSA reports a period boundary. (This requires that the code doesn't run too late, i.e., that underruns do not happen.) There may be some DLL to smooth out the measurements. The timestamps can be made more reliable by using a recent enough kernel and alsa-lib, and enabling timestamps for PCM pointer updates with snd_pcm_sw_params_set_tstamp_mode(); then snd_pcm_status() will return both the buffer position and the corresponding timestamp. > How can I detect a buffer underrun when I disabled underrun detection? The avail value is larger than the buffer size. Regards, Clemens ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-11-29 10:45 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-11-28 16:06 how to handle buffer underrun in a softsynth Henning Thielemann 2011-11-28 20:16 ` Clemens Ladisch 2011-11-29 8:39 ` Henning Thielemann 2011-11-29 10:46 ` Clemens Ladisch
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.