MajicDesigns/MD_MIDIFile

Help wanted: Sync with external midi clock

nutrun opened this issue · 6 comments

Hi,

I'd like to loop a MIDI file to an external MIDI clock.
Would you happen to have an example on how to achieve someting like that?

https://gist.github.com/nutrun/d129e4d8ddc33c2f183f77b4b95e8f41#file-external_midi_clock-ino-L55

Thanks.

No sorry, I don't have anything like that. This was asked previously and I think the previous person decided it was too hard (I did not hear back after a few interactions). The library allows the user to set the calling playing cadence so I think that the 'hooks' are there to do it.

If you do work it out, please let me know so we can include it as an example.

Had a closer look and I don't think it can be done without the library exposing delta time bytes, which I don't believe it does.
This calculation needs to happen on every external clock message received.
We could perhaps add a tick() method that track ticks when called on every clock message.

The processEvents() method allows you to trigger the library. It will then keep track of ticks using the number of ticks you give it.

Please read the library documentation if you have not already done so (html files in docs folder).

I've been using processEvents(), but I might be missing something, hence my original request. If I call processEvents(1) on each external clock message (which is what I think the docs suggest) e.g. here, the midi files I've been trying it with get played at 1/4 of the clock's tempo.

If I call processEvents(4), it plays the files at the correct tempo, but with a tiny lag when the loop goes back to the top (I'm in looping mode). I don't think the lag is performance related, because there's no lag in looping when I use the lib's setTempo() method.

I've tested this with various midi files and by sending clocks from a drum machine or Ableton on my laptop to an Arduino with the same results.

e.g. here,
The link is not documentation but some code, so I am not sure what your intent is there.

processEvents() is the right way to do this. There is no different once you hook in to that point on how the events are processed between 'internal' and 'external' ticks, just that you are bypassing the internal timing calculations so you need to pass in the right number of ticks. I am also not sure why you are perceiving a difference with the lag at the end as there should be no difference to the way it is processed (see issue #2 that has been previously raised).

My use of these libraries has been to simply play MIDI files on their own, so I am not really in a position to comment on how the external clocking works. This feature was put in after a previous user request.

Thanks for helping out. I'll let you know if I come up with anything. Closing the issue for now.