Android Question TTS isSpeaking listener

Branko Milosevic

Active Member
Licensed User
My app compiles a bunch of random words and silent periods between them and is successfully sent to the TTS engine. The play button needs to be disabled until speech is done and then immediately enabled.

There is a method isSpeaking that I use to test if speech has finished but needs to be in a loop keeping the main thread busy which I don't want.

How can I implement a listener with this:
B4X:
Dim jo As JavaObject = Starter.TTS1
  if jo.RunMethod("isSpeaking",Null) = false then log("done speaking")

this is the android listener:
B4X:
setOnUtteranceProgressListener
 

Branko Milosevic

Active Member
Licensed User
If you are using B4A v7 then you can use sleep to wait for it to change:
B4X:
Do While jo.RunMethod("isSpeaking",Null) = True
Sleep(100)
Loop
Log("done speaking")

Use a timer with older versions.
It's a 15 min long process, I was looking for a solution with an event listener to catch the event
 
Upvote 0

Branko Milosevic

Active Member
Licensed User
Nothing bad will happen with this loop even if it will run for 15 minutes. You can increase the timer interval to 1000ms.
Here is what I ended up with:
B4X:
timer1.Initialize("Timer1",1000)


Sub Timer1_Tick()
      Dim jo As JavaObject = Starter.TTS1
          If jo.RunMethod("isSpeaking",Null) = False Then
               timer1.Enabled=False
               button9.Enabled=True
           Else
                timer1.Enabled=True
                button9.Enabled=False
          End If
   
End Sub
 
Upvote 0

deantangNYP

Active Member
Licensed User
Longtime User
If you are using B4A v7 then you can use sleep to wait for it to change:
B4X:
Do While jo.RunMethod("isSpeaking",Null) = True
 Sleep(100)
Loop
Log("done speaking")

Use a timer with older versions.
Hi Erel, may i know where should i place this code//
 
Upvote 0

emexes

Expert
Licensed User
Here is what I ended up with:
B4X:
Sub Timer1_Tick()
    Dim jo As JavaObject = Starter.TTS1
    If jo.RunMethod("isSpeaking",Null) = False Then
        timer1.Enabled=False
        button9.Enabled=True
    Else
        timer1.Enabled=True
        button9.Enabled=False
    End If
End Sub

I feel like you could simplify this to:

B4X:
Sub CheckSpeakingTimer_Tick()

    Dim jo as JavaObject = Starter.TTS1
    If jo.RunMethod("isSpeaking", Null) then
        'still talking, so leave play button disabled and timer active
        '(good spot to hook in a talk-time display update)
    Else
        PlayButton.Enabled = True
        CheckSpeakingTimer.Enabled = False
        '(good spot to hook in a finished-talking event)
    End If

End Sub

assuming that you disable PlayButton and enable CheckSpeakingTimer when you first/next send text to TTS1.

If you're into brevity and just want the play button to automatically enable and disable itself, you could even:

B4X:
Sub CheckSpeakingTimer_Tick()

    Dim jo as JavaObject = Starter.TTS1
    PlayButton.Enabled = (jo.RunMethod("isSpeaking", Null) = False)

End Sub
 
Last edited:
Upvote 0

deantangNYP

Active Member
Licensed User
Longtime User
I feel like you could simplify this to:

B4X:
Sub CheckSpeakingTimer_Tick()

    Dim jo as JavaObject = Starter.TTS1
    If jo.RunMethod("isSpeaking", Null) then
        'still talking, so leave play button disabled and timer active
        '(good spot to hook in a talk-time display update)
    Else
        PlayButton.Enabled = True
        CheckSpeakingTimer.Enabled = False
        '(good spot to hook in a finished-talking event)
    End If

End Sub

assuming that you disable PlayButton and enable CheckSpeakingTimer when you first/next send text to TTS1.

If you're into brevity and just want the play button to automatically enable and disable itself, you could even:

B4X:
Sub CheckSpeakingTimer_Tick()

    Dim jo as JavaObject = Starter.TTS1
    PlayButton.Enabled = (jo.RunMethod("isSpeaking", Null) = False)

End Sub

Many Thanks. will try
 
Upvote 0

emexes

Expert
Licensed User
If you use the autonomous one:

B4X:
Sub CheckSpeakingTimer_Tick()

    Dim jo as JavaObject = Starter.TTS1
    PlayButton.Enabled = Not(jo.RunMethod("isSpeaking", Null))

End Sub

then remember you don't want this timer running if TTS1 is not operational, so make sure to start the timer AFTER you've initialized TTS1.

Also it is recommended to disable (pause) timers in the activity Pause event, and reenable them in the Resume event, to maximize battery life... so keep an eye out to make sure that you don't accidentally start the timer in the Resume event if TTS1 is not yet active. You'd think such things are impossible, but I'm speaking from experience when I say that impossible things bite hardest.

;-)
 
Last edited:
Upvote 0
Top