Sign in to follow this  
Followers 0
ProgAndy

SAPI 5.1 quite full example

20 posts in this topic

#1 ·  Posted (edited)

I converted one example from the SAPI SDK to AutoIT, it's not full completed, but the most important things are done :)

;[INCLUDES]
#include <GUIConstants.au3>
#include <GUIComboBoxEx.au3>
#Include <GuiImageList.au3>
#include <GUIEdit.au3>

;[OPTIONS]
Opt("GUIOnEventMode",1)

;[GLOBALS]
Global $m_bPaused = False, $m_bSpeaking = False
Global Enum Step *2 $SPF_ASYNC,             _
    $SPF_PURGEBEFORESPEAK,  _
    $SPF_IS_FILENAME,       _
    $SPF_IS_XML,  _
    $SPF_IS_NOT_XML, _       
    $SPF_PERSIST_XML, _
    $SPF_NLP_SPEAK_PUNC,    _
    $SPF_NLP_MASK,         _
    $SPF_VOICE_MASK,       _
    $SPF_UNUSED_FLAGS 
Global $m_speakFlags = BitOR($SPF_ASYNC,$SPF_IS_XML,$SPF_PURGEBEFORESPEAK)

;[OBJECTS]
Global $voice = ObjCreate("SAPI.SpVoice")
$oMyError = ObjEvent("AutoIt.Error","_COMError")

#region - GUI Create
$GUI = GUICreate('SAPI Test')
GUISetOnEvent($GUI_EVENT_CLOSE,"_Exit")
;~ $mnu_File = GUICtrlCreateMenu("File")
$list = GUICtrlCreateCombo("",10,10,100,100,$CBS_DROPDOWNLIST)
GUICtrlCreateLabel("Volume:",10,40,50,20)
$VolumeSldr = GUICtrlCreateSlider(60,40,200,20)
GUICtrlSetLimit(-1,100,0)
GUICtrlSetOnEvent(-1,"VolumeSldr_Scroll")
GUICtrlCreateLabel("Rate:",10,80,50,20)
$RateSldr = GUICtrlCreateSlider(60,80,200,20)
GUICtrlSetLimit(-1,15,-15)
GUICtrlSetOnEvent(-1,"RateSldr_Scroll")
$b_Speak = GUICtrlCreateButton("Speak",10,110,50)
GUICtrlSetOnEvent(-1,"_SpeakStart")
$b_Pause = GUICtrlCreateButton("Pause",60,110,50)
GUICtrlSetState(-1,$GUI_DISABLE)
GUICtrlSetOnEvent(-1,"PauseBtn_Click")
$b_Stop = GUICtrlCreateButton("Stop",120,110,50)
GUICtrlSetOnEvent(-1,"StopBtn_Click")
GUICtrlSetState(-1,$GUI_DISABLE)
$Text = GUICtrlCreateEdit("Text to speak",10,140,200,100)
$hMainTxtBox = GUICtrlGetHandle($Text)
$Img = GUICtrlCreatePic(@ScriptDir & "\avatar.gif",270,0,128,128)
$hPicBox = GUICtrlGetHandle($Img)
$hDebugTxtBox = _GUICtrlEdit_Create($GUI,"",10,270,380,130,$GUI_SS_DEFAULT_EDIT+$ES_READONLY)
$chkEvents = GUICtrlCreateCheckbox("Show Events",15,250,100,20)
GUISetState()
#endregion
GUICtrlCreateGroup("Speak Options",212,130,180,135)
GUICtrlCreateCheckbox("IsXML",217,143)
GUICtrlSetState(-1,$GUI_CHECKED)
GUICtrlSetOnEvent(-1,"chkSpFlagIsXML_Click")
GUICtrlCreateCheckbox("PersistXML",217,163)
GUICtrlSetOnEvent(-1,"chkSpFlagPersistXML_Click")
GUICtrlCreateCheckbox("IsFileName",217,183)
$chkSpFlagIsFilename = GUICtrlSetOnEvent(-1,"chkSpFlagIsFilename_Click")
GUICtrlCreateCheckbox("FlagsAsync",217,203)
GUICtrlSetState(-1,$GUI_CHECKED)
GUICtrlSetOnEvent(-1,"chkSpFlagAync_Click")
GUICtrlCreateCheckbox("PurgeBeforeSpeak",217,223)
GUICtrlSetOnEvent(-1,"chkSpFlagPurgeBeforeSpeak_Click")
GUICtrlSetState(-1,$GUI_CHECKED)
GUICtrlCreateCheckbox("NLPSpeakPunc",217,243)
GUICtrlSetOnEvent(-1,"chkSpFlagNLPSpeakPunc_Click")
GUICtrlCreateGroup ("",-99,-99,1,1)  ;close group

$ImgList = _GUIImageList_Create(128,128,6,1,1,14)
$hDC = _WinAPI_GetDC (GUICtrlGetHandle($Img))
_AddBmpList()

GUICtrlSetData($RateSldr, $Voice.Rate)
GUICtrlSetData($VolumeSldr, $Voice.Volume)

$x = ""
    For $Token In $Voice.GetVoices
        $x &= "|" & ($Token.GetDescription())
    Next
GUICtrlSetData($list,$x,"Microsoft Sam")
GUICtrlSetOnEvent($list,"VoiceCB_Click")
VoiceCB_Click()

ObjEvent($voice,"Voice_")
#region - GUI SelectLoop
While 1
    Sleep(100)
WEnd
#endregion
Func _Exit()
    StopBtn_Click()
    $voice = 0
    Exit
EndFunc
Func _SpeakStart()
    If $m_bPaused Then
        $Voice.Resume
        Return SetSpeakingState($m_bSpeaking, False)
    ElseIf $m_bSpeaking Then
        Return
    EndIf
    $Voice.Speak(GUICtrlRead($Text),$m_speakFlags)
    If @error <> 0 Then Return AddDebugInfo("Error on SpeakStart")
    $m_bSpeaking = True
    SetSpeakingState($m_bSpeaking, False)
    AddDebugInfo ("Speak")
EndFunc


Func Voice_Viseme($StreamNum , _
                         $StreamPos, _
                         $Duration , _
                         $VisemeType, _
                         $Feature , _
                         $VisemeId)
    
    ShowEvent( "Viseme", "StreamNum=" & $StreamNum, "StreamPos=" & $StreamPos, _
            "Duration=" & $Duration, "VisemeType=" & $VisemeType, _
            "Feature=" & $Feature, "VisemeId=" & $VisemeId)
    
;~     ' Here we are going to show different mouth positions according to the viseme.
;~     ' The picture we show doesn't necessarily match the real mouth position.
;~     ' Just trying to make it more interesting.

    _WinAPI_RedrawWindow($hPicBox)
    _GUIImageList_Draw($ImgList,$VisemeId,$hDC,0,0)
;~     VisemePicture.Picture = MouthImgList.Overlay("MICFULL", VisemeId)
    If (Mod($VisemeId, 6) = 2) Then
        _GUIImageList_Draw($ImgList,21,$hDC,0,0);VisemePicture.Picture = MouthImgList.Overlay("MICFULL", "MICEYECLOSED")
    ElseIf (Mod($VisemeId , 6) = 5) Then
            _GUIImageList_Draw($ImgList,22,$hDC,0,0);Set VisemePicture.Picture = MouthImgList.Overlay("MICFULL", "MICEYENARROW")
    EndIf
;~  ConsoleWrite(Mod($VisemeId, 6)  & @CRLF)
EndFunc

Func PauseBtn_Click()
    Switch $m_bPaused
        
    Case False
;~         AddDebugInfo "Pause"
        $Voice.Pause()
        If @error <> 0 Then Return AddDebugInfo("Error on SpeakPause")
        SetSpeakingState( $m_bSpeaking, True)
        AddDebugInfo ("Pause")
    
    Case True
;~         AddDebugInfo "Resume"
        $Voice.Resume()
        If @error <> 0 Then Return AddDebugInfo("Error on SpeakResume")
        SetSpeakingState($m_bSpeaking, False)
        AddDebugInfo ("Resume")

    EndSwitch
EndFunc


Func SetSpeakingState($bSpeaking , $bPaused)
;~     ' change state of menu items and buttons accordingly
;~     menuFileOpenText.Enabled = Not bSpeaking
;~     menuFileSpeakWave.Enabled = Not bSpeaking
;~     menuFileSaveToWave.Enabled = Not bSpeaking
    
    Local $statear[2] = [$GUI_DISABLE,$GUI_ENABLE]
    GUICtrlSetState($b_Speak,$statear[Not $bSpeaking])
    GUICtrlSetState($b_Pause,$statear[$bSpeaking])
    GUICtrlSetState($b_Stop,$statear[$bSpeaking])
    
;~     SpeakBtn.Enabled = True
    
;~     StopBtn.Enabled = bSpeaking
;~     SkipBtn.Enabled = (bSpeaking And Not bPaused)
;~     PauseBtn.Enabled = bSpeaking
    
    If $bPaused Then
        GUICtrlSetData($b_Pause, "Resume")
    Else
        GUICtrlSetData($b_Pause, "Pause")
    EndIf
    
    $m_bSpeaking = $bSpeaking
    $m_bPaused = $bPaused
EndFunc


Func RateSldr_Scroll()
    $Voice.Rate = GUICtrlread($RateSldr)
    If @error <> 0 Then Return AddDebugInfo("Error on Speak Rate")
EndFunc

Func StopBtn_Click()
;~     On Error GoTo ErrHandler
    AddDebugInfo ("Stop")
    
;~     ' when string to speak is NULL and dwFlags is set to SPF_PURGEBEFORESPEAK
;~     ' it indicates to SAPI that any remaining data to be synthesized should
;~     ' be discarded.
    If $m_bPaused Then $Voice.Resume
    
    If $m_bSpeaking Then $Voice.Speak (Chr(0), $SPF_PURGEBEFORESPEAK)
    
    
    SetSpeakingState( False, False)
    
;~     AddDebugInfo( "Speak Error: ", Err.Description
EndFunc

Func Voice_AudioLevel($StreamNumber , _
                             $StreamPosition , _
                             $AudioLevel )
    ShowEvent( "AudioLevel", "StreamNumber=" & $StreamNumber, _
            "StreamPosition=" & $StreamPosition, "AudioLevel=" & $AudioLevel)
EndFunc

Func Voice_Bookmark($StreamNumber , _
                           $StreamPosition , _
                           $Bookmark , _
                           $BookmarkId )
    ShowEvent ("BookMark", "StreamNumber=" & $StreamNumber, _
            "StreamPosition=" & $StreamPosition, "Bookmark=" & $Bookmark, _
            "BookmarkId=" & $BookmarkId)
EndFunc

Func Voice_EndStream($StreamNum , $StreamPos)
    ShowEvent( "EndStream", "StreamNum=" & $StreamNum, "StreamPos=" & $StreamPos)
    AddDebugInfo("STOP")

;~     ' select all text to indicate that we are done
    HighLightSpokenWords( 0, _GUICtrlEdit_GetTextLen($hMainTxtBox))
    
;~     ' reset the mouth
;~     Set VisemePicture.Picture = MouthImgList.Overlay("MICFULL", "MICFULL")
_WinAPI_RedrawWindow($hPicBox)
    
;~     ' reset the state of buttons, checkboxes and menu items
    SetSpeakingState( False, $m_bPaused)
EndFunc

Func Voice_EnginePrivate($StreamNumber , _
                                $StreamPosition , _
                                $lParam )
    ShowEvent( "EnginePrivate", "StreamNumber=" & $StreamNumber, _
            "StreamPosition=" & $StreamPosition, "lParam=" & $lParam)
EndFunc

Func Voice_Phoneme($StreamNumber, _
                          $StreamPosition, _
                          $Duration , _
                          $NextPhoneId , _
                          $Feature , _
                          $CurrentPhoneId )
    ShowEvent ("Phoneme", "StreamNumber=" & $StreamNumber, _
            "StreamPosition=" & $StreamPosition, "NextPhoneId=" & $NextPhoneId, _
            "Feature=" & $Feature, "CurrentPhoneId=" & $CurrentPhoneId)
EndFunc

Func Voice_Sentence($StreamNum , _
                           $StreamPos , _
                           $Pos , _
                           $Length )
    ShowEvent ("Sentence", "StreamNum=" & $StreamNum, "StreamPos=" & $StreamPos, _
            "Pos=" & $Pos, "Length=" & $Length)
EndFunc

Func Voice_StartStream($StreamNum, $StreamPos)
    ShowEvent( "StartStream", "StreamNum=" & $StreamNum, "StreamPos=" & $StreamPos)
    
;~     ' reset the state of buttons, checkboxes and menu items
    SetSpeakingState( True, $m_bPaused)
EndFunc


Func Voice_VoiceChange($StreamNum, _
                              $StreamPos, _
                              $Token )
    
    ShowEvent( "VoiceChange", "StreamNum=" & $StreamNum, "StreamPos=" & $StreamPos, _
            "Token=" & $Token.GetDescription)
    
;~     ' Let's sync up the combo box with the new value
    Local $i, $t
    For $i = 0 To _GUICtrlComboBoxEx_GetCount($list)
        $t =  _GUICtrlComboBoxEx_GetItemText($list,$i,$t)
        If $t = $Token.GetDescription() Then
            _GUICtrlComboBoxEx_SetCurSel($list,$i)
            Return
        EndIf
    Next
EndFunc

Func Voice_Word($StreamNum, _
                       $StreamPos , _
                       $Pos , _
                       $Length )
                       
    ShowEvent( "Word", "StreamNum=" & $StreamNum, "StreamPos=" & $StreamPos, _
            "Pos=" & $Pos, "Length=" & $Length)
    Local $mmt = _GUICtrlEdit_GetSel($hMainTxtBox)
    Debug( $Pos, $Length, $mmt[0], $mmt[1])
    
;~     ' Select the word that's currently being spoken.
    HighLightSpokenWords( $Pos, $Length)
EndFunc

Func VoiceCB_Click()
;~     ' change the voice to the selected one
;~     Set Voice.Voice = Voice.GetVoices().Item(VoiceCB.ListIndex)
    $Voice.Voice = $Voice.GetVoices().Item(_GUICtrlComboBoxEx_GetCurSel(GUICtrlGetHandle($list)))
EndFunc

Func VolumeSldr_Scroll()
    $Voice.Volume = GUICtrlread($VolumeSldr)
EndFunc

;~ ' The following functions are simply to sync up the speak flags.
;~ ' When the check box is checked, the corresponding bit is set in the flags.
Func chkSpFlagAync_Click()
;~     m_speakFlags = SetOrClearFlag(chkSpFlagAync.Value, m_speakFlags, SVSFlagsAsync)
    $m_speakFlags = SetOrClearFlag(_IsChecked(@GUI_CtrlId),$m_speakFlags,$SPF_ASYNC)
EndFunc

Func chkSpFlagIsFilename_Click()
;~     m_speakFlags = SetOrClearFlag(chkSpFlagIsFilename.Value, m_speakFlags, SVSFIsFilename)
    $m_speakFlags = SetOrClearFlag(_IsChecked(@GUI_CtrlId),$m_speakFlags,$SPF_IS_FILENAME)
EndFunc

Func chkSpFlagIsXML_Click()
;~     ' Note: special case here. There are two flags,SVSFIsXML and SVSFIsNotXML.
;~     ' When neither is set, SAPI will guess by peeking at beginning characters.
;~     ' In this sample, we explicitly set one of them.
;~     
    If _IsChecked(@GUI_CtrlId) Then
;~         ' clear SVSFIsNotXML bit and set SVSFIsXML bit
        $m_speakFlags = SetOrClearFlag(0,$m_speakFlags,$SPF_IS_NOT_XML)
        $m_speakFlags = SetOrClearFlag(1,$m_speakFlags,$SPF_IS_XML)
;~         m_speakFlags = m_speakFlags And Not SVSFIsNotXML
;~         m_speakFlags = m_speakFlags Or SVSFIsXML
    Else
;~         ' clear SVSFIsXML bit and set SVSFIsNotXML bit
        $m_speakFlags = SetOrClearFlag(1,$m_speakFlags,$SPF_IS_NOT_XML)
        $m_speakFlags = SetOrClearFlag(0,$m_speakFlags,$SPF_IS_XML)
;~      m_speakFlags = m_speakFlags And Not SVSFIsXML
;~         m_speakFlags = m_speakFlags Or SVSFIsNotXML
    EndIf
EndFunc

Func chkSpFlagNLPSpeakPunc_Click()
;~     m_speakFlags = SetOrClearFlag(chkSpFlagNLPSpeakPunc.Value, m_speakFlags, SVSFNLPSpeakPunc)
    $m_speakFlags = SetOrClearFlag(_IsChecked(@GUI_CtrlId),$m_speakFlags,$SPF_NLP_SPEAK_PUNC)
EndFunc

Func chkSpFlagPersistXML_Click()
;~     m_speakFlags = SetOrClearFlag(chkSpFlagPersistXML.Value, m_speakFlags, SVSFPersistXML)
    $m_speakFlags = SetOrClearFlag(_IsChecked(@GUI_CtrlId),$m_speakFlags,$SPF_PERSIST_XML)
EndFunc

Func chkSpFlagPurgeBeforeSpeak_Click()
;~     m_speakFlags = SetOrClearFlag(chkSpFlagPurgeBeforeSpeak.Value, m_speakFlags, SVSFPurgeBeforeSpeak)
    $m_speakFlags = SetOrClearFlag(_IsChecked(@GUI_CtrlId),$m_speakFlags,$SPF_PURGEBEFORESPEAK)
EndFunc

Func AddDebugInfo($DebugStr, $Error = "")
;~     ' This function adds debug string to the info window.
    
;~     ' First of all, let's delete a few charaters if the text box is about to
;~     ' overflow. In this sample we are using the default limit of charaters.
    If _GUICtrlEdit_GetTextLen($hDebugTxtBox) > 64000 Then
;~         Debug.Print 
        ConsoleWrite("Too much stuff in the debug window. Remove first 10K chars" & @CRLF)
;~         DebugTxtBox.SelStart = 0
;~         DebugTxtBox.SelLength = 10240
;~         DebugTxtBox.SelText = ""
        _GUICtrlEdit_SetSel($hDebugTxtBox,0,10240)
        _GUICtrlEdit_ReplaceSel($hDebugTxtBox,"",False)
    EndIf
    
;~     ' append the string to the DebugTxtBox text box and add a newline
;~     DebugTxtBox.SelStart = Len(DebugTxtBox.Text)
;~     DebugTxtBox.SelText = DebugStr & Error & vbCrLf
    _GUICtrlEdit_AppendText($hDebugTxtBox,$DebugStr & $Error & @CRLF)
EndFunc

Func ShowEvent($Param1,$Param2="",$Param3="",$Param4="",$Param5="",$Param6="",$Param7="",$Param8="")
;~     ' we will only show the events if the ShowEvents box is checked
    If _IsChecked($chkEvents) Then
        Local $strText, $i
        For $i = 1 To 8
            $strText &= Eval("Param"&$i) & ", "
        Next
;~      strText = Join(strArray, ", ")
        AddDebugInfo( "  Event: " & $strText)
    EndIf
EndFunc

Func HighLightSpokenWords($Pos , $Length )


;~     ' Only high light when the MainTxtBox is actually showing the spoken text,
;~     ' instead of file name
    If Not _IsChecked($chkSpFlagIsFilename) Then
        GUICtrlSetState($Text,$GUI_FOCUS)
        _GUICtrlEdit_BeginUpdate($hMainTxtBox)
        _GUICtrlEdit_SetSel($Text,$Pos,$Length+$Pos)
;~      MsgBox(0, '', @error)
        _GUICtrlEdit_EndUpdate($hMainTxtBox)
;~      Sleep(1000)
        If @error Then  AddDebugInfo( "Failed to high light words. This may be caused by too many charaters in the main text box.")
;~         MainTxtBox.SelLength = Length
    EndIf
    
;~ ErrHandler:
;~     AddDebugInfo( "Failed to high light words. This may be caused by too many charaters in the main text box.")
EndFunc

;~ ' This following helper function will set or clear a bit (flag) in the given
;~ ' integer (base) according to the condition (cond). If cond is 0, the bit
;~ ' is cleared. Otherwise, the bit is set. The resulting integer is returned.
Func SetOrClearFlag($cond, _
                    $base, _
                        $flag)
    
    If $cond = 0 Then
;~         ' the condition is false, clear the flag
;~         Return BitOR($base, BitNOT($flag))
        BitXOR($base,$flag,$flag)
    Else
;~         ' the condition is false, set the flag
        Return BitOR($base ,$flag)
    EndIf
EndFunc



;~ Public Function GetDirectory() As String

;~     Err.Clear

;~     On Error GoTo ErrHandler

;~     Dim DataKey As ISpeechDataKey
;~     Dim Category As New SpObjectTokenCategory
;~     
;~     'Get the sdk installation location from the registry
;~     'The value is under "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech". The string name is SDKPath"
;~     Category.SetId SpeechRegistryLocalMachineRoot
;~     Set DataKey = Category.GetDataKey
;~     GetDirectory = DataKey.GetStringValue("SDKPath")
;~     GetDirectory = GetDirectory + "samples\common"
;~     
;~     
;~     
;~ ErrHandler:
;~     If Err.Number <> 0 Then
;~         GetDirectory = ""
;~     End If
;~ End Function


; #FUNCTION# ====================================================================================================================
; Name...........: _GUIImageList_AddBitmap
; Description ...: Adds a bitmap to an image list
; Syntax.........: _GUIImageList_AddBitmap($hWnd, $sImage[, $sMask=""])
; Parameters ....: $hWnd        - Handle to the control
;                  $sImage      - Path to the bitmap that contains the image
;                  $sMask       - Path to the bitmap that contains the mask
; Return values .: Success      - The index of the image
;                  Failrue      - -1
; Author ........: Paul Campbell (PaulIA)
; Modified.......:
; Remarks .......:
; Related .......: _GUIImageList_Add, _GUIImageList_AddIcon
; Link ..........;
; Example .......; Yes
; ===============================================================================================================================
Func _GUIImageList_AddBitmapMasked($hWnd, $sImage, $iMask = 0)
    Local $hImage, $aSize, $iResult

    $aSize = _GUIImageList_GetIconSize($hWnd)
    $hImage = _WinAPI_LoadImage(0, $sImage, $IMAGE_BITMAP, $aSize[0], $aSize[1], $LR_LOADFROMFILE)
    If $hImage = 0 Then Return SetError(_WinAPI_GetLastError(), 1, -1)
    $iResult = _GUIImageList_AddMasked($hWnd, $hImage, $iMask)
;~  $iResult = _GUIImageList_Add($hWnd, $hImage, $hMask)
    _WinAPI_DeleteObject($hImage)

    Return $iResult
EndFunc   ;==>_GUIImageList_AddBitmap

Func _IsChecked($GUICtrl)
    Return (BitAND(GUICtrlRead($GUICtrl),$GUI_CHECKED) = $GUI_CHECKED)
EndFunc

Func _AddBmpList()
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_15.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_2.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_2.bmp"),0xFF00FF)
    
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_2.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_1.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_2.bmp"),0xFF00FF)
    
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_12.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_5.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_4.bmp"),0xFF00FF)
    
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_12.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_3.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_2.bmp"),0xFF00FF)
    
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_12.bmp"),0xFF00FF) ;---s
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_6.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_9.bmp"),0xFF00FF)
    
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_10.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_11.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_8.bmp"),0xFF00FF)
    
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_7.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_10.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_12.bmp"),0xFF00FF)
    
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_2.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_13.bmp"),0xFF00FF)
    _GUIImageList_AddBitmapMasked($ImgList,FileGetShortName(@ScriptDir&"\bitmap_14.bmp"),0xFF00FF)

EndFunc

Func Debug($Param1,$Param2="",$Param3="",$Param4="",$Param5="",$Param6="",$Param7="",$Param8="")
    Local $strText
    For $i = 1 To 8
        $strText &= Eval("Param"&$i) & ", "
    Next
    ConsoleWrite("#Debug: " & $strText & @CRLF)
EndFunc
Func _COMError()
;~   Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"      & @CRLF  & @CRLF & _
;~              "err.description is: "    & @TAB & $oMyError.description    & @CRLF & _
;~              "err.windescription:"     & @TAB & $oMyError.windescription & @CRLF & _
;~              "err.number is: "         & @TAB & hex($oMyError.number,8)  & @CRLF & _
;~              "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
;~              "err.scriptline is: "     & @TAB & $oMyError.scriptline     & @CRLF & _
;~              "err.source is: "         & @TAB & $oMyError.source         & @CRLF & _
;~              "err.helpfile is: "       & @TAB & $oMyError.helpfile       & @CRLF & _
;~              "err.helpcontext is: "    & @TAB & $oMyError.helpcontext _
;~             )
            
    Local $err = $oMyError.number
    If $err = 0 Then $err = -1
    Debug("Com Error", "Description: " & $oMyError.description, "ErrNumber: " & $oMyError.number)
    SetError($err)  ; to check for after this function returns
EndFunc

//Edit: Fixed: Replay after ending in paused state

Speech.zip

Edited by ProgAndy
1 person likes this

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites



Excellent job!

Here's some issues I've encountered.

1. If I press play and then pause button it will not output any sound after, pressing stop makes it freeze.

2. Changing the pitch to higher or lower will cause the animation/the entire window to be out of sync with the sound.


Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

Share this post


Link to post
Share on other sites

There was an error in _SpeakStart() Replace it with this:

Func _SpeakStart()
    If $m_bPaused Then
        $Voice.Resume
        Return SetSpeakingState($m_bSpeaking, False)
    ElseIf $m_bSpeaking Then
        Return
    EndIf
    $Voice.Speak(GUICtrlRead($Text),$m_speakFlags)
    If @error <> 0 Then Return AddDebugInfo("Error on SpeakStart")
    $m_bSpeaking = True
    SetSpeakingState($m_bSpeaking, False)
    AddDebugInfo ("Speak")
EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

This is pretty good.

This works with no problems when pasted into the "Text to speak" box:-

CODE
<voice required="name = Microsoft Sam">

This is a test.

<voice required="name = LH Michelle">

This is a test.

Now, if you could get in-line commands like {{Pause=1}} to work, that would be better than pretty good.

Share this post


Link to post
Share on other sites

How can i use a french voice ?

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Here's a patch to install German and French TTS-Language :)

RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ebook","Version")
If @error Then
    RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ebook","Version","REG_SZ","2.2")
    If MsgBox(36,'SAPI Language Install Patch',"Open Download-Page for TTS-Languages ?") = 6 Then ShellExecute("http://www.microsoft.com/reader/developers/downloads/tts.aspx")
    MsgBox(0, 'SAPI Language Install Patch', "Now install the Language-Pack from " & @CRLF & "http://www.microsoft.com/reader/developers/downloads/tts.aspx" & @CRLF & @CRLF & "Then click OK after installation.")
    RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ebook")
Else
    MsgBox(0, 'SAPI Language Install Patch', "You already ahve installed the Microsoft Reader, so no Patch is needed. "&@CRLF&"possibly you have to download the newest version from "&@CRLF&"http://www.microsoft.com/reader/")
EndIf
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Sorry to revive an old thread... ^_^

I can't get this to run properly, I added the WinAPI include... but it only modified the error slightly.... I know there is an include I'm missing here...

C:\Users\BinaryBrother\Documents\My Dropbox\Public\ProgAndy\Speech.au3(485,58) : WARNING: $IMAGE_BITMAP: possibly used before declaration.

$hImage = _WinAPI_LoadImage(0, $sImage, $IMAGE_BITMAP,

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

C:\Users\BinaryBrother\Documents\My Dropbox\Public\ProgAndy\Speech.au3(485,98) : WARNING: $LR_LOADFROMFILE: possibly used before declaration.

$hImage = _WinAPI_LoadImage(0, $sImage, $IMAGE_BITMAP, $aSize[0], $aSize[1], $LR_LOADFROMFILE)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

C:\Users\BinaryBrother\Documents\My Dropbox\Public\ProgAndy\Speech.au3(485,58) : ERROR: $IMAGE_BITMAP: undeclared global variable.

$hImage = _WinAPI_LoadImage(0, $sImage, $IMAGE_BITMAP,

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

C:\Users\BinaryBrother\Documents\My Dropbox\Public\ProgAndy\Speech.au3 - 1 error(s), 2 warning(s)

[EDIT]

I seem to have got it working declaring $IMAGE_BITMAP & $LE_LOADFROMFILE, and setting the variables as '1'... But that gives me a new array of COM errors... :huh2:

[/EDIT]

#Debug: Com Error, Description: , ErrNumber: -2147352571, , , , , ,

#Debug: Com Error, Description: , ErrNumber: -2147352571, , , , , ,

#Debug: 0, 4, 13, 13, , , , ,

#Debug: 5, 2, 0, 4, , , , ,

#Debug: 8, 5, 5, 7, , , , ,

P.S. I love your work ProgAndy, thanks (once again) for your hard-work... and for everyone else, please... No 'utter newb' comments... I believe I have respectfully worked my way up to 'Newb' with a capital 'N'. :) <--- after years of this... C'mon... Just give me the capital already... :) Edited by BinaryBrother

Share this post


Link to post
Share on other sites

There is one include missing: #include <Constants.au3>


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

Once again nice work ProgAndy!

Thanks,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

maybe some one can help me figure this out ... causei've been racking my brian for a while searching include files for a duplicate function named "_SendMessage"

if yall can help i'd love to hear it ...because with this script that you have posted wont work either i get this message

C:\AutoIt3\Include\Misc.au3 (442) : ==> Duplicate function name.:

Func _SendMessage($h_hWnd, $i_msg, $wParam = 0, $lParam = 0, $i_r = 0, $s_t1 = "int", $s_t2 = "int")

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Extremely simple text to speech, using default voice, volume, and rate.

Global $voice = ObjCreate("SAPI.SpVoice")
$string = "text to speech"
$Voice.Speak($string,11)
Sleep(1000)

Voices are enumerated alphabetically on your system, it appears. At any rate, this snippet will speak "text to speech" and then exit. This next example demonstrates slightly finer control: you can specify voice, volume, and rate.

Global $voice = ObjCreate("SAPI.SpVoice")
$Voice.Volume = 100
$Voice.Voice = $Voice.GetVoices().Item(1)
$Voice.Rate = 4
$string = "text to speech"
$Voice.Speak($string,11)
Sleep(1000)

This one is particularly amusing.

Global $voice = ObjCreate("SAPI.SpVoice")
$Voice.Volume = 100
$Voice.Voice = $Voice.GetVoices().Item(0)
$Voice.Rate = 10
$string = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
$Voice.Speak($string,11)
Sleep(3000)

Anyhow, progandy's example is a lot better, I just thought I'd leave some snippets for others who want to use it in their applications.

Share this post


Link to post
Share on other sites

Hi ProgAndy!

Thank you for directing me here to look at your wonderful script!

There is a lot I need to learn. Do you have time to answer a few of my questions on how your script works? I still have a few other problems with my script.

Thank you for your help.

Share this post


Link to post
Share on other sites

#16 ·  Posted

In my code (and other examples I've looked at), when SAPI.Voice is reading text, my program is busy until the text is finished.

How are you able to pause and have other controls available even while the text is being read?

Has it something to do with this: $Voice.Speak(GUICtrlRead($Text),$m_speakFlags)

I do not use GuiCtrlRead and just pass $Text through. Also, what do the flags control in $m_speakFlags?

This is the best example of the SAPI.SPvoice! I don't need all of the functionality, but there are a few I would like to implement.

Thank you.

Share this post


Link to post
Share on other sites

#17 ·  Posted

$m_speakFlags is a combination of the $SPF_-flags. One of those is $SPF_ASYNC which defines asynchronous output.


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

$m_speakFlags is a combination of the $SPF_-flags. One of those is $SPF_ASYNC which defines asynchronous output.

Thank you! At first I didn't think I needed any flags because my app is pretty basic, but now that it has grown and I am using it to read multi-page documents, the ability to pause/resume is now necessary.

I will look more into Speech Voice Flags:

Definition

Enum SpeechVoiceSpeakFlags

'SpVoice Flags

SVSFDefault = 0

SVSFlagsAsync = 1

SVSFPurgeBeforeSpeak = 2

SVSFIsFilename = 4

SVSFIsXML = 8

SVSFIsNotXML = 16

SVSFPersistXML = 32

'Normalizer Flags

SVSFNLPSpeakPunc = 64

'TTS Format

SVSFParseSapi =

SVSFParseSsml =

SVSFParseAutoDetect =

'Masks

SVSFNLPMask = 64

SVSFParseMask =

SVSFVoiceMask = 127

SVSFUnusedFlags = -128

End Enum

SPF_(flags)

// SpVoice flags

SPF_DEFAULT = 0,

SPF_ASYNC = (1L << 0),

SPF_PURGEBEFORESPEAK = (1L << 1),

SPF_IS_FILENAME = (1L << 2),

SPF_IS_XML = (1L << 3),

SPF_IS_NOT_XML = (1L << 4),

SPF_PERSIST_XML = (1L << 5),

// Normalizer flags

SPF_NLP_SPEAK_PUNC = (1L << 6),

// Masks

SPF_NLP_MASK = (SPF_NLP_SPEAK_PUNC),

SPF_VOICE_MASK = (SPF_ASYNC|SPF_PURGEBEFORESPEAK|SPF_IS_FILENAME|

SPF_IS_XML|SPF_IS_NOT_XML|SPF_NLP_MASK|SPF_PERSIST_XML),

SPF_UNUSED_FLAGS = ~(SPF_VOICE_MASK)

} SPEAKFLAGS;

Edited by coffeeturtle

Share this post


Link to post
Share on other sites

$m_speakFlags is a combination of the $SPF_-flags. One of those is $SPF_ASYNC which defines asynchronous output.

Your example script helped me out a lot! Thank you for everything!

($stext, 1) was enough to get the asynchronous to work in my app. It was then easy to code Play/Pause/Resume/Stop.

My original problem was that I was clearing out my clipboard too quickly after an item was being read in asynchronous mode. Apparently, in synchronous mode the clipboard clear didn't matter since nothing was done until after the copied text was completely read.

Again, thank you for your great work!

Share this post


Link to post
Share on other sites

WARNING: $IMAGE_BITMAP: possibly used before declaration.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0