forked from chrishorton/Hands-Free-Presentation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
detectors.py
102 lines (90 loc) · 3.76 KB
/
detectors.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
import sys
with open(".snowboy_path", "r") as snowboy_dest:
snowboy_package = snowboy_dest.read().strip()
sys.path.append(snowboy_package)
import snowboydecoder
import threading
import Queue
class Detectors(threading.Thread):
"""
Wrapper class around detectors to run them in a separate thread
and provide methods to pause, resume, and modify detection
"""
def __init__(self, models, **kwargs):
"""
Initialize Detectors object. **kwargs is for any __init__ keyword arguments to be passed into HotWordDetector
__init__() method.
"""
threading.Thread.__init__(self)
self.models = models
self.init_kwargs = kwargs
self.interrupted = True
self.commands = Queue.Queue()
self.vars_are_changed = True
self.detectors = None # Initialize when thread is run in self.run()
self.run_kwargs = None # Initialize when detectors start in self.start_recog()
def initialize_detectors(self):
"""
Returns initialized Snowboy HotwordDetector objects
"""
self.detectors = snowboydecoder.HotwordDetector(self.models, **self.init_kwargs)
def run(self):
"""
Runs in separate thread - waits on command to either run detectors or terminate thread from commands queue
"""
try:
while True:
command = self.commands.get(True)
if command == "Start":
self.interrupted = False
if self.vars_are_changed:
# If there is an existing detector object, terminate it
if self.detectors is not None:
self.detectors.terminate()
self.initialize_detectors()
self.vars_are_changed = False
print("Command recognition started.")
# Start detectors - blocks until interrupted by self.interrupted variable
self.detectors.start(interrupt_check=lambda: self.interrupted, **self.run_kwargs)
# After detectors have been interrupted
print('Command recognition stopped.')
elif command == "Terminate":
# Program ending - terminate thread
break
finally:
if self.detectors is not None:
self.detectors.terminate()
def start_recog(self, **kwargs):
"""
Starts recognition in thread. Accepts kwargs to pass into the HotWordDetector.start() method, but
does not accept interrupt_callback, as that is already set up.
"""
assert "interrupt_check" not in kwargs, \
"Cannot set interrupt_check argument. To interrupt detectors, use Detectors.stop_recog() instead"
self.run_kwargs = kwargs
self.commands.put("Start")
def stop_recog(self):
"""
Halts recognition in thread.
"""
self.interrupted = True
def terminate(self):
"""
Terminates recognition thread - called when program terminates
"""
self.stop_recog()
self.commands.put("Terminate")
def is_running(self):
return not self.interrupted
def change_models(self, models):
if self.is_running():
print("Models will be changed after restarting detectors.")
if self.models != models:
self.models = models
self.vars_are_changed = True
def change_sensitivity(self, sensitivity):
if self.is_running():
print("Sensitivity will be changed after restarting detectors.")
if self.init_kwargs['sensitivity'] != sensitivity:
self.init_kwargs['sensitivity'] = sensitivity
self.vars_are_changed = True