What kind of timer is most suitable for MIDI timing?

Viewed 183

I am writing a simple MIDI app for my own use, in C# and .NET 4.x.

I assume that commercial DAWs (on the Windows platform that is) use Windows Multimedia Timers for timing the playback of MIDI data. But I can't verify this, since commercial stuff is closed-source.

I'm hoping someone has knowledge in this area, and can tell me if my assumption is right. Or, are these DAWs using timers I'm not aware of? I want to make sure there isn't anything more suitable that I've overlooked.

1 Answers

Although I have not had the privilege of coding for commercial DAW projects specifically, I do have experience in coding for scenarios where the accurate timing of events is important, including MIDI processing/routing.

Your assumption is correct. Well-coded MIDI sequencers use the Windows Multimedia Timer to schedule the sending of MIDI messages to MIDI devices.

Microsoft's Multimedia Timer Reference actually mentions MIDI sequencing as an example use:

These timer services are useful for applications that demand high-resolution timing. For example, a MIDI sequencer requires a high-resolution timer because it must maintain the pace of MIDI events within a resolution of 1 millisecond.

How to use the timer is for another topic, I won't get into that here. But I'd like to point out a few things:

  • All modern hardware supports a timer resolution of 1 millisecond, it's basically a given, but you should still call timeGetDevCaps to make sure before calling timeBeginPeriod.

  • Using the multimedia timer, at 1 millisecond resolution, will have the effect of quantizing your MIDI messages to a 1 millisecond grid +/- some variance/jitter. In the vast majority of cases this is a non-issue because that is still a sufficiently fine resolution to provide reasonably nuanced timing, so far as musical timing goes anyway. If you absolutely need sub-millisecond timing, you will have to do as @iinspectable suggests - use the timer to get "close" and then spin to precisely time the sending of your MIDI messages. However, this approach comes at a cost. I don't know what your intentions are for the app, but should you have several simultaneous MIDI tracks playing, each with continuous controllers and pitch bend, you'll find your app spinning all the time and you'll peg a CPU core to 100% which is just plain bad.

  • Do look into Windows' Multimedia Class Scheduler Service to get prioritized access to CPU resources for your MIDI playback thread.

  • Don't be discouraged by comments from @iinspectable. You can absolutely do high-performance MIDI sequencing using C#/.NET. Your only concern needs to be that of the garbage collector unpredicatably pausing your app. You can always code in a way that minimizes GC (e.g. use structs not classes, don't create/destroy anything during playback). Also consider using GC.TryStartNoGCRegion to, for example, prevent GC pauses during playback.

Related