Highlight Text as it is Spoken (Graphic Control)

Category: Sound

Date: 02-16-2022

Return to Index


 
'Compilable Example:  (Jose Includes)
#Compiler PBWin 10
#Compile Exe
#Debug Display On
#Debug Error On
#Dim All
 
%IDC_Start   = 500
%IDC_Graphic = 501
%IDC_Stop    = 502
 
%Unicode=1
#Include "win32api.inc"
#Include "sapi.inc"
 
%Msg_SAPI_Event = %WM_User + 1
 
Global hDlg,hFont As Dword, wText As WString, pSp As ISpVoice
Global Words() As String, LineHeight As Long, gTemp$
 
Function PBMain() As Long
   Dialog New Pixels, 0, "SAPI Test",300,300,300,170, %WS_OverlappedWindow To hDlg
   Control Add Button, hDlg, %IDC_Start,"Start", 10,10,100,30
   Control Add Button, hDlg, %IDC_Stop,"Stop", 120,10,100,30
   Control Add Graphic, hDlg, %IDC_Graphic, "", 10,50,280,200, %WS_Border
   Graphic Attach hDlg, %IDC_Graphic, ReDraw
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   Local w,h As Long, nStart, nEnd As Dword
   Local eventItem As SPEVENT, eventStatus As SPVOICESTATUS
   Select Case Cb.Msg
      Case %WM_InitDialog
         pSp = NewCom "SAPI.SpVoice"
         pSp.SetInterest(SPFEI(%SPEI_WORD_BOUNDARY), SPFEI(%SPEI_WORD_BOUNDARY))
         pSp.SetNotifyWindowMessage(hDlg, %MSG_SAPI_EVENT, 0, 0)
 
         'set text, split into array
         ReDim Words(0 To 4)
         Words(1) = "Now is the time for all good"
         Words(2) = "men to register to vote and"
         Words(3) = "boot the bad men out on"
         Words(4) = "their backsides"
         wText    = Join$(Words(), $Spc)
 
         Font New "Tahoma",14,1 To hFont
         Control Set Font hDlg, %IDC_Start, hFont
         Control Set Font hDlg, %IDC_Stop, hFont
         Graphic Set Font hFont
         Graphic Width 5
         LineHeight = Graphic(Text.Size.Y,"X")
         DisplayWords
      Case %WM_Help
         ? gTemp$
      Case %WM_Size
         Dialog Get Client hDlg To w,h
         Control Set Size hDlg, %IDC_Graphic, w-20,h-60
      Case %WM_Command
         Select Case Cb.Ctl
            Case %IDC_Start
               DisplayWords
               pSp.Speak(ByVal StrPtr(wText), %SPF_Async, ByVal %Null)
               Exit Function
            Case %IDC_Stop
               wText = ""
               pSp.Speak(ByVal StrPtr(wText), %SVSFPurgeBeforeSpeak, ByVal %NULL)
               Exit Function
         End Select
      Case %Msg_SAPI_Event
         Do
            If pSp.GetEvents(1, eventItem, ByVal %NULL) <> %S_Ok Then Exit Do
            If eventItem.eEventId = %SPEI_WORD_BOUNDARY Then
               pSp.GetStatus(eventStatus, ByVal %NULL)
               nStart = eventStatus.ulInputWordPos
               nEnd = eventStatus.ulInputWordLen
               DisplayUnderLine nStart, nEnd
               Dialog Set Text hDlg, "Start: " & Str$(nStart) & " - Len: " & Str$(nEnd)
            End If
         Loop
   End Select
End Function
 
Sub DisplayWords
   Local i,iCount As Long, LineText As String
   Graphic Clear
   For i = 1 To 4
      LineText = Words(i)
      Replace $Lf With "In LineText           'wordwrap removes $CR
      Graphic Set Pos (0,LineHeight * iCount)   'get ready to print next line
      Graphic Print LineText
      Incr iCount
   Next i
   Graphic ReDraw
End Sub
 
Sub DisplayUnderLine(startChar As Long, WordLength As Long)
   Local i,x1,x2,y,LineNumber,CumChars,FirstChar As Long, CurrentWord$
   'get line number of startChar
   For i = 1 To UBound(Words)
      CumChars += Len(Words(i))+1
      If CumChars > startChar Then LineNumber = i : FirstChar = CumChars - Len(Words(i)) + 1 : Exit For
   Next i
   y = LineHeight * LineNumber                                                   'y position - current line
   x1 = Graphic(Text.Size.X,Mid$(wText,FirstChar To startChar-1))                'x1 position - start of current word
   x2 = x1 + Graphic(Text.Size.X,Mid$(wText,startChar To startChar+WordLength))  'x2 position - end of current word
   Graphic Line (x1,y)-(x2,y)
   Graphic ReDraw
End Sub
 


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm