1 '***************************************************************************
3 ' Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 ' Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 ' Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 ' Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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
36 Dim bVerbose
, bSAPI4
, bList
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
45 Dim counter
, ende
, list
49 Set oShell
= CreateObject("WScript.Shell")
50 Set oEnv
= oShell
.Environment("Process")
51 bVerbose
= (oEnv("V") <> "")
53 Set oArgs
= WScript
.Arguments
.Named
54 bSAPI4
= oArgs
.Exists("sapi4")
55 bList
= oArgs
.Exists("listvoices")
56 sLanguage
= oArgs
.Item("language")
57 sVoice
= oArgs
.Item("voice")
58 sSpeed
= oArgs
.Item("speed")
60 ' display a list of voices for the selected language
63 Set oSpVoice
= CreateObject("SAPI.SpVoice")
64 If Err
.Number
<> 0 Then
65 WScript
.StdErr
.WriteLine
"Error - could not get SpVoice object." _
66 & " SAPI 5 not installed?"
71 ' Select matching voice
72 For Each nLangID
in LangIDs(sLanguage
)
73 sSelectString
= "Language=" & Hex(nLangID
)
78 Set oSpVoice
.Voice
= oSpVoice
.GetVoices(sSelectString
).Item(counter
)
80 If Err
.Number
= 0 Then
81 list
= list
& oSpVoice
.Voice
.GetDescription
& ","
90 WScript
.StdErr
.WriteLine list
97 ' Create SAPI4 ActiveVoice object
98 Set oTTS
= WScript
.CreateObject("ActiveVoice.ActiveVoice", "TTS_")
99 If Err
.Number
<> 0 Then
101 Set oTTS
= WScript
.CreateObject("ActiveVoice.ActiveVoice.1", "TTS_")
102 If Err
.Number
<> 0 Then
103 WScript
.StdErr
.WriteLine
"Error - could not get ActiveVoice" _
104 & " object. SAPI 4 not installed?"
110 ' Select matching voice
111 For Each nLangID
in LangIDs(sLanguage
)
112 sSelectString
= "LanguageID=" & nLangID
114 sSelectString
= sSelectString
& ";Speaker=" & sVoice _
115 & ";ModeName=" & sVoice
117 nMode
= oTTS
.Find(sSelectString
)
118 If oTTS
.LanguageID(nMode
) = nLangID
And (sVoice
= "" Or _
119 oTTS
.Speaker(nMode
) = sVoice
Or oTTS
.ModeName(nMode
) = sVoice
) Then
120 If bVerbose
Then WScript
.StdErr
.WriteLine
"Using " & sSelectString
126 If sSelectString
= "" Then
127 WScript
.StdErr
.WriteLine
"Error - found no matching voice for " _
128 & sLanguage
& ", " & sVoice
134 If sSpeed
<> "" Then oSpVoice
.Speed
= sSpeed
136 ' Create SAPI5 object
137 Set oSpVoice
= CreateObject("SAPI.SpVoice")
138 If Err
.Number
<> 0 Then
139 WScript
.StdErr
.WriteLine
"Error - could not get SpVoice object." _
140 & " SAPI 5 not installed?"
144 ' Select matching voice
145 For Each nLangID
in LangIDs(sLanguage
)
146 sSelectString
= "Language=" & Hex(nLangID
)
148 sSelectString
= sSelectString
& ";Name=" & sVoice
150 Set oSpVoice
.Voice
= oSpVoice
.GetVoices(sSelectString
).Item(0)
151 If Err
.Number
= 0 Then
152 If bVerbose
Then WScript
.StdErr
.WriteLine
"Using " & sSelectString
159 If sSelectString
= "" Then
160 WScript
.StdErr
.WriteLine
"Error - found no matching voice for " _
161 & sLanguage
& ", " & sVoice
166 If sSpeed
<> "" Then oSpVoice
.Rate
= sSpeed
168 ' Filestream object for output
169 Set oSpFS
= CreateObject("SAPI.SpFileStream")
170 oSpFS
.Format
.Type = AudioFormat(oSpVoice
.Voice
.GetAttribute("Vendor"))
174 aLine
= Split(WScript
.StdIn
.ReadLine
, vbTab
, 2)
175 If Err
.Number
<> 0 Then
176 WScript
.StdErr
.WriteLine
"Error " & Err
.Number
& ": " & Err
.Description
179 Select Case aLine(0) ' command
184 WScript
.StdOut
.WriteLine oTTS
.MfgName(nMode
)
186 WScript
.StdOut
.WriteLine oSpVoice
.Voice
.GetAttribute("Vendor")
190 aData
= Split(aLine(1), vbTab
, 2)
191 aData(1) = UTF8decode(aData(1))
192 If bVerbose
Then WScript
.StdErr
.WriteLine
"Saying " & aData(1) _
195 oTTS
.FileName
= aData(0)
202 oSpFS
.Open
aData(0), SSFMCreateForWrite
, false
203 Set oSpVoice
.AudioOutputStream
= oSpFS
204 oSpVoice
.Speak
aData(1)
208 If bVerbose
Then WScript
.StdErr
.WriteLine
"> " & aLine(1)
209 oShell
.Run
aLine(1), 0, true
210 If Err
.Number
<> 0 Then
212 WScript
.StdErr
.Write
"> " & aLine(1) & ": "
214 If Err
.Number
= &H80070002
Then ' Actually file not found
215 WScript
.StdErr
.WriteLine
"command not found"
217 WScript
.StdErr
.WriteLine
"error " & Err
.Number
& ":" _
223 If bVerbose
Then WScript
.StdErr
.WriteLine
"Syncing"
224 WScript
.StdOut
.WriteLine
aLine(1) ' Just echo what was passed
226 If bVerbose
Then WScript
.StdErr
.WriteLine
"Quitting"
234 ' Decode an UTF-8 string into a standard windows unicode string (UTF-16)
235 Function UTF8decode(ByRef sText
)
236 Dim i
, c
, nCode
, nTail
, nTextLen
240 nTextLen
= Len(sText
)
243 c
= Asc(Mid(sText
, i
, 1))
245 If c
<= &h7F
Or c
>= &hC2
Then ' Start of new character
246 If c
< &h80
Then ' U-00000000 - U-0000007F, 1 byte
248 ElseIf c
< &hE0
Then ' U-00000080 - U-000007FF, 2 bytes
251 ElseIf c
< &hF0
Then ' U-00000800 - U-0000FFFF, 3 bytes
254 ElseIf c
< &hF5
Then ' U-00010000 - U-001FFFFF, 4 bytes
261 While nTail
> 0 And i
<= nTextLen
263 c
= Asc(Mid(sText
, i
, 1))
265 If (c
And &hC0
) = &h80
Then ' Valid continuation char
266 nCode
= nCode
* &h40
+ (c
And &h3F
)
267 Else ' Invalid continuation char
277 If nCode
>= &h10000
Then ' Character outside BMP - use surrogate pair
278 nCode
= nCode
- &h10000
279 c
= &hD800
+ ((nCode \
&h400
) And &h3FF
) ' high surrogate
280 UTF8decode
= UTF8decode
& ChrW(c
)
281 nCode
= &hDC00
+ (nCode
And &h3FF
) ' low surrogate
283 UTF8decode
= UTF8decode
& ChrW(nCode
)
287 ' SAPI5 output format selection based on engine
288 Function AudioFormat(ByRef sVendor
)
291 AudioFormat
= SPSF_22kHz16BitMono
293 AudioFormat
= SPSF_32kHz16BitMono
295 AudioFormat
= SPSF_16kHz16BitMono
297 AudioFormat
= SPSF_22kHz16BitMono
299 AudioFormat
= SPSF_16kHz16BitMono
301 AudioFormat
= SPSF_22kHz16BitMono
302 WScript
.StdOut
.WriteLine
"Warning - unknown vendor """ & sVendor _
303 & """ - using default wave format"
307 ' Language mapping rockbox->windows
308 Function LangIDs(ByRef sLanguage
)
311 Select Case sLanguage
313 LangIDs
= Array(&h436
)
315 LangIDs
= Array(&h402
)
317 LangIDs
= Array(&h403
)
319 LangIDs
= Array(&h804
) ' PRC
321 LangIDs
= Array(&h404
) ' Taiwan. Perhaps also Hong Kong, Singapore, Macau?
323 LangIDs
= Array(&h405
)
325 LangIDs
= Array(&h406
)
327 LangIDs
= Array(&h407
, &hc07
, &h1007
, &h1407
)
328 ' Standard, Austrian, Luxembourg, Liechtenstein (Swiss -> wallisertitsch)
330 LangIDs
= Array(&h425
)
332 LangIDs
= Array( &h809
, &h409
, &hc09
, &h1009
, &h1409
, &h1809
, _
333 &h1c09
, &h2009
, &h2409
, &h2809
, &h2c09
, &h3009
, _
335 ' Britsh, American, Australian, Canadian, New Zealand, Ireland,
336 ' South Africa, Jamaika, Caribbean, Belize, Trinidad, Zimbabwe,
339 LangIDs
= Array( &h40a
, &hc0a
, &h80a
, &h100a
, &h140a
, &h180a
, _
340 &h1c0a
, &h200a
, &h240a
, &h280a
, &h2c0a
, &h300a
, _
341 &h340a
, &h380a
, &h3c0a
, &h400a
, &h440a
, &h480a
, _
343 ' trad. sort., mordern sort., Mexican, Guatemala, Costa Rica,
344 ' Panama, Dominican Republic, Venezuela, Colombia, Peru, Argentina,
345 ' Ecuador, Chile, Uruguay, Paraguay, Bolivia, El Salvador,
346 ' Honduras, Nicaragua, Puerto Rico
348 WScript
.StdErr
.WriteLine
"Error: no esperanto support in Windows"
351 LangIDs
= Array(&h40b
)
353 LangIDs
= Array(&h40c
, &h80c
, &hc0c
, &h100c
, &h140c
, &h180c
)
354 ' Standard, Belgian, Canadian, Swiss, Luxembourg, Monaco
356 LangIDs
= Array(&h456
)
358 LangIDs
= Array(&h408
)
360 LangIDs
= Array(&h40d
)
362 LangIDs
= Array(&h40f
)
364 LangIDs
= Array(&h410
, &h810
) ' Standard, Swiss
366 LangIDs
= Array(&h411
)
368 LangIDs
= Array(&h412
)
370 LangIDs
= Array(&h40e
)
372 LangIDs
= Array(&h413
, &h813
) ' Standard, Belgian
374 LangIDs
= Array(&h414
) ' Bokmal
376 LangIDs
= Array(&h814
)
378 LangIDs
= Array(&h415
)
380 LangIDs
= Array(&h816
)
381 Case "portugues-brasileiro"
382 LangIDs
= Array(&h416
)
384 LangIDs
= Array(&h418
)
386 LangIDs
= Array(&h419
)
388 LangIDs
= Array(&h424
)
390 LangIDs
= Array(&h41d
, &h81d
) ' Standard, Finland
392 LangIDs
= Array(&h41f
)
393 Case "wallisertitsch"
394 LangIDs
= Array(&h807
) ' Swiss German