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];
        }
        public ChordAnalyzer(Model midi)
        {
            _midi     = midi;
            _beats    = _midi.EventsOfType <BeatEvent>().OrderBy(b => b.AbsoluteRealTime).ToArray();
            _segments = new ChordSegment[_beats.Length];

            _lowestPitch = midi.EventsOfType <NoteOn>(n => !n.IsPercussion && n.Volume > 0).Min(n => n.NoteNumber);

            var keyChanges = midi.IsKeyFoundByMidiItself
                ? new Queue <KeySignature>(midi.EventsOfType <KeySignature>().OrderBy(k => k.AbsoluteRealTime))
                : new Queue <KeySignature>();
            var actualKey = midi.IsKeyFoundByMidiItself ? keyChanges.Dequeue().Key : midi.Key.Value;

            _segments[0] = new ChordSegment(actualKey, null, _beats[0], _lowestPitch);
            for (var i = 1; i < _segments.Length; i++)
            {
                while (keyChanges.Count > 0 && keyChanges.Peek().AbsoluteRealTime <= _beats[i].AbsoluteRealTime)
                {
                    actualKey = keyChanges.Dequeue().Key;
                }

                _segments[i] = new ChordSegment(actualKey, _segments[i - 1], _beats[i], _lowestPitch);
            }
        }