fenrir/src/fenrirscreenreader/core/outputManager.py

195 lines
10 KiB
Python
Raw Normal View History

#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributors.
from fenrirscreenreader.core import debug
from fenrirscreenreader.utils import line_utils
import string, time, re
class outputManager():
def __init__(self):
self.lastEcho = ''
def initialize(self, environment):
self.env = environment
self.env['runtime']['settingsManager'].loadDriver(
self.env['runtime']['settingsManager'].getSetting('speech', 'driver'), 'speechDriver')
self.env['runtime']['settingsManager'].loadDriver(
self.env['runtime']['settingsManager'].getSetting('sound', 'driver'), 'soundDriver')
def shutdown(self):
self.env['runtime']['settingsManager'].shutdownDriver('soundDriver')
self.env['runtime']['settingsManager'].shutdownDriver('speechDriver')
def presentText(self, text, interrupt=True, soundIcon='', ignorePunctuation=False, announceCapital=False, flush=True):
if text == '':
return
if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'readNumbersAsDigits') and len(text.strip()) > 1:
2024-03-13 00:56:53 -04:00
text = re.sub(r"(\d)", r"\1 ", text).rstrip()
self.env['runtime']['debug'].writeDebugOut("presentText:\nsoundIcon:'"+soundIcon+"'\nText:\n" + text, debug.debugLevel.INFO)
if self.playSoundIcon(soundIcon, interrupt):
self.env['runtime']['debug'].writeDebugOut("soundIcon found", debug.debugLevel.INFO)
return
if (len(text) > 1) and (text.strip(string.whitespace) == ''):
return
toAnnounceCapital = announceCapital and text[0].isupper()
if toAnnounceCapital:
if self.playSoundIcon('capital', False):
2021-05-19 11:06:44 +02:00
toAnnounceCapital = False
self.lastEcho = text
self.speakText(text, interrupt, ignorePunctuation, toAnnounceCapital)
def getLastEcho(self):
return self.lastEcho
def speakText(self, text, interrupt=True, ignorePunctuation=False, announceCapital=False):
if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
self.env['runtime']['debug'].writeDebugOut("Speech disabled in outputManager.speakText", debug.debugLevel.INFO)
return
if self.env['runtime']['speechDriver'] == None:
self.env['runtime']['debug'].writeDebugOut("No speechDriver in outputManager.speakText", debug.debugLevel.ERROR)
return
if interrupt:
self.interruptOutput()
try:
self.env['runtime']['speechDriver'].setLanguage(self.env['runtime']['settingsManager'].getSetting('speech', 'language'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech language in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try:
self.env['runtime']['speechDriver'].setVoice(self.env['runtime']['settingsManager'].getSetting('speech', 'voice'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Error while setting speech voice in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try:
if announceCapital:
self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'capitalPitch'))
else:
self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech pitch in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try:
self.env['runtime']['speechDriver'].setRate(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech rate in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try:
self.env['runtime']['speechDriver'].setModule(self.env['runtime']['settingsManager'].getSetting('speech', 'module'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech module in outputManager.speakText", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
2021-05-19 11:06:44 +02:00
try:
self.env['runtime']['speechDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech volume in outputManager.speakText ", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
try:
2018-05-17 23:49:32 +02:00
if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'newLinePause'):
cleanText = text.replace('\n', ' , ')
2018-05-17 23:49:32 +02:00
else:
cleanText = text.replace('\n', ' ')
2018-05-17 23:49:32 +02:00
cleanText = self.env['runtime']['textManager'].replaceHeadLines(cleanText)
cleanText = self.env['runtime']['punctuationManager'].proceedPunctuation(cleanText, ignorePunctuation)
cleanText = re.sub(' +$', ' ', cleanText)
self.env['runtime']['speechDriver'].speak(cleanText)
self.env['runtime']['debug'].writeDebugOut("Speak: "+ cleanText, debug.debugLevel.INFO)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("\"speak\" in outputManager.speakText ", debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
def interruptOutput(self):
try:
self.env['runtime']['speechDriver'].cancel()
self.env['runtime']['debug'].writeDebugOut("Interrupt speech", debug.debugLevel.INFO)
except:
2021-05-19 11:06:44 +02:00
pass
def playSoundIcon(self, soundIcon='', interrupt=True):
if soundIcon == '':
return False
soundIcon = soundIcon.upper()
if not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'):
self.env['runtime']['debug'].writeDebugOut("Sound disabled in outputManager.playSoundIcon", debug.debugLevel.INFO)
return False
2019-02-18 10:09:17 +01:00
try:
e = self.env['soundIcons'][soundIcon]
except:
2021-05-19 11:06:44 +02:00
self.env['runtime']['debug'].writeDebugOut("SoundIcon doesnt exist: " + soundIcon, debug.debugLevel.WARNING)
return False
2019-02-18 10:09:17 +01:00
if self.env['runtime']['soundDriver'] == None:
self.env['runtime']['debug'].writeDebugOut("No soundDriver in outputManager.playSoundIcon: soundDriver not loaded", debug.debugLevel.ERROR)
2019-02-18 10:09:17 +01:00
return False
try:
self.env['runtime']['soundDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume'))
2019-02-18 10:09:17 +01:00
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::setVolume: " + str(e), debug.debugLevel.ERROR)
2019-02-18 10:09:17 +01:00
try:
self.env['runtime']['soundDriver'].playSoundFile(self.env['soundIcons'][soundIcon], interrupt)
return True
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::playSoundFile: " + str(e), debug.debugLevel.ERROR)
2019-02-18 10:09:17 +01:00
return False
return False
2021-05-19 11:06:44 +02:00
def playFrequence(self, frequence, duration, interrupt=True):
if not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'):
self.env['runtime']['debug'].writeDebugOut("Sound disabled in outputManager.playFrequence", debug.debugLevel.INFO)
2021-05-19 11:06:44 +02:00
return False
if frequence < 1 or frequence > 20000:
self.env['runtime']['debug'].writeDebugOut("outputManager.playFrequence::Filefrequence is out of range:" + str(frequence), debug.debugLevel.INFO)
2021-05-19 11:06:44 +02:00
return False
if self.env['runtime']['soundDriver'] == None:
self.env['runtime']['debug'].writeDebugOut("No soundDriver in outputManager.playFrequence: soundDriver not loaded", debug.debugLevel.ERROR)
2021-05-19 11:06:44 +02:00
return False
try:
self.env['runtime']['soundDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::setVolume: " + str(e), debug.debugLevel.ERROR)
2021-05-19 11:37:03 +02:00
adjustVolume = 0.0
try:
adjustVolume = 1.0 - (frequence / 20000)
except:
pass
if adjustVolume > 9.0:
adjustVolume = 9.0
2021-05-19 11:06:44 +02:00
try:
2021-05-19 11:37:03 +02:00
self.env['runtime']['soundDriver'].playFrequence(frequence, duration, adjustVolume, interrupt)
2021-05-19 11:06:44 +02:00
return True
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::playSoundFile: " + str(e), debug.debugLevel.ERROR)
2021-05-19 11:06:44 +02:00
return False
return False
def tempDisableSpeech(self):
if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
self.presentText(_("speech temporary disabled"), soundIcon='SpeechOff', interrupt=True)
self.env['commandBuffer']['enableSpeechOnKeypress'] = True
self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))
self.interruptOutput()
2021-05-19 11:06:44 +02:00
def announceActiveCursor(self, interrupt_p=False):
if self.env['runtime']['cursorManager'].isReviewMode():
2021-05-19 11:06:44 +02:00
self.presentText(' review cursor ', interrupt=interrupt_p)
else:
2021-05-19 11:06:44 +02:00
self.presentText(' text cursor ', interrupt=interrupt_p)