• SONAR
  • MIDI "Jitter" - It Does Exist (p.36)
2007/10/19 17:54:39
Jim Wright
As Yoda said "There is another...." way to improve MIDI timing accuracy on a Windows machine. At least in theory...

Bear with me while I set the stage.
There are (at least) three major sources of MIDI jitter on a Windows DAW.

1) is any jitter that's contributed by the underlying transport (USB, Firewire, PCI). USB contributes at least 2 milliseconds of jitter, for reasons discussed above. Firewire contributes about 0.3 milliseconds of jitter. PCI - contributes very little jitter (probably 5-20 microseconds at most; depends on drivers, interrupt configuration, etc.). Anything that Both Firewire and PCI will be

2) is the nature of MIDI DIN. If you stuff too much data over the wire too fast -- you will get "MIDI logjam" effects, a.k.a. smearing. This happens if you do something like send lots of tightly-packed controller messages. It happens because MIDI DIN can only send 1 byte of data every 320 microseconds - period. Try to send more, and data will just queue up until the logjam clears. This "smears" the timing. Note that USB MIDI is *not* susceptible to MIDI logjam effects in quite the same way, because it doesn't have a built-in throttle limiting data transfer to 1 byte every 320 microseconds. However, this is only true when the USB MIDI -- does not have MIDI DIN jacks. If you are using USB MIDI to send data to/from MIDI DIN jacks (as opposed to a hardware synth with a USB interface) --- then MIDI logjam can still occur, even with USB MIDI.

3) The final MIDI jitter source is the infamous 1 millisecond Windows "MM" timer, which sequencers have historically used for timing MIDI data.



OK. Time to explain how it's possible (in theory, at least) to avoid the 1 millisecond quantizing/jitter effects.

First, use a PCI-based MIDI interface - not USB MIDI. This removes one major potential jitter source.

Then - don't use the "MM" timer to time incoming and outgoing MIDI data. This part requires kernel-level coding, but should be doable.

The standard Windows API calls for sending and receiving MIDI do not actually use the MM timer directly. I know some posts have said they do - but those posts were wrong. For example, the API call for sending a single MIDI 'short" message looks something like midiOut(driverHandle,midiMessageData). There is no timestamp argument in that API call. Instead, Windows tries to send the data "as fast as possible" through the MIDI driver specified by 'driverHandle'.

If you call 'midiOut' from user-level code, then it can take a while for MIDI data to actually get sent out the MIDI DIN jack (Windows has to do a context switch from user to kernel level; various kinds of house-keeping may occur....). But, if you call midiOut from your own kernel-level code, sending MIDI data can be much more 'immediate' - especially if you bypass some of the normal Windows 'wrapping' of MIDI drivers, and tickle the driver more directly. Plus, if you are running kernel-level sequencer code - you can completely avoid using the 1 millisecond-resolution MM timer. What do you use instead? A higher-resolution, kernel-level timer (several kinds are available, Google on QueryPerformanceCounter for one option).

Putting all these pieces together --- a clever sequencer designer might be able to build a kernel-level 'event engine' that a) runs at kernel level, to avoid various layers of Windows cruft; b) talks to the MIDI interface drivers more directly, to bypass still more cruft; c) uses its own custom-shop high-performance timer, rather than the stock 'MM timer.
Easy? No. But it might be do-able.
Does Sonar do this? No. Noel said (later in this thread) that Sonar uses the "MM' timer.
Have I built code like this? No. All my sequencer engines were user-level stuff (lthe last one was Win98-vintage).
Will this make a different with USB MIDI drivers? Probably not. USB introduces enough other slop that it wouldn't be worth it.
How about Firewire? Possible, but more tricky to do than with PCI-based MIDI ports (because of the Firewire driver stack).
My gut tells me that a PCI-based interface still provides the best shot at minimizing jitter, because it has the lowest inherent 'transport jitter' (PCI bus is very very fast) and also has the simplest driver stack (less chance for Windows to muck things up).

Whew! If you plowed through all that, you probably deserve a beer

- Jim

Edit: Noel clarified that Sonar doesn't use a kernel-level event engine. Frankly, building one would be a pretty tricky piece of coding. It would be even more tricky to make this hypothetical 'kernel-level event engine' perform reliably, given all the other stuff that goes on in the kernel. Probably wiser not to go there...

"The difference between theory and practice in theory is much less than the difference between theory and practice in practice." [Randal L. Schwartz]

2007/10/19 17:58:45
Noel Borthwick [Cakewalk]
Exactly. Internally SONAR always internally operates and stores MIDI at 960PPQ. This is by design since SONAR 1 I think. The PPQ setting in the project is only for display and edit purposes.

ORIGINAL: brundlefly

If you're just trying to play to tempo, using a lower PPQN is more likely to get the note where you wanted it and will impose less system resources to do so.


Okay. I'm officially taking a stance: This is NOT true.

I set up a new Sonar project at 48PPQ, saved it as a template, closed Sonar, restarted, opened the template, and recorded some randomly played notes from my keyboard. In the event view, the first four events were at ticks 37, 3, 19 and 10. This would correspond to 740, 60, 380 and 200 at 960PPQ. But when I changed the project to 960PPQ, the displayed tick values were 742, 73, 392 and 201.

Based on this, I feel it is safe to say that Sonar always uses a resolution of at least 960PPQ internally, so there is no value in running at a lower PPQ setting, except possibly if you like the tick values to have a smaller range when you are looking at things in the event view.




2007/10/19 18:07:10
Steve_Karl

ORIGINAL: Jim Wright

My gut tells me that a PCI-based interface still provides the best shot at minimizing jitter, because it has the lowest inherent 'transport jitter' (PCI bus is very very fast) and also has the simplest driver stack (less chance for Windows to muck things up).

Whew! If you plowed through all that, you probably deserve a beer

- Jim



Excellent post Jim.
I agree on a gut level about the pci bus, remembering the first few USB midi devices and all of the discussion about the same type of issues kind of engraved it on a stone wall, in my mind at least.


2007/10/19 18:14:26
Steve_Karl
Oh ... thinking of hardware, an other Midi Interface that has worked well for me with no 'noticable' timing issues is the M-Audio 2496.
I used it for about 6 months when in transition from the Voyetra ( isa slot ) to the pci-822.
I still have the 2496 but it's in a retired PC that doesn't get used for music anymore.
2007/10/19 18:17:44
brundlefly
Exactly. Internally SONAR always internally operates and stores MIDI at 960PPQ. This is by design since SONAR 1 I think. The PPQ setting in the project is only for display and edit purposes.


Thanks for the clarification, Noel. Guess we should have gone to you first!
2007/10/19 18:21:47
Steve_Karl
We can then assume that there is no performance benifit running at a lower PPQ? ... and that there is even a chance of higher overhead making the translation from the 960 base to a lower ppq?

Interesting. Just thinking out loud here.
2007/10/19 18:51:47
dewdman42
Noel, I don't suppose there is any chance you can tell us what timers are used for retrieving midi data from the midi driver or whether Sonar uses kernel mode stuff of its own to timestamp incoming midi?
2007/10/19 18:55:59
dewdman42
Given the above statment from Noel, there is absolutely no point whatsoever for ever running Sonar at a value lower than 960PPQN. If that is how it is always recorded and played back no matter what you have it set at, then you might as well have Sonar set to that value so that what you see in the PRV is accurately reflecting what is actually recorded in the track and being played back.

Perhaps while editing in the PRV you might find it convenient to be able to nudge notes around at a lower resolution, but in my view if that is the case it should be a PRV lock-to-grid feature. The current implication by the manual and where it is configured; that changing this setting will change the fundamental timing of Sonar. This is apparently not the case.

Further to that, I would really like more information about what actual timer is used by Sonar for retrieving incoming midi events from the hardware and how that lines up with this 960PPQN hard coded resolution.
2007/10/19 18:58:23
Dave Malaguti [Cakewalk]

ORIGINAL: brundlefly
What you're saying is kind of what we all thought/expected. But this is not what I'm seeing in my testing. Ignoring for the moment whether a given transient starts right on the beat or not, if what you say is true, the beginnings of transients should be at even intervals (i.e. all early or late by the same amount. But I am seeing differences on the order of 100 samples from the expected interval between consecutive events when rendering through the TTS-1. I just did a test with the Dreamstation DXi, and got smaller errors, on the order of 30 samples. So it seems to be Synth-specific. I have not yet tried a VST instrument.


I just ran through your test, and it definitely looks like what you're seeing is introduced by TTS-1. I was able to reproduce your results, although the variations in the spacing of the hits were extremely regular in my test.

Sample Position Interval
0
1297 1297
2703 1406
4111 1408
5519 1408
6801 1282
8207 1406
9615 1408
11023 1408
12305 1282
13711 1406
15119 1408
16527 1408
17809 1282


I then re-ran the test, this time using Twonar, which as Noel has mentioned is a very simple DXi included as a sample with the SDK. As you can see from the results, jitter disappears entirely in this case.

Sample Position Interval
0
1379 1379
2757 1378
4135 1378
5514 1379
6892 1378
8270 1378
9648 1378
11026 1378
12404 1378
13782 1378
15160 1378
16539 1379
17917 1378


You can download Twonar here if you want to check it out. I think this shows fairly definitively that the problem is not in SONAR itself. We'll take a look at TTS-1 and see if anything can be done about the way it responds.
2007/10/19 19:00:24
dewdman42

ORIGINAL: Dave Malaguti [Cakewalk]
We'll take a look at TTS-1 and see if anything can be done about the way it responds.


Awesome!!!!
© 2026 APG vNext Commercial Version 5.1

Use My Existing Forum Account

Use My Social Media Account