Skip to content

Commit

Permalink
added file
Browse files Browse the repository at this point in the history
  • Loading branch information
EX3exp committed May 10, 2024
1 parent 54373a4 commit e889dfd
Showing 1 changed file with 54 additions and 58 deletions.
112 changes: 54 additions & 58 deletions OpenUtau.Core/KoreanPhonemizerUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using OpenUtau.Classic;
using Serilog;
using static OpenUtau.Api.Phonemizer;
using OpenUtau.Api;

namespace OpenUtau.Core {
/// <summary>
Expand Down Expand Up @@ -177,20 +178,20 @@ public static Hashtable Separate(string character) {
}

/// <summary>
/// merges separated hangeul into complete hangeul. (Example: {[0]: "ㄱ", [1]: "ㅏ", [2]: " "} => "가"})
/// merges separated hangeul into complete hangeul. (Example: {[offset + 0]: "ㄱ", [offset + 1]: "ㅏ", [offset + 2]: " "} => "가"})
/// <para>자모로 쪼개진 한글을 합쳐진 한글로 반환합니다.</para>
/// </summary>
/// <param name="separated">separated Hangeul. </param>
/// <returns>Returns complete Hangeul Character.</returns>
public static string Merge(Hashtable separatedHangeul){
public static string Merge(Hashtable separatedHangeul, int offset = 0){

int firstConsonantIndex; // (ex) 2
int middleVowelIndex; // (ex) 2
int lastConsonantIndex; // (ex) 21

char firstConsonant = ((string)separatedHangeul[0])[0]; // (ex) "ㄴ"
char middleVowel = ((string)separatedHangeul[1])[0]; // (ex) "ㅑ"
char lastConsonant = ((string)separatedHangeul[2])[0]; // (ex) "ㅇ"
char firstConsonant = ((string)separatedHangeul[offset + 0])[0]; // (ex) "ㄴ"
char middleVowel = ((string)separatedHangeul[offset + 1])[0]; // (ex) "ㅑ"
char lastConsonant = ((string)separatedHangeul[offset + 2])[0]; // (ex) "ㅇ"

if (firstConsonant == ' ') {firstConsonant = 'ㅇ';}

Expand Down Expand Up @@ -371,7 +372,7 @@ private static Hashtable Variate(Hashtable firstCharSeparated, Hashtable nextCha
nextFirstConsonant = "ㅇ";
}

if ((!firstLastConsonant.Equals("")) && nextFirstConsonant.Equals("ㅇ") && (!firstLastConsonant.Equals("ㅇ"))) {
if ((!firstLastConsonant.Equals(" ")) && nextFirstConsonant.Equals("ㅇ") && (!firstLastConsonant.Equals("ㅇ"))) {
// 연음 2
nextFirstConsonant = firstLastConsonant;
firstLastConsonant = " ";
Expand Down Expand Up @@ -919,10 +920,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, thisNoteSeparated[4]);
result.Add(8, thisNoteSeparated[5]);

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]});
return Merge(result, 3);
}
}
else if ((lyrics[0] != null) && (lyrics[2] == null)) {
Expand All @@ -941,10 +939,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, "null");
result.Add(8, "null");

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]});
return Merge(result, 3);
}
else if (whereYeonEum == 0) {
// 앞 노트에서 단어가 끝났다고 가정
Expand All @@ -959,10 +954,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, "null");
result.Add(8, "null");

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]});
return Merge(result, 3);
}
else {
Hashtable result = Variate(lyrics[0], lyrics[1], 0); // 첫 글자
Expand All @@ -976,10 +968,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, "null");
result.Add(8, "null");

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]});
return Merge(result, 3);
}
}
else if ((lyrics[0] != null) && (lyrics[2] != null)) {
Expand All @@ -998,10 +987,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, thisNoteSeparated[4]);
result.Add(8, thisNoteSeparated[5]);

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]});
return Merge(result, 3);
}
else if (whereYeonEum == 0) {
// 앞 노트에서 단어가 끝났다고 가정 / 릎. [위] 놓
Expand All @@ -1016,10 +1002,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, thisNoteSeparated[4]);
result.Add(8, thisNoteSeparated[5]);

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]});
return Merge(result, 3);
}
else {
Hashtable result = Variate(lyrics[0], lyrics[1], 0);
Expand All @@ -1033,10 +1016,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, thisNoteSeparated[4]);
result.Add(8, thisNoteSeparated[5]);

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]});
return Merge(result, 3);
}
}
else {
Expand All @@ -1060,11 +1040,7 @@ public static String Variate(String? prevNeighbour, String note, String? nextNei
result.Add(7, "null");
result.Add(8, "null");

return Merge(new Hashtable{
[0] = (string)result[3],
[1] = (string)result[4],
[2] = (string)result[5]
});
return Merge(result, 3);
}
}

Expand All @@ -1081,21 +1057,41 @@ public static Note[] ChangeLyric(Note[] group, string lyric) {
};
return group;
}
public static void RomanizeNotes(Note[][] groups, Dictionary<string, string[]> firstConsonants, Dictionary<string, string[]> vowels, Dictionary<string, string[]> lastConsonants, string semivowelSeparator=" ") {
// for ENUNU Phonemizer


public static void ModifyLyrics(Hashtable lyricSeparated,string lyric, Dictionary<string, string[]> firstConsonants, Dictionary<string, string[]> vowels, Dictionary<string, string[]> lastConsonants, string semivowelSeparator){
lyric += firstConsonants[(string)lyricSeparated[3]][0];
if (vowels[(string)lyricSeparated[4]][1] != "") {
// this vowel contains semivowel
lyric += semivowelSeparator + vowels[(string)lyricSeparated[4]][1] + vowels[(string)lyricSeparated[4]][2];
}
else{
lyric += " " + vowels[(string)lyricSeparated[4]][2];
}

lyric += lastConsonants[(string)lyricSeparated[5]][0];
}

public static void RomanizeNotes(Note[][] groups, bool _modifyLyrics = false, Dictionary<string, string[]> firstConsonants = null, Dictionary<string, string[]> vowels = null, Dictionary<string, string[]> lastConsonants = null, string semivowelSeparator = " ") {
// for ENUNU & DIFFS Phonemizer

int noteIdx = 0;
string lyric;
bool modifyLyrics = (!_modifyLyrics || firstConsonants == null || vowels == null || lastConsonants == null) ? false : true;

Note[] currentNote;
Note[]? prevNote = null;
Note[]? nextNote;

Note? prevNote_;
Note? nextNote_;


List<string> ResultLyrics = new List<string>();

foreach (Note[] group in groups){
currentNote = groups[noteIdx];
string originalLyric; // uses this when no variation needed
originalLyric = currentNote[0].lyric;

if (groups.Length > noteIdx + 1 && IsHangeul(groups[noteIdx + 1][0].lyric)) {
nextNote = groups[noteIdx + 1];
}
Expand All @@ -1120,7 +1116,7 @@ public static void RomanizeNotes(Note[][] groups, Dictionary<string, string[]> f
}
else{nextNote_ = null;}

string lyric = "";
lyric = originalLyric;

if (! IsHangeul(currentNote[0].lyric)){
ResultLyrics.Add(currentNote[0].lyric);
Expand All @@ -1129,27 +1125,27 @@ public static void RomanizeNotes(Note[][] groups, Dictionary<string, string[]> f
continue;
}

Hashtable lyricSeparated = Variate(prevNote_, currentNote[0], nextNote_);
lyric += firstConsonants[(string)lyricSeparated[3]][0];
if (vowels[(string)lyricSeparated[4]][1] != "") {
// this vowel contains semivowel
lyric += semivowelSeparator + vowels[(string)lyricSeparated[4]][1] + vowels[(string)lyricSeparated[4]][2];
}
else{
lyric += " " + vowels[(string)lyricSeparated[4]][2];
}

lyric += lastConsonants[(string)lyricSeparated[5]][0];

Hashtable lyricSeparated = Variate(prevNote_, currentNote[0], nextNote_);

ResultLyrics.Add(lyric.Trim());
if (modifyLyrics) {
ModifyLyrics(lyricSeparated, lyric, firstConsonants, vowels, lastConsonants, semivowelSeparator);
}
else {
lyric = Merge(lyricSeparated, 3);
}

ResultLyrics.Add(lyric.Trim());

prevNote = currentNote;
prevNote = currentNote;

noteIdx++;
noteIdx++;

}
Enumerable.Zip(groups, ResultLyrics.ToArray(), ChangeLyric).Last();
}


/// <summary>
/// abstract class for Ini Management
/// To use, child phonemizer should implement this class(BaseIniManager) with its own setting values!
Expand Down

0 comments on commit e889dfd

Please sign in to comment.