Skip to content

Commit

Permalink
Add wrapper around HotwordDetector class for Python to provide a simp…
Browse files Browse the repository at this point in the history
…le interface for running detectors in a separate thread
  • Loading branch information
rohantib committed Jun 20, 2017
1 parent 7923a81 commit c9f3fb6
Showing 1 changed file with 92 additions and 0 deletions.
92 changes: 92 additions & 0 deletions examples/Python/snowboythreaded.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import snowboydecoder
import threading
import Queue


class ThreadedDetector(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
# Start detectors - blocks until interrupted by self.interrupted variable
self.detectors.start(interrupt_check=lambda: self.interrupted, **self.run_kwargs)
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.")
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.")
self.init_kwargs['sensitivity'] = sensitivity
self.vars_are_changed = True

0 comments on commit c9f3fb6

Please sign in to comment.