On Wednesday, January 20, 2010, harryhaaren(a)gmail.com wrote:
I've been dev-ing MIDI/audio programs in C++ &
Python for a while, but I'm
struggling with one concept:
How to approach time. If i want to "schedule" events for the future, what
is the "correct" way to do this?
In my opinion, you can solve the problem very easily with a queue. For
instance, ALSA sequencer uses internally a priority queue. You put your
events into a queue in time order, and it holds and releases the events when
the correct time arrives for each event. Usually, MIDI APIs have functions to
manage event scheduling so you only need to add time-stamped events to the
MIDI queues, and the events will be delivered at the right times to the
output ports.
There are MIDI APIs that don't offer any facility for queuing/scheduling,
because they are designed for real time use only (for instance: RtMIDI.) In
this case, you have two options: use another API or implement yourself the
queue, and use a timer to extract the events at their deadlines. There are
many possible timers available. One of them is an audio stream: the count of
audio samples provides a constant time reference. This has a shortcoming if
your application is not audio-centric: you need an audio stream flowing, even
when your MIDI synths are always external musical instruments.
There are more time-related issues. Music has usually a "tempo" property
(speed), and users may want to change it in real-time. So you need to take
this into account when you are timestamping your events: it is better to use
non-absolute times, in order to avoid recalculations when the user changes
the tempo on the fly.
How does eg: Seq24, Ardour, RoseGarden etc approach
the time management?
Seq24 and Rosegarden use the well documented ALSA sequencer scheduling:
http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html#seq_ev_queue
An example is the utility 'aplaymidi' (simple SMF command line player):
http://git.alsa-project.org/?p=alsa-utils.git;a=tree;f=seq/aplaymidi;hb=HEAD
Regards,
Pedro