/// <summary> /// Writes the given metadata into the given stream using the ID3v1.1 standard /// NB : Metadata fields that are not supported by ID3v1.1 standard (e.g. Composer) won't be written into the stream, even though their value are set /// </summary> /// <param name="tag">Metadata to be written</param> /// <param name="w">Stream to be used</param> /// <returns>True if operation completed successfuly; else false</returns> protected override Int32 write(TagData tag, BinaryWriter w, String zone) { // ID3v1 tags are C-String(null-terminated)-based tags // they are not unicode-encoded, hence the use of ReadOneByteChars w.Write(ID3V1_ID.ToCharArray()); w.Write(Utils.BuildStrictLengthString(tag.Title, 30, '\0').ToCharArray()); w.Write(Utils.BuildStrictLengthString(tag.Artist, 30, '\0').ToCharArray()); w.Write(Utils.BuildStrictLengthString(tag.Album, 30, '\0').ToCharArray()); // ID3v1 standard requires the year w.Write(Utils.BuildStrictLengthString(TrackUtils.ExtractStrYear(tag.RecordingYear), 4, '\0').ToCharArray()); w.Write(Utils.BuildStrictLengthString(tag.Comment, 28, '\0').ToCharArray()); // ID3v1.1 standard w.Write('\0'); w.Write((Byte)Math.Min(TrackUtils.ExtractTrackNumber(tag.TrackNumber), Byte.MaxValue)); Byte genre = 0; if (tag.Genre != null) { for (Byte i = 0; i < MAX_MUSIC_GENRES; i++) { if (tag.Genre.ToUpper().Equals(MusicGenre[i].ToUpper())) { genre = i; break; } } } w.Write(genre); return(7); }
public void TrackUtils_EncodePopularity() { // Cases not covered by metadata-specific test classes Assert.AreEqual(0, TrackUtils.EncodePopularity("0.5", MetaDataIO.RC_ASF)); Assert.AreEqual(1, TrackUtils.EncodePopularity("1.5", MetaDataIO.RC_ASF)); Assert.AreEqual(1, TrackUtils.EncodePopularity("1,5", MetaDataIO.RC_ASF)); Assert.AreEqual(25, TrackUtils.EncodePopularity("2.5", MetaDataIO.RC_ASF)); Assert.AreEqual(50, TrackUtils.EncodePopularity("3.5", MetaDataIO.RC_ASF)); Assert.AreEqual(75, TrackUtils.EncodePopularity("4.5", MetaDataIO.RC_ASF)); Assert.AreEqual(99, TrackUtils.EncodePopularity("5", MetaDataIO.RC_ASF)); Assert.AreEqual(0, TrackUtils.EncodePopularity("0.25", MetaDataIO.RC_APE)); Assert.AreEqual(10, TrackUtils.EncodePopularity("0.5", MetaDataIO.RC_APE)); Assert.AreEqual(20, TrackUtils.EncodePopularity("1", MetaDataIO.RC_APE)); Assert.AreEqual(30, TrackUtils.EncodePopularity("1.5", MetaDataIO.RC_APE)); Assert.AreEqual(40, TrackUtils.EncodePopularity("2", MetaDataIO.RC_APE)); Assert.AreEqual(50, TrackUtils.EncodePopularity("2.5", MetaDataIO.RC_APE)); Assert.AreEqual(60, TrackUtils.EncodePopularity("3", MetaDataIO.RC_APE)); Assert.AreEqual(70, TrackUtils.EncodePopularity("3.5", MetaDataIO.RC_APE)); Assert.AreEqual(80, TrackUtils.EncodePopularity("4", MetaDataIO.RC_APE)); Assert.AreEqual(90, TrackUtils.EncodePopularity("4.5", MetaDataIO.RC_APE)); Assert.AreEqual(100, TrackUtils.EncodePopularity("5", MetaDataIO.RC_APE)); Assert.AreEqual(0, TrackUtils.EncodePopularity("0.25", MetaDataIO.RC_ID3v2)); Assert.AreEqual(13, TrackUtils.EncodePopularity("0.5", MetaDataIO.RC_ID3v2)); Assert.AreEqual(1, TrackUtils.EncodePopularity("1", MetaDataIO.RC_ID3v2)); // <-- yes, 1 Assert.AreEqual(54, TrackUtils.EncodePopularity("1.5", MetaDataIO.RC_ID3v2)); Assert.AreEqual(64, TrackUtils.EncodePopularity("2", MetaDataIO.RC_ID3v2)); Assert.AreEqual(118, TrackUtils.EncodePopularity("2.5", MetaDataIO.RC_ID3v2)); Assert.AreEqual(128, TrackUtils.EncodePopularity("3", MetaDataIO.RC_ID3v2)); Assert.AreEqual(186, TrackUtils.EncodePopularity("3.5", MetaDataIO.RC_ID3v2)); Assert.AreEqual(196, TrackUtils.EncodePopularity("4", MetaDataIO.RC_ID3v2)); Assert.AreEqual(242, TrackUtils.EncodePopularity("4.5", MetaDataIO.RC_ID3v2)); Assert.AreEqual(255, TrackUtils.EncodePopularity("5", MetaDataIO.RC_ID3v2)); }
protected override int write(TagData tag, BinaryWriter w, string zone) { long counterPos; uint counter = 0; string vendor; if (AdditionalFields.ContainsKey(VENDOR_METADATA_ID)) { vendor = AdditionalFields[VENDOR_METADATA_ID]; } else { // Even when no existing field, vendor field is mandatory in OGG structure // => a file with no vendor is a FLAC file vendor = VENDOR_DEFAULT_FLAC; } w.Write((uint)vendor.Length); w.Write(Encoding.UTF8.GetBytes(vendor)); counterPos = w.BaseStream.Position; w.Write((uint)0); // Tag counter placeholder to be rewritten in a few lines counter = writeFrames(tag, w); if (writeMetadataFramingBit) { w.Write((byte)1); // Framing bit (mandatory for OGG container) } // PADDING MANAGEMENT // Write the remaining padding bytes, if any detected during initial reading if (managePadding) { long paddingSizeToWrite; if (tag.PaddingSize > -1) { paddingSizeToWrite = tag.PaddingSize; } else { paddingSizeToWrite = TrackUtils.ComputePaddingSize(initialPaddingOffset, initialPaddingSize, initialPaddingOffset, w.BaseStream.Position); } if (paddingSizeToWrite > 0) { for (int i = 0; i < paddingSizeToWrite; i++) { w.Write((byte)0); } } } long finalPos = w.BaseStream.Position; w.BaseStream.Seek(counterPos, SeekOrigin.Begin); w.Write(counter); w.BaseStream.Seek(finalPos, SeekOrigin.Begin); return((int)counter); }
public void TrackUtils_ExtractStrYear() { Assert.AreEqual("1952", TrackUtils.ExtractStrYear("1952")); Assert.AreEqual("1952", TrackUtils.ExtractStrYear("1952.1")); Assert.AreEqual("1952", TrackUtils.ExtractStrYear("1952,1")); Assert.AreEqual("1952", TrackUtils.ExtractStrYear("1952aaa")); Assert.AreEqual("1952", TrackUtils.ExtractStrYear("aaa1952")); Assert.AreEqual("1952", TrackUtils.ExtractStrYear("aa1952aa")); Assert.AreEqual("", TrackUtils.ExtractStrYear("")); Assert.AreEqual("", TrackUtils.ExtractStrYear(null)); Assert.AreEqual("", TrackUtils.ExtractStrYear("aaaa")); Assert.AreEqual("", TrackUtils.ExtractStrYear("999")); }
private void writeSubChunk(BinaryWriter writer, byte frameCode, string text) { writer.Write(frameCode); byte type = 1; if (extendedFrameTypes.ContainsKey(frameCode)) { type = extendedFrameTypes[frameCode]; } writer.Write(type); switch (type) { case XID6_TVAL: if (frameCode == XID6_TRACK) // Specific case : upper byte is the number 0-99, lower byte is an optional ASCII character { byte trackValue = (byte)Math.Min((ushort)0xFF, TrackUtils.ExtractTrackNumber(text)); writer.Write('\0'); // Optional char support is not implemented writer.Write(trackValue); } else { writer.Write(ushort.Parse(text)); // Value is directly written as an ushort into the length field } break; case XID6_TSTR: if (text.Length > 255) { text = text.Substring(0, 255); } else if (text.Length < 3) { text = Utils.BuildStrictLengthString(text, 3, ' '); } byte[] textBinary = Utils.Latin1Encoding.GetBytes(text); writer.Write((ushort)(textBinary.Length + 1)); writer.Write(textBinary); writer.Write('\0'); break; case XID6_TINT: writer.Write((ushort)4); writer.Write(Int32.Parse(text)); break; } }
public void TrackUtils_ExtractTrackNumber() { Assert.AreEqual(15, TrackUtils.ExtractTrackNumber("15")); Assert.AreEqual(15, TrackUtils.ExtractTrackNumber(" 15")); Assert.AreEqual(15, TrackUtils.ExtractTrackNumber(" 15 ")); Assert.AreEqual(15, TrackUtils.ExtractTrackNumber("15 ")); Assert.AreEqual(15, TrackUtils.ExtractTrackNumber("15.1")); Assert.AreEqual(15, TrackUtils.ExtractTrackNumber("15,1")); Assert.AreEqual(15, TrackUtils.ExtractTrackNumber("a15a")); Assert.AreEqual(0, TrackUtils.ExtractTrackNumber("")); Assert.AreEqual(0, TrackUtils.ExtractTrackNumber(null)); Assert.AreEqual(0, TrackUtils.ExtractTrackNumber("aaa")); Assert.AreEqual(0, TrackUtils.ExtractTrackNumber("99999999")); }
private WriteResult writePaddingBlock(BinaryWriter w, long cumulativeDelta) { long paddingSizeToWrite = TrackUtils.ComputePaddingSize(initialPaddingOffset, initialPaddingSize, -cumulativeDelta); if (paddingSizeToWrite > 0) { w.Write(META_PADDING); w.Write(StreamUtils.EncodeBEUInt24((uint)paddingSizeToWrite)); for (int i = 0; i < paddingSizeToWrite; i++) { w.Write((byte)0); } return(new WriteResult(WriteMode.REPLACE, 1)); } else { return(new WriteResult(WriteMode.REPLACE, 0)); } }
protected string formatBeforeWriting(byte frameType, TagData tag, IDictionary <byte, string> map) { string value = ""; string total = ""; switch (frameType) { case TagData.TAG_FIELD_RATING: return(TrackUtils.EncodePopularity(map[frameType], ratingConvention).ToString()); case TagData.TAG_FIELD_TRACK_NUMBER: value = map[TagData.TAG_FIELD_TRACK_NUMBER]; map.TryGetValue(TagData.TAG_FIELD_TRACK_TOTAL, out total); return(TrackUtils.ApplyLeadingZeroes(value, total, tag.TrackDigitsForLeadingZeroes, Settings.UseLeadingZeroes, Settings.OverrideExistingLeadingZeroesFormat)); case TagData.TAG_FIELD_TRACK_TOTAL: value = map[TagData.TAG_FIELD_TRACK_TOTAL]; total = value; return(TrackUtils.ApplyLeadingZeroes(value, total, tag.TrackDigitsForLeadingZeroes, Settings.UseLeadingZeroes, Settings.OverrideExistingLeadingZeroesFormat)); case TagData.TAG_FIELD_TRACK_NUMBER_TOTAL: value = map[TagData.TAG_FIELD_TRACK_NUMBER_TOTAL]; total = value; return(TrackUtils.ApplyLeadingZeroes(value, total, tag.TrackDigitsForLeadingZeroes, Settings.UseLeadingZeroes, Settings.OverrideExistingLeadingZeroesFormat)); case TagData.TAG_FIELD_DISC_NUMBER: value = map[TagData.TAG_FIELD_DISC_NUMBER]; map.TryGetValue(TagData.TAG_FIELD_DISC_TOTAL, out total); return(TrackUtils.ApplyLeadingZeroes(value, total, tag.DiscDigitsForLeadingZeroes, Settings.UseLeadingZeroes, Settings.OverrideExistingLeadingZeroesFormat)); case TagData.TAG_FIELD_DISC_TOTAL: value = map[TagData.TAG_FIELD_DISC_TOTAL]; total = value; return(TrackUtils.ApplyLeadingZeroes(value, total, tag.DiscDigitsForLeadingZeroes, Settings.UseLeadingZeroes, Settings.OverrideExistingLeadingZeroesFormat)); case TagData.TAG_FIELD_DISC_NUMBER_TOTAL: value = map[TagData.TAG_FIELD_DISC_NUMBER_TOTAL]; total = value; return(TrackUtils.ApplyLeadingZeroes(value, total, tag.DiscDigitsForLeadingZeroes, Settings.UseLeadingZeroes, Settings.OverrideExistingLeadingZeroesFormat)); default: return(map[frameType]); } }
public void TrackUtils_ExtractTrackTotal() { Assert.AreEqual(16, TrackUtils.ExtractTrackTotal("15/16")); Assert.AreEqual(1, TrackUtils.ExtractTrackTotal("15/1")); Assert.AreEqual(16, TrackUtils.ExtractTrackTotal(" 15 / 16 ")); Assert.AreEqual(16, TrackUtils.ExtractTrackTotal("15//16")); Assert.AreEqual(16, TrackUtils.ExtractTrackTotal("15//16.1")); Assert.AreEqual(16, TrackUtils.ExtractTrackTotal("15//16,1")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal("15")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal(" 15")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal(" 15 ")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal("15.1")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal("15,1")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal("")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal(null)); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal("15/aaa")); Assert.AreEqual(0, TrackUtils.ExtractTrackTotal("15/99999999")); }
public void TrackUtils_ApplyLeadingZeroes() { // Use existing track format Assert.AreEqual("1", TrackUtils.FormatWithLeadingZeroes("1", false, 1, false, "")); Assert.AreEqual("1", TrackUtils.FormatWithLeadingZeroes("1", false, 1, false, "10")); Assert.AreEqual("1", TrackUtils.FormatWithLeadingZeroes("1", false, 1, true, "10")); Assert.AreEqual("01", TrackUtils.FormatWithLeadingZeroes("1", false, 2, true, "1")); Assert.AreEqual("01", TrackUtils.FormatWithLeadingZeroes("1", false, 2, false, "1")); Assert.AreEqual("01/01", TrackUtils.FormatWithLeadingZeroes("1/1", false, 2, false, "1")); Assert.AreEqual("01/01", TrackUtils.FormatWithLeadingZeroes("01/1", false, 2, false, "1")); // Override existing track format Assert.AreEqual("1", TrackUtils.FormatWithLeadingZeroes("1", true, 2, false, "10")); Assert.AreEqual("1", TrackUtils.FormatWithLeadingZeroes("1", true, 2, false, "1")); Assert.AreEqual("01", TrackUtils.FormatWithLeadingZeroes("1", true, 2, true, "1")); Assert.AreEqual("01", TrackUtils.FormatWithLeadingZeroes("1", true, 2, true, "10")); Assert.AreEqual("01", TrackUtils.FormatWithLeadingZeroes("1", true, 0, true, "1")); Assert.AreEqual("01/01", TrackUtils.FormatWithLeadingZeroes("1/1", true, 0, true, "1")); Assert.AreEqual("01/01", TrackUtils.FormatWithLeadingZeroes("1/01", true, 0, true, "1")); Assert.AreEqual("001", TrackUtils.FormatWithLeadingZeroes("1", true, 0, true, "100")); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { // Get query terms char track = '@'; // we will never see this in a nat message so we use it as our default bool si = false; // Check track arg if (!string.IsNullOrWhiteSpace(req.Query["id"]) && req.Query["id"].Count == 1) { track = req.Query["id"].ToString()[0]; } // Check SI if (!string.IsNullOrWhiteSpace(req.Query["si"]) && bool.TryParse(req.Query["si"], out var res)) { if (res || !res) { si = res; } } // Get the tracks List <Track> parsedTracks = TrackUtils.ParseTracks(si); Track returnObj = parsedTracks.Where(t => t.Id == track).FirstOrDefault(); // Error if not found if (returnObj == null) { return(new NotFoundObjectResult("The requested track was not found in the message.")); } // Return the result if it is found return(new OkObjectResult(returnObj)); }
public void TrackUtils_DecodePopularity() { // Classic behaviour (more cases in metadata-specific test classes such as ID3v2, APE...) Assert.AreEqual(0.1, TrackUtils.DecodePopularity(((char)15).ToString(), MetaDataIO.RC_ID3v2)); Assert.AreEqual(0.4, TrackUtils.DecodePopularity(((char)117).ToString(), MetaDataIO.RC_ID3v2)); // Star ratings (very rare) // Assert.AreEqual((float)1.0 /5, TrackUtils.DecodePopularity("*", MetaDataIO.RC_ID3v2)); <-- case not handled (see comments in code) Assert.AreEqual(2.0 / 5, TrackUtils.DecodePopularity("**", MetaDataIO.RC_ID3v2)); Assert.AreEqual(3.0 / 5, TrackUtils.DecodePopularity("***", MetaDataIO.RC_ID3v2)); Assert.AreEqual(4.0 / 5, TrackUtils.DecodePopularity("****", MetaDataIO.RC_ID3v2)); Assert.AreEqual(1, TrackUtils.DecodePopularity("*****", MetaDataIO.RC_ID3v2)); // Fringe cases not covered by test data in metadata-specific test classes Assert.AreEqual(0, TrackUtils.DecodePopularity("0", MetaDataIO.RC_ASF)); Assert.AreEqual(0, TrackUtils.DecodePopularity("7", MetaDataIO.RC_APE)); Assert.AreEqual(6.0 / 10, TrackUtils.DecodePopularity("6", MetaDataIO.RC_ID3v2)); Assert.AreEqual(1, TrackUtils.DecodePopularity("10", MetaDataIO.RC_ID3v2)); // Error cases Assert.AreEqual(0, TrackUtils.DecodePopularity("", MetaDataIO.RC_ID3v2)); Assert.AreEqual(0, TrackUtils.DecodePopularity(null, MetaDataIO.RC_ID3v2)); Assert.AreEqual(0, TrackUtils.DecodePopularity("aaa", MetaDataIO.RC_ID3v2)); }
private void readHeaderTags(BinaryReader source, ref SPCHeader header, ReadTagParams readTagParams) { long initialPosition = source.BaseStream.Position; SetMetaField(HEADER_TITLE.ToString(), Utils.Latin1Encoding.GetString(source.ReadBytes(32)).Replace("\0", "").Trim(), readTagParams.ReadAllMetaFrames, ZONE_HEADER); SetMetaField(HEADER_ALBUM.ToString(), Utils.Latin1Encoding.GetString(source.ReadBytes(32)).Replace("\0", "").Trim(), readTagParams.ReadAllMetaFrames, ZONE_HEADER); SetMetaField(HEADER_DUMPERNAME.ToString(), Utils.Latin1Encoding.GetString(source.ReadBytes(16)).Replace("\0", "").Trim(), readTagParams.ReadAllMetaFrames, ZONE_HEADER); SetMetaField(HEADER_COMMENT.ToString(), Utils.Latin1Encoding.GetString(source.ReadBytes(32)).Replace("\0", "").Trim(), readTagParams.ReadAllMetaFrames, ZONE_HEADER); byte[] date, song, fade; // NB : Dump date is used to determine if the tag is binary or text-based. // It won't be recorded as a property of TSPC date = source.ReadBytes(11); song = source.ReadBytes(3); fade = source.ReadBytes(5); bool bin; int dateRes = isText(date); int songRes = isText(song); int fadeRes = isText(fade); //if ( 0 == (dateRes | songRes | fadeRes) ) // No time nor date -> use default //{ bin = true; //} //else if ((songRes != -1) && (fadeRes != -1)) // No time, or time is text { if (dateRes > 0) //If date is text, then tag is text { bin = false; } else if (0 == dateRes) //No date { bin = PREFER_BIN; //Times could still be binary (ex. 56 bin = '8' txt) } else if (-1 == dateRes) //Date contains invalid characters { bin = true; for (int i = 4; i < 8; i++) { bin = bin && (0 == date[i]); } } } else { bin = true; } int fadeVal; int songVal; if (bin) { fadeVal = fade[0] * 0x000001 + fade[1] * 0x0000FF + fade[2] * 0x00FF00 + fade[3] * 0xFF0000; if (fadeVal > 59999) { fadeVal = 59999; } songVal = song[0] * 0x01 + song[1] * 0x10; if (songVal > 959) { songVal = 959; } source.BaseStream.Seek(-1, SeekOrigin.Current); // We're one byte ahead SetMetaField(HEADER_FADE.ToString(), Utils.Latin1Encoding.GetString(fade), readTagParams.ReadAllMetaFrames, ZONE_HEADER); } else { fadeVal = TrackUtils.ExtractTrackNumber(Utils.Latin1Encoding.GetString(fade)); songVal = TrackUtils.ExtractTrackNumber(Utils.Latin1Encoding.GetString(song)); SetMetaField(HEADER_FADE.ToString(), Utils.Latin1Encoding.GetString(fade), readTagParams.ReadAllMetaFrames, ZONE_HEADER); } SetMetaField(HEADER_DUMPDATE.ToString(), Utils.Latin1Encoding.GetString(date), readTagParams.ReadAllMetaFrames, ZONE_HEADER); SetMetaField(HEADER_SONGLENGTH.ToString(), Utils.Latin1Encoding.GetString(song), readTagParams.ReadAllMetaFrames, ZONE_HEADER); // if fadeval > 0 alone, the fade is applied on the default 3:00 duration without extending it if (songVal > 0) { duration = Math.Round((double)fadeVal) + songVal; } SetMetaField(HEADER_ARTIST.ToString(), Utils.Latin1Encoding.GetString(source.ReadBytes(32)).Replace("\0", "").Trim(), readTagParams.ReadAllMetaFrames, ZONE_HEADER); header.Size += source.BaseStream.Position - initialPosition; if (readTagParams.PrepareForWriting) { structureHelper.AddZone(initialPosition, (int)(source.BaseStream.Position - initialPosition), ZONE_HEADER); } }
protected override void Merge(Track source, Track target) { TrackUtils.Merge(source, target); }
protected override QueryFilters <TrackProperty> GetChanges(Track original, Track changed) { return(TrackUtils.GetChanges(original, changed)); }
private TagData toTagData() { TagData result = new TagData(); result.Title = Title; result.Artist = Artist; result.Composer = Composer; result.Comment = Comment; result.Genre = Genre; result.OriginalArtist = OriginalArtist; result.OriginalAlbum = OriginalAlbum; result.GeneralDescription = Description; result.Rating = (Popularity * 5).ToString(); result.Copyright = Copyright; result.Publisher = Publisher; if (!PublishingDate.Equals(DateTime.MinValue)) { result.PublishingDate = TrackUtils.FormatISOTimestamp(PublishingDate); } result.AlbumArtist = AlbumArtist; result.Conductor = Conductor; if (!Date.Equals(DateTime.MinValue)) { result.RecordingDate = TrackUtils.FormatISOTimestamp(Date); } result.RecordingYear = Year.ToString(); result.Album = Album; result.TrackNumber = TrackNumber.ToString(); result.TrackTotal = TrackTotal.ToString(); result.DiscNumber = DiscNumber.ToString(); result.DiscTotal = DiscTotal.ToString(); result.ChaptersTableDescription = ChaptersTableDescription.ToString(); result.Chapters = new List <ChapterInfo>(); foreach (ChapterInfo chapter in Chapters) { result.Chapters.Add(new ChapterInfo(chapter)); } if (Lyrics != null) { result.Lyrics = new LyricsInfo(Lyrics); } foreach (string s in AdditionalFields.Keys) { result.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_ANY, s, AdditionalFields[s])); } // Detect and tag deleted Additional fields (=those which were in initialAdditionalFields and do not appear in AdditionalFields anymore) foreach (string s in initialAdditionalFields) { if (!AdditionalFields.ContainsKey(s)) { MetaFieldInfo metaFieldToDelete = new MetaFieldInfo(MetaDataIOFactory.TAG_ANY, s, ""); metaFieldToDelete.MarkedForDeletion = true; result.AdditionalFields.Add(metaFieldToDelete); } } result.Pictures = new List <PictureInfo>(); if (currentEmbeddedPictures != null) { foreach (PictureInfo targetPic in currentEmbeddedPictures) { targetPic.TransientFlag = 0; } } if (initialEmbeddedPictures != null && currentEmbeddedPictures != null) { foreach (PictureInfo picInfo in initialEmbeddedPictures) { // Detect and tag deleted pictures (=those which were in initialEmbeddedPictures and do not appear in embeddedPictures anymore) if (!currentEmbeddedPictures.Contains(picInfo)) { PictureInfo picToDelete = new PictureInfo(picInfo); picToDelete.MarkedForDeletion = true; result.Pictures.Add(picToDelete); } else // Only add new additions (pictures identical to initial list will be kept, and do not have to make it to the list, or else a duplicate will be created) { foreach (PictureInfo targetPic in currentEmbeddedPictures) { if (targetPic.Equals(picInfo)) { // Compare picture contents targetPic.ComputePicHash(); if (targetPic.PictureHash != picInfo.PictureHash) { // A new picture content has been defined for an existing location result.Pictures.Add(targetPic); PictureInfo picToDelete = new PictureInfo(picInfo); picToDelete.MarkedForDeletion = true; result.Pictures.Add(picToDelete); } targetPic.TransientFlag = 1; } } } } if (currentEmbeddedPictures != null) { foreach (PictureInfo targetPic in currentEmbeddedPictures) { if (0 == targetPic.TransientFlag) // Entirely new pictures without equivalent in initialEmbeddedPictures { result.Pictures.Add(targetPic); } } } } return(result); }
private uint writeFrames(TagData tag, BinaryWriter w) { bool doWritePicture; uint nbFrames = 0; IDictionary <byte, String> map = tag.ToMap(); // Supported textual fields foreach (byte frameType in map.Keys) { foreach (string s in frameMapping.Keys) { if (frameType == frameMapping[s]) { if (map[frameType].Length > 0) // No frame with empty value { string value = map[frameType]; if (TagData.TAG_FIELD_RATING == frameType) { value = TrackUtils.EncodePopularity(value, ratingConvention).ToString(); } writeTextFrame(w, s, value); nbFrames++; } break; } } } // Chapters if (Chapters.Count > 0) { writeChapters(w, Chapters); } // Other textual fields foreach (MetaFieldInfo fieldInfo in tag.AdditionalFields) { if ((fieldInfo.TagType.Equals(MetaDataIOFactory.TAG_ANY) || fieldInfo.TagType.Equals(getImplementedTagType())) && !fieldInfo.MarkedForDeletion && !fieldInfo.NativeFieldCode.Equals(VENDOR_METADATA_ID)) { writeTextFrame(w, fieldInfo.NativeFieldCode, fieldInfo.Value); nbFrames++; } } // Picture fields if (writePicturesWithMetadata) { foreach (PictureInfo picInfo in tag.Pictures) { // Picture has either to be supported, or to come from the right tag standard doWritePicture = !picInfo.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported); if (!doWritePicture) { doWritePicture = (getImplementedTagType() == picInfo.TagType); } // It also has not to be marked for deletion doWritePicture = doWritePicture && (!picInfo.MarkedForDeletion); if (doWritePicture) { writePictureFrame(w, picInfo.PictureData, picInfo.NativeFormat, ImageUtils.GetMimeTypeFromImageFormat(picInfo.NativeFormat), picInfo.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) ? picInfo.NativePicCode : ID3v2.EncodeID3v2PictureType(picInfo.PicType), picInfo.Description); nbFrames++; } } } return(nbFrames); }
protected void readExistingTagsOnFile(AudioDataManager theFile, int nbPictures = 2) { Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.getMeta(tagType)); IMetaDataIO meta = theFile.getMeta(tagType); Assert.IsTrue(meta.Exists); // Supported fields if (testData.Title != null) { Assert.AreEqual(testData.Title, meta.Title); } if (testData.Album != null) { Assert.AreEqual(testData.Album, meta.Album); } if (testData.Artist != null) { Assert.AreEqual(testData.Artist, meta.Artist); } if (testData.AlbumArtist != null) { Assert.AreEqual(testData.AlbumArtist, meta.AlbumArtist); } if (testData.Comment != null) { Assert.AreEqual(testData.Comment, meta.Comment); } if (testData.RecordingYear != null) { Assert.AreEqual(testData.RecordingYear, meta.Year); } //if (testData.RecordingDate != null) Assert.AreEqual(testData.RecordingDate, meta.); if (testData.Genre != null) { Assert.AreEqual(testData.Genre, meta.Genre); } if (testData.Rating != null) { if (Utils.IsNumeric(testData.Rating)) { float f = float.Parse(testData.Rating); Assert.AreEqual((f / 5.0).ToString(), meta.Popularity.ToString()); } else if (0 == testData.Rating.Length) { Assert.AreEqual("0", meta.Popularity.ToString()); } else { Assert.AreEqual(testData.Rating, meta.Popularity.ToString()); } } if (testData.TrackNumber != null) { Assert.AreEqual(TrackUtils.ExtractTrackNumber(testData.TrackNumber).ToString(), meta.Track.ToString()); } if (testData.Composer != null) { Assert.AreEqual(testData.Composer, meta.Composer); } if (testData.DiscNumber != null) { Assert.AreEqual(TrackUtils.ExtractTrackNumber(testData.DiscNumber).ToString(), meta.Disc.ToString()); } if (testData.Conductor != null) { Assert.AreEqual(testData.Conductor, meta.Conductor); } if (testData.Publisher != null) { Assert.AreEqual(testData.Publisher, meta.Publisher); } if (testData.Copyright != null) { Assert.AreEqual(testData.Copyright, meta.Copyright); } if (testData.GeneralDescription != null) { Assert.AreEqual(testData.GeneralDescription, meta.GeneralDescription); } // Unsupported field if (testData.AdditionalFields != null && testData.AdditionalFields.Count > 0) { foreach (MetaFieldInfo field in testData.AdditionalFields) { Assert.IsTrue(meta.AdditionalFields.Keys.Contains(field.NativeFieldCode)); Assert.AreEqual(field.Value, meta.AdditionalFields[field.NativeFieldCode]); } } // Pictures if (testData.Pictures != null && testData.Pictures.Count > 0) { Assert.AreEqual(nbPictures, meta.EmbeddedPictures.Count); byte nbFound = 0; foreach (PictureInfo pic in meta.EmbeddedPictures) { foreach (PictureInfo testPicInfo in testData.Pictures) { if (pic.NativePicCode.Equals(testPicInfo.NativePicCode) || (pic.NativePicCodeStr != null && pic.NativePicCodeStr.Equals(testPicInfo.NativePicCodeStr)) ) { nbFound++; pic.ComputePicHash(); Assert.AreEqual(testPicInfo.PictureHash, pic.PictureHash); } } } Assert.AreEqual(testData.Pictures.Count, nbFound); } }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { // Get query terms bool si = false; bool eventTracks = false; bool concorde = false; // Check SI if (!string.IsNullOrWhiteSpace(req.Query["si"]) && bool.TryParse(req.Query["si"], out var res)) { if (res || !res) { si = res; } } // Check event tracks if (string.IsNullOrWhiteSpace(req.Query["concorde"]) && !string.IsNullOrWhiteSpace(req.Query["event"]) && bool.TryParse(req.Query["event"], out var res1)) { if (res1 || !res1) { eventTracks = res1; } } // Check SI if (string.IsNullOrWhiteSpace(req.Query["event"]) && !string.IsNullOrWhiteSpace(req.Query["concorde"]) && bool.TryParse(req.Query["concorde"], out var res2)) { if (res2 || !res2) { concorde = res2; } } // Get the tracks List <Track> parsedTracks = new List <Track>(); // Return the results if (eventTracks) { // Event path string path = "https://ganderoceanicoca.ams3.digitaloceanspaces.com/resources/data/eventTracks.json"; // Return using (WebClient client = new WebClient()) { return(new OkObjectResult(client.DownloadString(path))); } } else if (concorde) { // Concorde track path string path = "https://ganderoceanicoca.ams3.digitaloceanspaces.com/resources/data/concordeTracks.json"; // Return using (WebClient client = new WebClient()) { return(new OkObjectResult(client.DownloadString(path))); } } else { // Assign and return parsedTracks = TrackUtils.ParseTracks(si); return(new OkObjectResult(parsedTracks)); } }
public void TrackUtils_FormatISOTimestamp() { Assert.AreEqual("1990-04-01", TrackUtils.FormatISOTimestamp("1990", "0104", "")); Assert.AreEqual("1990-04-01T04:12", TrackUtils.FormatISOTimestamp("1990", "0104", "0412")); Assert.AreEqual("1990-04-01T04:12:44", TrackUtils.FormatISOTimestamp("1990", "0104", "041244")); }
private Int32 writeFrames(TagData tag, BinaryWriter w) { Boolean doWritePicture; var nbFrames = 0; // Picture fields (first before textual fields, since APE tag is located on the footer) foreach (var picInfo in tag.Pictures) { // Picture has either to be supported, or to come from the right tag standard doWritePicture = !picInfo.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported); if (!doWritePicture) { doWritePicture = (getImplementedTagType() == picInfo.TagType); } // It also has not to be marked for deletion doWritePicture = doWritePicture && (!picInfo.MarkedForDeletion); if (doWritePicture) { writePictureFrame(w, picInfo.PictureData, picInfo.NativeFormat, ImageUtils.GetMimeTypeFromImageFormat(picInfo.NativeFormat), picInfo.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) ? picInfo.NativePicCodeStr : encodeAPEPictureType(picInfo.PicType), picInfo.Description); nbFrames++; } } var map = tag.ToMap(); // Supported textual fields foreach (var frameType in map.Keys) { foreach (var s in frameMapping.Keys) { if (frameType == frameMapping[s]) { if (map[frameType].Length > 0) // No frame with empty value { var value = map[frameType]; if (TagData.TAG_FIELD_RATING == frameType) { value = TrackUtils.EncodePopularity(value, ratingConvention).ToString(); } writeTextFrame(w, s, value); nbFrames++; } break; } } } // Other textual fields foreach (var fieldInfo in tag.AdditionalFields) { if ((fieldInfo.TagType.Equals(MetaDataIOFactory.TAG_ANY) || fieldInfo.TagType.Equals(getImplementedTagType())) && !fieldInfo.MarkedForDeletion) { writeTextFrame(w, fieldInfo.NativeFieldCode, fieldInfo.Value); nbFrames++; } } return(nbFrames); }