SynthMaker

tempo detection from audio stream

Archive · 2010 15 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

philter5 ·

hey guys, i am still trying to build an beat detector but i am missing one important thing: does somebody know a way how i can get the avergage tempo WITHOUT big value jumps if there is one offbeat or something like that? i don´t need an 100 % accurate beatdetector but it should work at least with a simple monoton 4/4 techno kick . any help?

rl ·

You could 'lowpass' the calculated BPM results. A simple implementation would be a moving average, where you calculate the average over the last e.g. 10 results.

trogluddite ·

This little equation may be handy - it's also useful for de-zippling control signals...

Average=Sensitivity*NewSample+(1-Sensitivity)*Average.

If Sensitivity is zero, no changes can occur; if it is one, the new value takes straight away. You can then add a Sensitivity knob to alter the update speed. Has the slight disadvantage of never quite reaching the exact value (but will get very close). Also, probably worth applying a 'window' technique. If the new reading is, say, more than 10% different to the average, then ignore it and keep the BPM the same. A very narrow bandpass filter on the audio input will also help - so that you can target the part of the audio with the steadiest beat (i.e. Kick drum, usually).

MegaHurtz ·

count and average.

philter5 ·

trogluddite wrote: Also, probably worth applying a 'window' technique. If the new reading is, say, more than 10% different to the average, then ignore it and keep the BPM the same.

i think thats what i am looking for 😀 . but my problem is that i am not hot with code AND math. i know that´s a biiiig prob 😉 and it makes it hard for me to understand. i allready have a bandpass filter on the audio in and a small code that gives me the average of the tempo. i am not at my SM machine atm but i can post the OSM later. 😕

MegaHurtz ·

I noticed you already got one, but that didnt stop me 😈 Here`s my stab at a tap tempo.

Edit: The readout says samples but it`s bpm..

philter5 ·

thx a lot for sharing megahurtz 😀

oddson ·

trogluddite wrote: Average=Sensitivity*NewSample+(1-Sensitivity)*Average.

If that seems familiar it's because it's a simple first-order low-pass filter.

A moving average could work to (which is a simple FIR filter of whatever order you choose).

I haven't seen what MegaHertz has done yet (not at S|M machine) but one issue is how you count events that are on the 100-1000 MS scale within sample-rate code. That is you can't directly apply y(t)=ax(t) + (1-a)y(t-1) at sample rate since the pulse detection is only updating the putative BPM after thousands of samples. You could force it into green where each pulse becomes the an event but then usual problems of getting info into green in a reliable way from a code module come into play (how do you ensure that the code causes exactly one trigger in green when the pulse detection fires -- especially in light of the timing inconsistancies of Windows timers -- which may not appear to be an issue here but when GUI interactions are taking place delays at the 100 MS level are not unheard of).

I'm looking forward to see what MHz has cooked up as it's an interesting problem.

MegaHurtz ·

No worries m8 this is so accurate it shows the rounding error in the sm osc 😉 //In the last section of code there`s a movaps to nothing, missed that one.(right in the middle). If you want it to average, there is a thing I thougt of thats not implemented yet. Maybe ill make it tomorrow. You can take the output prior to the current out value. And do a ((current+late)*0.5). Although its kind of a brainbender to do it where it`s supposed to be.

Ofcourse has to be accompanied by the lightweight timer in samples.

oddson ·

MegaHurtz wrote: ... Here`s my stab at a tap tempo. ...

Ah! I took it you were working on the averaging issue.

If you can make that thing increment an integer for the inputs (which I can use in green world to detect when the value is new) then I'll give the green low-pass thing a try.

oddson ·

Here's a green IIR lowpass filter if you can use green for whatever you need this for.

I've just faked the input -- it should produce random variations around 100 bpm.

(The update triggers don't line up with the BPM output but I don't think that matters for the green IIR lowpass.)

MegaHurtz ·

It`s interesting how to do it for on the fly detection. if you have three straight beats and one drop beat, you`d get something like (120,120,...,60) so (300/3)=100. wich is far from the truth. Ofcourse if you index them by number you`d get the possibility to ignore some numbers. But there`s an intresting problem.

Maybe someone has some usefull insight in how to take care of this? i`d like to build it.

oddson ·

A two-sided approach could be used. A filter for minor tempo variations due to imperfect beat or slightly sloppy detection and a second logic based output that looks for major tempo change.

In the latter a putative change in tempo would have to be confirmed by two consecutive beats at the new tempo. If a newly detected beat falls outside a range of values the system would go into a new mode of operation where it continued to output the previous value but waited for a new beat that was within range at the new tempo.

So a drop beat beat would be noted but the output to the stabilization filter would not alter. If confirmed by a second beat the new BPM would replace any lag values in the filter and become the first guess at the new centre for subsequent beats to influence in the filter. If the new beat is not confirmed but the inter-pulse distance is within bounds of an integer multiple of the old then the old beat is confirmed and the system returns to normal mode. Then the problem is what to do if neither the old nor new tempos are confirmed... (as it write this I'm reminded of a similar problem with a pitch detection scheme I tried to build where the detection of a zero-crossing differing from the last detected pitch could be a real thing or an harmonic abnormality in the signal. I never did crack that nut.)

But this is way more than what was sought... something to tract steady 4/4 beat.

MegaHurtz ·

Yes! lot of inspiration coming. get on it as soon as I have the time.

philter5 ·

i tried to learn some things from megaahurtz OSM and by this way i have added a float array to index a specific number of floats and then get the average of that. i also included a switch to select if the average bpm float gets refreshed every beat OR when the index has reached its maximum.all in green. i tried to solve the part with the 10 % difference , too , but i´ve had no success. would be nice if somebody can tell me that i am on the right way OR where my mistakes are.

thx

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.