1 |
|
# Orca |
2 |
|
# |
3 |
|
# Copyright 2004-2006 Sun Microsystems Inc. |
4 |
|
# |
5 |
|
# This library is free software; you can redistribute it and/or |
6 |
|
# modify it under the terms of the GNU Library General Public |
7 |
|
# License as published by the Free Software Foundation; either |
8 |
|
# version 2 of the License, or (at your option) any later version. |
9 |
|
# |
10 |
|
# This library is distributed in the hope that it will be useful, |
11 |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
|
# Library General Public License for more details. |
14 |
|
# |
15 |
|
# You should have received a copy of the GNU Library General Public |
16 |
|
# License along with this library; if not, write to the |
17 |
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
|
# Boston, MA 02111-1307, USA. |
19 |
|
|
20 |
|
"""Manages the default speech server for orca. A script can use this |
21 |
1 |
as its speech server, or it can feel free to create one of its own.""" |
22 |
|
|
23 |
1 |
__id__ = "$Id: speech.py 1973 2007-02-02 23:22:35Z wwalker $" |
24 |
1 |
__version__ = "$Revision: 1973 $" |
25 |
1 |
__date__ = "$Date: 2007-02-02 15:22:35 -0800 (Fri, 02 Feb 2007) $" |
26 |
1 |
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc." |
27 |
1 |
__license__ = "LGPL" |
28 |
|
|
29 |
1 |
import logging |
30 |
1 |
log = logging.getLogger("speech") |
31 |
|
|
32 |
1 |
import time |
33 |
|
|
34 |
1 |
import debug |
35 |
1 |
import orca_state |
36 |
1 |
import platform |
37 |
1 |
import settings |
38 |
|
|
39 |
1 |
from acss import ACSS |
40 |
1 |
from orca_i18n import _ # for gettext support |
41 |
|
|
42 |
|
# The speech server to use for all speech operations. |
43 |
|
# |
44 |
1 |
_speechserver = None |
45 |
|
|
46 |
1 |
def getSpeechServerFactories(): |
47 |
|
"""Imports all known SpeechServer factory modules. Returns a list |
48 |
|
of modules that implement the getSpeechServers method, which |
49 |
|
returns a list of speechserver.SpeechServer instances. |
50 |
|
""" |
51 |
|
|
52 |
1 |
factories = [] |
53 |
|
|
54 |
1 |
moduleNames = settings.speechFactoryModules |
55 |
3 |
for moduleName in moduleNames: |
56 |
2 |
try: |
57 |
2 |
module = __import__(moduleName, |
58 |
2 |
globals(), |
59 |
2 |
locals(), |
60 |
2 |
['']) |
61 |
2 |
factories.append(module) |
62 |
0 |
except: |
63 |
0 |
debug.printException(debug.LEVEL_OFF) |
64 |
|
|
65 |
1 |
return factories |
66 |
|
|
67 |
1 |
def init(): |
68 |
|
|
69 |
0 |
global _speechserver |
70 |
|
|
71 |
2 |
if _speechserver: |
72 |
0 |
return |
73 |
|
|
74 |
|
# First, find the factory module to use. We will |
75 |
|
# allow the user to give their own factory module, |
76 |
|
# thus we look first in the global name space, and |
77 |
|
# then we look in the orca namespace. |
78 |
|
# |
79 |
2 |
moduleName = settings.speechServerFactory |
80 |
|
|
81 |
2 |
if moduleName: |
82 |
0 |
debug.println(debug.LEVEL_CONFIGURATION, |
83 |
0 |
"Using speech server factory: %s" % moduleName) |
84 |
|
else: |
85 |
2 |
debug.println(debug.LEVEL_CONFIGURATION, |
86 |
2 |
"Speech not available.") |
87 |
2 |
return |
88 |
|
|
89 |
0 |
factory = None |
90 |
0 |
try: |
91 |
0 |
factory = __import__(moduleName, |
92 |
0 |
globals(), |
93 |
0 |
locals(), |
94 |
0 |
['']) |
95 |
0 |
except: |
96 |
0 |
try: |
97 |
0 |
moduleName = moduleName.replace("orca.","",1) |
98 |
0 |
factory = __import__(moduleName, |
99 |
0 |
globals(), |
100 |
0 |
locals(), |
101 |
0 |
['']) |
102 |
0 |
except: |
103 |
0 |
debug.printException(debug.LEVEL_SEVERE) |
104 |
|
|
105 |
|
# Now, get the speech server we care about. |
106 |
|
# |
107 |
0 |
speechServerInfo = settings.speechServerInfo |
108 |
0 |
if speechServerInfo: |
109 |
0 |
_speechserver = factory.SpeechServer.getSpeechServer(speechServerInfo) |
110 |
|
else: |
111 |
0 |
_speechserver = factory.SpeechServer.getSpeechServer() |
112 |
|
|
113 |
1 |
def __resolveACSS(acss=None): |
114 |
0 |
if acss: |
115 |
0 |
return acss |
116 |
|
else: |
117 |
0 |
voices = settings.voices |
118 |
0 |
return voices[settings.DEFAULT_VOICE] |
119 |
|
|
120 |
1 |
def sayAll(utteranceIterator, progressCallback): |
121 |
0 |
if settings.silenceSpeech: |
122 |
0 |
return |
123 |
0 |
if _speechserver: |
124 |
0 |
_speechserver.sayAll(utteranceIterator, progressCallback) |
125 |
|
|
126 |
1 |
def speak(text, acss=None, interrupt=True): |
127 |
|
"""Speaks all queued text immediately. If text is not None, |
128 |
|
it is added to the queue before speaking. |
129 |
|
|
130 |
|
Arguments: |
131 |
|
- text: optional text to add to the queue before speaking |
132 |
|
- acss: acss.ACSS instance; if None, |
133 |
|
the default voice settings will be used. |
134 |
|
Otherwise, the acss settings will be |
135 |
|
used to augment/override the default |
136 |
|
voice settings. |
137 |
|
- interrupt: if True, stops any speech in progress before |
138 |
|
speaking the text |
139 |
|
""" |
140 |
|
|
141 |
|
# We will not interrupt a key echo in progress. |
142 |
|
# |
143 |
143 |
if orca_state.lastKeyEchoTime: |
144 |
0 |
interrupt = interrupt \ |
145 |
|
and ((time.time() - orca_state.lastKeyEchoTime) > 0.5) |
146 |
|
|
147 |
143 |
if settings.silenceSpeech: |
148 |
0 |
return |
149 |
|
|
150 |
143 |
debug.println(debug.LEVEL_INFO, "SPEECH OUTPUT: '" + text + "'") |
151 |
143 |
log.info("'%s'" % text) |
152 |
|
|
153 |
143 |
if _speechserver: |
154 |
0 |
_speechserver.speak(text, __resolveACSS(acss), interrupt) |
155 |
|
|
156 |
1 |
def isSpeaking(): |
157 |
|
""""Returns True if the system is currently speaking.""" |
158 |
0 |
if _speechserver: |
159 |
0 |
return _speechserver.isSpeaking() |
160 |
|
else: |
161 |
0 |
return False |
162 |
|
|
163 |
1 |
def speakUtterances(utterances, acss=None, interrupt=True): |
164 |
|
"""Speaks the given list of utterances immediately. |
165 |
|
|
166 |
|
Arguments: |
167 |
|
- list: list of strings to be spoken |
168 |
|
- acss: acss.ACSS instance; if None, |
169 |
|
the default voice settings will be used. |
170 |
|
Otherwise, the acss settings will be |
171 |
|
used to augment/override the default |
172 |
|
voice settings. |
173 |
|
- interrupt: if True, stop any speech currently in progress. |
174 |
|
""" |
175 |
|
|
176 |
|
# We will not interrupt a key echo in progress. |
177 |
|
# |
178 |
799 |
if orca_state.lastKeyEchoTime: |
179 |
0 |
interrupt = interrupt \ |
180 |
|
and ((time.time() - orca_state.lastKeyEchoTime) > 0.5) |
181 |
|
|
182 |
799 |
if settings.silenceSpeech: |
183 |
0 |
return |
184 |
|
|
185 |
2399 |
for utterance in utterances: |
186 |
1600 |
debug.println(debug.LEVEL_INFO, |
187 |
1600 |
"SPEECH OUTPUT: '" + utterance + "'") |
188 |
1600 |
log.info("'%s'" % utterance) |
189 |
|
|
190 |
799 |
if _speechserver: |
191 |
0 |
_speechserver.speakUtterances(utterances, |
192 |
0 |
__resolveACSS(acss), |
193 |
0 |
interrupt) |
194 |
|
|
195 |
1 |
def stop(): |
196 |
1683 |
if _speechserver: |
197 |
0 |
_speechserver.stop() |
198 |
|
|
199 |
1 |
def increaseSpeechRate(script=None, inputEvent=None): |
200 |
10 |
if _speechserver: |
201 |
0 |
_speechserver.increaseSpeechRate() |
202 |
10 |
return True |
203 |
|
|
204 |
1 |
def decreaseSpeechRate(script=None, inputEvent=None): |
205 |
10 |
if _speechserver: |
206 |
0 |
_speechserver.decreaseSpeechRate() |
207 |
10 |
return True |
208 |
|
|
209 |
1 |
def increaseSpeechPitch(script=None, inputEvent=None): |
210 |
12 |
if _speechserver: |
211 |
0 |
_speechserver.increaseSpeechPitch() |
212 |
12 |
return True |
213 |
|
|
214 |
1 |
def decreaseSpeechPitch(script=None, inputEvent=None): |
215 |
18 |
if _speechserver: |
216 |
0 |
_speechserver.decreaseSpeechPitch() |
217 |
18 |
return True |
218 |
|
|
219 |
1 |
def shutdown(): |
220 |
0 |
global _speechserver |
221 |
2 |
if _speechserver: |
222 |
0 |
_speechserver.shutdownActiveServers() |
223 |
0 |
_speechserver = None |
224 |
|
|
225 |
1 |
def reset(text=None, acss=None): |
226 |
0 |
global _speechserver |
227 |
0 |
if _speechserver: |
228 |
0 |
_speechserver.reset(text, acss) |
229 |
|
|
230 |
1 |
def testNoSettingsInit(): |
231 |
0 |
init() |
232 |
0 |
speak("testing") |
233 |
0 |
speak("this is higher", ACSS({'average-pitch' : 7})) |
234 |
0 |
speak("this is slower", ACSS({'rate' : 3})) |
235 |
0 |
speak("this is faster", ACSS({'rate' : 80})) |
236 |
0 |
speak("this is quiet", ACSS({'gain' : 2})) |
237 |
0 |
speak("this is loud", ACSS({'gain' : 10})) |
238 |
0 |
speak("this is normal") |
239 |
|
|
240 |
1 |
def test(): |
241 |
0 |
import speechserver |
242 |
0 |
factories = getSpeechServerFactories() |
243 |
0 |
for factory in factories: |
244 |
0 |
print factory.__name__ |
245 |
0 |
servers = factory.SpeechServer.getSpeechServers() |
246 |
0 |
for server in servers: |
247 |
0 |
try: |
248 |
0 |
print " ", server.getInfo() |
249 |
0 |
for family in server.getVoiceFamilies(): |
250 |
0 |
name = family[speechserver.VoiceFamily.NAME] |
251 |
0 |
print " ", name |
252 |
0 |
acss = ACSS({ACSS.FAMILY : family}) |
253 |
0 |
server.speak(name, acss) |
254 |
0 |
server.speak("testing") |
255 |
0 |
server.shutdown() |
256 |
0 |
except: |
257 |
0 |
debug.printException(debug.LEVEL_OFF) |
258 |
0 |
pass |