Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[function] Easy Text to speech


  • Please log in to reply
43 replies to this topic
sumon
  • Moderators
  • 1317 posts
  • Last active: Dec 05 2016 10:14 PM
  • Joined: 18 May 2010
Don't know if you knew this, but I found a TTS_Google on the german forums: <!-- m -->http://de.autohotkey...opic.php?t=8210<!-- m -->

It basically lets you do text-to-speech using Googles TTS function, thus enabling many languages and voices. :)

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
@sumon:
Well, I need offline solution but thanks for a link - it's nice & useful so I'll put it in the first post. ;)

@genmce:

Looks like "set rate" is the speed of speech.

Yes.

Also - I don't see a pitch adjustment (perhaps I missed it), is that possible?

No.

Each word spoken on the beat/in time with the midi clock

Imagine that pressing hotkey is in fact MIDI-IN message:
AnnaVoice := TTS_CreateVoice("Microsoft Anna")
1::TTS(AnnaVoice, "Speak", "My")
2::TTS(AnnaVoice, "Speak", "dog")
3::TTS(AnnaVoice, "Speak", "has")
4::TTS(AnnaVoice, "Speak", "fleas")
But note that you can't speak multiple phrases at the same time. No overlapping. Unless you use AutoHotkey.dll

bruno
  • Members
  • 635 posts
  • Last active: Nov 04 2015 02:26 PM
  • Joined: 07 Mar 2011
This was one of the most mind-boggling scripts of all time! :wink:

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
:)

Remington
  • Members
  • 13 posts
  • Last active: Jul 23 2011 08:40 PM
  • Joined: 10 Jul 2011
Our 8 year old daughter absolutely loves playing with this program and I figured others would find it entertaining/helpful.

; Instantly read text aloud upon pressing Enter.

/*
Intended Audience:
   * Young children who get a kick out of playing with Text-to-Speech or who are learning to spell.
   * Speech impaired individuals who want to be able to use TTS at near conversational speeds for communication.
   * Anonymous callers.
   * Prank callers.

Prerequisits:
   * AutoHotkey_L available at http://www.autohotkey.net/~Lexikos/AutoHotkey_L/. This code is not compatible with AutoHotkey Basic.
   * Create one text file named "Text-to-Speech Male.txt" and one named "Text-to-Speech Female.txt". It does not matter where the files are located.
   * SAPI voice(s) preinstalled. The voice "Microsoft Anna" should be preinstalled on Vista and Windows 7 operating systems so at least the female voice should work by default on most modern systems. "Microsoft Sam" is the default voice for Windows XP but "Microsoft Sam," "Microsoft Mike," and "Microsoft Mary" do not work on Windows Vista and later. NextUp.com is a convenient place to purchase additional and/or better voices but you may have to purchase one of their programs to be able to use the voices. See http://www.nextup.com/TextAloud/SpeechEngine/voices.html
   
Instructions:
   See what TTS voices you have available on your system and see what they are called by executing the following script:
      ; TTS Voice List by Learning one
      Voice := ComObjCreate("SAPI.SpVoice")
      MsgBox % TTS(Voice, "GetVoices")
      ExitApp
   Customize the names of the TTS voices in the following script
   Execute the script.
   Open one or both of the text files created above.
   Type something into one of the text files.
   Press Enter
   The text will automatically be read.
   Press Enter again to repeat the speech.
   Start typing while text is highlighted to replace with a new phrase.
*/

; C U S T O M I Z E   T H E   F O L L O W I N G   T T S   N A M E S :
; (These should be identical to one of the voices listed in TTS Voice List script from the instructions.)

MaleVoice := TTS_CreateVoice("ScanSoft Lee_Full_22kHz") ; This is a great sounding, premium Austrialian voice. See http://www.nextup.com/TextAloud/SpeechEngine/voices.html#Nuance
FemaleVoice := TTS_CreateVoice("Microsoft Anna") ; Beginning with Windows Vista and Windows 7, Microsoft Anna is the default English voice.

; E N D  O F  C U S T O M I Z A T I O N

; Text reader for male voice
SetTitleMatchMode , 2 ; This allows WinWaitActive/#IfWinActive to match a part of the window title rather than the whole thing.
#IfWinActive , Text-to-Speech Male ; This causes the hotkey to only work in a window titled Text-to-Speech Male
Enter::TTS(MaleVoice, "ToggleSpeak", gst()) ; Type some text and press Enter to have it spoken.
Return

; Text reader for female voice
SetTitleMatchMode , 2 ; This allows WinWaitActive/#IfWinActive to match a part of the window title rather than the whole thing.
#IfWinActive , Text-to-Speech Female ; This causes the hotkey to only work in a window titled Text-to-Speech Female
Enter::TTS(FemaleVoice, "ToggleSpeak", gst()) ; Type some text and press Enter to have it spoken by Microsoft Anna.
Return

; F U N C T I O N S :
; -------------------------------------------
; GetSelectedText Function by Learning one
gst() {    
   Send , ^a^c
   ClipWait , 0.1
   ToReturn := Clipboard, Clipboard := ClipboardBackup
   if !IsClipEmpty
   ClipWait, 0.5, 1
   Return ToReturn
}

; TTS (Text-to-Speech) Function
TTS(oVoice, command, param1="", param2="") {      ; by Learning one. For AHK_L. Thanks: jballi, Sean, Frankie.
   ; AHK forum location:   www.autohotkey.com/forum/topic57773.html
   ; Read more:         msdn.microsoft.com/en-us/library/ms723602(v=VS.85).aspx, www.autohotkey.com/forum/topic45471.html
   static CommandList := "ToggleSpeak,Speak,SpeakWait,Pause,Stop,SetRate,SetVolume,SetVoice,GetVoices,GetStatus,GetCount,SpeakToFile"
   if command not in %CommandList%
   {
      MsgBox, 16, TTS() error, "%command%" is not valid command.
      return
   }
   if command = ToggleSpeak   ; speak or stop speaking
   {
      Status := oVoice.Status.RunningState
      if Status = 1   ; finished
      oVoice.Speak(param1,0x1)   ; speak asynchronously
      Else if Status = 0   ; paused
      {
         oVoice.Resume
         oVoice.Speak("",0x1|0x2)   ; stop
         oVoice.Speak(param1,0x1)   ; speak asynchronously
      }
      Else if Status = 2   ; reading
      oVoice.Speak("",0x1|0x2)   ; stop
   }
   Else if command = Speak      ; speak asynchronously
   {
      Status := oVoice.Status.RunningState
      if Status = 0   ; paused
      oVoice.Resume
      oVoice.Speak("",0x1|0x2)   ; stop
      oVoice.Speak(param1,0x1)   ; speak asynchronously
   }
   Else if command = SpeakWait      ; speak synchronously
   {
      Status := oVoice.Status.RunningState
      if Status = 0   ; paused
      oVoice.Resume
      oVoice.Speak("",0x1|0x2)   ; stop
      oVoice.Speak(param1,0x0)   ; speak synchronously
   }
   Else if command = Pause   ; Pause toggle
   {
      Status := oVoice.Status.RunningState
      if Status = 0   ; paused
      oVoice.Resume
      else if Status = 2   ; reading
      oVoice.Pause
   }
   Else if command = Stop
   {
      Status := oVoice.Status.RunningState
      if Status = 0   ; paused
      oVoice.Resume
      oVoice.Speak("",0x1|0x2)   ; stop
   }
   Else if command = SetRate
   oVoice.Rate := param1      ; rate (reading speed): param1 from -10 to 10. 0 is default.
   Else if command = SetVolume
   oVoice.Volume := param1      ; volume (reading loudness): param1 from 0 to 100. 100 is default
   Else if command = SetVoice
   {
      Loop, % oVoice.GetVoices.Count
      {
         Name := oVoice.GetVoices.Item(A_Index-1).GetAttribute("Name")   ; 0 based
         If (Name = param1)
         {
            DoesVoiceExist = 1
            break
         }
      }
      if !DoesVoiceExist
      {
         MsgBox,64,, Voice "%param1%" does not exist.
         return
      }
      While   !(oVoice.Status.RunningState = 1)
      Sleep, 20
      oVoice.Voice := oVoice.GetVoices("Name=" param1).Item(0) ; set voice to param1
   }
   Else if command = GetVoices
   {
      param1 := (param1 = "") ? "`n" : param1      ; param1 as delimiter
      Loop, % oVoice.GetVoices.Count
      {
         Name := oVoice.GetVoices.Item(A_Index-1).GetAttribute("Name")   ; 0 based
         VoiceList .= Name param1
      }
      Return RTrim(VoiceList,param1)
   }
   Else if command = GetStatus
   {
      Status := oVoice.Status.RunningState
      if StatusNum = 0 ; paused
      Return "paused"
      Else if StatusNum = 1 ; finished
      Return "finished"
      Else if StatusNum = 2 ; reading
      Return "reading"
   }
   else if command = GetCount
   return oVoice.GetVoices.Count
   Else if command = SpeakToFile   ; param1 = TextToSpeak,    param2 = OutputFilePath
   {
      oldAOS := oVoice.AudioOutputStream
      oldAAOFCONS := oVoice.AllowAudioOutputFormatChangesOnNextSet
      oVoice.AllowAudioOutputFormatChangesOnNextSet := 1   
      
      SpStream := ComObjCreate("SAPI.SpFileStream")
      FileDelete, % param2   ; OutputFilePath
      SpStream.Open(param2, 3)
      oVoice.AudioOutputStream := SpStream
      TTS(oVoice, "SpeakWait", param1)
      SpStream.Close()
      oVoice.AudioOutputStream := oldAOS
      oVoice.AllowAudioOutputFormatChangesOnNextSet := oldAAOFCONS
   }
}   

TTS_CreateVoice(VoiceName="", VoiceRate="", VoiceVolume="") {      ; by Learning one. For AHK_L.
   oVoice := ComObjCreate("SAPI.SpVoice")
   if !(VoiceName = "")
   TTS(oVoice, "SetVoice", VoiceName)
   if VoiceRate between -10 and 10
   oVoice.Rate := VoiceRate      ; rate (reading speed): param1 from -10 to 10. 0 is default.
   if VoiceVolume between 0 and 100
   oVoice.Volume := VoiceVolume   ; volume (reading loudness): param1 from 0 to 100. 100 is default
   return oVoice
}

Remington

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
:)

AurelTristen
  • Members
  • 7 posts
  • Last active: Jan 29 2012 05:04 AM
  • Joined: 14 Nov 2008
That script is really cool Remington! I'm not much of a scripter / programmer, so I'm trying to figure it all out.

What would I need to simply speak a phrase set by the script its self, without any custom voice options, clipboard management or any of that?

I was totally unaware of AutoHotkey_L, so I'm lost all over again.
I have no idea what I'm doing, but its AWESOME!

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
In AHK_L TTS is a one-liner
ComObjCreate("SAPI.SpVoice").Speak("Testing one two three")


AurelTristen
  • Members
  • 7 posts
  • Last active: Jan 29 2012 05:04 AM
  • Joined: 14 Nov 2008
Holy crap, thanks! So something like this would do what I need:

ComObjCreate("SAPI.SpVoice").Speak("%string%")

That would make eyes-free feedback so much easier. I guess I need to do some serious reading on this _L situation.
I have no idea what I'm doing, but its AWESOME!

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
You should read up on expressions: <!-- m -->http://d.ahk4.me/Variables#Expressions<!-- m -->
Basically remove the "%%" around the variable.
pVoice := ComObjCreate("SAPI.SpVoice")
pVoice.Speak("Literal string")
pVoice.Speak(Variable)
Note how I stored the object in a variable -- it will run faster with multiple things to "say" since it won't keep re-creating.

hqworp
  • Members
  • 2 posts
  • Last active: Feb 10 2012 07:19 AM
  • Joined: 10 Feb 2012
Hi All,

How can I use other SAPI voices? the script above use only SAPI voice and I have SAPI5 and SAPI 4 voices too...

Thanls!!!

HQWarp
  • Guests
  • Last active:
  • Joined: --
if I run the script above using the x64 execution, its see only 1 TTS

BUT if i run the script using the x86, then I see the real number that installed on my system...

Thanks to all on the great script...

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009

How can I use other SAPI voices?

First you'll have to download and install additional SAPI voices. I posted links to some free SAPI voices here.

* * *

:arrow: TTS() and TTS_CreateVoice() updated
The new feature is that now user can easily change voice's pitch. I also posted 2 new examples.

daveclark
  • Members
  • 7 posts
  • Last active: Aug 01 2015 12:26 PM
  • Joined: 26 Dec 2011
I too am having problem with memory overuse.
After speaking, the script won't clear memory.
Could you help me, Learning One?

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
Hi daveclark,

when I run example 1 script, it initially takes 2780 K of memory. After pressing F1, it takes 9250 K, and it's not increasing after that. If you have similar results - that's OK.
Try this simple script:
oVoice := ComObjCreate("SAPI.SpVoice")
MsgBox, Check memory usage now and after you press OK.
oVoice.Speak("Automate almost anything by sending keystrokes and mouse clicks.",0x0)
Similar thing as in example 1 happens here as well - before pressing OK, it takes 2780 K, and after pressing OK, it takes 9070 K.
So, after calling Speak method, memory usage will increase. If you think that's not OK, than I think you'll have to contact Lexikos or maybe Microsoft.