moving forward

This commit is contained in:
gauthiier 2022-03-13 17:09:05 +01:00
parent 11201664b8
commit ffa298a1fd
8 changed files with 483 additions and 31 deletions

View File

@ -1,29 +1,34 @@
{ {
"voices": [ "voices": [
{ {
"name": "Ralph", "name": "ETHER",
"model_dir": "data/tokens+models/Emerson-Nature.txt_bs=64_ns=8000_vs=5000", "model_dir": "data/tokens+models/Emerson-Nature.txt_bs=64_ns=8000_vs=5000",
"tokeniser_file": "data/tokens+models/Emerson-Nature.txt_bs=64_ns=8000_vs=5000/Emerson-Nature.txt_ns=5000.tokenizer.json", "tokeniser_file": "data/tokens+models/Emerson-Nature.txt_bs=64_ns=8000_vs=5000/Emerson-Nature.txt_ns=5000.tokenizer.json",
"temperature": "0.9" "temperature": "0.9"
}, },
{ {
"name": "Jean", "name": "CHAOS",
"model_dir": "data/tokens+models/Lafontaine-Fables[english].txt_bs=64_ns=8000_vs=5000", "model_dir": "data/tokens+models/Lafontaine-Fables[english].txt_bs=64_ns=3000_vs=5000",
"tokeniser_file": "data/tokens+models/Lafontaine-Fables[english].txt_bs=64_ns=8000_vs=5000/Lafontaine-Fables[english].txt_ns=5000.tokenizer.json", "tokeniser_file": "data/tokens+models/Lafontaine-Fables[english].txt_bs=64_ns=3000_vs=5000/Lafontaine-Fables[english].txt_ns=5000.tokenizer.json",
"temperature": "1.2" "temperature": "1.2"
}, },
{ {
"name": "Blake", "name": "BLAKE",
"model_dir": "data/tokens+models/Blake-Songs-of-Innocence-and-of-Experience.txt_bs=64_ns=8000_vs=5000", "model_dir": "data/tokens+models/Blake-Songs-of-Innocence-and-of-Experience.txt_bs=64_ns=3000_vs=5000",
"tokeniser_file": "data/tokens+models/Blake-Songs-of-Innocence-and-of-Experience.txt_bs=64_ns=8000_vs=5000/Blake-Songs-of-Innocence-and-of-Experience.txt_ns=5000.tokenizer.json", "tokeniser_file": "data/tokens+models/Blake-Songs-of-Innocence-and-of-Experience.txt_bs=64_ns=3000_vs=5000/Blake-Songs-of-Innocence-and-of-Experience.txt_ns=5000.tokenizer.json",
"temperature": "1.5" "temperature": "1.5"
}, },
{ {
"name": "Friedrich", "name": "THEO",
"model_dir": "data/tokens+models/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_bs=64_ns=8000_vs=5000", "model_dir": "data/tokens+models/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_bs=64_ns=8000_vs=5000",
"tokeniser_file": "data/tokens+models/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_bs=64_ns=8000_vs=5000/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_ns=5000.tokenizer.json", "tokeniser_file": "data/tokens+models/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_bs=64_ns=8000_vs=5000/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_ns=5000.tokenizer.json",
"temperature": "1.5" "temperature": "1.5"
},
{
"name": "POMPOM",
"model_dir": "data/tokens+models/NEWNATUREPOEMS.txt_bs=64_ns=5000_vs=5000",
"tokeniser_file": "data/tokens+models/NEWNATUREPOEMS.txt_bs=64_ns=5000_vs=5000/NEWNATUREPOEMS.txt_ns=5000.tokenizer.json",
"temperature": "0.5"
} }
] ]
} }

113
speak_broadcast.py Normal file
View File

@ -0,0 +1,113 @@
import argparse, json, sys, time, random
import utterance.voice
import utterance.utils
import utterance.osc
import examine.metric
UTTERANCE_LEN = 16
broadcast = None
def format_str(text: str) -> str:
t = utterance.utils.clean(text)
return utterance.utils.format(t)
def broadcast_utterance(v, utterance):
global broadcast
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)
broadcast.command('clear')
time.sleep(2)
def main() -> int:
global broadcast
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()
with open(args.config) as f:
conf = json.load(f)
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)
broadcast = utterance.osc.OscBroadcaster(name="osc_broadcast", host=conf['host'], port=conf['port'], command_channel=conf['command_osc_channel'])
broadcast.start_osc()
nbr_voices = len(voices)
state = 'c'
metric = examine.metric.Metric(model_input='data/models/doc2vec.model')
s = set(range(0, nbr_voices - 1))
rindex = random.sample(s, 1)[0]
v = voices[rindex]
uv = v.utter_one()
uv = format_str(uv)
v_vec = metric.vector(uv)
while state == 'c':
candidates = random.sample(s, 3)
results = []
for c in candidates:
if c == rindex:
continue
vc = voices[c]
vc_texts = vc.utter_n(n=50)
for t in vc_texts:
t = format_str(t)
t_vec = metric.vector(t)
d = examine.metric.cos_dist(v_vec, t_vec)
results.append([d, t, c])
results.sort(key=lambda t: t[0], reverse=True)
broadcast_utterance(v, uv)
# new round
top = results[0]
rindex = top[2]
v = voices[rindex]
uv = top[1]
v_vec = metric.vector(top[1])
# state = input("Continue? ")
broadcast.terminate_osc()
if __name__ == '__main__':
sys.exit(main())

View File

@ -1,8 +1,11 @@
import argparse, json, sys, time, random import argparse, json, sys, time, random
import utterance.voice import utterance.voice
import utterance.utils import utterance.utils
import utterance.osc
import examine.metric import examine.metric
UTTERANCE_LEN = 16
def format_str(text: str) -> str: def format_str(text: str) -> str:
t = utterance.utils.clean(text) t = utterance.utils.clean(text)
return utterance.utils.format(t) return utterance.utils.format(t)
@ -11,20 +14,23 @@ def format_str(text: str) -> str:
def main() -> int: def main() -> int:
p = argparse.ArgumentParser() p = argparse.ArgumentParser()
p.add_argument("-c", "--config", type=str, default="config.json", help="configuratin file") 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") p.add_argument("-i", "--iterations", type=int, default=10, help="number of iterations")
args = p.parse_args() args = p.parse_args()
print(args)
with open(args.config) as f: with open(args.config) as f:
conf = json.load(f) conf = json.load(f)
voices = [] voices = []
for v in conf['voices']: for v in conf['voices']:
voice = utterance.voice.Voice(name=v["name"].upper(), model=v['model_dir'], tokenizer=v['tokeniser_file'], temp=float(v["temperature"]), lenght=16) 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) voices.append(voice)
broadcast = utterance.osc.OscBroadcaster(name="osc_broadcast", host=conf['host'], port=conf['port'], command_channel=conf['command_osc_channel'])
broadcast.start_osc()
nbr_voices = len(voices) nbr_voices = len(voices)
state = 'c' state = 'c'
@ -94,23 +100,7 @@ def main() -> int:
broadcast.terminate_osc()
# nbr_voices = len(voices)
# current_voice = ""
# for i in range(args.iterations):
# rindex = random.randint(0, nbr_voices - 1)
# v = voices[rindex]
# if v.name != current_voice:
# print("==========")
# print(v.name + ":")
# current_voice = v.name
# t = v.utter_one()
# if t != None:
# t = utterance.utils.clean(t)
# t = utterance.utils.format(t)
# print(t)
# time.sleep(4)
if __name__ == '__main__': if __name__ == '__main__':

159
speak_metric_broadcast.py Normal file
View File

@ -0,0 +1,159 @@
import argparse, json, sys, time, random
import utterance.voice
import utterance.utils
import examine.metric
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
voices_broadcast = {}
conf = {}
def init_broadcast():
global conf, voices_broadcast
with open('voice.config.json') as f:
conf = json.load(f)
# configure voices and their channels
for v in conf['voices']:
voices_broadcast[v['name']] = v['osc_channel']['root'] + v['osc_channel']['utterance']
print(voices_broadcast)
# Start the system.
osc_startup()
# Make client channels to send packets.
osc_udp_client(conf['host'], conf['port'], "aaaa")
def broadcast_utterance(name, utterance):
global conf, voices_broadcast
sentences = utterance.split('\n')
text = name + ":"
for t in sentences:
if ',' in t:
phrases = t.split(',')
for i in range(0, len(phrases)):
p = phrases[i]
if p != "":
text += " " + p
if i != len(phrases) - 1 :
text += ','
msg = oscbuildparse.OSCMessage(voices_broadcast[name], None, [text])
osc_send(msg, "aaaa")
osc_process()
time.sleep(2)
else:
if text == "":
text += t
else:
text += "\n" + t
msg = oscbuildparse.OSCMessage(voices_broadcast[name], None, [text])
osc_send(msg, "aaaa")
osc_process()
time.sleep(2)
msg = oscbuildparse.OSCMessage(conf['command_osc_channel'], None, ["clear"])
osc_send(msg, "aaaa")
osc_process()
def format_str(text: str) -> str:
t = utterance.utils.clean(text)
return utterance.utils.format(t)
def main() -> int:
p = argparse.ArgumentParser()
p.add_argument("-c", "--config", type=str, default="config.json", help="configuratin file")
p.add_argument("-i", "--iterations", type=int, default=10, help="number of iterations")
args = p.parse_args()
print(args)
with open(args.config) as f:
conf = json.load(f)
voices = []
for v in conf['voices']:
voice = utterance.voice.Voice(name=v["name"].upper(), model=v['model_dir'], tokenizer=v['tokeniser_file'], temp=float(v["temperature"]), lenght=7)
voices.append(voice)
init_broadcast()
nbr_voices = len(voices)
state = 'c'
metric = examine.metric.Metric(model_input='data/models/doc2vec.model')
s = set(range(0, nbr_voices - 1))
# rindex = random.sample(s, 1)[0]
rindex = 4
v = voices[rindex]
uv = v.utter_one()
uv = format_str(uv)
v_vec = metric.vector(uv)
while 1:
candidates = random.sample(s, 2)
results = []
for c in candidates:
if c == rindex:
continue
vc = voices[c]
vc_texts = vc.utter_n(n=25)
for t in vc_texts:
t = format_str(t)
t_vec = metric.vector(t)
d = examine.metric.cos_dist(v_vec, t_vec)
results.append([d, t, c])
results.sort(key=lambda t: t[0], reverse=True)
# print('----------------------------')
# print(v.name + ":")
# print(uv)
# print('----------------------------')
broadcast_utterance(v.name, uv)
# for r in results[:2]:
# print('-->' + str(r[0]))
# print(r[1])
# print('+++++++++++++++++++++++++')
# new round
top = results[0]
rindex = top[2]
v = voices[rindex]
uv = top[1]
v_vec = metric.vector(top[1])
# state = input("Continue? ")
osc_terminate()
if __name__ == '__main__':
sys.exit(main())

34
utterance/osc.py Normal file
View File

@ -0,0 +1,34 @@
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
class OscBroadcaster:
def __init__(self, name: str, host: str, port: str, command_channel: str):
self.name = name
self.host = host
self.port = port
self.cmd = command_channel
osc_udp_client(self.host, self.port, self.name)
def utterance(self, utterance: str, channel: str):
msg = oscbuildparse.OSCMessage(channel, None, [utterance])
osc_send(msg, self.name)
osc_process()
def command(self, command: str):
msg = oscbuildparse.OSCMessage(self.cmd, None, [command])
osc_send(msg, self.name)
osc_process()
@staticmethod
def start_osc():
osc_startup()
@staticmethod
def terminate_osc():
osc_terminate()

View File

@ -1,4 +1,4 @@
import string import string, regex
def clean(text: str) -> str: def clean(text: str) -> str:
@ -17,3 +17,32 @@ def clean(text: str) -> str:
def format(text: str) -> str: def format(text: str) -> str:
return text.replace('\r\n', '\n').replace('\n\n', '\n') return text.replace('\r\n', '\n').replace('\n\n', '\n')
def fragments(utterance: str):
frags = []
sentences = utterance.splitlines()
PUNCT_RE = regex.compile(r'(\p{Punctuation})')
for s in sentences:
sf = PUNCT_RE.split(s)
cum = ""
for k in sf:
if len(k) < 1:
continue
elif len(k) > 1:
cum += k
elif k not in string.punctuation:
cum += k
else:
cum += k
frags.append(cum)
cum = ""
cum += '\n'
frags.append(cum)
return frags

View File

@ -1,5 +1,6 @@
from aitextgen import aitextgen from aitextgen import aitextgen
import utterance.utils import utterance.utils
import regex, string
class Voice: class Voice:
@ -16,3 +17,17 @@ class Voice:
def utter_one(self, temp: int = None, lenght: float = None) -> str: def utter_one(self, temp: int = None, lenght: float = None) -> str:
return self.utter_n(n=1, temp=temp, lenght=lenght)[0] return self.utter_n(n=1, temp=temp, lenght=lenght)[0]
def set_channel(self, root: str, endpoint: str):
self.channel = root + endpoint
def channel(self):
return self.channel
def fragments(self, utt: str):
self.utterance = utt
self.utterance_fragments = utterance.utils.fragments(utt)
return self.utterance_fragments

107
voice.config.json Normal file
View File

@ -0,0 +1,107 @@
{
"command_osc_channel" : "/command",
"host" : "127.0.0.1",
"port" : "1111",
"voices" : [
{
"background" : "0xff571111",
"color" : "0xffc8d75d",
"font" : "Times New Roman",
"name" : "CHAOS",
"osc_channel" : {
"background" : "/background",
"color" : "/font/color",
"root" : "/chaos",
"size" : "/font/size",
"type" : "/font/type",
"utterance" : "/utterance"
},
"model" :{
"model_dir": "data/tokens+models/Lafontaine-Fables[english].txt_bs=64_ns=3000_vs=5000",
"tokeniser_file": "data/tokens+models/Lafontaine-Fables[english].txt_bs=64_ns=3000_vs=5000/Lafontaine-Fables[english].txt_ns=5000.tokenizer.json",
"temperature": "1.2"
},
"size" : 100
},
{
"background" : "0xff020000",
"color" : "0xffebf3f1",
"font" : "Arial-BoldMT",
"name" : "ETHER",
"osc_channel" : {
"background" : "/background",
"color" : "/font/color",
"root" : "/ether",
"size" : "/font/size",
"type" : "/font/type",
"utterance" : "/utterance"
},
"model" :{
"model_dir": "data/tokens+models/Emerson-Nature.txt_bs=64_ns=8000_vs=5000",
"tokeniser_file": "data/tokens+models/Emerson-Nature.txt_bs=64_ns=8000_vs=5000/Emerson-Nature.txt_ns=5000.tokenizer.json",
"temperature": "0.9"
},
"size" : 100
},
{
"background" : "0xffdcb213",
"color" : "0xff353a39",
"font" : "NotoSansVai-Regular",
"name" : "BLAKE",
"osc_channel" : {
"background" : "/background",
"color" : "/font/color",
"root" : "/blake",
"size" : "/font/size",
"type" : "/font/type",
"utterance" : "/utterance"
},
"model" :{
"model_dir": "data/tokens+models/Blake-Songs-of-Innocence-and-of-Experience.txt_bs=64_ns=3000_vs=5000",
"tokeniser_file": "data/tokens+models/Blake-Songs-of-Innocence-and-of-Experience.txt_bs=64_ns=3000_vs=5000/Blake-Songs-of-Innocence-and-of-Experience.txt_ns=5000.tokenizer.json",
"temperature": "1.5"
},
"size" : 100
},
{
"background" : "0xff020000",
"color" : "0xffebf3f1",
"font" : "Arial-BoldMT",
"name" : "POMPOM",
"osc_channel" : {
"background" : "/background",
"color" : "/font/color",
"root" : "/pompom",
"size" : "/font/size",
"type" : "/font/type",
"utterance" : "/utterance"
},
"model" :{
"model_dir": "data/tokens+models/NEWNATUREPOEMS.txt_bs=64_ns=5000_vs=5000",
"tokeniser_file": "data/tokens+models/NEWNATUREPOEMS.txt_bs=64_ns=5000_vs=5000/NEWNATUREPOEMS.txt_ns=5000.tokenizer.json",
"temperature": "0.5"
},
"size" : 100
},
{
"background" : "0xff571111",
"color" : "0xffc8d75d",
"font" : "Times New Roman",
"name" : "THEO",
"osc_channel" : {
"background" : "/background",
"color" : "/font/color",
"root" : "/theo",
"size" : "/font/size",
"type" : "/font/type",
"utterance" : "/utterance"
},
"model" :{
"model_dir": "data/tokens+models/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_bs=64_ns=8000_vs=5000",
"tokeniser_file": "data/tokens+models/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_bs=64_ns=8000_vs=5000/Schelling-ON-THE-RELATION-OF-THE-PLASTIC-ARTS-TO-NATURE.txt_ns=5000.tokenizer.json",
"temperature": "1.5"
},
"size" : 100
}
]
}