New configuration for ridgid card selection by client
This commit is contained in:
parent
a9c3d7ba12
commit
6182362acc
2 changed files with 132 additions and 43 deletions
|
@ -5,11 +5,13 @@ voice:
|
|||
input_rate: 44100
|
||||
target_rate: 16000
|
||||
port: 4444
|
||||
input_name: null
|
||||
input_name: 'AK5371'
|
||||
output_name: 'USB Audio Device'
|
||||
input_mixer: 'Mic'
|
||||
output_mixer: 'PCM'
|
||||
input_volume: 90
|
||||
output_volume: 60
|
||||
file_address: "http://hugveycmd.local:8888"
|
||||
play_device: 0 # alsa mixer nr
|
||||
play_volume: 80
|
||||
play_audiodev: "hw:2,0" # sox AUDIODEV
|
||||
|
||||
|
||||
|
||||
|
|
157
hugvey/client.py
157
hugvey/client.py
|
@ -36,14 +36,14 @@ def setLogger(hv_id):
|
|||
class VoiceServer(object):
|
||||
"""A UDP server, providing mic data at 16 kHz"""
|
||||
|
||||
def __init__(self, loop, hugvey, voice_port: int, input_rate: int, input_name: str = None, target_rate: int = 16000):
|
||||
self.voice_port = voice_port
|
||||
self.input_rate = input_rate
|
||||
self.target_rate = target_rate
|
||||
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
|
||||
self.clients = []
|
||||
self.laststate = None
|
||||
self.input_name = input_name
|
||||
self.ctx = Context.instance()
|
||||
self.loop = loop
|
||||
self.hugvey = hugvey
|
||||
|
@ -53,22 +53,99 @@ class VoiceServer(object):
|
|||
self.prerol_frame_count = math.ceil(self.input_rate / self.chunk)
|
||||
self.prerol_frames = collections.deque(maxlen = self.prerol_frame_count)
|
||||
|
||||
def get_input_idx(self):
|
||||
self.p = pyaudio.PyAudio()
|
||||
# wait a sec for the input devices to come up
|
||||
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
|
||||
# input_device_idx = 6
|
||||
# input_device_idx = 0
|
||||
|
||||
devices_count = self.p.get_device_count()
|
||||
for i in range(devices_count):
|
||||
dev = self.p.get_device_info_by_index(i)
|
||||
if input_device_idx is None and dev['maxInputChannels'] > 0:
|
||||
if (self.input_name and self.input_name in dev['name']) or \
|
||||
(not self.input_name and dev['name'] != 'default'):
|
||||
input_device_idx = dev['index']
|
||||
logger.info("Use device {0}: {1}".format(
|
||||
if output_device_idx is None and dev['maxOutputChannels'] > 0:
|
||||
if (self.config['voice']['output_name'] and self.config['voice']['output_name'] in dev['name']) or \
|
||||
(not self.config['voice']['output_name'] and dev['name'] != 'default'):
|
||||
output_device_idx = dev['index']
|
||||
logger.info("Use output device {0}: {1}".format(
|
||||
dev['index'], dev['name']))
|
||||
logger.debug("{} {:0d} {}".format(
|
||||
"* " if input_device_idx == i else "- ", i, dev['name']))
|
||||
return input_device_idx
|
||||
if input_device_idx is None and dev['maxInputChannels'] > 0:
|
||||
if (self.config['voice']['input_name'] and self.config['voice']['input_name'] in dev['name']) or \
|
||||
(not self.config['voice']['input_name'] and dev['name'] != 'default'):
|
||||
input_device_idx = dev['index']
|
||||
logger.info("Use input device {0}: {1}".format(
|
||||
dev['index'], dev['name']))
|
||||
logger.debug("{} {:0d} {} (i: {}, o: {})".format(
|
||||
"< " 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]
|
||||
# get eg: "hw:1" or "hw:0" -> used by alsaaudio.Mixer(device=..)
|
||||
output_card_name = output_device_name.split(",",1)[0]
|
||||
except IndexError as e:
|
||||
output_device_name = None
|
||||
output_card_name = None
|
||||
try:
|
||||
input_device_name = self.p.get_device_info_by_index(input_device_idx)['name'].split("(",1)[1][:-1]
|
||||
input_card_name = input_device_name.split(",",1)[0]
|
||||
except IndexError as e:
|
||||
input_device_name = None
|
||||
input_card_name = None
|
||||
|
||||
print(output_device_name, input_device_name)
|
||||
|
||||
|
||||
return {
|
||||
'input': {
|
||||
'idx': input_device_idx,
|
||||
'device': input_device_name,
|
||||
'card': input_card_name
|
||||
},
|
||||
'output': {
|
||||
'idx': output_device_idx,
|
||||
'device': output_device_name,
|
||||
'card': output_card_name
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# def get_output_idxs(self):
|
||||
# pass
|
||||
#
|
||||
# def get_input_idx(self):
|
||||
# input_device_idx = None
|
||||
# # input_device_idx = 6
|
||||
# # input_device_idx = 0
|
||||
# devices_count = self.p.get_device_count()
|
||||
# for i in range(devices_count):
|
||||
# dev = self.p.get_device_info_by_index(i)
|
||||
# if input_device_idx is None and dev['maxInputChannels'] > 0:
|
||||
# if (self.input_name and self.input_name in dev['name']) or \
|
||||
# (not self.input_name and dev['name'] != 'default'):
|
||||
# input_device_idx = dev['index']
|
||||
# logger.info("Use device {0}: {1}".format(
|
||||
# dev['index'], dev['name']))
|
||||
# logger.debug("{} {:0d} {}".format(
|
||||
# "* " if input_device_idx == i else "- ", i, dev['name']))
|
||||
# return input_device_idx
|
||||
|
||||
def onBuffer(self, in_data, frame_count, time_info, status):
|
||||
if self.input_rate == self.target_rate:
|
||||
|
@ -108,13 +185,28 @@ class VoiceServer(object):
|
|||
CHANNELS = 1
|
||||
CHUNK = 4096
|
||||
|
||||
self.p = pyaudio.PyAudio()
|
||||
|
||||
self.stopped = False
|
||||
|
||||
# wait a sec for the input devices to come up
|
||||
logger.debug('wait for mic')
|
||||
await asyncio.sleep(3)
|
||||
logger.debug('done waiting for mic')
|
||||
|
||||
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(
|
||||
self.config['voice']['input_mixer'],
|
||||
self.info['input']['card'],
|
||||
self.config['voice']['input_volume']
|
||||
))
|
||||
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'],
|
||||
self.info['output']['card'],
|
||||
self.config['voice']['output_volume']
|
||||
))
|
||||
alsaaudio.Mixer(self.config['voice']['output_mixer'], device=self.info['output']['card']).setvolume(
|
||||
self.config['voice']['output_volume'])
|
||||
|
||||
stream = self.p.open(
|
||||
format=FORMAT,
|
||||
|
@ -123,12 +215,12 @@ class VoiceServer(object):
|
|||
input=True,
|
||||
frames_per_buffer=CHUNK,
|
||||
stream_callback=self.onBuffer,
|
||||
input_device_index=self.get_input_idx()
|
||||
input_device_index=self.info['input']['idx']
|
||||
)
|
||||
|
||||
while not self.stopped:
|
||||
try:
|
||||
address = "tcp://*:{}".format(self.voice_port + self.hugvey.id)
|
||||
address = "tcp://*:{}".format(self.config['voice']['port'] + self.hugvey.id)
|
||||
self.voice_socket = self.ctx.socket(zmq.PUB)
|
||||
self.voice_socket.bind(address)
|
||||
|
||||
|
@ -335,25 +427,20 @@ class Hugvey(object):
|
|||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
if self.config['voice']['play_device'] and 'alsaaudio' in sys.modules:
|
||||
alsaaudio.Mixer(self.config['voice']['play_device']).setvolume(
|
||||
self.config['voice']['play_volume'])
|
||||
self.voice_server = VoiceServer(
|
||||
loop=loop,
|
||||
hugvey=self,
|
||||
config=self.config
|
||||
)
|
||||
|
||||
self.cmd_server = CommandHandler(
|
||||
hugvey_id=self.id,
|
||||
cmd_address=self.config['events']['cmd_address'],
|
||||
publish_address=self.config['events']['publish_address'],
|
||||
file_address=self.config['voice']['file_address'],
|
||||
play_audiodev=self.config['voice']['play_audiodev']
|
||||
)
|
||||
self.voice_server = VoiceServer(
|
||||
loop=loop,
|
||||
hugvey=self,
|
||||
voice_port=int(self.config['voice']['port']),
|
||||
input_rate=int(self.config['voice']['input_rate']),
|
||||
input_name=self.config['voice']['input_name'],
|
||||
target_rate=int(self.config['voice']['target_rate']),
|
||||
play_audiodev=self.voice_server.info['output']['device']
|
||||
)
|
||||
|
||||
logger.info('start')
|
||||
# self.voice_server.asyncStart(loop)
|
||||
# loop.run_until_complete(self.voice_server.start())
|
||||
|
|
Loading…
Reference in a new issue