Skip to content

Commit

Permalink
Merge pull request #277 from andy840119/chinese-time-tag-auto-generator
Browse files Browse the repository at this point in the history
Create lyric creator for chinses lyric.
  • Loading branch information
andy840119 authored Dec 3, 2020
2 parents c12ef25 + 8af76b3 commit ea18d82
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Karaoke.Edit.Generator.TimeTags.Zh;
using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Tests.Edit.Generator.TimeTags.Zh
{
[TestFixture]
public class ZhTimeTagGeneratorTest
{
[TestCase("測試一些歌詞", new double[] { 0, 1, 2, 3, 4, 5, 5.5 })]
[TestCase("拉拉拉~~~", new double[] { 0, 1, 2, 5.5 })]
[TestCase("拉~拉~拉~", new double[] { 0, 2, 4, 5.5 })]
public void TestLyricWithCheckLineEndKeyUp(string lyric, double[] index)
{
var config = generatorConfig(nameof(ZhTimeTagGeneratorConfig.CheckLineEndKeyUp));
RunTimeTagCheckTest(lyric, index, config);
}

#region test helper

protected void RunTimeTagCheckTest(string lyricText, double[] index, ZhTimeTagGeneratorConfig config)
{
var generator = new ZhTimeTagGenerator(config);
var lyric = generateLyric(lyricText);

// create time tag and actually time tag.
var timeTags = getTimeTagIndex(generator.CreateTimeTags(lyric));
var actualIndexed = getTimeTagIndexByArray(index);

// check should be equal
Assert.AreEqual(timeTags, actualIndexed);
}

private TimeTagIndex[] getTimeTagIndex(Tuple<TimeTagIndex, double?>[] timeTags)
=> timeTags.Select((v, i) => v.Item1).ToArray();

private ZhTimeTagGeneratorConfig generatorConfig(params string[] properties)
{
var config = new ZhTimeTagGeneratorConfig();

foreach (var propertyName in properties)
{
if (propertyName == null)
continue;

var theMethod = config.GetType().GetProperty(propertyName);
if (theMethod == null)
throw new MissingMethodException("Config is not exist.");

theMethod.SetValue(config, true);
}

return config;
}

private TimeTagIndex[] getTimeTagIndexByArray(double[] timeTags)
=> timeTags.Select(timeTag =>
{
var state = Math.Abs(timeTag) % 1 == 0.5 ? TimeTagIndex.IndexState.End : TimeTagIndex.IndexState.Start;
var index = (int)timeTag;
return new TimeTagIndex(index, state);
}).ToArray();

private Lyric generateLyric(string text)
=> new Lyric { Text = text };

#endregion
}
}
19 changes: 19 additions & 0 deletions osu.Game.Rulesets.Karaoke.Tests/Utils/CharUtilsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,24 @@ public void TestIsAsciiSymbol(char c, bool match)
var isAsciiSymbol = CharUtils.IsAsciiSymbol(c);
Assert.AreEqual(isAsciiSymbol, match);
}

[TestCase('你', true)]
[TestCase('好', true)]
[TestCase('世', true)]
[TestCase('界', true)]
[TestCase('A', false)]
[TestCase('a', false)]
[TestCase('A', false)]
[TestCase('a', false)]
[TestCase('~', false)]
[TestCase('~', false)]
[TestCase('ハ', false)]
[TestCase('は', false)]
[TestCase('ハ', false)]
public void TestIsChinese(char c, bool result)
{
var isChinses = CharUtils.IsChinese(c);
Assert.AreEqual(isChinses, result);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Utils;
using System;
using System.Collections.Generic;

namespace osu.Game.Rulesets.Karaoke.Edit.Generator.TimeTags.Zh
{
public class ZhTimeTagGenerator : TimeTagGenerator<ZhTimeTagGeneratorConfig>
{
public ZhTimeTagGenerator(ZhTimeTagGeneratorConfig config)
: base(config)
{
}

protected override void TimeTagLogic(Lyric lyric, List<Tuple<TimeTagIndex, double?>> timeTags)
{
var text = lyric.Text;
for (var i = 1; i < text.Length; i++)
{
if (CharUtils.IsChinese(text[i]))
{
timeTags.Add(TimeTagsUtils.Create(new TimeTagIndex(i, TimeTagIndex.IndexState.Start), null));
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

namespace osu.Game.Rulesets.Karaoke.Edit.Generator.TimeTags.Zh
{
public class ZhTimeTagGeneratorConfig : TimeTagGeneratorConfig
{
}
}
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.Karaoke/Utils/CharUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Text.Unicode;

namespace osu.Game.Rulesets.Karaoke.Utils
{
public static class CharUtils
Expand Down Expand Up @@ -43,5 +45,18 @@ public static bool IsAsciiSymbol(char c)
c >= '[' && c <= '`' ||
c >= '{' && c <= '~';
}

/// <summary>
/// Check this char is chinese character
/// </summary>
/// <param name="character"></param>
/// <returns></returns>
public static bool IsChinese(char character)
{
// From : https://stackoverflow.com/a/61738863/4105113
var minValue = UnicodeRanges.CjkUnifiedIdeographs.FirstCodePoint;
var maxValue = minValue + UnicodeRanges.CjkUnifiedIdeographs.Length;
return character >= minValue && character < maxValue;
}
}
}

0 comments on commit ea18d82

Please sign in to comment.