View Issue Details

IDProjectCategoryView StatusLast Update
0005352ardourbugspublic2013-04-06 14:32
Reporterkane Assigned To 
Status newResolutionopen 
Summary0005352: ardour midi clock external sync is not working
DescriptionMidi clock is not currently working as this post details:

Steps to reproduce:
1. open ardour, go to edit -> preferences -> transport, select midi clock as ardour transport master.
2. click the button beside the ardour main record button which toggles between internal and external sync.
3. connect my midi clock source (which i know works because i have it working with other programs) to ardour's midi clock in slot. 4. hit play on the clock source. ardour will respond and start moving. if i hit stop, ardour will also stop. however, ardour's tempo does not change (even though the source has a different tempo), and as such ardour becomes very off beat very quickly.
Additional InformationIn addition, on the ardour gui in the bottom right of the primary clock section, there is a little thing that has a delta symbol (small triangle), and then lists a number with the unit sm (samples i presume). This number will go towards -infinity when ardour has a slower bpm than the source, and will go towards +infinity when ardour has a faster bpm than the source - it appears that the delta indicates how far off ardour is from the source.

I spoke with las on irc and he said that after these steps he would consider midi clock broken. He also said it may have been because of the recent LTC and MTC improvements that midi clock was broken.

As a final note, my ardour3 revision is ardour3rc2.
TagsNo tags attached.

  Users sponsoring this issue
Sponsors List Total Sponsorship = US$ 10

2013-02-25 22:21: kane (US$ 10)
  Users sponsoring this issue (Total Sponsorship = US$ 10)



2013-03-01 19:11

administrator   ~0014667

I can reproduce this. It's not related to any LTC or MTC changes.

The documentation on is misleading.

Ardour will pay no attention to external bpm/meter settings. It always uses the tempo/meter defined in the Ardour timeline. Ardour does however chase external variations and follow smoothly.

What you describe is exactly what it should behave like according to the current implementation: Ardour counts "ticks" and accurately translates those to Ardour Bar|Beat|Tick only depending on the BPM/Meter at the given point in ardour's timeline.

It's a design decision which does not cover your use-case.


2013-03-02 21:27

administrator   ~0014669

Is there a good use-case for the current behavior?

I expect that the vast majority of users will want Ardour to follow external speed changes as kane describes. The question remains what ardour should do if the incoming MIDIClock's BPM does not match the Tempo of Ardour.

A) vari-speed external_BPM / internal_BPM: both audio-and MIDI would be aligned but ardour's internal Bar|Beat|Tick counter would not match the external BBT.

B) fixed-speed 1.0 +-DLL, but adjust internal Tempo: Bar|Beat|Tick are accurate (if the Metrum matches), midi-regions locked to BBT are in perfect sync, Audio and non-locked regions will drift.

C) fixed-speed 1.0 +-DLL, no tempo adjustment - what is currently done.

While (A) seems the best solution, it won't for for sync recordings because Ardour always records at speed = 1.0.
(B) is very tricky since overriding the tempo on the timeline is not yet possible.


2013-04-05 06:19

reporter   ~0014808

I think I fixed it, it seems to work for me now.
Note: For extreme tempo/samplerate/frame size settings it
might be good to be able to adjust the
filter bandwidth of the control loop.

You can pull the fixes from git.


2013-04-05 21:34

administrator   ~0014815

The large part of this issue as been addressed (Apr 04, 2013) with commits 985e3d..6f4736.

Ardour now chases external Midi-clock tics and vari-speeds along.

It works fine for small jack buffersize (tested with 64 and 256 fpp) and there seem to be some wow and flutter for lager buffersizes which is still under investigation.


2013-04-05 23:08

reporter   ~0014816

Please note that large buffersizes will probably never work properly.

The catch here is that ardour can adjust its transport speed only every
audio buffer block. So if that is too slow the speed will oscillate since
it will get too far if the speed is greater and lag behind if speed is smaller.

To vary the speed inside one block probably would need a huge rewrite of ardours
whole signal processing infrastructure.


2013-04-05 23:45

administrator   ~0014817


That's not it. Gradual speed-changes at e.g. 8k audio-sample granularity are not a problem and don't cause wow and flutter (well they might; but..)

MIDI message arrives in a different thread - not correlated with the process-callback. With increasing buffer-sizes the jitter on (t1 - t0) increases as well.

The DLL in the Midi-clock-slave is updated in the MIDI thread. So it can happen that in one audio-process-callback (t1-t0) is slightly larger than it should be and in the next audio-process-callback it is slightly slower -> wobble. The DLL does not flatten this: It only tracks Midi-clock speed-changes but does not align them to jack-cycles.

There are three clock domains and two threads involved.
  * soundcard A: audioi-i/o (jack process callback thread)
  * soundcard B: midi-i/o (Ardour evoral thread
  * the midi-clock source connected to soundcard B (Ardour evoral thread)

The MTC slave uses two DLLs to solve this.
In the case of MTC, one DLL is used to track the speed of the MTC signal (in the MIDI thread) and the second DLL to align the absolute timecode (in the audio-process-cb thread). The difference "MTC position in midi-thread" vs "transport pos in audio-thread" is then used to flatten' (filter) the speed (see speed_flt libs/ardour/

I'm not exactly sure how to apply the same concept to Midi-clock since there is no absolute reference point.


2013-04-06 13:29

administrator   ~0014823

there is no "Ardour evoral thread"


2013-04-06 14:32

administrator   ~0014832

OK, the terminology may be wrong but the fact remains that

SLAVE::speed_and_position() is called from a different thread than

The latter events are bound to port->parser()->EVENTNAME.connect_same_thread(..)
and the former is called from and

I did not trace it, but just printed thread_id's.

I now think I had it the wrong way 'round :) MIDI arrive in jack-process callback, speed_and_position() is called from the-thread-that-shall-not-be-named...

Issue History

Date Modified Username Field Change
2013-02-25 22:21 kane New Issue
2013-02-25 22:21 kane Sponsorship Added kane: US$ 10
2013-02-25 22:21 kane Sponsorship Total 0 => 10
2013-03-01 19:11 x42 Note Added: 0014667
2013-03-02 21:27 x42 Note Added: 0014669
2013-04-05 06:19 hansfbaier Note Added: 0014808
2013-04-05 21:34 x42 Note Added: 0014815
2013-04-05 23:08 hansfbaier Note Added: 0014816
2013-04-05 23:45 x42 Note Added: 0014817
2013-04-06 13:29 paul Note Added: 0014823
2013-04-06 14:32 x42 Note Added: 0014832