-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspeak.py
executable file
·160 lines (134 loc) · 5.91 KB
/
speak.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/python3
#
# speak.py Speaker utilities
# includes protection from quotes and apostrophes in phrase
# removes asterisks
# observes quietTime from 11PM until 10AM
#
# includes optional vol parameter (range 10-500 useful)
# includes optional ignore (quietTime) parameter
# Aug2024: Changed to use piper-tts
# Oct2019: increased volume for MonkMakes Amplified Speaker
# reduced speed to 150wpm (default was 175)
# switched to espeak-ng (supported, better quality)
# say( phrase, vol=125, anytime=False)
# whisper( phrase, vol= 50, anytime=True)
# shout( phrase, vol=250, anytime=False)
# To Use in Bash Files with Parameters
# ~/GoPi5Go/plib/speak.py "Hello ${1} testing" 200
# ~/GoPi5Go/plib/speak.py "Hello ${1} testing" 100 True
import subprocess
import sys
sys.path.append('/home/pi/GoPi5Go/plib')
# import runLog
import time
debug = False
import math
import logging
import os
# create logger
logger = logging.getLogger('speakLog')
logger.setLevel(logging.INFO)
loghandler = logging.FileHandler('/home/pi/GoPi5Go/logs/speak.log')
logformatter = logging.Formatter('%(asctime)s|%(message)s',"%Y-%m-%d %H:%M")
loghandler.setFormatter(logformatter)
logger.addHandler(loghandler)
# QUIET TIME is before 10AM and after 11PM
# (unless told to ignore , then never quietTime
def quietTime(startOK=10,notOK=23,ignore=False):
timeNow = time.localtime()
if debug:
print("time.localtime().tm_hour():",timeNow.tm_hour)
print("startOK: {} notOK: {}".format(startOK, notOK))
if (ignore):
return False
elif (startOK <= timeNow.tm_hour < notOK):
return False
else:
return True
# Speak a phrase using espeak
# Options: vol: 10 is whisper, 50 is "normal Dave", 200 is shouting, 500 is screaming
# anytime: True means ignore quietTime check
def say_espeak(phrase,vol=100,anytime=False):
phrase = phrase.replace("I'm","I m")
phrase = phrase.replace("'","")
phrase = phrase.replace('"',' quote ')
phrase = phrase.replace('*',"")
# subprocess.check_output(['espeak -ven+f3 -s200 "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
spoken = ""
if (quietTime(ignore=anytime)):
print("QuietTime speak request: {} at vol: {}".format(phrase,vol))
spoken = " - quiet time"
else:
# subprocess.check_output(['espeak -ven-us+f5 -a'+str(vol)+' "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
# subprocess.check_output(['espeak-ng -s150 -ven-us+f5 -a'+str(vol)+' "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
subprocess.check_output(['espeak-ng -a'+str(vol)+' "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
logger.info(phrase+spoken)
def say_piper(phrase,vol=75,anytime=False):
phrase = phrase.replace("I'm","I m")
phrase = phrase.replace("'","")
phrase = phrase.replace('"',' quote ')
phrase = phrase.replace('*',"")
# subprocess.check_output(['espeak -ven+f3 -s200 "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
spoken = ""
if (quietTime(ignore=anytime)):
print("QuietTime speak request: {} at vol: {}".format(phrase,vol))
spoken = " - quiet time"
else:
# subprocess.check_output(['espeak -ven-us+f5 -a'+str(vol)+' "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
# subprocess.check_output(['espeak-ng -s150 -ven-us+f5 -a'+str(vol)+' "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
# subprocess.check_output(['espeak-ng -a'+str(vol)+' "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
# subprocess.check_output(['echo "%s" | piper --model /home/pi/GoPi5Go/models/piper-tts/en_US-arctic-medium.onnx --output_raw | aplay -D plughw:2,0 -r 22050 -f S16_LE -t raw -' % phrase], stderr=subprocess.STDOUT, shell=True)
# subprocess.check_output(['./piper.sh "%s"' % phrase], stderr=subprocess.STDOUT, shell=True)
cmd = "amixer -D pulse set Master {:d}%".format(int(vol))
# print("cmd:",cmd)
# subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
os.system(cmd)
cmd = '~/GoPi5Go/plib/piper.sh "%s"' % phrase
# subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
os.system(cmd)
# reset mixer to whisper level
# cmd = "amixer -D pulse set Master {:d}%".format(40)
# subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
logger.info(phrase+spoken)
def say(phrase,vol=75,anytime=False):
# say_espeak(phrase,vol,anytime)
# vol = 50 for HP amplified spkr
# vol = vol + 40 # adjust for flite
# say_flite(phrase,vol,anytime)
say_piper(phrase,vol,anytime)
def shout(phrase,vol=100,anytime=False):
# say_espeak(phrase,vol,anytime)
# vol = vol - 50 # adjust for flite
# say_flite(phrase,vol,anytime)
say_piper(phrase,vol,anytime)
def whisper(phrase,vol=45,anytime=False):
# say_espeak(phrase,vol,anytime)
# vol = vol + 30 # adjust for flite
# say_flite(phrase,vol,anytime=False)
say_piper(phrase,vol,anytime)
# ##### MAIN ####
# @runLog.logRun
def main():
# global debug
# logger.info("Starting speak.py test main")
if (len(sys.argv) >1):
strToSay = sys.argv[1]
if ( len(sys.argv)>2 ):
vol=int(sys.argv[2])
else:
vol=80
if ( len(sys.argv)>3 ):
ignore= ( sys.argv[3] == "True" )
else:
ignore=False
say(strToSay,vol,ignore)
else:
debug = True
say("Just saying. This phrase contained an apostrophe which isn't allowed")
whisper('I need to whisper. This phrase contains "a quoted word" ')
shout("I feel like shouting. My name is Go Pi 5 Go Dave. ")
# whisper("Whisper at 20. I don't know Pogo. Never met the little bot",20,True)
whisper("Whisper at 30. I don't know Pogo. Never met the little bot",30,True)
if __name__ == "__main__":
main()