void ValidateOto(UTrack track, UNote note) { phonemeMapped = string.Empty; if (Error) { return; } if (track.Singer == null || !track.Singer.Loaded) { Error = true; return; } // Load oto. if (track.Singer.TryGetMappedOto(phoneme, note.tone, out var oto)) { this.oto = oto; Error = false; phonemeMapped = oto.Alias; } else { this.oto = default; Error = true; phonemeMapped = string.Empty; } }
public void Validate(UProject project, UTrack track, UVoicePart part, UNote note) { Error = note.Error; ValidateDuration(note); ValidateOto(track, note); ValidateOverlap(project, note); ValidateEnvelope(project, note); }
public static UNote Create() { var note = new UNote(); note.pitch = new UPitch(); note.vibrato = new UVibrato(); return(note); }
public UNote CreateNote() { UNote note = UNote.Create(); note.pitch.AddPoint(new PitchPoint(-25, 0)); note.pitch.AddPoint(new PitchPoint(25, 0)); return(note); }
public override void Validate(UProject project, UTrack track) { UNote lastNote = null; foreach (UNote note in notes) { note.Prev = lastNote; note.Next = null; if (lastNote != null) { lastNote.Next = note; } lastNote = note; } foreach (UNote note in notes) { note.ExtendedDuration = note.duration; if (note.Prev != null && note.Prev.End == note.position && note.lyric.StartsWith("...")) { note.Extends = note.Prev.Extends ?? note.Prev; note.Extends.ExtendedDuration = note.End - note.Extends.position; } else { note.Extends = null; } } foreach (UNote note in notes.Reverse()) { note.Phonemize(project, track); } UPhoneme lastPhoneme = null; foreach (UNote note in notes) { foreach (var phoneme in note.phonemes) { phoneme.Parent = note; phoneme.Prev = lastPhoneme; phoneme.Next = null; if (lastPhoneme != null) { lastPhoneme.Next = phoneme; } lastPhoneme = phoneme; } } foreach (UNote note in notes) { note.Validate(project, track, this); } }
void ValidateOverlap(UProject project, UNote note) { if (Error) { return; } float consonantStretch = (float)Math.Pow(2f, 1.0f - GetExpression(project, "vel").Item1 / 100f); overlap = (float)oto.Overlap * consonantStretch * (overlapScale ?? 1); preutter = (float)oto.Preutter * consonantStretch * (preutterScale ?? 1); overlapped = false; if (Prev == null) { return; } int gapTick = Parent.position + position - (Prev.Parent.position + Prev.End); float gapMs = (float)project.TickToMillisecond(gapTick); float maxPreutter = preutter; if (gapMs <= 0) { // Keep at least half of last phoneme, or 10% if preutterScale is set. overlapped = true; maxPreutter = (float)project.TickToMillisecond(Prev.Duration) * (preutterScale == null ? 0.5f : 0.9f); } else if (gapMs < preutter) { maxPreutter = gapMs; } if (preutter > maxPreutter) { float ratio = maxPreutter / preutter; preutter = maxPreutter; overlap *= ratio; } preutter = Math.Max(0, preutter); overlap = Math.Min(overlap, preutter); Prev.tailIntrude = overlapped ? preutter : 0; Prev.tailOverlap = overlapped ? overlap : 0; Prev.ValidateEnvelope(project, Prev.Parent); if (Next == null) { tailIntrude = 0; tailOverlap = 0; } }
public UstxSerializationTest(ITestOutputHelper output) { this.output = output; descriptor = new UExpressionDescriptor("velocity", "vel", 0, 200, 100); note = UNote.Create(); note.position = 120; note.duration = 60; note.tone = 42; note.lyric = "あ"; note.noteExpressions.Add(new UExpression(descriptor) { value = 99, }); note.phonemeExpressions.Add(new UExpression(descriptor) { index = 0, value = 123, }); }
void ValidateDuration(UNote note) { if (Error) { return; } if (Parent.Extends != null) { Duration = Parent.Extends.ExtendedEnd - Parent.position - position; } else { Duration = Parent.ExtendedDuration - position; } if (Next != null) { Duration = Math.Min(Duration, Next.Parent.position + Next.position - (Parent.position + position)); } Error = Duration <= 0; }
void ValidateEnvelope(UProject project, UNote note) { if (Error) { return; } var vol = GetExpression(project, "vol").Item1; var atk = GetExpression(project, "atk").Item1; var dec = GetExpression(project, "dec").Item1; Vector2 p0, p1, p2, p3, p4; p0.X = -preutter; p1.X = p0.X + (overlapped ? overlap : 5f); p2.X = Math.Max(0f, p1.X); p3.X = (float)project.TickToMillisecond(Duration) - (float)tailIntrude; p4.X = p3.X + (float)tailOverlap; if (p3.X == p4.X) { p3.X = Math.Max(p2.X, p3.X - 25f); } p0.Y = 0f; p1.Y = vol; p1.X = p0.X + (overlapped ? overlap : 5f); p1.Y = atk * vol / 100f; p2.Y = vol; p3.Y = vol * (1f - dec / 100f); p4.Y = 0f; envelope.data[0] = p0; envelope.data[1] = p1; envelope.data[2] = p2; envelope.data[3] = p3; envelope.data[4] = p4; }