From 1d59f7c31680d35c8d4d61ccf178e097a6de2d36 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Fri, 17 Nov 2023 13:42:29 +0100 Subject: [PATCH 1/4] CV oto fix --- OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs index 1860b2164..322165f89 100644 --- a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs @@ -38,18 +38,24 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN return MakeSimpleResult(oto.Alias); } int vcLen = 120; - if (singer.TryGetMappedOto(lyric, notes[0].tone + attr0.toneShift, attr0.voiceColor, out var cvOto)) { + if (singer.TryGetMappedOto(lyric, notes[0].tone + attr1.toneShift, attr1.voiceColor, out var cvOto)) { vcLen = MsToTick(cvOto.Preutter); if (cvOto.Overlap == 0 && vcLen < 120) { vcLen = Math.Min(120, vcLen * 2); // explosive consonant with short preutter. } } var vcPhoneme = $"{prevVowel} {consonant}"; - if (singer.TryGetMappedOto(vcPhoneme, prevNeighbour.Value.tone + attr0.toneShift, attr0.voiceColor, out oto)) { - vcPhoneme = oto.Alias; + if (prevNeighbour != null) { + if (singer.TryGetMappedOto(vcPhoneme, prevNeighbour.Value.tone + attr0.toneShift, attr0.voiceColor, out oto)) { + vcPhoneme = oto.Alias; + } + } else { + if (singer.TryGetMappedOto(vcPhoneme, notes[0].tone + attr0.toneShift, attr0.voiceColor, out oto)) { + vcPhoneme = oto.Alias; + } } - if (singer.TryGetMappedOto(vcPhoneme, prevNeighbour.Value.tone + attr0.toneShift, attr0.voiceColor, out oto)) { + if (singer.TryGetMappedOto(vcPhoneme, notes[0].tone + attr0.toneShift, attr0.voiceColor, out oto)) { return new Result { phonemes = new Phoneme[] { new Phoneme() { From 583ebd0299ec3ed4c1246c43ffeff70bc89f9b3f Mon Sep 17 00:00:00 2001 From: Lotte V Date: Fri, 17 Nov 2023 14:09:01 +0100 Subject: [PATCH 2/4] Remove unused code --- OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs index 322165f89..fcb03b600 100644 --- a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs @@ -33,7 +33,6 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN } return MakeSimpleResult($"{prevVowel} R"); } - int totalDuration = notes.Sum(n => n.duration); if (singer.TryGetMappedOto($"{prevVowel} {lyric}", notes[0].tone + attr0.toneShift, attr0.voiceColor, out var oto)) { return MakeSimpleResult(oto.Alias); } From 667392d479dfef3dbfd0266afbd04b0e677c62fd Mon Sep 17 00:00:00 2001 From: Lotte V Date: Mon, 20 Nov 2023 00:06:46 +0100 Subject: [PATCH 3/4] Calculate VC length based on velocity --- OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs index fcb03b600..64909ba79 100644 --- a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs @@ -48,10 +48,16 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN if (singer.TryGetMappedOto(vcPhoneme, prevNeighbour.Value.tone + attr0.toneShift, attr0.voiceColor, out oto)) { vcPhoneme = oto.Alias; } + // totalDuration calculated on basis of previous note length + int totalDuration = prevNeighbour.Value.duration; + // vcLength depends on the Vel of the current base note + vcLen = Convert.ToInt32(Math.Min(totalDuration / 1.5, Math.Max(60, vcLen * (attr1.consonantStretchRatio ?? 1)))); } else { if (singer.TryGetMappedOto(vcPhoneme, notes[0].tone + attr0.toneShift, attr0.voiceColor, out oto)) { vcPhoneme = oto.Alias; } + // no previous note, so length can be minimum velocity regardless of oto + vcLen = Convert.ToInt32(Math.Min(vcLen * 2, Math.Max(60, vcLen * (attr1.consonantStretchRatio ?? 1)))); } if (singer.TryGetMappedOto(vcPhoneme, notes[0].tone + attr0.toneShift, attr0.voiceColor, out oto)) { From a3fd2ee258a8f29afc91a127da99d66c98478086 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Mon, 20 Nov 2023 21:38:17 +0100 Subject: [PATCH 4/4] Negative overlap + minimum length 30 --- OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs index 64909ba79..5bf66a02e 100644 --- a/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/ChineseCVVCPhonemizer.cs @@ -42,6 +42,9 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN if (cvOto.Overlap == 0 && vcLen < 120) { vcLen = Math.Min(120, vcLen * 2); // explosive consonant with short preutter. } + if (cvOto.Overlap < 0) { + vcLen = MsToTick(cvOto.Preutter - cvOto.Overlap); + } } var vcPhoneme = $"{prevVowel} {consonant}"; if (prevNeighbour != null) { @@ -51,13 +54,13 @@ public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevN // totalDuration calculated on basis of previous note length int totalDuration = prevNeighbour.Value.duration; // vcLength depends on the Vel of the current base note - vcLen = Convert.ToInt32(Math.Min(totalDuration / 1.5, Math.Max(60, vcLen * (attr1.consonantStretchRatio ?? 1)))); + vcLen = Convert.ToInt32(Math.Min(totalDuration / 1.5, Math.Max(30, vcLen * (attr1.consonantStretchRatio ?? 1)))); } else { if (singer.TryGetMappedOto(vcPhoneme, notes[0].tone + attr0.toneShift, attr0.voiceColor, out oto)) { vcPhoneme = oto.Alias; } // no previous note, so length can be minimum velocity regardless of oto - vcLen = Convert.ToInt32(Math.Min(vcLen * 2, Math.Max(60, vcLen * (attr1.consonantStretchRatio ?? 1)))); + vcLen = Convert.ToInt32(Math.Min(vcLen * 2, Math.Max(30, vcLen * (attr1.consonantStretchRatio ?? 1)))); } if (singer.TryGetMappedOto(vcPhoneme, notes[0].tone + attr0.toneShift, attr0.voiceColor, out oto)) {