Looking for "better" tap tempo abstraction

Dec 4, 2011 at 5:48am

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?

Thanks,
D

#60450
Dec 4, 2011 at 10:58am

Hi
“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:

– Pasted Max Patch, click to expand. –

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?

Brendan

EDIT: added a synced beat generator

#217563
Dec 4, 2011 at 11:53am

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.

#217564
Dec 4, 2011 at 12:17pm

Ah, ok

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 :(

Brendan

#217565
Dec 4, 2011 at 12:19pm

ps

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……

pseudo-code:

-average the first N timings
-accept subsequent timings only within that measurement
-set new tempo only after N measurements are completed

?

#217566
Dec 4, 2011 at 1:07pm

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)

#217567
Dec 4, 2011 at 7:53pm

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?

Brendan

#217568
Feb 3, 2012 at 10:22pm

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.

#217569
Feb 4, 2012 at 7:40am

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?

#217570
Aug 18, 2013 at 7:32am

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?

#259182
Aug 18, 2013 at 9:05am

+1

#259200
Aug 18, 2013 at 9:28am

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.

#259202
Aug 18, 2013 at 11:35am
– Pasted Max Patch, click to expand. –

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.

#259207
Aug 18, 2013 at 11:55pm

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.

#259232
Aug 19, 2013 at 5:58am

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.

#259259
Sep 5, 2013 at 11:59am

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)

#264398
Sep 5, 2013 at 1:55pm

I didn’t think of a median. I never tried that. I’ll have to check it out. Thanks man!

#264408
Sep 7, 2013 at 8:07am

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.

#264593

You must be logged in to reply to this topic.