Android Code Snippet precise timing beats (Metronome)

Long time I was not able to write a precise metronome (a tool for musicians). Playing the beats with SoundPool and a Timer was not accurate at all, because of the timer. Even playing in a own thread was not really precise. Finally I got now a 100% precise solution with the AudioTrack Library. For this code you also need the Threading and the ByteConverter Lib.

B4X:
Sub Process_Globals
    Private i_Milliseconds As Int = 500
    Private ConverterByte As ByteConverter
    Private at_Sound As AudioTrack
    Private b_Sounddata(), b_SoundQuietData(200000) As Byte
    Private SoundThread As Thread
End Sub

Sub Activity_Create(FirstTime As Boolean)
   
    'The Beatsound should be a short mono Wavefile with normal 16 Bit and Samplerate 44.100
    Dim allbytes() As Byte = File.ReadBytes(File.DirAssets, "t2.wav")
    Dim iFirstByte As Int = 44 'first byte after wave-header
    Dim iAnzBytes As Int = allbytes.Length - iFirstByte
    Dim sounddata(iAnzBytes) As Byte
    ConverterByte.ArrayCopy(allbytes, iFirstByte, sounddata, 0, iAnzBytes)
    b_Sounddata = sounddata
   
    at_Sound.Initialize(at_Sound.Stream_Music, 44100, at_Sound.CH_CONF_MONO, at_Sound.AF_PCM_16, 4410, at_Sound.Mode_Stream)
   at_Sound.Play
   SoundThread.Start(Me, "SoundThreadSub", Null)
End Sub

Sub SoundThreadSub
   Do While i_Milliseconds > 0
       'SoundThread.RunOnGuiThread("BeatShow", Null)
      
       Dim iSilinceLen As Int = i_Milliseconds * 2 * 44.1 - b_Sounddata.Length
       at_Sound.WriteByte(b_SoundQuietData, 0, iSilinceLen)
       at_Sound.WriteByte(b_Sounddata, 0, b_Sounddata.Length)
   Loop
End Sub

The metrum means beats per minute, so the milliseconds you get with 60000 / metrum. With a Sub "BeatShow" you can also show the beat in the UI.
The code writes the beats and the silence between it directly to the soundstream.
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
One of the first projects I created with B4a was a metronome, long before the hardware was fast enough to do audio effectively. I created a midi file and played that. Then I created the MidiLib and used that to create midi in realtime. Well done. I'm glad you got it working.
 
Top