NATURESPEAK-ML-UTTER/speak_broadcast.py

155 lines
3.6 KiB
Python
Raw Normal View History

2022-03-13 18:56:35 +01:00
import argparse, json, sys, time, random, logging, signal
2022-03-13 17:09:05 +01:00
import utterance.voice
import utterance.utils
import utterance.osc
import examine.metric
UTTERANCE_LEN = 16
2022-03-13 18:56:35 +01:00
NUM_METRIC_GEN = 50
NUM_SAMPLE_VOICES = 3
2022-03-13 17:09:05 +01:00
broadcast = None
2022-03-13 18:56:35 +01:00
metric = None
exit = False
2022-03-13 17:09:05 +01:00
2022-03-13 18:56:35 +01:00
def format_str(text) -> str:
2022-03-13 17:09:05 +01:00
t = utterance.utils.clean(text)
2022-03-13 18:56:35 +01:00
return utterance.utils.format(t)
def utter_one(v) -> str:
u = v.utter_one()
return format_str(u)
def utter_one_vectorise(v):
global metric
uv = utter_one(v)
uv_vec = metric.vector(uv)
return uv, uv_vec
def utter_n_vectorise_distance(v, n, vec):
global metric
results = []
texts = v.utter_n(n=n)
for t in texts:
t = format_str(t)
t_vec = metric.vector(t)
d = examine.metric.cos_dist(vec, t_vec)
results.append([d, t, v])
return results
2022-03-13 17:09:05 +01:00
def broadcast_utterance(v, utterance):
2022-03-13 18:56:35 +01:00
global broadcast, exit
2022-03-13 17:09:05 +01:00
text = v.name.upper() + ":\n"
broadcast.utterance(text, v.channel)
time.sleep(2)
frags = v.fragments(utterance)
for f in frags:
text += f
broadcast.utterance(text, v.channel)
time.sleep(2)
2022-03-13 18:56:35 +01:00
if exit:
return
2022-03-13 17:09:05 +01:00
broadcast.command('clear')
time.sleep(2)
2022-03-13 18:56:35 +01:00
def signal_terminate(signum, frame):
global exit
logging.warning("::SIGNAL TERMINATE::")
exit = True
2022-03-13 17:09:05 +01:00
def main() -> int:
2022-03-13 18:56:35 +01:00
global broadcast, metric
2022-03-13 17:09:05 +01:00
p = argparse.ArgumentParser()
p.add_argument("-c", "--config", type=str, default="voice.config.json", help="configuratin file")
p.add_argument("-i", "--iterations", type=int, default=10, help="number of iterations")
args = p.parse_args()
2022-03-13 18:56:35 +01:00
logging.basicConfig(level=logging.INFO)
logging.info(f"INIT::loading config file - {args.config}")
2022-03-13 17:09:05 +01:00
with open(args.config) as f:
conf = json.load(f)
2022-03-13 18:56:35 +01:00
logging.info(conf)
#--------------------#
# VOICES
#--------------------#
logging.info(f"INIT::creating voices")
2022-03-13 17:09:05 +01:00
voices = []
for v in conf['voices']:
model = v['model']
voice = utterance.voice.Voice(name=v["name"].upper(), model=model['model_dir'], tokenizer=model['tokeniser_file'], temp=float(model["temperature"]), lenght=UTTERANCE_LEN)
voice.set_channel(v['osc_channel']['root'], v['osc_channel']['utterance'])
voices.append(voice)
2022-03-13 18:56:35 +01:00
#--------------------#
# NET
#--------------------#
logging.info(f"INIT::setting up OSC")
broadcast = utterance.osc.OscBroadcaster(name="osc_broadcast", host=conf['host'], port=conf['port'], command_channel=conf['command_osc_channel'])
broadcast.start_osc()
2022-03-13 17:09:05 +01:00
2022-03-13 18:56:35 +01:00
#--------------------#
# METRIC
#--------------------#
logging.info(f"INIT::loading doc2vec metrics")
2022-03-13 17:09:05 +01:00
metric = examine.metric.Metric(model_input='data/models/doc2vec.model')
2022-03-13 18:56:35 +01:00
#--------------------#
# A
#--------------------#
logging.info(f"INIT::generating first utterance")
random.seed(time.time())
v = random.choice(voices)
uv, uv_vec = utter_one_vectorise(v)
2022-03-13 17:09:05 +01:00
2022-03-13 18:56:35 +01:00
while not exit:
2022-03-13 17:09:05 +01:00
2022-03-13 18:56:35 +01:00
logging.info(f"LOOP::broadcasting {v.name}")
broadcast_utterance(v, uv)
2022-03-13 17:09:05 +01:00
2022-03-13 18:56:35 +01:00
logging.info(f"LOOP::finding candidates")
start = time.time()
candidates = random.sample(voices, NUM_SAMPLE_VOICES)
2022-03-13 17:09:05 +01:00
results = []
for c in candidates:
2022-03-13 18:56:35 +01:00
if exit:
break
if c == v:
2022-03-13 17:09:05 +01:00
continue
2022-03-13 18:56:35 +01:00
results += utter_n_vectorise_distance(c, NUM_METRIC_GEN, uv_vec)
2022-03-13 17:09:05 +01:00
results.sort(key=lambda t: t[0], reverse=True)
2022-03-13 18:56:35 +01:00
lapse = time.time() - start
logging.info(f"LOOP::done - {lapse} secs")
2022-03-13 17:09:05 +01:00
2022-03-13 18:56:35 +01:00
# ok here we need to randomise maybe...?!
# ([d, t, v])
choice = results[0]
v = choice[2]
uv = choice[1]
uv_vec = metric.vector(uv)
logging.info(f"LOOP::next {v.name}")
2022-03-13 17:09:05 +01:00
2022-03-13 18:56:35 +01:00
logging.info(f"TERMINATE::terminating OSC")
2022-03-13 17:09:05 +01:00
broadcast.terminate_osc()
2022-03-13 18:56:35 +01:00
logging.info(f"FIN")
2022-03-13 17:09:05 +01:00
if __name__ == '__main__':
2022-03-13 18:56:35 +01:00
signal.signal(signal.SIGINT, signal_terminate)
sys.exit(main())