From fdacc3cfcb62050b7ba2e6301aed73e0d26d7048 Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Thu, 2 Mar 2023 16:54:39 +0800 Subject: [PATCH 1/3] time signature fix --- OpenUtau.Core/Util/TimeAxis.cs | 4 ++-- OpenUtau.Test/Core/Util/TimeAxisTest.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenUtau.Core/Util/TimeAxis.cs b/OpenUtau.Core/Util/TimeAxis.cs index d26de4625..31ea1640c 100644 --- a/OpenUtau.Core/Util/TimeAxis.cs +++ b/OpenUtau.Core/Util/TimeAxis.cs @@ -104,8 +104,8 @@ public void BuildSegments(UProject project) { tempoSegments[i].tickEnd = tempoSegments[i + 1].tickPos; } for (var i = 0; i < tempoSegments.Count; ++i) { - tempoSegments[i].msPerTick = 60.0 * 1000.0 * tempoSegments[i].beatPerBar / (tempoSegments[i].bpm * 4 * project.resolution); - tempoSegments[i].ticksPerMs = tempoSegments[i].bpm * 4 * project.resolution / (60.0 * 1000.0 * tempoSegments[i].beatPerBar); + tempoSegments[i].msPerTick = 60.0 * 1000.0 / (tempoSegments[i].bpm * project.resolution); + tempoSegments[i].ticksPerMs = tempoSegments[i].bpm * project.resolution / (60.0 * 1000.0); if (i > 0) { tempoSegments[i].msPos = tempoSegments[i - 1].msPos + tempoSegments[i - 1].Ticks * tempoSegments[i - 1].msPerTick; tempoSegments[i - 1].msEnd = tempoSegments[i].msPos; diff --git a/OpenUtau.Test/Core/Util/TimeAxisTest.cs b/OpenUtau.Test/Core/Util/TimeAxisTest.cs index 278e739f8..213c0bf56 100644 --- a/OpenUtau.Test/Core/Util/TimeAxisTest.cs +++ b/OpenUtau.Test/Core/Util/TimeAxisTest.cs @@ -26,15 +26,15 @@ public void ConvertMsTest() { Assert.Equal(2500, timeAxis.TickPosToMsPos(2400), 6); Assert.Equal(5000, timeAxis.TickPosToMsPos(4800), 6); Assert.Equal(9000, timeAxis.TickPosToMsPos(7200), 6); - Assert.Equal(20333.33333333, timeAxis.TickPosToMsPos(15960), 6); - Assert.Equal(35666.66666667, timeAxis.TickPosToMsPos(24000), 6); + Assert.Equal(21833.33333333, timeAxis.TickPosToMsPos(15960), 6); + Assert.Equal(37166.66666667, timeAxis.TickPosToMsPos(24000), 6); Assert.Equal(0, timeAxis.MsPosToTickPos(0)); Assert.Equal(2400, timeAxis.MsPosToTickPos(2500)); Assert.Equal(4800, timeAxis.MsPosToTickPos(5000)); Assert.Equal(7200, timeAxis.MsPosToTickPos(9000)); - Assert.Equal(15960, timeAxis.MsPosToTickPos(20333.33333333)); - Assert.Equal(24000, timeAxis.MsPosToTickPos(35666.66666667)); + Assert.Equal(15960, timeAxis.MsPosToTickPos(21833.33333333)); + Assert.Equal(24000, timeAxis.MsPosToTickPos(37166.66666667)); } [Fact] From 66884ea61ea6ac053f4d5c360405aafefe16c728 Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Tue, 14 Mar 2023 23:09:59 +0800 Subject: [PATCH 2/3] enunux: raw phonemes lyric support --- .../EnunuOnnx/EnunuOnnxPhonemizer.cs | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/OpenUtau.Plugin.Builtin/EnunuOnnx/EnunuOnnxPhonemizer.cs b/OpenUtau.Plugin.Builtin/EnunuOnnx/EnunuOnnxPhonemizer.cs index 0f6ca11ef..bff118fb6 100644 --- a/OpenUtau.Plugin.Builtin/EnunuOnnx/EnunuOnnxPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/EnunuOnnx/EnunuOnnxPhonemizer.cs @@ -252,14 +252,30 @@ public string GetPhonemeType(string phoneme) { } string[] GetSymbols(Note note) { - if (string.IsNullOrEmpty(note.phoneticHint)) { - // User has not provided hint, query CMUdict. - return g2p.Query(note.lyric.ToLowerInvariant()) ?? new string[] {defaultPause}; - } - // Split space-separated symbols into an array. - return note.phoneticHint.Split() - .Where(s => g2p.IsValidSymbol(s)) // skip the invalid symbols. - .ToArray(); + //priority: + //1. phonetic hint + //2. query from g2p dictionary + //3. treat lyric as phonetic hint, including single phoneme + //4. default pause + if (!string.IsNullOrEmpty(note.phoneticHint)) { + // Split space-separated symbols into an array. + return note.phoneticHint.Split() + .Where(s => g2p.IsValidSymbol(s)) // skip the invalid symbols. + .ToArray(); + } + // User has not provided hint, query g2p dictionary. + var g2presult = g2p.Query(note.lyric.ToLowerInvariant()); + if(g2presult != null) { + return g2presult; + } + //not founded in g2p dictionary, treat lyric as phonetic hint + var lyricSplited = note.lyric.Split() + .Where(s => g2p.IsValidSymbol(s)) // skip the invalid symbols. + .ToArray(); + if (lyricSplited.Length > 0) { + return lyricSplited; + } + return new string[] { defaultPause }; } //make a HTS Note from given symbols and UNotes From 6294082bc288965e003ae9392b27ba830fb44760 Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Sun, 19 Mar 2023 11:07:48 +0800 Subject: [PATCH 3/3] per-voicebank rhythmizer support --- .../DiffSinger/DiffSingerRenderer.cs | 2 +- .../DiffSingerRhythmizerPhonemizer.cs | 37 +++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs b/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs index bd500cebc..8eda7c147 100644 --- a/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs +++ b/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs @@ -161,7 +161,7 @@ float[] InvokeDiffsinger(RenderPhrase phrase,int speedup) { //get speaker curves NDArray spkCurves = np.zeros(totalFrames, speakers.Count); foreach(var curve in phrase.curves) { - if(IsVoiceColorCurve(curve.Item1,out int subBankId)) { + if(IsVoiceColorCurve(curve.Item1,out int subBankId) && subBankId < singer.Subbanks.Count) { var spkId = speakers.IndexOf(singer.Subbanks[subBankId].Suffix); spkCurves[":", spkId] = DiffSingerUtils.SampleCurve(phrase, curve.Item2, 0, frameMs, totalFrames, headFrames, tailFrames, x => x * 0.01f) diff --git a/OpenUtau.Core/DiffSinger/DiffSingerRhythmizerPhonemizer.cs b/OpenUtau.Core/DiffSinger/DiffSingerRhythmizerPhonemizer.cs index 5cab17c6e..e0efcc67b 100644 --- a/OpenUtau.Core/DiffSinger/DiffSingerRhythmizerPhonemizer.cs +++ b/OpenUtau.Core/DiffSinger/DiffSingerRhythmizerPhonemizer.cs @@ -25,7 +25,6 @@ public class DsRhythmizerYaml { } class DsRhythmizer { - public string name; public string Location; public DsRhythmizerConfig config; public InferenceSession session; @@ -47,13 +46,17 @@ public static Dictionary LoadPhoneDict(string path, Encoding T } //通过名称获取音素时长模型 - public DsRhythmizer(string name) { - this.name = name; - Location = Path.Combine(PathManager.Inst.DependencyPath, name); + public static DsRhythmizer FromName(string name) { + var path = Path.Combine(PathManager.Inst.DependencyPath, name); + return new DsRhythmizer(path); + } + + public DsRhythmizer(string path) { + this.Location = path; config = Core.Yaml.DefaultDeserializer.Deserialize( File.ReadAllText(Path.Combine(Location, "vocoder.yaml"), System.Text.Encoding.UTF8)); - phoneDict = LoadPhoneDict(Path.Combine(Location,"dsdict.txt"), Encoding.UTF8); + phoneDict = LoadPhoneDict(Path.Combine(Location, "dsdict.txt"), Encoding.UTF8); //导入音素列表 string phonemesPath = Path.Combine(Location, config.phonemes); phonemes = File.ReadLines(phonemesPath, Encoding.UTF8).ToList(); @@ -78,16 +81,20 @@ public override void SetSinger(USinger singer) { } //加载音素时长模型 try { - string rhythmizerName; - string rhythmizerYamlPath = Path.Combine(singer.Location, "dsrhythmizer.yaml"); - if (File.Exists(rhythmizerYamlPath)) { - rhythmizerName = Core.Yaml.DefaultDeserializer.Deserialize( - File.ReadAllText(rhythmizerYamlPath, singer.TextFileEncoding)).rhythmizer; - } else { - rhythmizerName = DsRhythmizer.DefaultRhythmizer; - } - if (rhythmizer == null || rhythmizer.name != rhythmizerName) { - rhythmizer = new DsRhythmizer(rhythmizerName); + //if rhythmizer is packed within the voicebank + var packedRhythmizerPath = Path.Combine(singer.Location, "rhythmizer"); + if(Directory.Exists(packedRhythmizerPath)) { + rhythmizer = new DsRhythmizer(packedRhythmizerPath); + } else { + string rhythmizerName; + string rhythmizerYamlPath = Path.Combine(singer.Location, "dsrhythmizer.yaml"); + if (File.Exists(rhythmizerYamlPath)) { + rhythmizerName = Core.Yaml.DefaultDeserializer.Deserialize( + File.ReadAllText(rhythmizerYamlPath, singer.TextFileEncoding)).rhythmizer; + } else { + rhythmizerName = DsRhythmizer.DefaultRhythmizer; + } + rhythmizer = DsRhythmizer.FromName(rhythmizerName); } //导入拼音转音素字典,仅从时长模型包中导入字典 phoneDict = rhythmizer.phoneDict;