timer problem

Cor

Active Member
Licensed User
Longtime User
Timer tick shows every 500 msec different label color

Tried on different devices, but sometimes when i start play_click

the timer_tick will not tick every 500 msec
sometimes faster, time is out of sync

I need this to make a metronome for the drummer in our band

Time Machine, een band die je terug brengt naar de sixties, seventies en eighties

attached is an example

B4X:
Sub Process_Globals
    Dim beatTimer As Timer
    beatTimer.Initialize("beatTimer",1000)
end sub

sub Globals
dim currentBeat as int
dim nrBeats as int

nrBeats=4
end sub


Sub ImageViewPlay_Click
If ImageViewPlay.Tag="0" Then
  currentBeat=1
  beatTimer.Interval=500 '1000 msec = 1sec
  beatTimer.Enabled=True
  beatTimer_Tick
  ImageViewPlay.Tag="1"
  ImageViewPlay.bitmap=LoadBitmap(File.DirAssets,"stop.png")
  
Else If ImageViewPlay.Tag="1" Then
  beatTimer.Enabled=False
  ClearBeat  'cset beat color to default gray
  ImageViewPlay.Tag="0"
  ImageViewPlay.Bitmap=LoadBitmap(File.DirAssets,"play.png")
End If

End Sub



Sub beatTimer_Tick
  If nrBeats=4 Then
    If currentBeat = 1 Then
      beat1.Color = Colors.Green
      beat2.Color = Colors.Gray
      beat3.Color = Colors.Gray
      beat4.Color = Colors.Gray
      currentBeat=2
    Else If currentBeat = 2 Then
      beat1.Color = Colors.Gray
      beat2.Color = Colors.red
      beat3.Color = Colors.Gray
      beat4.Color = Colors.Gray
      currentBeat=3
    Else If currentBeat = 3 Then
      beat1.Color = Colors.Gray
      beat2.Color = Colors.gray
      beat3.Color = Colors.red
      beat4.Color = Colors.Gray
      currentBeat=4
    Else If currentBeat = 4 Then
      beat1.Color = Colors.Gray
      beat2.Color = Colors.gray
      beat3.Color = Colors.Gray
      beat4.Color = Colors.red
      currentBeat=1
     End If
  End If
  

End Sub
 

Attachments

  • metronome.zip
    16.9 KB · Views: 489

agraham

Expert
Licensed User
Longtime User
The Timer cannot be relied upon for consistent timing as it is invoked by posting messages to the message queue and it is indeterminate when they will acually be received and the Tick event run.

The Chronometer in my Clock library has access to the system millisecond counter using GetElapsedRealTime. I don't know what accuracy a metronome needs but you could try setting the Timer to something like 20mS and in the Tick event check GetElapsedRealTime for the required elapsed interval. That might get you accuracy approximately equal to the Timer interval.
 
Upvote 0

Cor

Active Member
Licensed User
Longtime User
The Timer cannot be relied upon for consistent timing
The the timer object is then useless i think if we cannot rely on it.

Is there another way to access the system time without clock library.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I have written a metronome, in the end I used a midi file for better accuracy, but I do have a visual element that does as Agraham sugests, I have amended your code (attached) with something similar. see if it's any better. It seems so on my emulator, but may not be good enough.

Steve

Edit: I didn't use the Clocks library but just tested against DateTime.Now
 

Attachments

  • MetronomeCor.zip
    17 KB · Views: 522
Last edited:
Upvote 0

Cor

Active Member
Licensed User
Longtime User
My problem was not related to accurate timing but that the timer

does not start consequently at 500 msec

see my example, tried on different devices.

the date example added by Steve has not that probem
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Sorry, not being a musician I don't know how accurate a metronome should be and thought that a few milliseconds uncertainty might be might be putting your drummer off his beat ;)

I think you've found a bug. If you set the interval when you initialise the Timer to that which you first use then it behaves properly. Similarly if you stop and restart it it's OK. However if you initialise it with one value, then set the interval to another value you get two ticks per interval instead of one

@Erel - Look at the app in the first post. If the new interval is different to the old setInterval() calls startTicking() which then does an unwanted BA.handler.postDelayed(tt, interval) so it goes wrong when when run() does this as well. :(

EDIT :- I might not have got the mechanism right but something odd is happening. :confused:
 
Last edited:
Upvote 0
Top