public Spring AddSpring(int start, int duration, float preSpringSize, float postSpringSize) { Version++; Spring spring; if (!Springs.ContainsKey(start)) { spring = new Spring(); spring.TimePosition = start; spring.AllDurations.Add(duration); // check in the previous spring for the shortest duration that overlaps with this spring // Gourlay defines that we need the smallest note duration that either starts **or continues** on the current spring. if (_timeSortedSprings.Count > 0) { int smallestDuration = duration; var previousSpring = _timeSortedSprings[_timeSortedSprings.Count - 1]; foreach (var prevDuration in previousSpring.AllDurations) { var end = previousSpring.TimePosition + prevDuration; if (end >= start && prevDuration < smallestDuration) { smallestDuration = prevDuration; } } } spring.LongestDuration = duration; spring.PostSpringWidth = postSpringSize; spring.PreSpringWidth = preSpringSize; Springs[start] = spring; var timeSorted = _timeSortedSprings; var insertPos = timeSorted.Count - 1; while (insertPos > 0 && timeSorted[insertPos].TimePosition > start) { insertPos--; } _timeSortedSprings.InsertAt(insertPos + 1, spring); } else { spring = Springs[start]; if (spring.PostSpringWidth < postSpringSize) { spring.PostSpringWidth = postSpringSize; } if (spring.PreSpringWidth < preSpringSize) { spring.PreSpringWidth = preSpringSize; } if (duration < spring.SmallestDuration) { spring.SmallestDuration = duration; } if (duration > spring.LongestDuration) { spring.LongestDuration = duration; } spring.AllDurations.Add(duration); } if (_minTime > start) { _minTime = start; } return(spring); }