diff --git a/TuneLab/Data/Note.cs b/TuneLab/Data/Note.cs index b0321c8..b1d3989 100644 --- a/TuneLab/Data/Note.cs +++ b/TuneLab/Data/Note.cs @@ -105,10 +105,10 @@ protected override void Set(string value) { base.Set(value); mNote.Phonemes.Clear(); - mNote.Pronunciation.Set(string.Empty); + mNote.Pronunciation.Set(LyricUtils.GetPreferredPronunciation(Value)); } - Note mNote; + readonly Note mNote; } class DataPronunciation(Note note) : DataString(note) diff --git a/TuneLab/Utils/LyricUtils.cs b/TuneLab/Utils/LyricUtils.cs index d5fc751..5570c78 100644 --- a/TuneLab/Utils/LyricUtils.cs +++ b/TuneLab/Utils/LyricUtils.cs @@ -1,14 +1,34 @@ using IKg2p; +using Microsoft.International.Converters.PinYinConverter; using System.Collections.Generic; using System.Linq; +using TuneLab.Base.Structures; namespace TuneLab.Utils; internal static class LyricUtils { + public struct LyricResult + { + public string Lyric; + public string Pronunciation; + /*public IReadOnlyList Candidates;*/ + } + + public static List Split(string lyrics) + { + var g2pResults = ZhG2p.MandarinInstance.Convert(lyrics, false, true); + var results = new List(); + foreach (var g2pRes in g2pResults) + { + results.Add(new LyricResult() { Lyric = g2pRes.lyric, Pronunciation = g2pRes.syllable/*, Candidates = g2pRes.candidates*/ }); + } + return results; + } + public static List SplitLyrics(string lyrics) { - List result = new List(); + var result = new List(); var splitedLyrics = SplitByInvailidChars(lyrics); foreach (var lyric in splitedLyrics) { @@ -31,13 +51,25 @@ public static IEnumerable SplitByInvailidChars(string lyric) .Where(s => !string.IsNullOrEmpty(s)); } + public static string GetPreferredPronunciation(string lyric) + { + var pinyin = ZhG2p.MandarinInstance.Convert(lyric, false, true)[0]; + if (!pinyin.error) + return pinyin.syllable; + + return string.Empty; + } + public static IReadOnlyCollection GetPronunciations(string lyric) { if (lyric.Length == 1) { - var pinyin = ZhG2p.MandarinInstance.Convert(lyric, false, true)[0]; - if (!pinyin.error) - return new List { pinyin.syllable }.AsReadOnly(); + var c = lyric[0]; + if (ChineseChar.IsValidChar(c)) + { + var chineseChar = new ChineseChar(c); + return chineseChar.Pinyins.Take(chineseChar.PinyinCount).Convert(ToPinyin).ToHashSet(); + } } return []; @@ -49,7 +81,7 @@ static string ToPinyin(string pinyin) return string.Empty; if (char.IsNumber(pinyin[^1])) - return pinyin.Substring(0, pinyin.Length - 1).ToLower(); + return pinyin[..^1].ToLower(); return pinyin.ToLower(); } diff --git a/TuneLab/Views/LyricInput.axaml.cs b/TuneLab/Views/LyricInput.axaml.cs index 5395b62..a34b238 100644 --- a/TuneLab/Views/LyricInput.axaml.cs +++ b/TuneLab/Views/LyricInput.axaml.cs @@ -83,15 +83,20 @@ void OnLyricInputConfirm() if (mNotes.Count == 0) return; - var lyrics = LyricUtils.SplitLyrics(mLyricInputBox.Text); + var lyricResults = LyricUtils.Split(mLyricInputBox.Text); var notes = mSkipTenutoCheckBox.IsChecked ? mNotes.Where(note => note.Lyric.Value != "-") : mNotes; - using var enumerator = (mSkipTenutoCheckBox.IsChecked ? lyrics.Where(lyric => lyric != "-") : lyrics).GetEnumerator(); + using var enumerator = (mSkipTenutoCheckBox.IsChecked ? lyricResults.Where(lyricResult => lyricResult.Lyric != "-") : lyricResults).GetEnumerator(); foreach (var note in notes) { if (!enumerator.MoveNext()) break; - note.Lyric.Set(enumerator.Current); + var current = enumerator.Current; + note.Lyric.Set(current.Lyric); + if (current.Lyric == "-") + continue; + + note.Pronunciation.Set(current.Pronunciation); } mNotes.First().Commit();