[alsa-devel] usleep() and nanosleep() timings seem inaccurate using ALSA

Carlo Florendo subscribermail at gmail.com
Thu Mar 29 11:46:38 CEST 2007


Good Day!

After studying the intricacies of MIDI, I ended up writing an 
implementation of the MIDI protocol and file format.

I then studied the ALSA sequencer API to be able to control a synthesizer 
keyboard and play MIDI files.  I've used aplaymidi, aconnect, arecordmidi, 
and all those great ALSA utilities.  They're very good!

However, I wanted to have a simple ncurses based, command line MIDI 
sequencer meant for small Linux distributions such as DSL or Trustix so I 
began to write a command line sequencer using ALSA.  I've encountered one 
problem about using usleep() and nanosleep() especially in 2.4 kernels.

The core of my problem in my application is that the MIDI files slow down 
their tempo when pitch changes are made on a particular channel/track, 
while a NOTE-ON event is being played.

For simplicity's sake, I'll give timing examples in terms of seconds and 
not bars nor measures.

For example, if I've got a 2 second NOTE-ON playing a guitar note, all 
timings are ok.  If the NOTE-ON is interspersed with CONTROLLER messages 
such as a pitch bend, the part which is supposed to sound in approximately 
2 seconds, sounds much longer than that.

The effect of this is that a ritardando is heard everytime short-duration 
CONTROLLER messages are sent.

The problem disappears when I use the sequencer queues.  However,  the 
problem manifests itself when using direct output (i.e. not using queues, 
using snd_seq_event_output and snd_seq_drain_output one after the other). 
The reason why I would not want to use the queue is that I'd want the UI of 
  my program (such as metronome ticks and counts) to somehow synch with the 
sound that is being heard.  I've tried removing all UI elements, thinking 
that the UI controls might have caused the delay, but still the ritardando 
effect persists.

The structure of my code is like this:

parse_midi_file();
merge_all_tracks_to_one_single_track();
normalize_the_delta_times()
for all events; do
    usleep(delta_time_for_each_event);
    play_the_event_using_alsa_direct_output();
done

The ritardando effect is a bit lesser using 2.6 kernels.  If I use queues, 
the problem disappears completely in 2.4 and 2.6 kernels.   I don't hear 
the effect with simple MIDI files, such as with piano pieces.

By the way, I intend to use my app with a 2.4 kernel.

Does anybody have a solution to the delay problem? Please point out to me 
if I'm doing anything wrong since I've just been working with alsa-seq for 
a few months.

Thank you very much.

Best Regards,

Carlo



-- 
Carlo Florendo
Softare Engineer/Network Co-Administrator
Astra Philippines Inc.
UP-Ayala Technopark, Diliman 1101, Quezon City
Philippines
http://www.astra.ph

--
The Astra Group of Companies
5-3-11 Sekido, Tama City
Tokyo 206-0011, Japan
http://www.astra.co.jp


More information about the Alsa-devel mailing list