private double GetStartingValue(EnvelopeCore.StepCollection coll)
        {
            double startingValue = 0;

            if (coll.Phase == EnvelopePhase.Loop)
            {
                if (coll.ParentEnvelope.Attack.Any())
                {
                    startingValue = coll.ParentEnvelope.Attack.Last().TargetValue;
                }
                else
                {
                    startingValue = 1;
                }
            }
            else if (coll.Phase == EnvelopePhase.Release)
            {
                if (coll.ParentEnvelope.Loop.Any())
                {
                    startingValue = coll.ParentEnvelope.Loop.Last().TargetValue;
                }
                else if (coll.ParentEnvelope.Attack.Any())
                {
                    startingValue = coll.ParentEnvelope.Attack.Last().TargetValue;
                }
                else
                {
                    startingValue = 1;
                }
            }

            return(startingValue);
        }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
            {
                return(null);
            }

            if (!(value is EnvelopeCore.StepCollection))
            {
                throw new ArgumentException("EnvPhaseToGeometryConverter requires a value of type StepCollection");
            }

            double totalSeconds = 0;

            EnvelopeCore.StepCollection coll = value as EnvelopeCore.StepCollection;
            Point[] points = coll.Select(s => new Point(totalSeconds += s.Seconds, 1 - s.TargetValue)).ToArray();

            double startingValue = GetStartingValue(coll);

            // The units don't matter here -- just that the projection is independently proportional on each axis.
            // For display, the path objects of related stepcollections eill need to have the same scaling as each other to line up correctly.

            PathFigure figure = new PathFigure();

            figure.StartPoint = new Point(0, 1 - startingValue);

            if (coll.Any())
            {
                points.Execute(p => figure.Segments.Add(new LineSegment(p, true)));

                if (coll.Phase == EnvelopePhase.Release && coll.Last().TargetValue != 0)
                {
                    figure.Segments.Add(new LineSegment(new Point(totalSeconds, 1), true));
                }

                AddFrame(figure, coll.TotalSeconds);
            }
            else if (coll.Phase == EnvelopePhase.Loop)
            {
                figure.Segments.Add(new LineSegment(new Point(coll.TotalSeconds, 1 - startingValue), true));
                AddFrame(figure, coll.TotalSeconds);
            }

            PathGeometry geo = new PathGeometry();

            geo.Figures.Add(figure);
            geo.Freeze();

            return(geo);
        }