Looking for "better" tap tempo abstraction
I’m looking for a tap tempo algorithm in Max that does better time detection than the examples I’ve found. In particular, I’m looking for something that can both lock in to a tempo quickly but yet be able to adjust as I tap without taking too long to match my new tempo but not be too jumpy. I’ve played around with the examples, changing the number of taps being averaged, etc, but I can’t get it work nearly as well as the tap tempo detection that I have on either my Korg Oasys or on my Boss Digital Space Echo (which seems to work even better than the Oasys). On these, I can let them free-run but if I start tapping, they very quickly adjust to my new tempo with any sudden changes. I suspect they’re using some non-linear weighted system for adjusting the tempo based on "recent" taps.
Anyone know of a more sophisticated tap tempo system for Max?
"more sophisticated" than what? You don’t mention the method you’re using; I would suggest [timer] followed by some [zl] objects for averaging, like this:
----------begin_max5_patcher---------- 743.3ocyXtrbaCBEFdsyL4cfp0tNbQWvcUeJ5lNY5fkINzXgzHgacRl9tWIH xwwQRFYKYrWXFN.he93bNBzq2dyDuEoa4EdfuA9IXxjWKsLQaqxxjZCS7RXa iWyJzczKgWTvVw8l9ViJ9VktAzNSOjJURVBWa9G77kLIaWixMIB4ZtR+zv6O jBwK5gfPyf606zMp5tipMarodNiaDumG3951DK0ya5he+Uh+toMioheTHW8q bdrxLH774kSD.YJH3YAkUnyff60i4e2dSUYYwTqgyhMJUpr40JpuqoEL4plW W3HKVWXey5BV++Yrtj7+VNuedOOgqxSAHHD7cVrR7GNvodAcPLa7DvXesCAN RWabPVFK9IfnhYWewKnNozbpFKzvphP5Hxn0BI+DnCoezA2Ncl1JgHGmPDBo pvOb.HTbZRBWp9LhJJ8i3KX4m.lP8CSvlv.tKLfB0wQT8+Q3wDCJVFXQVhin .paJnW4jH5fgg1hWtCPFrjI39mLQTtyzXzB0hzIFeEhIAL5rvSqGMgF4R7zL al2IahLtNZpDhLGSYTbcdYMnXSxkv+4TR2144blaBoHZ+HiazY5.0AjVkmtI 6ZESgVfInIaLY.vzE5TtQVr6izYrG2C49k6.gvxeybYRjGVmxZIKaDxBNQ0b JBMhQIJQBO2kAHFF0dTB0BNEr+Y2FGNUvWWdaSWBJcLWqbJ33XhpoT.bDozS 7mOADA6Gh767LMSapnQj4ebjEnC8BiZEYlGr9tOG9IYzOT8kh9HHKR2jGWq3 5O3A.9tDWxKTBISIJSW+duvGzqGEKWxke.eIhkYokK22TRW6uVKtp74GWbjd KNDDo+zM9jpBBjtq1fH6pzFVxTzoHayqj8Qg6pMHxFamqPjSbEPVItpKa6.w Y09MxMwPGhjlE2795KNLw2HazVnax8XiznNQZg1HM2DlFXkzhtheahN4M5ZV bNvgypDbGFMegDmUuXH3rkVkgxh+CP4grOG -----------end_max5_patcher-----------
The minute fluctuations in timings between physical taps WILL create jumps, unless you use some heavy-handed interpolation – which will introduce a delay. Maybe add a [line] at the output?
EDIT: added a synced beat generator
I had looked at (http://www.cycling74.com/forums/topic.php?id=23813) and also at jb.taptempo (http://www.greyfade.com/joe/maxmsp.html)
They both felt like "engineering" / "mechanical" solutions but neither of them "felt" right, at least compared to the way tap tempo works on the instruments and devices I mentioned, both of which I’ve used in live situations with a band and was able to easily sync my sequenced arpegggiators to the drummer. There were no noticeable jumps nor was there any significant delay.
I’ve done a little bit of reading since posting the question and as far as I can tell, it’s not sufficient to just take the moving average of some number of taps. The articles I’ve seen seem to have some non-linear (weighted) bias as well as some beat prediction capabilities.
To paraphrase the judge, this is one of those things that I know what feels right but I don’t know why.
I’ll take a look at your patch when I’m in front of my computer later today.
then perhaps my ‘solution’ is a little simplistic for your needs – no weighted bias or predictive capabilities, just some averaging, but with the [zl] and [line] objects it works for me.
sorry to disappoint :(
if you keep this thread live over the next week or so, I have no doubt that a maths guru will jump in with some [expr] or other function that does what you need……
-average the first N timings
-accept subsequent timings only within that measurement
-set new tempo only after N measurements are completed
First of all, you’re not disappointing, I truly appreciate getting responses — sometimes such dialogs help guide towards solutions.
Nor am I suggesting that such things as "weighted bias" and/or "predictive capabilities" ARE the solution, it’s just that as I look around, I’m seeing references to such things.
Now, I just had a chance to play with your patch and as it turns out, your timer triggering that metro actually seems to work quite well EXCEPT that as I manually tap, I think it’s generating both the automatic beat as well as my tap, so I get two taps close together.
(By the way, I’m less interested in actually seeing the BPM value, than just getting a smooth beat that’s responsive to manual tapping)
Again, ah yes
I overlooked that bang duplication;
maybe a simple [onebang] with a small delayed reset, c. 5-20ms, off the top of my head?
I have found success with the [zl stream] object with the [mean] object underneath it. Using an argument of 3 or 4 is pretty smooth comparatively.
How does this compare to the tap tempo in the sync~ object, does anyone know? Can these solutions be used to affect max’s global tempo setting?
Hey, it’s been a while but I’m going to stick my nose in here. As a DJ, I am looking for a similar solution. Basically, I am looking for a super intuitive timing belt type device that I can use to sync Ableton Live to live performances and cd’s with the flexibility to allow for drift.
Ultimately the goal, I just sit and tap quarter notes into the thing and it does whatever necessary to stay with me. However, if I stop tapping to sip on a martini, it keeps going. If I feel the groove lock, and I want to mess with some other effects, I can stop tapping, but if it starts to fall out of sync, I can just start tapping away and it adjusts to match.
My first attempt (involving averages and differences…etc) only led to ableton oscillating around the tempo of the song and rapidly going buck wild…one tap it’s going 32 bpm, next tap 500 bpm. From there it’s just a crap shoot and sonic destruction. I see it only as a great way to end a set…
But I digress. I"m seeing a few major components to such a system:
– detection of good vs mistaken taps. If mistakes get filtered out (like 1/2 way between a beat) then junky data won’t corrupt your tempo.
– some way to detect consistent differences in timing which don’t mean a change in tempo (constantly 10 ms behind the beat doesn’t mean slower tempo, it just means slow down and speed back up when you’ve added 10 ms delay.
– What to do when you stop tapping…if the user stops tapping when it feels right, there might have to be a final adjustment to keep the system in the groove based on all of the previous data.
– some system to keep it from drifting to the wrong downbeat while trying to correct.
– of course, how do you recognize an accel. or rit. and work that in? Also, what about a sudden a-tempo which is bound to happen as well.
DHJDHJDHJ, I think that is closer to the core of what you are asking, and I have been asking that for quite some time now. I wish I had more facility to answer these questions, and unfortunately due to my current work, I haven’t been able to devote much time to the problem, but maybe collaboratively, we Max/MSPer’s could come up with a solution. Any thoughts?
It might be an idea to limit the range of possible right answers to something within 10bpm of the current tempo or manually enter an initial idea for tempo. That way you could stop your patch outputting stupid numbers like 500bpm or 32bpm so limit it to your normal working tempo range which for DJ music tends to be an extremely fine range with many DJ’s never going much more than 5BPM either way – a tempo range of 118 to 144 would probably cover almost all techno, house, club DJ’s and it would be easy to have HipHop and D’nB modes for those working outside that tempo range.
Final adjustment could be done with a nudge function – basically a line to the transport object that speeds up/slows down the tempo and the reverts to the original tempo when you let go of the button – so a 1 from the button starts the tempo ramp and a 0 from the button stops the ramp and resets the original tempo.
Instead of or complimentary to your use of a tap tempo solution you could look into bonk~ and MIDI Clock.
I haven’t built a tap tempo (outside of the one Brendan showed you) but if I was going to this is where I would start – weighting, analysis, MIDI syncing and fine control.
-- Pasted Max Patch, click to expand. --Copy all of the following text. Then, in Max, select New From Clipboard.----------begin_max5_patcher---------- 1793.3oc2assjahCD8Y6uBEprUkI6jIRhKF121Z+E12RRMEFK6gDLPAxSlro x+9htfML.xBaLFm4A7ftQ2mt0QsZD+b9LikIuPxM.+E3SfYy947Yy3EwJXl7 9YFa8eIHxOm2LifjsaIwTi6E0QIuP4kGmPI.5SDPQCR8yByShA46Vl5SCdhj U17nvXRPxtXdeLkEtNIllG9eDVYH7CPYw7tFFu4wLR.UHh1HXQ0.rsM6mE7q VtO.AeQ1mvUbgIY4W+foS4CMd21v3HBkq.nJOzX+s7GpwemE5GUo4I6nksGx J7WymytbulXTL46ERPCHhBPO.VWVr3YP+QJQnaFqiR7Kv0x+YuNoO7XJPDjs G6GyEbrB1A7XOHvC9Dfmtbgn9oF8VmwVbWBSG9Oha5TmstZtDcoyAQgAe6yw 8WuQN15q2lSsoBEd3q1RxyKTR3CcNi3TlCX4BOvM35oDVvCBrfFP2g+nf9Li oLgImfOgIR3SXInGcTp7nI2bgs4.RVVR1In3lB+eWth6fTp3vqlhWPrWLHGe Afk9waNI9eOXE6u.L5BFvKtZ7+cvI7dfBpfydMQOIc4C1Jvj1CY.OBDBcfIj WRy.ucMB7Qv6d6Z76w2A9S.ZPILKcZDbGHrkRuF6qFB0EqA5NPN0OiB1RnYI .zmiw0KA+4Xy6.emo4r.T2Bx+Qbv.EPpb4WwUDRY.o3oWzGTx1zDiSMLbDjq u1Ji8.e8h8X4NJ8vxnMlrTmkssPKw1UVUQrbJ6Zqpo5kSOe2+yUYP1P8UF3E VYnIa1DQ5TYBioJ0EKgimz+yxp7Za5Bx6BqKcvby4dzzb0inaEprzyzRYfNH 2qFW8YZekrp5Yes9cx9J0b8rulWM66HEHaIYkxPRP3oVfroUxA1EHfVup4.y 0TE1zN2mYe8PpJLjLIfHQjhgILh7LIKmsk0CsdlgeZZkhmUoKLX7qI7Ax998 EEFKJBsunLxygk82STXgwYdYk6CGwBKB+RDKlHWH77.ThIEFxMQIAeivgFXY gqHq62njjRhOzCdKpcodKCiSyH4Ewc4SkJQ0mr+tH5isa1qW+Z+.RmctU62L iMYgqRhYBQsdxJt7wwBIPjsvpxMuEw9oszYZRRzR+LlIYYDolotXZheb3VeJ gFJjGLbe+B2llEJBvdeYjX+hw3o7frjnnZCknlmaolUEdCAjuGth9DerNfV0 RhcU+rpSfqUtJ9r9vooXtaoSc31hQlMqCVuF+WJqwAVuJEQ7fgsGwciH3vUU l1HFUy.zEA4rRRR4bwSDuqQbVm77Mer.oJ9SownZ.DGyDn.ME3ns0QQSTmnI 9DQSz3flT.Dr7nPYe8paauRhkiLgxLPcTHEdq5fRA3QBRw8CR2uSmaNHcSwB G.rRLkAnC.XJcSs7NJXtXvmxORfYkznpSjmmBVV6Ut4zHkpMvRmaW5yk.jZz jOK+9A.UKS.qXQolu71Fnp8sKC5RvGFKXEu.VAVati5NymvzDVYuzT+MjVwU jZFzyw2TlVBwdiLwrY7HWEf3Ma.SqHQ9+nH.a3w8NOe7DIdW0NlGyozcRCmb oouK4zcX4k42n7ZWfR2qPC6VsqTS4KEQbLLRB9FP75PFIRvhMJmo2NNGh0pE uf7iG2i8jNrGwvZnmJ6UY2c1VcqxlZQ3+pWGUG9QFi5zplzPJhq.Zq2zJ7.N s5e8SmfHRYHA5hHnADQ9GFQSaXxgTvwdkzcjMKtxvpucvJOYWVPITHskf5p0 JRNMLdeBI+zgXIeUCeJb0p5I.TjOqUoIE6uUJefunk0suhMWbP5H2NMZ3UWt 0AucmdvsVtIKlVvsths0zBtstQ8tstM8tstM8twnd.2SGwdglRMFOo7Rv5tT YKlkqp2smljISqU3Yo+WawFMsDas4RNA3F6Xwxsho7TXh7ZdGVb5dwlV6u6R 5acQ0Vyoj1pKyUKvxUkAXglSkZw48pJ2nKr20kRtczTtMmThs1w36LoDaWcE 6gbYYYgkm0Hib+mIqdr3wPBnO5SoYgK2QE6Qu1AgpsCqyk5D9nnpic3h1Dkr zORdZt1OFFyOfBSriCnk3i2P9Iuo97l6N0NMfu4irC3y9WnvQNMr8GTLsa+P rzVpx+86jhZITbs9TDbFbWC9SodB6Dfxqo4jPSy.JqQK20B20V.rIuV6bZML T5JSHrNxj8nJSt5JRnQSjL0xz4LpvjYcHPgLglTlNyd5MYC4aG.4I9z.vNsb m7.o4Zs+tyEb0Ydw3ZueEyvv3CZ5I1G1Br36BDINOJUuC4VCbcOev8UBYGA4 YNpdtHScPW33RNqESHZ5ISdiqoySG2I2I2ZXH29ASRhPLxl8ik7yalc2YJrN ZZRwimI0RWFB3zhgvaTEIsb7wipHoiuz3FhqNKadNjCE27q4+OjOtT9D -----------end_max5_patcher-----------
I thought a bit about the problem, and I cooked up this idea. Note the subpatcher. It doesn’t measure tempo. Instead, it takes two out of sync metro objects and syncs them up. Of course they have to work at the same tempo, but this can provide final sync once the tempo tapped is established. This could aid in solving bullet 2 of my point mentioned before.
Audiolemon, that is a good point. It is important to differentiate between half note and quarter note pulses. Is dubstep 140 BPM or 70?
Another thought, which I’ll explore next time I work on this problem, is how does the function of taps affect the clock depending on how many taps have been performed? I expect my first few taps to be out of time, and wouldn’t want tap #2 to trigger a skip, but if I’ve been tapping a while, I would want to have good enough response to lead a ritard, accelerando, or even an a-tempo.
My advice would be to avoid rolling your own and instead look at some of the results from the Music information Retrieval world.
Tempo tracking is hard problem , so it’s worth looking at expert solutions. There’s always knowledge to be gained from trying to do it yourself, but for sheer efficacy…
Will try to post some links this week.
Peter, I agree. It is always easier to follow a recipe someone else has hashed out than to work it out yourself. I would take that advice if Ableton’s tap tempo function wouldn’t spin out of control so easily. At least that’s what I’ve experienced with it.
I tried combining my shifting abstraction with a kind of ZL filter presented by N00B_MEISTER earlier. It feels good. It averages to your tempo, and then will slowly shift in sync with your taps. However, on extreme jumps it will still oscillate around tempi a bit before it averages in. I think the problem involves how many beats to average in your tempo calculation. I am averaging 16 taps, which leads to a very sluggish tempo change.
My next thought is to have Max analyze the curve created by the series of taps. More on that later, time for breakfast.
I’m looking forward to these MIR sites, never knew that existed.
You might also look at a median filter. These are good for this particular type of situation because they ignore outliers.
(use zl.stream 7 -> zl.median for example)
I didn’t think of a median. I never tried that. I’ll have to check it out. Thanks man!
Just be sure to account for the difference between odd-numbered and even-numbered medians. (odd-numbered will always output a value in the input set; even numbered will output the average of the two center values)
Median filters are also really great for threshold detection tasks. Unlike averaging filters, they can jump to a new value faster.
Anybody have an example of using median? Anybody find links to good algorithms?
Very interesting thread–wondering why it died out…. I’ll have a look at the posted code at any rate.
Thanks to notifications…this thread is never dead…
ZL has a median function. Type "zl median" in an object to get it.
This patcher I made in a few minutes generates a random list over time. You don’t need to sort to get the median. Happy patching!
-- Pasted Max Patch, click to expand. --Copy all of the following text. Then, in Max, select New From Clipboard.----------begin_max5_patcher---------- 719.3ocyXtsiaBCDF9ZxSwHto2rMBavjPuqOGsqpHfSVuErSwFsmz9tWefbn YSpLzH2HEAxiO8OeLdrcdaVT7JwyTYL7E3aPTzayhhrlLFhFJGE2V9bUSoz1 r3JQaKkqhuyUmh9rxZugIUPsfJ4eRAbJsFTBXEEjhNEs967WafVZMqjCLInd fBskaXUvShNck8a2R6.ope8ZS0O1qGKc22PUvKhdnD9UOq5mfcNDqgtRdsnE 38sqncx46zRCiSqD8bqfxFLpaDi2PUV0iFLtsTU8.iu4GczJky6QKSlmbGfW RLuPEXyqb8S39gNsVvUR1qT6.Ypd+DH5U6lgcVY0VpHV83mQKhOZD3ks1QH9 qcrxlXSEuOal4wcd9Ev41wiz+HDmigstIw4rIi08vCVclTurk5F8XlIj.hWU x2DueHOFB4WWHzRkxxMzODFRvyImEM3KilrBKZRyHGPCZ4XQC5Rn477fb6xi zhjvyirq7hD5S5g8C3XeVnwxDB53zC43q7xGyZmyykzaatLDqDdtfCy5mbHk ncRHCC4oleKxgB7XozBWtW2VLYIKBwJph.AnzA7n4jAMF.kmNQ.QBIfV9+DP .NahLBGRFsHTLZZvnHjr3JeBlU8JkfO5iw41GJe+42NIcqmN3EOmF45toxiB 1T2pcWfNJTaoDrSfHaXUT3v0BFKXbYIySCEXB1QPL2UbpPYXu0fAEbPfxvMc QIISjKtLjtrkiGKn+108N6wx7iJ1tZuu9I+2CVGwX+OQkTz2Usat2ccR3fyT SkJFuTwzITOzHcbKf12lGX00T9w2QukUuUmeRMnA39y9cyWIk5ghVdyoH7ez laAEkMNFQPEyI5d3BwItz.mTBkYKo2JgLT5ezOx7L561hrnv9wF4klHAcIwI H3BZJKnZxKIE1nIejTQPgjOq3VD1PIOTTdPUDwm.ovlBvy78SUQ5BuO62DD8 rdF -----------end_max5_patcher-----------
If you’re wondering why I disappeared…well, life happened, but I am still working on it off and on. I am no longer djing…but I am a published composer, so I am transitioning toward electro-acoustic work. So this means I still have an application for the tap tempo algorithm, but I need to make it much more robust…For example, taking a live performance and extracting the tempo & downbeat from subtle fluctuations in velocity and a variety of rhythms. But that is WAAAAY down the road right now, so this particular problem is on hold for me.
Here’s a simple tap-tempo abstraction I use often. It’s the basic approach outlined at the beginning of the thread. The one change I’ve made is to sort the list of timings and throw away the highest and lowest values before calculating the average. This helps to deal with spurious values. I’m using mean here; will play with median soon.
-- Pasted Max Patch, click to expand. --Copy all of the following text. Then, in Max, select New From Clipboard.----------begin_max5_patcher---------- 1581.3oc6ZssqiZCE84juBKdpUJSD1ABj9RU+NFUEY.eR7LFCBLmKyn4eu9B j.DfCIgPSkZdfj3ar7hk26s2letbgUPx6jbKve.9JXwhetbwBcQpBVT9+EVw 32CY3bcyrRJDLhvZkopbwGLht7pR3EwTtrE5VCKKjFY5av29xF2ZszLX5lZW VZJVDdjxOrOiDJL.Ct0cs8JvFG8WnSWA+cYeBShiIbcqsD3zTRDPPhSS.TNH HM1R0pesbo5xpQNM4j2jnsBpBx6lQ+3w0w4H0XVViYFH9HkXvp0KrDrrsUP6 kDtHm9CcsPzZ6am2rspMjbbro6+UFEy5lQgeJih70e4sQ+GjhQuAp5dUDnqW Q3cGBh37ITODSv7OQJrBXQ48nH1cGBBH7ZEDnOiPQN1ZdUqGf6tQ8fF08RJm IhOYJae4Td2UKzQFwwF6QHTxI7bpf9JU7A32b9xetBDQdAWvD.ue+VjLUica MC9URF9.AHNR.Yjbg0TKLtVcwPld2TWX3sUKL7tQgQeDh3XVxa.7a3OzbxQ5 giRZAf4Q.VxapeJwa.IKepYJzDxT6flEMH8W9N2ES0i0lev.jPJKG.6e40p5 KwtIhBcIQ4LglZ1XnFeEd.tv6xTS+7TNiFRlcdxcx4IjNngGHOkjIlYRZ6zK l15osx69nHIQFAGC7lYhxa5IJGiZ5NIJs03AIi.L+vYBIEmIQufjsmvwAFVv tFOGlvRxL8V6m47EXMe0ikVCNzX772J+3spyeUe3kSQZbQrlGssqFd4SnpRO g3LZiafm6pFWqOnc5A5X6Qv2.Jj5Jxo4HHaadHtjyVuqC28SpwYix.AebqmB .ndkNZYyExmIKvnsSNSs0Waj16QPTofvzBAMdfkZCsYS3Z2ctPoz5VM+.8lv cbZnqcFRyDSYcUttGjrRRpjkj2XJiHiVNmlvqM9KrjaoqVwKp0EE09MyJqxY tYQroH6SEkQdkV0emSkhyj3VHAcQlYx9teklQMLIQjLdAUCESgxGxKqFvpop qYeFPeSnf6zhCzFuySWkMJVR32IQ0AkURJgS4ox8DHiRFKJQ2opK2Mx9AdJ2 rQufCI8NBc97bg0gLZTBWgjFDtp3p6obWAlIna8YjtEbbZGcVJljjSOUlKmo E4A3L0yiReCnpJEIIrlUcpeLxKhxpSobdKpTjj1ekYxMXLPeCRjUFOzXqqIe eA2T6d4JYw9b495Z1NLiUtzt4v+NV5SAKHp01ktappz3e7XdXVBi0X9Zp40N pIRJkCIuQiDGMNIp87V1bZZkRx5zS4H5A0FOaTl.eHuYIWXxPVTQP4R08pDp vjyhlMnQ9DqutrtQvFkOT1j5AF8YruucB2+N49jvkJyL1E4M3hbGP4xnadEy LIXBPyk6rOUFZMIBH4JhUUuzdFJMbbiDTCuEscs1XF2s60FyggrkbebOxp0s oaCN85Do2LRXqsm5UywKxtxw6imhktjCUltGjma5V9ASzadrDMzVuTvc6byz eQZI6eAVF0MK67fX4p8koMzrAs1cdI4mIKFtOHJ1w++MXzU9Wlbd1Soder1K pe1BiUwNBlxtalx6dMd53Mx3GTnFjKiZMGHiJTNV5reahgPFNQYzEV+mkI8u yUuWKQhUzVISND6cd+KLJuu.W0nRUe2zZdRQVXEoUNYAMQnLPbAkeZKce8jA uVs6HMJhvayiQzbUr+lcgLJIv0hX2Qh3sOMHFMRDu4oAwdiDwnmFDuYjH14o AwNiDwvmFDu8J3X3Df3RuwU4sxRk0hn8lLzrGKDYzfBgwPX8DwcUYRXvDTcf kDfYkIQ3TjGCkygyIlX44IySy6j.z+FyEpwk1koRqUdERKD.QBHRc7IRjPLu HKS46iPQZJICvjNKE5S9XxeeD1MgGytmY+RHStUsseHuPBpCEU+pHvnS+qmA xdBoC+M0N+y9nCsxpY.NF1oswpRNZXiTiwIvkFmtzvzEOqFKZ7FAZ1NanA5L B33MavY2HQCbdHmsMtU83LdFwyXzNv4SJCGyJK37odFiV1c9XG+wvNy3Rc3H vi58zclvSqaUO3w84hePyGdbGiwG3MBGiS0VGDsBIsN.5VG97kG7b+G5b6Cb Vdm+0x+A2ZamR -----------end_max5_patcher-----------
Holland! Thanks for sharing! Mind if I stitch that together with the beat follower? I’m also playing around with the median and also averaging the median and average together…
Would there be a better math to do combining the median and the average?
I prefer the simple median myself for most such applications because it will definitely be one of the values I tapped, though YMMV. If you’re looking for a more detailed approach, tap-tempo is basically the simplest case of what is called "beat induction". (simplest in the sense that it’s totally regular and not looking for a meter) It might be worth checking out the research in this area if you’re looking for improvements.
Great to see this thread come up! I’ve tried to do this before but stopped because of seemingly insurmountable problems, e.g. how to recognise the difference between ritard or accel and a sudden tempo change. But as I was reading it occurred to me that the patch could have 2 tap inlets: one for gradual tempo changes and the other for sudden ones. Sudden changes could have the option of waiting (or not) for the next bang output and could kick in from the 2nd tap.
My patches were intended for playing drum sounds with MIDI bass pedals, and I was trying to make them cover all possible uses – keep going (or not) when input taps stop, use [bucket] to constantly analyse tempo, gradual or sudden changes, output bangs in-between main beats, etc. etc.
Now you guys have given me a whole swag of ideas to try out, so THANKS! =:-) If I get any good results I’ll definitely be back to add to this already terrific pool of ideas and pasted patches.
Peter, that’s fascinating! I’ll have to read more about beat induction. I found this paper:
:which approaches the process of beat induction from a psychology of expectation. Of course this is drifting away from this thread and going toward something broader in terms of a computer generally following an ensemble.
Great paper Chris . Thanks for sharing it !
Definitely great to see this activity….I still haven’t found a suitable solution.
I have vague intuition for a physical model for my purposes but my math is too rusty to implement it these days. I imagine a flywheel with some specified (possibly changeable )weight and diameter that spins at some rate representing a tempo. There would also be a gear that would allow "instantaneous" speed changes (go to half speed, double speed). So the flywheel would tend to keep the tempo rate constant in the absence of taps.
Incoming taps (including both time between taps, rate of change between taps and perhaps even the velocity of each tap if you’re doing it from a keyboard) could be used to influence the behavior. So depending on what you’re needing to do, a very slight change in tap rate might be ignored, or cause slight changes. A few missing taps followed by taps at the original rate would have no effect, tapping really hard suddenly might serve to create a rapid change.
Clearly some of this is can be modeled with some kind of weighted moving average but there’s also interpretation needed so the system can differentiate between slight tap change rates, missing taps, the desire to induce sudden change, etc
Just food for thought. Clearly I should catch up on the literature as well :-)
Good afternoon all! I took some of the latest ideas and threw together a combination of the sync patch I had earlier and added the latest in tempo mean/averaging discussion to create a follower. Some pluses:
+ It will find a new tempo, and then sync the metronome to play with it.
+ It seems to be very stable.
Some areas for improvement:
– When doing an accell or decel, it will constantly lag ahead or behind the curve. Maybe some sort of prediction algorithm would be helpful.
– When you establish a tempo, you have to tap a full 7-8 clicks or it will pop to a different tempo when you stop tapping.
– right now the patcher below averages the mean and average. Is there a way to control that so you could set 100% mean, or 100% average, or 50 50?
This is quickly growing into a much bigger solution that I’m working on, particularly involving recognizing a tempo within rhythms, and then getting a sense of beat and speed there.
-- Pasted Max Patch, click to expand. --Copy all of the following text. Then, in Max, select New From Clipboard.----------begin_max5_patcher---------- 2569.3oc4bszbqhbEds8uh9pZRMISzka+taxtjMoxhopTUVjE4NUJjTaaFi. U.J956Ty+8zO.IYaAtADHpxdgjnEBN8Wed7cNmF+a2dyhUYeSUr.7W.+GvM2 7a2dyM1gLCbS0w2rXaz2VmDUXOsEqy1tUkVtXo66JUeqzN9e6e9y0icWVZYZ zVkc7+ZdbTR82rKpb8Cwo2+eyUqKc2UJmE.WV+FIz7JFF.A+R0uIdi85js5W +rjWegR2uMNMQUZkIzI22h3uauuHr9Bc3by1WVexPyf+9s2ZdY4.mykOn.qR 1q.Q4pHPTZTxyeWU.Ji1UnOZCXipTkqET8QfR01cYfUQEpMfrTf4mF8+T4Q2 q.Y2YObqJJ09ypG+oGhSTfM4Y61owLPY1N6WuJqrLaKPOsVoxKB.f+Qo9V9n 9FKb25xLPQT497nRUsHmDmpVmsO0J2HReVn3DnYsIz9pjG.oLj9JAPlOe1UK 17a0RCjO5VstSiHfnM+59hxhJ3uLOKMaq5G0GGuUYfwsFXv9s61mTbXkRixm EX48x.fYQzZ3UDfwRJLTiwgMfqjYFttOO8H5oUt+TubDPfV..Y8CfP7.DAw3 gM6MfAuN3vVUQg177M3.gnuOB.5fX4tOkOuS4lgKVbXZzMjg6PFoSQg5NnAP 47JG3t.JnKHnvgiDnfkL+AE70ATRUOou8uASRyJU5q7hALswH6zlgZKbICc1 oM4Z4n3eUFkWpCEdvWwRimz5XiKsA2dgmXvSwIIl3cO.tKKII6IvyY6yqBkZ N6hxnmAwofhmSWqOY84EWF70zul9uePkZNYvlrzezDdb2R8W4N+hRUzlms+9 mhzCdWVt8T096shy8QwoAm0+tre90rJnUN23NuahyuhQCmWt1+6YQItfdwE. 6bqWJsU9zcZtRqoJkz.BHeWD3tn0plPExjDv6X3+toIHpvAqt.E1lsKgNuzD VmDu9wulNrH69LumYja9Cf0Y4loRbV+l7XgivraZK3sN4QyqI+1BfJOOKeHQ pDUAnaMRE4JQk6tjL8EoQpI5uNRiJfEqhRuuuj2nrSV+qhd2.LfECGFvWNdJ +D.F7NXyfHzRItb94ArVvD9rh6l5a6xA+vcHvW.+we3N7Og+Sf+L.cwY7Woz 3X4gwr.MkAAF2BLwtNvzp8kkG8L9l4+KMbZVUvUUAln90y5jncqiq+boximW yE4HOWJyt+9DUiyk3zx1WVbj0bbWoz5WOKiMzHOUZvRzlkfmKV8w3qtvjsF3 hdkxrb5BbUE+VPaEFHyt.WrQIxEslCqy7n8n4jYUjKcXpfwDSpxtgPZESlWU h4SeQmXt9uQBXBYmPywEPnQfAMq.lum.1p1DG0bzPi2kggKUNX331vEzEvH5 B5Y4Q0ysFSc44daPlUt.wrv13HedxDvtfQzKGFUnR.Db6QlGfxSkGXVcUjZI qxYkpio8due.6AquTydocqJz0IdcSEZntimlp+lqJ5Wowqcq3hCEJaE.lasl LO6IPzSQOagfGhu+AMJXKQcR1SlOV0s2yVV5d0NWFtpbrNzhFvEXBRp0bZnI J3qCj0b.J053jh1x8dvNYp.GdqEsiNq7xnwkhj30pQEWpxNjSCHPNS1RGnlc XSVd4XpvvXGSXtIPgO6.kxbUzVfXLAFm2FQq09Wbk.Fqq056s9NGuUmZ8IDn Zho2KStVeMq+gXcJECgxWXSUdX08qyRxxcmMLPx0+IVd1OgZHv2A2Uk4wEqi RrRFLHbNk+9Jv6Seb.U1nBl8IeUDedQTZ+tcpbPR713RqV1PHJUolgvstm6P yrVRa7faIIkDOLdhU9pE5zx4RJrsVP.mUTeV0Rr8gXUToN3JsEt0pUP5vV6C EvBYHoXrKYw5c6Wmjs9wwrTNnpR4zdWb4yOv4yiUq7pCYUs8cwsUlBRn+A3m JfYrLlH9aLQgezLlH9aLQuldZdYWVNgYnsuXcq2KmPOjCO9y6UAkcFarVISy kypVx7ouX1FPPnecjrWnh6MV64dENqJydI.BVsnSoYzmcbV0dKmzJzHfyJEF M+1wEZHP+gFzrBZtOpT0RFRCHa8ZPAdxlptwDCDyp5XLdaVop9fWQzwDkoEM E7Ly+xp155actzCJXNFdh2WRqLcPrYlKlUfOOxvSc6XB8XyjHtR6hhld1Mt3 aqspjEXtx.5RVnomYCAcVYIsQkD8rlxEbTxVnBWnd31UvlU3xHk+TMwE2tCr 87mjezxepFbj72O+ovOP0hnNRMF990h.A+vTKh5t04isDB+QyVBQMpIdYKIQ WQvYWTp5vDYUV9FU9o27lexSngHWOagALFTRwFVZn.JDgvjy2YI6O.dxKHoD SXmESvcX2+Bmj4M00RGAw8HgJCPTAlJLaWSsg.EwY7lZnlcxhWVC.sLso8bZ auX1suwq9utfchXF+kXQQ19700J5063XvQ0yMphx3zH6imzwSxvj7jS5g3Ma Tom1Ryswa1koShtRH.+xYWY7UlHdHRFt+cQjnts7FWDH0YkxQlszzKGYfBsv GfjNs.oYWf9txjoxdSnLYJ9A.8dqt3tISDlysKSDfCCgBiSI7qFZnxMzC41v crSxcX3aja4kUtQPeLvwSpN.xGaEIZRkIoO3T3jJRg93GrqZbN0KATDvgBNm ur1343PCEIQ9J2nNH2XaZrBM+JDQJBolGzO4KGZnZkLOrvsVJnoyRg4i0aWi E5h7wbb2qhLZOZJjVSgd6BBVKsg1mqyJ8W6QC0iNYDVuIBtCMwATpl5H2r88 bO6dGF5RH2WZchJm.WdcBuj1tpSbhzJQbABcTw3vPCTt4g9hxSm2fWQUqA9b SaPJAz202tGkhqWlQTcdVrS3y8lgL9Br67tC9IfWBNpW74DI7ZNmdk31f97z x45Ul8MHSvoUelNBq809SCwuXUEObMUu3GPm1UUtOYBC6EB5xWRGFs9fKgr9 dZfjtxuRPNJqL3kRVIdkOvztVS8Q+yJ3cgwma4EwjADABRMOEQUke6vPCEK4 9J2c.KqVpQbbfTxkTzAhTGGZnxsW3MeZ0A7gA.kMoxjWtfl13J9PcaZ8S6Sj NwzpJ4gDMsJR9TS.Dp69IjtmzsJp.UtIrGMzpu3iCh4GDNwEF2mBPhmXYxGW 63I1dzmj2wSqEI1GOoXduJ+gjqeCxs++RF613LmYHJAEvHgZiVSQHcFvGFZn yNuhbMsEgzqdDRj8BwoRQ.AKCoglNxQZXHIMf5JyCNjd5.Cclg7EsgcqT0l5 oGFPHbgPbrB60iLA8GkH5c+QEbRH+fl8gQlhl5NwDf7Y0GOwsFi3qLg5bhI0 9pbomZOZndq7RZQ8RUz5Rkoc4RNjD8wglD4l2wzVOJ2v5nCRQc.C3EI5f2wi 6mbSM6wHpYiKAC3HgfHNc7gxCzmvHrosBjLx7SlH9PvgMwaIGeRqfMDWk5C9 8a++.cb.XI. -----------end_max5_patcher-----------
Thanks, Peter — I’ll check it out.
I’ve been playing around with this and still haven’t found a great solution.
One seemingly insurmountable problem is this: If, for example, you have a click happening at 88 bpm and then want to tap in 100 bpm, if you just start tapping at 100 bpm it’s easy enough to make the click speed up to 100, BUT It’ll never be in sync with your tapping unless you stop and join in again. Or unless you make it faster than 100 till they’re in sync then drop the click to 100 again.
That can’t be how it works on your Korg Oasys or Boss Digital Space Echo, can it, David?! It doesn’t seem very intuitive but I can’t see how to work around it.
Working out the mean of the last n tapping times, or removing taps more than a certain percentage away from the current tempo was done pretty quickly, but this problem’s got me stumped. Any ideas?
I haven’t had time (no pun intended) to look at this again yet but the issues you raise are precisely why I have this vague intuition of modelling tempo using a flywheel with inertia. The wheel would tend to want to keep its current tempo and depending on how you tap (and change your tapping rate), the characteristics of the flywheel (that make it "want" to be at a certain speed) would adjust, sometimes drastically.
I know this seems vague (that’s partially the problem with intuition) but there may be treasure there :-)
My Kronos (used to be Oasys) just seems to do a very nice job when I tap based on the rest of the band changing speed. I’ve asked on the Korg forums but never got an answer from anyone. I don’t have the Space Echo any more.
The adaptive oscillator algorithm incorporates phase information. You might look at a digital PLL algorithm as well. (Phase locked loop)
I did include a code that picks up a tempo and syncs with your tap. It is my last post from June 27. I would love your feedback on how it works. It’s not perfect, but it at least attempts to do everything that you’re talking about.
I like the idea of including some sort of fly wheel design. It might also be good to clear out the buffer with the absence of taps, so you could give two definitive taps to get a whole new tempo. All further refinement..Anyway, I’m rambling now. But maybe to clarify final behavior it would be good to define all the kinds of user input that might have to come into the algorithm. Accelerando…Rallentando…A-tempo…Subito allegro…the list goes on. Then we could define ways the user could input that clearly into the system.
I’ll have to check those out!
@chrisroode Obviously I have no scientific basic for the flywheel idea since I haven’t even tried to validate the notion but I’m certainly very appreciate that you are thinking about the whole issue.
I sort of understand Peter’s suggestion about using PLLs. However, it’s not obvious to me (because I don’t know that stuff deeply) how well the parameters/independent variables, feedback, etc that define a PLL map to a physical model of a flywheel.
In other words, when I think about simulating a flywheel, I’m thinking more about how the kind of material, thickness, diameter (and therefore the mass) and so forth, impact the speed and resistance to acceleration, etc but changing those kinds of parameters either smoothly or discontinuously seems more intuitive to get the desired behavior.
@chrisroode: Sorry – I’ve been distracted for a few days. Will definitely have a closer look at your patch. The first time I looked I couldn’t understand the maths without spending a bit of time on it, but it sounds like it’d be well and truly worth it.
For now, though, can you tell me whether it makes one of the metros speed up till they’re in sync then slow it down again…?
@dhjdhjdhj: If (at least part of) what you mean with your flywheel metaphor is that the tempo keeps going at its current rate (whether you’re tapping or not) until you make it change by tapping at a new tempo, then I’ve got that happening. If Chris’ syncing patch can be added to it we might have a solution – hopefully, one that works well and feels right.
I’ll get onto it in a few days. As Rachel Hunter famously said: It won’t heppen overnight, but it will heppen. ;-)
@Bill Canty — it’s really more about how the flywheel rate changes when influenced by incoming taps (and perhaps other parameters such as velocity of a tap when available)
Hey, crazy week here. I’ll try to answer your question: There are two systems working to adjust the tempo and the phase of the click in my previous patch.
1) Average and Median the last 8 or so taps to find a tempo.
2) Time the click and the tap, and use the timing difference to predict how far out of phase the click is and adjust it for the next click.
The problem is that the click is so good at #2 that it can appear to follow you really well. Therefore, if you get to your desired tempo, you need to tap a good 2 measures so that #1 can find the tempo you are at. If you stop tapping prematurely, when #2’s phase adjustment returns to 0 in the absence of taps, the metro can end up being as much as 20 clicks off. I have some ideas on how to fix it…but it’ll have to wait..thank you band camp…#forTheRecordILoveTeachingDrumline
Someone said this thread never dies.
@chrisroode, did you fix your remaining problem in the end?
I just read this on the interwebs (link):
As each new tap comes in, compare it to the previous average. If it falls outside of a certain range of acceptable variation, throw out all the old ones and start over from scratch. Now we’ve got the best of both worlds: if the taps are nice and steady, just keep on collecting intervals, and the average keeps getting more and more accurate. But, if a rogue tap comes in, you don’t have to wait for the 2 second timeout or the old taps to "fall off" the end of the array, just keep on tapping, and the metronome will adjust to follow your new tempo!
I thought this approach was pretty interesting.
Band camp led into a one day a week teaching job, which became three, and then some other good news about a composition I submitted to a contest…then it was november…and then december came…Then as a new years resolution I came to prioritize what i’m doing with side project…because my teaching work is crazy and i’m about as organized as a drummer artist can be…So, this project has fallen off on the wayside, but it’s not forgotten either way.
The way I might plop it open is if I start working on my beat induction algorithm for computer music systems…which I might get going at some point…
You’re more than welcome to open up the patch I have above. It’s the latest version I had of a tap tempo algorithm…
I had a look at your patch, I like your style! The thing that’s missing for my usecase is that you can’t just tap three times to get it going, you really have to tap 7 times until the
[zl stream 7] is filled. I’ll work a bit on it and post the results here as soon as I got something. Maybe I’ll get that idea that I talked about earlier to work. Thanks for getting back Chris.
Forums > MaxMSP