## Has anyone got a formula for BPM ??

Started by wadmixfm, June 14, 2024, 18:38:54

With ya but For my program as they say it's close enough for jazz

Yes its really me

#### Midimaster

what do you mean? I'm no native English speaker.

Your algo will fail more and more, when you start adding more graphic features or do more complex rhythms. Or if you work with fast songs around 200bpm and triplet notes, etc... While mine keeps completely stabile, no matter what you add to the code.

And it maybe that your algo gives a good impression in average ticks during one minute, but if you listen to the single events you will hear sudden time-laps between the beats.

Here is an example with 200bpm and triplet eighths (swing jazz), which needs a base of 48 positions in a bar (array) instead of 16. So the ticks are now only 5000/tem long. Means: at 200bpm each tick is only 25msec long.

We would expect 100 ticks, but see:

`SuperStrictGraphics 800,600Global Start:Int, Frames:Int, NextBeat:IntStart  = MilliSecs()+2500Frames = 0Repeat Cls DrawText "DELAY Test running...", 100,100 DrawAnything Frames = Frames +1 Delay 25 Flip 0Until MilliSecs()>StartPrint "DELAY based couting:   " + FramesStart     = MilliSecs()+2500Frames    = 0NextBeat  = MilliSecs()Repeat Cls DrawText "NEXTBEAT Test running...",100,100 DrawAnything If MilliSecs()>NextBeat Frames   = Frames +1 NextBeat = Nextbeat +25 EndIf Flip 0Until MilliSecs()>StartPrint "NextBeat based couting: " + FramesFunction DrawAnything() DrawText "time remaining..." + Int(start-MilliSecs()), 100,60 For Local i:Int=0 To 360 DrawOval 400+Sin(i)*100, 300+ Cos(i)*100,5,5 Next End Function `
...back from Egypt

#### Jayenkai

Test Proggy <--  You should find that beatB "should" stay in sync, whilst beatA will drift wildly.

Quote from: Midimaster on June 17, 2024, 16:39:27 what do you mean? I'm no native English speaker.

Your algo will fail more and more, when you start adding more graphic features or do more complex rhythms. Or if you work with fast songs around 200bpm and triplet notes, etc... While mine keeps completely stabile, no matter what you add to the code.

And it maybe that your algo gives a good impression in average ticks during one minute, but if you listen to the single events you will hear sudden time-laps between the beats.

Here is an example with 200bpm and triplet eighths (swing jazz), which needs a base of 48 positions in a bar (array) instead of 16. So the ticks are now only 5000/tem long. Means: at 200bpm each tick is only 25msec long.

We would expect 100 ticks, but see:

`SuperStrictGraphics 800,600Global Start:Int, Frames:Int, NextBeat:IntStart  = MilliSecs()+2500Frames = 0Repeat Cls DrawText "DELAY Test running...", 100,100 DrawAnything Frames = Frames +1 Delay 25 Flip 0Until MilliSecs()>StartPrint "DELAY based couting:   " + FramesStart     = MilliSecs()+2500Frames    = 0NextBeat  = MilliSecs()Repeat Cls DrawText "NEXTBEAT Test running...",100,100 DrawAnything If MilliSecs()>NextBeat Frames   = Frames +1 NextBeat = Nextbeat +25 EndIf Flip 0Until MilliSecs()>StartPrint "NextBeat based couting: " + FramesFunction DrawAnything() DrawText "time remaining..." + Int(start-MilliSecs()), 100,60 For Local i:Int=0 To 360 DrawOval 400+Sin(i)*100, 300+ Cos(i)*100,5,5 Next End Function `
sorry midimaster

when i say close enough for jazz it means its almost to close for comfort ,almost hit the nail on the head haha

by the way

i have only 2 lines of data in the whole program if you look at my new pic

this is all the user is going to see at the bottom of the page will be a song creator section to play the patterns

now i ran your code and yes it works well

mine is virtually the same as yours and i left it running last night with the image above playing the same pattern at 125bpm and after 1 hour it was still showing at 125 bpm i timed it with the stopwatch i write music theory so i understand how bpm works  in the real world its easy in the computer world its slightly daunting but i have managed to do it

when i have finished the program to a usable state i will send you this version

i have a version for mac and for windows

lee

Yes its really me

#19
what you have to remember is this was originally written for the commodore 64

i am just reviving it to the modern day equivalent with a few little extras but keeping it close to the original

all i have done is modernized it with new samples and more patterns and loops

same amount of samples 16 all recorded at 44000khz mono.

in the program i am using the module you created MimaAudio and there is no latency at all especially when you are
inputting the notes in real time from the keyboard.

recently i did Specdrum which you had a look at and since then i have done loads more too it added lyric teleprompter and midi control to an external drum machine and loads more

these programs are for nostalgia purposes there not for any monetary gain i do this for fun

and who is to say how i program them , there are no rules in basic creation if it works it works

I can tell you that my specdrum program is used with my band as we are only a 3 piece 1 vocal 1 bass myself lead guitar and i use specdrum with a real sounding drumkit samples with added reverb and through a P A if you close your eyes you really can't tell is there is a drummer there or not lol (slight exaggeration there ) but you see my point

lee

i must add in the c64 version his samples do sound grainy as they were only 3bit and about 0.3k each sample remember the old 64 only had 64k and most of that was taken up with rom and basic code haha simon pick did well for 1986

Yes its really me

#20
here is a video of mine running so far

sorry i forgot to add - there is no narration i was only capturing the audio from the computer

in the video when it starts you will see me move the cursors to input the notes or sounds

then i will change the tempo up and down and increase and decrease the bar length

when you do this it starts the pattern from the beginning thats why it looks like its stuttering its not the case lol

next time i do a vid i will add Narration
Yes its really me

`SuperStrict   ' Import necessary modules Import brl.timer Import brl.standardio   ' Define BPM and calculate the interval in milliseconds Global BPM:Int = 120 Global Interval:Float = 60000.0 / Float(BPM) ' Interval in milliseconds   ' Define the drum pattern length (4 beats for a 4/4 measure) Global PatternLength:Int = 4   ' Start the timer Global StartTime:Float = Millisecs() Global CurrentTime:Float Global NextBeatTime:Float = StartTime + Interval Global CurrentBeat:Int = 0   ' Main loop While Not KeyDown(KEY_ESCAPE)     ' Get the current time     CurrentTime = Millisecs()       ' Check if it's time for the next beat     If CurrentTime >= NextBeatTime         ' Perform the action for the current beat         PlayBeat(CurrentBeat)           ' Move to the next beat         CurrentBeat = (CurrentBeat + 1) Mod PatternLength           ' Schedule the next beat         NextBeatTime = CurrentTime + Interval     EndIf       ' Sleep for a short while to prevent high CPU usage     Delay(10) Wend   ' Print a message when exiting the loop Print "Exiting..."   ' Function to play the beat Function PlayBeat(beat:Int)     Select beat         Case 0             Print "Kick  | Hi-Hat"         Case 1             Print "Snare | Hi-Hat"         Case 2             Print "Kick  | Hi-Hat"         Case 3             Print "Snare | Hi-Hat"         Default             Print "Unknown beat"     End SelectEnd Function   `
Yes its really me

The above code seems to work
Yes its really me

#### Midimaster

#23
This is still wrong:

NextBeatTime = CurrentTime + Interval

All beats have a distance of 40msec. First beat is at 0000. So the the next beat is at 0040, then 0080, ... right?

` If CurrentTime >= NextBeatTime `
...waits until Millisecs() (or CurrentTime) is equal or bigger than 0040. This happens when it is 0040 or 0041 or 0042 upto 0049. ok?
This can happen because you wait a delay of 10msec each loop!!!

Now the event "0040" is executed at 0049.
After this, you add 40 to the CurrentTime, which is in worst case 0049. The sum is 0089.

As next step the loops waits until CurrentTime is equal or bigger than 0089. This happens when it is 0089 or 0090 or 0092 upto 0098. ok?

Now the event "0080" is executed at f.e. 0092
After this, you add 40 to the CurrentTime, which is in this case 0092. The sum is 0132.

In total this means:

The events planned at 0000, 0040, 0080, 00120

are in reality at:

0000, 0049, 0092, 0135

The error is added from step to step and gets bigger and bigger, in average 15msec, total song length : +15% slower

When you replace

`NextBeatTime = CurrentTime + Interval`with
`NextBeatTime = NextBeatTime + Interval`
everything is fine!

Here is the explanation:

Think again about the same (theoretic) situation:

All beats have a distance of 40msec. First beat is at 0000. So the the next beat is at 0040, then 0080, ... right?

` If CurrentTime >= NextBeatTime `
...waits until Millisecs() (or CurrentTime) is equal or bigger than 0040. This happens when it is 0040 or 0041 or 0042 upto 0049. ok?
This can happen because you wait a delay of 10msec each loop!!!

Now the event "0040" is executed at 0049.
After this, you add 40 to the NextBeatTime, which is still 0040. The sum is 0080.

As next step the loops waits until CurrentTime is equal or bigger than 0080. This happens when it is 0080 or 0081 or 0082 upto 0089. ok?

Now the event "0080" is executed at f.e. 0082
After this, you add 40 to the NextBeatTime, which is still 0080. The sum is 0120.

In total this means:

The events planned at 0000, 0040, 0080, 00120

are in reality at:

0000, 0049, 0082, 0125

The error is limited to max 10msec, in average 5msec, total song length : 100%, no SlowDown.

No need for a DELAY of 10msec!!!

your idea of a DELAY is good. But there is no need for a delay of 10msec! Do some tests! Already with a delay of 1msec the CPU performance consumption of your app shrinks from 50% to 10%. Or with a delay or 2msec it shrinks from 50% to 5%. And there is no more significant improvement when you try 3msec ... 10msec!

But the stability of your drum increases dramatically when you use a delay of 2msec.

The events planned at 0000, 0040, 0080, 00120

are now at:

0000, 0041, 0080, 0121

...back from Egypt