-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
149 lines (127 loc) · 4.69 KB
/
main.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
import wiringpi
import pyaudio
import wave
import audioop
from collections import deque
import os
import time
import math
from google.cloud import speech
client = speech.Client()
LANG_CODE = 'en-US' # Language to use
CHUNK = 1024 # CHUNKS of bytes to read each time from mic
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
THRESHOLD = 1500 # The threshold intensity that defines silence
SILENCE_LIMIT = 2 # Silence limit in seconds to stop the recording
PREV_AUDIO = 0.5 #seconds of audo to prepend to the sending data
def audio_int(num_samples=50):
print ("Getting intensity values from mic.")
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
values = [math.sqrt(abs(audioop.avg(stream.read(CHUNK), 4)))
for x in range(num_samples)]
values = sorted(values, reverse=True)
r = sum(values[:int(num_samples * 0.2)]) / int(num_samples * 0.2)
print (" Finished ")
print (" Average audio intensity is ", r)
stream.close()
p.terminate()
return r
def listen_for_speech(threshold=THRESHOLD):
#Open stream
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print ("* Listening mic. ")
audio2send = []
cur_data = '' # current chunk of audio data
rel = RATE/CHUNK
slid_win = deque(maxlen=math.floor(SILENCE_LIMIT * rel))
#Prepend audio from 0.5 seconds before noise was detected
prev_audio = deque(maxlen=math.floor(PREV_AUDIO * rel))
started = False
response = []
while (True):
cur_data = stream.read(CHUNK)
slid_win.append(math.sqrt(abs(audioop.avg(cur_data, 4))))
#print slid_win[-1]
if(sum([x > THRESHOLD for x in slid_win]) > 0):
if(not started):
print ("Starting record of phrase")
started = True
audio2send.append(cur_data)
elif (started is True):
stream.stop_stream()
print ("Finished")
filename = save_speech(list(prev_audio) + audio2send, p)
p = stt_google_wav(filename)
if p == "exit":
break
# Remove temp file. Comment line to review.
os.remove(filename)
# Reset all
started = False
slid_win = deque(maxlen=math.floor(SILENCE_LIMIT * rel))
prev_audio = deque(maxlen=math.floor(0.5 * rel))
audio2send = []
stream.start_stream()
print ("Listening ...")
else:
prev_audio.append(cur_data)
print ("exiting")
p.terminate()
return
def save_speech(data, p):
filename = 'output_'+str(int(time.time()))
# writes data to WAV file
data = b''.join(data)
wf = wave.open(filename + '.wav', 'wb')
wf.setnchannels(1)
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(16000) # TODO make this value a function parameter?
wf.writeframes(data)
wf.close()
return filename + '.wav'
def stt_google_wav(audio_fname):
""" Sends audio file (audio_fname) to Google's text to speech
service and returns service's response. We need a FLAC
converter if audio is not FLAC (check FLAC_CONV). """
print ("Sending ", audio_fname)
#Convert to flac first
with open(audio_fname, 'rb') as stream:
sample = client.sample(stream=stream,
encoding=speech.Encoding.LINEAR16,
sample_rate_hertz=16000)
results = sample.streaming_recognize(language_code='en-US')
for result in results:
for alternative in result.alternatives:
print('=' * 20)
print('transcript: ' + alternative.transcript)
print('confidence: ' + str(alternative.confidence))
if alternative.transcript == "exit":
return "exit"
if alternative.transcript == "light on":
wiringpi.digitalWrite(4,1)
if alternative.transcript == "lights on":
wiringpi.digitalWrite(4,1)
if alternative.transcript == "light off":
wiringpi.digitalWrite(4,0)
if alternative.transcript == "lights off":
wiringpi.digitalWrite(4,0)
if(__name__ == '__main__'):
try:
wiringpi.wiringPiSetupGpio()
except:
print ("GPIO issue", sys.exc_info()[0])
wiringpi.pinMode(4,1)
wiringpi.digitalWrite(4,0)
listen_for_speech()