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 oVoice
' for traversing the list of voices
42 Dim nLangID
, sSelectString
44 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 bList
= oArgs
.Exists("listvoices")
55 sLanguage
= oArgs
.Item("language")
56 sVoice
= oArgs
.Item("voice")
57 sSpeed
= oArgs
.Item("speed")
61 ' Create SAPI4 ActiveVoice object
62 Set oTTS
= WScript
.CreateObject("ActiveVoice.ActiveVoice", "TTS_")
63 If Err
.Number
<> 0 Then
65 Set oTTS
= WScript
.CreateObject("ActiveVoice.ActiveVoice.1", "TTS_")
66 If Err
.Number
<> 0 Then
67 WScript
.StdErr
.WriteLine
"Error - could not get ActiveVoice" _
68 & " object. SAPI 4 not installed?"
75 ' Just list available voices for the selected language
76 For Each nLangID
in LangIDs(sLanguage
)
77 For nMode
= 1 To oTTS
.CountEngines
78 If oTTS
.LanguageID(nMode
) = nLangID
Then
79 WScript
.StdErr
.Write oTTS
.ModeName(nMode
) & ","
83 WScript
.StdErr
.WriteLine
87 ' Select matching voice
88 For Each nLangID
in LangIDs(sLanguage
)
89 sSelectString
= "LanguageID=" & nLangID
91 sSelectString
= sSelectString
& ";Speaker=" & sVoice _
92 & ";ModeName=" & sVoice
94 nMode
= oTTS
.Find(sSelectString
)
95 If oTTS
.LanguageID(nMode
) = nLangID
And (sVoice
= "" Or _
96 oTTS
.Speaker(nMode
) = sVoice
Or oTTS
.ModeName(nMode
) = sVoice
) Then
97 If bVerbose
Then WScript
.StdErr
.WriteLine
"Using " & sSelectString
103 If sSelectString
= "" Then
104 WScript
.StdErr
.WriteLine
"Error - found no matching voice for " _
105 & sLanguage
& ", " & sVoice
111 If sSpeed
<> "" Then oTTS
.Speed
= sSpeed
113 ' Create SAPI5 object
114 Set oSpVoice
= CreateObject("SAPI.SpVoice")
115 If Err
.Number
<> 0 Then
116 WScript
.StdErr
.WriteLine
"Error - could not get SpVoice object." _
117 & " SAPI 5 not installed?"
122 ' Just list available voices for the selected language
123 For Each nLangID
in LangIDs(sLanguage
)
124 sSelectString
= "Language=" & Hex(nLangID
)
125 For Each oVoice
in oSpVoice
.GetVoices(sSelectString
)
126 WScript
.StdErr
.Write oVoice
.GetAttribute("Name") & ","
129 WScript
.StdErr
.WriteLine
133 ' Select matching voice
134 For Each nLangID
in LangIDs(sLanguage
)
135 sSelectString
= "Language=" & Hex(nLangID
)
137 sSelectString
= sSelectString
& ";Name=" & sVoice
139 Set oSpVoice
.Voice
= oSpVoice
.GetVoices(sSelectString
).Item(0)
140 If Err
.Number
= 0 Then
141 If bVerbose
Then WScript
.StdErr
.WriteLine
"Using " & sSelectString
148 If sSelectString
= "" Then
149 WScript
.StdErr
.WriteLine
"Error - found no matching voice for " _
150 & sLanguage
& ", " & sVoice
155 If sSpeed
<> "" Then oSpVoice
.Rate
= sSpeed
157 ' Filestream object for output
158 Set oSpFS
= CreateObject("SAPI.SpFileStream")
159 oSpFS
.Format
.Type = AudioFormat(oSpVoice
.Voice
.GetAttribute("Vendor"))
163 aLine
= Split(WScript
.StdIn
.ReadLine
, vbTab
, 2)
164 If Err
.Number
<> 0 Then
165 WScript
.StdErr
.WriteLine
"Error " & Err
.Number
& ": " & Err
.Description
168 Select Case aLine(0) ' command
173 WScript
.StdOut
.WriteLine oTTS
.MfgName(nMode
)
175 WScript
.StdOut
.WriteLine oSpVoice
.Voice
.GetAttribute("Vendor")
179 aData
= Split(aLine(1), vbTab
, 2)
180 aData(1) = UTF8decode(aData(1))
181 If bVerbose
Then WScript
.StdErr
.WriteLine
"Saying " & aData(1) _
184 oTTS
.FileName
= aData(0)
191 oSpFS
.Open
aData(0), SSFMCreateForWrite
, false
192 Set oSpVoice
.AudioOutputStream
= oSpFS
193 oSpVoice
.Speak
aData(1)
197 If bVerbose
Then WScript
.StdErr
.WriteLine
"> " & aLine(1)
198 oShell
.Run
aLine(1), 0, true
199 If Err
.Number
<> 0 Then
201 WScript
.StdErr
.Write
"> " & aLine(1) & ": "
203 If Err
.Number
= &H80070002
Then ' Actually file not found
204 WScript
.StdErr
.WriteLine
"command not found"
206 WScript
.StdErr
.WriteLine
"error " & Err
.Number
& ":" _
212 If bVerbose
Then WScript
.StdErr
.WriteLine
"Syncing"
213 WScript
.StdOut
.WriteLine
aLine(1) ' Just echo what was passed
215 If bVerbose
Then WScript
.StdErr
.WriteLine
"Quitting"
223 ' Decode an UTF-8 string into a standard windows unicode string (UTF-16)
224 Function UTF8decode(ByRef sText
)
225 Dim i
, c
, nCode
, nTail
, nTextLen
229 nTextLen
= Len(sText
)
232 c
= Asc(Mid(sText
, i
, 1))
234 If c
<= &h7F
Or c
>= &hC2
Then ' Start of new character
235 If c
< &h80
Then ' U-00000000 - U-0000007F, 1 byte
237 ElseIf c
< &hE0
Then ' U-00000080 - U-000007FF, 2 bytes
240 ElseIf c
< &hF0
Then ' U-00000800 - U-0000FFFF, 3 bytes
243 ElseIf c
< &hF5
Then ' U-00010000 - U-001FFFFF, 4 bytes
250 While nTail
> 0 And i
<= nTextLen
252 c
= Asc(Mid(sText
, i
, 1))
254 If (c
And &hC0
) = &h80
Then ' Valid continuation char
255 nCode
= nCode
* &h40
+ (c
And &h3F
)
256 Else ' Invalid continuation char
266 If nCode
>= &h10000
Then ' Character outside BMP - use surrogate pair
267 nCode
= nCode
- &h10000
268 c
= &hD800
+ ((nCode \
&h400
) And &h3FF
) ' high surrogate
269 UTF8decode
= UTF8decode
& ChrW(c
)
270 nCode
= &hDC00
+ (nCode
And &h3FF
) ' low surrogate
272 UTF8decode
= UTF8decode
& ChrW(nCode
)
276 ' SAPI5 output format selection based on engine
277 Function AudioFormat(ByRef sVendor
)
280 AudioFormat
= SPSF_22kHz16BitMono
282 AudioFormat
= SPSF_32kHz16BitMono
284 AudioFormat
= SPSF_16kHz16BitMono
286 AudioFormat
= SPSF_22kHz16BitMono
288 AudioFormat
= SPSF_16kHz16BitMono
290 AudioFormat
= SPSF_22kHz16BitMono
291 WScript
.StdOut
.WriteLine
"Warning - unknown vendor """ & sVendor _
292 & """ - using default wave format"
296 ' Language mapping rockbox->windows
297 Function LangIDs(ByRef sLanguage
)
300 Select Case sLanguage
302 LangIDs
= Array(&h436
)
304 LangIDs
= Array(&h402
)
306 LangIDs
= Array(&h403
)
308 LangIDs
= Array(&h804
) ' PRC
310 LangIDs
= Array(&h404
) ' Taiwan. Perhaps also Hong Kong, Singapore, Macau?
312 LangIDs
= Array(&h405
)
314 LangIDs
= Array(&h406
)
316 LangIDs
= Array(&h407
, &hc07
, &h1007
, &h1407
)
317 ' Standard, Austrian, Luxembourg, Liechtenstein (Swiss -> wallisertitsch)
319 LangIDs
= Array(&h425
)
321 LangIDs
= Array( &h809
, &h409
, &hc09
, &h1009
, &h1409
, &h1809
, _
322 &h1c09
, &h2009
, &h2409
, &h2809
, &h2c09
, &h3009
, _
324 ' British, American, Australian, Canadian, New Zealand, Ireland,
325 ' South Africa, Jamaika, Caribbean, Belize, Trinidad, Zimbabwe,
328 LangIDs
= Array( &h40a
, &hc0a
, &h80a
, &h100a
, &h140a
, &h180a
, _
329 &h1c0a
, &h200a
, &h240a
, &h280a
, &h2c0a
, &h300a
, _
330 &h340a
, &h380a
, &h3c0a
, &h400a
, &h440a
, &h480a
, _
332 ' trad. sort., mordern sort., Mexican, Guatemala, Costa Rica,
333 ' Panama, Dominican Republic, Venezuela, Colombia, Peru, Argentina,
334 ' Ecuador, Chile, Uruguay, Paraguay, Bolivia, El Salvador,
335 ' Honduras, Nicaragua, Puerto Rico
337 WScript
.StdErr
.WriteLine
"Error: no esperanto support in Windows"
340 LangIDs
= Array(&h40b
)
342 LangIDs
= Array(&h40c
, &h80c
, &hc0c
, &h100c
, &h140c
, &h180c
)
343 ' Standard, Belgian, Canadian, Swiss, Luxembourg, Monaco
345 LangIDs
= Array(&h456
)
347 LangIDs
= Array(&h408
)
349 LangIDs
= Array(&h40d
)
351 LangIDs
= Array(&h439
)
353 LangIDs
= Array(&h40f
)
355 LangIDs
= Array(&h410
, &h810
) ' Standard, Swiss
357 LangIDs
= Array(&h411
)
359 LangIDs
= Array(&h412
)
361 LangIDs
= Array(&h40e
)
363 LangIDs
= Array(&h413
, &h813
) ' Standard, Belgian
365 LangIDs
= Array(&h414
) ' Bokmal
367 LangIDs
= Array(&h814
)
369 LangIDs
= Array(&h415
)
371 LangIDs
= Array(&h816
)
372 Case "portugues-brasileiro"
373 LangIDs
= Array(&h416
)
375 LangIDs
= Array(&h418
)
377 LangIDs
= Array(&h419
)
379 LangIDs
= Array(&h424
)
381 LangIDs
= Array(&hc1a
) ' Cyrillic
383 LangIDs
= Array(&h41d
, &h81d
) ' Standard, Finland
385 LangIDs
= Array(&h464
) ' Filipino, might not be 100% correct
387 LangIDs
= Array(&h41e
)
389 LangIDs
= Array(&h41f
)
390 Case "wallisertitsch"
391 LangIDs
= Array(&h807
) ' Swiss German