Skip to content

Commit

Permalink
中文歌词支持
Browse files Browse the repository at this point in the history
  • Loading branch information
LiuYunPlayer committed May 15, 2024
1 parent d769ea3 commit a599a1d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
1 change: 0 additions & 1 deletion TuneLab/Data/INote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ internal interface INote : IDataObject<NoteInfo>, ISelectable, ILinkedNode<INote
INote? LastInSegment { get; set; }

int ISynthesisNote.Pitch => Pitch.Value;
string ISynthesisNote.Lyric => Lyric.Value;
PropertyObject ISynthesisNote.Properties => new(Properties);
IReadOnlyList<SynthesizedPhoneme> ISynthesisNote.Phonemes => Phonemes.Convert(GetPhoneme);
ISynthesisNote? ISynthesisNote.Next => NextInSegment;
Expand Down
22 changes: 20 additions & 2 deletions TuneLab/Data/Note.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ internal class Note : DataObject, INote
IDataProperty<string> INote.Lyric => Lyric;
IDataObjectList<IPhoneme> INote.Phonemes => Phonemes;

string ISynthesisNote.Lyric => Lyric.Pronunciation ?? Lyric.Value;

INote? ILinkedNode<INote>.Next { get; set; } = null;
INote? ILinkedNode<INote>.Last { get; set; } = null;
ILinkedList<INote>? ILinkedNode<INote>.LinkedList { get; set; }
Expand Down Expand Up @@ -85,13 +87,29 @@ void IDataObject<NoteInfo>.SetInfo(NoteInfo info)
IDataObject<NoteInfo>.SetInfo(Phonemes, info.Phonemes.Convert(Phoneme.Create).ToArray());
}

class DataLyric(Note note) : DataString(note)
class DataLyric : DataString
{
public string? Pronunciation => mPronunciation;

public DataLyric(Note note) : base(note)
{
mNote = note;
Modified.Subscribe(() =>
{
var pronunciations = LyricUtils.GetPronunciations(Value);
if (!pronunciations.IsEmpty())
mPronunciation = pronunciations.First();
});
}

public override void Set(string value)
{
base.Set(value);
note.Phonemes.Clear();
mNote.Phonemes.Clear();
}

string? mPronunciation;
Note mNote;
}

readonly IMidiPart mPart;
Expand Down
1 change: 1 addition & 0 deletions TuneLab/TuneLab.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="8.0.3" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PinYinConverterCore" Version="1.0.2" />
<PackageReference Include="Svg.Skia" Version="1.0.0.17" />
<PackageReference Include="ZstdSharp.Port" Version="0.8.0" />
</ItemGroup>
Expand Down
28 changes: 28 additions & 0 deletions TuneLab/Utils/LyricUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.International.Converters.PinYinConverter;
using TuneLab.Base.Structures;

namespace TuneLab.Utils;

Expand Down Expand Up @@ -50,4 +52,30 @@ public static IEnumerable<string> SplitByInvailidChars(string lyric)
'。', ',', '!', '?', ';', ':', '“', '”', '‘', '’', '(', ')', '【', '】', '『', '』', '—', '·'])
.Where(s => !string.IsNullOrEmpty(s));
}

public static IReadOnlyCollection<string> GetPronunciations(string lyric)
{
if (lyric.Length == 1)
{
var c = lyric[0];
if (ChineseChar.IsValidChar(c))
{
var chineseChar = new ChineseChar(c);
return chineseChar.Pinyins.Take(chineseChar.PinyinCount).Convert(ToPinyin).ToArray();
}
}

return [];
}

static string ToPinyin(string pinyin)
{
if (string.IsNullOrEmpty(pinyin))
return string.Empty;

if (char.IsNumber(pinyin[^1]))
return pinyin.Substring(0, pinyin.Length - 1).ToLower();

return pinyin.ToLower();
}
}

0 comments on commit a599a1d

Please sign in to comment.