Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "no value" to expression #1048

Merged
merged 1 commit into from
Feb 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions OpenUtau.Core/Commands/ExpCommands.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

using OpenUtau.Core.Ustx;
using OpenUtau.Core.Util;

Expand All @@ -24,15 +23,15 @@ public ExpCommand(UVoicePart part) {
public class SetNoteExpressionCommand : ExpCommand {
public readonly UProject project;
public readonly UTrack track;
public readonly float[] newValue;
public readonly float[] oldValue;
public SetNoteExpressionCommand(UProject project, UTrack track, UVoicePart part, UNote note, string abbr, float[] values) : base(part) {
public readonly float?[] newValue;
public readonly float?[] oldValue;
public SetNoteExpressionCommand(UProject project, UTrack track, UVoicePart part, UNote note, string abbr, float?[] values) : base(part) {
this.project = project;
this.track = track;
this.Note = note;
Key = abbr;
newValue = values;
oldValue = note.GetExpression(project, track, abbr).Select(t => t.Item1).ToArray();
oldValue = note.GetExpressionNoteHas(project, track, abbr);
}
public override string ToString() => $"Set note expression {Key}";
public override void Execute() => Note.SetExpression(project, track, Key, newValue);
Expand All @@ -47,21 +46,26 @@ public class SetPhonemeExpressionCommand : ExpCommand {
public readonly UProject project;
public readonly UTrack track;
public readonly UPhoneme phoneme;
public readonly float newValue;
public readonly float oldValue;
public readonly float? newValue;
public readonly float? oldValue;
public override ValidateOptions ValidateOptions
=> new ValidateOptions {
SkipTiming = true,
Part = Part,
SkipPhonemizer = !needsPhonemizer.Contains(Key),
};
public SetPhonemeExpressionCommand(UProject project, UTrack track, UVoicePart part, UPhoneme phoneme, string abbr, float value) : base(part) {
public SetPhonemeExpressionCommand(UProject project, UTrack track, UVoicePart part, UPhoneme phoneme, string abbr, float? value) : base(part) {
this.project = project;
this.track = track;
this.phoneme = phoneme;
Key = abbr;
newValue = value;
oldValue = phoneme.GetExpression(project, track, abbr).Item1;
var oldExp = phoneme.GetExpression(project, track, abbr);
if (oldExp.Item2) {
oldValue = oldExp.Item1;
} else {
oldValue = null;
}
}
public override string ToString() => $"Set phoneme expression {Key}";
public override void Execute() {
Expand Down
2 changes: 1 addition & 1 deletion OpenUtau.Core/Editing/LyricBatchEdits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
docManager.ExecuteCmd(new ChangeNoteLyricCommand(part, note, lyric));

int index = colors.FirstOrDefault(c => c.Value == suffix).Key;
docManager.ExecuteCmd(new SetNoteExpressionCommand(project, track, part, note, Format.Ustx.CLR, new float[] { index }));
docManager.ExecuteCmd(new SetNoteExpressionCommand(project, track, part, note, Format.Ustx.CLR, new float?[] { index }));
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions OpenUtau.Core/Editing/NoteBatchEdits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (note.lyric != lyric && (note.Next == null || note.Next.position > note.End + 120)) {
var addNote = project.CreateNote(note.tone, note.End, 120);
foreach(var exp in note.phonemeExpressions.OrderBy(exp => exp.index)) {
addNote.SetExpression(project, project.tracks[part.trackNo], exp.abbr, new float[] { exp.value });
addNote.SetExpression(project, project.tracks[part.trackNo], exp.abbr, new float?[] { exp.value });
}
toAdd.Add(addNote);
}
Expand Down Expand Up @@ -99,7 +99,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
}
var addNote = project.CreateNote(note.tone, note.position - duration, duration);
foreach (var exp in note.phonemeExpressions.Where(exp => exp.index == 0)) {
addNote.SetExpression(project, project.tracks[part.trackNo], exp.abbr, new float[] { exp.value });
addNote.SetExpression(project, project.tracks[part.trackNo], exp.abbr, new float?[] { exp.value });
}
toAdd.Add(addNote);
}
Expand Down
35 changes: 29 additions & 6 deletions OpenUtau.Core/Ustx/UNote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class UNote : IComparable {
[YamlIgnore] public int RightBound => position + duration;
[YamlIgnore] public bool Error { get; set; } = false;
[YamlIgnore] public bool OverlapError { get; set; } = false;
[YamlIgnore] public List<UExpression> phonemizerExpressions = new List<UExpression>();

public static UNote Create() {
var note = new UNote();
Expand Down Expand Up @@ -165,38 +166,60 @@ public List<Tuple<float, bool>> GetExpression(UProject project, UTrack track, st
if (phonemeExp != null) {
list.Add(Tuple.Create(phonemeExp.value, true));
} else {
list.Add(Tuple.Create(trackExp.value, false));
var phonemizerExp = phonemizerExpressions.FirstOrDefault(exp => exp.descriptor?.abbr == abbr && exp.index == i);
if (phonemizerExp != null) {
list.Add(Tuple.Create(phonemizerExp.value, false));
} else {
list.Add(Tuple.Create(trackExp.value, false));
}
}
}
return list;
}

public void SetExpression(UProject project, UTrack track, string abbr, float[] values) {
/// <summary>
/// Returns value if phoneme has expression, null otherwise.
/// </summary>
public float?[] GetExpressionNoteHas(UProject project, UTrack track, string abbr) {
var list = new List<float?>();
int indexes = (phonemeExpressions.Max(exp => exp.index) ?? 0) + 1;
for (int i = 0; i < indexes; i++) {
var phonemeExp = phonemeExpressions.FirstOrDefault(exp => exp.descriptor?.abbr == abbr && exp.index == i);
if (phonemeExp != null) {
list.Add(phonemeExp.value);
} else {
list.Add(null);
}
}
return list.ToArray();
}

public void SetExpression(UProject project, UTrack track, string abbr, float?[] values) {
if (!track.TryGetExpression(project, abbr, out UExpression trackExp)) {
return;
}
int indexes = (phonemeExpressions.Max(exp => exp.index) ?? 0) + 1;

for (int i = 0; i < indexes; i++) {
float value;
float? value;
if (values.Length > i) {
value = values[i];
} else {
value = values.Last();
}

if (trackExp.value == value) {
if (value == null) {
phonemeExpressions.RemoveAll(exp => exp.descriptor?.abbr == abbr && exp.index == i);
continue;
}
var phonemeExp = phonemeExpressions.FirstOrDefault(exp => exp.descriptor?.abbr == abbr && exp.index == i);
if (phonemeExp != null) {
phonemeExp.descriptor = trackExp.descriptor;
phonemeExp.value = value;
phonemeExp.value = (float)value;
} else {
phonemeExpressions.Add(new UExpression(trackExp.descriptor) {
index = i,
value = value,
value = (float)value,
});
}
}
Expand Down
20 changes: 11 additions & 9 deletions OpenUtau.Core/Ustx/UPhoneme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,22 @@ void ValidateEnvelope(UProject project, UTrack track, UNote note) {
envelope.data[4] = p4;
}

/**
<summary>
If the phoneme does not have the corresponding expression, return the track's expression and false
</summary>
*/
/// <summary>
/// If the phoneme does not have the corresponding expression, return the track's expression and false
/// <summary>
public Tuple<float, bool> GetExpression(UProject project, UTrack track, string abbr) {
track.TryGetExpression(project, abbr, out UExpression trackExp);
var note = Parent.Extends ?? Parent;
var phonemeExp = note.phonemeExpressions.FirstOrDefault(
exp => exp.descriptor?.abbr == abbr && exp.index == index);
var phonemeExp = note.phonemeExpressions.FirstOrDefault(exp => exp.descriptor?.abbr == abbr && exp.index == index);
if (phonemeExp != null) {
return Tuple.Create(phonemeExp.value, true);
} else {
return Tuple.Create(trackExp.value, false);
var phonemizerExp = note.phonemizerExpressions.FirstOrDefault(exp => exp.descriptor?.abbr == abbr && exp.index == index);
if (phonemizerExp != null) {
return Tuple.Create(phonemizerExp.value, false);
} else {
return Tuple.Create(trackExp.value, false);
}
}
}

Expand All @@ -187,7 +189,7 @@ public void SetExpression(UProject project, UTrack track, string abbr, float? va
return;
}
var note = Parent.Extends ?? Parent;
if (value == null || trackExp.value == value) {
if (value == null) {
note.phonemeExpressions.RemoveAll(exp => exp.descriptor?.abbr == abbr && exp.index == index);
} else {
var phonemeExp = note.phonemeExpressions.FirstOrDefault(exp => exp.descriptor?.abbr == abbr && exp.index == index);
Expand Down
4 changes: 3 additions & 1 deletion OpenUtau/Controls/ExpressionCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ public override void Render(DrawingContext context) {
double y = optionHeight * (descriptor.options.Length - 1 - i + 0.5);
using (var state = context.PushTransform(Matrix.CreateTranslation(x1 + 4.5, y))) {
if ((int)value == i) {
context.DrawGeometry(brush, null, pointGeometry);
if (overriden) {
context.DrawGeometry(brush, null, pointGeometry);
}
context.DrawGeometry(null, hPen, circleGeometry);
} else {
context.DrawGeometry(null, ThemeManager.NeutralAccentPenSemi, circleGeometry);
Expand Down
2 changes: 1 addition & 1 deletion OpenUtau/Controls/NotePropertyExpression.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:vm="using:OpenUtau.App.ViewModels"
x:Class="OpenUtau.App.Controls.NotePropertyExpression">
<Grid ColumnDefinitions="143,7,50,20,*">
<Label Content="{Binding Name}" Grid.Column="0" VerticalAlignment="Center"/>
<Label Content="{Binding Name}" Grid.Column="0" VerticalAlignment="Center" FontWeight="{Binding NameFontWeight}"/>
<TextBox Text="{Binding Value, Mode=OneWay}" Grid.Column="2" IsVisible="{Binding IsNumerical}" VerticalAlignment="Center" IsEnabled="{Binding IsNoteSelected}"
GotFocus="OnTextBoxGotFocus" LostFocus="OnTextBoxLostFocus"/>
<Slider Grid.Column="4" Classes="fader" Value="{Binding Value, Mode=OneWay}" Minimum="{Binding Min}" Maximum="{Binding Max}"
Expand Down
33 changes: 27 additions & 6 deletions OpenUtau/ViewModels/NotePropertiesViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using Avalonia.Media;
using OpenUtau.Core;
using OpenUtau.Core.Format;
using OpenUtau.Core.Ustx;
Expand Down Expand Up @@ -193,17 +194,25 @@ private void AttachExpressions() {
} else if (exp.IsOptions) {
exp.SelectedOption = (int)phonemeExpression.value;
}
exp.HasValue = true;
} else {
if (exp.IsNumerical) {
exp.Value = exp.defaultValue;
} else if (exp.IsOptions) {
exp.SelectedOption = (int)exp.defaultValue;
}

if (selectedNotes.Any(note => note.phonemeExpressions.FirstOrDefault(e => e.abbr == exp.abbr) != null)) {
exp.HasValue = true;
} else {
exp.HasValue = false;
}
}
}
} else {
foreach (NotePropertyExpViewModel exp in Expressions) {
exp.IsNoteSelected = false;
exp.HasValue = false;
if (exp.IsNumerical) {
exp.Value = exp.defaultValue;
} else if (exp.IsOptions) {
Expand Down Expand Up @@ -456,7 +465,7 @@ public void SetVibratoEnable() {
DocManager.Inst.EndUndoGroup();
}
}
public void SetNumericalExpressionsChanges(string abbr, float value) {
public void SetNumericalExpressionsChanges(string abbr, float? value) {
if (AllowNoteEdit && Part != null && selectedNotes.Count > 0) {
var track = DocManager.Inst.Project.tracks[Part.trackNo];

Expand All @@ -469,7 +478,7 @@ public void SetNumericalExpressionsChanges(string abbr, float value) {
}
}
}
public void SetOptionalExpressionsChanges(string abbr, int value) {
public void SetOptionalExpressionsChanges(string abbr, int? value) {
if (!NoteLoading && Part != null && selectedNotes.Count > 0) {
var track = DocManager.Inst.Project.tracks[Part.trackNo];
DocManager.Inst.StartUndoGroup();
Expand Down Expand Up @@ -534,6 +543,8 @@ public class NotePropertyExpViewModel : ViewModelBase {
[Reactive] public float Value { get; set; }
[Reactive] public int SelectedOption { get; set; }
[Reactive] public bool DropDownOpen { get; set; }
[Reactive] public bool HasValue { get; set; } = false;
[Reactive] public FontWeight NameFontWeight { get; set; }

private NotePropertiesViewModel parentViewmodel;

Expand Down Expand Up @@ -562,14 +573,24 @@ public NotePropertyExpViewModel(UExpressionDescriptor descriptor, NoteProperties
}
});
}

this.WhenAnyValue(vm => vm.HasValue)
.Subscribe(value => {
if (value) {
NameFontWeight = FontWeight.Bold;
} else {
NameFontWeight = FontWeight.Normal;
}
});
}

public void SetNumericalExpressions(object? obj) {
float value;
if (obj != null && (obj is float f || float.TryParse(obj.ToString(), out f)) && f >= Min && f <= Max) {
float? value = null;
if (obj != null && (obj is float f || float.TryParse(obj.ToString(), out f))) {
if (f < Min && f > Max) {
return;
}
value = f;
} else {
value = defaultValue;
}
parentViewmodel.SetNumericalExpressionsChanges(abbr, value);
this.RaisePropertyChanged(nameof(Value));
Expand Down
2 changes: 1 addition & 1 deletion OpenUtau/ViewModels/NotesViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ public async void PasteSelectedParams(PianoRollWindow window) {
break;
default:
if (vm.Params[i].IsSelected) {
float[] values = copyNote.GetExpression(Project, track, vm.Params[i].Abbr).Select(t => t.Item1).ToArray();
float?[] values = copyNote.GetExpressionNoteHas(Project, track, vm.Params[i].Abbr);
DocManager.Inst.ExecuteCmd(new SetNoteExpressionCommand(Project, track, Part, note, vm.Params[i].Abbr, values));
}
break;
Expand Down
Loading