public ChordSegment(Key key, ChordSegment previousChordSegment, BeatEvent beat, byte lowestPitch)
        {
            Key = key;
            PreviousChordSegment = previousChordSegment;
            Beat = beat;

            NotesInLevel2Beats = new NotesInSegment(beat.AbsoluteRealTime, beat.Length, lowestPitch);

            BestPrevious = new int[24];
            Scores       = new double[24];
            BaseScores   = new double[24];
        }
        private void AddNotesToSegments()
        {
            var current = 0;
            var notes   = _midi.EventsOfType <NoteOn>().Where(n => !n.IsPercussion && n.Volume > 0).OrderBy(n => n.AbsoluteRealTime);

            foreach (var note in notes)
            {
                // while the segment does not contain this note
                while (_segments[current].Beat.AbsoluteRealTime + _segments[current].Beat.Length <= note.AbsoluteRealTime)
                {
                    current++;
                }

                for (var span = current; span < _segments.Length && _segments[span].Beat.AbsoluteRealTime < note.End; span++)
                {
                    _segments[span].AddNote(note);
                }
            }

            var notesInLevel0 = new NotesInSegment(TimeSpan.Zero, TimeSpan.Zero, _lowestPitch);
            var notesInLevel1 = new NotesInSegment(TimeSpan.Zero, TimeSpan.Zero, _lowestPitch);

            foreach (var segment in _segments)
            {
                if (segment.Beat.Level == 1 || segment.Beat.Level == 0)
                {
                    notesInLevel1.ComputeScores(true);
                    notesInLevel1 = new NotesInSegment(segment.Beat.AbsoluteRealTime, TimeSpan.Zero, _lowestPitch);
                }
                if (segment.Beat.Level == 0)
                {
                    notesInLevel0.ComputeScores(false);
                    notesInLevel0 = new NotesInSegment(segment.Beat.AbsoluteRealTime, TimeSpan.Zero, _lowestPitch);
                }

                segment.NotesInLevel0Beats = notesInLevel0;
                segment.NotesInLevel1Beats = notesInLevel1;

                notesInLevel0.Join(segment.NotesInLevel2Beats);
                notesInLevel1.Join(segment.NotesInLevel2Beats);
            }

            notesInLevel0.ComputeScores(false);
            notesInLevel1.ComputeScores(true);
        }