Add highwater mark for client zmq to lower level

This commit is contained in:
Hugvey Central Command 2019-05-13 19:48:13 +02:00
parent 2acfb1c321
commit 019479d916

View file

@ -38,7 +38,7 @@ class VoiceServer(object):
def __init__(self, loop, hugvey, config):
self.config = config
self.input_rate = self.config['voice']['input_rate']
self.target_rate = self.config['voice']['target_rate']
self.stopped = True
@ -47,28 +47,28 @@ class VoiceServer(object):
self.ctx = Context.instance()
self.loop = loop
self.hugvey = hugvey
self.chunk = 4096
self.mic_prerol_sec = .2
self.prerol_frame_count = math.ceil((self.input_rate / self.chunk) * self.mic_prerol_sec)
self.prerol_frames = collections.deque(maxlen = self.prerol_frame_count)
self.p = pyaudio.PyAudio()
# wait a sec for the input devices to come up
logger.debug("Use a mic prerol of {} frames".format(self.prerol_frame_count))
logger.debug('wait for mic')
time.sleep(3)
logger.debug('done waiting for mic')
self.info = self.get_card_info()
def get_card_info(self):
output_device_idx = None
input_device_idx = None
devices_count = self.p.get_device_count()
for i in range(devices_count):
dev = self.p.get_device_info_by_index(i)
@ -88,13 +88,13 @@ class VoiceServer(object):
"< " if output_device_idx == i else "> " if input_device_idx == i else "- ", i, dev['name'],
dev['maxInputChannels'],
dev['maxOutputChannels']))
# Don't continue without pyAudio indexes
if input_device_idx is None:
raise Exception("Input device is not found: {}".format(self.config['voice']['input_name']))
if output_device_idx is None:
raise Exception("Output device is not found: {}".format(self.config['voice']['output_name']))
try:
# get eg: "hw:1,0" or "hw:0,3" -> used by Sox' play
output_device_name = self.p.get_device_info_by_index(output_device_idx)['name'].split("(",1)[1][:-1]
@ -109,28 +109,28 @@ class VoiceServer(object):
except IndexError as e:
input_device_name = None
input_card_name = None
logger.debug("Output: {}, Input: {}".format(output_device_name, input_device_name))
return {
'input': {
'idx': input_device_idx,
'device': input_device_name,
'card': input_card_name
'card': input_card_name
},
'output': {
'idx': output_device_idx,
'device': output_device_name,
'card': output_card_name
'card': output_card_name
}
}
#
#
# def get_output_idxs(self):
# pass
#
#
# def get_input_idx(self):
# input_device_idx = None
# # input_device_idx = 6
@ -159,14 +159,14 @@ class VoiceServer(object):
try:
if self.hugvey.cmd_server.muteMic:
logger.log(LOG_BS, 'block recording {}' .format(
self.hugvey.cmd_server.muteMic))
# logger.log(LOG_BS, 'block recording {}' .format(
# self.hugvey.cmd_server.muteMic))
# multiply by 0 to disable audio recording while playback
f = audioop.mul(f, 2, 0)
self.loop.call_soon_threadsafe(self.voice_socket.send, f)
self.loop.call_soon_threadsafe(self.voice_socket.send, f)
except Exception as e:
logger.warn("Error sending to {}".format(e))
pass
@ -177,10 +177,10 @@ class VoiceServer(object):
CHANNELS = 1
CHUNK = 4096
self.stopped = False
if 'alsaaudio' in sys.modules:
if self.config['voice']['input_mixer'] and self.config['voice']['input_volume'] and self.info['input']['card']:
logger.info("Set input volume on {}/{} to {}".format(
@ -190,7 +190,7 @@ class VoiceServer(object):
))
alsaaudio.Mixer(self.config['voice']['input_mixer'], device=self.info['input']['card']).setvolume(
self.config['voice']['input_volume'])
if self.config['voice']['output_mixer'] and self.config['voice']['output_volume'] and self.info['output']['card']:
logger.info("Set output volume on {}/{} to {}".format(
self.config['voice']['output_mixer'],
@ -214,6 +214,7 @@ class VoiceServer(object):
try:
address = "tcp://*:{}".format(self.config['voice']['port'] + self.hugvey.id)
self.voice_socket = self.ctx.socket(zmq.PUB)
self.voice_socket.set_hwm(100)
self.voice_socket.bind(address)
logger.info(
@ -263,7 +264,7 @@ class CommandHandler(object):
return
logger.info("Received {}".format(cmd))
if cmd['action'] == 'show_yourself':
self.showMyself()
if cmd['action'] == 'prepare':
@ -275,7 +276,7 @@ class CommandHandler(object):
def cmdPlay(self, cmd):
self.muteMic = True
msgId = cmd['id']
pitch = cmd['pitch'] if 'pitch' in cmd else 50
file = cmd['file'] if 'file' in cmd else None
@ -284,7 +285,7 @@ class CommandHandler(object):
# use duration for timing the popen duration (and redo it if needed)
duration = cmd['duration'] if 'duration' in cmd else None
self.playingMsgId = msgId
if self.playPopen:
logger.info("Interrupting playback of {}".format(self.playingMsgId))
self.playPopen.terminate()
@ -298,7 +299,7 @@ class CommandHandler(object):
file = self.file_address + "/" + file
# logger.debug(['play', file])
playCmd = ['play', file]
for param, value in params.items():
if not value:
continue
@ -312,9 +313,9 @@ class CommandHandler(object):
environment_vars['AUDIODRIVER'] = self.play_audiodriver
elif self.play_audiodev is not None:
environment_vars['AUDIODEV'] = self.play_audiodev
logger.debug(playCmd)
t = None
if duration is not None:
t = threading.Timer(duration+3, self.checkPopen, (msgId,))
@ -330,10 +331,10 @@ class CommandHandler(object):
returnCode = self.playPopen.returncode if self.playPopen else 0
logger.debug('finished')
self.playPopen = None
if t is not None:
t.cancel()
else:
logger.info("Speak: {}".format(text))
playCmd = ['espeak', '-p', '{0}'.format(pitch), text]
@ -354,14 +355,14 @@ class CommandHandler(object):
'event': 'playbackFinish',
'msgId': msgId
})
def checkPopen(self, msgId):
if self.playingMsgId != msgId:
return
if self.playPopen is None:
return
# prevent a lock of the story, no repeat or anything for now
logger.critical("Interrupting playback after timeout")
self.playPopen.terminate()
@ -430,7 +431,7 @@ class CommandHandler(object):
await asyncio.sleep(0.05)
s.close()
async def heartbeat(self):
while True:
self.showMyself()
@ -466,15 +467,15 @@ class Hugvey(object):
def start(self):
logger.debug('Hugvey {}, reporting'.format(self.id))
self.loop = asyncio.get_event_loop()
self.voice_server = VoiceServer(
loop=self.loop,
hugvey=self,
config=self.config
)
self.cmd_server = CommandHandler(
hugvey_id=self.id,
cmd_address=self.config['events']['cmd_address'],
@ -483,7 +484,7 @@ class Hugvey(object):
play_audiodev=self.voice_server.info['output']['device'],
play_audiodriver=self.config['voice']['output_driver'] if 'output_driver' in self.config['voice'] else None,
)
logger.info('start')
# self.voice_server.asyncStart(loop)
# loop.run_until_complete(self.voice_server.start())