Skip to content

Commit 1edf767

Browse files
maiko3tattunMaiko
andauthored
Bug fixes for envelopes, including crashes (#2214)
* Fixed a crash in edge cases during envelope manipulation * The phoneme timing reset menu includes attack and release times * Fixed a bug in “Lengthen crossfades” and improved the logic * Improved the hit-test logic for overlap points --------- Co-authored-by: Maiko <maikotattun@yahoo.co.jp>
1 parent 4ef8b1c commit 1edf767

5 files changed

Lines changed: 20 additions & 13 deletions

File tree

OpenUtau.Core/Commands/NoteCommands.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ public PhonemePreutterCommand(UVoicePart part, UNote note, int index, UPhoneme p
542542
}
543543
max = Math.Max(0, max);
544544
double min = -phoneme.autoPreutter;
545-
newDelta = (float)Math.Clamp(delta, min, max);
545+
newDelta = (float)Math.Max(Math.Min(delta, max), min);
546546
}
547547
public override void Execute() {
548548
var o = note.GetPhonemeOverride(index);
@@ -574,7 +574,7 @@ public PhonemeOverlapCommand(UVoicePart part, UNote note, int index, UPhoneme ph
574574
double overlap = phoneme.preutter - phoneme.autoOverlap;
575575
double max = phoneme.envelope.data[3].X + overlap;
576576
double min = -phoneme.Prev?.DurationMs + 5 + overlap ?? 0;
577-
newDelta = (float)Math.Clamp(delta, min, max);
577+
newDelta = (float)Math.Max(Math.Min(delta, max), min);
578578
}
579579
public override void Execute() {
580580
var o = note.GetPhonemeOverride(index);
@@ -605,7 +605,7 @@ public PhonemeAttackTimeCommand(UVoicePart part, UNote note, int index, UPhoneme
605605

606606
double max = phoneme.autoPreutter - phoneme.GetFadeIn() + phoneme.envelope.data[3].X;
607607
double min = -phoneme.GetFadeIn() + 5;
608-
newDelta = (float)Math.Clamp(delta, min, max);
608+
newDelta = (float)Math.Max(Math.Min(delta, max), min);
609609
}
610610
public override void Execute() {
611611
var o = note.GetPhonemeOverride(index);
@@ -637,7 +637,7 @@ public PhonemeReleaseTimeCommand(UVoicePart part, UNote note, int index, UPhonem
637637
var p3x = phoneme.envelope.data[4].X - phoneme.GetFadeOut();
638638
double max = p3x - phoneme.envelope.data[2].X;
639639
double min = -phoneme.GetFadeOut() + 5;
640-
newDelta = (float)Math.Clamp(delta, min, max);
640+
newDelta = (float)Math.Max(Math.Min(delta, max), min);
641641
}
642642
public override void Execute() {
643643
var o = note.GetPhonemeOverride(index);
@@ -652,7 +652,7 @@ public override void Unexecute() {
652652

653653
public class ClearPhonemeTimingCommand : NoteCommand {
654654
readonly UNote note;
655-
readonly Tuple<int, int?, float?, float?>[] oldValues;
655+
readonly Tuple<int, int?, float?, float?, float?, float?>[] oldValues;
656656
public override ValidateOptions ValidateOptions => new ValidateOptions {
657657
SkipTiming = true,
658658
Part = Part,
@@ -661,7 +661,7 @@ public class ClearPhonemeTimingCommand : NoteCommand {
661661
public ClearPhonemeTimingCommand(UVoicePart part, UNote note) : base(part, note) {
662662
this.note = note;
663663
oldValues = note.phonemeOverrides
664-
.Select(o => Tuple.Create(o.index, o.offset, o.preutterDelta, o.overlapDelta))
664+
.Select(o => Tuple.Create(o.index, o.offset, o.preutterDelta, o.overlapDelta, o.attackTimeDelta, o.releaseTimeDelta))
665665
.ToArray();
666666
}
667667

@@ -670,6 +670,8 @@ public override void Execute() {
670670
o.offset = null;
671671
o.preutterDelta = null;
672672
o.overlapDelta = null;
673+
o.attackTimeDelta = null;
674+
o.releaseTimeDelta = null;
673675
}
674676
}
675677
public override void Unexecute() {
@@ -678,6 +680,8 @@ public override void Unexecute() {
678680
o.offset = t.Item2;
679681
o.preutterDelta = t.Item3;
680682
o.overlapDelta = t.Item4;
683+
o.attackTimeDelta = t.Item5;
684+
o.releaseTimeDelta = t.Item6;
681685
}
682686
}
683687
public override string ToString() => "Clear phoneme timing";

OpenUtau.Core/Editing/NoteBatchEdits.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,13 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
313313
foreach (var note in notes) {
314314
foreach (UPhoneme phoneme in part.phonemes) {
315315
if (phoneme.Parent == note && phoneme.Prev != null && phoneme.PositionMs == phoneme.Prev.EndMs) {
316-
docManager.ExecuteCmd(new PhonemePreutterCommand(part, note, phoneme.index, phoneme, (float)phoneme.maxOtoPreutter));
317-
var overlap = phoneme.preutter * ratio;
318-
if (overlap > phoneme.autoOverlap) {
319-
docManager.ExecuteCmd(new PhonemeOverlapCommand(part, note, phoneme.index, phoneme, (float)(overlap - phoneme.autoOverlap)));
316+
var max = Math.Min(phoneme.maxOtoPreutter, phoneme.Prev.DurationMs - 5);
317+
docManager.ExecuteCmd(new PhonemePreutterCommand(part, note, phoneme.index, phoneme, (float)(max - phoneme.autoPreutter)));
318+
if (phoneme.autoOverlap > 0) {
319+
var overlap = max * ratio;
320+
if (overlap > phoneme.autoOverlap) {
321+
docManager.ExecuteCmd(new PhonemeOverlapCommand(part, note, phoneme.index, phoneme, (float)(overlap - phoneme.autoOverlap)));
322+
}
320323
}
321324
}
322325
}

OpenUtau/Controls/PianoRoll.axaml.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,8 +1308,7 @@ public void PhonemeCanvasPointerMoved(object sender, PointerEventArgs args) {
13081308
return;
13091309
}
13101310
var hitInfo = ViewModel.NotesViewModel.HitTest.HitTestPhoneme(point.Position);
1311-
var adjacent = hitInfo.phoneme != null && hitInfo.phoneme.Next != null && hitInfo.phoneme.Next.adjacent;
1312-
if (hitInfo.hitPosition || hitInfo.hitPreutter || (hitInfo.hitOverlap && adjacent) || hitInfo.hitAttackTime || hitInfo.hitReleaseTime) {
1311+
if (hitInfo.hitPosition || hitInfo.hitPreutter || hitInfo.hitOverlap || hitInfo.hitAttackTime || hitInfo.hitReleaseTime) {
13131312
Cursor = ViewConstants.cursorSizeWE;
13141313
ViewModel.MouseoverPhoneme(null);
13151314
return;

OpenUtau/Strings/Strings.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ Warning: this option removes custom presets.</system:String>
483483
<system:String x:Key="pianoroll.menu.notes.reset.all">Reset notes to default</system:String>
484484
<system:String x:Key="pianoroll.menu.notes.reset.allparameters">Reset all parameters</system:String>
485485
<system:String x:Key="pianoroll.menu.notes.reset.exps">Reset all expressions</system:String>
486-
<system:String x:Key="pianoroll.menu.notes.reset.phonemetimings">Reset phoneme timings</system:String>
486+
<system:String x:Key="pianoroll.menu.notes.reset.phonemetimings">Reset phoneme timings and envelopes</system:String>
487487
<system:String x:Key="pianoroll.menu.notes.reset.pitchbends">Reset pitch bends</system:String>
488488
<system:String x:Key="pianoroll.menu.notes.reset.vibratos">Reset vibratos</system:String>
489489
<system:String x:Key="pianoroll.menu.part">Part</system:String>

OpenUtau/ViewModels/NotesViewModelHitTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ public PhonemeHitInfo HitTestPhoneme(Point mousePos) {
386386
return result;
387387
}
388388
// p4 Overlap
389+
if (phoneme.Next == null || phoneme.Next.position != phoneme.End) continue;
389390
int p4Tick = timeAxis.MsPosToTickPos(phoneme.PositionMs + phoneme.envelope.data[4].X) - viewModel.Part.position;
390391
double p4x = viewModel.TickToneToPoint(p4Tick, 0).X;
391392
point = new Point(p4x, 60 - phoneme.envelope.data[4].Y * 0.24 - 1);

0 commit comments

Comments
 (0)