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