Skip to content

Commit

Permalink
Merge pull request #806 from lottev1991/CvvcFallbackSemiFix
Browse files Browse the repository at this point in the history
[JA CVVC & Presamp] Semi-fix for voice color fallbacks
  • Loading branch information
stakira authored Sep 2, 2023
2 parents 29ea5b0 + ffab03d commit 950f686
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 7 deletions.
36 changes: 35 additions & 1 deletion OpenUtau.Plugin.Builtin/JapaneseCVVCPhonemizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,39 @@ static JapaneseCVVCPhonemizer() {
private bool checkOtoUntilHit(string[] input, Note note, out UOto oto) {
oto = default;
var attr = note.phonemeAttributes?.FirstOrDefault(attr => attr.index == 0) ?? default;
var attr1 = note.phonemeAttributes?.FirstOrDefault(attr => attr.index == 1) ?? default;

var otos = new List<UOto>();
foreach (string test in input) {
if (singer.TryGetMappedOto(test + attr.alternate, note.tone + attr.toneShift, attr.voiceColor, out var otoAlt)) {
otos.Add(otoAlt);
} else if (singer.TryGetMappedOto(test, note.tone + attr.toneShift, attr.voiceColor, out var otoCandidacy)) {
otos.Add(otoCandidacy);
}
}

string color = attr.voiceColor ?? "";
if (otos.Count > 0) {
if (otos.Any(oto => (oto.Color ?? string.Empty) == color)) {
oto = otos.Find(oto => (oto.Color ?? string.Empty) == color);
return true;
} else if (otos.Any(oto => (color ?? string.Empty) == color)) {
oto = otos.Find(oto => (color ?? string.Empty) == color);
return true;
} else {
return false;
}
}
return false;
}

// checking VCs
// when VC does not exist, it will not be inserted
// TODO: fix duplicate voice color fallback bug (for now, this is better than nothing)
private bool checkOtoUntilHitVc(string[] input, Note note, out UOto oto) {
oto = default;
var attr = note.phonemeAttributes?.FirstOrDefault(attr => attr.index == 0) ?? default;
var attr1 = note.phonemeAttributes?.FirstOrDefault(attr => attr.index == 1) ?? default;

var otos = new List<UOto>();
foreach (string test in input) {
Expand All @@ -125,6 +158,7 @@ private bool checkOtoUntilHit(string[] input, Note note, out UOto oto) {
return false;
}


// can probably be cleaned up more but i have work in the morning. have fun.
public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevNeighbour, Note? nextNeighbour, Note[] prevNeighbours) {
var note = notes[0];
Expand Down Expand Up @@ -217,7 +251,7 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN
vcPhonemes[1] = $"{vowel} {con}";
}
//if (singer.TryGetMappedOto(vcPhoneme, note.tone + attr0.toneShift, attr0.voiceColor, out var oto1)) {
if (checkOtoUntilHit(vcPhonemes, note, out var oto1)) {
if (checkOtoUntilHitVc(vcPhonemes, note, out var oto1)) {
vcPhoneme = oto1.Alias;
} else {
return new Result {
Expand Down
45 changes: 39 additions & 6 deletions OpenUtau.Plugin.Builtin/JapanesePresampPhonemizer.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using Classic;
using OpenUtau.Api;
using OpenUtau.Classic;
using OpenUtau.Core.Ustx;

namespace OpenUtau.Plugin.Builtin {
Expand All @@ -20,7 +18,7 @@ public class JapanesePresampPhonemizer : Phonemizer {
// Partial supporting: [NUM][APPEND][PITCH] -> Using to exclude useless characters in lyrics

// in case voicebank is missing certain symbols
static readonly string[] substitution = new string[] {
static readonly string[] substitution = new string[] {
"ty,ch,ts=t", "j,dy=d", "gy=g", "ky=k", "py=p", "ny=n", "ry=r", "my=m", "hy,f=h", "by,v=b", "dz=z", "l=r", "ly=l"
};

Expand Down Expand Up @@ -200,7 +198,7 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN
}
// next is CV (VC needed)
tests = new List<string> { $"{vowel}{vcpad}" };
if (checkOtoUntilHit(tests, note, out oto1)) {
if (checkOtoUntilHitVc(tests, note, out oto1)) {
vcPhoneme = oto1.Alias;
} else {
return MakeSimpleResult(currentLyric);
Expand All @@ -226,14 +224,19 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN
}
}

var otos = new List<UOto>();
var attr = note.phonemeAttributes?.FirstOrDefault(attr => attr.index == 0) ?? default;
string color = attr.voiceColor ?? "";

// Insert VC before next neighbor
vcPhoneme = $"{vowel}{vcpad}{consonant}";
var vcPhonemes = new List<string> { vcPhoneme };
// find potential substitute symbol
if (substituteLookup.TryGetValue(consonant ?? string.Empty, out var con)) {
vcPhonemes.Add($"{vowel}{vcpad}{con}");
}
if (checkOtoUntilHit(vcPhonemes, note, out var oto)) {
if (checkOtoUntilHitVc(vcPhonemes, note, out var oto)) {
otos.Any(oto => (oto.Color ?? string.Empty) == color);
vcPhoneme = oto.Alias;
} else {
return MakeSimpleResult(currentLyric);
Expand Down Expand Up @@ -290,12 +293,42 @@ private bool checkOtoUntilHit(List<string> input, Note note, out UOto oto) {
if (otos.Any(oto => (oto.Color ?? string.Empty) == color)) {
oto = otos.Find(oto => (oto.Color ?? string.Empty) == color);
return true;
} else if (otos.Any(oto => (color ?? string.Empty) == color)) {
oto = otos.Find(oto => (color ?? string.Empty) == color);
return true;
} else {
return false;
}
}
return false;
}

// checking VCs
// when VC does not exist, it will not be inserted
// TODO: fix duplicate voice color fallback bug (for now, this is better than nothing)
private bool checkOtoUntilHitVc(List<string> input, Note note, out UOto oto) {
oto = default;
var attr = note.phonemeAttributes?.FirstOrDefault(attr => attr.index == 0) ?? default;

var otos = new List<UOto>();
foreach (string test in input) {
if (singer.TryGetMappedOto(test + attr.alternate, note.tone + attr.toneShift, attr.voiceColor, out var otoAlt)) {
otos.Add(otoAlt);
} else if (singer.TryGetMappedOto(test, note.tone + attr.toneShift, attr.voiceColor, out var otoCandidacy)) {
otos.Add(otoCandidacy);
}
}

string color = attr.voiceColor ?? "";
if (otos.Count > 0) {
if (otos.Any(oto => (oto.Color ?? string.Empty) == color)) {
oto = otos.Find(oto => (oto.Color ?? string.Empty) == color);
return true;
} else {
return false;
}
}
return false;
}
}
}
}

0 comments on commit 950f686

Please sign in to comment.