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