Has anyone got a formula for BPM ??

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

Previous topic - Next topic

wadmixfm

  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:

 

SuperStrict
Graphics 800,600
Global Start:Int, Frames:Int, NextBeat:Int

Start  = MilliSecs()+2500
Frames = 0

Repeat
Cls
DrawText "DELAY Test running...", 100,100
DrawAnything
Frames = Frames +1
Delay 25
Flip 0
Until MilliSecs()>Start

Print "DELAY based couting:   " + Frames

Start     = MilliSecs()+2500
Frames    = 0
NextBeat  = MilliSecs()
Repeat
Cls
DrawText "NEXTBEAT Test running...",100,100
DrawAnything
If MilliSecs()>NextBeat
Frames   = Frames +1
NextBeat = Nextbeat +25
EndIf
Flip 0
Until MilliSecs()>Start

Print "NextBeat based couting: " + Frames


Function 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
...crossing the alps with my bike at the moment

Jayenkai

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

wadmixfm

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:

 

SuperStrict
Graphics 800,600
Global Start:Int, Frames:Int, NextBeat:Int

Start  = MilliSecs()+2500
Frames = 0

Repeat
Cls
DrawText "DELAY Test running...", 100,100
DrawAnything
Frames = Frames +1
Delay 25
Flip 0
Until MilliSecs()>Start

Print "DELAY based couting:   " + Frames

Start     = MilliSecs()+2500
Frames    = 0
NextBeat  = MilliSecs()
Repeat
Cls
DrawText "NEXTBEAT Test running...",100,100
DrawAnything
If MilliSecs()>NextBeat
Frames   = Frames +1
NextBeat = Nextbeat +25
EndIf
Flip 0
Until MilliSecs()>Start

Print "NextBeat based couting: " + Frames


Function 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 :)

wadmixfm

#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 :)

wadmixfm

#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 :)

wadmixfm

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 Select
End Function   
Yes its really me :)

wadmixfm

Yes its really me :)

Midimaster

#23
This is still wrong:

NextBeatTime = CurrentTime + Interval
 


Think about this (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?


Your code line ...
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?


Your code line ...
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


...crossing the alps with my bike at the moment