From a835e25f0f53b8dce3d0e354789147e2dd1fcb5e Mon Sep 17 00:00:00 2001 From: Maiko Date: Wed, 4 Oct 2023 18:14:26 +0900 Subject: [PATCH 01/16] Fix parse plugin's pitch bend --- OpenUtau.Core/Classic/Ust.cs | 3 +- OpenUtau.Core/Classic/UstNote.cs | 90 ++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/OpenUtau.Core/Classic/Ust.cs b/OpenUtau.Core/Classic/Ust.cs index ef570eb1b..e5a9b0d65 100644 --- a/OpenUtau.Core/Classic/Ust.cs +++ b/OpenUtau.Core/Classic/Ust.cs @@ -180,7 +180,8 @@ private static void ParseNote(UNote note, int lastNotePos, int lastNoteEnd, List lyric = note.lyric, position = note.position, duration = note.duration, - noteNum = note.tone + noteNum = note.tone, + pitch = note.pitch }; ustNote.Parse(lastNotePos, lastNoteEnd, iniLines, out noteTempo); note.lyric = ustNote.lyric; diff --git a/OpenUtau.Core/Classic/UstNote.cs b/OpenUtau.Core/Classic/UstNote.cs index 827a6d1e1..3eb784350 100644 --- a/OpenUtau.Core/Classic/UstNote.cs +++ b/OpenUtau.Core/Classic/UstNote.cs @@ -277,48 +277,82 @@ void ParseEnvelope(string ust, IniLine ustLine) { } void ParsePitchBend(string pbs, string pbw, string pby, string pbm) { + var pitch = this.pitch != null ? this.pitch.Clone() : new UPitch() ; + var points = pitch.data; + + // PBS if (!string.IsNullOrWhiteSpace(pbs)) { - var pitch = new UPitch(); - var points = pitch.data; - points.Clear(); - // PBS var parts = pbs.Contains(';') ? pbs.Split(';') : pbs.Split(','); float pbsX = parts.Length >= 1 && ParseFloat(parts[0], out pbsX) ? pbsX : 0; float pbsY = parts.Length >= 2 && ParseFloat(parts[1], out pbsY) ? pbsY : 0; - points.Add(new PitchPoint(pbsX, pbsY)); - // PBW, PBY - var x = points.First().X; - if (!string.IsNullOrWhiteSpace(pbw)) { - var w = pbw.Split(',').Select(s => ParseFloat(s, out var v) ? v : 0).ToList(); - var y = (pby ?? "").Split(',').Select(s => ParseFloat(s, out var v) ? v : 0).ToList(); + if(points.Count > 0) { + points[0] = new PitchPoint(pbsX, pbsY); + } else { + points.Add(new PitchPoint(pbsX, pbsY)); + } + } + if (points.Count == 0) { + return; + } + // PBW, PBY + var x = points.First().X; + var w = new List(); + var y = new List(); + if (!string.IsNullOrWhiteSpace(pbw)) { + w = pbw.Split(',').Select(s => ParseFloat(s, out var v) ? v : 0).ToList(); + } + if (!string.IsNullOrWhiteSpace(pby)) { + y = pby.Split(',').Select(s => ParseFloat(s, out var v) ? v : 0).ToList(); + } + if (w.Count != 0 || y.Count != 0) { + if (points.Count > 1 && points.Count - 1 == w.Count && w.Count == y.Count) { // replace to new point + for (var i = 0; i < w.Count(); i++) { + x += w[i]; + points[i + 1] = new PitchPoint(x, y[i]); + } + } else if (points.Count > 1 && points.Count - 1 == w.Count && y.Count == 0) { // replace w only + for (var i = 0; i < w.Count(); i++) { + x += w[i]; + points[i + 1].X = x; + } + } else if (points.Count > 1 && w.Count == 0 && points.Count - 1 == y.Count) { // replace y only + for (var i = 0; i < y.Count(); i++) { + points[i + 1].Y = y[i]; + } + } else { while (w.Count > y.Count) { y.Add(0); } + for (var i = points.Count - 1; i > 0; i--) { + points.Remove(points[i]); + } for (var i = 0; i < w.Count(); i++) { x += w[i]; points.Add(new PitchPoint(x, y[i])); } } - // PBM - if (!string.IsNullOrWhiteSpace(pbm)) { - var m = pbm.Split(new[] { ',' }); - for (var i = 0; i < m.Count() && i < points.Count; i++) { - switch (m[i]) { - case "r": - points[i].shape = PitchPointShape.o; - break; - case "s": - points[i].shape = PitchPointShape.l; - break; - case "j": - points[i].shape = PitchPointShape.i; - break; - default: - points[i].shape = PitchPointShape.io; - break; - } + } + // PBM + if (!string.IsNullOrWhiteSpace(pbm)) { + var m = pbm.Split(new[] { ',' }); + for (var i = 0; i < m.Count() && i < points.Count; i++) { + switch (m[i]) { + case "r": + points[i].shape = PitchPointShape.o; + break; + case "s": + points[i].shape = PitchPointShape.l; + break; + case "j": + points[i].shape = PitchPointShape.i; + break; + default: + points[i].shape = PitchPointShape.io; + break; } } + } + if (points.Count > 1) { this.pitch = pitch; } } From d6215bdd267124b33adc561325ff1ada622adcb1 Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Fri, 13 Oct 2023 23:39:13 +0800 Subject: [PATCH 02/16] ctrl-click to add note into selection without deselect the other notes --- OpenUtau/ViewModels/NotesViewModel.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenUtau/ViewModels/NotesViewModel.cs b/OpenUtau/ViewModels/NotesViewModel.cs index 07f2d4605..64ee78259 100644 --- a/OpenUtau/ViewModels/NotesViewModel.cs +++ b/OpenUtau/ViewModels/NotesViewModel.cs @@ -511,17 +511,24 @@ public void DeselectNotes() { } public void ToggleSelectNote(UNote note) { + /// + /// Change the selection state of a note without affecting the selection state of the other notes. + /// Add it to selection if it isn't selected, or deselect it if it is already selected. + /// if (Part == null) { return; } if (Selection.Contains(note)) { DeselectNote(note); } else { - SelectNote(note); + SelectNote(note, false); } } public void SelectNote(UNote note) { + /// + /// Select a note and deselect all the other notes. + /// SelectNote(note, true); } public void SelectNote(UNote note, bool deselectExisting) { From 7d890b2e9401f604f116d8bbb1220ba47ba8c523 Mon Sep 17 00:00:00 2001 From: Maiko Date: Sat, 14 Oct 2023 15:46:22 +0900 Subject: [PATCH 03/16] Add ust parse test --- OpenUtau.Core/Classic/UstNote.cs | 7 +--- OpenUtau.Test/Classic/UstTest.cs | 55 +++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/OpenUtau.Core/Classic/UstNote.cs b/OpenUtau.Core/Classic/UstNote.cs index 3eb784350..512bcd3b6 100644 --- a/OpenUtau.Core/Classic/UstNote.cs +++ b/OpenUtau.Core/Classic/UstNote.cs @@ -305,12 +305,7 @@ void ParsePitchBend(string pbs, string pbw, string pby, string pbm) { y = pby.Split(',').Select(s => ParseFloat(s, out var v) ? v : 0).ToList(); } if (w.Count != 0 || y.Count != 0) { - if (points.Count > 1 && points.Count - 1 == w.Count && w.Count == y.Count) { // replace to new point - for (var i = 0; i < w.Count(); i++) { - x += w[i]; - points[i + 1] = new PitchPoint(x, y[i]); - } - } else if (points.Count > 1 && points.Count - 1 == w.Count && y.Count == 0) { // replace w only + if (points.Count > 1 && points.Count - 1 == w.Count && y.Count == 0) { // replace w only for (var i = 0; i < w.Count(); i++) { x += w[i]; points[i + 1].X = x; diff --git a/OpenUtau.Test/Classic/UstTest.cs b/OpenUtau.Test/Classic/UstTest.cs index 43342f77e..1863f3916 100644 --- a/OpenUtau.Test/Classic/UstTest.cs +++ b/OpenUtau.Test/Classic/UstTest.cs @@ -58,7 +58,12 @@ public void EqualInLyric() { Length=15 Lyric=A==B[C=D],EFG NoteNum=60 -PreUtterance="; +PreUtterance= +VBR=80,200,20,20,20,0,-50,0 +PBW=292,183 +PBS=-222;-19 +PBY=-20.7, +"; using (var stream = new MemoryStream()) { using (var writer = new StreamWriter(stream, leaveOpen: true)) { writer.Write(ust); @@ -73,6 +78,12 @@ public void EqualInLyric() { Assert.Single(part.notes); Assert.Equal("A==B[C=D],EFG", part.notes.First().lyric); Assert.Equal(60, part.notes.First().tone); + Assert.Equivalent(new UPitch {data = new List { + new PitchPoint { X = -222, Y = -19, shape = PitchPointShape.io}, + new PitchPoint { X = 70, Y = -20.7f, shape = PitchPointShape.io}, // X = -222 + 292 = 70 + new PitchPoint { X = 253, Y = 0, shape = PitchPointShape.io} // X = 70 + 183 = 253 + }, snapFirst = false } , part.notes.First().pitch); + Assert.Equivalent(new UVibrato { length = 80, period = 200, depth = 20, @in = 20, @out = 20, shift = 0, drift = -50, volLink = 0 }, part.notes.First().vibrato); } } } @@ -94,27 +105,37 @@ public void ParsePluginParseNoteTest() { var before = UNote.Create(); before.lyric = "a"; - before.duration = 10; + before.duration = 100; var first = UNote.Create(); first.lyric = "ka"; - first.duration = 20; + first.duration = 200; + first.pitch.data = new List { + new PitchPoint { X = -50, Y = 0, shape = PitchPointShape.io}, + new PitchPoint { X = 0, Y = 10, shape = PitchPointShape.io}, + new PitchPoint { X = 93.75f, Y = -12.2f, shape = PitchPointShape.io}, + new PitchPoint { X = 194.7f, Y = 0, shape = PitchPointShape.io} + }; var second = UNote.Create(); second.lyric = "r"; - second.duration = 30; + second.duration = 300; var third = UNote.Create(); third.lyric = "ta"; - third.duration = 40; + third.duration = 400; + third.pitch.data = new List { + new PitchPoint { X = -100, Y = 0, shape = PitchPointShape.io}, + new PitchPoint { X = 130, Y = 0, shape = PitchPointShape.io} + }; var last = UNote.Create(); last.lyric = "na"; - last.duration = 50; + last.duration = 500; var after = UNote.Create(); after.lyric = "ha"; - after.duration = 60; + after.duration = 600; part.notes.Add(before); part.notes.Add(first); @@ -141,12 +162,16 @@ public void ParsePluginParseNoteTest() { writer.WriteLine("[#0000]"); writer.WriteLine("Length=480"); writer.WriteLine("Lyric=A"); + writer.WriteLine("PBY=10,-10,0"); // Change only height of the third point writer.WriteLine("[#0001]"); writer.WriteLine("Length=480"); writer.WriteLine("Lyric=R"); // duration is null (change) writer.WriteLine("[#0002]"); writer.WriteLine("Lyric=zo"); + writer.WriteLine("PBS=-50"); // Reset points + writer.WriteLine("PBW=100"); + writer.WriteLine("PBY=0"); // duration is zero (delete) writer.WriteLine("[#0003]"); writer.WriteLine("Length="); @@ -164,8 +189,22 @@ public void ParsePluginParseNoteTest() { Assert.Equal(3, toAdd.Count); Assert.Equal(480, toAdd[0].duration); Assert.Equal("A", toAdd[0].lyric); - Assert.Equal(40, toAdd[1].duration); + Assert.Equivalent(new UPitch { + data = new List { + new PitchPoint { X = -50, Y = 0, shape = PitchPointShape.io}, + new PitchPoint { X = 0, Y = 10, shape = PitchPointShape.io}, + new PitchPoint { X = 93.75f, Y = -10, shape = PitchPointShape.io}, + new PitchPoint { X = 194.7f, Y = 0, shape = PitchPointShape.io} + }, snapFirst = true + }, toAdd[0].pitch); + Assert.Equal(400, toAdd[1].duration); Assert.Equal("zo", toAdd[1].lyric); + Assert.Equivalent(new UPitch { + data = new List { + new PitchPoint { X = -50, Y = 0, shape = PitchPointShape.io}, + new PitchPoint { X = 50, Y = 0, shape = PitchPointShape.io} + }, snapFirst = true + }, toAdd[1].pitch); Assert.Equal(240, toAdd[2].duration); Assert.Equal("me", toAdd[2].lyric); } finally { From ecd256465604f0f0551655514f43896751016dba Mon Sep 17 00:00:00 2001 From: Maiko Date: Sat, 14 Oct 2023 20:46:25 +0900 Subject: [PATCH 04/16] Display trackNo currently rendering --- OpenUtau.Core/Classic/ClassicRenderer.cs | 14 +++++++------- OpenUtau.Core/Classic/WorldlineRenderer.cs | 4 ++-- OpenUtau.Core/Enunu/EnunuRenderer.cs | 4 ++-- OpenUtau.Core/Render/IRenderer.cs | 2 +- OpenUtau.Core/Render/RenderEngine.cs | 2 +- OpenUtau.Core/Vogen/VogenRenderer.cs | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/OpenUtau.Core/Classic/ClassicRenderer.cs b/OpenUtau.Core/Classic/ClassicRenderer.cs index aba324b4a..f5ea2b4e0 100644 --- a/OpenUtau.Core/Classic/ClassicRenderer.cs +++ b/OpenUtau.Core/Classic/ClassicRenderer.cs @@ -47,15 +47,15 @@ public RenderResult Layout(RenderPhrase phrase) { }; } - public Task Render(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender) { + public Task Render(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender) { if (phrase.wavtool == SharpWavtool.nameConvergence || phrase.wavtool == SharpWavtool.nameSimple) { - return RenderInternal(phrase, progress, cancellation, isPreRender); + return RenderInternal(phrase, progress, trackNo, cancellation, isPreRender); } else { - return RenderExternal(phrase, progress, cancellation, isPreRender); + return RenderExternal(phrase, progress, trackNo, cancellation, isPreRender); } } - public Task RenderInternal(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender) { + public Task RenderInternal(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender) { var resamplerItems = new List(); foreach (var phone in phrase.phones) { resamplerItems.Add(new ResamplerItem(phrase, phone)); @@ -78,7 +78,7 @@ public Task RenderInternal(RenderPhrase phrase, Progress progress, VoicebankFiles.Inst.CopyBackMetaFiles(item.inputFile, item.inputTemp); } } - progress.Complete(1, $"{item.resampler} \"{item.phone.phoneme}\""); + progress.Complete(1, $"Track {trackNo} : {item.resampler} \"{item.phone.phoneme}\""); }); var result = Layout(phrase); var wavtool = new SharpWavtool(true); @@ -91,13 +91,13 @@ public Task RenderInternal(RenderPhrase phrase, Progress progress, return task; } - public Task RenderExternal(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender) { + public Task RenderExternal(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender) { var resamplerItems = new List(); foreach (var phone in phrase.phones) { resamplerItems.Add(new ResamplerItem(phrase, phone)); } var task = Task.Run(() => { - string progressInfo = $"{phrase.wavtool} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; + string progressInfo = $"Track {trackNo} : {phrase.wavtool} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; progress.Complete(0, progressInfo); var wavPath = Path.Join(PathManager.Inst.CachePath, $"cat-{phrase.hash:x16}.wav"); var result = Layout(phrase); diff --git a/OpenUtau.Core/Classic/WorldlineRenderer.cs b/OpenUtau.Core/Classic/WorldlineRenderer.cs index 275ca926c..deed5fd94 100644 --- a/OpenUtau.Core/Classic/WorldlineRenderer.cs +++ b/OpenUtau.Core/Classic/WorldlineRenderer.cs @@ -47,7 +47,7 @@ public RenderResult Layout(RenderPhrase phrase) { }; } - public Task Render(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender) { + public Task Render(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender) { var resamplerItems = new List(); foreach (var phone in phrase.phones) { resamplerItems.Add(new ResamplerItem(phrase, phone)); @@ -55,7 +55,7 @@ public Task Render(RenderPhrase phrase, Progress progress, Cancell var task = Task.Run(() => { var result = Layout(phrase); var wavPath = Path.Join(PathManager.Inst.CachePath, $"wdl-{phrase.hash:x16}.wav"); - string progressInfo = $"{this} {string.Join(" ", phrase.phones.Select(p => p.phoneme))}"; + string progressInfo = $"Track {trackNo} : {this} {string.Join(" ", phrase.phones.Select(p => p.phoneme))}"; progress.Complete(0, progressInfo); if (File.Exists(wavPath)) { try { diff --git a/OpenUtau.Core/Enunu/EnunuRenderer.cs b/OpenUtau.Core/Enunu/EnunuRenderer.cs index ab906601f..4e2a43198 100644 --- a/OpenUtau.Core/Enunu/EnunuRenderer.cs +++ b/OpenUtau.Core/Enunu/EnunuRenderer.cs @@ -68,13 +68,13 @@ public RenderResult Layout(RenderPhrase phrase) { }; } - public Task Render(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender) { + public Task Render(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender) { var task = Task.Run(() => { lock (lockObj) { if (cancellation.IsCancellationRequested) { return new RenderResult(); } - string progressInfo = $"{this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; + string progressInfo = $"Track {trackNo} : {this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; progress.Complete(0, progressInfo); var tmpPath = Path.Join(PathManager.Inst.CachePath, $"enu-{phrase.preEffectHash:x16}"); var ustPath = tmpPath + ".tmp"; diff --git a/OpenUtau.Core/Render/IRenderer.cs b/OpenUtau.Core/Render/IRenderer.cs index 1b38e4abc..fdc5f6ef3 100644 --- a/OpenUtau.Core/Render/IRenderer.cs +++ b/OpenUtau.Core/Render/IRenderer.cs @@ -42,7 +42,7 @@ public interface IRenderer { bool SupportsRenderPitch { get; } bool SupportsExpression(UExpressionDescriptor descriptor); RenderResult Layout(RenderPhrase phrase); - Task Render(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender = false); + Task Render(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender = false); RenderPitchResult LoadRenderedPitch(RenderPhrase phrase); UExpressionDescriptor[] GetSuggestedExpressions(USinger singer, URenderSettings renderSettings); } diff --git a/OpenUtau.Core/Render/RenderEngine.cs b/OpenUtau.Core/Render/RenderEngine.cs index 3f3ba17fb..13ee40419 100644 --- a/OpenUtau.Core/Render/RenderEngine.cs +++ b/OpenUtau.Core/Render/RenderEngine.cs @@ -213,7 +213,7 @@ private void RenderRequests( var phrase = tuple.Item1; var source = tuple.Item2; var request = tuple.Item3; - var task = phrase.renderer.Render(phrase, progress, cancellation, true); + var task = phrase.renderer.Render(phrase, progress, request.trackNo, cancellation, true); task.Wait(); if (cancellation.IsCancellationRequested) { break; diff --git a/OpenUtau.Core/Vogen/VogenRenderer.cs b/OpenUtau.Core/Vogen/VogenRenderer.cs index 6b9d8a938..d48debd27 100644 --- a/OpenUtau.Core/Vogen/VogenRenderer.cs +++ b/OpenUtau.Core/Vogen/VogenRenderer.cs @@ -54,7 +54,7 @@ public RenderResult Layout(RenderPhrase phrase) { }; } - public Task Render(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender = false) { + public Task Render(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender = false) { var task = Task.Run(() => { lock (lockObj) { if (cancellation.IsCancellationRequested) { @@ -62,7 +62,7 @@ public Task Render(RenderPhrase phrase, Progress progress, Cancell } var result = Layout(phrase); var wavPath = Path.Join(PathManager.Inst.CachePath, $"vog-{phrase.hash:x16}.wav"); - string progressInfo = $"{this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; + string progressInfo = $"Track {trackNo} : {this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; progress.Complete(0, progressInfo); if (File.Exists(wavPath)) { try { From 3105638735063f55efc4802be07169a4152c6131 Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Sun, 15 Oct 2023 15:55:55 +0800 Subject: [PATCH 05/16] fix typo --- OpenUtau.Core/DependencyInstaller.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenUtau.Core/DependencyInstaller.cs b/OpenUtau.Core/DependencyInstaller.cs index b63536dcb..87d7073d7 100644 --- a/OpenUtau.Core/DependencyInstaller.cs +++ b/OpenUtau.Core/DependencyInstaller.cs @@ -41,7 +41,7 @@ public static void Install(string archivePath) { entry.WriteToFile(Path.Combine(basePath, entry.Key)); } } - DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"dependency \"{name}\" installaion finished")); + DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Installed dependency \"{name}\"")); } } } From d87fbe755b7c97b959094bab9ddf7b7603df6b45 Mon Sep 17 00:00:00 2001 From: lennyservant Date: Mon, 9 Oct 2023 10:53:44 +0800 Subject: [PATCH 06/16] change classic pitch to sample pitch using sample positions instead of index math --- OpenUtau.Core/Classic/ResamplerItem.cs | 44 ++++++++++++++------------ OpenUtau.Core/Util/TimeAxis.cs | 6 ++++ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/OpenUtau.Core/Classic/ResamplerItem.cs b/OpenUtau.Core/Classic/ResamplerItem.cs index b234d68dd..e6c597221 100644 --- a/OpenUtau.Core/Classic/ResamplerItem.cs +++ b/OpenUtau.Core/Classic/ResamplerItem.cs @@ -74,27 +74,29 @@ public ResamplerItem(RenderPhrase phrase, RenderPhone phone) { pitchCount = Math.Max(pitchCount, 0); pitches = new int[pitchCount]; - double phoneStartMs = phone.positionMs - pitchLeadingMs; - double phraseStartMs = phrase.positionMs - phrase.leadingMs; - for (int i = 0; i < phone.tempos.Length; i++) { - double startMs = Math.Max(phrase.timeAxis.TickPosToMsPos(phone.tempos[i].position), phoneStartMs); - double endMs = i + 1 < phone.tempos.Length ? phrase.timeAxis.TickPosToMsPos(phone.tempos[i + 1].position) : phone.positionMs + phone.envelope[4].X; - double durationMs = endMs - startMs; - int tempoPitchCount = (int)Math.Floor(MusicMath.TempoMsToTick(tempo, durationMs) / 5.0); - int tempoPitchSkip = (int)Math.Floor(MusicMath.TempoMsToTick(tempo, startMs - phoneStartMs) / 5.0); - tempoPitchCount = Math.Min(tempoPitchCount, pitches.Length - tempoPitchSkip); - int phrasePitchSkip = (int)Math.Floor(phrase.timeAxis.TicksBetweenMsPos(phraseStartMs, startMs) / 5.0); - double intervalPitchMs = 120 / tempo * 500 / 480 * 5; - double diffPitchMs = startMs - phraseStartMs - phrase.timeAxis.TickPosToMsPos(phrasePitchSkip * 5); - double tempoRatio = phone.tempos[i].bpm / tempo; - for (int j = 0; j < tempoPitchCount; j++) { - int index = tempoPitchSkip + j; - int scaled = phrasePitchSkip + (int)Math.Ceiling(j * tempoRatio); - scaled = Math.Clamp(scaled, 0, phrase.pitches.Length - 1); - int nextScaled = Math.Clamp(scaled + 1, 0, phrase.pitches.Length - 1); - index = Math.Clamp(index, 0, pitchCount - 1); - pitches[index] = (int)Math.Round((phrase.pitches[nextScaled]- phrase.pitches[scaled]) /intervalPitchMs * diffPitchMs + phrase.pitches[scaled] - phone.tone * 100); - } + var phrasePitchStartMs = phrase.positionMs - phrase.leadingMs; + var phrasePitchStartTick = (int)Math.Floor(phrase.timeAxis.MsPosToNonExactTickPos(phrasePitchStartMs)); + + var pitchIntervalMs = MusicMath.TempoTickToMs(tempo, 5); + var pitchSampleStartMs = phone.positionMs - pitchLeadingMs; + + for (int i=0; i seg.msPos == ms || seg.msEnd > ms); // TODO: optimize + double tickPos = segment.tickPos + (ms - segment.msPos) * segment.ticksPerMs; + return tickPos; + } + public int MsPosToTickPos(double ms) { var segment = tempoSegments.First(seg => seg.msPos == ms || seg.msEnd > ms); // TODO: optimize double tickPos = segment.tickPos + (ms - segment.msPos) * segment.ticksPerMs; From 064af390dd7b3876a030646e4fa437ab820f7641 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Tue, 17 Oct 2023 15:33:01 +0200 Subject: [PATCH 07/16] ValidateAlias fixex +optimization --- OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs index ffdc622b5..fdba8d896 100644 --- a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs @@ -146,9 +146,9 @@ protected override string[] GetSymbols(Note note) { string[] diphthongs = new[] { "aI", "eI", "OI", "aU", "oU", "VI", "VU", "@U" }; string[] affricates = new[] { "dZ", "tS" }; foreach (string s in original) { - if (diphthongs.Contains(s) && !HasOto($"{s} b", note.tone)) { + if (diphthongs.Contains(HasOto(s, note.tone) ? s : s) && !HasOto($"- {s}", note.tone) && !HasOto(s, note.tone) && !HasOto(ValidateAlias($"- {s}"), note.tone) && !HasOto(ValidateAlias(s), note.tone)) { modified.AddRange(new string[] { s[0].ToString(), s[1] + '^'.ToString() }); - } else if (affricates.Contains(s) && !HasOto($"i {s}", note.tone) && !HasOto($"i: {s}", note.tone)) { + } else if (affricates.Contains(s) && !HasOto($"{s}A", note.tone) && !HasOto($"{s} A", note.tone) && !HasOto($"{s}Q", note.tone) && !HasOto($"{s} Q", note.tone)) { modified.AddRange(new string[] { s[0].ToString(), s[1].ToString() }); } else { modified.Add(s); @@ -169,19 +169,19 @@ protected override List ProcessSyllable(Syllable syllable) { var rv = $"- {v}"; // Switch between phonetic systems, depending on certain aliases in the bank - if (HasOto($"i: b", syllable.tone) || !HasOto($"3 b", syllable.tone)) { + if (HasOto($"- i:", syllable.tone) || HasOto($"i:", syllable.tone) || (!HasOto($"- 3", syllable.tone) && !HasOto($"3", syllable.tone))) { isVocaSampa = true; } - if (!HasOto($"V b", syllable.vowelTone)) { + if (!HasOto($"- V", syllable.vowelTone) && !HasOto($"V", syllable.vowelTone)) { isSimpleDelta = true; } - if (!HasOto($"I b", syllable.vowelTone)) { + if (!HasOto($"- I", syllable.vowelTone) && !HasOto($"I", syllable.vowelTone)) { isMiniDelta = true; } - if (HasOto("か", syllable.vowelTone)) { + if (HasOto("あ", syllable.vowelTone) || HasOto("- あ", syllable.vowelTone)) { isEnPlusJa = true; } @@ -189,7 +189,7 @@ protected override List ProcessSyllable(Syllable syllable) { isTrueXSampa = true; } - if (!HasOto($"3 b", syllable.tone) && !HasOto($"@` b", syllable.tone)) { + if ((!HasOto($"- 3", syllable.tone) && !HasOto($"3", syllable.tone)) || (!HasOto($"- @`", syllable.tone) && !HasOto($"@`", syllable.tone))) { isSalemList = true; } @@ -222,7 +222,7 @@ protected override List ProcessSyllable(Syllable syllable) { var cv = $"{cc[0]}{v}"; if (HasOto(rcv, syllable.vowelTone) || HasOto(ValidateAlias(rcv), syllable.vowelTone)) { basePhoneme = rcv; - } else if ((!HasOto(rcv, syllable.vowelTone) || !HasOto(ValidateAlias(rcv), syllable.vowelTone)) && (HasOto(crv, syllable.vowelTone) || HasOto(ValidateAlias(crv), syllable.vowelTone))) { + } else if ((!HasOto(rcv, syllable.vowelTone) && !HasOto(ValidateAlias(rcv), syllable.vowelTone)) && (HasOto(crv, syllable.vowelTone) || HasOto(ValidateAlias(crv), syllable.vowelTone))) { basePhoneme = crv; TryAddPhoneme(phonemes, syllable.tone, $"- {cc[0]}", ValidateAlias($"- {cc[0]}")); } else { @@ -299,7 +299,7 @@ protected override List ProcessSyllable(Syllable syllable) { lastC = i; basePhoneme = ccv; break; - } else if ((HasOto(rccv, syllable.vowelTone) || HasOto(ValidateAlias(rccv), syllable.vowelTone)) && (!HasOto(ccv, syllable.vowelTone) || !HasOto(ValidateAlias(ccv), syllable.vowelTone))) { + } else if ((HasOto(rccv, syllable.vowelTone) || HasOto(ValidateAlias(rccv), syllable.vowelTone)) && (!HasOto(ccv, syllable.vowelTone) && !HasOto(ValidateAlias(ccv), syllable.vowelTone))) { lastC = i; basePhoneme = rccv; break; @@ -432,7 +432,7 @@ protected override List ProcessEnding(Ending ending) { var vcr2 = $"{v}{cc[0]} -"; if (HasOto(vcr, ending.tone) || HasOto(ValidateAlias(vcr), ending.tone)) { phonemes.Add(vcr); - } else if ((!HasOto(vcr, ending.tone) || !HasOto(ValidateAlias(vcr), ending.tone)) && (HasOto(vcr2, ending.tone) || HasOto(ValidateAlias(vcr2), ending.tone))) { + } else if ((!HasOto(vcr, ending.tone) && !HasOto(ValidateAlias(vcr), ending.tone)) && (HasOto(vcr2, ending.tone) || HasOto(ValidateAlias(vcr2), ending.tone))) { phonemes.Add(vcr2); } else { phonemes.Add(vc); From 509505d3e6f75b7111ce1917486ae2aa5c3e9136 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Tue, 17 Oct 2023 15:34:42 +0200 Subject: [PATCH 08/16] Oops, remove leftover test code --- OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs index fdba8d896..c71cb68b1 100644 --- a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs @@ -146,7 +146,7 @@ protected override string[] GetSymbols(Note note) { string[] diphthongs = new[] { "aI", "eI", "OI", "aU", "oU", "VI", "VU", "@U" }; string[] affricates = new[] { "dZ", "tS" }; foreach (string s in original) { - if (diphthongs.Contains(HasOto(s, note.tone) ? s : s) && !HasOto($"- {s}", note.tone) && !HasOto(s, note.tone) && !HasOto(ValidateAlias($"- {s}"), note.tone) && !HasOto(ValidateAlias(s), note.tone)) { + if (diphthongs.Contains(s) && !HasOto($"- {s}", note.tone) && !HasOto(s, note.tone) && !HasOto(ValidateAlias($"- {s}"), note.tone) && !HasOto(ValidateAlias(s), note.tone)) { modified.AddRange(new string[] { s[0].ToString(), s[1] + '^'.ToString() }); } else if (affricates.Contains(s) && !HasOto($"{s}A", note.tone) && !HasOto($"{s} A", note.tone) && !HasOto($"{s}Q", note.tone) && !HasOto($"{s} Q", note.tone)) { modified.AddRange(new string[] { s[0].ToString(), s[1].ToString() }); From dd87cb5d1129a02251dc0723e405217cfabef8a6 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Tue, 17 Oct 2023 15:39:50 +0200 Subject: [PATCH 09/16] Add diphthongs + vowel fallback --- OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs index c71cb68b1..e1f2f4ddf 100644 --- a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs @@ -20,7 +20,7 @@ public class EnXSampaPhonemizer : SyllableBasedPhonemizer { /// Due to the flexibility of X-SAMPA, it was easy to add the custom sounds. More suggestions for this are always welcome. /// - private readonly string[] vowels = "a,A,@,{,V,O,aU,aI,E,3,eI,I,i,oU,OI,U,u,Q,Ol,Ql,aUn,e@,eN,IN,e,o,Ar,Qr,Er,Ir,Or,Ur,ir,ur,aIr,aUr,A@,Q@,E@,I@,O@,U@,i@,u@,aI@,aU@,@r,@l,@m,@n,@N,1,e@m,e@n,y,I\\,M,U\\,Y,@\\,@`,3`,A`,Q`,E`,I`,O`,U`,i`,u`,aI`,aU`,},2,3\\,6,7,8,9,&,{~,I~,aU~,VI,VU,@U,i:,u:,O:,e@0,E~,e~,3r,ar,or,{l,Al,al,El,Il,il,ul,Ul,mm,nn,ll,NN".Split(','); + private readonly string[] vowels = "a,A,@,{,V,O,aU,aI,E,3,eI,I,i,oU,OI,U,u,Q,Ol,Ql,aUn,e@,eN,IN,e,o,Ar,Qr,Er,Ir,Or,Ur,ir,ur,aIr,aUr,A@,Q@,E@,I@,O@,U@,i@,u@,aI@,aU@,@r,@l,@m,@n,@N,1,e@m,e@n,y,I\\,M,U\\,Y,@\\,@`,3`,A`,Q`,E`,I`,O`,U`,i`,u`,aI`,aU`,},2,3\\,6,7,8,9,&,{~,I~,aU~,VI,VU,@U,ai,ei,Oi,au,ou,Ou,@u,i:,u:,O:,e@0,E~,e~,3r,ar,or,{l,Al,al,El,Il,il,ul,Ul,mm,nn,ll,NN".Split(','); private readonly string[] consonants = "b,tS,d,D,4,f,g,h,dZ,k,l,m,n,N,p,r,s,S,t,T,v,w,W,j,z,Z,t_},・,_".Split(','); private readonly string[] affricates = "tS,dZ".Split(','); private readonly string[] shortConsonants = "4".Split(","); @@ -143,7 +143,7 @@ protected override string[] GetSymbols(Note note) { } List modified = new List(); // Splits diphthongs and affricates if not present in the bank - string[] diphthongs = new[] { "aI", "eI", "OI", "aU", "oU", "VI", "VU", "@U" }; + string[] diphthongs = new[] { "aI", "eI", "OI", "aU", "oU", "VI", "VU", "@U", "ai", "ei", "Oi", "au", "ou", "Ou", "@u", }; string[] affricates = new[] { "dZ", "tS" }; foreach (string s in original) { if (diphthongs.Contains(s) && !HasOto($"- {s}", note.tone) && !HasOto(s, note.tone) && !HasOto(ValidateAlias($"- {s}"), note.tone) && !HasOto(ValidateAlias(s), note.tone)) { @@ -177,7 +177,7 @@ protected override List ProcessSyllable(Syllable syllable) { isSimpleDelta = true; } - if (!HasOto($"- I", syllable.vowelTone) && !HasOto($"I", syllable.vowelTone)) { + if ((!HasOto($"- I", syllable.vowelTone) && !HasOto($"I", syllable.vowelTone)) || (!HasOto($"- U", syllable.vowelTone) && !HasOto($"U", syllable.vowelTone))) { isMiniDelta = true; } From 573dbeeb95ae442779695fb6db9d191f92362bb0 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Tue, 17 Oct 2023 15:44:49 +0200 Subject: [PATCH 10/16] Add new diphthongs to template --- OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml b/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml index e229a5ceb..a9c227fb2 100644 --- a/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml +++ b/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml @@ -137,6 +137,13 @@ symbols: - {symbol: VI, type: vowel} - {symbol: VU, type: vowel} - {symbol: '@U', type: vowel} + - {symbol: ai, type: vowel} + - {symbol: ei, type: vowel} + - {symbol: Oi, type: vowel} + - {symbol: au, type: vowel} + - {symbol: ou, type: vowel} + - {symbol: Ou, type: vowel} + - {symbol: '@u', type: vowel} - {symbol: 'i:', type: vowel} - {symbol: 'u:', type: vowel} - {symbol: 'O:', type: vowel} From 9ea91e4644b05702760dc72ba7d1920b2fb69978 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Tue, 17 Oct 2023 16:10:29 +0200 Subject: [PATCH 11/16] Vocaloid-style rhotic fallbacks for VCC --- OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs index e1f2f4ddf..8c53a7416 100644 --- a/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs +++ b/OpenUtau.Plugin.Builtin/EnXSampaPhonemizer.cs @@ -35,7 +35,7 @@ public class EnXSampaPhonemizer : SyllableBasedPhonemizer { .ToDictionary(parts => parts[0], parts => parts[1]); // For banks aliased with VOCALOID-style phonemes - private readonly Dictionary vocaSampa = "A=Q;E=e;i=i:;u=u:;O=O:;3=@r;oU=@U".Split(';') + private readonly Dictionary vocaSampa = "A=Q;E=e;i=i:;u=u:;O=O:;3=@r;oU=@U;Ar=Q@;Qr=Q@;Er=e@;er=e@;Ir=I@;ir=I@;i:r=I@;Or=O@;O:r=O@;Ur=U@;ur=U@;u:r=U@".Split(';') .Select(entry => entry.Split('=')) .Where(parts => parts.Length == 2) .Where(parts => parts[0] != parts[1]) From 4edd5007f18afd9cc0185883581924c564595010 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Tue, 17 Oct 2023 23:11:59 +0200 Subject: [PATCH 12/16] Symbol sorting --- OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml b/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml index a9c227fb2..d7dbfaa7c 100644 --- a/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml +++ b/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml @@ -137,17 +137,17 @@ symbols: - {symbol: VI, type: vowel} - {symbol: VU, type: vowel} - {symbol: '@U', type: vowel} + - {symbol: '@u', type: vowel} + - {symbol: 'i:', type: vowel} + - {symbol: 'u:', type: vowel} + - {symbol: 'O:', type: vowel} + - {symbol: e@0, type: vowel} - {symbol: ai, type: vowel} - {symbol: ei, type: vowel} - {symbol: Oi, type: vowel} - {symbol: au, type: vowel} - {symbol: ou, type: vowel} - {symbol: Ou, type: vowel} - - {symbol: '@u', type: vowel} - - {symbol: 'i:', type: vowel} - - {symbol: 'u:', type: vowel} - - {symbol: 'O:', type: vowel} - - {symbol: e@0, type: vowel} - {symbol: 4, type: tap} - {symbol: W, type: fricative} - {symbol: 't_}', type: stop} From 6936536cfa119850f7dc24052b87a7fd94032324 Mon Sep 17 00:00:00 2001 From: Lotte V Date: Tue, 17 Oct 2023 23:13:30 +0200 Subject: [PATCH 13/16] Symbol sorting --- OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml b/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml index d7dbfaa7c..96df29ffd 100644 --- a/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml +++ b/OpenUtau.Plugin.Builtin/Data/en-xsampa.template.yaml @@ -137,7 +137,6 @@ symbols: - {symbol: VI, type: vowel} - {symbol: VU, type: vowel} - {symbol: '@U', type: vowel} - - {symbol: '@u', type: vowel} - {symbol: 'i:', type: vowel} - {symbol: 'u:', type: vowel} - {symbol: 'O:', type: vowel} @@ -148,6 +147,7 @@ symbols: - {symbol: au, type: vowel} - {symbol: ou, type: vowel} - {symbol: Ou, type: vowel} + - {symbol: '@u', type: vowel} - {symbol: 4, type: tap} - {symbol: W, type: fricative} - {symbol: 't_}', type: stop} From da00c86bd7413cb113703e4ef67edc854336145d Mon Sep 17 00:00:00 2001 From: Lotte V Date: Wed, 18 Oct 2023 00:53:12 +0200 Subject: [PATCH 14/16] Null commit to re-run AppVeyor From 19066688f53584e0a9271e74bae168482d486f9f Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Wed, 18 Oct 2023 10:25:00 +0800 Subject: [PATCH 15/16] melody encoder support --- OpenUtau.Core/DiffSinger/DiffSingerConfig.cs | 1 + OpenUtau.Core/DiffSinger/DiffSingerPitch.cs | 85 +++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/OpenUtau.Core/DiffSinger/DiffSingerConfig.cs b/OpenUtau.Core/DiffSinger/DiffSingerConfig.cs index a8b5a7f29..f75ce88dd 100644 --- a/OpenUtau.Core/DiffSinger/DiffSingerConfig.cs +++ b/OpenUtau.Core/DiffSinger/DiffSingerConfig.cs @@ -35,6 +35,7 @@ public class DsConfig { public int sample_rate = 44100; public bool predict_dur = true; public bool use_expr = false; + public bool use_note_rest = false; public float frameMs(){ return 1000f * hop_size / sample_rate; } diff --git a/OpenUtau.Core/DiffSinger/DiffSingerPitch.cs b/OpenUtau.Core/DiffSinger/DiffSingerPitch.cs index 9de9066a5..7cbec606d 100644 --- a/OpenUtau.Core/DiffSinger/DiffSingerPitch.cs +++ b/OpenUtau.Core/DiffSinger/DiffSingerPitch.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; @@ -67,6 +68,11 @@ public DiffSingerSpeakerEmbedManager getSpeakerEmbedManager(){ return speakerEmbedManager; } + void SetRange(T[] list, T value, int startIndex, int endIndex){ + for(int i=startIndex;i(); - //Pitch Predictor + //Pitch Predictor + var note_rest = new List{true}; + bool prevNoteRest = true; + int phIndex = 0; + foreach(var note in phrase.notes) { + //Slur notes follow the previous note's rest status + if(note.lyric.StartsWith("+")) { + note_rest.Add(prevNoteRest); + continue; + } + //find all the phonemes in the note's time range + while(phIndex ph.end <= note.position + 1) + .TakeWhile(ph => ph.position < note.end - 1) + .ToArray(); + //If all the phonemes in a note's time range are AP, SP or consonant, + //it is a rest note + bool isRest = phs.Length == 0 + || phs.All(ph => ph.phoneme == "AP" || ph.phoneme == "SP" || !g2p.IsVowel(ph.phoneme)); + note_rest.Add(isRest); + prevNoteRest = isRest; + } + var note_midi = phrase.notes .Select(n=>(float)n.tone) .Prepend((float)phrase.notes[0].tone) .ToArray(); + //get the index of groups of consecutive rest notes + int restGroupStart = 0; + var restGroups = new List>{}; + foreach(int noteIndex in Enumerable.Range(1,note_rest.Count - 1)) { + if(!note_rest[noteIndex-1] && note_rest[noteIndex]) { + //start a new rest group + restGroupStart = noteIndex; + } + if(note_rest[noteIndex-1] && !note_rest[noteIndex]) { + //end the current rest group + restGroups.Add(new Tuple(restGroupStart,noteIndex)); + } + } + if(!note_rest[^1]) { + //end the last rest group + restGroups.Add(new Tuple(restGroupStart,note_rest.Count)); + } + //Set tone for each rest group + foreach(var restGroup in restGroups){ + if(restGroup.Item1 == 0 && restGroup.Item2 == note_rest.Count){ + //If All the notes are rest notes, don't set tone + break; + } + if(restGroup.Item1 == 0){ + //If the first note is a rest note, set the tone to the tone of the first non-rest note + SetRange(note_midi, note_midi[restGroup.Item2], 0, restGroup.Item2); + } else if(restGroup.Item2 == note_rest.Count){ + //If the last note is a rest note, set the tone to the tone of the last non-rest note + SetRange(note_midi, note_midi[restGroup.Item1-1], restGroup.Item1, note_rest.Count); + } else { + //If the first and last notes are non-rest notes, set the tone to the nearest non-rest note + SetRange(note_midi, + note_midi[restGroup.Item1-1], + restGroup.Item1, + (restGroup.Item1 + restGroup.Item2 + 1)/2 + ); + SetRange(note_midi, + note_midi[restGroup.Item2], + (restGroup.Item1 + restGroup.Item2 + 1)/2, + restGroup.Item2 + ); + } + } + //use the delta of the positions of the next note and the current note //to prevent incorrect timing when there is a small space between two notes var note_dur = phrase.notes.Zip(phrase.notes.Skip(1), @@ -138,7 +213,6 @@ public RenderPitchResult Process(RenderPhrase phrase){ .Append(0) .ToList(); note_dur[^1]=totalFrames-note_dur.Sum(); - var pitch = Enumerable.Repeat(60f, totalFrames).ToArray(); var retake = Enumerable.Repeat(true, totalFrames).ToArray(); var speedup = Preferences.Default.DiffsingerSpeedup; @@ -185,6 +259,13 @@ public RenderPitchResult Process(RenderPhrase phrase){ pitchInputs.Add(NamedOnnxValue.CreateFromTensor("spk_embed", spkEmbedTensor)); } + //Melody encoder + if(dsConfig.use_note_rest) { + pitchInputs.Add(NamedOnnxValue.CreateFromTensor("note_rest", + new DenseTensor(note_rest.ToArray(), new int[] { note_rest.Count }, false) + .Reshape(new int[] { 1, note_rest.Count }))); + } + var pitchOutputs = pitchModel.Run(pitchInputs); var pitch_out = pitchOutputs.First().AsTensor().ToArray(); var pitchEnd = phrase.timeAxis.MsPosToTickPos(startMs + (totalFrames - 1) * frameMs) - phrase.position; From 4def4cace0d85476cf7f82efdf296b27a34bc138 Mon Sep 17 00:00:00 2001 From: Sugita Akira Date: Thu, 19 Oct 2023 20:39:48 -0700 Subject: [PATCH 16/16] Fix build --- OpenUtau.Core/Classic/ClassicRenderer.cs | 2 +- OpenUtau.Core/Classic/WorldlineRenderer.cs | 2 +- OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs | 2 +- OpenUtau.Core/Enunu/EnunuRenderer.cs | 2 +- OpenUtau.Core/Vogen/VogenRenderer.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenUtau.Core/Classic/ClassicRenderer.cs b/OpenUtau.Core/Classic/ClassicRenderer.cs index f5ea2b4e0..a4ebe403b 100644 --- a/OpenUtau.Core/Classic/ClassicRenderer.cs +++ b/OpenUtau.Core/Classic/ClassicRenderer.cs @@ -78,7 +78,7 @@ public Task RenderInternal(RenderPhrase phrase, Progress progress, VoicebankFiles.Inst.CopyBackMetaFiles(item.inputFile, item.inputTemp); } } - progress.Complete(1, $"Track {trackNo} : {item.resampler} \"{item.phone.phoneme}\""); + progress.Complete(1, $"Track {trackNo}: {item.resampler} \"{item.phone.phoneme}\""); }); var result = Layout(phrase); var wavtool = new SharpWavtool(true); diff --git a/OpenUtau.Core/Classic/WorldlineRenderer.cs b/OpenUtau.Core/Classic/WorldlineRenderer.cs index deed5fd94..b3bc19510 100644 --- a/OpenUtau.Core/Classic/WorldlineRenderer.cs +++ b/OpenUtau.Core/Classic/WorldlineRenderer.cs @@ -55,7 +55,7 @@ public Task Render(RenderPhrase phrase, Progress progress, int tra var task = Task.Run(() => { var result = Layout(phrase); var wavPath = Path.Join(PathManager.Inst.CachePath, $"wdl-{phrase.hash:x16}.wav"); - string progressInfo = $"Track {trackNo} : {this} {string.Join(" ", phrase.phones.Select(p => p.phoneme))}"; + string progressInfo = $"Track {trackNo}: {this} {string.Join(" ", phrase.phones.Select(p => p.phoneme))}"; progress.Complete(0, progressInfo); if (File.Exists(wavPath)) { try { diff --git a/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs b/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs index cdfb4420b..792c2aafb 100644 --- a/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs +++ b/OpenUtau.Core/DiffSinger/DiffSingerRenderer.cs @@ -66,7 +66,7 @@ public RenderResult Layout(RenderPhrase phrase) { }; } - public Task Render(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender) { + public Task Render(RenderPhrase phrase, Progress progress, int trackNo, CancellationTokenSource cancellation, bool isPreRender) { var task = Task.Run(() => { lock (lockObj) { if (cancellation.IsCancellationRequested) { diff --git a/OpenUtau.Core/Enunu/EnunuRenderer.cs b/OpenUtau.Core/Enunu/EnunuRenderer.cs index 4e2a43198..d5545f86a 100644 --- a/OpenUtau.Core/Enunu/EnunuRenderer.cs +++ b/OpenUtau.Core/Enunu/EnunuRenderer.cs @@ -74,7 +74,7 @@ public Task Render(RenderPhrase phrase, Progress progress, int tra if (cancellation.IsCancellationRequested) { return new RenderResult(); } - string progressInfo = $"Track {trackNo} : {this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; + string progressInfo = $"Track {trackNo}: {this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; progress.Complete(0, progressInfo); var tmpPath = Path.Join(PathManager.Inst.CachePath, $"enu-{phrase.preEffectHash:x16}"); var ustPath = tmpPath + ".tmp"; diff --git a/OpenUtau.Core/Vogen/VogenRenderer.cs b/OpenUtau.Core/Vogen/VogenRenderer.cs index d48debd27..5b3599cec 100644 --- a/OpenUtau.Core/Vogen/VogenRenderer.cs +++ b/OpenUtau.Core/Vogen/VogenRenderer.cs @@ -62,7 +62,7 @@ public Task Render(RenderPhrase phrase, Progress progress, int tra } var result = Layout(phrase); var wavPath = Path.Join(PathManager.Inst.CachePath, $"vog-{phrase.hash:x16}.wav"); - string progressInfo = $"Track {trackNo} : {this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; + string progressInfo = $"Track {trackNo}: {this} \"{string.Join(" ", phrase.phones.Select(p => p.phoneme))}\""; progress.Complete(0, progressInfo); if (File.Exists(wavPath)) { try {