public void NewMeasure(double beatSpaceLength) { if (_measureBeatSpace != null) { _beatCursor = _measureBeatSpace.End; } _measureBeatSpace = new LinearInterval { Start = _beatCursor, End = _beatCursor + beatSpaceLength }; }
public static IEnumerable <SongSegment> CalculateSongSegments(Tempo tempo, double songLength, double offset = 0) { var bpmChanges = tempo.Bpm.ToList(); if (!bpmChanges.Any()) { throw new ArgumentException("tempo must at least contain one bpm entry", nameof(tempo)); } if (bpmChanges.First().Time > 0) { bpmChanges[0] = new BpmChange { Time = 0, Bpm = bpmChanges.First().Bpm }; } var segmentBoundaries = new Queue <ITimeIndexed>( bpmChanges.Cast <ITimeIndexed>() .Concat(tempo.Interruptions.Cast <ITimeIndexed>()) .OrderBy(x => x.Time)); var timeCursor = offset; var beatCursor = 0.0; var bpm = 0.0; var segments = new List <SongSegment>(); Action <double> commitSegment = end => { var songTime = new LinearInterval { Start = timeCursor, End = end }; var beatSpace = new LinearInterval { Start = beatCursor, End = beatCursor + songTime.Length * bpm / 60 }; segments.Add(new SongSegment { Bpm = bpm, SongTime = songTime, BeatSpace = beatSpace }); }; while (segmentBoundaries.Count > 0) { var current = segmentBoundaries.Dequeue(); if (current.Time > timeCursor) { commitSegment(current.Time); timeCursor = current.Time; beatCursor += segments.Last().BeatSpace.Length; } var bpmChange = current as BpmChange; if (bpmChange != null) { bpm = bpmChange.Bpm; } var interruption = current as Interruption; if (interruption != null) { timeCursor += interruption.Duration; } } if (timeCursor < songLength) { commitSegment(songLength); } return(segments); }