示例#1
0
 public PerceptualTime(
     TupletClass tuplet,
     LengthClass length,
     int dots
     )
 {
     Tuplet = tuplet;
     Length = length;
     Dots   = dots;
 }
示例#2
0
        void LayoutBeams()
        {
            var beamsequences =
                new List <ChordLayout[]>();

            foreach (var chord in chords.OrderBy(chord => chord.Duration.Start).OrderByDescending(chord => chord.Duration.Length.Ticks))
            {
                if (chord.Flags != 0)
                {
                    continue; // already hit
                }
                if (chord.Length.Length > LengthClass.Quarter)
                {
                    var cell =
                        chord.Notes[0].Core.Cell;

                    if (chord.Duration.End < cell.Duration.End)
                    {
                        var train =
                            new List <ChordLayout>();

                        var last = chord;

                        while (last.Duration.End < cell.Duration.End)
                        {
                            train.Add(last);

                            var candidates =
                                chords
                                .Where(candidate => candidate.Duration.Start == last.Duration.End)
                                .Where(candidate => candidate.Duration.Length < Time.Note_4th)
                                .ToArray();

                            var bestcandidate =
                                candidates
                                .OrderBy(
                                    candidate =>
                                    candidate.Notes.Min(note => Math.Abs(note.HalfLine - last.Notes.Min(note2 => note2.HalfLine)))
                                    )
                                .FirstOrDefault();

                            if (bestcandidate == null)
                            {
                                break;
                            }

                            last = bestcandidate;
                        }

                        if (last.Duration.End == cell.Duration.End)
                        {
                            train.Add(last);
                        }

                        if (train.Count > 1)
                        {
                            var Xs =
                                train.Select(item => item.X).ToArray();

                            var Ys =
                                train.Select(item => item.Notes.Average(note => (float)note.HalfLine)).ToArray();

                            float m, b;
                            if (!Statistics.LinearRegression(Xs, Ys, out m, out b))
                            {
                                b = 0;
                                m = 0;
                            }

                            var stemdirection = NoteStemDirection.None;
                            var stemside      = NoteStemSide.None;
                            if (train.Average(chordi => chordi.Notes.Average(notei => (float)notei.HalfLine)) >= staff.MiddleHalfLine)
                            {
                                stemdirection = NoteStemDirection.Down;
                                stemside      = NoteStemSide.Left;
                            }
                            else
                            {
                                stemdirection = NoteStemDirection.Up;
                                stemside      = NoteStemSide.Right;
                            }

                            float stemoffset = 3;
                            if (stemdirection == NoteStemDirection.Down)
                            {
                                stemoffset *= -1;
                            }

                            LengthClass lastlengthclass = LengthClass.Invalid;
                            for (var i = 0; i < train.Count; i++)
                            {
                                var is1  = i == 0;
                                var is2  = i == 1;
                                var item = train[i];

                                item.StemDirection   = stemdirection;
                                item.StemSide        = stemside;
                                item.FlagSlope       = m;
                                item.LastLengthClass = lastlengthclass;
                                lastlengthclass      = item.Length.Length;

                                if (is1)
                                {
                                    item.FlagDirection = FlagDirection.Right;
                                    item.FlagLength    = ToVirtualPX(item.Duration.Length);
                                }
                                else
                                {
                                    item.FlagDirection = FlagDirection.Left;
                                    item.FlagLength    = ToVirtualPX(train[i - 1].Duration.Length);
                                }

                                if (is1 || is2)
                                {
                                    item.FlagLength /= 2F;
                                }
                                else
                                {
                                    item.Past2nd = true;
                                }

                                item.TiedFlags = item.Length.Length - LengthClass.Quarter;
                                //TODO: also identify which are free flags

                                item.StemStartHalfLines = stemoffset + item.X * m + b;
                            }
                        }
                        else
                        {
                            chord.FreeFlags = chord.Length.Length - LengthClass.Quarter;

                            if (chord.StemDirection == NoteStemDirection.Down)
                            {
                                chord.FlagDirection = FlagDirection.Left;
                            }
                            else
                            {
                                chord.FlagDirection = FlagDirection.Right;
                            }
                        }
                    }
                    else
                    {
                        chord.FreeFlags = chord.Length.Length - LengthClass.Quarter;

                        if (chord.StemDirection == NoteStemDirection.Down)
                        {
                            chord.FlagDirection = FlagDirection.Left;
                        }
                        else
                        {
                            chord.FlagDirection = FlagDirection.Right;
                        }
                    }
                }
            }
        }