MajicDesigns / MD_MIDIFile

Standard MIDI Files (SMF) Processing Library
GNU Lesser General Public License v2.1
110 stars 38 forks source link

Help wanted: Sync with external midi clock #6

Closed nutrun closed 5 years ago

nutrun commented 5 years ago

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.

MajicDesigns commented 5 years ago

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.

nutrun commented 5 years ago

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.

MajicDesigns commented 5 years ago

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).

nutrun commented 5 years ago

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.

MajicDesigns commented 5 years ago

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.

nutrun commented 5 years ago

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