Announcement

Collapse
No announcement yet.

Selecting the default voice for Text-To-Speech

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Selecting the default voice for Text-To-Speech

    Jim has kindly posted some code to allow text to speech output to a wav file. I have 3 voices installed on my system and I'm selecting the default voice in the control panel, however the speech file is always generated using the first one in the dropdown list in the control panel.

    https://forum.powerbasic.com/forum/u...ile-using-sapi

    Can anyone tell me how to select the default voice to use?

    THanks

  • #2
    Hey Steve!
    I know I posted some code here recently on that. Look for something like this ...

    Code:
       If FemaleVoice = 1 Then voice$$ = "Microsoft Zira Desktop - English (United States)"
       If FemaleVoice = 0 Then voice$$ = "Microsoft David Desktop - English (United States)"
       SpSetVoice(psp,voice$$)

    Comment


    • #3
      This is how I do it.

      Code:
            ' Get a reference to the SAPI ISpeechObjectTokens collection
            OBJECT CALL gdoSp.GetVoices( ) TO vRes
            IF ISFALSE OBJRESULT THEN
                LET oTokens = vRes
                vRes = EMPTY
                'Get the number of tokens
                OBJECT GET oTokens.Count TO vRes
                nCount = VARIANT#( vRes )
                'Parse the collection (zero based)
                FOR i = 0 TO nCount - 1
                    vIdx = i AS LONG
                    'Get the item by its index
                    OBJECT CALL oTokens.Item( vIdx ) TO vRes
                    IF ISFALSE OBJRESULT THEN
                        LET oToken = vRes
                        vRes = EMPTY
                        IF ISFALSE OBJRESULT THEN
                            'Get the description
                            OBJECT CALL oToken.GetDescription( ) TO vRes
                            IF ISFALSE OBJRESULT THEN
                                strDesc = VARIANT$( vRes )
                                ' If its the token we are after, set the Voice property
                                'MyVoiceName = "Microsoft Zira Desktop - English (United States)"
                                'MyVoiceName = "Microsoft Anna Desktop - English (United States)"
                                'MyVoiceName = "TOSHIBA male adult (U.S.)"
                                'MyVoiceName = "Microsoft David Desktop - English (United States)"
                                  IF strDesc = lsSpName THEN
                                    LET vToken = oToken
                                    OBJECT SET gdoSp.Voice = vToken
                                    LET oToken = NOTHING
                                    EXIT FOR
                                  END IF
                            END IF
                          LET oToken = NOTHING
                        END IF
                    END IF
                NEXT i
                LET oTokens = NOTHING
            END IF
      If strDesc = lsSpName then you have made the selection you want based on the text description (strDesc) of the voice. Where lsSpName is the target voice you want.

      Note: Any reference to gdoSp should be replaced with oVoice to match the Source Code app.
      And perhaps DIM oVoice AS DISPATCH
      You'll have to change other parts as well. Sorry nothing complete here.

      Comment


      • #4
        Steve you probably use something like this to get a list of the voices..

        Code:
        '_________________________________________________________________
        '
        ' SUB funGetVoices
        '_________________________________________________________________
        
        
        FUNCTION funGetVoices() AS STRING
        ' return the list of voices
          LOCAL vRes         AS VARIANT
          LOCAL vTxt         AS VARIANT
          LOCAL vTime        AS VARIANT
          LOCAL oTokens      AS DISPATCH
          LOCAL oToken       AS DISPATCH
          LOCAL vToken       AS VARIANT
          LOCAL i            AS LONG
          LOCAL vIdx         AS VARIANT
          LOCAL nCount       AS LONG
          LOCAL strDesc      AS STRING
          LOCAL strVoiceList AS STRING
        
          LOCAL liCount      AS LONG
        
            strVoiceList = ""
            IF ISFALSE ISOBJECT( gdoSp ) THEN
                LET gdoSp = NEWCOM "SAPI.SpVoice"
                IF ISFALSE ISOBJECT( gdoSp ) THEN
                    EXIT FUNCTION
                END IF
            END IF
            'Get a reference to the SAPI ISpeechObjectTokens collection
            OBJECT CALL gdoSp.GetVoices( ) TO vRes
            IF ISFALSE OBJRESULT THEN
                SET oTokens = vRes
                vRes = EMPTY
                'Get the number of tokens
                OBJECT GET oTokens.Count TO vRes
                nCount = VARIANT#( vRes )
                'Parse the collection (zero based)
                liCount = 0
        
                FOR i = 0 TO nCount - 1
                    vIdx = i AS LONG
                    ' Get the item by his index
                    OBJECT CALL oTokens.Item( vIdx ) TO vRes
                    IF ISFALSE OBJRESULT THEN
                        SET oToken = vRes
                        vRes = EMPTY
                        IF ISFALSE OBJRESULT THEN
                            'Get the description
                            OBJECT CALL oToken.GetDescription( ) TO vRes
                            IF ISFALSE OBJRESULT THEN
                                strDesc = VARIANT$( vRes )
                                IF strDesc = "TOSHIBA male adult (U.S.)" THEN
                                    GOTO OverThere
                                ELSE
                                    IF liCount <= 8 THEN
                                        strDesc = "00" + TRIM$(STR$(liCount + 1)) + ".  " + strDesc
                                    END IF
                                    IF liCount >= 8 AND liCount <= 98 THEN
                                        strDesc = "0" + TRIM$(STR$(liCount + 1)) + ".  " + strDesc
                                    END IF
                                    strVoiceList = strVoiceList & strDesc & "|"
                                    INCR liCount
                                END IF
                                OverThere:
                            END IF
                        END IF
                        SET oToken = NOTHING
                    END IF
                NEXT i
                SET oTokens = NOTHING
            END IF
        
            strVoiceList = RTRIM$(strVoiceList,"|")
            FUNCTION = strVoiceList
        
        END FUNCTION

        Comment


        • #5
          The example above culls
          "TOSHIBA male adult (U.S.)"
          so it does not put it in the list.

          This may be helpful https://forum.powerbasic.com/forum/u...831#post686831

          Comment


          • #6
            I've updated the code to this and Jim's function funGetVoices() on my system I have Microsoft George, Hazel and Susan in my control panel. The function only returns 2 in the string (one English (Great Britian and the other English US) which is a bit odd.

            Code:
             001.  Microsoft Hazel Desktop - English (Great Britain)|002.  Microsoft Zira Desktop - English (United States)
            When I check the registry I can see those 2 voices Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices

            Also I can't figure out how to modify the SpSetVoice function and compile so I've disabled is at the moment.

            Code:
            ' SED_PBWIN
            
            #COMPILE EXE
            #DIM ALL
            
            #INCLUDE "Win32api.inc"
            
            ENUM SpeechStreamFileMode
            
            SSFMOpenForRead = 0
            SSFMOpenReadWrite = 1
            SSFMCreate = 2
            SSFMCreateForWrite = 3
            
            END ENUM
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            $PROGID_SpeechLib_SpVoice = "SAPI.SpVoice"
            $PROGID_SpeechLib_SpFileStream = "SAPI.SpFileStream"
            $IID_SpeechLib_ISpeechFileStream = GUID$( "{AF67F125-AB39-4E93-B4A2-CC2E66E182A7}" )
            $IID_SpeechLib_ISpeechAudioFormat = GUID$( "{E6E9C590-3E18-40E3-8299-061F98BDE7C7}" )
            $IID_SpeechLib_ISpeechWaveFormatEx = GUID$( "{7A1EF0D5-1581-4741-88E4-209A49F11A10}" )
            $IID_SpeechLib_ISpeechVoice = GUID$( "{269316D8-57BD-11D2-9EEE-00C04F797396}" )
            $IID_SpeechLib_ISpeechVoiceStatus = GUID$( "{8BE47B07-57F6-11D2-9EEE-00C04F797396}" )
            $IID_SpeechLib_ISpeechObjectToken = GUID$( "{C74A3ADC-B727-4500-A84A-B526721C8B8C}" )
            $IID_SpeechLib_ISpeechDataKey = GUID$( "{CE17C09B-4EFA-44D5-A4C9-59D9585AB0CD}" )
            $IID_SpeechLib_ISpeechObjectTokenCategory = GUID$( "{CA7EAC50-2D01-4145-86D4-5AE7D70F4469}" )
            $IID_SpeechLib_ISpeechObjectTokens = GUID$( "{9285B776-2E7B-4BC0-B53E-580EB6FA967F}" )
            $IID_SpeechLib_ISpeechBaseStream = GUID$( "{6450336F-7D49-4CED-8097-49D6DEE37294}" )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechBaseStream
            ' Description     : ISpeechBaseStream Interface
            ' This Interface cannot be created directly it can only
            ' be returned by a Method or Property in this library.
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechBaseStream $IID_SpeechLib_ISpeechBaseStream
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET Format < 1 >( ) AS ISpeechAudioFormat
            PROPERTY SET PutRef_Format < 1 >( BYVAL AudioFormat AS ISpeechAudioFormat )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD READ < 2 >( BYREF Buffer AS VARIANT, BYVAL NumberOfBytes AS LONG ) AS LONG
            METHOD WRITE < 3 >( BYVAL Buffer AS VARIANT ) AS LONG
            METHOD SEEK < 4 >( BYVAL Position AS VARIANT, OPT BYVAL Origin AS LONG ) AS VARIANT
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechObjectTokens
            ' Description     : ISpeechObjectTokens Interface
            ' This Interface cannot be created directly it can only
            ' be returned by a Method or Property in this library.
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechObjectTokens $IID_SpeechLib_ISpeechObjectTokens
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET COUNT < 1 >( ) AS LONG
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD ITEM < 0 >( BYVAL Index AS LONG ) AS ISpeechObjectToken
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET PropGet__NewEnum < - 4 >( ) AS IUNKNOWN
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechObjectTokenCategory
            ' Description     : ISpeechObjectTokenCategory Interface
            ' Class Name      : SpObjectTokenCategory
            ' ClassID         : $CLSID_SpeechLib_SpObjectTokenCategory
            ' ProgID          : $PROGID_SpeechLib_SpObjectTokenCategory
            ' Version ProgID  : $PROGID_SpeechLib_SpObjectTokenCategory1
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechObjectTokenCategory $IID_SpeechLib_ISpeechObjectTokenCategory
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET ID < 1 >( ) AS WSTRING
            PROPERTY SET DEFAULT < 2 >( BYVAL TokenId AS WSTRING )
            PROPERTY GET DEFAULT < 2 >( ) AS WSTRING
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD SetId < 3 >( BYVAL Id AS WSTRING, OPT BYVAL CreateIfNotExist AS INTEGER )
            METHOD GetDataKey < 4 >( OPT BYVAL Location AS LONG ) AS ISpeechDataKey
            METHOD EnumerateTokens < 5 >( OPT BYVAL RequiredAttributes AS WSTRING, OPT BYVAL OptionalAttributes AS WSTRING ) AS _
              ISpeechObjectTokens
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechDataKey
            ' Description     : ISpeechDataKey Interface
            ' This Interface cannot be created directly it can only
            ' be returned by a Method or Property in this library.
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechDataKey $IID_SpeechLib_ISpeechDataKey
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD SetBinaryValue < 1 >( BYVAL ValueName AS WSTRING, BYVAL Value AS VARIANT )
            METHOD GetBinaryValue < 2 >( BYVAL ValueName AS WSTRING ) AS VARIANT
            METHOD SetStringValue < 3 >( BYVAL ValueName AS WSTRING, BYVAL Value AS WSTRING )
            METHOD GetStringValue < 4 >( BYVAL ValueName AS WSTRING ) AS WSTRING
            METHOD SetLongValue < 5 >( BYVAL ValueName AS WSTRING, BYVAL Value AS LONG )
            METHOD GetLongValue < 6 >( BYVAL ValueName AS WSTRING ) AS LONG
            METHOD OpenKey < 7 >( BYVAL SubKeyName AS WSTRING ) AS ISpeechDataKey
            METHOD CreateKey < 8 >( BYVAL SubKeyName AS WSTRING ) AS ISpeechDataKey
            METHOD DeleteKey < 9 >( BYVAL SubKeyName AS WSTRING )
            METHOD DeleteValue < 10 >( BYVAL ValueName AS WSTRING )
            METHOD EnumKeys < 11 >( BYVAL Index AS LONG ) AS WSTRING
            METHOD EnumValues < 12 >( BYVAL Index AS LONG ) AS WSTRING
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechObjectToken
            ' Description     : ISpeechObjectToken Interface
            ' Class Name      : SpObjectToken
            ' ClassID         : $CLSID_SpeechLib_SpObjectToken
            ' ProgID          : $PROGID_SpeechLib_SpObjectToken
            ' Version ProgID  : $PROGID_SpeechLib_SpObjectToken1
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechObjectToken $IID_SpeechLib_ISpeechObjectToken
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET ID < 1 >( ) AS WSTRING
            PROPERTY GET DataKey < 2 >( ) AS ISpeechDataKey
            PROPERTY GET Category < 3 >( ) AS ISpeechObjectTokenCategory
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD GetDescription < 4 >( OPT BYVAL Locale AS LONG ) AS WSTRING
            METHOD SetId < 5 >( BYVAL Id AS WSTRING, OPT BYVAL CategoryID AS WSTRING, OPT BYVAL CreateIfNotExist AS INTEGER )
            METHOD GetAttribute < 6 >( BYVAL AttributeName AS WSTRING ) AS WSTRING
            METHOD CreateInstance < 7 >( OPT BYVAL pUnkOuter AS IUNKNOWN, OPT BYVAL ClsContext AS LONG ) AS IUNKNOWN
            METHOD Remove < 8 >( BYVAL ObjectStorageCLSID AS WSTRING )
            METHOD GetStorageFileName < 9 >( BYVAL ObjectStorageCLSID AS WSTRING, BYVAL KeyName AS WSTRING, BYVAL FileName AS WSTRING, _
              BYVAL Folder AS LONG ) AS WSTRING
            METHOD RemoveStorageFileName < 10 >( BYVAL ObjectStorageCLSID AS WSTRING, BYVAL KeyName AS WSTRING, BYVAL DeleteFile AS _
              INTEGER )
            METHOD IsUISupported < 11 >( BYVAL TypeOfUI AS WSTRING, OPT BYREF IN ExtraData AS VARIANT, OPT BYVAL PB_Object AS _
              IUNKNOWN ) AS INTEGER
            METHOD DisplayUI < 12 >( BYVAL hWnd AS LONG, BYVAL Title AS WSTRING, BYVAL TypeOfUI AS WSTRING, OPT BYREF IN ExtraData AS _
              VARIANT, OPT BYVAL PB_Object AS IUNKNOWN )
            METHOD MatchesAttributes < 13 >( BYVAL Attributes AS WSTRING ) AS INTEGER
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechVoiceStatus
            ' Description     : ISpeechVoiceStatus Interface
            ' This Interface cannot be created directly it can only
            ' be returned by a Method or Property in this library.
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechVoiceStatus $IID_SpeechLib_ISpeechVoiceStatus
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET CurrentStreamNumber < 1 >( ) AS LONG
            PROPERTY GET LastStreamNumberQueued < 2 >( ) AS LONG
            PROPERTY GET LastHResult < 3 >( ) AS LONG
            PROPERTY GET RunningState < 4 >( ) AS LONG
            PROPERTY GET InputWordPosition < 5 >( ) AS LONG
            PROPERTY GET InputWordLength < 6 >( ) AS LONG
            PROPERTY GET InputSentencePosition < 7 >( ) AS LONG
            PROPERTY GET InputSentenceLength < 8 >( ) AS LONG
            PROPERTY GET LastBookmark < 9 >( ) AS WSTRING
            PROPERTY GET LastBookmarkId < 10 >( ) AS LONG
            PROPERTY GET PhonemeId < 11 >( ) AS INTEGER
            PROPERTY GET VisemeId < 12 >( ) AS INTEGER
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechVoice
            ' Description     : ISpeechVoice Interface
            ' Class Name      : SpVoice
            ' ClassID         : $CLSID_SpeechLib_SpVoice
            ' ProgID          : $PROGID_SpeechLib_SpVoice
            ' Version ProgID  : $PROGID_SpeechLib_SpVoice1
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechVoice $IID_SpeechLib_ISpeechVoice
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET STATUS < 1 >( ) AS ISpeechVoiceStatus
            PROPERTY GET Voice < 2 >( ) AS ISpeechObjectToken
            PROPERTY SET PutRef_Voice < 2 >( BYVAL Voice AS ISpeechObjectToken )
            PROPERTY GET AudioOutput < 3 >( ) AS ISpeechObjectToken
            PROPERTY SET PutRef_AudioOutput < 3 >( BYVAL AudioOutput AS ISpeechObjectToken )
            PROPERTY GET AudioOutputStream < 4 >( ) AS ISpeechBaseStream
            PROPERTY SET PutRef_AudioOutputStream < 4 >( BYVAL AudioOutputStream AS ISpeechBaseStream )
            PROPERTY GET Rate < 5 >( ) AS LONG
            PROPERTY SET Rate < 5 >( BYVAL Rate AS LONG )
            PROPERTY GET Volume < 6 >( ) AS LONG
            PROPERTY SET Volume < 6 >( BYVAL Volume AS LONG )
            PROPERTY SET AllowAudioOutputFormatChangesOnNextSet < 7 >( BYVAL Allow AS INTEGER )
            PROPERTY GET AllowAudioOutputFormatChangesOnNextSet < 7 >( ) AS INTEGER
            PROPERTY GET EventInterests < 8 >( ) AS LONG
            PROPERTY SET EventInterests < 8 >( BYVAL EventInterestFlags AS LONG )
            PROPERTY SET PRIORITY < 9 >( BYVAL Priority AS LONG )
            PROPERTY GET PRIORITY < 9 >( ) AS LONG
            PROPERTY SET AlertBoundary < 10 >( BYVAL Boundary AS LONG )
            PROPERTY GET AlertBoundary < 10 >( ) AS LONG
            PROPERTY SET SynchronousSpeakTimeout < 11 >( BYVAL msTimeout AS LONG )
            PROPERTY GET SynchronousSpeakTimeout < 11 >( ) AS LONG
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD Speak < 12 >( BYVAL TEXT AS WSTRING, OPT BYVAL Flags AS LONG ) AS LONG
            METHOD SpeakStream < 13 >( BYVAL Stream AS ISpeechBaseStream, OPT BYVAL Flags AS LONG ) AS LONG
            METHOD Pause < 14 >( )
            METHOD RESUME < 15 >( )
            METHOD Skip < 16 >( BYVAL PB_Type AS WSTRING, BYVAL NumItems AS LONG ) AS LONG
            METHOD GetVoices < 17 >( OPT BYVAL RequiredAttributes AS WSTRING, OPT BYVAL OptionalAttributes AS WSTRING ) AS _
              ISpeechObjectTokens
            METHOD GetAudioOutputs < 18 >( OPT BYVAL RequiredAttributes AS WSTRING, OPT BYVAL OptionalAttributes AS WSTRING ) AS _
              ISpeechObjectTokens
            METHOD WaitUntilDone < 19 >( BYVAL msTimeout AS LONG ) AS INTEGER
            METHOD SpeakCompleteEvent < 20 >( ) AS LONG
            METHOD IsUISupported < 21 >( BYVAL TypeOfUI AS WSTRING, OPT BYREF IN ExtraData AS VARIANT ) AS INTEGER
            METHOD DisplayUI < 22 >( BYVAL hWndParent AS LONG, BYVAL Title AS WSTRING, BYVAL TypeOfUI AS WSTRING, OPT BYREF IN _
              ExtraData AS VARIANT )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechWaveFormatEx
            ' Description     : ISpeechWaveFormatEx Interface
            ' Class Name      : SpWaveFormatEx
            ' ClassID         : $CLSID_SpeechLib_SpWaveFormatEx
            ' ProgID          : $PROGID_SpeechLib_SpWaveFormatEx
            ' Version ProgID  : $PROGID_SpeechLib_SpWaveFormatEx1
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechWaveFormatEx $IID_SpeechLib_ISpeechWaveFormatEx
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET FormatTag < 1 >( ) AS INTEGER
            PROPERTY SET FormatTag < 1 >( BYVAL FormatTag AS INTEGER )
            PROPERTY GET Channels < 2 >( ) AS INTEGER
            PROPERTY SET Channels < 2 >( BYVAL Channels AS INTEGER )
            PROPERTY GET SamplesPerSec < 3 >( ) AS LONG
            PROPERTY SET SamplesPerSec < 3 >( BYVAL SamplesPerSec AS LONG )
            PROPERTY GET AvgBytesPerSec < 4 >( ) AS LONG
            PROPERTY SET AvgBytesPerSec < 4 >( BYVAL AvgBytesPerSec AS LONG )
            PROPERTY GET BlockAlign < 5 >( ) AS INTEGER
            PROPERTY SET BlockAlign < 5 >( BYVAL BlockAlign AS INTEGER )
            PROPERTY GET BitsPerSample < 6 >( ) AS INTEGER
            PROPERTY SET BitsPerSample < 6 >( BYVAL BitsPerSample AS INTEGER )
            PROPERTY GET ExtraData < 7 >( ) AS VARIANT
            PROPERTY SET ExtraData < 7 >( BYVAL ExtraData AS VARIANT )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechAudioFormat
            ' Description     : ISpeechAudioFormat Interface
            ' Class Name      : SpAudioFormat
            ' ClassID         : $CLSID_SpeechLib_SpAudioFormat
            ' ProgID          : $PROGID_SpeechLib_SpAudioFormat
            ' Version ProgID  : $PROGID_SpeechLib_SpAudioFormat1
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechAudioFormat $IID_SpeechLib_ISpeechAudioFormat
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET TYPE < 1 >( ) AS LONG
            PROPERTY SET TYPE < 1 >( BYVAL AudioFormat AS LONG )
            PROPERTY GET GUID < 2 >( ) AS WSTRING
            PROPERTY SET GUID < 2 >( BYVAL PB_Guid AS WSTRING )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD GetWaveFormatEx < 3 >( ) AS ISpeechWaveFormatEx
            METHOD SetWaveFormatEx < 4 >( BYVAL PB_WaveFormatEx AS ISpeechWaveFormatEx )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' Interface Name  : ISpeechFileStream
            ' Description     : ISpeechFileStream Interface
            ' Class Name      : SpFileStream
            ' ClassID         : $CLSID_SpeechLib_SpFileStream
            ' ProgID          : $PROGID_SpeechLib_SpFileStream
            ' Version ProgID  : $PROGID_SpeechLib_SpFileStream1
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            INTERFACE ISpeechFileStream $IID_SpeechLib_ISpeechFileStream
            INHERIT IDISPATCH
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            PROPERTY GET Format < 1 >( ) AS ISpeechAudioFormat
            PROPERTY SET PutRef_Format < 1 >( BYVAL Rhs AS ISpeechAudioFormat )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            METHOD READ < 2 >( BYREF Buffer AS VARIANT, BYVAL NumberOfBytes AS LONG ) AS LONG
            METHOD WRITE < 3 >( BYVAL Buffer AS VARIANT ) AS LONG
            METHOD SEEK < 4 >( BYVAL Position AS VARIANT, OPT BYVAL Origin AS LONG ) AS VARIANT
            METHOD OPEN < 100 >( BYVAL FileName AS WSTRING, OPT BYVAL FileMode AS LONG, OPT BYVAL PB_DoEvents AS INTEGER )
            METHOD CLOSE < 101 >( )
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            END INTERFACE
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            ' SpSetVoice
            ' Sets the voice used by the speech engine.
            ' ========================================================================================
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            #IF 1 = 0
            FUNCTION SpSetVoice( _
                  BYVAL pISpVoice AS ISpVoice, _        ' Reference to the IspVoice interface
                  BYVAL bstrVoice AS WSTRING _        ' ANSI STRING - Voice to set, e.g. "Microsoft Mary"
                  ) AS LONG        ' HRESULT
                LOCAL hr AS LONG
                LOCAL pIEnumSpObjectTokens AS IEnumSpObjectTokens
                LOCAL nCount AS DWORD
                LOCAL i AS DWORD
                LOCAL pISpObjectToken AS ISpObjectToken
                LOCAL celtFetched AS DWORD
                LOCAL pszValue AS WSTRINGZ PTR
                LOCAL bstrDesc AS WSTRING
                IF ISNOTHING( pISpVoice ) THEN FUNCTION = %E_POINTER : EXIT FUNCTION
                ' // Get a reference to an enumerator for the voices collection
                ' // using the helper function SpEnumTokens
                hr = SpEnumTokens( $$SPCAT_VOICES, BYVAL %NULL, BYVAL %NULL, pIEnumSpObjectTokens )
                ' // Parse the collection
                IF SUCCEEDED( hr ) THEN
                    pIEnumSpObjectTokens.GetCount( nCount )
                    FOR i = 0 TO nCount - 1
                        hr = pIEnumSpObjectTokens.Next( 1, pISpObjectToken, celtFetched )
                        IF FAILED( hr ) OR celtFetched = 0 THEN EXIT FOR
                        hr = SpGetDescription( pISpObjectToken, pszValue )
                        IF hr = %S_OK AND pszValue <> %NULL THEN
                            bstrDesc = @pszValue
                            CoTaskMemFree BYVAL pszValue
                            IF bstrDesc = bstrVoice THEN
                                pISpVoice.SetVoice pISpObjectToken
                                pISpObjectToken = NOTHING
                                EXIT FOR
                            END IF
                        END IF
                        pISpObjectToken = NOTHING
                    NEXT
                    pIEnumSpObjectTokens = NOTHING
                END IF
                FUNCTION = hr
            END FUNCTION
            #ENDIF
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            'END OF EXTRACT
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            FUNCTION funGetVoices( ) AS STRING
                ' return the list of voices
                LOCAL vRes AS VARIANT
                LOCAL vTxt AS VARIANT
                LOCAL vTime AS VARIANT
                LOCAL oTokens AS DISPATCH
                LOCAL oToken AS DISPATCH
                LOCAL vToken AS VARIANT
                LOCAL i AS LONG
                LOCAL vIdx AS VARIANT
                LOCAL nCount AS LONG
                LOCAL strDesc AS STRING
                LOCAL strVoiceList AS STRING
                DIM oVoice AS DISPATCH
                LOCAL liCount AS LONG
                strVoiceList = ""
                IF ISFALSE ISOBJECT( oVoice ) THEN
                    LET oVoice = NEWCOM "SAPI.SpVoice"
                    IF ISFALSE ISOBJECT( oVoice ) THEN
                        EXIT FUNCTION
                    END IF
                END IF
                'Get a reference to the SAPI ISpeechObjectTokens collection
                OBJECT CALL oVoice.GetVoices( ) TO vRes
                IF ISFALSE OBJRESULT THEN
                    SET oTokens = vRes
                    vRes = EMPTY
                    'Get the number of tokens
                    OBJECT GET oTokens.Count TO vRes
                    nCount = VARIANT#( vRes )
                    'Parse the collection (zero based)
                    liCount = 0
                    FOR i = 0 TO nCount        ' - 1
                        vIdx = i AS LONG
                        ' Get the item by his index
                        OBJECT CALL oTokens.Item( vIdx ) TO vRes
                        IF ISFALSE OBJRESULT THEN
                            SET oToken = vRes
                            vRes = EMPTY
                            IF ISFALSE OBJRESULT THEN
                                'Get the description
                                OBJECT CALL oToken.GetDescription( ) TO vRes
                                IF ISFALSE OBJRESULT THEN
                                    strDesc = VARIANT$( vRes )
                                    IF strDesc = "TOSHIBA male adult (U.S.)" THEN
                                        GOTO OverThere
                                    ELSE
                                        IF liCount < = 8 THEN
                                            strDesc = "00" + TRIM$( STR$( liCount + 1 )) + ".  " + strDesc
                                        END IF
                                        IF liCount > = 8 AND liCount < = 98 THEN
                                            strDesc = "0" + TRIM$( STR$( liCount + 1 )) + ".  " + strDesc
                                        END IF
                                        strVoiceList = strVoiceList & strDesc & "|"
                                        INCR liCount
                                    END IF
            OverThere :
                                END IF
                            END IF
                            SET oToken = NOTHING
                        END IF
                    NEXT i
                    SET oTokens = NOTHING
                END IF
                strVoiceList = RTRIM$( strVoiceList, "|" )
                FUNCTION = strVoiceList
            END FUNCTION
            
            
            
            '----------------------------------------------------------------------------(')
            
            
            
            FUNCTION PBMAIN( ) AS LONG
                DIM wszFile AS WSTRINGZ * %MAX_PATH
                DIM oFileStream AS ISpeechFileStream
                DIM oVoice AS ISpeechVoice
                MSGBOX funGetVoices
                LET oVoice = NEWCOM $PROGID_SpeechLib_SpVoice
                IF ISFALSE ISOBJECT( oVoice ) THEN
                    MSGBOX "Cannot get object: oVoice"
                    EXIT FUNCTION
                END IF
                wszFile = CURDIR$ + "\TTS_Test.wav"
                LET oFileStream = NEWCOM $PROGID_SpeechLib_SpFileStream
                IF ISFALSE ISOBJECT( oFileStream ) THEN
                    SET oVoice = NOTHING
                    MSGBOX "Cannot get object: oFileStream"
                    EXIT FUNCTION
                END IF
                oFileStream.Open wszFile, %SpeechStreamFileMode.SSFMCreateForWrite, %TRUE
                oVoice.PutRef_AudioOutputStream = oFileStream
                oVoice.Speak "this is the default voice"
                oFileStream.Close
                SET oVoice = NOTHING
                SET oFileStream = NOTHING
                '
            END FUNCTION

            Comment


            • #7
              Steve see this link...
              https://forum.powerbasic.com/forum/u...ice#post772928

              The solution to your issue is only a click away. Enjoy
              jimbo

              Comment


              • #8
                Here is another one using a lot of José stuff and includes.
                A little bit of Gary's stuff, and a little bit of mine.

                As is... Yours to double check...

                Click image for larger version  Name:	TextToSpeechToWav01.png Views:	1 Size:	44.0 KB ID:	773036

                Code:
                'Thanks to José Roca includes, code is using JRS includes.
                #COMPILE EXE '#Win 9.07 (D:\Basic\Bas\Jose Roca\Forum\Jose\Windows API Headers\1.19 (PB9.x)\uz)#
                #DIM ALL
                #REGISTER NONE
                #INCLUDE "Win32Api.inc"
                #INCLUDE "CommCtrl.inc"
                #INCLUDE "Ole2Utils.inc"
                #INCLUDE "Sapi.inc"
                #IF %PB_REVISION < &H1000
                #INCLUDE "SapiUtils.inc"
                #ENDIF
                '#RESOURCE ".pbr"
                
                $PROGID_SAPISpFileStream  = "SAPI.SpFileStream"
                $PROGID_SAPISpFileStream1 = "SAPI.SpFileStream.1"
                %SPF_ASYNC                = 1
                %SVSFlagsAsync            = %SPF_ASYNC
                
                GLOBAL hDlg    AS DWORD
                GLOBAL DoSpeak AS DWORD
                GLOBAL DoPause AS DWORD
                
                %LabelVoice     = 101
                %LabelFormat    = 102
                %LabelVolume    = 103
                %LabelSpeed     = 104
                %LabelText      = 105
                
                %ListboxVoice   = 201
                
                %TextboxText    = 301
                
                %ButtonSpeak    = 401
                %ButtonWave     = 402
                %ButtonStop     = 403
                %ButtonPause    = 404
                %ButtonSapiCpl  = 405
                %ButtonExit     = 406
                
                %TrackbarVolume = 501
                %TrackbarSpeed  = 502
                
                %FrameVolume    = 601
                %FrameSpeed     = 602
                
                %ComboFormat    = 701
                
                $SPCAT_VOICES   = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices"
                $SPCAT_VOICES10 = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices"
                
                '_____________________________________________________________________________
                
                FUNCTION pUnicodeToAnsi(BYVAL pUnicode AS DWORD)AS STRING
                 LOCAL CharCount AS DWORD
                 LOCAL sAnsi     AS STRING
                
                 IF pUnicode THEN 'Avoid gpf
                   CharCount = LStrlenW(BYVAL pUnicode) 'Get dual bytes character count
                   sAnsi     = NUL$(CharCount) 'Initialize string
                   WideCharToMultiByte(%CP_ACP, %NULL, BYVAL pUnicode, CharCount, _
                                       BYVAL STRPTR(sAnsi), CharCount, BYVAL %NULL, BYVAL %NULL)
                   FUNCTION = sAnsi
                 END IF
                
                END FUNCTION
                '_____________________________________________________________________________
                
                SUB FormatComboFill()
                 DIM SpeechFormat(4 TO 68) AS STRING
                 LOCAL Looper              AS LONG
                
                 SpeechFormat(04) = "SAFT8kHz8BitMono"
                 SpeechFormat(05) = "SAFT8kHz8BitStereo"
                 SpeechFormat(06) = "SAFT8kHz16BitMono"
                 SpeechFormat(07) = "SAFT8kHz16BitStereo"
                 SpeechFormat(08) = "SAFT11kHz8BitMono"
                 SpeechFormat(09) = "SAFT11kHz8BitStereo"
                 SpeechFormat(10) = "SAFT11kHz16BitMono"
                 SpeechFormat(11) = "SAFT11kHz16BitStereo"
                 SpeechFormat(12) = "SAFT12kHz8BitMono"
                 SpeechFormat(13) = "SAFT12kHz8BitStereo"
                 SpeechFormat(14) = "SAFT12kHz16BitMono"
                 SpeechFormat(15) = "SAFT12kHz16BitStereo"
                 SpeechFormat(16) = "SAFT16kHz8BitMono"
                 SpeechFormat(17) = "SAFT16kHz8BitStereo"
                 SpeechFormat(18) = "SAFT16kHz16BitMono"
                 SpeechFormat(19) = "SAFT16kHz16BitStereo"
                 SpeechFormat(20) = "SAFT22kHz8BitMono"
                 SpeechFormat(21) = "SAFT22kHz8BitStereo"
                 SpeechFormat(22) = "SAFT22kHz16BitMono"
                 SpeechFormat(23) = "SAFT22kHz16BitStereo"
                 SpeechFormat(24) = "SAFT24kHz8BitMono"
                 SpeechFormat(25) = "SAFT24kHz8BitStereo"
                 SpeechFormat(26) = "SAFT24kHz16BitMono"
                 SpeechFormat(27) = "SAFT24kHz16BitStereo"
                 SpeechFormat(28) = "SAFT32kHz8BitMono"
                 SpeechFormat(29) = "SAFT32kHz8BitStereo"
                 SpeechFormat(30) = "SAFT32kHz16BitMono"
                 SpeechFormat(31) = "SAFT32kHz16BitStereo"
                 SpeechFormat(32) = "SAFT44kHz8BitMono"
                 SpeechFormat(33) = "SAFT44kHz8BitStereo"
                 SpeechFormat(34) = "SAFT44kHz16BitMono"
                 SpeechFormat(35) = "SAFT44kHz16BitStereo"
                 SpeechFormat(36) = "SAFT48kHz8BitMono"
                 SpeechFormat(37) = "SAFT48kHz8BitStereo"
                 SpeechFormat(38) = "SAFT48kHz16BitMono"
                 SpeechFormat(39) = "SAFT48kHz16BitStereo"
                 SpeechFormat(40) = "SAFTTrueSpeech_8kHz1BitMono"
                 SpeechFormat(41) = "SAFTCCITT_ALaw_8kHzMono"
                 SpeechFormat(42) = "SAFTCCITT_ALaw_8kHzStereo"
                 SpeechFormat(43) = "SAFTCCITT_ALaw_11kHzMono"
                 SpeechFormat(44) = "SAFTCCITT_ALaw_11kHzStereo"
                 SpeechFormat(45) = "SAFTCCITT_ALaw_22kHzMono"
                 SpeechFormat(46) = "SAFTCCITT_ALaw_22kHzStereo"
                 SpeechFormat(47) = "SAFTCCITT_ALaw_44kHzMono"
                 SpeechFormat(48) = "SAFTCCITT_ALaw_44kHzStereo"
                 SpeechFormat(49) = "SAFTCCITT_uLaw_8kHzMono"
                 SpeechFormat(50) = "SAFTCCITT_uLaw_8kHzStereo"
                 SpeechFormat(51) = "SAFTCCITT_uLaw_11kHzMono"
                 SpeechFormat(52) = "SAFTCCITT_uLaw_11kHzStereo"
                 SpeechFormat(53) = "SAFTCCITT_uLaw_22kHzMono"
                 SpeechFormat(54) = "SAFTCCITT_uLaw_22kHzStereo"
                 SpeechFormat(55) = "SAFTCCITT_uLaw_44kHzMono"
                 SpeechFormat(56) = "SAFTCCITT_uLaw_44kHzStereo"
                 SpeechFormat(57) = "SAFTADPCM_8kHzMono"
                 SpeechFormat(58) = "SAFTADPCM_8kHzStereo"
                 SpeechFormat(59) = "SAFTADPCM_11kHzMono"
                 SpeechFormat(60) = "SAFTADPCM_11kHzStereo"
                 SpeechFormat(61) = "SAFTADPCM_22kHzMono"
                 SpeechFormat(62) = "SAFTADPCM_22kHzStereo"
                 SpeechFormat(63) = "SAFTADPCM_44kHzMono"
                 SpeechFormat(64) = "SAFTADPCM_44kHzStereo"
                 SpeechFormat(65) = "SAFTGSM610_8kHzMono"
                 SpeechFormat(66) = "SAFTGSM610_11kHzMono"
                 SpeechFormat(67) = "SAFTGSM610_22kHzMono"
                 SpeechFormat(68) = "SAFTGSM610_44kHzMono"
                
                 FOR Looper = 4 TO 68
                   COMBOBOX ADD hDlg, %ComboFormat, SpeechFormat(Looper)
                 NEXT
                
                END SUB
                '______________________________________________________________________________
                
                FUNCTION FileNameIncrement(sFileName AS STRING) AS STRING
                 LOCAL sFileNameNum  AS STRING
                 LOCAL sNum          AS STRING
                 LOCAL sFileDir      AS STRING
                 LOCAL sPath         AS STRING
                 LOCAL Num           AS LONG
                 LOCAL NumFound      AS LONG
                 LOCAL NumFoundBig   AS LONG
                 LOCAL LastBackSlash AS LONG
                 LOCAL LastDot       AS LONG
                 LOCAL NumPos        AS LONG
                
                 LastBackSlash = INSTR(-1, sFileName, "\")
                 LastDot       = INSTR(-1, sFileName, ".")
                
                 IF LastDot < LastBackSlash THEN LastDot = 0 'Ignore dot if before last back slash
                
                 IF LastBackSlash THEN 'Some Path
                   sPath = LEFT$(sFileNAme, LastBackSlash)
                   IF LastDot THEN 'Path and .ext
                     NumPos = LastDot - 1
                   ELSE 'Path but no .ext
                     NumPos = LEN(sFileName) + 1
                   END IF
                 ELSE 'No path
                   IF LastDot THEN 'No path but some .ext
                     NumPos = LastDot - 1
                   ELSE 'No path, no .ext
                     NumPos = LEN(sFileName) + 1
                   END IF
                 END IF
                
                 'Find already existing bigger number
                 sFileNameNum = LEFT$(sFileName, NumPos) & "(????)" & MID$(sFileName, NumPos + 1)
                 sFileDir = DIR$(sFileNameNum)
                 DO WHILE LEN(sFileDir)
                   NumFound = VAL(MID$(sPath & sFileDir, NumPos + 2, 4))
                   IF NumFound > NumFoundBig THEN
                     NumFoundBig = NumFound
                   END IF
                   sFileDir = DIR$
                 LOOP
                 DIR$ CLOSE
                
                 Num = NumFoundBig + 1
                 FUNCTION = LEFT$(sFileName, NumPos) & _
                            "(" & FORMAT$(NumFoundBig + 1, "0000") & ")" & _
                            MID$(sFileName, NumPos + 1)
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION ExeName2(Action AS LONG) AS STRING 'Return the ExeName of this app.
                 LOCAL zFileName   AS ASCIIZ * %MAX_PATH
                 LOCAL PathFileLen AS LONG
                 LOCAL FileExtLen  AS LONG
                 LOCAL DotPos      AS LONG
                 LOCAL SlashPos    AS LONG
                
                 PathFileLen = GetModuleFileName(0, zFileName, %MAX_PATH)
                 SlashPos    = INSTR(-1, zFileName, "\")
                 DotPos      = INSTR(-1, zFileName, ".")
                 IF DotPos < SlashPos THEN DotPos = 0
                 FileExtLen = PathFileLen - SlashPos
                
                 SELECT CASE Action
                
                   CASE 1 'C: - Drive
                     IF ASC(zFileName, 2) = 58 THEN 'X: 58
                       FUNCTION = LEFT$(zFileName, 2)
                     END IF
                
                   CASE 2 'C:\Subdir\ - Drive and Path (Including last backslash)
                     FUNCTION = LEFT$(zFileName, SlashPos)
                
                   CASE 3 '\Subdir\ - Path (Including first and last backslash)
                     FUNCTION = MID$(zFileName, 3, SlashPos - 2)
                
                   CASE 4 'C:\Subdir\File - Drive, Path and Filename (No Extention, Dot excluded)
                     IF DotPos THEN
                       FUNCTION = LEFT$(zFileName, DotPos - 1)
                     ELSE
                       FUNCTION = LEFT$(zFileName, PathFileLen)
                     END IF
                
                   CASE 5 'C:\Subdir\File.Exe - Path, Filename and Extention
                     FUNCTION = LEFT$(zFileName, PathFileLen)
                
                   CASE 6 'File - Filename (No Extention)
                     IF DotPos THEN
                       FUNCTION = MID$(zFileName, SlashPos + 1, FileExtLen - (PathFileLen - DotPos) - 1)
                     ELSE
                       FUNCTION = MID$(zFileName, SlashPos + 1, FileExtLen)
                     END IF
                
                   CASE 7 'File.Exe - Filename and Extention
                     FUNCTION = MID$(zFileName, SlashPos + 1, FileExtLen)
                
                   CASE 8 '.Exe - Extention (Including Dot)
                     FUNCTION = MID$(zFileName, DotPos)
                
                 END SELECT
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION VoiceGet(BYVAL sCategoryId AS STRING, BYVAL RegistrySelection AS LONG) AS LONG
                 LOCAL pISpVoice            AS IspVoice
                 LOCAL pIEnumSpObjectTokens AS IEnumSpObjectTokens
                 LOCAL pISpObjectToken      AS ISpObjectToken
                 LOCAL ppToken              AS ISpObjectToken
                 LOCAL sVoice               AS STRING
                 LOCAL sVoiceDefault        AS STRING
                 LOCAL dwCount              AS DWORD
                 LOCAL Looper               AS DWORD
                 LOCAL dwCeltFetched        AS DWORD
                 LOCAL dwValue              AS DWORD
                 LOCAL hr                   AS LONG
                 LOCAL ListboxIndex         AS LONG
                
                 pISpVoice = NEWCOM CLSID $CLSID_SpVoice 'Create an instance of the ISpVoice interface
                 IF ISOBJECT(pISpVoice) THEN
                
                   pISpVoice.GetVoice(ppToken) 'Get default voice
                   hr = SpGetDescription(ppToken, dwValue)
                   IF hr = %S_OK AND dwValue <> %NULL THEN
                     sVoiceDefault = pUnicodeToAnsi(dwValue) 'Get default voice
                     CoTaskMemFree(dwValue)
                   END IF
                   ppToken = NOTHING
                
                   'Get a reference to an enumerator for the voices collection using the helper function SpEnumTokens
                   sCategoryId = UCODE$(sCategoryId & $NUL)
                   hr = SpEnumTokens(BYVAL STRPTR(sCategoryId), BYVAL %NULL, BYVAL %NULL, pIEnumSpObjectTokens)
                   IF SUCCEEDED(hr) THEN
                     pIEnumSpObjectTokens.GetCount(dwCount)
                     FOR Looper = 0 TO dwCount - 1
                       hr = pIEnumSpObjectTokens.Next(1, pISpObjectToken, dwCeltFetched)
                       IF FAILED(hr) OR dwCeltFetched = 0 THEN EXIT FOR
                       hr = SpGetDescription(pISpObjectToken, dwValue)
                       IF hr = %S_OK AND dwValue <> %NULL THEN
                         sVoice = pUnicodeToAnsi(dwValue)
                         ListboxIndex = SendDlgItemMessage(hDlg, %ListboxVoice, %LB_ADDSTRING, 0, STRPTR(sVoice))
                         LISTBOX SET USER hDlg, %ListboxVoice, ListboxIndex + 1, RegistrySelection
                         IF pUnicodeToAnsi(dwValue) = sVoiceDefault THEN
                           FUNCTION = ListboxIndex + 1
                         END IF
                         CoTaskMemFree(dwValue)
                       END IF
                       pISpObjectToken = NOTHING
                     NEXT
                     pIEnumSpObjectTokens = NOTHING
                   END IF
                   pISpVoice = NOTHING
                 END IF
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION VoiceSet(sVoice AS STRING, pISpVoice AS ISpVoice, BYVAL RegistrySelection AS LONG) AS LONG
                 LOCAL pIEnumSpObjectTokens AS IEnumSpObjectTokens
                 LOCAL pISpObjectToken      AS ISpObjectToken
                 LOCAL sCategoryId          AS STRING
                 LOCAL hr                   AS LONG
                 LOCAL dwCount              AS DWORD
                 LOCAL Looper               AS DWORD
                 LOCAL dwCeltFetched        AS DWORD
                 LOCAL dwValue              AS DWORD
                
                 IF RegistrySelection = 10 THEN
                   sCategoryId = UCODE$($SPCAT_VOICES10 & $NUL)
                 ELSE
                   sCategoryId = UCODE$($SPCAT_VOICES & $NUL)
                 END IF
                
                 hr = SpEnumTokens(BYVAL STRPTR(sCategoryId), BYVAL %NULL, BYVAL %NULL, pIEnumSpObjectTokens)
                 IF SUCCEEDED(hr) THEN
                   pIEnumSpObjectTokens.GetCount(dwCount)
                   FOR Looper = 0 TO dwCount - 1
                     hr = pIEnumSpObjectTokens.Next(1, pISpObjectToken, dwCeltFetched)
                     IF FAILED(hr) OR dwCeltFetched = 0 THEN EXIT FOR
                     hr = SpGetDescription(pISpObjectToken, dwValue)
                     IF hr = %S_OK AND dwValue <> %NULL THEN
                       IF pUnicodeToAnsi(dwValue) = sVoice THEN
                         pISpVoice.SetVoice pISpObjectToken
                       END IF
                       CoTaskMemFree(dwValue)
                     END IF
                     pISpObjectToken = NOTHING
                   NEXT
                   pIEnumSpObjectTokens = NOTHING
                 END IF
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION VoiceSetWav(sVoice AS STRING, pISpVoice AS ISpeechVoice, BYVAL RegistrySelection AS LONG) AS LONG
                 LOCAL pIEnumSpObjectTokens AS IEnumSpObjectTokens
                 LOCAL pISpObjectToken      AS ISpObjectToken
                 LOCAL sCategoryId          AS STRING
                 LOCAL hr                   AS LONG
                 LOCAL dwCount              AS DWORD
                 LOCAL Looper               AS DWORD
                 LOCAL dwCeltFetched        AS DWORD
                 LOCAL dwValue              AS DWORD
                
                 IF RegistrySelection = 10 THEN
                   sCategoryId = UCODE$($SPCAT_VOICES10 & $NUL)
                 ELSE
                   sCategoryId = UCODE$($SPCAT_VOICES & $NUL)
                 END IF
                 hr = SpEnumTokens(BYVAL STRPTR(sCategoryId), BYVAL %NULL, BYVAL %NULL, pIEnumSpObjectTokens)
                 IF SUCCEEDED(hr) THEN
                   pIEnumSpObjectTokens.GetCount(dwCount)
                   FOR Looper = 0 TO dwCount - 1
                     hr = pIEnumSpObjectTokens.Next(1, pISpObjectToken, dwCeltFetched)
                     IF FAILED(hr) OR dwCeltFetched = 0 THEN EXIT FOR
                     hr = SpGetDescription(pISpObjectToken, dwValue)
                     IF hr = %S_OK AND dwValue <> %NULL THEN
                       IF pUnicodeToAnsi(dwValue) = sVoice THEN
                         pISpVoice.putref_Voice = pISpObjectToken
                         FUNCTION = %TRUE
                       END IF
                       CoTaskMemFree(dwValue)
                     END IF
                     pISpObjectToken = NOTHING
                   NEXT
                   pIEnumSpObjectTokens = NOTHING
                 END IF
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION VoiceToWav() AS LONG
                 LOCAL FileStream        AS ISpeechFileStream
                 LOCAL Voice2            AS ISpeechVoice
                 LOCAL sFileName         AS STRING
                 LOCAL sText             AS STRING
                 LOCAL sBuffer           AS STRING
                 LOCAL wVolume           AS DWORD
                 LOCAL wSpeed            AS DWORD
                 LOCAL wFormat           AS DWORD
                 LOCAL index             AS LONG
                 LOCAL RegistrySelection AS LONG
                
                 FileStream = NEWCOM $PROGID_SAPISpFileStream1 'Or $PROGID_SAPISpFileStream
                 IF ISOBJECT(FileStream) THEN
                   COMBOBOX GET SELECT hDlg, %ComboFormat TO wFormat
                   wFormat = wFormat + 3
                   FileStream.Format.Type = wFormat
                   sFileName = ExeName2(4) & ".wav"
                   sFileName = FileNameIncrement(sFileName)
                   #IF %PB_REVISION < &H1000
                   FileStream.Open(UCODE$(sFilename & $NUL), %SSFMCreateForWrite, %TRUE)
                   #ELSE
                   FileStream.Open(sFilename, %SSFMCreateForWrite, %TRUE)
                   #ENDIF
                   Voice2 = NEWCOM CLSID $CLSID_SpVoice
                   IF ISOBJECT(Voice2) THEN
                     LISTBOX GET TEXT hDlg, %ListboxVoice TO sBuffer
                     LISTBOX GET SELECT hDlg, %ListboxVoice TO index
                     LISTBOX GET USER hDlg, %ListboxVoice, index TO RegistrySelection
                     VoiceSetWav(sBuffer, Voice2, RegistrySelection)
                
                     Voice2.putref_AudioOutputStream = FileStream
                
                     CONTROL GET TEXT hDlg, %LabelVolume TO sBuffer
                     wVolume = VAL(sBuffer)
                     Voice2.Volume = wVolume
                
                     'Talking speed from -10 to 10
                     CONTROL GET TEXT hDlg, %LabelSpeed TO sBuffer
                     wSpeed = VAL(sBuffer)
                     Voice2.Rate = wSpeed
                
                     CONTROL GET TEXT hDlg, %TextboxText TO sText
                
                     #IF %PB_REVISION < &H1000
                     Voice2.Speak UCODE$(sText & $NUL)
                     #ELSE
                     Voice2.Speak sText & $NUL
                     #ENDIF
                
                     Voice2.WaitUntilDone(&HFFFFFFFF)
                     Voice2 = NOTHING
                   END IF
                   FileStream.Close
                   FileStream = NOTHING
                   SHELL("Explorer.exe /select, " & $DQ & sFileName & $DQ) 'See new file in Windows Explorer
                 END IF
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION Speak() AS LONG
                 LOCAL pISpVoice         AS ISpVoice
                 LOCAL eventStatus       AS SPVOICESTATUS
                 LOCAL sText             AS STRING
                 LOCAL wsText            AS STRING
                 LOCAL sBuffer           AS STRING
                 LOCAL ulStreamNumber    AS DWORD
                 LOCAL wVolume           AS DWORD
                 LOCAL wSpeed            AS DWORD
                 LOCAL wFormat           AS DWORD
                 LOCAL RetVal            AS DWORD
                 LOCAL index             AS LONG
                 LOCAL RegistrySelection AS LONG
                
                 'Create an instance of the ISpVoice interface
                 pISpVoice = NEWCOM CLSID $CLSID_SpVoice
                 IF ISNOTHING(pISpVoice) THEN EXIT FUNCTION
                
                 'Speak some text
                 CONTROL GET TEXT hDlg, %TextboxText TO sText
                
                 wsText = UCODE$(sText & $NUL)
                
                 LISTBOX GET TEXT hDlg, %ListboxVoice TO sBuffer
                 LISTBOX GET SELECT hDlg, %ListboxVoice TO index
                 LISTBOX GET USER hDlg, %ListboxVoice, index TO RegistrySelection
                
                 VoiceSet(sBuffer, pISpVoice, RegistrySelection)
                
                 COMBOBOX GET SELECT hDlg, %ComboFormat TO wFormat
                 wFormat = wFormat + 3
                
                 pISpVoice.Speak(BYVAL STRPTR(wsText), %SVSFlagsAsync OR 0, ulStreamNumber)
                 DO
                   IF DoPause THEN
                     IF DoPause = 1 THEN pISpVoice.Pause()  : DoPause = 3
                     IF DoPause = 2 THEN pISpVoice.Resume() : DoPause = 0
                   ELSE
                
                     pISpVoice.GetStatus(eventStatus, BYVAL %NULL)
                     CONTROL SEND hDlg, %TextboxText, %EM_SETSEL, eventStatus.ulInputWordPos, _
                     eventStatus.ulInputWordPos + eventStatus.ulInputWordLen
                
                     CONTROL SEND hDlg, %TextboxText, %EM_SCROLLCARET, 0, 0
                
                     CONTROL GET TEXT hDlg, %LabelVolume TO sBuffer
                     wVolume = VAL(sBuffer)
                     pISpVoice.SetVolume(wVolume) 'Volume from zero to 100
                
                     CONTROL GET TEXT hDlg, %LabelSpeed TO sBuffer
                     wSpeed = VAL(sBuffer)
                     pISpVoice.SetRate(wSpeed) 'Talking speed from -10 to 10
                
                   END IF
                   RetVal = pISpVoice.WaitUntilDone(50) 'Milisec
                   IF RetVal = 0 THEN EXIT DO
                   IF DoSpeak = %FALSE THEN EXIT DO
                   DIALOG DOEVENTS
                 LOOP
                
                 pISpVoice = NOTHING 'Release the interface
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION XmlStrip(BYVAL sText AS STRING) AS STRING
                 LOCAL xPos1 AS LONG
                 LOCAL tPos1 AS LONG
                 LOCAL tag   AS LONG
                
                 'Simplistic Xml strip for demo purpose
                 tPos1 = 1
                 FOR xPos1 = 1 TO LEN(sText)
                   IF ASC(sText, xPos1) = 60 THEN         '< &lt; &LT; &#x0003C; &#60;
                     tag = %TRUE
                   ELSEIF ASC(sText, xPos1 - 1) = 62 THEN '> &gt; &GT; &#x0003E; &#62;
                     tag = %FALSE
                   END IF
                   IF tag = %FALSE THEN
                     ASC(sText, tPos1) = ASC(sText, xPos1)
                     IF ASC(sText, xPos1) = 38 THEN '&
                       SELECT CASE MID$(sText, xPos1 + 1, 3)
                         CASE "lt;", "LT;"
                           ASC(sText, tPos1) = 60 '< &lt; &LT;
                           xPos1 = xPos1 + 3
                         CASE "gt;", "GT;"
                           ASC(sText, tPos1) = 62 '> &gt; &GT;
                           xPos1 = xPos1 + 3
                         CASE ELSE
                           IF ASC(sText, xPos1 + 1) = 35 THEN '#
                             SELECT CASE MID$(sText, xPos1 + 1, 4)
                               CASE "#60;"
                                 ASC(sText, tPos1) = 60 '< &#60;
                                 xPos1 = xPos1 + 4
                               CASE "#62;"
                                 ASC(sText, tPos1) = 62 '> &#62;
                                 xPos1 = xPos1 + 4
                               CASE ELSE
                                 SELECT CASE MID$(sText, xPos1 + 1, 8)
                                   CASE "#x0003C;"
                                     ASC(sText, tPos1) = 60 '< &#x0003C;
                                     xPos1 = xPos1 + 8
                                   CASE "#x0003E;"
                                     ASC(sText, tPos1) = 62 '> &#x0003E;
                                     xPos1 = xPos1 + 8
                               END SELECT
                             END SELECT
                           END IF
                       END SELECT
                     END IF
                     INCR tPos1
                   END IF
                 NEXT
                 FUNCTION = LEFT$(sText, tPos1 - 1)
                
                END FUNCTION
                '_____________________________________________________________________________
                
                CALLBACK FUNCTION DlgProc
                 STATIC hControlFocus AS DWORD
                 LOCAL DefaultVoice   AS LONG
                
                 SELECT CASE CBMSG
                
                   CASE %WM_INITDIALOG
                     CONTROL SEND CBHNDL, %TrackbarVolume, %TBM_SETRANGE, %TRUE, MAKDWD(0, 100) 'Set range
                     CONTROL SEND CBHNDL, %TrackbarVolume, %TBM_SETTICFREQ, 10, 0  'Set tic frequency
                     CONTROL SEND CBHNDL, %TrackbarVolume, %TBM_SETPAGESIZE, 0, 10 'Set page size
                
                     CONTROL SEND CBHNDL, %TrackbarSpeed, %TBM_SETRANGE, %TRUE, MAKDWD(0, 20) 'Set range
                     CONTROL SEND CBHNDL, %TrackbarSpeed, %TBM_SETTICFREQ, 2, 0   'Set tic frequency
                     CONTROL SEND CBHNDL, %TrackbarSpeed, %TBM_SETPAGESIZE, 0, 20 'Set page size
                     CONTROL SEND CBHNDL, %TrackbarSpeed, %TBM_SETPOS, %TRUE, 10  'Set initial position
                
                     FormatComboFill
                     COMBOBOX SELECT hDlg, %ComboFormat, %SAFT44kHz16BitMono - 3
                     DefaultVoice = VoiceGet($SPCAT_VOICES, 0)
                     IF DefaultVoice > 0 THEN LISTBOX SELECT hDlg, %ListboxVoice, DefaultVoice
                     DefaultVoice = VoiceGet($SPCAT_VOICES10, 10)
                     IF DefaultVoice > 0 THEN LISTBOX SELECT hDlg, %ListboxVoice, DefaultVoice
                     CONTROL DISABLE hDlg, %ButtonPause
                
                   CASE %WM_VSCROLL, %WM_HSCROLL 'Handle in CBLPARAM, code in LO(WORD, CBWPARAM), position in HI(INTEGER, CBWPARAM)
                     SELECT CASE LOWRD(CBWPARAM)
                
                       CASE %TB_THUMBTRACK, %TB_LINEDOWN, %TB_LINEUP, _
                            %TB_PAGEDOWN, %TB_PAGEUP, %TB_TOP, %TB_BOTTOM
                
                         SELECT CASE GetDlgCtrlID(CBLPARAM) 'Handle in CBLPARAM to id
                
                           CASE %TrackbarVolume
                             CONTROL SET TEXT CBHNDL, %LabelVolume, STR$(100 - HI(WORD, CBWPARAM)) 'Update label with position
                
                           CASE %TrackbarSpeed
                             CONTROL SET TEXT CBHNDL, %LabelSpeed, STR$(10 - HI(WORD, CBWPARAM)) 'Update label with position
                
                         END SELECT
                     END SELECT
                
                   CASE %WM_COMMAND
                     SELECT CASE LOWRD(CBWPARAM)
                
                       CASE %ButtonSpeak '/Stop
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                           IF DoSpeak = %FALSE THEN
                             CONTROL SET TEXT hDlg, %ButtonSpeak, "&Stop"
                             CONTROL DISABLE hDlg, %ButtonWave
                             CONTROL DISABLE hDlg, %ButtonExit
                             CONTROL DISABLE hDlg, %ComboFormat
                             CONTROL DISABLE hDlg, %ListboxVoice
                             CONTROL ENABLE hDlg, %ButtonPause
                             DoSpeak = %TRUE
                             Speak
                             DoSpeak = %FALSE
                             CONTROL SET TEXT hDlg, %ButtonSpeak, "&Speak"
                             CONTROL ENABLE hDlg, %ButtonWave
                             CONTROL ENABLE hDlg, %ButtonExit
                             CONTROL ENABLE hDlg, %ComboFormat
                             CONTROL ENABLE hDlg, %ListboxVoice
                             CONTROL DISABLE hDlg, %ButtonPause
                           ELSE
                             DoSpeak = %FALSE
                           END IF
                         END IF
                
                       CASE %ButtonPause
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                           IF DoPause = 0 THEN
                             DoPause = 1
                             CONTROL SET TEXT hDlg, %ButtonPause, "Re&sume"
                             CONTROL DISABLE hDlg, %ButtonSpeak
                           ELSE
                             DoPause = 2 '1 = pause, 2 = resume
                             CONTROL SET TEXT hDlg, %ButtonPause, "Pau&se"
                             CONTROL ENABLE hDlg, %ButtonSpeak
                           END IF
                         END IF
                
                       CASE %ButtonWave
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                           CONTROL DISABLE hDlg, %ButtonSpeak
                           CONTROL DISABLE hDlg, %ButtonWave
                           CONTROL DISABLE hDlg, %ButtonExit
                           VoiceToWav
                           CONTROL ENABLE hDlg, %ButtonSpeak
                           CONTROL ENABLE hDlg, %ButtonWave
                           CONTROL ENABLE hDlg, %ButtonExit
                         END IF
                
                       CASE %ButtonSapiCpl
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                           LOCAL ProcessId AS DWORD
                           ProcessId = SHELL("rundll32.exe shell32.dll,Control_RunDLL C:\Windows\system32\speech\SpeechUX\SAPI.cpl")
                         END IF
                
                       CASE %ButtonExit
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                           DIALOG END hDlg
                         END IF
                
                     END SELECT
                
                   CASE %WM_NCACTIVATE
                     IF CBWPARAM THEN            'Application is getting focus
                       IF hControlFocus THEN     'Check if valid focus
                         SetFocus(hControlFocus) 'Restore focus on control
                         hControlFocus = 0
                       END IF
                     ELSE                         'Application is about to loose focus
                       hControlFocus = GetFocus() 'Remember witch control have focus
                     END IF
                
                  END SELECT
                
                END FUNCTION
                '______________________________________________________________________________
                
                FUNCTION PBMAIN()
                
                 DIALOG FONT "Segoe UI", 9
                 DIALOG NEW %HWND_DESKTOP, ExeName2(6), , , 312, 168, _
                 %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
                
                 SetClassLong(hDlg, %GCL_HICON, ExtractIcon(GetModuleHandle(""), "%SystemRoot%\system32\wpdshext.dll", 6))
                
                 CONTROL ADD LABEL, hDlg, %LabelVoice, "Voice available", 5, 5, 60, 10
                 CONTROL ADD LISTBOX, hDlg, %ListboxVoice, , 5, 15, 220, 50
                
                 CONTROL ADD LABEL, hDlg, %LabelFormat, "Format", 5, 60, 60, 10
                 CONTROL ADD COMBOBOX, hDlg, %ComboFormat, , 5, 70, 125, 100, _
                 %CBS_DROPDOWNLIST OR %WS_TABSTOP OR %WS_VSCROLL, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT
                
                 CONTROL ADD BUTTON, hDlg, %ButtonSapiCpl, "SAPI &CPL", 150, 70, 72, 13
                
                 CONTROL ADD LABEL, hDlg, %LabelText, "Speech", 5, 85, 60, 10
                
                 LOCAL sText AS STRING
                 sText = _
                 "<?xml version='1.0' encoding='UTF-8'?>"                      & $CRLF & _ '
                 "<vxml xmlns='http://www.w3.org/2001/vxml'"                   & $CRLF & _ '
                 "      xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" & $CRLF & _ '
                 "      xsi:schemaLocation='http://www.w3.org/2001/vxml"       & $CRLF & _ '
                 "      http://www.w3.org/TR/voicexml20/vxml.xsd'"             & $CRLF & _ '
                 "      version='2.0'><form><block>"                           & $CRLF & _ '
                 ""                                                            & $CRLF & _ '
                 "Now going for a two seconds pause..."                        & $CRLF & _ '
                 "<break time='2000ms'/>"                                      & $CRLF & _ '
                 "The pause is over!."                                         & $CRLF & _ '
                 ""                                                            & $CRLF & _ '
                 "</block></form></vxml>"                                      & $CRLF
                
                 CONTROL ADD TEXTBOX, hDlg, %TextboxText, sText, 5, 95, 220, 50, %WS_TABSTOP OR %WS_BORDER OR _
                 %ES_LEFT OR %ES_NOHIDESEL OR %WS_VSCROLL OR %ES_WANTRETURN OR %ES_MULTILINE
                
                 CONTROL ADD FRAME, hDlg, %FrameVolume, "Volume", 230, 5, 35, 140
                 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarVolume, "&V", 235, 13, 25, 122, _
                 %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %TBS_VERT OR %TBS_LEFT OR %TBS_AUTOTICKS
                 CONTROL ADD LABEL, hDlg, %LabelVolume, "100", 240, 135, 20, 9
                
                 CONTROL ADD FRAME, hDlg, %FrameSpeed, "Speed", 235 + 35, 5, 35, 140
                 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarSpeed, "&D", 275, 13, 25, 122, _
                 %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %TBS_VERT OR %TBS_LEFT OR %TBS_AUTOTICKS
                 CONTROL ADD LABEL, hDlg, %LabelSpeed, "0", 284, 135, 20, 9
                
                 CONTROL ADD BUTTON, hDlg, %ButtonSpeak, "Spea&k", 5, 150, 72, 15
                
                 CONTROL ADD BUTTON, hDlg, %ButtonPause, "Pau&se", 82, 150, 72, 15
                
                 CONTROL ADD BUTTON, hDlg, %ButtonWave, "Make &wave file", 158, 150, 72, 15
                
                 CONTROL ADD BUTTON, hDlg, %ButtonExit, "E&xit", 235, 150, 72, 15
                
                 DIALOG SHOW MODAL    hDlg CALL DlgProc
                
                END FUNCTION
                '______________________________________________________________________________
                '
                Last edited by Pierre Bellisle; 14 Jun 2018, 02:09 PM.

                Comment


                • #9
                  Windows 10 has two different TTS engines installed by default. There are the WinRT (Tablet Mode, used to be called Metro) speech synthesis APIs (in the Windows.Media.SpeechSynthesis namespace), and the SAPI (Desktop Mode) speech synthesis APIs (in the System.Speech.Synthesis namespace, and the COM ISpVoice interface).

                  David and Zira are SAPI voices; the language packs install WinRT voices.

                  If you want to use the language pack voices, In Pierre's Code (Post #8)

                  change
                  Code:
                  $SPCAT_VOICES   = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices"
                  To
                  Code:
                  $SPCAT_VOICES   = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices"

                  Comment


                  • #10
                    Code above is updated so both "Speech" and "Speech_OneCore" voices entrys are added to the list...

                    Comment


                    • #11
                      Pierre,
                      your changes do add both Speech" and "Speech_OneCore" voices entries to the list.
                      but only speaks with default voice, not the selected list item.

                      VoiceGet function should be changed

                      Code:
                      FUNCTION VoiceGet(BYVAL sCategoryId AS STRING, BYVAL RegistrySelection AS LONG) AS LONG
                      .
                      .
                             IF hr = %S_OK AND dwValue <> %NULL THEN
                               LISTBOX ADD hDlg, %ListboxVoice, pUnicodeToAnsi(dwValue) TO ListboxIndex    'added this
                      LISTBOX SET USER hDlg, %ListboxVoice, ListboxIndex, RegistrySelection       'added this
                               IF pUnicodeToAnsi(dwValue) = sVoiceDefault THEN
                                 LISTBOX GET COUNT hDlg, %ListboxVoice TO ListboxIndex
                                 LISTBOX SELECT hDlg, %ListboxVoice, ListboxIndex
                      'LISTBOX SET USER hDlg, %ListboxVoice, ListboxIndex, RegistrySelection    ' not sure this is needed
                               END IF
                               CoTaskMemFree(dwValue)
                             END IF
                      .
                      .
                      END FUNCTION

                      Comment


                      • #12
                        I did fix many bugs, above code is updated...

                        Comment


                        • #13
                          Brilliant Pierre,
                          how do you pause the speech text for a fixed duration say 3 to 5 secs before start of another sentence?

                          I have tried using "......................" but to no avail as it only last a second.

                          Comment


                          • #14
                            The em-dash "—" inserts a ½ second only delay.
                            One way could be to use XML text to get many options such as pausing... <break time=""5s"" /> will set a five second pause.

                            Comment


                            • #15
                              Thanks Pierre, how to incorporate the XML scripts into the textbox ?

                              As I have tried adding <break time=""5s"" /> into it, the voice just reads it out aloud

                              Comment


                              • #16
                                The Microsoft implementation of SSML is based on Speech Synthesis Markup Language (SSML) Version 1.0.
                                You have to give header, and version info, etc...
                                Copy and paste the following short example as is in the textbox of the program I posted above.

                                Code:
                                <?xml version="1.0" encoding="ISO-8859-1"?>
                                <speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
                                <sentence>
                                Now going for a two seconds pause... <break time="2s" /> The pause is over!.
                                </sentence>
                                </speak>

                                Comment


                                • #17
                                  Hi Pierre

                                  After copying and pasting the above scripts into the textbox and when it runs it still reads aloud whatever on that script !
                                  Hence it is not functioning as it should be ?

                                  Comment


                                  • #18
                                    Works fine for me under W7 and W10.
                                    I uploaded a new version that use "$PROGID_SAPISpFileStream1" with a pause button, a button to call SAPI control panel dialog, and simpler XML text.
                                    Another way for you might be to add some pause/resume custom calls in the pISpVoice.Speak() loop.

                                    Comment


                                    • #19
                                      Did not work for me in Windows 7, probably due to settings on my laptop. Thanks anyway ,Pierre , I would use the pause/resume button for this purpose.

                                      Comment


                                      • #20
                                        Interesting, I just tried on a fresh Windows 7-64 installation and all is fine...

                                        Might be a missing dot net framework related file or some other one.
                                        If you feel like it, you may download and install "Speech SDK 5.1" at
                                        https://www.microsoft.com/en-us/down....aspx?id=10121
                                        and see if it help. Note that there is a link to the SAPI.chm help file.

                                        There is also: "Speech Utilities for Microsoft Speech Technologies"
                                        Tools to troubleshoot, analyze, and diagnose elements of speech applications.
                                        at https://www.microsoft.com/en-us/down....aspx?id=18885

                                        Hope you will find a solution if the pause/resume functions are not adequate for your context.


                                        Comment

                                        Working...
                                        X