public override void BeforeSave(UProject project, UTrack track) { foreach (var note in notes) { note.BeforeSave(project, track, this); } }
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 override void AfterLoad(UProject project, UTrack track) { foreach (var note in notes) { note.AfterLoad(project, track, this); } Duration = GetBarDurTick(project); }
public void AfterLoad(UProject project, UTrack track, UVoicePart part) { foreach (var exp in noteExpressions) { exp.descriptor = project.expressions[exp.abbr]; } foreach (var exp in phonemeExpressions) { exp.descriptor = project.expressions[exp.abbr]; } }
public void BeforeSave(UProject project, UTrack track, UVoicePart part) { noteExpressions.ForEach(exp => exp.index = null); noteExpressions = noteExpressions .OrderBy(exp => exp.abbr) .ToList(); phonemeExpressions = phonemeExpressions .OrderBy(exp => exp.index) .ThenBy(exp => exp.abbr) .ToList(); }
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); } }
public void Phonemize(UProject project, UTrack track) { if (track.Singer == null || !track.Singer.Loaded) { return; } if (Extends != null) { return; } List <UNote> notes = new List <UNote> { this }; while (notes.Last().Next != null && notes.Last().Next.Extends == this) { notes.Add(notes.Last().Next); } int endOffset = 0; if (notes.Last().Next != null && notes.Last().Next.phonemes.Count > 0) { endOffset = Math.Min(0, notes.Last().Next.position - notes.Last().End + notes.Last().Next.phonemes[0].position); } var prev = Prev?.ToProcessorNote(); var next = notes.Last().Next?.ToProcessorNote(); bool prevIsNeighbour = Prev?.End >= position; if (Prev?.Extends != null) { prev = Prev.Extends.ToProcessorNote(); var phoneme = prev.Value; phoneme.duration = Prev.ExtendedDuration; prev = phoneme; } bool nextIsNeighbour = notes.Last().End >= notes.Last().Next?.position; track.Phonemizer.SetTiming(project.bpm, project.beatUnit, project.resolution); var phonemizerNotes = notes.Select(note => note.ToProcessorNote()).ToArray(); phonemizerNotes[phonemizerNotes.Length - 1].duration += endOffset; if (string.IsNullOrEmpty(phonemizerNotes[0].lyric) && string.IsNullOrEmpty(phonemizerNotes[0].phoneticHint)) { phonemes.Clear(); return; } Phonemizer.Result phonemizerResult; try { phonemizerResult = track.Phonemizer.Process( phonemizerNotes, prev, next, prevIsNeighbour ? prev : null, nextIsNeighbour ? next : null); } catch (Exception e) { Log.Error(e, "phonemizer error"); phonemizerResult = new Phonemizer.Result() { phonemes = new Phonemizer.Phoneme[] { new Phonemizer.Phoneme { phoneme = "error" } } }; } var newPhonemes = phonemizerResult.phonemes; // Apply overrides. for (int i = phonemeOverrides.Count - 1; i >= 0; --i) { if (phonemeOverrides[i].IsEmpty) { phonemeOverrides.RemoveAt(i); } } foreach (var o in phonemeOverrides) { if (o.index >= 0 && o.index < newPhonemes.Length) { var p = newPhonemes[o.index]; if (o.phoneme != null) { p.phoneme = o.phoneme; } if (o.offset != null) { p.position += o.offset.Value; } newPhonemes[o.index] = p; } } // Safety treatment after phonemizer output and phoneme overrides. int maxPostion = notes.Last().End - notes.First().position + endOffset - 10; for (int i = newPhonemes.Length - 1; i >= 0; --i) { var p = newPhonemes[i]; p.position = Math.Min(p.position, maxPostion); newPhonemes[i] = p; maxPostion = p.position - 10; } DistributePhonemes(notes, newPhonemes); }
public void Validate(UProject project, UTrack track, UVoicePart part) { duration = Math.Max(10, duration); if (Prev != null && Prev.End > position) { Error = true; OverlapError = true; return; } Error = false; OverlapError = false; if (track.Singer == null || !track.Singer.Loaded) { Error |= true; } if (pitch.snapFirst) { if (Prev != null && Prev.End == position) { pitch.data[0].Y = (Prev.tone - tone) * 10; } else { pitch.data[0].Y = 0; } } for (var i = 0; i < phonemes.Count; i++) { var phoneme = phonemes[i]; phoneme.Parent = this; phoneme.Index = i; } foreach (var phoneme in phonemes) { phoneme.Validate(project, track, part, this); Error |= phoneme.Error; } // Update has override bits. foreach (var phoneme in phonemes) { phoneme.HasPhonemeOverride = false; phoneme.HasOffsetOverride = false; phoneme.preutterScale = null; phoneme.overlapScale = null; } foreach (var o in (Extends ?? this).phonemeOverrides) { int index = o.index - PhonemeOffset; if (index >= 0 && index < phonemes.Count) { if (o.phoneme != null) { phonemes[index].HasPhonemeOverride = true; } if (o.offset != null) { phonemes[index].HasOffsetOverride = true; } phonemes[index].preutterScale = o.preutterScale; phonemes[index].overlapScale = o.overlapScale; } } }
public virtual void Validate(UProject project, UTrack track) { }
public virtual void AfterLoad(UProject project, UTrack track) { }
public virtual void BeforeSave(UProject project, UTrack track) { }