47
46
speaker_attenuation = 1.0
55
###########################################
57
def is_speaking_func():
60
############################################
61
# based on _espeak.py (nvda)
69
class BgThread(threading.Thread):
71
threading.Thread.__init__(self)
77
func, args, kwargs = bgQueue.get()
83
log.error("Error running function from queue", exc_info=True)
86
def _execWhenDone(func, *args, **kwargs):
88
# This can't be a kwarg in the function definition because it will consume the first non-keywor dargument which is meant for func.
89
mustBeAsync = kwargs.pop("mustBeAsync", False)
90
if mustBeAsync or bgQueue.unfinished_tasks != 0:
91
# Either this operation must be asynchronous or There is still an operation in progress.
92
# Therefore, run this asynchronously in the background thread.
93
bgQueue.put((func, args, kwargs))
98
buff = ctypes.create_string_buffer(MSGLEN)
56
return _bgthread.isSpeaking
59
_bgthread.isSpeaking = b
100
61
# call from BgThread
101
62
def _speak(msg, index=None):
102
63
global currIndex, buff
106
66
msg = _nvdajp_predic.convert(msg)
107
67
if DEBUG_INFO: logwrite("_speak(%s)" % msg)
109
69
if DEBUG_INFO: lw = logwrite
110
70
for m in string.split(msg):
113
if DEBUG_INFO: logwrite("processing (%s)" % m)
114
text = m.encode(_jtalk_core.CODE, 'ignore')
115
_jtalk_core.Mecab_text2mecab(buff, text); str = buff.value
116
if DEBUG_INFO: logwrite("libjt_text2mecab done")
117
if not isSpeaking: _jtalk_core.libjt_refresh(); return
118
mf = _jtalk_core.MecabFeatures()
119
_jtalk_core.Mecab_analysis(str, mf)
120
if DEBUG_INFO: logwrite("Mecab_analysis done")
121
if not isSpeaking: _jtalk_core.libjt_refresh(); return
122
_jtalk_core.libjt_synthesis(mf.feature, mf.size,
124
feed_func_ = player.feed, # player.feed() is called inside
125
is_speaking_func_ = is_speaking_func,
126
thres_ = thres_level,
127
thres2_ = thres2_level,
128
level_ = int(max_level * speaker_attenuation),
130
lf0_offset_ = lf0_offset,
133
if DEBUG_INFO: logwrite("libjt_synthesis done")
134
_jtalk_core.libjt_refresh()
136
if DEBUG_INFO: logwrite("WindowsError")
71
if len(m) == 0: continue
73
if DEBUG_INFO: logwrite("processing (%s)" % m)
74
text = m.encode(_jtalk_core.CODE, 'ignore')
75
_jtalk_core.Mecab_text2mecab(buff, text); str = buff.value
76
if DEBUG_INFO: logwrite("libjt_text2mecab done")
77
if not isSpeaking(): _jtalk_core.libjt_refresh(); return
78
mf = _jtalk_core.MecabFeatures()
79
_jtalk_core.Mecab_analysis(str, mf)
80
if DEBUG_INFO: logwrite("Mecab_analysis done")
81
if not isSpeaking(): _jtalk_core.libjt_refresh(); return
82
_jtalk_core.libjt_synthesis(mf.feature, mf.size,
84
feed_func_ = player.feed, # player.feed() is called inside
85
is_speaking_func_ = isSpeaking,
87
thres2_ = thres2_level,
88
level_ = int(max_level * speaker_attenuation),
90
lf0_offset_ = lf0_offset,
93
if DEBUG_INFO: logwrite("libjt_synthesis done")
94
_jtalk_core.libjt_refresh()
96
if DEBUG_INFO: logwrite("WindowsError")
138
98
lastIndex = currIndex
142
102
def speak(msg, index=None):
143
103
msg = msg.rstrip()
144
104
if msg == '': return
145
105
if msg == u'ー': msg = u'チョーオン'
146
106
if msg == u'ン': msg = u'ウン'
147
_execWhenDone(_speak, msg, index, mustBeAsync=True)
107
_bgthread.execWhenDone(_speak, msg, index, mustBeAsync=True)
150
global isSpeaking, bgQueue
151
110
# Kill all speech from now.
152
111
# We still want parameter changes to occur, so requeue them.
154
113
stop_task_count = 0 # for log.info()
157
item = bgQueue.get_nowait() # [func, args, kwargs]
116
item = _bgthread.bgQueue.get_nowait() # [func, args, kwargs]
158
117
if item[0] != _speak:
159
118
params.append(item)
161
120
stop_task_count = stop_task_count + 1
121
_bgthread.bgQueue.task_done()
163
122
except Queue.Empty:
164
123
# Let the exception break us out of this loop, as queue.empty() is not reliable anyway.
166
125
for item in params:
126
_bgthread.bgQueue.put(item)
169
128
if DEBUG_INFO: logwrite("stop: %d task(s) stopping" % stop_task_count)