diff --git a/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs b/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs index 8b2ea676..095da339 100644 --- a/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs +++ b/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs @@ -1499,6 +1499,54 @@ public void TestUserTextInformationFrame () }); } + [Test] + public void TestMovementNameFrame () + { + ByteVector id = "MVNM"; + var frame = new TextInformationFrame (id) { + Text = val_mult + }; + + FrameTest (frame, 2, + delegate (Frame f, StringType e) { + (f as TextInformationFrame).TextEncoding = e; + }, + (d, v) => new TextInformationFrame (d, v), + + delegate (Frame f, string m) { + var g = (f as TextInformationFrame); + Assert.AreEqual (id, g.FrameId, m); + Assert.AreEqual (val_mult.Length, g.Text.Length, m); + for (int i = 0; i < val_mult.Length; i++) { + Assert.AreEqual (val_mult[i], g.Text[i], m); + } + }); + } + + [Test] + public void TestMovementNumberFrame () + { + ByteVector id = "MVIN"; + var frame = new TextInformationFrame (id) { + Text = val_mult + }; + + FrameTest (frame, 2, + delegate (Frame f, StringType e) { + (f as TextInformationFrame).TextEncoding = e; + }, + (d, v) => new TextInformationFrame (d, v), + + delegate (Frame f, string m) { + var g = (f as TextInformationFrame); + Assert.AreEqual (id, g.FrameId, m); + Assert.AreEqual (val_mult.Length, g.Text.Length, m); + for (int i = 0; i < val_mult.Length; i++) { + Assert.AreEqual (val_mult[i], g.Text[i], m); + } + }); + } + [Test] public void TestUniqueFileIdentifierFrame () { diff --git a/src/TaglibSharp/Id3v2/FrameFactory.cs b/src/TaglibSharp/Id3v2/FrameFactory.cs index 9a1b9c5c..3754539f 100644 --- a/src/TaglibSharp/Id3v2/FrameFactory.cs +++ b/src/TaglibSharp/Id3v2/FrameFactory.cs @@ -216,7 +216,10 @@ public static Frame CreateFrame (ByteVector data, File file, ref int offset, byt if (header.FrameId == FrameType.TXXX) return new UserTextInformationFrame (data, position, header, version); - if (header.FrameId[0] == (byte)'T') + // Apple proprietary MVNM (Movement Name), MVIN (Movement Number) are in fact text frames. + if (header.FrameId[0] == (byte)'T' || + header.FrameId == "MVNM" || + header.FrameId == "MVIN") return new TextInformationFrame (data, position, header, version); // Involved People List (frames 4.4 in 2.3. in 2.4 this is a TIPL frame) diff --git a/src/TaglibSharp/Id3v2/FrameHeader.cs b/src/TaglibSharp/Id3v2/FrameHeader.cs index 877947f1..783818d9 100644 --- a/src/TaglibSharp/Id3v2/FrameHeader.cs +++ b/src/TaglibSharp/Id3v2/FrameHeader.cs @@ -381,7 +381,7 @@ static ReadOnlyByteVector ConvertId (ByteVector id, byte version, bool toVersion } static readonly ReadOnlyByteVector[,] version2_frames = - new ReadOnlyByteVector[59, 2] { + new ReadOnlyByteVector[61, 2] { { "BUF", "RBUF" }, { "CNT", "PCNT" }, { "COM", "COMM" }, @@ -440,7 +440,9 @@ static ReadOnlyByteVector ConvertId (ByteVector id, byte version, bool toVersion { "WCP", "WCOP" }, { "WPB", "WPUB" }, { "WXX", "WXXX" }, - { "XRV", "RVA2" } + { "XRV", "RVA2" }, + { "MVN", "MVNM" }, + { "MVI", "MVIN" } }; static readonly ReadOnlyByteVector[,] version3_frames = diff --git a/src/TaglibSharp/Id3v2/FrameTypes.cs b/src/TaglibSharp/Id3v2/FrameTypes.cs index 2fda85de..e430af85 100644 --- a/src/TaglibSharp/Id3v2/FrameTypes.cs +++ b/src/TaglibSharp/Id3v2/FrameTypes.cs @@ -101,5 +101,7 @@ static class FrameType public static readonly ReadOnlyByteVector WPUB = "WPUB"; public static readonly ReadOnlyByteVector WXXX = "WXXX"; public static readonly ReadOnlyByteVector ETCO = "ETCO"; + public static readonly ReadOnlyByteVector MVNM = "MVNM"; // Movement Name + public static readonly ReadOnlyByteVector MVIN = "MVIN"; // Movement Number/Count } } diff --git a/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs b/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs index 541adf2a..053563a3 100644 --- a/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs +++ b/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs @@ -875,7 +875,9 @@ protected void ParseRawData () FrameId == FrameType.TPE1 || FrameId == FrameType.TPE2 || FrameId == FrameType.TPE3 || - FrameId == FrameType.TPE4) { + FrameId == FrameType.TPE4 || + FrameId == FrameType.MVNM || + FrameId == FrameType.MVIN) { field_list.AddRange (value.Split ('/')); } else if (FrameId == FrameType.TCON) { while (value.Length > 1 && value[0] == '(') {