Android Question Synchronising audio and graphics

Arf

Well-Known Member
Licensed User
Longtime User
I am trying to draw a series of png's onto around half the screen area, like this:
B4X:
ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step1.jpg")
and at the same time playing a 'tick' sound.

This repeats quickly, imagine lke a random spinning number slot machine stylee.

The audio and video doesn't sync though, is there a strategy that I can emply to make them sync?

Also, is PNG drawing slower than bitmap, or what should I do to optimise this?
 

Arf

Well-Known Member
Licensed User
Longtime User
I'll try preload the images as a list - thought they were png but realised I switched to jpgs.
I'm not using a timer, I'm using Sleep(ms) to delay in between iterations within the 'Spin' function, so the time between each image and sound update is the time taken to play the tick (I also use a Sleep() while Isplaying loop to wait till playing ends, rightly or wrongly), and the additional delay contributed by the Sleep(ms) thereafter - this ms number increments so the spins get slower over time.

My background is embedded C in microcontrollers so the whole completely event driven format is something I'm getting used to.

B4X:
Sub Spin
    Dim time As Float
    Dim reps As Int
    Dim Num As Int
    Dim LastNum As Int
   
    time = 10
    reps = 20
   
    Do While reps <> 0
        reps = reps - 1
        Do While Num = LastNum
            Num = Rnd(1, 17)
        Loop
       
        DrawOutcome(Num)

        LastNum = Num
        CallSub(listen,"PlayTick")
        Sleep(time)
        If reps < 6 Then
            time = time * 4.5
        End If
    Loop
    listen.Spun = Num
End Sub

Sub DrawOutcome(Which As Int)
    Select Case Which
        Case 1
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step1.jpg")
        Case 2
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step2.jpg")
        Case 3
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step3.jpg")
        Case 4
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step4.jpg")
        Case 5
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step5.jpg")
        Case 6
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step6.jpg")
        Case 7
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step7.jpg")
        Case 8
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step8.jpg")
        Case 9
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step9.jpg")
        Case 10
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step10.jpg")
        Case 11
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step11.jpg")
        Case 12
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step12.jpg")
        Case 13
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step13.jpg")
        Case 14
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step14.jpg")
        Case 15
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step15.jpg")
        Case 16
            ImageView1.Bitmap = LoadBitmap(File.DirAssets,"step16.jpg")
        Case Else
    End Select
End Sub

Sub Sleep(ms As Long)
Dim now As Long
   If ms > 1000 Then ms =1000   'avoid application not responding error
   now=DateTime.now
   Do Until (DateTime.now>now+ms)
     DoEvents
   Loop
End Sub

and then in the service module:
B4X:
Sub LoadTick
    MP.Load(File.DirAssets, "tick.wav")
End Sub

Sub PlayTick
    MP.Play
    WaitPlayFinish
End Sub

Sub WaitPlayFinish
    Do While MP.IsPlaying = True
        Sleep(5)   
    Loop
End Sub

I load the tick file before entering the spin function elsewhere in the code. I am guessing that the use of Sleep() is probably weaved into the problem with syncronisity that I'm seeing. Typically I see a bunch of image changes happen very quickly, then slow down as there is a whole bunch of ticks, then the situation improves as the time between ticks gets bigger.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
You'd be better off using a timer to drive the whole thing, and using Soundpool to play the sounds as it is a short sound.
 
  • Like
Reactions: Arf
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Using a list for the bitmaps and Soundpool for the audio did the trick, lovely and smooth now, thanks.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Ok, I'll convert to timer instead. By pausing the main thread you mean using Sleep, right?
I had just assumed it was non blocking as it had a 'DoEvents' in the waiting loop, but it just occurrred to me I don't know what
DoEvents does.
I best do some more reading!
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
By pausing the main thread you mean using Sleep, right?
i think he means this
B4X:
Do While MP.IsPlaying = True
        Sleep(5) 
    Loop

or similar

B4X:
Do While MP.IsPlaying = True
        DoEvents
    Loop

Try to avoid such code.
 
Upvote 0
Top