Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passive Listening for commands #434

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ target/

# SublimeLinter config file
.sublimelinterrc

# PyCharm Project

.idea/
25 changes: 18 additions & 7 deletions client/conversation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

class Conversation(object):

def __init__(self, persona, mic, profile):
def __init__(self, persona, mic, profile, isPassiveEnabled):
self._logger = logging.getLogger(__name__)
self.persona = persona
self.mic = mic
self.profile = profile
self.brain = Brain(mic, profile)
self.notifier = Notifier(profile)
self.isPassiveEnabled = isPassiveEnabled

def handleForever(self):
"""
Expand All @@ -28,20 +29,30 @@ def handleForever(self):

self._logger.debug("Started listening for keyword '%s'",
self.persona)
threshold, transcribed = self.mic.passiveListen(self.persona)
threshold, transcribed, passivePhrases = \
self.mic.passiveListen(self.persona)
self._logger.debug("Stopped listening for keyword '%s'",
self.persona)

if not transcribed or not threshold:
self._logger.info("Nothing has been said or transcribed.")
continue

self._logger.info("Keyword '%s' has been said!", self.persona)

self._logger.debug("Started to listen actively with threshold: %r",
threshold)
input = self.mic.activeListenToAllOptions(threshold)
self._logger.debug("Stopped to listen actively with threshold: %r",
threshold)
if self.isPassiveEnabled is True and len(passivePhrases) != 0:

input = passivePhrases
self._logger.debug("Checking for passive phrase '%s' with " +
"threshold: %r", input, threshold)

else:

self._logger.debug("Started to listen actively with " +
"threshold: %r", threshold)
input = self.mic.activeListenToAllOptions(threshold)
self._logger.debug("Stopped to listen actively with " +
"threshold: %r", threshold)

if input:
self.brain.query(input)
Expand Down
22 changes: 18 additions & 4 deletions client/mic.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def passiveListen(self, PERSONA):
print "No disturbance detected"
stream.stop_stream()
stream.close()
return (None, None)
return (None, None, None)

# cutoff any recording before this disturbance was detected
frames = frames[-20:]
Expand All @@ -178,10 +178,24 @@ def passiveListen(self, PERSONA):
# check if PERSONA was said
transcribed = self.passive_stt_engine.transcribe(f)

if any(PERSONA in phrase for phrase in transcribed):
return (THRESHOLD, PERSONA)
# this is an array of all the passive phrases the user has said to us
passivePhrases = []

return (False, transcribed)
for loopedPhrase in transcribed:

if loopedPhrase.startswith(PERSONA):

# get the command without the personal prefix
potentialCommand = loopedPhrase[len(PERSONA):]
# if the user wasn't merely calling out to the machine, add it
if len(potentialCommand) != 0:
passivePhrases.append(potentialCommand)

if len(passivePhrases) != 0 or \
any(PERSONA in phrase for phrase in transcribed):
return (THRESHOLD, PERSONA, passivePhrases)
else:
return (False, transcribed, [])

def activeListen(self, THRESHOLD=None, LISTEN=True, MUSIC=False):
"""
Expand Down
17 changes: 17 additions & 0 deletions client/populate.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,23 @@ def verifyLocation(place):
if response == 'Y':
profile['stt_passive_engine'] = "sphinx"

print("\nActivation Settings")
print("By default, Jasper listens out for it's name 'Jasper' " +
"then it prompts you for a command by playing a sound. " +
"Optionally, you can combine the two steps " +
"into one with the passive setting enabled. " +
"'Jasper tell me a joke' can be used in 1 sentence " +
"without needing the prompt. The default way of " +
"communicating can still be used with passive enabled. " +
"Type 'yes' if you would like enable this feature, or " +
"'no' otherwise")
activationResponse = raw_input('Enable Passive mode? (yes)/(no): ')

if activationResponse == 'yes' or activationResponse == 'y':
profile['passive_enabled'] = 'true'
else:
profile['passive_enabled'] = 'false'

# write to profile
print("Writing to profile...")
if not os.path.exists(jasperpath.CONFIG_PATH):
Expand Down
12 changes: 11 additions & 1 deletion jasper.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,17 @@ def run(self):
salutation = "How can I be of service?"
self.mic.say(salutation)

conversation = Conversation("JASPER", self.mic, self.config)
try:
passiveEnabled = self.config['passive_enabled']
except KeyError:
passiveEnabled = "false"
logger.warning("passive_enabled not specified in profile, " +
"defaulting to '%s'", passiveEnabled)

passiveEnabled = passiveEnabled == "true"

conversation = Conversation("JASPER", self.mic, self.config,
passiveEnabled)
conversation.handleForever()

if __name__ == "__main__":
Expand Down