* src/Tag.cs, src/AudioFileWrapper.cs, src/Util/Utils.cs, src/Util/AudioFileReader.cs: Additions to deal with track count info * src/M4a/M4aTag.cs, src/Mp3/Id3Tag.cs, src/Mp3/Util/Id3v23TagReader.cs, src/Ape/ApeTag.cs, src/Ape/Util/ApeTagReader.cs, src/Ogg/OggTag.cs: Handle track count field * tests/samples/: Set the track count to 7 * tests/EntaggedTest.cs: Add TrackCount tests Index: tests/EntaggedTest.cs =================================================================== --- tests/EntaggedTest.cs (revision 48490) +++ tests/EntaggedTest.cs (working copy) @@ -21,6 +21,7 @@ Assert.AreEqual("Acid Punk", afw.Genre); Assert.AreEqual("APE title", afw.Title); Assert.AreEqual(6, afw.TrackNumber); + Assert.AreEqual(7, afw.TrackCount); Assert.AreEqual(1234, afw.Year); } } @@ -44,6 +45,7 @@ Assert.AreEqual("Acid Punk", afw.Genre); Assert.AreEqual("FLAC title", afw.Title); Assert.AreEqual(6, afw.TrackNumber); + Assert.AreEqual(7, afw.TrackCount); Assert.AreEqual(1234, afw.Year); } } @@ -67,6 +69,7 @@ Assert.AreEqual("Acid Punk", afw.Genre); Assert.AreEqual("MP3 title", afw.Title); Assert.AreEqual(6, afw.TrackNumber); + Assert.AreEqual(7, afw.TrackCount); Assert.AreEqual(1234, afw.Year); } } @@ -91,6 +94,7 @@ Assert.AreEqual("Acid Punk", afw.Genre); Assert.AreEqual("MPC title", afw.Title); Assert.AreEqual(6, afw.TrackNumber); + Assert.AreEqual(7, afw.TrackCount); Assert.AreEqual(1234, afw.Year); } } @@ -114,6 +118,8 @@ Assert.AreEqual("Acid Punk", afw.Genre); Assert.AreEqual("OGG title", afw.Title); Assert.AreEqual(6, afw.TrackNumber); + Assert.AreEqual(7, afw.TrackCount); Assert.AreEqual(1234, afw.Year); } } + Index: tests/samples/sample.mp3 =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tests/samples/sample.mpc =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tests/samples/sample.ape =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tests/samples/sample.flac =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tests/samples/sample.ogg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: src/Tag.cs =================================================================== --- src/Tag.cs (revision 48490) +++ src/Tag.cs (working copy) @@ -89,6 +89,7 @@ void AddGenre(string s); void AddTitle(string s); void AddTrack(string s); + void AddTrackCount(string s); void AddYear(string s); IList Get(string id); @@ -103,6 +104,9 @@ IList Track { get; } + IList TrackCount { + get; + } IList Year { get; } @@ -168,6 +172,10 @@ { get { return Get(TrackId); } } + public IList TrackCount + { + get { return Get(TrackCountId); } + } public IList Year { get { return Get(YearId); } @@ -198,6 +206,10 @@ { Set (CreateTrackField (s)); } + public void SetTrackCount(string s) + { + Set (CreateTrackCountField (s)); + } public void SetYear(string s) { Set (CreateYearField (s)); @@ -228,6 +240,10 @@ { Add (CreateTrackField (s)); } + public void AddTrackCount(string s) + { + Add (CreateTrackCountField (s)); + } public void AddYear(string s) { Add (CreateYearField (s)); @@ -406,6 +422,9 @@ protected abstract string TrackId { get; } + protected abstract string TrackCountId { + get; + } protected abstract string YearId { get; } @@ -420,6 +439,7 @@ protected abstract TagField CreateAlbumField(string content); protected abstract TagField CreateTitleField(string content); protected abstract TagField CreateTrackField(string content); + protected abstract TagField CreateTrackCountField(string content); protected abstract TagField CreateYearField(string content); protected abstract TagField CreateCommentField(string content); protected abstract TagField CreateGenreField(string content); @@ -444,7 +464,8 @@ "TRACK", "YEAR", "GENRE", - "COMMENT" + "COMMENT", + "TRACKCOUNT", }; public static int ARTIST = 0; @@ -454,6 +475,7 @@ public static int YEAR = 4; public static int GENRE = 5; public static int COMMENT = 6; + public static int TRACKCOUNT = 7; protected override string ArtistId { get { return keys[ARTIST]; } @@ -467,6 +489,9 @@ protected override string TrackId { get { return keys[TRACK]; } } + protected override string TrackCountId { + get { return keys[TRACKCOUNT]; } + } protected override string YearId { get { return keys[YEAR]; } } @@ -489,6 +514,9 @@ protected override TagField CreateTrackField(string content) { return new GenericTagTextField(keys[TRACK], content); } + protected override TagField CreateTrackCountField(string content) { + return new GenericTagTextField(keys[TRACKCOUNT], content); + } protected override TagField CreateYearField(string content) { return new GenericTagTextField(keys[YEAR], content); } Index: src/M4a/M4aTag.cs =================================================================== --- src/M4a/M4aTag.cs (revision 48490) +++ src/M4a/M4aTag.cs (working copy) @@ -63,6 +63,11 @@ return new M4aTagField(TrackId, content); } + protected override TagField CreateTrackCountField(string content) + { + return new M4aTagField(TrackCountId, content); + } + protected override TagField CreateYearField(string content) { return new M4aTagField(YearId, content); @@ -70,51 +75,42 @@ protected override string AlbumId { - get { - return "ALBUM"; - } + get { return "ALBUM"; } } protected override string ArtistId { - get { - return "ARTIST"; - } + get { return "ARTIST"; } } protected override string CommentId { - get { - return "COMMENTS"; - } + get { return "COMMENTS"; } } protected override string GenreId { - get { - return "GENRE"; - } + get { return "GENRE"; } } protected override string TitleId { - get { - return "TITLE"; - } + get { return "TITLE"; } } protected override string TrackId { - get { - return "TRACKNUMBER"; - } + get { return "TRACKNUMBER"; } } + protected override string TrackCountId + { + get { return "EntaggedTrackCount"; } + } + protected override string YearId { - get { - return "YEAR"; - } + get { return "YEAR"; } } protected override bool IsAllowedEncoding(string enc) @@ -124,7 +120,7 @@ public override string ToString() { - return "OGG " + base.ToString(); + return "M4A " + base.ToString(); } } } Index: src/Mp3/Id3Tag.cs =================================================================== --- src/Mp3/Id3Tag.cs (revision 48490) +++ src/Mp3/Id3Tag.cs (working copy) @@ -78,6 +78,9 @@ protected override string TrackId { get { return "TRCK"; } } + protected override string TrackCountId { + get { return "EntaggedTrackCount"; } + } protected override string YearId { get { return "TYER"; } } @@ -89,25 +92,28 @@ } protected override TagField CreateArtistField(string content) { - return new TextId3Frame("TPE1", content); + return new TextId3Frame(ArtistId, content); } protected override TagField CreateAlbumField(string content) { - return new TextId3Frame("TALB", content); + return new TextId3Frame(AlbumId, content); } protected override TagField CreateTitleField(string content) { - return new TextId3Frame("TIT2", content); + return new TextId3Frame(TitleId, content); } protected override TagField CreateTrackField(string content) { - return new TextId3Frame("TRCK", content); + return new TextId3Frame(TrackId, content); } + protected override TagField CreateTrackCountField(string content) { + return new TextId3Frame(TrackCountId, content); + } protected override TagField CreateYearField(string content) { - return new TextId3Frame("TYER", content); + return new TextId3Frame(YearId, content); } protected override TagField CreateCommentField(string content) { return new CommId3Frame(content); } protected override TagField CreateGenreField(string content) { - return new TextId3Frame("TCON", content); + return new TextId3Frame(GenreId, content); } protected override bool IsAllowedEncoding(string enc) { Index: src/Mp3/Util/Id3v23TagReader.cs =================================================================== --- src/Mp3/Util/Id3v23TagReader.cs (revision 48490) +++ src/Mp3/Util/Id3v23TagReader.cs (working copy) @@ -84,8 +84,22 @@ if( "" != field) { Id3Frame f = CreateId3Frame(field, b, version); - if(f != null) - tag.Add(f); + switch (field) { + case "TRCK": + if (!(f is TextId3Frame)) + break; + string num, count; + Utils.SplitTrackNumber(((TextId3Frame)f).Content, out num, out count); + if (num != null) + tag.Add(new TextId3Frame(field, num)); + if (count != null) + tag.Add(new TextId3Frame("EntaggedTrackCount", count)); + break; + + default: + tag.Add(f); + break; + } } } Index: src/Ape/ApeTag.cs =================================================================== --- src/Ape/ApeTag.cs (revision 48490) +++ src/Ape/ApeTag.cs (working copy) @@ -49,6 +49,9 @@ protected override string TrackId { get { return "Track"; } } + protected override string TrackCountId { + get { return "EntaggedTrackCount"; } + } protected override string YearId { get { return "Year"; } } @@ -60,25 +63,28 @@ } protected override TagField CreateArtistField(string content) { - return new ApeTagTextField("Artist", content); + return new ApeTagTextField(ArtistId, content); } protected override TagField CreateAlbumField(string content) { - return new ApeTagTextField("Album", content); + return new ApeTagTextField(AlbumId, content); } protected override TagField CreateTitleField(string content) { - return new ApeTagTextField("Title", content); + return new ApeTagTextField(TitleId, content); } protected override TagField CreateTrackField(string content) { - return new ApeTagTextField("Track", content); + return new ApeTagTextField(TrackId, content); } + protected override TagField CreateTrackCountField(string content) { + return new ApeTagTextField(TrackCountId, content); + } protected override TagField CreateYearField(string content) { - return new ApeTagTextField("Year", content); + return new ApeTagTextField(YearId, content); } protected override TagField CreateCommentField(string content) { - return new ApeTagTextField("Comment", content); + return new ApeTagTextField(CommentId, content); } protected override TagField CreateGenreField(string content) { - return new ApeTagTextField("Genre", content); + return new ApeTagTextField(GenreId, content); } protected override bool IsAllowedEncoding(string enc) { Index: src/Ape/Util/ApeTagReader.cs =================================================================== --- src/Ape/Util/ApeTagReader.cs (revision 48490) +++ src/Ape/Util/ApeTagReader.cs (working copy) @@ -31,6 +31,7 @@ */ using System.IO; +using System.Text; using Entagged.Audioformats.Exceptions; using Entagged.Audioformats.Util; @@ -102,13 +103,28 @@ apeStream.Read( b , 0, b .Length); apeStream.Seek(1, SeekOrigin.Current); string field = new string(System.Text.Encoding.GetEncoding("ISO-8859-1").GetChars(b)); - + //Read Item content b = new byte[contentLength]; apeStream.Read( b , 0, b .Length); - if(!binary) - tag.Add(new ApeTagTextField(field, new string(System.Text.Encoding.UTF8.GetChars(b)))); - else + if(!binary) { + string content = new string(Encoding.UTF8.GetChars(b)); + switch (field) { + case "Track": + string num, count; + Utils.SplitTrackNumber(content, out num, out count); + if (num != null) + tag.Add(new ApeTagTextField(field, num)); + if (count != null) + tag.Add(new ApeTagTextField("EntaggedTrackCount", count)); + break; + + default: + tag.Add(new ApeTagTextField(field, content)); + break; + } + + } else tag.Add(new ApeTagBinaryField(field, b)); } Index: src/AudioFileWrapper.cs =================================================================== --- src/AudioFileWrapper.cs (revision 48490) +++ src/AudioFileWrapper.cs (working copy) @@ -126,6 +126,13 @@ } } + public int[] TrackCounts + { + get { + return Utils.FieldListToIntArray(Tag.TrackCount); + } + } + public int[] Years { get { @@ -180,7 +187,18 @@ } } } - + + public int TrackCount + { + get { + try { + return Convert.ToInt32(((TagTextField)Tag.TrackCount[0]).Content); + } catch(Exception) { + return 0; + } + } + } + public int Year { get { Index: src/Ogg/OggTag.cs =================================================================== --- src/Ogg/OggTag.cs (revision 48490) +++ src/Ogg/OggTag.cs (working copy) @@ -41,31 +41,35 @@ public const string DEFAULT_VENDOR = "Entagged - The Musical Box"; protected override TagField CreateAlbumField(string content) { - return new OggTagField("ALBUM", content); + return new OggTagField(AlbumId, content); } protected override TagField CreateArtistField(string content) { - return new OggTagField("ARTIST", content); + return new OggTagField(ArtistId, content); } protected override TagField CreateCommentField(string content) { - return new OggTagField("DESCRIPTION", content); + return new OggTagField(CommentId, content); } protected override TagField CreateGenreField(string content) { - return new OggTagField("GENRE", content); + return new OggTagField(GenreId, content); } protected override TagField CreateTitleField(string content) { - return new OggTagField("TITLE", content); + return new OggTagField(TitleId, content); } protected override TagField CreateTrackField(string content) { - return new OggTagField("TRACKNUMBER", content); + return new OggTagField(TrackId, content); } + protected override TagField CreateTrackCountField(string content) { + return new OggTagField(TrackCountId, content); + } + protected override TagField CreateYearField(string content) { - return new OggTagField("DATE", content); + return new OggTagField(YearId, content); } protected override string AlbumId { @@ -92,6 +96,10 @@ get { return "TRACKNUMBER"; } } + protected override string TrackCountId { + get { return "TRACKTOTAL"; } + } + protected override string YearId { get { return "DATE"; } } Index: src/Util/Utils.cs =================================================================== --- src/Util/Utils.cs (revision 48490) +++ src/Util/Utils.cs (working copy) @@ -106,6 +106,9 @@ foreach (TagTextField track in tag.Track) ret.AddTrack (track.Content); + foreach (TagTextField trackcount in tag.TrackCount) + ret.AddTrackCount (trackcount.Content); + foreach (TagTextField year in tag.Year) ret.AddYear (year.Content); @@ -118,6 +121,19 @@ return ret; } + + // Splits (e.g.) "1/6" into track 1 of 6. + public static void SplitTrackNumber(string content, out string num, out string count) + { + string[] split = content.Split(new char[] {'/'}, 2); + if (split.Length == 1) { + num = content; + count = null; + } else { + num = split[0]; + count = split[1]; + } + } } } Index: src/Util/AudioFileReader.cs =================================================================== --- src/Util/AudioFileReader.cs (revision 48490) +++ src/Util/AudioFileReader.cs (working copy) @@ -74,7 +74,7 @@ return new AudioFile(info, tag); } catch ( Exception e ) { - throw new CannotReadException(e.Message); + throw new CannotReadException(e.ToString()); } finally { try{ Index: ChangeLog =================================================================== --- ChangeLog (revision 48490) +++ ChangeLog (working copy) @@ -1,3 +1,13 @@ +2005-08-18 Daniel Drake + + * src/Tag.cs, src/AudioFileWrapper.cs, src/Util/Utils.cs, + src/Util/AudioFileReader.cs: Additions to deal with track count info + * src/M4a/M4aTag.cs, src/Mp3/Id3Tag.cs, src/Mp3/Util/Id3v23TagReader.cs, + src/Ape/ApeTag.cs, src/Ape/Util/ApeTagReader.cs, src/Ogg/OggTag.cs: + Handle track count field + * tests/samples/: Set the track count to 7 + * tests/EntaggedTest.cs: Add TrackCount tests + 2005-08-17 Daniel Drake * configure.ac, Makefile.am: Added references to tests/