public override AtTag Encode(RubyTag?component)
        {
            var rubyTag = component.Value;

            var rubyIndex = Array.IndexOf(_lyric?.RubyTags ?? new [] { rubyTag }, rubyTag);

            var name  = "Ruby" + (rubyIndex + 1);
            var value = $"{rubyTag.Parent},{rubyTag.Ruby}";

            if (rubyTag.StartPosition == null && rubyTag.EndPosition == null)
            {
                return new AtTag
                       {
                           Name  = name,
                           Value = value
                       }
            }
            ;

            var startTimeTag = GenerateTimeTagByPosition(rubyTag.StartPosition);
            var endTimeTag   = GenerateTimeTagByPosition(rubyTag.EndPosition);

            value += $",{startTimeTag},{endTimeTag}";

            // TODO : need to implement time range
            return(new AtTag
            {
                Name = name,
                Value = value
            });

            string GenerateTimeTagByPosition(Position?position)
            {
                if (position == null)
                {
                    return(null);
                }

                // Get position value
                var p = position.Value;

                //Get time
                var time = _lyric?.Lines[p.Line]?.TimeTags[p.Index].Time;

                return(time == null ? null : TimeTagExtension.MillionSecondToTimeTag(time.Value));
            }
        }
    }
Example #2
0
        public override string Encode(LyricLine line)
        {
            var sb = new StringBuilder();

            //Add head time tag
            sb.Append(HeadTimeTag(line));

            //Get time tag and chat for each char
            for (var i = 0; i < line.Text.Length; i++)
            {
                sb.Append(TimeTaggedChar(line, i));
            }

            //Add tail time tag
            sb.Append(TailTimeTag(line));

            return(sb.ToString());

            string TimeTaggedChar(LyricLine l, int index)
            {
                var t1 = l.TimeTags[1 + index * 2];
                var t2 = l.TimeTags[1 + index * 2 + 1];

                return(TimeTagExtension.MillionSecondToTimeTag(t1.CheckedTime) +
                       l.Text[index] +
                       TimeTagExtension.MillionSecondToTimeTag(t2.CheckedTime));
            }

            string HeadTimeTag(LyricLine l)
            {
                return(TimeTagExtension.MillionSecondToTimeTag(l.TimeTags[0].CheckedTime));
            }

            string TailTimeTag(LyricLine l)
            {
                return(TimeTagExtension.MillionSecondToTimeTag(l.TimeTags[l.TimeTags.Length - 1].CheckedTime));
            }
        }
Example #3
0
 public void Initialize()
 {
     // Use [mm:ss:ss]
     TimeTagExtension.SetDecimalPointColon();
 }
        public override RubyTag?Decode(AtTag tag)
        {
            if (!tag.Name.ToLower().StartsWith("ruby"))
            {
                return(null);
            }

            var      values        = tag.Value.Split(',');
            var      parent        = values[0];
            var      ruby          = values[1];
            Position?startPosition = null;
            Position?endPosition   = null;

            // Filter duplicated if ruby == parent's text
            if (_filterDuplicated && ruby == parent)
            {
                return(null);
            }

            // TODO : have a better way to deal time tag in ruby.
            ruby = string.Join("", TimeTagExtension.SeparateKaraokeLine(ruby).Select(x => x.Word));

            // Has start time and end time
            if (values.Length >= 3)
            {
                startPosition = FindPositionByTimeTag(values[2]);
            }
            if (values.Length > 3)
            {
                endPosition = FindPositionByTimeTag(values[3]);
            }

            return(new RubyTag
            {
                Parent = parent,
                Ruby = ruby,
                StartPosition = startPosition,
                EndPosition = endPosition
            });

            Position?FindPositionByTimeTag(string timeTagText)
            {
                if (string.IsNullOrEmpty(timeTagText))
                {
                    return(null);
                }

                var milliSecond = TimeTagExtension.TimeTagToMillionSecond(timeTagText);

                for (var i = 0; i < _lyric.Lines.Length; i++)
                {
                    var line = _lyric.Lines[i];
                    for (var j = 0; j < line.TimeTags.Length; j++)
                    {
                        var timeTag = line.TimeTags[j];
                        if (timeTag.Time == milliSecond)
                        {
                            return(new Position
                            {
                                Line = i,
                                Index = (int)Math.Ceiling((float)(j - 1) / 2)
                            });
                        }
                    }
                }

                return(null);
            }
        }
Example #5
0
        public override LyricLine Decode(string t)
        {
            var pairs = TimeTagExtension.SeparateKaraokeLine(t);

            // Combine texts
            var text = pairs.Aggregate("", (current, p) => current + p.Word);

            // Create and make sure all check is false
            var timeTags = new TimeTag[text.Length * 2 + 2];

            for (var i = 0; i < timeTags.Length; i++)
            {
                timeTags[i] = new TimeTag(-1, false);
            }

            // TODO : what is ti
            int ti;

            if (pairs[0].Word == "")
            {
                timeTags[0] = new TimeTag(pairs[0].MillionSecond, pairs[0].MillionSecond > 0);
                ti          = 1;
            }
            else
            {
                timeTags[1] = new TimeTag(pairs[0].MillionSecond, pairs[0].MillionSecond > 0);
                ti          = pairs[0].Word.Length * 2;
            }

            // TODO : what are this doing
            for (var pi = 1; pi < pairs.Length; pi++)
            {
                if (pairs[pi].Word.Length == 0)
                {
                    if (ti % 2 == 0)
                    {
                        timeTags[ti] = new TimeTag(pairs[pi].MillionSecond);
                        ti++;
                    }
                }
                else
                {
                    if (ti % 2 == 0)
                    {
                        ti++;
                    }
                    timeTags[ti] = new TimeTag(pairs[pi].MillionSecond);
                    ti          += pairs[pi].Word.Length * 2 - 1;
                }
            }

            // 隣接した同時間タイムタグがあれば、手前(文字後)を無効化
            for (var i = 0; i < timeTags.Length; i += 2)
            {
                if (timeTags[i].Time == timeTags[i + 1].Time && timeTags[i].Check && timeTags[i + 1].Check)
                {
                    var tag = timeTags[i];
                    tag.Check   = false;
                    timeTags[i] = tag;
                }
            }

            return(new LyricLine
            {
                Text = text,
                TimeTags = timeTags
            });
        }