Loopy Pro: Create music, your way.
What is Loopy Pro? — Loopy Pro is a powerful, flexible, and intuitive live looper, sampler, clip launcher and DAW for iPhone and iPad. At its core, it allows you to record and layer sounds in real-time to create complex musical arrangements. But it doesn’t stop there—Loopy Pro offers advanced tools to customize your workflow, build dynamic performance setups, and create a seamless connection between instruments, effects, and external gear.
Use it for live looping, sequencing, arranging, mixing, and much more. Whether you're a live performer, a producer, or just experimenting with sound, Loopy Pro helps you take control of your creative process.
Download on the App StoreLoopy Pro is your all-in-one musical toolkit. Try it for free today.
How to make a solid MIDI clock receiver
Hey folks - in this week's episode of the Loopy Masterpiece blog I'm talking about my work with The Spectacular Sync Engine; specifically, how the MIDI clock receiver works.
Comments
Cool, I've done in the past a similar approach on a midi engine (bome's midi translator) to sync software and hardware gear. Although I use a different approach ( calculate the clock pretty much like you did but I send a simple midi CC or sysex tempo change,which my hardware gear recognizes and changes the bpm) ,eventually I had a lag when jumping to large values e.g. : 80 to 150 bpm.
The lag caused my patterns not syncing on different gear or software. So I simply calculated the tempo difference over time and added a bigger/smaller value to sync. Better give an example :
If the tempo changes from 80 to 180 ,I send a value of ~200 momentary and after a period of time I send the actual tempo ,to anticipate the lag and the other sequencers catch up...
Same thing when tempo goes down eg from 200 to 120 ,I send first a value of ~100 bpm and then the actual tempo , else the other slave sequencers would be ahead.
The rounding approach is very tricky when someone is tapping a button to define tempo. That leads to tempo values like 120,7 . So maybe using average but keep one digit would be a sweet spot.
Unfortunately I don't have experience on programming to actually help on coding, but I hope my post is useful .thank you very much for this project
Thanks for posting this. My set up is quite sync-drunk so your work is much appreciated. Cheers man.
Michael, have you considered applying an adaptive Kalman filter to smooth out the noise? The Kalman uses a stream of states (where you are now) and measurements (where you are next), and predicts the optimal (in a linear sense) next state which takes measurement noise into account (assuming Gaussian noise, but works well in other scenarios, too). It is pretty much the standard for GPS tracking, for instance. An incoming MIDI clock is not much different; you have the current BPM as the state, and the next MIDI clock received gives you a new noisy measurement.
I´ve had my first app in development for a (much too long!) time now, and I´ve always thought I´d use Kalman to improve tempo sync issues. With TSSE in development, I´d much rather see it implemented there!
@eivind_n: I like the idea of a Kalman filter, but a difference with GPS tracking might be the possible occurrence of stepwise changes in BPM, which may be difficult to deal with in a linear filter.
@Michael: thanks for this story. I follow the exact same approach, except for the rounding step: agree with @Korakios on this. Estimating BPM is one thing, making sure that source and app are in phase is another, especially in the presence of BPM jumps. I am wondering how you will be approaching this part of the sync challenge, perhaps in the next video ;-)
Yes, keeping a jitter-free and accurate beat position is the other important part, I assume he'll deal with soon. I think using a Kalman filter or a delay-locked loop (related to the PLL concept) is a recommended way to go. Check out this paper for its application in the context of an audio frame clock.
http://kokkinizita.linuxaudio.org/papers/usingdll.pdf
Sorry about the delay, folks Stupid inbox.
@eivind_n/@Marinus/@sonosaurus: I did experiment with a Kalman filter, but I just couldn't get it to perform as well as a decent sized averaging buffer! I'm a bit rusty on the underlying theory, so it could be that someone more versed in it could achieve better results, but I did quite a bit of experimentation with changing parameters, and it just didn't converge as fast or as well as the buffer (with a reset switch to converge quicker to changes).
The rounding's definitely not a perfect solution, but it seems to work reasonably well - note that I'm rounding to whatever is stable, so if it's an accurate-enough source it'll round to very high precision.