Add highwater mark for client zmq to lower level
This commit is contained in:
parent
2acfb1c321
commit
019479d916
1 changed files with 46 additions and 45 deletions
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue