Speculative fix for a sometimes speech crash bug.
This commit is contained in:
@@ -22,6 +22,8 @@ class OutputManager:
|
||||
self.interrupt_thread = None
|
||||
self.interrupt_done = None
|
||||
self.interrupt_wait_timeout = 0.1
|
||||
self.speech_driver_lock = threading.Lock()
|
||||
self.speech_driver_lock_timeout = 0.05
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
@@ -159,132 +161,144 @@ class OutputManager:
|
||||
return
|
||||
if interrupt or flush:
|
||||
self.interrupt_output()
|
||||
if not self.speech_driver_lock.acquire(
|
||||
timeout=self.speech_driver_lock_timeout
|
||||
):
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"OutputManager.speak_text: Speech driver busy, dropping speech",
|
||||
debug.DebugLevel.WARNING,
|
||||
)
|
||||
return
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_language(
|
||||
self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"speech", "language"
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_language(
|
||||
self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"speech", "language"
|
||||
)
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech language in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_voice(
|
||||
self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"speech", "voice"
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech language in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"Error while setting speech voice in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
if announce_capital:
|
||||
self.env["runtime"]["SpeechDriver"].set_pitch(
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_voice(
|
||||
self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"speech", "voice"
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"Error while setting speech voice in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
if announce_capital:
|
||||
self.env["runtime"]["SpeechDriver"].set_pitch(
|
||||
self.env["runtime"][
|
||||
"SettingsManager"
|
||||
].get_setting_as_float("speech", "capital_pitch")
|
||||
)
|
||||
else:
|
||||
self.env["runtime"]["SpeechDriver"].set_pitch(
|
||||
self.env["runtime"][
|
||||
"SettingsManager"
|
||||
].get_setting_as_float("speech", "pitch")
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech pitch in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_rate(
|
||||
self.env["runtime"][
|
||||
"SettingsManager"
|
||||
].get_setting_as_float("speech", "capital_pitch")
|
||||
].get_setting_as_float("speech", "rate")
|
||||
)
|
||||
else:
|
||||
self.env["runtime"]["SpeechDriver"].set_pitch(
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech rate in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_module(
|
||||
self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"speech", "module"
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech module in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_volume(
|
||||
self.env["runtime"][
|
||||
"SettingsManager"
|
||||
].get_setting_as_float("speech", "pitch")
|
||||
].get_setting_as_float("speech", "volume")
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech pitch in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_rate(
|
||||
self.env["runtime"]["SettingsManager"].get_setting_as_float(
|
||||
"speech", "rate"
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech volume in OutputManager.speak_text ",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech rate in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_module(
|
||||
self.env["runtime"]["SettingsManager"].get_setting(
|
||||
"speech", "module"
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech module in OutputManager.speak_text",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].set_volume(
|
||||
self.env["runtime"]["SettingsManager"].get_setting_as_float(
|
||||
"speech", "volume"
|
||||
try:
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
||||
"general", "new_line_pause"
|
||||
):
|
||||
clean_text = text.replace("\n", " , ")
|
||||
else:
|
||||
clean_text = text.replace("\n", " ")
|
||||
|
||||
clean_text = self.env["runtime"][
|
||||
"TextManager"
|
||||
].replace_head_lines(clean_text)
|
||||
clean_text = self.process_mid_word_punctuation(clean_text)
|
||||
clean_text = self.env["runtime"][
|
||||
"PunctuationManager"
|
||||
].proceed_punctuation(clean_text, ignore_punctuation)
|
||||
clean_text = re.sub(" +$", " ", clean_text)
|
||||
self.env["runtime"]["SpeechDriver"].speak(
|
||||
clean_text, True, ignore_punctuation
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"setting speech volume in OutputManager.speak_text ",
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
|
||||
try:
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
||||
"general", "new_line_pause"
|
||||
):
|
||||
clean_text = text.replace("\n", " , ")
|
||||
else:
|
||||
clean_text = text.replace("\n", " ")
|
||||
|
||||
clean_text = self.env["runtime"]["TextManager"].replace_head_lines(
|
||||
clean_text
|
||||
)
|
||||
clean_text = self.process_mid_word_punctuation(clean_text)
|
||||
clean_text = self.env["runtime"][
|
||||
"PunctuationManager"
|
||||
].proceed_punctuation(clean_text, ignore_punctuation)
|
||||
clean_text = re.sub(" +$", " ", clean_text)
|
||||
self.env["runtime"]["SpeechDriver"].speak(
|
||||
clean_text, True, ignore_punctuation
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"Speak: " + clean_text, debug.DebugLevel.INFO
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
'"speak" in OutputManager.speak_text ', debug.DebugLevel.ERROR
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"Speak: " + clean_text, debug.DebugLevel.INFO
|
||||
)
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
'"speak" in OutputManager.speak_text ',
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
str(e), debug.DebugLevel.ERROR
|
||||
)
|
||||
finally:
|
||||
self.speech_driver_lock.release()
|
||||
|
||||
def interrupt_output(self, wait=True):
|
||||
interrupt_done, started = self.start_interrupt_output()
|
||||
@@ -320,6 +334,15 @@ class OutputManager:
|
||||
self.interrupt_running = False
|
||||
|
||||
def cancel_speech(self):
|
||||
if not self.speech_driver_lock.acquire(
|
||||
timeout=self.speech_driver_lock_timeout
|
||||
):
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"OutputManager interrupt_output: Speech driver busy, "
|
||||
"skipping interrupt",
|
||||
debug.DebugLevel.WARNING,
|
||||
)
|
||||
return
|
||||
try:
|
||||
self.env["runtime"]["SpeechDriver"].cancel()
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
@@ -331,6 +354,8 @@ class OutputManager:
|
||||
+ str(e),
|
||||
debug.DebugLevel.ERROR,
|
||||
)
|
||||
finally:
|
||||
self.speech_driver_lock.release()
|
||||
|
||||
def play_sound_icon(self, sound_icon="", interrupt=True):
|
||||
if sound_icon == "":
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
version = "2026.05.18"
|
||||
version = "2026.05.19"
|
||||
code_name = "testing"
|
||||
|
||||
Reference in New Issue
Block a user