diff --git a/ATL.unit-test/IO/HighLevel.cs b/ATL.unit-test/IO/HighLevel.cs index d9e5d65f..29da6329 100644 --- a/ATL.unit-test/IO/HighLevel.cs +++ b/ATL.unit-test/IO/HighLevel.cs @@ -424,7 +424,7 @@ public void TagIO_RW_Padding() tagIO_RW_AddPadding("MP3/empty.mp3"); tagIO_RW_AddPadding("OGG/empty.ogg", 8); // 8 extra bytes for the segments table extension tagIO_RW_AddPadding("MP4/chapters_NERO.mp4"); - tagIO_RW_AddPadding("FLAC/empty.flac", ATL.Settings.PaddingSize + 4); // Additional padding for the ID3v2 tag + 4 bytes for VorbisComment's PADDING block header + tagIO_RW_AddPadding("FLAC/empty.flac", 4); // Additional padding : 4 bytes for VorbisComment's PADDING block header } finally { diff --git a/ATL.unit-test/Resources/tmp/AtomicParsley.exe b/ATL.unit-test/Resources/tmp/AtomicParsley.exe deleted file mode 100644 index 47040f64..00000000 Binary files a/ATL.unit-test/Resources/tmp/AtomicParsley.exe and /dev/null differ diff --git a/ATL/AudioData/AudioDataManager.cs b/ATL/AudioData/AudioDataManager.cs index 24f1af09..622d45f6 100644 --- a/ATL/AudioData/AudioDataManager.cs +++ b/ATL/AudioData/AudioDataManager.cs @@ -256,14 +256,16 @@ public ISet getRecommendedMetas() if (1 == supportedMetas.Count) result.Add(supportedMetas[0]); else { - if (audioDataIO is OptimFrog) result.Add(TagType.APE); // TODO this is ugly + if (audioDataIO is OptimFrog) result.Add(TagType.APE); // TODO this is ugly (see #249) else { var id3v2Exists = supportedMetas.Contains(TagType.ID3V2); + bool isNativeRich = audioDataIO.IsNativeMetadataRich && supportedMetas.Exists(meta => meta == TagType.NATIVE); foreach (var meta in supportedMetas.Where(meta => meta != TagType.ID3V1)) { - if (meta == TagType.ID3V2 || meta == TagType.NATIVE) result.Add(meta); // Default preference go to these - if (meta == TagType.APE && !id3v2Exists) result.Add(meta); // If no ID3v2 support at all + if (meta == TagType.NATIVE && isNativeRich) result.Add(meta); + if (meta == TagType.ID3V2 && !isNativeRich) result.Add(meta); // If poor native metadata + if (meta == TagType.APE && !id3v2Exists && !isNativeRich) result.Add(meta); // If no ID3v2 support and poor native metadata } } } diff --git a/ATL/AudioData/AudioFileIO.cs b/ATL/AudioData/AudioFileIO.cs index f0ac0cb7..778ff061 100644 --- a/ATL/AudioData/AudioFileIO.cs +++ b/ATL/AudioData/AudioFileIO.cs @@ -247,6 +247,8 @@ public List GetSupportedMetas() return audioData.GetSupportedMetas(); } /// + public bool IsNativeMetadataRich => audioData.IsNativeMetadataRich; + /// public bool Read(Stream source, AudioDataManager.SizeInfo sizeNfo, MetaDataIO.ReadTagParams readTagParams) { return audioData.Read(source, sizeNfo, readTagParams); diff --git a/ATL/AudioData/IO/AA.cs b/ATL/AudioData/IO/AA.cs index 9b8613bc..adc37416 100644 --- a/ATL/AudioData/IO/AA.cs +++ b/ATL/AudioData/IO/AA.cs @@ -147,6 +147,8 @@ public int SampleRate return new List { MetaDataIOFactory.TagType.NATIVE }; } /// + public bool IsNativeMetadataRich => false; + /// public ChannelsArrangement ChannelsArrangement => MONO; /// public long AudioDataOffset { get; set; } diff --git a/ATL/AudioData/IO/AAC.cs b/ATL/AudioData/IO/AAC.cs index 609db882..62d3aba9 100644 --- a/ATL/AudioData/IO/AAC.cs +++ b/ATL/AudioData/IO/AAC.cs @@ -94,6 +94,8 @@ public AudioFormat AudioFormat return new List { MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.ID3V1 }; } /// + public bool IsNativeMetadataRich => false; + /// public ChannelsArrangement ChannelsArrangement { get; private set; } /// diff --git a/ATL/AudioData/IO/AC3.cs b/ATL/AudioData/IO/AC3.cs index f3b7dbdf..15c5845f 100644 --- a/ATL/AudioData/IO/AC3.cs +++ b/ATL/AudioData/IO/AC3.cs @@ -46,6 +46,8 @@ class AC3 : IAudioDataIO return new List { MetaDataIOFactory.TagType.APE }; } /// + public bool IsNativeMetadataRich => false; + /// public long AudioDataOffset { get; set; } /// public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/AIFF.cs b/ATL/AudioData/IO/AIFF.cs index 0c8c397c..9fb385d8 100644 --- a/ATL/AudioData/IO/AIFF.cs +++ b/ATL/AudioData/IO/AIFF.cs @@ -112,6 +112,8 @@ public AudioFormat AudioFormat { return new List { MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/Ape.cs b/ATL/AudioData/IO/Ape.cs index 68680c96..0b9704bd 100644 --- a/ATL/AudioData/IO/Ape.cs +++ b/ATL/AudioData/IO/Ape.cs @@ -141,7 +141,8 @@ private sealed class ApeDescriptor { return new List { MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.ID3V1 }; } - + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/CAF.cs b/ATL/AudioData/IO/CAF.cs index 355c2810..20131c52 100644 --- a/ATL/AudioData/IO/CAF.cs +++ b/ATL/AudioData/IO/CAF.cs @@ -154,6 +154,9 @@ class CAF : MetaDataIO, IAudioDataIO return new List { MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => false; + protected override int getDefaultTagOffset() { return TO_BUILTIN; diff --git a/ATL/AudioData/IO/DSF.cs b/ATL/AudioData/IO/DSF.cs index d488ca92..84a216d9 100644 --- a/ATL/AudioData/IO/DSF.cs +++ b/ATL/AudioData/IO/DSF.cs @@ -53,7 +53,8 @@ class DSF : IAudioDataIO, IMetaDataEmbedder { return new List { MetaDataIOFactory.TagType.ID3V2 }; } - + /// + public bool IsNativeMetadataRich => false; // IMetaDataEmbedder public long HasEmbeddedID3v2 => id3v2Offset; public uint ID3v2EmbeddingHeaderSize => 0; diff --git a/ATL/AudioData/IO/DTS.cs b/ATL/AudioData/IO/DTS.cs index c036c820..8b5b62d1 100644 --- a/ATL/AudioData/IO/DTS.cs +++ b/ATL/AudioData/IO/DTS.cs @@ -40,6 +40,8 @@ class DTS : IAudioDataIO { return new List(); // No supported metas } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/DummyReader.cs b/ATL/AudioData/IO/DummyReader.cs index 0d6a3eb9..12012319 100644 --- a/ATL/AudioData/IO/DummyReader.cs +++ b/ATL/AudioData/IO/DummyReader.cs @@ -54,6 +54,8 @@ public DummyReader(string filePath) { return new List { MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => false; /// public bool Read(Stream source, AudioDataManager.SizeInfo sizeNfo, MetaDataIO.ReadTagParams readTagParams) diff --git a/ATL/AudioData/IO/FLAC.cs b/ATL/AudioData/IO/FLAC.cs index a1dc2039..f3546b03 100644 --- a/ATL/AudioData/IO/FLAC.cs +++ b/ATL/AudioData/IO/FLAC.cs @@ -112,6 +112,8 @@ public override IList MetadataFormats // Native is for VorbisTag return new List { MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.ID3V2 }; } + /// + public bool IsNativeMetadataRich => true; // ---------- CONSTRUCTORS & INITIALIZERS diff --git a/ATL/AudioData/IO/GYM.cs b/ATL/AudioData/IO/GYM.cs index 6cca997e..d088f934 100644 --- a/ATL/AudioData/IO/GYM.cs +++ b/ATL/AudioData/IO/GYM.cs @@ -67,6 +67,8 @@ class GYM : MetaDataIO, IAudioDataIO { return new List { MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => false; // IMetaDataIO protected override int getDefaultTagOffset() diff --git a/ATL/AudioData/IO/IT.cs b/ATL/AudioData/IO/IT.cs index 6b302f1b..e8e7c734 100644 --- a/ATL/AudioData/IO/IT.cs +++ b/ATL/AudioData/IO/IT.cs @@ -71,6 +71,8 @@ class IT : MetaDataIO, IAudioDataIO return new List { MetaDataIOFactory.TagType.NATIVE }; } /// + public bool IsNativeMetadataRich => false; + /// public long AudioDataOffset { get; set; } /// public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/MIDI.cs b/ATL/AudioData/IO/MIDI.cs index 449c0d30..1464b00d 100644 --- a/ATL/AudioData/IO/MIDI.cs +++ b/ATL/AudioData/IO/MIDI.cs @@ -317,6 +317,8 @@ public void Add(MidiEvent evt) return new List { MetaDataIOFactory.TagType.NATIVE }; // Only for comments } /// + public bool IsNativeMetadataRich => false; + /// public long AudioDataOffset { get; set; } /// public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/MKA.cs b/ATL/AudioData/IO/MKA.cs index 9297a63c..1c1d1179 100644 --- a/ATL/AudioData/IO/MKA.cs +++ b/ATL/AudioData/IO/MKA.cs @@ -248,6 +248,8 @@ public AudioFormat AudioFormat protected override MetaDataIOFactory.TagType getImplementedTagType() => MetaDataIOFactory.TagType.NATIVE; + /// + public bool IsNativeMetadataRich => true; protected override Field getFrameMapping(string zone, string ID, byte tagVersion) { Field supportedMetaId = Field.NO_FIELD; diff --git a/ATL/AudioData/IO/MOD.cs b/ATL/AudioData/IO/MOD.cs index b84ffcdb..d93e2331 100644 --- a/ATL/AudioData/IO/MOD.cs +++ b/ATL/AudioData/IO/MOD.cs @@ -138,6 +138,8 @@ public AudioFormat AudioFormat { return new List { MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/MP4.cs b/ATL/AudioData/IO/MP4.cs index 40954fde..cc7e3bb7 100644 --- a/ATL/AudioData/IO/MP4.cs +++ b/ATL/AudioData/IO/MP4.cs @@ -184,7 +184,8 @@ public bool isValid() { return new List { MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V1 }; } - + /// + public bool IsNativeMetadataRich => true; public ChannelsArrangement ChannelsArrangement { get; private set; } public long AudioDataOffset { get; set; } diff --git a/ATL/AudioData/IO/MPEGaudio.cs b/ATL/AudioData/IO/MPEGaudio.cs index 0a01fe16..fa3f644f 100644 --- a/ATL/AudioData/IO/MPEGaudio.cs +++ b/ATL/AudioData/IO/MPEGaudio.cs @@ -332,6 +332,8 @@ public AudioFormat AudioFormat { return new List { MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => false; // ---------- CONSTRUCTORS & INITIALIZERS diff --git a/ATL/AudioData/IO/MPEGplus.cs b/ATL/AudioData/IO/MPEGplus.cs index ac95fedd..ed5f9841 100644 --- a/ATL/AudioData/IO/MPEGplus.cs +++ b/ATL/AudioData/IO/MPEGplus.cs @@ -85,6 +85,8 @@ public void computeVersion() MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/Ogg.cs b/ATL/AudioData/IO/Ogg.cs index 91c7f5d5..313b88fc 100644 --- a/ATL/AudioData/IO/Ogg.cs +++ b/ATL/AudioData/IO/Ogg.cs @@ -343,6 +343,8 @@ public AudioFormat AudioFormat // According to id3.org (FAQ), ID3 is not compatible with OGG. Hence ATL does not allow ID3 tags to be written on OGG files; native is for VorbisTag return new List { MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => true; /// public override IList MetadataFormats diff --git a/ATL/AudioData/IO/OptimFROG.cs b/ATL/AudioData/IO/OptimFROG.cs index 0c636d99..851641c4 100644 --- a/ATL/AudioData/IO/OptimFROG.cs +++ b/ATL/AudioData/IO/OptimFROG.cs @@ -157,6 +157,8 @@ public static bool IsValidHeader(byte[] data) { return new List { MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => false; public bool Read(Stream source, SizeInfo sizeNfo, MetaDataIO.ReadTagParams readTagParams) { diff --git a/ATL/AudioData/IO/PSF.cs b/ATL/AudioData/IO/PSF.cs index 308cd84b..d1665a36 100644 --- a/ATL/AudioData/IO/PSF.cs +++ b/ATL/AudioData/IO/PSF.cs @@ -98,6 +98,8 @@ public AudioFormat AudioFormat { return new List { MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/S3M.cs b/ATL/AudioData/IO/S3M.cs index 13999919..a7b2bef9 100644 --- a/ATL/AudioData/IO/S3M.cs +++ b/ATL/AudioData/IO/S3M.cs @@ -84,6 +84,8 @@ public AudioFormat AudioFormat // IMetaDataIO protected override int getDefaultTagOffset() => TO_BUILTIN; protected override MetaDataIOFactory.TagType getImplementedTagType() => MetaDataIOFactory.TagType.NATIVE; + /// + public bool IsNativeMetadataRich => false; protected override Field getFrameMapping(string zone, string ID, byte tagVersion) { throw new NotImplementedException(); diff --git a/ATL/AudioData/IO/SPC.cs b/ATL/AudioData/IO/SPC.cs index c83e0d3b..cbb814fd 100644 --- a/ATL/AudioData/IO/SPC.cs +++ b/ATL/AudioData/IO/SPC.cs @@ -164,6 +164,8 @@ partial class SPC : MetaDataIO, IAudioDataIO { return new List { MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.APE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/TAK.cs b/ATL/AudioData/IO/TAK.cs index 6d816af3..18c1b635 100644 --- a/ATL/AudioData/IO/TAK.cs +++ b/ATL/AudioData/IO/TAK.cs @@ -39,6 +39,8 @@ class TAK : IAudioDataIO { return new List { MetaDataIOFactory.TagType.APE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/TTA.cs b/ATL/AudioData/IO/TTA.cs index b52a24c6..e1b8d152 100644 --- a/ATL/AudioData/IO/TTA.cs +++ b/ATL/AudioData/IO/TTA.cs @@ -44,6 +44,8 @@ class TTA : IAudioDataIO { return new List { MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/TwinVQ.cs b/ATL/AudioData/IO/TwinVQ.cs index 713646de..79a49cd0 100644 --- a/ATL/AudioData/IO/TwinVQ.cs +++ b/ATL/AudioData/IO/TwinVQ.cs @@ -104,6 +104,8 @@ private sealed class HeaderInfo { return new List { MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/VGM.cs b/ATL/AudioData/IO/VGM.cs index 9a4ddab6..acbce885 100644 --- a/ATL/AudioData/IO/VGM.cs +++ b/ATL/AudioData/IO/VGM.cs @@ -62,6 +62,8 @@ class VGM : MetaDataIO, IAudioDataIO { return new List { MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/WAV.cs b/ATL/AudioData/IO/WAV.cs index 152328de..b4c4e457 100644 --- a/ATL/AudioData/IO/WAV.cs +++ b/ATL/AudioData/IO/WAV.cs @@ -124,6 +124,8 @@ public AudioFormat AudioFormat // Native for bext, info and iXML chunks return new List { MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/WAVPack.cs b/ATL/AudioData/IO/WAVPack.cs index 7df2f410..b1c34eb6 100644 --- a/ATL/AudioData/IO/WAVPack.cs +++ b/ATL/AudioData/IO/WAVPack.cs @@ -149,6 +149,8 @@ public void Reset() { return new List { MetaDataIOFactory.TagType.APE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/IO/WMA.cs b/ATL/AudioData/IO/WMA.cs index a1713aa7..9878fcd7 100644 --- a/ATL/AudioData/IO/WMA.cs +++ b/ATL/AudioData/IO/WMA.cs @@ -187,6 +187,8 @@ private void Reset() { return new List { MetaDataIOFactory.TagType.NATIVE, MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V1 }; } + /// + public bool IsNativeMetadataRich => true; /// protected override Field getFrameMapping(string zone, string ID, byte tagVersion) diff --git a/ATL/AudioData/IO/XM.cs b/ATL/AudioData/IO/XM.cs index feb6c791..2a92a9ef 100644 --- a/ATL/AudioData/IO/XM.cs +++ b/ATL/AudioData/IO/XM.cs @@ -77,6 +77,8 @@ public AudioFormat AudioFormat { return new List { MetaDataIOFactory.TagType.NATIVE }; } + /// + public bool IsNativeMetadataRich => false; public long AudioDataOffset { get; set; } public long AudioDataSize { get; set; } diff --git a/ATL/AudioData/Interfaces/IAudioDataIO.cs b/ATL/AudioData/Interfaces/IAudioDataIO.cs index a84b2946..9c598ee6 100644 --- a/ATL/AudioData/Interfaces/IAudioDataIO.cs +++ b/ATL/AudioData/Interfaces/IAudioDataIO.cs @@ -95,6 +95,14 @@ long AudioDataSize /// Metadata type supported by the present audio format List GetSupportedMetas(); + /// + /// True if the native tagging system contains a wide array of fields + /// + bool IsNativeMetadataRich + { + get; + } + /// /// Read audio data from the given stream. /// NB1 : Standard metadata (i.e. ID3v2, ID3v1 and APE) have to be read _before_ calling this method, and their size stored in sizeInfo