From 9fa45457588aee786a7fcc0c7133b21fa83194ed Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Sat, 7 Oct 2023 16:51:23 +0800 Subject: [PATCH 1/4] show scale degree --- OpenUtau.Core/Commands/ProjectCommands.cs | 12 +++++++ OpenUtau.Core/Ustx/UProject.cs | 1 + OpenUtau.Core/Util/MusicMath.cs | 30 ++++++++++++++++ OpenUtau.Core/Util/Preferences.cs | 1 + OpenUtau/Controls/TrackBackground.cs | 38 ++++++++++++++++++--- OpenUtau/Strings/Strings.axaml | 5 +++ OpenUtau/ViewModels/PlaybackViewModel.cs | 13 +++++++ OpenUtau/ViewModels/PreferencesViewModel.cs | 7 ++++ OpenUtau/Views/KeyDialog.axaml | 21 ++++++++++++ OpenUtau/Views/KeyDialog.axaml.cs | 30 ++++++++++++++++ OpenUtau/Views/MainWindow.axaml | 12 +++++-- OpenUtau/Views/MainWindow.axaml.cs | 13 ++++++- OpenUtau/Views/PreferencesDialog.axaml | 6 ++++ 13 files changed, 181 insertions(+), 8 deletions(-) create mode 100644 OpenUtau/Views/KeyDialog.axaml create mode 100644 OpenUtau/Views/KeyDialog.axaml.cs diff --git a/OpenUtau.Core/Commands/ProjectCommands.cs b/OpenUtau.Core/Commands/ProjectCommands.cs index a61b8d8d4..f279c32c2 100644 --- a/OpenUtau.Core/Commands/ProjectCommands.cs +++ b/OpenUtau.Core/Commands/ProjectCommands.cs @@ -140,6 +140,18 @@ public override void Unexecute() { } } + public class KeyCommand : ProjectCommand{ + public readonly int oldKey; + public readonly int newKey; + public KeyCommand(UProject project, int key) : base(project) { + oldKey = project.key; + newKey = key; + } + public override string ToString() => $"Change key from {oldKey} to {newKey}"; + public override void Execute() => project.key = newKey; + public override void Unexecute() => project.key = oldKey; + } + public class ConfigureExpressionsCommand : ProjectCommand { readonly UExpressionDescriptor[] oldDescriptors; readonly UExpressionDescriptor[] newDescriptors; diff --git a/OpenUtau.Core/Ustx/UProject.cs b/OpenUtau.Core/Ustx/UProject.cs index 0bbf5193f..974fb00c7 100644 --- a/OpenUtau.Core/Ustx/UProject.cs +++ b/OpenUtau.Core/Ustx/UProject.cs @@ -48,6 +48,7 @@ public class UProject { public string[] expSelectors = new string[] { Format.Ustx.DYN, Format.Ustx.PITD, Format.Ustx.CLR, Format.Ustx.ENG, Format.Ustx.VEL }; public int expPrimary = 0; public int expSecondary = 1; + public int key = 0;//Music key of the project, 0 = C, 1 = C#, 2 = D, ..., 11 = B public List timeSignatures; public List tempos; public List tracks; diff --git a/OpenUtau.Core/Util/MusicMath.cs b/OpenUtau.Core/Util/MusicMath.cs index 4a4b85d60..f8123bd9a 100644 --- a/OpenUtau.Core/Util/MusicMath.cs +++ b/OpenUtau.Core/Util/MusicMath.cs @@ -32,6 +32,36 @@ public enum KeyColor { White, Black } { "B", 11 }, }; + public static readonly string[] Solfeges = { + "do", + "", + "re", + "", + "mi", + "fa", + "", + "sol", + "", + "la", + "", + "ti", + }; + + public static readonly string[] NumberedNotations = { + "1", + "", + "2", + "", + "3", + "4", + "", + "5", + "", + "6", + "", + "7", + }; + public static string GetToneName(int noteNum) { return noteNum < 0 ? string.Empty : KeysInOctave[noteNum % 12].Item1 + (noteNum / 12 - 1).ToString(); } diff --git a/OpenUtau.Core/Util/Preferences.cs b/OpenUtau.Core/Util/Preferences.cs index b2ef443c5..88f80b679 100644 --- a/OpenUtau.Core/Util/Preferences.cs +++ b/OpenUtau.Core/Util/Preferences.cs @@ -112,6 +112,7 @@ public class SerializablePreferences { public bool ShowPrefs = true; public bool ShowTips = true; public int Theme; + public int DegreeStyle; public bool UseTrackColor = false; public bool ClearCacheOnQuit = false; public bool PreRender = true; diff --git a/OpenUtau/Controls/TrackBackground.cs b/OpenUtau/Controls/TrackBackground.cs index e44606742..0b4a1e441 100644 --- a/OpenUtau/Controls/TrackBackground.cs +++ b/OpenUtau/Controls/TrackBackground.cs @@ -1,9 +1,11 @@ using System; +using System.Linq; using System.Reactive.Linq; using Avalonia; using Avalonia.Controls.Primitives; using Avalonia.Media; using OpenUtau.Core; +using OpenUtau.Core.Util; using ReactiveUI; namespace OpenUtau.App.Controls { @@ -65,12 +67,29 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang } } + int mod(int a, int b){ + return (a % b + b) % b; + } + public override void Render(DrawingContext context) { if (TrackHeight == 0) { return; } int track = (int)TrackOffset; double top = TrackHeight * (track - TrackOffset); + int key = DocManager.Inst.Project == null ? 0 : DocManager.Inst.Project.key; + string[] degreeNames; + switch(Preferences.Default.DegreeStyle){ + case 1: + degreeNames = MusicMath.Solfeges; + break; + case 2: + degreeNames = MusicMath.NumberedNotations; + break; + default: + degreeNames = Enumerable.Repeat("", 12).ToArray(); + break; + } while (top < Bounds.Height) { bool isAltTrack = IsAltTrack(track) ^ (ThemeManager.IsDarkMode && !IsKeyboard); bool isCenterKey = IsKeyboard && IsCenterKey(track); @@ -85,11 +104,20 @@ public override void Render(DrawingContext context) { brush = isCenterKey ? ThemeManager.CenterKeyNameBrush : isAltTrack ? ThemeManager.BlackKeyNameBrush : ThemeManager.WhiteKeyNameBrush; - string toneName = MusicMath.GetToneName(ViewConstants.MaxTone - 1 - track); - var textLayout = TextLayoutCache.Get(toneName, brush, 12); - var textPosition = new Point(Bounds.Width - 4 - (int)textLayout.Width, (int)(top + (TrackHeight - textLayout.Height) / 2)); - using (var state = context.PushTransform(Matrix.CreateTranslation(textPosition))) { - textLayout.Draw(context, new Point()); + int tone = ViewConstants.MaxTone - 1 - track; + string toneName = MusicMath.GetToneName(tone); + var toneTextLayout = TextLayoutCache.Get(toneName, brush, 12); + var toneTextPosition = new Point(Bounds.Width - 4 - (int)toneTextLayout.Width, (int)(top + (TrackHeight - toneTextLayout.Height) / 2)); + using (var state = context.PushTransform(Matrix.CreateTranslation(toneTextPosition))) { + toneTextLayout.Draw(context, new Point()); + } + //scale degree display + int degree = mod(tone - key, 12); + string degreeName = degreeNames[degree]; + var degreeTextLayout = TextLayoutCache.Get(degreeName, brush, 12); + var degreeTextPosition = new Point(4, (int)(top + (TrackHeight - degreeTextLayout.Height) / 2)); + using (var state = context.PushTransform(Matrix.CreateTranslation(degreeTextPosition))) { + degreeTextLayout.Draw(context, new Point()); } } track++; diff --git a/OpenUtau/Strings/Strings.axaml b/OpenUtau/Strings/Strings.axaml index 2797c2935..448735777 100644 --- a/OpenUtau/Strings/Strings.axaml +++ b/OpenUtau/Strings/Strings.axaml @@ -34,6 +34,7 @@ Save project file first Installing phonemizer Installing + Key Cancel No Ok @@ -284,6 +285,10 @@ Stable vLabeler Path Appearance + Scale degree display style + Numbered (1 2 3 4 5 6 7) + Off + Solfège (do re mi fa sol la ti) Language Show other tracks' notes on piano roll Show portrait on piano roll diff --git a/OpenUtau/ViewModels/PlaybackViewModel.cs b/OpenUtau/ViewModels/PlaybackViewModel.cs index de6c4eadf..dcfd82a75 100644 --- a/OpenUtau/ViewModels/PlaybackViewModel.cs +++ b/OpenUtau/ViewModels/PlaybackViewModel.cs @@ -11,6 +11,8 @@ public class PlaybackViewModel : ViewModelBase, ICmdSubscriber { public int BeatPerBar => Project.timeSignatures[0].beatPerBar; public int BeatUnit => Project.timeSignatures[0].beatUnit; public double Bpm => Project.tempos[0].bpm; + public int Key => Project.key; + public string KeyName => MusicMath.KeysInOctave[Key].Item1; public int Resolution => Project.resolution; public int PlayPosTick => DocManager.Inst.playPosTick; public TimeSpan PlayPosTime => TimeSpan.FromMilliseconds((int)Project.timeAxis.TickPosToMsPos(DocManager.Inst.playPosTick)); @@ -61,6 +63,15 @@ public void SetBpm(double bpm) { DocManager.Inst.EndUndoGroup(); } + public void SetKey(int key) { + if (key == DocManager.Inst.Project.key) { + return; + } + DocManager.Inst.StartUndoGroup(); + DocManager.Inst.ExecuteCmd(new KeyCommand(Project, key)); + DocManager.Inst.EndUndoGroup(); + } + public void OnNext(UCommand cmd, bool isUndo) { if (cmd is BpmCommand || cmd is TimeSignatureCommand || @@ -68,10 +79,12 @@ cmd is AddTempoChangeCommand || cmd is DelTempoChangeCommand || cmd is AddTimeSigCommand || cmd is DelTimeSigCommand || + cmd is KeyCommand || cmd is LoadProjectNotification) { this.RaisePropertyChanged(nameof(BeatPerBar)); this.RaisePropertyChanged(nameof(BeatUnit)); this.RaisePropertyChanged(nameof(Bpm)); + this.RaisePropertyChanged(nameof(KeyName)); MessageBus.Current.SendMessage(new TimeAxisChangedEvent()); if (cmd is LoadProjectNotification) { DocManager.Inst.ExecuteCmd(new SetPlayPosTickNotification(0)); diff --git a/OpenUtau/ViewModels/PreferencesViewModel.cs b/OpenUtau/ViewModels/PreferencesViewModel.cs index 6b348aed7..e8d7414ea 100644 --- a/OpenUtau/ViewModels/PreferencesViewModel.cs +++ b/OpenUtau/ViewModels/PreferencesViewModel.cs @@ -40,6 +40,7 @@ public AudioOutputDevice? AudioOutputDevice { [Reactive] public GpuInfo OnnxGpu { get; set; } [Reactive] public bool HighThreads { get; set; } [Reactive] public int Theme { get; set; } + [Reactive] public int DegreeStyle { get; set; } [Reactive] public bool UseTrackColor { get; set; } [Reactive] public bool ShowPortrait { get; set; } [Reactive] public bool ShowGhostNotes { get; set; } @@ -131,6 +132,7 @@ public PreferencesViewModel() { OnnxGpuOptions = Onnx.getGpuInfo(); OnnxGpu = OnnxGpuOptions.FirstOrDefault(x => x.deviceId == Preferences.Default.OnnxGpu, OnnxGpuOptions[0]); Theme = Preferences.Default.Theme; + DegreeStyle = Preferences.Default.DegreeStyle; UseTrackColor = Preferences.Default.UseTrackColor; ShowPortrait = Preferences.Default.ShowPortrait; ShowGhostNotes = Preferences.Default.ShowGhostNotes; @@ -202,6 +204,11 @@ public PreferencesViewModel() { Preferences.Save(); App.SetTheme(); }); + this.WhenAnyValue(vm => vm.DegreeStyle) + .Subscribe(degreeStyle => { + Preferences.Default.DegreeStyle = degreeStyle; + Preferences.Save(); + }); this.WhenAnyValue(vm => vm.UseTrackColor) .Subscribe(trackColor => { Preferences.Default.UseTrackColor = trackColor; diff --git a/OpenUtau/Views/KeyDialog.axaml b/OpenUtau/Views/KeyDialog.axaml new file mode 100644 index 000000000..aca4ab3e6 --- /dev/null +++ b/OpenUtau/Views/KeyDialog.axaml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/OpenUtau/Views/PianoRollWindow.axaml.cs b/OpenUtau/Views/PianoRollWindow.axaml.cs index f85129c9f..459f30910 100644 --- a/OpenUtau/Views/PianoRollWindow.axaml.cs +++ b/OpenUtau/Views/PianoRollWindow.axaml.cs @@ -802,6 +802,19 @@ void OnSnapDivKeyDown(object sender, KeyEventArgs e) { } } + public void OnKeyMenuButton(object sender, RoutedEventArgs args) { + KeyMenu.PlacementTarget = sender as Button; + KeyMenu.Open(); + } + + void OnKeyKeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Enter && e.KeyModifiers == KeyModifiers.None) { + if (sender is ContextMenu menu && menu.SelectedItem is MenuItemViewModel item) { + item.Command?.Execute(item.CommandParameter); + } + } + } + #region value tip void IValueTip.ShowValueTip() { From b230415f73fc9a8a01a2399cbbf6170cc89d71e7 Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:25:20 +0800 Subject: [PATCH 3/4] resolve conflict --- OpenUtau/Views/PianoRollWindow.axaml | 541 +++++++++++++-------------- 1 file changed, 259 insertions(+), 282 deletions(-) diff --git a/OpenUtau/Views/PianoRollWindow.axaml b/OpenUtau/Views/PianoRollWindow.axaml index f9fabc1c0..a6c6f13e9 100644 --- a/OpenUtau/Views/PianoRollWindow.axaml +++ b/OpenUtau/Views/PianoRollWindow.axaml @@ -14,10 +14,10 @@ - - + + @@ -31,14 +31,14 @@ - + - - - - + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + - - + - @@ -434,7 +412,7 @@ - - - - - - - - - - - + - @@ -518,20 +496,19 @@ Text="{DynamicResource tip.exps}"/> - - + - + - - + From 6a9a8670fdc847d0a295a2276646863ba1a8158f Mon Sep 17 00:00:00 2001 From: oxygen-dioxide <54425948+oxygen-dioxide@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:36:45 +0800 Subject: [PATCH 4/4] add back --- OpenUtau/Views/PianoRollWindow.axaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/OpenUtau/Views/PianoRollWindow.axaml b/OpenUtau/Views/PianoRollWindow.axaml index a6c6f13e9..51d890a0b 100644 --- a/OpenUtau/Views/PianoRollWindow.axaml +++ b/OpenUtau/Views/PianoRollWindow.axaml @@ -394,6 +394,20 @@ +