def dum_v(): from Vowel import Vowel e1 = uniform(min_e1, max_e1) e2 = uniform(min_e2, max_e2) length = randint(100, 300) v = Vowel(e1, e2, length, "") name = [] if is_high(v): name.append("high") elif is_low(v): name.append("low") else: name.append("mid") if is_back(v): name.append("back") elif is_front(v): name.append("front") else: name.append("central") if length > 200: name.append("long") else: name.append("short") v.name = "-".join(name) return v
def __init__(self, verses): self.tohoku_tokenizer = BertJapaneseTokenizer.from_pretrained( 'cl-tohoku/bert-base-japanese-whole-word-masking') self.tohoku_bert_model = AutoModelForMaskedLM.from_pretrained( 'cl-tohoku/bert-base-japanese-whole-word-masking') self.lyrics = self.load_lyrics(verses) self.replaced_verses = [] self.vowel = Vowel.Vowel()
def get_vowel_random(self): ''' The vowel is the agent's phonetic representation of a vowel i.e. their pronunciation of their vowel percept. generative -> vowel is identical to percept mod generative -> vowel is noisy production of percept exemplar -> vowel is average of history (percept is a memory bank) ''' from random import uniform, randint p = self.percept radius = self.noise if ((not radius) or (not p)): return p circle_range = self.circle_range #radius = perception margin in ERB units #imitation will be a randomly selected point inside this circle e1 = p.e1 e2 = p.e2 l = int(p.length) #find the domain of circle fn to get x-coord (f2 value) left = e2 + radius right = e2 - radius rand_x = uniform(right, left) #generate x #find the range for y-coord (f1 value at x = rand_x) floor, c = circle_range(rand_x, e2, e1, radius) ceiling = min(rand_x, c) #constraint: f1 <= f2 rand_y = uniform(floor, ceiling) #generate y #constraint: length of imitation needs to be in range [100..300] #random number in that range and within original length+-50 length_min = max([100, (l - 25)]) length_max = length_min + 50 new_e1, new_e2 = rand_y, rand_x new_length = randint(length_min, length_max) name = p.name #match the name for the incoming signal #keep the imitations in a range if new_e1 > max_e1: new_e1 = max_e1 if new_e2 > max_e2: new_e2 = max_e2 if new_e1 < min_e1: new_e1 = min_e1 if new_e2 < min_e2: new_e2 = min_e2 new_v = Vowel.Vowel(new_e1, new_e2, new_length, name) self.set_vowel(new_v) return new_v
def dum_vowel(self): pos_lower = 700 pos_upper = 2400 pos = random.randint(pos_lower, pos_upper) closeLower = 275 closeUpper = 800 closed = random.randint(close_lower, close_upper) return Vowel.Vowel(pos, closed, random.randint(1, 250))
def guess_by_margin(self, unknown_v): #radius = perception margin in ERB units #imitation will be a randomly selected point inside this circle radius = self.phone_radius if not radius: return self.copy_vowel(unknown_v) e1 = unknown_v.e1 e2 = unknown_v.e2 l = int(unknown_v.length) #find the domain of circle fn to get x-coord (f2 value) left = e2 + radius right = e2 - radius rand_x = uniform(right, left) #generate x #find the range for y-coord (f1 value at x = rand_x) floor, c = circle_range(rand_x, e2, e1, radius) ceiling = min(rand_x, c) #constraint: f1 <= f2 rand_y = uniform(floor, ceiling) #generate y #constraint: length of imitation needs to be in range [100..300] #random number in that range and within original length+-50 length_min = max([100, (l - 25)]) length_max = min([length_min + 50, 300]) new_e1, new_e2 = rand_y, rand_x new_length = randint(length_min, length_max) w = unknown_v.name #match the name for the incoming signal if new_e1 > max_e1: new_e1 = max_e1 if new_e2 > max_e2: new_e2 = max_e2 if new_e1 < min_e1: new_e1 = min_e1 if new_e2 < min_e2: new_e2 = min_e2 new_v = Vowel.Vowel(new_e1, new_e2, new_length, w) new_v.set_features(max_e1, max_e2, min_e1, min_e2) return new_v
def get_midpt(self, v1, v2): nv_e1 = int((v1.e1 + v2.e1) / 2) nv_e2 = int((v1.e2 + v2.e2) / 2) if nv_e1 > nv_e2: nv_e1 = nv_e2 nv_l = int((v1.length + v2.length) / 2) ########################################################### #Not sure what to do here... #If the names don't match then new vowel should be compared #to the convention prototypes, except we can't access those #Maybe if the names match they should merge to one vowel #but if the names differ they should join to form a diphthong? ############################################################## name = v1.name nv = Vowel.Vowel(nv_e1, nv_e2, nv_l, name) for w in self.idio.values(): w.merge_midpoint(v1, v2, nv) return nv
def margin_tester(margin=1): import Convention v = Vowel.Vowel(10.5, 18.5, 250, 0) a = Agent(1, 1, margin, 1) v_str = str(v) m_str = str(margin) pts = [v] print("original:", v) c = Convention.Convention() for i in range(1000): im = a.guess_by_margin(v) dist = v.euc(im) #print("im: ", im, " dist: ", dist) pts.append(im) #v = im c.win = c.formant_space() c.plot_sets([pts], 0, v_str + " | " + m_str)
def merge_mid(self, v1, v2): '''two vowels of equal fnl load merge to their midpoint''' nv_e1 = ((v1.e1 + v2.e1) / 2) nv_e2 = ((v1.e2 + v2.e2) / 2) if nv_e1 > nv_e2: nv_e1 = nv_e2 nv_l = int((v1.length + v2.length) / 2) ########################################################### #Not sure what to do here... #If the names don't match then new vowel should be compared #to the convention prototypes, except we can't access those #UPDATE: Convention fixes this in get_rep_set method # ^Not a great fix #Maybe if the names match they should merge to one vowel #but if the names differ they should join to form a diphthong? ############################################################## #name = "" name = v1.name nv = Vowel.Vowel(nv_e1, nv_e2, nv_l, name) nv.weight = v1.weight + v2.weight # if self.chosen: print("\nCONFLICT:", v1, "and", v2, "merging to midpoint at", nv) v1n = v1.name v2n = v2.name nvn = nv.name if v1n != nvn: print(v1n, ">", nvn) if v2n != nvn: print(v2n, ">", nvn) for w in self.idio.values(): w.merge_midpoint(v1, v2, nv) rep = self.repertoire rep.remove(v1) rep.remove(v2) rep.append(nv)
def get_vowel(self): ''' applies random noise then assimilation ''' from random import uniform, randint fm = phon_fd P = Phonology.Phonology onset = self.onset.name nuc = self.percept coda = self.coda.name #apply random noise first radius = self.noise if radius > 0: circle_range = self.circle_range #radius = perception margin in ERB units #imitation will be a randomly selected point inside this circle e1 = nuc.e1 e2 = nuc.e2 l = int(nuc.length) #find the domain of circle fn to get x-coord (f2 value) left = e2 + radius right = e2 - radius rand_x = uniform(right, left) #generate x #find the range for y-coord (f1 value at x = rand_x) floor, c = circle_range(rand_x, e2, e1, radius) ceiling = min(rand_x, c) #constraint: f1 <= f2 rand_y = uniform(floor, ceiling) #generate y #constraint: length of imitation needs to be in range [100..300] #random number in that range and within original length+-50 length_min = max([100, (l - 50)]) length_max = min([length_min + 50, 300]) new_e1, new_e2 = rand_y, rand_x new_length = randint(length_min, length_max) name = nuc.name #match the name for the incoming signal #keep the imitations in a range if new_e1 > max_e1: new_e1 = max_e1 if new_e2 > max_e2: new_e2 = max_e2 if new_e1 < min_e1: new_e1 = min_e1 if new_e2 < min_e2: new_e2 = min_e2 n_nuc = Vowel.Vowel(new_e1, new_e2, new_length, name) else: n_nuc = nuc.cc() #APPLY COARTICULATION TRANSFORMS c1 = P(fm[onset]) c2 = P(fm[coda]) nfl = n_nuc.features ofl = c1.features cfl = c2.features #simulated morphological alternations #chance of a feature being "left off" due to context/use (inflectional/derivational) #morphable_features = ["stop", "voiced", "fricative", "spread"] morph_chance = 50 #onset transformations (coart) for of in ofl: ofns = c1.articulations of_nuc = ofns[of]((onset, n_nuc, coda), 0, True) n_nuc = of_nuc #nucleus production noise (art) for nf in nfl: nf_nuc = ofns[nf]((onset, n_nuc, coda), 1, True) n_nuc = nf_nuc #coda transformations (coart) for cf in cfl: cfns = c2.articulations cf_nuc = cfns[cf]((onset, n_nuc, coda), 2, True) n_nuc = cf_nuc return n_nuc