First attempt at making BPM object. Please share your thoughts!


#1

Hey

This is first naive attempt at making a frequency to BPM converter. I
took a look at some Reaktor patches for BPM calculating. I tested it at
120 BPM since it can be calculated into a clean frequency. 120/60 =
2hz. But it starts drifting noticeable after 4 bars.

Would be great if anyone wants to chip in. To have a BPM object would
really benefit everyone that works with computer music in BPM.

Patch: BPM Object I.axp (4.0 KB)


#2

why not send it midi gates or midi clock?


#3

Yeah That is an option.

But isn't the whole idea of Axoloti that you want it to be independent and not rely on computers and other sources for sync, etc.?


#4

I'm not sure what you try to do with that patch you created. You're multiplying the output of the LFO with 60 - why? Your patch drifts because the display is not very accurate. If you switch to ms you can tune the LFO better (best I got was 500.1ms - it should be exact 500ms).

I'm trying to understand how the LFO works and try to create one where you enter a BPM. Will post if I got any further.


#5

@hpfmn

I am trying to do the exactly same thing you are trying to do; to make a BPM based object. If you want to approach it in your way, you have to go all the way down to programming level, I think. Sure if you know how to do that, please do so smile I would love to get that object. I don't know programming, and I was basically just trying to solve the issue with the tools we have now and some math.

You're multiplying the output of the LFO with 60 - why?

Cause that is how you calculate frequencies into BPM, search google if you don't believe.

This is how it is done in most cases, BUT it is really hard to do with all frequencies, cause a lot of the calculations from BPM to frequencies ends up in uneven frequency numbers that is not possible to set as a value in any lfo in Axoloti.

Frequency to bpm calculations:
Frequency multiplied by 60 = BPM

BPM to frequency calculations:
BPM divided by 60 = frequency.


#6

Yeah I know the thing about how you would calculate the frequency<->BPM thing. But what you're doing is just multipliing the signal of the LFO (a square wave). So you're applying gain on the LFO wink

EDIT:
To understand what happens all about Frequency and BPM: (you don't need to google for that)
BPM mean Beats per Minute
Hz (Frequncy) means Beats per Second
one minute has 60 seconds -> Hz to BPM multiply with 60 (1/s=1/(min/60)=1/min * 60) , BPM to HZ divide by 60


#7

No, I am multiplying the frequency of the LFO(2hz) with 60 which is 120BPM.

That was the purpose anyway. Could be the wrong module for calculation. Which one you think I should use instead? wink

Like I write, I think ALOT of people will benefit from this object and I only started the thread to get a nice discussion going with different inputs so we can get it right smile


#8

as @hpfmn says multiplying by 60 is just gaining the signal.
(btw, bpm = hz * 60, since hz is cycle per second and you want cycles per minute)

if you click on the LFO number (says 2.0Hz) it cycles through, display units, last one is BPM.
you wont get exactly 120bpm (closest you can get is 120.04 (using ctrl+shift), so thats 0.6ms out)

I wonder if the pitch input could be used to help 'fine' tune it.... as the accuracy of input here, is being controlled by the UI, not the implementation.

probably easier to implement though as a new object, where we can use an integer bpm input, and then create a pulse as a trigger output.

Id say thats one use, if you want to use a computer thats fine too, also remember clock signals come from other hardware too, like synths/grooveboxes etc.


#10

Great about the multiplying. Still learning about these objects and great that you chip in. Which object should I use instead?

if you click on the LFO number (says 2.0Hz) it cycles through, display units, last one is BPM.
you wont get exactly 120bpm (closest you can get is 120.04 (using ctrl+shift), so thats 0.6ms out)

But that just tells me that the LFO amounts are off then. and the calculations are right...

IF 2hz becomes 120.04 BPM after changing the display, then there is something wrong with how it is displayed or the calculations inside the LFO. 2hz IS 120 BPM and not 120.04 BPM. Agree or not?

I think a new object programmed from bottom up would be a great solution. Only very few BPMs have even numbers when converted to frequencies, for example 90, 120, 180, and so on..... But the LFO speed thingy is a bit worrying. Especially if you want to make things precise and sync it with loops in BPM and alot of other scenarios....

We should make a "wishlist" with objects, etc that could use an update or a "would be nice to have list" smile

Still pretty happy with it. Almost reach my goal on building my sample manipulator and it is better than I had planned wink


#11

The differences when showing different units come from rounding the numbers in order to display them with a limited number of digits. If you see 2.00Hz it may be 1.996Hz because only 3 significant digits are shown.

The frequency range on lfo's is tuned in "semitones", only a couple of octaves down compared to normal oscillators.

There may also be a slight inaccuracy in the implementation. But I'm surprised that it 'd drift apart after just four bars.
Will make some measurements when I find time.

I can see the need for a tempo lfo, with outputs for bar, quarter, and 24ppq. Oh I see midi/out/clock, but it lacks a scale indication on the tempo parameter, and maybe other aspects of this object are unfinished.


#12

not really wrong, it just normal issues you get when you have display rounding...

theres a few things going on in this 'area' which confuse things:
- floating point numbers represented as 32bits are never entirely accurate
- there is a conversion from 'midi note' to frequency (see the pitch+/- that tells you its using pitch not frequency natively)
- display accuracy/rounding
- a dials 'micro' increments, e.g. whats the smallest amount we can shift it by?

anyway... so yes these could be avoided (or alleviated) using a custom clock object with integer times.

as for how you can fix...
so to change the cycle of a clock, gets into the territory of clock multipliers/combining multiple signals.
but thats not easy to get accurate.

what might work is to try an LFO that has a frequency input, say use a lfo/sine lin, this may not have the same inaccuracies, as it avoid the last 3 of the problems above.

It would be interesting to see if its helps

of course its worth noting 0.6ms is not very long.... the sample rate is 48000 with 16 samples , so that about which is about 0.3ms ! so the drift is not very big... about 1 second in 30 minutes.

this only becomes a problem if you are trying to sync to something external but if thats the case you always send sync signal, as no clock is entirely accurate. this sync then resets the clocks, to avoid the natural drift between different clocks.

(times relatives, so doesnt really matter if 120bpm is really 120.04 as long as all devices agree it :))


#13

I haven't read all the responses... but I made a little metronome out of your patch smiley
CheapMetro.axp (3.9 KB)

it uses this fast hacked object
countdown_square.axo (1.0 KB)

Basically I'm overflowing a integer - and I calculated the magic number (subtraction - going through all the values a 32bit integer can have in 1 BPM) the following way:

Countdown number for 1 BPM=(MAX_INT*(1 BPM/60))/(CALL Rate) = ((2^32-1)*(1/60))/3000 = 23860.929416666666

You see it's a fraction - so I approximated to 23861 wink

EDIT: and from there you can go to any BPM by multiplying smiley (23861*2 means two times as fast - which means 2 BPM and so on and so forth)


#14

Btw. maybe @johannes or somebody else can tell me why it is just working with substraction but not with addition? Does an ARM-Integer just overflow for subtraction - or is just me?


#15

ARM-integers are just integers, and overflow both on substract or add.
Only had a very brief look at your code, where does the magic number 0x8000ffff come from?
I'd use a signed int for Phase, and compare Phase>0 in the end. Saves loading a literal.


#16

The number 0x80000000 would probably make more sense wink
just did that thing because I wanted more a square than a pulse because than I could see it in a display (disp/char b) - just a pulse is too short to see it in that display.

EDIT: using a singed int is actually much better wink - and no it's also working with addition. So I had earlier probably something else wrong.

EDIT2: So here is the improved version wink countdown_square.axo (1.0 KB)


#17

@johannes as the other guys wrote I might have used the wrong object for calculation and that might have to do with some of the drifting? What do you say about it?

I compared it to the click of Logic DAW.

@thetechnobear
But in this case, when you need something to the beat, you cannot have roundings like you say about the LFO. Still the LFO rounding concerns me also for other purposes, but again I have no idea on how other synth are really build and if they have rounding on their LFOs. Adding a sync function to the LFO would also be great, but for now, lets just figure out the BPM object. I think that will open of for making the synced LFOs too...... Cause sync is important in modern world music. Also if you want to sync the lfos to Midi clock, it is a problem. this is not possible at the moment, right?

I know 0.06 is not much, but 0.01 is also not much, but not good enough when you want to sync it to BPM, that is the whole point, right? It has to sync and be precise.

About the 120 BPM being 120.04: I understand your thought path, but no one I know thinks 120 BPM is 120.04 BPM. As far as I know all DAWs and the rest of the world agrees that 120 BPM is 120 BPM and not 120.04 BPM.

And this is even one of the even frequency numbers. How will it look if you for example take 137 BPM and look at the LFO freq?(sorry cant check right now, will check later). I think it will be alot worse than the even BPMs.

I think BPM object is very essential to modern music in many ways. Maybe YOU don't want to use it, but it should at least be an option, right?

smile


#18

@hpfmn

Awesome mate smile WIll definitely check you clock square.axo smile

Yesterday I spend most of the evening trying to figure out this problem, googling and so on.... So I am pretty happy that you want to chip in with your skills. But with no programming skills, it is hard to do..... I have so many ideas i would like to make with this platform. And most need a BPM object smile

If anyone can point me in the direction of "programming for beginners", that is usable with Axoloti(C++??) I would love to read about it.......


#19

You multiplied the gate output of lfo/square by 60. While that does not make sense, it also makes no difference in your findings.

The drift may be there, I need to setup measurements. I can see the relevance of a clock master object. I can see the need for a midi clock sync slave LFO's. Give it some time, things will develop further.


#20

not really my point, that 120 <> 120.04, or if thats important or not.
really was trying to highlight the times we are talking (fractions on a ms), and that really syncing is more important.

anyway, as i said, have you tried a frequency based LFO, like lfo/sine lin which should, I think, not have this issue. (basically an unsynced clock would be pretty similar, just using a pulse rather than a sine, but both are useable given triggers are based on rising transitions)


#21

Thanks smile

I thought I multiplied the frequency of the LFO with 60, since I used a multiply object for the calculations. Since you say it doesnt really matter or do any difference I will leave it there and dive into other ideas. Still learning the math side of it. Never had to worry about these things on G2.