Skip to content

Commit

Permalink
interrupts for no echo
Browse files Browse the repository at this point in the history
  • Loading branch information
C-Loftus committed Feb 7, 2024
1 parent 0ddbc9d commit c2e8356
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 21 deletions.
6 changes: 2 additions & 4 deletions core/core-agnostic.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def initialize_settings():
# initialize the settings only after the user settings have been loaded
app.register('ready', initialize_settings)


speaker_cancel_callback: Optional[callable] = None

@mod.action_class
Expand Down Expand Up @@ -117,7 +116,7 @@ def toggle_echo_all():
ctx.settings["user.echo_context"] = True


def tts(text: str):
def tts(text: str, interrupt:bool = True):
'''text to speech with robot voice'''
raise NotImplementedError("Sight-Free-Talon Error: TTS not implemented in this context")

Expand All @@ -129,7 +128,7 @@ def toggle_reader():
"""Toggles the screen reader on and off"""
actions.user.tts("Toggle Reader Not Supported In This Context")

def base_win_tts(text: str):
def base_win_tts(text: str, interrupt: bool):
"""Base function for windows tts. We expose this
so we can share the speaker object across files since
it won't get overridden by the other tts functions"""
Expand All @@ -138,6 +137,5 @@ def switch_voice():
"""Switches the tts voice"""
actions.user.tts("Switching Not Supported In This Context")


def piper(text: str):
"""Text to speech with a piper model"""
7 changes: 5 additions & 2 deletions core/core-linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ def switch_voice():
speaker = "espeak"
actions.user.tts("Switched to espeak")

def tts(text: str):
def tts(text: str, interrupt:bool =True):
"""Text to speech with a robotic/narrator voice"""
if interrupt:
actions.user.cancel_current_speaker()

match speaker:
case "espeak":
actions.user.espeak(text)
Expand All @@ -40,7 +43,7 @@ def tts(text: str):
def espeak(text: str):
"""Text to speech with a robotic/narrator voice"""
rate = settings.get("user.tts_speed", 0)
# convert -5 to 5 to -100 to 100
# convert -10 to 10 to -100 to 100
rate = rate * 10
# text = remove_special(text)

Expand Down
11 changes: 9 additions & 2 deletions core/core-mac.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from talon import Context, actions
from talon import Context, actions, settings
import subprocess

ctxMac = Context()
Expand All @@ -8,10 +8,17 @@

@ctxMac.action_class('user')
class UserActions:
def tts(text: str):
def tts(text: str, interrupt:bool =True):
"""Text to speech with a robotic/narrator voice"""
# We can't really schedule this since it is a system command, so we
# have to spawn a new process each time unfortunately
if interrupt:
actions.user.cancel_current_speaker()

speed = settings.get("user.tts_speed")
# TODO: our speed is from -10 to 10 for espeak but needs
# to be converted into words per min for say.

proc = subprocess.Popen(["say", text])
actions.user.set_cancel_callback(proc.kill)

Expand Down
9 changes: 5 additions & 4 deletions core/core-windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@

@ctxWindows.action_class('user')
class UserActions:
def base_win_tts(text: str):
def base_win_tts(text: str, interrupt: bool):
"""Base function for windows tts. We expose this
so we can share the speaker object across files. We don't want
it to get overridden by the other tts functions"""
speaker.set_rate(settings.get("user.tts_speed", 0))
speaker.set_volume(settings.get("user.tts_volume", 50))
speaker.speak(text, interrupt=True)
speaker.speak(text, interrupt)

def tts(text: str):
def tts(text: str, interrupt:bool =True):
"""text to speech with windows voice"""
actions.user.base_win_tts(text)
# Base interrupt to the base
actions.user.base_win_tts(text, interrupt)

def toggle_reader():
"""Toggles the screen reader on and off"""
Expand Down
2 changes: 1 addition & 1 deletion docs/src/abilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ This repository works best with NVDA and Windows. Since Talon always has the cha

Some sighted users may simply want to reduce eye strain without needing to use a screen reader. This repository is designed to help in this situation, and make it easier to transition one's workflow to use the eyes less. In this scenario, I recommend simply using the default setting configuration and using many of the built in TTS tools, such as the Read Aloud functionality in Microsoft Edge to reduce the amount one needs to read.

I recommend using the screen curtain feature in NVDA to entirely turn off the screen when you do not need it. This eliminates all light, both blue light and other colors, but still lets you use your computer and listen to audio output.
I recommend using the screen curtain feature in NVDA to entirely turn off the screen when you do not need it. This eliminates all light and thus eyestrain or sensory effects, but still lets you use your computer and listen to audio output.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def handle_client(self, client_socket: socket.socket):
result += handle_command(message)

response = f"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nMessage received: Result: {result}".encode() # Create a HTTP response
client_socket.send(response)
client_socket.sendall(response)

def output_spec_file(self):
# write a json file to let clients know how to connect and what commands are available
Expand Down Expand Up @@ -106,7 +106,7 @@ def create_server(self):
except Exception as e:
print(f"Error handling message from client: {e}")
finally:
client_socket.close()
client_socket.close()

class GlobalPlugin(globalPluginHandler.GlobalPlugin):

Expand Down
20 changes: 15 additions & 5 deletions nvda/nvda.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def set_nvda_running_tag():
# Load the NVDA client library
dir_path = os.path.dirname(os.path.realpath(__file__))
dll_path = os.path.join(dir_path, "nvdaControllerClient64.dll")
nvda_client: ctypes.WinDLL = ctypes.windll.LoadLibrary(dll_path)
nvda_client: ctypes.WinDLL = ctypes.windll.LoadLibrary(dll_path)

cron.interval("3s", set_nvda_running_tag.update)
else:
Expand Down Expand Up @@ -68,12 +68,21 @@ def is_nvda_running() -> bool:

NVDA_RUNNING_CONSTANT = 0
client_response = nvda_client.nvdaController_testIfRunning()

if client_response == NVDA_RUNNING_CONSTANT:
return True
else:
if settings.get("user.addon_debug"):
print(f"NVDA not running. Client response value: {client_response}")
print(f"NVDA not running. Client response value: {client_response}")
# if client_response == 1717:
# # reload the dll if there is an error
# print("Reloading NVDA dll")
# ctypes.windll.kernel32.FreeLibrary(nvda_client._handle)
# nvda_client: ctypes.WinDLL = ctypes.windll.LoadLibrary(dll_path)
# return nvda_client.nvdaController_testIfRunning()
# else:
return False


def nvda_tts(text: str, use_clipboard: bool= False):
'''text to speech with NVDA'''
Expand Down Expand Up @@ -110,12 +119,13 @@ def nvda_tts(text: str, use_clipboard: bool= False):
else:
nvda_client.nvdaController_speakText(text)

def tts(text: str):
"""Text to speech"""
def tts(text: str, interrupt:bool =True):
"""Text to speech within NVDA"""
if settings.get("user.tts_via_screenreader"):
# we ignore interrupt since that is done by NVDA
actions.user.nvda_tts(text)
else:
actions.user.base_win_tts(text)
actions.user.base_win_tts(text, interrupt)


def cancel_current_speaker():
Expand Down
9 changes: 8 additions & 1 deletion sight-free-global.talon
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@
toggle echo:
user.toggle_echo()

# Echo and interrupt the current speaker
echo this:
key(ctrl-c)
sleep(0.1)
user.tts(clip.text())

echo no interrupt:
key(ctrl-c)
sleep(0.1)
interrupt = false
user.tts(clip.text(), interrupt)

echo clipboard:
user.tts(clip.text())

Expand Down Expand Up @@ -42,7 +49,7 @@ toggle [screen] reader:
toggle (key | keypress) sound:
user.toggle_keypress_sound()

(swtich | change) voice:
(switch | change) voice:
user.switch_voice()

toggle braille:
Expand Down

0 comments on commit c2e8356

Please sign in to comment.