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

Replace all the .lrc file support to .kar #2268

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ private static KaraokeBeatmap decodeBeatmap(string fileName)
using var stream = new LineBufferedReader(resStream);

// Create karaoke beatmap decoder
var lrcDecoder = new KaraokeLegacyBeatmapDecoder();
var decoder = new KaraokeLegacyBeatmapDecoder();

// Create initial beatmap
var beatmap = lrcDecoder.Decode(stream);
var beatmap = decoder.Decode(stream);

// Convert to karaoke beatmap
return (KaraokeBeatmap)new KaraokeBeatmapConverter(beatmap, new KaraokeRuleset()).Convert();
Expand Down
74 changes: 0 additions & 74 deletions osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Formats/LrcEncoderTest.cs

This file was deleted.

17 changes: 3 additions & 14 deletions osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseTagHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using osu.Framework.Graphics.Sprites;
using osu.Game.IO;
using osu.Game.Rulesets.Karaoke.Beatmaps;
using osu.Game.Rulesets.Karaoke.Beatmaps.Formats;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;
using osu.Game.Rulesets.Karaoke.Extensions;
using osu.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Tests.Extensions;

Expand Down Expand Up @@ -203,18 +201,9 @@ public static Lyric ParseLyricWithTimeTag(string? str)
if (string.IsNullOrEmpty(str))
return new Lyric();

using var stream = new MemoryStream();
using var writer = new StreamWriter(stream);
using var reader = new LineBufferedReader(stream);

// Create stream
writer.Write(str);
writer.Flush();
stream.Position = 0;

// Create karaoke note decoder
var decoder = new LrcDecoder();
return decoder.Decode(reader).HitObjects.OfType<Lyric>().First();
var decoder = new KarDecoder();
return decoder.Decode(str).First();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// 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.IO;
using System.Linq;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.IO;
using osu.Game.Rulesets.Karaoke.Beatmaps.Formats;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Tests.Asserts;
using osu.Game.Rulesets.Karaoke.Tests.Helper;

namespace osu.Game.Rulesets.Karaoke.Tests.Beatmaps.Formats;
namespace osu.Game.Rulesets.Karaoke.Tests.Integration.Formats;

[TestFixture]
public class LrcDecoderTest
public class KarDecoderTest
{
[TestCase("[00:01.00]か[00:02.00]ら[00:03.00]お[00:04.00]け[00:05.00]", "からおけ", 1000, 5000)]
public void TestLyricTextAndTime(string lyricText, string expectedText, double expectedStartTime, double expectedEndTime)
{
var beatmap = decodeLrcLine(lyricText);

// Get first lyric from beatmap
var actual = beatmap.HitObjects.OfType<Lyric>().FirstOrDefault()!;
var lyrics = new KarDecoder().Decode(lyricText);
var actual = lyrics.FirstOrDefault()!;

Assert.IsNotNull(actual);
Assert.AreEqual(expectedText, actual.Text);
Assert.AreEqual(expectedStartTime, actual.LyricTimingInfo?.StartTime);
Expand All @@ -34,8 +29,8 @@ public void TestLyricTextAndTime(string lyricText, string expectedText, double e
public void TestLyricTimeTag(string text, string[] timeTags)
{
// Get first lyric from beatmap
var beatmap = decodeLrcLine(text);
var lyric = beatmap.HitObjects.OfType<Lyric>().FirstOrDefault();
var lyrics = new KarDecoder().Decode(text);
var lyric = lyrics.FirstOrDefault()!;

// Check time tag
var expected = TestCaseTagHelper.ParseTimeTags(timeTags);
Expand All @@ -47,29 +42,13 @@ public void TestLyricTimeTag(string text, string[] timeTags)
[TestCase("[00:04.00]か[00:04.00]ら[00:05.00]お[00:06.00]け[00:07.00]")]
public void TestDecodeLyricWithDuplicatedTimeTag(string text)
{
Assert.Throws<FormatException>(() => decodeLrcLine(text));
Assert.Throws<FormatException>(() => new KarDecoder().Decode(text));
}

[Ignore("Waiting for lyric parser update.")]
[TestCase("[00:04.00]か[00:03.00]ら[00:02.00]お[00:01.00]け[00:00.00]")]
public void TestDecodeLyricWithTimeTagNotOrder(string text)
{
Assert.Throws<FormatException>(() => decodeLrcLine(text));
}

private static Beatmap decodeLrcLine(string line)
{
using var stream = new MemoryStream();
using var writer = new StreamWriter(stream);
using var reader = new LineBufferedReader(stream);

// Create stream
writer.Write(line);
writer.Flush();
stream.Position = 0;

// Create karaoke note decoder
var decoder = new LrcDecoder();
return decoder.Decode(reader);
Assert.Throws<FormatException>(() => new KarDecoder().Decode(text));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Tests.Helper;
using osu.Game.Rulesets.Objects;

namespace osu.Game.Rulesets.Karaoke.Tests.Integration.Formats;

public class KarEncoderTest
{
[TestCase("からおけ", new string[] { }, "からおけ")]
[TestCase("からおけ", new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000", "[3,start]:4000", "[3,end]:5000" }, "[00:01.00]か[00:02.00]ら[00:03.00]お[00:04.00]け[00:05.00]")]
public void TestLyricWithTimeTag(string lyricText, string[] timeTags, string expected)
{
var lyric = new Lyric
{
Text = lyricText,
TimeTags = TestCaseTagHelper.ParseTimeTags(timeTags),
};

string actual = new KarEncoder().Encode(new Beatmap
{
HitObjects = new List<HitObject>
{
lyric,
},
});

Assert.AreEqual(actual, expected);
}
}
61 changes: 61 additions & 0 deletions osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/KarFileTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.IO;
using osu.Game.IO.Serialization;
using osu.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Tests.Resources;
using osu.Game.Rulesets.Objects;

namespace osu.Game.Rulesets.Karaoke.Tests.Integration.Formats;

public class KarFileTest
{
private static IEnumerable<string> allKarFileNames => TestResources.GetStore().GetAvailableResources()
.Where(res => res.EndsWith(".kar", StringComparison.Ordinal)).Select(x => Path.GetFileNameWithoutExtension(x!));

[TestCaseSource(nameof(allKarFileNames))]
public void TestDecodeEncodedBeatmap(string fileName)
{
var decoded = decode(fileName, out var encoded);

// Note : this test case does not cover ruby property
Assert.That(decoded.HitObjects.Count, Is.EqualTo(encoded.HitObjects.Count));
Assert.That(encoded.Serialize(), Is.EqualTo(decoded.Serialize()));
}

private static Beatmap decode(string filename, out Beatmap encoded)
{
using var stream = TestResources.OpenKarResource(filename);
using var sr = new LineBufferedReader(stream);

// Read file and decode to file
var legacyDecoded = new Beatmap
{
HitObjects = new KarDecoder().Decode(sr.ReadToEnd()).OfType<HitObject>().ToList(),
};

using var ms = new MemoryStream();
using var sw = new StreamWriter(ms);
using var sr2 = new LineBufferedReader(ms);

// Then encode file to stream
string encodeResult = new KarEncoder().Encode(legacyDecoded);
sw.WriteLine(encodeResult);
sw.Flush();

ms.Position = 0;

encoded = new Beatmap
{
HitObjects = new KarDecoder().Decode(sr2.ReadToEnd()).OfType<HitObject>().ToList(),
};
return legacyDecoded;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Tests.Helper;
using osu.Game.Rulesets.Objects;

namespace osu.Game.Rulesets.Karaoke.Tests.Integration.Formats;

public class LrcDecoderTest
{
[TestCase("からおけ", new string[] { }, "[00:00.00] からおけ")] // todo: handle the start time.
[TestCase("からおけ", new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000", "[3,start]:4000", "[3,end]:5000" }, "[00:00.00] <00:01.00>か<00:02.00>ら<00:03.00>お<00:04.00>け<00:05.00>")]
public void TestLyricWithTimeTag(string lyricText, string[] timeTags, string expected)
{
var lyric = new Lyric
{
Text = lyricText,
TimeTags = TestCaseTagHelper.ParseTimeTags(timeTags),
};

string actual = new LrcEncoder().Encode(new Beatmap
{
HitObjects = new List<HitObject>
{
lyric,
},
});

Assert.AreEqual(actual, expected);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Tests.Asserts;
using osu.Game.Rulesets.Karaoke.Tests.Helper;

namespace osu.Game.Rulesets.Karaoke.Tests.Integration.Formats;

public class LrcEncoderTest
{
[TestCase("[00:01.00]<00:01.00>か<00:02.00>ら<00:03.00>お<00:04.00>け<00:05.00>", "からおけ", 1000, 5000)]
public void TestLyricTextAndTime(string lyricText, string expectedText, double expectedStartTime, double expectedEndTime)
{
// Get first lyric from beatmap
var lyrics = new LrcDecoder().Decode(lyricText);
var actual = lyrics.FirstOrDefault()!;

Assert.IsNotNull(actual);
Assert.AreEqual(expectedText, actual.Text);
Assert.AreEqual(expectedStartTime, actual.LyricTimingInfo?.StartTime);
Assert.AreEqual(expectedEndTime, actual.LyricTimingInfo?.EndTime);
}

[TestCase("[00:01.00]<00:01.00>か<00:02.00>ら<00:03.00>お<00:04.00>け<00:05.00>", new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000", "[3,start]:4000", "[3,end]:5000" })]
public void TestLyricTimeTag(string text, string[] timeTags)
{
// Get first lyric from beatmap
var lyrics = new LrcDecoder().Decode(text);
var lyric = lyrics.FirstOrDefault()!;

// Check time tag
var expected = TestCaseTagHelper.ParseTimeTags(timeTags);
var actual = lyric?.TimeTags ?? throw new ArgumentNullException(nameof(lyric));
TimeTagAssert.ArePropertyEqual(expected, actual);
}

[Ignore("Time-tags with same time might be allowed.")]
[TestCase("[00:04.00]<00:04.00>か<00:04.00>ら<00:05.00>お<00:06.00>け<00:07.00>")]
public void TestDecodeLyricWithDuplicatedTimeTag(string text)
{
Assert.Throws<FormatException>(() => new LrcDecoder().Decode(text));
}

[Ignore("Waiting for lyric parser update.")]
[TestCase("[00:04.00]<00:04.00>か<00:03.00>ら<00:02.00>お<00:01.00>け<00:00.00>")]
public void TestDecodeLyricWithTimeTagNotOrder(string text)
{
Assert.Throws<FormatException>(() => new LrcDecoder().Decode(text));
}
}
Loading