/* 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); }