private SpeechSound convertPhoneme(Phoneme phoneme) { SpeechSound ss = new SpeechSound(); if (phoneme.preceding != null) { ss.Preceded = true; ss.Successed = false; Phone glide = new Phone(); glide.converProtoPhone(phoneme.phones[0]); ss.Glide = glide; Phone[] phones = new Phone[phoneme.phones.Length - 1]; for (int ii = 0; ii < phones.Length; ii++) { Phone phone = new Phone(); phone.converProtoPhone(phoneme.phones[ii + 1]); phones[ii] = phone; } ss.Phonemes = phones; } else if (phoneme.successing != null) { ss.Preceded = false; ss.Successed = true; Phone glide = new Phone(); glide.converProtoPhone(phoneme.phones[phoneme.phones.Length - 1]); ss.Glide = glide; Phone[] phones = new Phone[phoneme.phones.Length - 1]; for (int ii = 0; ii < phones.Length; ii++) { Phone phone = new Phone(); phone.converProtoPhone(phoneme.phones[ii]); phones[ii] = phone; } ss.Phonemes = phones; } else { ss.Preceded = false; ss.Successed = false; Phone[] phones = new Phone[phoneme.phones.Length]; for (int ii = 0; ii < phones.Length; ii++) { Phone phone = new Phone(); phone.converProtoPhone(phoneme.phones[ii]); phones[ii] = phone; } ss.Phonemes = phones; } ss.Transliteration = phoneme.letters; ss.Frequency = phoneme.frequency; return(ss); }
public static SpeechSound deepCopy(SpeechSound other) { SpeechSound result = new SpeechSound(); // result.Phonemes = other.Phonemes; // need change result.Phonemes = new Phone[other.Phonemes.Length]; for (int i = 0; i < other.Phonemes.Length; i++) { result.Phonemes[i] = Phone.deepCopy(other.Phonemes[i]); } result.Glide = Phone.deepCopy(other.Glide); // need change result.Preceded = other.Preceded; result.Successed = other.Successed; result.Transliteration = other.Transliteration; result.Frequency = other.Frequency; return(result); }
public static Word deepCopy(Word other) { Word copy = new Word(); copy.Phonemes = new SpeechSound[other.Phonemes.Length]; for (int i = 0; i < copy.Phonemes.Length; i++) { copy.Phonemes[i] = SpeechSound.deepCopy(other.Phonemes[i]); } if (other.Prefix != null) { copy.Prefix = SpeechSound.deepCopy(other.Prefix); } if (other.Suffix != null) { copy.Suffix = SpeechSound.deepCopy(other.Suffix); } copy.Suffixed = other.Suffixed; copy.Prefixed = other.Prefixed; return(copy); }
private Word generateWord(Morphome rule) { Word result = new Word(); System.Random rnd = new System.Random(); List <SpeechSound> list = new List <SpeechSound>(); int maxLoop = 50; // Pure word if (!rule.AfroAsian) { int specialSyllable = -1; if (rule.SpecialPhone) { specialSyllable = rnd.Next(0, rule.SyllableNumber); if (specialSyllable >= rule.SyllableNumber) { specialSyllable = rule.SyllableNumber - 1; } } for (int i = 0; i < rule.SyllableNumber; i++) { // Check if this is accent syllable bool accented = false; Phone[] accents = null; if (rule.Tones == null || rule.Tones.Length < 1) { accented = false; } else { foreach (Morphome.ToneRequiement tr in rule.Tones) { if (i == tr.Position) { accented = true; accents = tr.Accents; break; } } } accented = accented && accents != null && accents.Length > 0; // If this is the first syllable SpeechSound[] onsets = null; if (i == specialSyllable && rule.SpecialConsonants != null && rule.SpecialConsonants.Length > 0) { onsets = rule.SpecialConsonants; } else if (i == 0) { onsets = WordOnsets; } else { onsets = SyllableOnsets; } double maxOnsetFreq = 0; foreach (SpeechSound ss in onsets) { maxOnsetFreq += ss.Frequency; } bool notOk = true; // If this is the last syllable SpeechSound[] codas = null; if (i == rule.SyllableNumber - 1) { codas = WordCodas; } else { codas = SyllableCodas; } double maxCodaFreq = 0; foreach (SpeechSound ss in codas) { maxCodaFreq += ss.Frequency; } // Repeatively try to make the syllable until it saticify all the requirement int loopNum = 0; while (notOk && loopNum < maxLoop) { loopNum++; // Try to get the onset consonant double checkOnsetFreq = rnd.NextDouble() * maxOnsetFreq; double count = 0.0; SpeechSound chosenOnset = null; foreach (SpeechSound ss in onsets) { count += ss.Frequency; if (count >= checkOnsetFreq) { chosenOnset = SpeechSound.deepCopy(ss); break; } } if (chosenOnset == null) { continue; } // Checkout the list of vowels SpeechSound[] potential = null; if (i == specialSyllable && rule.SpecialVowels != null && rule.SpecialVowels.Length > 0) { potential = rule.SpecialVowels; } if (accented) { potential = StressedVowels; } else { potential = UnstressedVowels; } // Check if the onset require semivowel if (chosenOnset.Successed) { List <SpeechSound> alter = new List <SpeechSound>(); foreach (SpeechSound toCheck in potential) { if (toCheck.Preceded) { if (chosenOnset.Glide.Equals(toCheck.Glide)) { alter.Add(toCheck); } } } if (alter.Count < 1) { continue; } potential = alter.ToArray(); } // Get the vowel SpeechSound vowel = null; double maxVowelFreq = 0; foreach (SpeechSound ss in potential) { maxVowelFreq += ss.Frequency; } double checkVowelFreq = rnd.NextDouble() * maxVowelFreq; count = 0.0; foreach (SpeechSound ss in potential) { count += ss.Frequency; if (count >= checkVowelFreq) { vowel = SpeechSound.deepCopy(ss); break; } } if (vowel == null) { continue; } // Add accent if needed if (accented) { Phone accp = accents[rnd.Next(0, accents.Length)]; vowel.addPhone(accp); string accentTrans = accp.IPA; vowel.Transliteration += accentTrans; } list.Add(chosenOnset); list.Add(vowel); // Get the coda consonant if (codas != null && codas.Length > 0) { double checkCodaFreq = rnd.NextDouble() * maxCodaFreq; count = 0.0; SpeechSound chosenCoda = null; foreach (SpeechSound ss in codas) { count += ss.Frequency; if (count >= checkCodaFreq) { chosenCoda = SpeechSound.deepCopy(ss); break; } } if (chosenCoda == null) { continue; } list.Add(chosenCoda); } notOk = false; } // If the loop number excede the max loop number if (loopNum >= maxLoop) { list.Add(SpeechSound.deepCopy(SyllableOnsets[rnd.Next(0, SyllableOnsets.Length - 1)])); list.Add(SpeechSound.deepCopy(UnstressedVowels[rnd.Next(0, UnstressedVowels.Length - 1)])); if (SyllableCodas != null && SyllableCodas.Length > 0) { list.Add(SpeechSound.deepCopy(SyllableCodas[rnd.Next(0, SyllableCodas.Length - 1)])); } } } if (rule.Affixed) { if (rule.Prefix != null && rule.Prefix.Phonemes.Length > 0) { result.Prefixed = true; result.Prefix = SpeechSound.deepCopy(rule.Prefix); } if (rule.Suffix != null && rule.Suffix.Phonemes.Length > 0) { result.Suffixed = true; result.Suffix = SpeechSound.deepCopy(rule.Suffix); } } } else { // Get all the consonants ready List <SpeechSound> potentialConsonant = new List <SpeechSound>(); SpeechSound[][] allsounds = new SpeechSound[4][]; allsounds[0] = WordCodas; allsounds[1] = WordOnsets; allsounds[2] = SyllableCodas; allsounds[3] = SyllableOnsets; // Pick valid consonants foreach (SpeechSound[] row in allsounds) { foreach (SpeechSound ss in row) { if (ss.Phonemes.Length == 1) { potentialConsonant.Add(SpeechSound.deepCopy(ss)); } else if (ss.Phonemes.Length == 2) { if (ss.Phonemes[ss.Phonemes.Length - 1].Sornority != null && !ss.Phonemes[ss.Phonemes.Length - 1].Sornority.Equals("")) { if (rule.SemivoweledConsonant) { potentialConsonant.Add(SpeechSound.deepCopy(ss)); } } else if (rule.ClusteredConsonant) { potentialConsonant.Add(SpeechSound.deepCopy(ss)); } } else if (ss.Phonemes.Length > 2) { if (ss.Phonemes[ss.Phonemes.Length - 1].Sornority != null && !ss.Phonemes[ss.Phonemes.Length - 1].Sornority.Equals("")) { if (rule.SemivoweledConsonant && rule.ClusteredConsonant) { potentialConsonant.Add(SpeechSound.deepCopy(ss)); } } else if (rule.ClusteredConsonant) { potentialConsonant.Add(SpeechSound.deepCopy(ss)); } } } } // If there is no valid consonants foreach (SpeechSound[] row in allsounds) { foreach (SpeechSound ss in row) { potentialConsonant.Add(SpeechSound.deepCopy(ss)); } } // Make the word double maxFreq = 0; foreach (SpeechSound ss in potentialConsonant) { maxFreq += ss.Frequency; } for (int i = 0; i < rule.HolderVowels.Length; i++) { double checkFreq = rnd.NextDouble() * maxFreq; double count = 0.0; SpeechSound chosen = null; foreach (SpeechSound ss in potentialConsonant) { count += ss.Frequency; if (count >= checkFreq) { chosen = SpeechSound.deepCopy(ss); break; } } if (chosen == null) { chosen = SpeechSound.deepCopy(potentialConsonant.ToArray()[0]); } list.Add(chosen); list.Add(SpeechSound.deepCopy(rule.HolderVowels[i])); } } SpeechSound previous = list[0]; for (int i = 1; i < list.Count; i++) { SpeechSound current = list[i]; if (current.Phonemes.Length == 1 && current.Phonemes[0].IPA != null && current.Phonemes[0].IPA.Equals("'")) { if (previous.Phonemes.Length > 0 && (previous.Phonemes[previous.Phonemes.Length - 1].Openness == null || previous.Phonemes[previous.Phonemes.Length - 1].Openness.Equals(""))) { list.RemoveAt(i); i--; } } } result.Phonemes = list.ToArray(); return(result); }
public Word changeWord(Word input) { if (input == null) { return(null); } List <Phone> list = new List <Phone>(); if (IncludeAffix && input.Prefixed && input.Prefix != null) { if (input.Prefix.Phonemes != null) { list.AddRange(input.Prefix.Phonemes); } } foreach (SpeechSound ss in input.Phonemes) { if (ss.Preceded) { list.Add(ss.Glide); } foreach (Phone p in ss.Phonemes) { list.Add(p); } if (ss.Successed) { list.Add(ss.Glide); } } if (IncludeAffix && input.Suffixed && input.Suffix != null) { if (input.Suffix.Phonemes != null) { list.AddRange(input.Suffix.Phonemes); } } // Debug.Log(list.Count); // TODO... // find the target pattern // change the target pattern to the desired pattern Manager manager = UnityEngine.Object.FindObjectOfType <Manager>(); PhoneManager phoneManager = manager.phoneManager; int i = 0; while (i < list.Count) { if (list[i].Level != null && !list[i].Level.Equals("")) { i++; continue; } bool fullMatch = true; int length = 0; // Find the target parttern List <List <Phone> > founded = new List <List <Phone> >(); for (int j = 0; j < Target.Length; j++) { // If this require an initial position if (Target[j].Initial) { if (i + length == 0) { founded.Add(new List <Phone>()); } else { fullMatch = false; break; } } // If this requires a terminal position else if (Target[j].Terminal) { Debug.Log("in branch"); if (i + length == list.Count) { Debug.Log("find end"); founded.Add(new List <Phone>()); } else { fullMatch = false; break; } } // If this is a single vowel else if (Target[j].SingleHolder && Target[j].Type.Contains("w")) { List <Phone> tem = new List <Phone>(); if (i + length >= list.Count) { fullMatch = false; break; } if (list[i + length].Openness != null && !list[i + length].Openness.Equals("")) { tem.Add(list[i + length]); length++; if (i + length < list.Count && list[i + length].Level != null && !list[i + length].Level.Equals("")) { tem.Add(list[i + length]); length++; } founded.Add(tem); } else { fullMatch = false; break; } } // If this is a single consonant else if (Target[j].SingleHolder && Target[j].Type.Contains("n")) { List <Phone> tem = new List <Phone>(); if (i + length >= list.Count) { fullMatch = false; break; } if (list[i + length].MOA != null && !list[i + length].MOA.Equals("")) { tem.Add(list[i + length]); length++; founded.Add(tem); } else { fullMatch = false; break; } } // If this is a vowel cluster else if (Target[j].MultipleHolder && Target[j].Type.Contains("w")) { List <Phone> tem = new List <Phone>(); int count = 0; if (i + length >= list.Count) { fullMatch = false; break; } while (i + length < list.Count && list[i + length].Openness != null && !list[i + length].Openness.Equals("")) { count++; tem.Add(list[i + length]); length++; if (i + length < list.Count && list[i + length].Level != null && !list[i + length].Level.Equals("")) { tem.Add(list[i + length]); length++; } } if (count != 0) { founded.Add(tem); } else { fullMatch = false; break; } } // If this is a consonant cluster else if (Target[j].MultipleHolder && Target[j].Type.Contains("n")) { List <Phone> tem = new List <Phone>(); int count = 0; if (i + length >= list.Count) { fullMatch = false; break; } while (i + length < list.Count && list[i + length].POA != null && !list[i + length].POA.Equals("")) { count++; tem.Add(list[i + length]); length++; } if (count != 0) { founded.Add(tem); } else { fullMatch = false; break; } } // If this is a specified vowel else if (Target[j].Type.Contains("w")) { List <Phone> tem = new List <Phone>(); if (i + length >= list.Count || list[i + length].Openness == null || list[i + length].Openness.Equals("")) { fullMatch = false; break; } int row = Target[j].Roundness; int column = Target[j].Openness; bool isOpen = false, isRound = false; if (row >= phoneManager.vowelPool.Length) { isRound = true; } else if (row >= 0) { int poolIndex = 0; while (poolIndex < phoneManager.vowelPool[row].Length) { if (phoneManager.vowelPool[row][poolIndex] != null) { if (list[i + length].Roundness.Equals(phoneManager.vowelPool[row][poolIndex].Roundness)) { if (list[i + length].FCB.Equals(phoneManager.vowelPool[row][poolIndex].FCB)) { isRound = true; } } break; } poolIndex++; } } if (column >= phoneManager.vowelPool[0].Length) { isOpen = true; } else if (column >= 0) { int poolIndex = 0; while (poolIndex < phoneManager.vowelPool.Length) { if (phoneManager.vowelPool[poolIndex][column] != null) { if (list[i + length].Openness.Equals(phoneManager.vowelPool[poolIndex][column].Openness)) { isOpen = true; } break; } poolIndex++; } } if (isRound && isOpen) { tem.Add(list[i + length]); length++; if (i + length < list.Count && list[i + length].Level != null && !list[i + length].Level.Equals("")) { tem.Add(list[i + length]); length++; } founded.Add(tem); } else { fullMatch = false; break; } } // If this is a specified consonant else if (Target[j].Type.Contains("n")) { List <Phone> tem = new List <Phone>(); if (i + length >= list.Count || list[i + length].MOA == null || list[i + length].MOA.Equals("")) { fullMatch = false; break; } int row = Target[j].POA; int column = Target[j].MOA; bool isPOA = false, isMOA = false; if (row >= phoneManager.consonantPool.Length) { isPOA = true; } else if (row >= 0) { int poolIndex = 0; while (poolIndex < phoneManager.consonantPool[row].Length) { if (phoneManager.consonantPool[row][poolIndex] != null) { if (list[i + length].POA.Equals(phoneManager.consonantPool[row][poolIndex].POA)) { isPOA = true; } break; } poolIndex++; } } if (column >= phoneManager.consonantPool[0].Length) { isMOA = true; } else if (column >= 0) { int poolIndex = 0; while (poolIndex < phoneManager.consonantPool.Length) { if (phoneManager.consonantPool[poolIndex][column] != null) { if (list[i + length].MOA.Equals(phoneManager.consonantPool[poolIndex][column].MOA)) { if (list[i + length].Aspiration.Equals(phoneManager.consonantPool[poolIndex][column].Aspiration)) { if (list[i + length].Voiceness.Equals(phoneManager.consonantPool[poolIndex][column].Voiceness)) { isMOA = true; } } } break; } poolIndex++; } } if (isPOA && isMOA) { tem.Add(list[i + length]); length++; founded.Add(tem); } else { fullMatch = false; break; } } // If this is a specified glide else if (Target[j].Type.Contains("d")) { List <Phone> tem = new List <Phone>(); if (i + length >= list.Count || list[i + length].Sornority == null || list[i + length].Sornority.Equals("")) { fullMatch = false; break; } int row = Target[j].GlideIndex; bool isPOA = false; if (row >= phoneManager.semivowelPool.Length) { isPOA = true; } else if (row >= 0) { if (phoneManager.semivowelPool[row] != null) { if (list[i + length].IPA.Equals(phoneManager.semivowelPool[row].IPA)) { isPOA = true; } } } if (isPOA) { tem.Add(list[i + length]); length++; founded.Add(tem); } else { fullMatch = false; break; } } // Back up case, should not be used else { fullMatch = false; break; } } // If the pattern is found, then process it if (fullMatch) { Debug.Log("matched"); // First, parse the original list to have the first part and the last part List <Phone> head = new List <Phone>(), tail = new List <Phone>(); for (int j = 0; j < i; j++) { head.Add(list[j]); } for (int j = i + length; j < list.Count; j++) { tail.Add(list[j]); } // Then build up the middle part List <List <Phone> > middle = new List <List <Phone> >(); for (int j = 0; j < Result.Length; j++) { MetaBlock block = Result[j]; // if the meta block is empty, then make the corresponding part empty if (block.Descriptions.Length == 0) { middle.Add(new List <Phone>()); } // if the meta block is not empty, then build up the list else { List <Phone> tem = new List <Phone>(); bool getAccent = false; foreach (Description description in block.Descriptions) { // if the description is unchanged if (description.Unchanged) { tem.AddRange(founded[j]); } // if the description is a specified vowel else if (description.Type.Contains("w")) { int row = -1, column = -1; // check out the row/roundedness of the vowel // if the vowel is copying old roundness if (description.DimensionTwo) { string roundedness = founded[description.Roundness][0].Roundness; Debug.Log(founded[description.Roundness][0]); for (int k = 0; k < phoneManager.vowelPool.Length; k++) { if (roundedness.Equals(phoneManager.vowelPool[k][0].Roundness)) { row = k; break; } } } // if the vowel specifying new roundness else { row = description.Roundness; } // check out the column/openness of the vowel if (description.DimensionOne) { string openness = founded[description.Openness][0].Openness; for (int k = 0; k < phoneManager.vowelPool[0].Length; k++) { if (phoneManager.vowelPool[0][k] != null && openness.Equals(phoneManager.vowelPool[0][k].Openness)) { if (founded[description.Openness][0].FCB.Equals(phoneManager.vowelPool[0][k].FCB)) { column = k; break; } } } } // if the vowel specifying new roundness else { column = description.Openness; } // check out the phone from phone pool if (description.DimensionTwo && description.DimensionOne && description.Roundness == description.Openness) { tem.Add(founded[description.Roundness][0]); } else if (!(row < 0 || column < 0 || row >= phoneManager.vowelPool.Length || column >= phoneManager.vowelPool[0].Length)) { Debug.Log(phoneManager.vowelPool[row][column]); if (phoneManager.vowelPool[row][column] != null) { Phone newPhone = new Phone(); newPhone.converProtoPhone(phoneManager.vowelPool[row][column]); tem.Add(newPhone); } } Debug.Log(tem.Count); } // if the description is a specified consonant else if (description.Type.Contains("n")) { int row = -1, column = -1; // check out the row/roundedness of the vowel // if the vowel is copying old roundness if (description.DimensionTwo) { string poa = founded[description.POA][0].POA; for (int k = 0; k < phoneManager.consonantPool.Length; k++) { if (phoneManager.consonantPool[k][0] != null && poa.Equals(phoneManager.consonantPool[k][0].POA)) { row = k; break; } } } // if the vowel specifying new roundness else { row = description.POA; } // check out the column/openness of the vowel if (description.DimensionTwo && description.DimensionOne && description.MOA == description.POA) { tem.Add(founded[description.MOA][0]); } else if (description.DimensionOne) { string moa = founded[description.MOA][0].MOA; for (int k = 0; k < phoneManager.consonantPool[0].Length; k++) { if (phoneManager.consonantPool[0][k] != null && moa.Equals(phoneManager.consonantPool[0][k].MOA)) { if (founded[description.MOA][0].Aspiration.Equals(phoneManager.consonantPool[0][k].Aspiration)) { if (founded[description.MOA][0].Voiceness.Equals(phoneManager.consonantPool[0][k].Voiceness)) { column = k; break; } } } } } // if the vowel specifying new roundness else { column = description.MOA; } // check out the phone from phone pool if (!(row < 0 || column < 0 || row >= phoneManager.consonantPool.Length || column >= phoneManager.consonantPool[0].Length)) { if (phoneManager.consonantPool[row][column] != null) { Phone newPhone = new Phone(); newPhone.converProtoPhone(phoneManager.consonantPool[row][column]); tem.Add(newPhone); } } Debug.Log(tem.Count); } // if the description is a specified consonant else if (description.Type.Contains("d")) { Phone newPhone = new Phone(); newPhone.converProtoPhone(phoneManager.semivowelPool[description.GlideIndex % phoneManager.semivowelPool.Length]); tem.Add(newPhone); } // back up case, this should not be used else { tem.Clear(); tem.AddRange(founded[j]); break; } foreach (Phone p in tem) { if (p.Level != null && !p.Level.Equals("")) { getAccent = true; } } bool originalHasAccent = false; Phone accent = null; foreach (Phone p in founded[j]) { if (p.Level != null && !p.Level.Equals("")) { originalHasAccent = true; accent = p; } } Debug.Log(originalHasAccent); Debug.Log(getAccent); if (!getAccent && originalHasAccent) { for (int k = 0; k < tem.Count; k++) { if (tem[k].Openness != null && !tem[k].Openness.Equals("")) { tem.Insert(k + 1, accent); break; } } } } middle.Add(tem); } } // Now, all three parts has been built, it is time to create a new list List <Phone> newList = new List <Phone>(); newList.AddRange(head); for (int j = 0; j < middle.Count; j++) { newList.AddRange(middle[j]); } int newIndex = newList.Count; i = newIndex - 1 > i + 1 ? newIndex - 1 : i + 1; newList.AddRange(tail); list = newList; } i++; } Word result = new Word(); if (IncludeAffix) { result.Suffix = null; result.Prefix = null; result.Suffixed = false; result.Prefixed = false; } else { result.Suffix = input.Suffix; result.Prefix = input.Prefix; result.Suffixed = input.Suffixed; result.Prefixed = input.Prefixed; } result.Phonemes = new SpeechSound[list.Count]; for (i = 0; i < list.Count; i++) { SpeechSound ss = new SpeechSound(); ss.Phonemes = new Phone[1]; ss.Phonemes[0] = list[i]; ss.Glide = null; ss.Preceded = false; ss.Successed = false; ss.Transliteration = list[i].IPA; ss.Frequency = 0; result.Phonemes[i] = ss; } return(result); }
public void createLangauge() { LanguageFamily newLanguageFamily = new LanguageFamily(); Manager manager = Object.FindObjectOfType <Manager>(); LanguageManager languageManager = manager.languageManager; newLanguageFamily.Name = languageManager.languageName; // Get consonants and vowels into the new language family object Phoneme[][] allPhonemes = new Phoneme[6][]; allPhonemes[0] = languageManager.consonantBoW; allPhonemes[1] = languageManager.consonantBoS; allPhonemes[2] = languageManager.consonantEoS; allPhonemes[3] = languageManager.consonantEoW; allPhonemes[4] = languageManager.vowelAS; allPhonemes[5] = languageManager.vowelUS; for (int i = 0; i < allPhonemes.Length; i++) { // Create new array of speech sounds SpeechSound[] speechSounds; if (i == 0) { newLanguageFamily.WordOnsets = new SpeechSound[allPhonemes[i].Length]; speechSounds = newLanguageFamily.WordOnsets; } else if (i == 1) { newLanguageFamily.SyllableOnsets = new SpeechSound[allPhonemes[i].Length]; speechSounds = newLanguageFamily.SyllableOnsets; } else if (i == 2) { newLanguageFamily.SyllableCodas = new SpeechSound[allPhonemes[i].Length]; speechSounds = newLanguageFamily.SyllableCodas; } else if (i == 3) { newLanguageFamily.WordCodas = new SpeechSound[allPhonemes[i].Length]; speechSounds = newLanguageFamily.WordCodas; } else if (i == 4) { newLanguageFamily.StressedVowels = new SpeechSound[allPhonemes[i].Length]; speechSounds = newLanguageFamily.StressedVowels; } else { newLanguageFamily.UnstressedVowels = new SpeechSound[allPhonemes[i].Length]; speechSounds = newLanguageFamily.UnstressedVowels; } for (int j = 0; j < allPhonemes[i].Length; j++) { Phoneme phoneme = allPhonemes[i][j]; SpeechSound ss = new SpeechSound(); if (phoneme.preceding != null) { ss.Preceded = true; ss.Successed = false; Phone glide = new Phone(); glide.converProtoPhone(phoneme.phones[0]); ss.Glide = glide; Phone[] phones = new Phone[phoneme.phones.Length - 1]; for (int ii = 0; ii < phones.Length; ii++) { Phone phone = new Phone(); phone.converProtoPhone(phoneme.phones[ii + 1]); phones[ii] = phone; } ss.Phonemes = phones; } else if (phoneme.successing != null) { ss.Preceded = false; ss.Successed = true; Phone glide = new Phone(); glide.converProtoPhone(phoneme.phones[phoneme.phones.Length - 1]); ss.Glide = glide; Phone[] phones = new Phone[phoneme.phones.Length - 1]; for (int ii = 0; ii < phones.Length; ii++) { Phone phone = new Phone(); phone.converProtoPhone(phoneme.phones[ii]); phones[ii] = phone; } ss.Phonemes = phones; } else { ss.Preceded = false; ss.Successed = false; Phone[] phones = new Phone[phoneme.phones.Length]; for (int ii = 0; ii < phones.Length; ii++) { Phone phone = new Phone(); phone.converProtoPhone(phoneme.phones[ii]); phones[ii] = phone; } ss.Phonemes = phones; } ss.Transliteration = phoneme.letters; ss.Frequency = phoneme.frequency; speechSounds[j] = ss; } } // Get accents into the new language family object Phone[] accents = new Phone[languageManager.accents.Length]; for (int i = 0; i < languageManager.accents.Length; i++) { Phone accent = new Phone(); accent.converProtoPhone(languageManager.accents[i]); } newLanguageFamily.Accents = accents; // Get all the accent rule // generalPanel, VerbPanerl, NounPanel, AdjectivePanel; // Nouns, Adjectives; newLanguageFamily.Generals = getOnePartOfSpeech(generalPanel); newLanguageFamily.Verbs = getOnePartOfSpeech(VerbPanerl); newLanguageFamily.Nouns = getOnePartOfSpeech(NounPanel); newLanguageFamily.Adjectives = getOnePartOfSpeech(AdjectivePanel); // WordOnsets, WordCodas, SyllableOnsets, SyllableCodas, StressedVowels, UnstressedVowels; //consonantBoW, consonantBoS, consonantEoS, consonantEoW; //public Phoneme[] vowelAS, vowelUS; string vocabPath = "/Files/Customization/" + newLanguageFamily.Name; Debug.Log(vocabPath); if (!System.IO.Directory.Exists(Application.dataPath + vocabPath)) { System.IO.Directory.CreateDirectory(Application.dataPath + vocabPath); } newLanguageFamily.Directory = vocabPath; SoundChange rootChange = new SoundChange(); rootChange.Name = newLanguageFamily.Name; rootChange.Directory = vocabPath + "/change_rule/"; if (!System.IO.Directory.Exists(Application.dataPath + rootChange.Directory)) { System.IO.Directory.CreateDirectory(Application.dataPath + rootChange.Directory); } rootChange.Directory = vocabPath + "/change_rule/root"; rootChange.Branches = new string[0]; rootChange.Rules = new Sandhi[0]; newLanguageFamily.Root = rootChange; string langaugeData = JsonUtility.ToJson(newLanguageFamily); System.IO.File.WriteAllText(Application.dataPath + "/Files/Customization/Languages/" + newLanguageFamily.Name + ".languageFamily", langaugeData); // Set the new language to the manager manager.currentLanguage = newLanguageFamily; // Jump to next scenes SceneManager.LoadScene("LanguageScreen"); }