/* There are two constructors, one of which is a copy constructor. */
        public BeatTracker(double interval, BeatEvent firstEvent, double originalScore)
        {
            Interval       = interval;
            NextPrediction = firstEvent.Time + interval;
            ProcessedItems = new List <BeatEvent>();
            ProcessedItems.Add(firstEvent);

            /* NOTE: For now we use sum of velocities as the rating.
             * This could also use drum-specific information. */
            Rating        = firstEvent.Notes.Sum(n => n.Velocity);
            OriginalScore = originalScore;
        }
        /* Create a rhythm from a tracker and list of events, by quantizing the events
         * according to the beat tracker given to the function. */
        public static RhythmStructure CreateRhythm(BeatTracker tracker, List <BeatEvent> events)
        {
            const byte      numDivisions = 4;
            int             eventIndex   = 0;
            RhythmStructure rhythm       = new RhythmStructure(tracker.Interval);

            /* Iterate over all the beats and semiquavers, and set the semiquaver interval. */
            for (int i = 0; i < tracker.ProcessedItems.Count; i++)
            {
                BeatEvent baseEvent = tracker.ProcessedItems[i];
                double    interval;
                if (i != tracker.ProcessedItems.Count - 1)
                {
                    BeatEvent nextEvent = tracker.ProcessedItems[i + 1];
                    interval = (nextEvent.Time - baseEvent.Time) / 4;
                }
                else
                {
                    interval = (tracker.NextPrediction - baseEvent.Time) / 4;
                }

                for (int j = 0; j < numDivisions; j++)
                {
                    HashSet <Drum> drums = new HashSet <Drum>();

                    /* Determine the time at which one semiquaver event occurs and then quantizes each note event to the semiquaver. */
                    double baseTime = baseEvent.Time + (j * interval);
                    if (eventIndex < events.Count && baseTime - (interval / 2) < events[eventIndex].Time && baseTime + (interval / 2) > events[eventIndex].Time)
                    {
                        foreach (NoteEvent noteEvent in events[eventIndex].Notes)
                        {
                            if (indexToDrum.Keys.Contains(noteEvent.Channel))
                            {
                                Drum drum = indexToDrum[noteEvent.Channel];
                                drums.Add(drum);
                            }
                        }
                        eventIndex++;
                    }

                    rhythm.AddDrums(drums);
                }
            }

            return(rhythm);
        }
 public EventInterval(BeatEvent event1, BeatEvent event2)
 {
     Event1 = event1;
     Event2 = event2;
     Length = Math.Abs(event1.Time - event2.Time);
 }