Skip to content

Instantly share code, notes, and snippets.

@lepinekong
Last active April 22, 2018 16:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lepinekong/a403da009633cef635b2fa2ea30d10c8 to your computer and use it in GitHub Desktop.
Save lepinekong/a403da009633cef635b2fa2ea30d10c8 to your computer and use it in GitHub Desktop.
See youtube below for easy install instruction (just copy and paste oneliner in Powershell) and demo tour of Text-to-speech with Cortana:
https://www.youtube.com/watch?v=u3rIyxtpEFY
$demo="cortana";$github='https://gist.github.com/lepinekong/a403da009633cef635b2fa2ea30d10c8';$demofolder="C:\red\demos\$demo";$exefolder="C:\red";$exeurl='https://static.red-lang.org/dl/win/red-063.exe';Add-Type -AssemblyName Microsoft.VisualBasic;$demofolder=[Microsoft.VisualBasic.Interaction]::InputBox("Enter folder for $demo demo:", $demo, $demofolder);if ($demofolder -ne $null) {$demo=Split-Path $demofolder -Leaf;Function Get-Links {Param($uri);[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;$WebResponse = Invoke-WebRequest -Uri "$uri";return $ResponseLinks=$WebResponse.Links | Select href};$AllLinks = Get-Links $github;Function Filter-Link {Param($filter);$links = $AllLinks | Where-Object {$_.href -match "$filter"};$link=$links[0].href;return $link};Function Get-Github-Url {Param($filename);$link=Filter-Link $filename;$url="https://gist.githubusercontent.com$link";return $url};$src=Get-Github-Url 'user.apps.cortana.speech.red';New-Item -ItemType Directory -Force -Path $red-folder;New-Item -ItemType Directory -Force -Path $demofolder;New-Item -ItemType Directory -Force -Path "$demofolder";$Webcli=New-Object System.Net.WebClient;if (!(Test-Path `"$exefolder\red.exe`")) {$Webcli.DownloadFile("$exeurl","$exefolder\red.exe")};$link=Get-Github-Url "MicrosoftEvaMobile.reg";$Webcli.DownloadFile($link,"$demofolder\MicrosoftEvaMobile.reg");$voice=Get-Content "$demofolder\MicrosoftEvaMobile.reg";$voice | Out-File -filepath "$demofolder\MicrosoftEvaMobile.reg" -Encoding "ascii";start explorer.exe -ArgumentList "/select, `"$demofolder\MicrosoftEvaMobile.reg`"";"Red [] `n print to-local-file what-dir `n do read $src" | Out-File -filepath "$demofolder\$demo.red" -Encoding "UTF8";"start `"%~n0`" `"$exefolder\red.exe`" `"$demofolder\%~n0.red`" %1" | Out-File -filepath "$demofolder\$demo.bat" -Encoding ASCII;cmd.exe /c "$demofolder\$demo.bat";Add-Type -AssemblyName PresentationFramework;$msgBox=[System.Windows.MessageBox]::Show('Would you like to download the source?','Download','YesNo','Question');switch ($msgBox) {'Yes' {$Webcli.DownloadFile($src,"$demofolder\$demo.red");$link=Get-Github-Url "user.apps.cortana.speech.deploy.ps1";$Webcli.DownloadFile($link,"$demofolder\user.apps.cortana.speech.deploy.ps1");$link=Get-Github-Url "user.apps.cortana.speech.deploy.red";$Webcli.DownloadFile($link,"$demofolder\user.apps.cortana.speech.deploy.red")} 'No' {}}}
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MSTTS_V110_enUS_EvaM]
@="Microsoft Eva Mobile - English (United States)"
"409"="Microsoft Eva Mobile - English (United States)"
"CLSID"="{179F3D56-1B0B-42B2-A962-59B7EF59FE1B}"
"LangDataPath"=hex(2):25,00,77,00,69,00,6e,00,64,00,69,00,72,00,25,00,5c,00,53,\
00,70,00,65,00,65,00,63,00,68,00,5f,00,4f,00,6e,00,65,00,43,00,6f,00,72,00,\
65,00,5c,00,45,00,6e,00,67,00,69,00,6e,00,65,00,73,00,5c,00,54,00,54,00,53,\
00,5c,00,65,00,6e,00,2d,00,55,00,53,00,5c,00,4d,00,53,00,54,00,54,00,53,00,\
4c,00,6f,00,63,00,65,00,6e,00,55,00,53,00,2e,00,64,00,61,00,74,00,00,00
"VoicePath"=hex(2):25,00,77,00,69,00,6e,00,64,00,69,00,72,00,25,00,5c,00,53,00,\
70,00,65,00,65,00,63,00,68,00,5f,00,4f,00,6e,00,65,00,43,00,6f,00,72,00,65,\
00,5c,00,45,00,6e,00,67,00,69,00,6e,00,65,00,73,00,5c,00,54,00,54,00,53,00,\
5c,00,65,00,6e,00,2d,00,55,00,53,00,5c,00,4d,00,31,00,30,00,33,00,33,00,45,\
00,76,00,61,00,00,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MSTTS_V110_enUS_EvaM\Attributes]
"Age"="Adult"
"Gender"="Female"
"Version"="11.0"
"Language"="409"
"Name"="Microsoft Eva Mobile"
"SharedPronunciation"=""
"Vendor"="Microsoft"
"DataVersion"="11.0.2013.1022"
Red [
Title: "user.apps.cortana.speech.deploy.red"
Description: {This script will generate user.apps.cortana.speech.deploy.ps1
the Zero Install Oneliner Powershell Script}
Urls: [
https://mcpmag.com/articles/2013/01/22/pshell-invoke-webrequest.aspx
https://www.jaapbrasser.com/quicktip-select-all-links-using-invoke-webrequest/
]
]
;===========================================================================================
; PREAMBLE
;===========================================================================================
; loading library
REMOTE-LIB: false
unless ((REMOTE-LIB = false) and (exists? lib: %.system.user.apps.authoring.library.red)) [
print "Loading remote lib"
do read https://gist.githubusercontent.com/lepinekong/7574892bfefe7e53e7bd4dd4759f30f8/raw/2dec6c1f92fe1834632d998ffb831539caa23d63/.github.lib.red
github-url-entry: https://gist.github.com/lepinekong/7574892bfefe7e53e7bd4dd4759f30f8
lib: get-github-url github-url-entry %.system.user.apps.authoring.library.red
]
do read lib
;self script path
script-path: system/options/script
short-filename: .get-short-filename/wo-extension script-path
;===========================================================================================
; DATA
;===========================================================================================
template: [
source: {
$demo="cortana"
$github='https://gist.github.com/lepinekong/a403da009633cef635b2fa2ea30d10c8'
$demofolder="C:\red\demos\$demo"
$exefolder="C:\red"
$exeurl='https://static.red-lang.org/dl/win/red-063.exe'
Add-Type -AssemblyName Microsoft.VisualBasic
$demofolder=[Microsoft.VisualBasic.Interaction]::InputBox("Enter folder for $demo demo:", $demo, $demofolder)
if ($demofolder -ne $null) {$demo=Split-Path $demofolder -Leaf
Function Get-Links {Param($uri)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$WebResponse = Invoke-WebRequest -Uri "$uri"
return $ResponseLinks=$WebResponse.Links | Select href}
$AllLinks = Get-Links $github
Function Filter-Link {Param($filter)
$links = $AllLinks | Where-Object {$_.href -match "$filter"}
$link=$links[0].href
return $link}
Function Get-Github-Url {Param($filename)
$link=Filter-Link $filename
$url="https://gist.githubusercontent.com$link"
return $url}
$src=Get-Github-Url 'user.apps.cortana.speech.red'
New-Item -ItemType Directory -Force -Path $red-folder
New-Item -ItemType Directory -Force -Path $demofolder
New-Item -ItemType Directory -Force -Path "$demofolder"
$Webcli=New-Object System.Net.WebClient
if (!(Test-Path `"$exefolder\red.exe`")) {$Webcli.DownloadFile("$exeurl","$exefolder\red.exe")}
$link=Get-Github-Url "MicrosoftEvaMobile.reg"
$Webcli.DownloadFile($link,"$demofolder\MicrosoftEvaMobile.reg")
$voice=Get-Content "$demofolder\MicrosoftEvaMobile.reg"
$voice | Out-File -filepath "$demofolder\MicrosoftEvaMobile.reg" -Encoding "ascii"
start explorer.exe -ArgumentList "/select, `"$demofolder\MicrosoftEvaMobile.reg`""
"Red [] `n print to-local-file what-dir `n do read $src" | Out-File -filepath "$demofolder\$demo.red" -Encoding "UTF8"
"start `"%~n0`" `"$exefolder\red.exe`" `"$demofolder\%~n0.red`" %1" | Out-File -filepath "$demofolder\$demo.bat" -Encoding ASCII
cmd.exe /c "$demofolder\$demo.bat"
Add-Type -AssemblyName PresentationFramework
$msgBox=[System.Windows.MessageBox]::Show('Would you like to download the source?','Download','YesNo','Question')
switch ($msgBox) {'Yes' {$Webcli.DownloadFile($src,"$demofolder\$demo.red")
$link=Get-Github-Url "user.apps.cortana.speech.deploy.ps1"
$Webcli.DownloadFile($link,"$demofolder\user.apps.cortana.speech.deploy.ps1")
$link=Get-Github-Url "user.apps.cortana.speech.deploy.red"
$Webcli.DownloadFile($link,"$demofolder\user.apps.cortana.speech.deploy.red")} 'No' {}}}
}
]
;===========================================================================================
; PROGRAM
;===========================================================================================
out: copy ""
source: .select template 'source
block: .read/lines source
forall block [
element: trim/head/tail block/1
unless (element = "") [
append out element
unless (tail? next next block) [append out ";"]
back back block
]
]
out-file: .to-file [short-filename ".ps1"]
write out-file out
;for debug in Powershell
split-source: function[][
src: read out-file
block: split src ";"
out: copy ""
forall block [
element: trim/head/tail block/1
unless (element = "") [
append out element
unless (tail? next next block) [append out newline]
back back block
]
]
write-clipboard out
]
split-source
Red [
Title: "user.apps.cortana.speech.red"
Description: {Easy Text to Speech with Cortana Natural Voice}
Demo: https://www.youtube.com/watch?v=u3rIyxtpEFY
Links: [
Red-Tutorials: [
https://dev.to/lepinekong/red-for-hopeless-programmers---part-i-3g0
https://dev.to/lepinekong/red-for-hopeless-programmers---part-ii-258
]
]
History: [
v1.0.0: {Initial version}
]
]
;===========================================================================================
; PREAMBLE
;===========================================================================================
; loading library
REMOTE-LIB: false ; TODO: allow local lib in next version
unless ((REMOTE-LIB = false) and (exists? lib: %.system.libraries.shell.red)) [
print "Loading remote lib"
do read https://gist.githubusercontent.com/lepinekong/7574892bfefe7e53e7bd4dd4759f30f8/raw/f1edb84222f3163b56b9c5bf2befd1ecaf988784/.github.lib.red
github-url-entry: https://gist.github.com/lepinekong/f007c5358104f0469d8b1ea7da11650e
lib: get-github-url github-url-entry %.system.libraries.shell.red
]
do read lib
;self script path
script-path: system/options/script
short-filename: .get-short-filename/wo-extension script-path
;install cortana the first time
install-cortana-voice: does [
ans: ask "Are you on a recent Windows 10 (YES/NO, NO by default): "
if not (ans = "YES") [
print "you cannot install Cortana Voice but still can play with Text2Speech"
exit
]
ans: ask "Double-Click on MicrosoftEvaMobile.reg (YES/NO/NEVER, NO by default, if NO you will be asked next time): "
if ans = "YES" [
cortana-voice-path: to-local-file rejoin [script-path "MicrosoftEvaMobile.reg"]
;call rejoin [{cmd /c regedit.exe "} cortana-voice-path {"}]
ans: ask "Is MicrosoftEvaMobile.reg installed (YES/NO, NO by default, if no you will be asked next time): "
if ans = "YES" [
write %config.red {
Red []
CORTANA-INSTALLED: "YES"
}
]
]
if ans = "NEVER" [
cortana-voice-path: to-local-file rejoin [script-path "MicrosoftEvaMobile.reg"]
call rejoin [{cmd /c regedit.exe "} cortana-voice-path {"}]
write %config.red {
Red []
CORTANA-INSTALLED: "NEVER"
}
]
]
either (exists? %config.red) [
do read %config.red
if CORTANA-INSTALLED = "NO" [
install-cortana-voice
]
] [
install-cortana-voice
]
;===========================================================================================
; PROGRAM
;===========================================================================================
user.app.speak: function[.message [word! string!] /print][
DEFAULT_RATE: 0
;-------------------------------------------------
.rate: DEFAULT_RATE
;-------------------------------------------------
message: replace/all .message "“" "" ; Cortana doesn't recognize "“"
message: replace/all .message "”" "" ; Cortana doesn't recognize "”"
rate: .rate
;-------------------------------------------------
template: .to-powershell [ ; all . methods are defined in library
{Add-Type -AssemblyName System.speech}
{$speaker = New-Object System.Speech.Synthesis.SpeechSynthesizer}
{$speaker.rate=<%rate%>}
{$Speaker.Speak("<%message%>")}
]
powershell-command: .string.expand template [ ; .string.expand is defined in library
message: (message)
rate: (rate)
]
.refresh-screen
if print [system/words/print .message] ; since print is used as refinement one should call system/words/print
.refresh-screen ; defined in library as .do-events/no-wait
call/wait powershell-command ; /wait waits for speak to finish sentence
]
speak: :user.app.speak; speak is clone of user.app.speak method
msg: {Hello, I'm Cortana, the natural voice for Windows 10 only.
Run MicrosoftEvaMobile.reg with admin right to update registry.
Check that you have recent version of Windows 10 and be aware I don't guarantee the result.}
speak/print msg ; /print is a refinement for printing message before speaking
; it's shortcut for {print msg .refresh-screen speak msg .refresh-screen}
msg: {Note that you can change the DEFAULT RATE of speed in program. 0 is normal speed, 1 is faster.}
speak/print msg
msg: "Now, try: paste something to say in clipboard, Press a key when done..."
speak/print msg
ask "Press a key when done..."
msg: read-clipboard
speak/print msg
print {you can type command "speak/print read-clipboard" at any time}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment