1 '***************************************************************************
3 ' Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 ' Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 ' Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 ' Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 ' $Id: sapi5_voice.vbs$
10 ' Copyright (C) 2007 Steve Bavin, Jens Arnold, Mesar Hameed
12 ' All files in this archive are subject to the GNU General Public License.
13 ' See the file COPYING in the source tree root for full license agreement.
15 ' This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 ' KIND, either express or implied.
18 '***************************************************************************
22 Const SSFMCreateForWrite
= 3
24 ' Audio formats for SAPI5 filestream object
25 Const SPSF_8kHz16BitMono
= 6
26 Const SPSF_11kHz16BitMono
= 10
27 Const SPSF_12kHz16BitMono
= 14
28 Const SPSF_16kHz16BitMono
= 18
29 Const SPSF_22kHz16BitMono
= 22
30 Const SPSF_24kHz16BitMono
= 26
31 Const SPSF_32kHz16BitMono
= 30
32 Const SPSF_44kHz16BitMono
= 34
33 Const SPSF_48kHz16BitMono
= 38
35 Dim oShell
, oArgs
, oEnv
37 Dim sLanguage
, sVoice
, sSpeed
39 Dim oSpVoice
, oSpFS
' SAPI5 voice and filestream
40 Dim oTTS
, nMode
' SAPI4 TTS object, mode selector
41 Dim nLangID
, sSelectString
43 Dim aLine
, aData
' used in command reading
48 Set oShell
= CreateObject("WScript.Shell")
49 Set oEnv
= oShell
.Environment("Process")
50 bVerbose
= (oEnv("V") <> "")
52 Set oArgs
= WScript
.Arguments
.Named
53 bSAPI4
= oArgs
.Exists("sapi4")
54 sLanguage
= oArgs
.Item("language")
55 sVoice
= oArgs
.Item("voice")
56 sSpeed
= oArgs
.Item("speed")
59 ' Create SAPI4 ActiveVoice object
60 Set oTTS
= WScript
.CreateObject("ActiveVoice.ActiveVoice", "TTS_")
61 If Err
.Number
<> 0 Then
63 Set oTTS
= WScript
.CreateObject("ActiveVoice.ActiveVoice.1", "TTS_")
64 If Err
.Number
<> 0 Then
65 WScript
.StdErr
.WriteLine
"Error - could not get ActiveVoice" _
66 & " object. SAPI 4 not installed?"
72 ' Select matching voice
73 For Each nLangID
in LangIDs(sLanguage
)
74 sSelectString
= "LanguageID=" & nLangID
76 sSelectString
= sSelectString
& ";Speaker=" & sVoice _
77 & ";ModeName=" & sVoice
79 nMode
= oTTS
.Find(sSelectString
)
80 If oTTS
.LanguageID(nMode
) = nLangID
And (sVoice
= "" Or _
81 oTTS
.Speaker(nMode
) = sVoice
Or oTTS
.ModeName(nMode
) = sVoice
) Then
82 If bVerbose
Then WScript
.StdErr
.WriteLine
"Using " & sSelectString
88 If sSelectString
= "" Then
89 WScript
.StdErr
.WriteLine
"Error - found no matching voice for " _
90 & sLanguage
& ", " & sVoice
96 If sSpeed
<> "" Then oSpVoice
.Speed
= sSpeed
99 Set oSpVoice
= CreateObject("SAPI.SpVoice")
100 If Err
.Number
<> 0 Then
101 WScript
.StdErr
.WriteLine
"Error - could not get SpVoice object." _
102 & " SAPI 5 not installed?"
106 ' Select matching voice
107 For Each nLangID
in LangIDs(sLanguage
)
108 sSelectString
= "Language=" & Hex(nLangID
)
110 sSelectString
= sSelectString
& ";Name=" & sVoice
112 Set oSpVoice
.Voice
= oSpVoice
.GetVoices(sSelectString
).Item(0)
113 If Err
.Number
= 0 Then
114 If bVerbose
Then WScript
.StdErr
.WriteLine
"Using " & sSelectString
121 If sSelectString
= "" Then
122 WScript
.StdErr
.WriteLine
"Error - found no matching voice for " _
123 & sLanguage
& ", " & sVoice
128 If sSpeed
<> "" Then oSpVoice
.Rate
= sSpeed
130 ' Filestream object for output
131 Set oSpFS
= CreateObject("SAPI.SpFileStream")
132 oSpFS
.Format
.Type = AudioFormat(oSpVoice
.Voice
.GetAttribute("Vendor"))
136 aLine
= Split(WScript
.StdIn
.ReadLine
, vbTab
, 2)
137 If Err
.Number
<> 0 Then
138 WScript
.StdErr
.WriteLine
"Error " & Err
.Number
& ": " & Err
.Description
141 Select Case aLine(0) ' command
146 WScript
.StdOut
.WriteLine oTTS
.MfgName(nMode
)
148 WScript
.StdOut
.WriteLine oSpVoice
.Voice
.GetAttribute("Vendor")
152 aData
= Split(aLine(1), vbTab
, 2)
153 aData(1) = UTF8decode(aData(1))
154 If bVerbose
Then WScript
.StdErr
.WriteLine
"Saying " & aData(1) _
157 oTTS
.FileName
= aData(0)
164 oSpFS
.Open
aData(0), SSFMCreateForWrite
, false
165 Set oSpVoice
.AudioOutputStream
= oSpFS
166 oSpVoice
.Speak
aData(1)
170 If bVerbose
Then WScript
.StdErr
.WriteLine
"> " & aLine(1)
171 oShell
.Run
aLine(1), 0, true
173 If bVerbose
Then WScript
.StdErr
.WriteLine
"Syncing"
174 WScript
.StdOut
.WriteLine
aLine(1) ' Just echo what was passed
176 If bVerbose
Then WScript
.StdErr
.WriteLine
"Quitting"
184 ' Decode an UTF-8 string into a standard windows unicode string (UTF-16)
185 Function UTF8decode(ByRef sText
)
186 Dim i
, c
, nCode
, nTail
, nTextLen
190 nTextLen
= Len(sText
)
193 c
= Asc(Mid(sText
, i
, 1))
195 If c
<= &h7F
Or c
>= &hC2
Then ' Start of new character
196 If c
< &h80
Then ' U-00000000 - U-0000007F, 1 byte
198 ElseIf c
< &hE0
Then ' U-00000080 - U-000007FF, 2 bytes
201 ElseIf c
< &hF0
Then ' U-00000800 - U-0000FFFF, 3 bytes
204 ElseIf c
< &hF5
Then ' U-00010000 - U-001FFFFF, 4 bytes
211 While nTail
> 0 And i
<= nTextLen
213 c
= Asc(Mid(sText
, i
, 1))
215 If (c
And &hC0
) = &h80
Then ' Valid continuation char
216 nCode
= nCode
* &h40
+ (c
And &h3F
)
217 Else ' Invalid continuation char
227 If nCode
>= &h10000
Then ' Character outside BMP - use surrogate pair
228 nCode
= nCode
- &h10000
229 c
= &hD800
+ ((nCode \
&h400
) And &h3FF
) ' high surrogate
230 UTF8decode
= UTF8decode
& ChrW(c
)
231 nCode
= &hDC00
+ (nCode
And &h3FF
) ' low surrogate
233 UTF8decode
= UTF8decode
& ChrW(nCode
)
237 ' SAPI5 output format selection based on engine
238 Function AudioFormat(ByRef sVendor
)
241 AudioFormat
= SPSF_22kHz16BitMono
243 AudioFormat
= SPSF_32kHz16BitMono
245 AudioFormat
= SPSF_16kHz16BitMono
247 AudioFormat
= SPSF_22kHz16BitMono
249 AudioFormat
= SPSF_16kHz16BitMono
251 AudioFormat
= SPSF_22kHz16BitMono
252 WScript
.StdErr
.WriteLine
"Warning - unknown vendor """ & sVendor _
253 & """ - using default wave format"
257 ' Language mapping rockbox->windows
258 Function LangIDs(ByRef sLanguage
)
261 Select Case sLanguage
263 LangIDs
= Array(&h436
)
265 LangIDs
= Array(&h402
)
267 LangIDs
= Array(&h403
)
269 LangIDs
= Array(&h804
) ' PRC
271 LangIDs
= Array(&h404
) ' Taiwan. Perhaps also Hong Kong, Singapore, Macau?
273 LangIDs
= Array(&h405
)
275 LangIDs
= Array(&h406
)
277 LangIDs
= Array(&h407
, &hc07
, &h1007
, &h1407
)
278 ' Standard, Austrian, Luxembourg, Liechtenstein (Swiss -> wallisertitsch)
280 LangIDs
= Array(&h425
)
282 LangIDs
= Array( &h809
, &h409
, &hc09
, &h1009
, &h1409
, &h1809
, _
283 &h1c09
, &h2009
, &h2409
, &h2809
, &h2c09
, &h3009
, _
285 ' Britsh, American, Australian, Canadian, New Zealand, Ireland,
286 ' South Africa, Jamaika, Caribbean, Belize, Trinidad, Zimbabwe,
289 LangIDs
= Array( &h40a
, &hc0a
, &h80a
, &h100a
, &h140a
, &h180a
, _
290 &h1c0a
, &h200a
, &h240a
, &h280a
, &h2c0a
, &h300a
, _
291 &h340a
, &h380a
, &h3c0a
, &h400a
, &h440a
, &h480a
, _
293 ' trad. sort., mordern sort., Mexican, Guatemala, Costa Rica,
294 ' Panama, Dominican Republic, Venezuela, Colombia, Peru, Argentina,
295 ' Ecuador, Chile, Uruguay, Paraguay, Bolivia, El Salvador,
296 ' Honduras, Nicaragua, Puerto Rico
298 WScript
.StdErr
.WriteLine
"Error: no esperanto support in Windows"
301 LangIDs
= Array(&h40b
)
303 LangIDs
= Array(&h40c
, &h80c
, &hc0c
, &h100c
, &h140c
, &h180c
)
304 ' Standard, Belgian, Canadian, Swiss, Luxembourg, Monaco
306 LangIDs
= Array(&h456
)
308 LangIDs
= Array(&h408
)
310 LangIDs
= Array(&h40d
)
312 LangIDs
= Array(&h40f
)
314 LangIDs
= Array(&h410
, &h810
) ' Standard, Swiss
316 LangIDs
= Array(&h411
)
318 LangIDs
= Array(&h412
)
320 LangIDs
= Array(&h40e
)
322 LangIDs
= Array(&h413
, &h813
) ' Standard, Belgian
324 LangIDs
= Array(&h414
) ' Bokmal
326 LangIDs
= Array(&h814
)
328 LangIDs
= Array(&h415
)
330 LangIDs
= Array(&h816
)
331 Case "portugues-brasileiro"
332 LangIDs
= Array(&h416
)
334 LangIDs
= Array(&h418
)
336 LangIDs
= Array(&h419
)
338 LangIDs
= Array(&h424
)
340 LangIDs
= Array(&h41d
, &h81d
) ' Standard, Finland
342 LangIDs
= Array(&h41f
)
343 Case "wallisertitsch"
344 LangIDs
= Array(&h807
) ' Swiss German