Mute speech events before playing back audio

This commit is contained in:
Ruben van de Ven 2019-04-12 12:38:00 +02:00
parent a4acc04a91
commit 554f6a2cc3
3 changed files with 42 additions and 6 deletions

View file

@ -158,9 +158,9 @@ class VoiceServer(object):
in_data, 2, 1, self.input_rate, self.target_rate, self.laststate) in_data, 2, 1, self.input_rate, self.target_rate, self.laststate)
try: try:
if self.hugvey.cmd_server.playPopen is not None: if self.hugvey.cmd_server.muteMic:
logger.debug('block recording {}' .format( logger.debug('block recording {}' .format(
self.hugvey.cmd_server.playPopen)) self.hugvey.cmd_server.muteMic))
# if recording is blocked, store the latest n frames. So we can release # if recording is blocked, store the latest n frames. So we can release
# this buffer to the mic stream # this buffer to the mic stream
@ -256,6 +256,7 @@ class CommandHandler(object):
self.hugvey_id = hugvey_id self.hugvey_id = hugvey_id
self.cmd_address = cmd_address self.cmd_address = cmd_address
self.publish_address = publish_address self.publish_address = publish_address
self.muteMic = False
self.playPopen = None self.playPopen = None
self.file_address = file_address self.file_address = file_address
self.playingMsgId = None self.playingMsgId = None
@ -272,12 +273,16 @@ class CommandHandler(object):
logger.info("Received {}".format(cmd)) logger.info("Received {}".format(cmd))
if cmd['action'] == 'show_yourself': if cmd['action'] == 'show_yourself':
self.showMyself() self.showMyself()
if cmd['action'] == 'prepare':
self.muteMic = True
if cmd['action'] == 'play': if cmd['action'] == 'play':
self.cmdPlay(cmd) self.cmdPlay(cmd)
if cmd['action'] == 'stop': if cmd['action'] == 'stop':
self.cmdPlay(cmd, cmd['id']) self.cmdPlay(cmd, cmd['id'])
def cmdPlay(self, cmd): def cmdPlay(self, cmd):
self.muteMic = True
msgId = cmd['id'] msgId = cmd['id']
pitch = cmd['pitch'] if 'pitch' in cmd else 50 pitch = cmd['pitch'] if 'pitch' in cmd else 50
file = cmd['file'] if 'file' in cmd else None file = cmd['file'] if 'file' in cmd else None
@ -308,7 +313,10 @@ class CommandHandler(object):
logger.debug(playCmd) logger.debug(playCmd)
self.playPopen = subprocess.Popen( self.playPopen = subprocess.Popen(
playCmd, stdout=subprocess.PIPE, env=environment_vars) playCmd, stdout=subprocess.PIPE, env=environment_vars)
self.sendMessage({
'event': 'playbackStart',
'msgId': msgId
})
returnCode = self.playPopen.wait() returnCode = self.playPopen.wait()
logger.debug('finished') logger.debug('finished')
self.playPopen = None self.playPopen = None
@ -326,6 +334,7 @@ class CommandHandler(object):
"Finished playback. Return code: {}".format(returnCode)) "Finished playback. Return code: {}".format(returnCode))
self.playingMsgId = None self.playingMsgId = None
self.muteMic = False
self.sendMessage({ self.sendMessage({
'event': 'playbackFinish', 'event': 'playbackFinish',
'msgId': msgId 'msgId': msgId

View file

@ -191,6 +191,7 @@ class GoogleVoiceClient(object):
self.pause() self.pause()
return return
self.subsequentMutedFrames = 0
# self.logger.debug("We have mic!") # self.logger.debug("We have mic!")
if not self.isRunning.is_set(): if not self.isRunning.is_set():
self.logger.info("Resume voice") self.logger.info("Resume voice")

View file

@ -746,6 +746,13 @@ class Story(object):
# reinitiate current message # reinitiate current message
await self.setCurrentMessage(self.currentMessage) await self.setCurrentMessage(self.currentMessage)
if e['event'] == "playbackStart":
if e['msgId'] != self.currentMessage.id:
continue
self.lastMsgStartTime = self.timer.getElapsed()
self.logger.debug("Start playback")
if e['event'] == "playbackFinish": if e['event'] == "playbackFinish":
if e['msgId'] == self.currentMessage.id: if e['msgId'] == self.currentMessage.id:
#TODO: migrate value to Messagage instead of Story #TODO: migrate value to Messagage instead of Story
@ -771,6 +778,16 @@ class Story(object):
# participants speaks, reset counter # participants speaks, reset counter
self.stats['consecutiveSilentTimeouts'] = 0 self.stats['consecutiveSilentTimeouts'] = 0
# if self.currentMessage and not self.lastMsgStartTime:
if self.currentMessage and not self.lastMsgFinishTime:
# Ignore incoming speech events until we receive a 'playbackStart' event.
# After that moment the mic will be muted, so nothing should come in _anyway_
# unless google is really slow on us. But by taking the start time we don't ignore
# messages that come in, in the case google is faster than our playbackFinish event.
# (if this setup doesn't work, try to test on self.lastMsgFinish time anyway)
# it keeps tricky with all these run conditions
continue
# message is still playing: # message is still playing:
if self.currentMessage and not self.lastMsgFinishTime and self.previousReply and self.previousReply.forMessage.interruptCount < 4: if self.currentMessage and not self.lastMsgFinishTime and self.previousReply and self.previousReply.forMessage.interruptCount < 4:
timeDiff = self.timer.getElapsed() - self.previousReply.forMessage.getFinishedTime() timeDiff = self.timer.getElapsed() - self.previousReply.forMessage.getFinishedTime()
@ -883,10 +900,18 @@ class Story(object):
self.currentMessage = message self.currentMessage = message
self.lastMsgTime = time.time() self.lastMsgTime = time.time()
self.lastMsgFinishTime = None # to be filled in by the event self.lastMsgFinishTime = None # to be filled in by the event
self.lastMsgStartTime = None # to be filled in by the event
# if not reset: # if not reset:
self.previousReply = self.currentReply # we can use this for interrptions self.previousReply = self.currentReply # we can use this for interrptions
self.currentReply = useReply #self.currentMessage.reply self.currentReply = useReply #self.currentMessage.reply
# send command to already mute mic
self.hugvey.sendCommand({
'action': 'prepare',
'id': message.id
})
# else: # else:
# # if we press 'save & play', it should not remember it's last reply to that msg # # if we press 'save & play', it should not remember it's last reply to that msg
# self.previousReply = self.currentReply # we can use this for interrptions # self.previousReply = self.currentReply # we can use this for interrptions
@ -901,6 +926,7 @@ class Story(object):
# TODO: prep events & timer etc. # TODO: prep events & timer etc.
fn = await message.getAudioFilePath() fn = await message.getAudioFilePath()
# self.hugvey.google.pause() # pause STT to avoid text events while decision is made
self.hugvey.sendCommand({ self.hugvey.sendCommand({
'action': 'play', 'action': 'play',
'file': fn, 'file': fn,