-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
151 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
from talon import Context, actions, settings | ||
import os, subprocess | ||
|
||
ctxLinux = Context() | ||
ctxLinux.matches = r""" | ||
os: linux | ||
""" | ||
|
||
from typing import Literal | ||
speaker: Literal["espeak", "piper"] = "espeak" | ||
|
||
|
||
@ctxLinux.action_class('user') | ||
class UserActions: | ||
|
||
def toggle_reader(): | ||
"""Toggles the screen reader on and off""" | ||
actions.user.toggle_orca() | ||
|
||
def switch_voice(): | ||
"""Switches the tts voice""" | ||
global speaker | ||
if speaker == "espeak": | ||
speaker = "piper" | ||
actions.user.tts("Switched to piper") | ||
else: | ||
speaker = "espeak" | ||
actions.user.tts("Switched to espeak") | ||
|
||
def tts(text: str): | ||
"""Text to speech with a robotic/narrator voice""" | ||
match speaker: | ||
case "espeak": | ||
actions.user.espeak(text) | ||
case "piper": | ||
actions.user.piper(text) | ||
case _: | ||
raise ValueError(f"Unknown speaker {speaker}") | ||
|
||
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 | ||
rate = rate * 10 | ||
# text = remove_special(text) | ||
|
||
proc = subprocess.Popen(["spd-say", text, "--rate", str(rate)]) | ||
actions.user.set_cancel_callback(proc.kill) | ||
|
||
|
||
def piper(text: str): | ||
"""Text to speech with a robotic/narrator voice""" | ||
# change the directory to the directory of this file | ||
# so we can run the command from the correct directory | ||
model_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "additional_voices", "models") | ||
# You have to install piper with pipx | ||
piper = os.path.expanduser("~/.local/bin/piper") | ||
|
||
os.chdir(model_dir) | ||
|
||
modes = ['en_US-amy-low.onnx', 'en_US-lessac-medium.onnx'] | ||
# high = 22050 | ||
# Hz for playback in low quality | ||
low = 16000 | ||
|
||
# we need this more verbose representation here so we don't use the | ||
# shell and have risks of shell expansion | ||
command1 = ["echo", f"{text}"] | ||
|
||
command2 = [piper, "--model", modes[0], "--length_scale", "0.5", "--output_raw"] | ||
|
||
command3 = ["aplay", "-r", str(low), "-c", "1", "-f", "S16_LE", "-t", "raw"] | ||
|
||
echo = subprocess.Popen(command1, stdout=subprocess.PIPE) | ||
piper = subprocess.Popen(command2, stdin=echo.stdout, stdout=subprocess.PIPE) | ||
echo.stdout.close() | ||
aplay = subprocess.Popen(command3, stdin=piper.stdout) | ||
piper.stdout.close() | ||
actions.user.set_cancel_callback(aplay.kill) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from talon import Context, actions | ||
import subprocess | ||
|
||
ctxMac = Context() | ||
ctxMac.matches = r""" | ||
os: mac | ||
""" | ||
|
||
@ctxMac.action_class('user') | ||
class UserActions: | ||
def tts(text: str): | ||
"""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 | ||
proc = subprocess.Popen(["say", text]) | ||
actions.user.set_cancel_callback(proc.kill) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from talon import Context, settings | ||
import os | ||
|
||
from .sapi import SAPI5 | ||
|
||
if os.name == 'nt': | ||
speaker = SAPI5() | ||
|
||
|
||
ctxWindows = Context() | ||
ctxWindows.matches = r""" | ||
os: windows | ||
""" | ||
|
||
@ctxWindows.action_class('user') | ||
class UserActions: | ||
def base_win_tts(text: str): | ||
"""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) | ||
|
||
def tts(text: str): | ||
"""text to speech with windows voice""" | ||
actions.user.base_win_tts(text) | ||
|
||
def toggle_reader(): | ||
"""Toggles the screen reader on and off""" | ||
actions.user.toggle_nvda() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters