示例#1
0
        /// <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);
        }
示例#2
0
        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));
        }
示例#3
0
        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);
        }
示例#4
0
        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"));
        }
示例#5
0
        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;
            }
        }
示例#6
0
        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"));
        }
示例#7
0
        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));
            }
        }
示例#8
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"));
        }
示例#10
0
        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"));
        }
示例#11
0
        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));
        }
示例#12
0
        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));
        }
示例#13
0
        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));
 }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        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);
            }
        }
示例#19
0
        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));
            }
        }
示例#20
0
 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"));
 }
示例#21
0
        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);
        }