public void Parse() { bool success = MeasuredTimePosition.TryParse("1:1.500", out var timePosition); Assert.IsTrue(success, "Unparsable because ???"); Assert.AreEqual(new MeasuredTimePosition(1, 1, 0.5f), timePosition, "Something wrong with parsing"); }
public void AdvanceToStartOfNextMeasure() { var timePosition = new MeasuredTimePosition(1, 2, 0); timePosition.AdvanceToStartOfNextMeasure(); Assert.AreEqual(new MeasuredTimePosition(2, 1, 0), timePosition, "I cannot believe I wrote a test case for this"); }
/// <summary>Creates a new instance of the <seealso cref="GuidelineEditorPreset"/> class.</summary> /// <param name="name">The name of the preset.</param> /// <param name="offset">The offset, in seconds, of the preset.</param> /// <param name="start">The starting position from which to generate the guidelines.</param> /// <param name="end">The ending position at which to stop generating the guidelines.</param> public GuidelineEditorPreset(string name, double offset, MeasuredTimePosition start, MeasuredTimePosition end) { Name = name; Offset = offset; StartingPosition = start; EndingPosition = end; }
public void Comparison() { var timePositions = new MeasuredTimePosition[] { new MeasuredTimePosition(1, 1, 0.5f), new MeasuredTimePosition(1, 2, 0.5f), new MeasuredTimePosition(2, 1, 0), new MeasuredTimePosition(2, 420, 0.1337f), new MeasuredTimePosition(3, 1, 0), }; for (int i = 0; i < timePositions.Length; i++) { for (int j = 0; j < i; j++) { Assert.IsTrue(timePositions[i] > timePositions[j]); } Assert.IsTrue(timePositions[i] == timePositions[i]); for (int j = i + 1; j < timePositions.Length; j++) { Assert.IsTrue(timePositions[i] < timePositions[j]); } } }
/// <summary>Parses a <seealso cref="GuidelineEditorPresetEventPatternInfo"/> from raw data.</summary> /// <param name="s">The raw data of the pattern that will be parsed.</param> /// <param name="patternPool">The pattern pool from which to retrieve the pattern object that is referred.</param> public static GuidelineEditorPresetEventPatternInfo Parse(string s, List <GuidelineEditorPresetPattern> patternPool) { var split = s.Split(", "); var pattern = patternPool.Find(p => p.Name == split[0]); var start = MeasuredTimePosition.Parse(split[1]); return(new GuidelineEditorPresetEventPatternInfo(pattern, start)); }
/// <summary>Converts a relative time position into an absolute time position.</summary> /// <param name="relativeTimePosition">The relative time position to convert to an absolute one.</param> public TimeSpan ConvertTime(MeasuredTimePosition relativeTimePosition) { var absolute = GetAbsoluteTimePosition(); var relative = GetRelativeTimePosition(); var distance = relativeTimePosition.DistanceFrom(relative, TimeSignature); return(absolute + distance.GetDurationTimeSpan(BPM, TimeSignature)); }
private static SortedList <TimingPoint> ConvertToSortedList(List <TimingPoint> presetTimingPoints) { var timingPoints = new SortedList <TimingPoint>(presetTimingPoints.Count, CompareTimingPoints); var absoluteTimingPoints = Convert <TimingPoint, AbsoluteTimingPoint>(presetTimingPoints); if (absoluteTimingPoints.Count == 0) { throw new InvalidOperationException("No absolute timing points were used"); } absoluteTimingPoints[0].SetAsInitialTimingPoint(); var relativeTimingPoints = Convert <TimingPoint, RelativeTimingPoint>(presetTimingPoints); relativeTimingPoints.Sort((a, b) => MeasuredTimePosition.CompareByAbsolutePosition(a.TimePosition, b.TimePosition)); // Add absolute timing points and calculate their relative time positions AbsoluteTimingPoint previousAbsolute = null; foreach (var a in absoluteTimingPoints) { if (previousAbsolute != null) { a.CalculateRelativeTimePosition(previousAbsolute); } timingPoints.Add(previousAbsolute = a); } // Add relative timing points, calculate their absolute time positions and adjust the absolute timing points' relative time positions foreach (var r in relativeTimingPoints) { int index = timingPoints.IndexBefore(r); r.CalculateAbsoluteTimePosition(timingPoints[index]); if (index + 1 < timingPoints.Count) { // The next timing point is certainly an absolute timing point since no relative timing points have been added beyond that one yet var nextAbsolute = timingPoints[index + 1] as AbsoluteTimingPoint; // Calculate the measure adjustment for the first absolute timing point to apply it to all the rest int currentMeasure = nextAbsolute.RelativeTimePosition.Measure; nextAbsolute.CalculateRelativeTimePosition(r); int newMeasure = nextAbsolute.RelativeTimePosition.Measure; int measureAdjustment = newMeasure - currentMeasure; if (measureAdjustment != 0) { for (int i = index + 2; i < timingPoints.Count; i++) { (timingPoints[i] as AbsoluteTimingPoint).AdjustMeasure(measureAdjustment); } } } timingPoints.Add(r); } return(timingPoints); }
/// <summary>Parses a <seealso cref="GuidelineEditorPresetEvent"/> from raw data.</summary> /// <param name="s">The raw data of the event that will be parsed.</param> /// <param name="patternPool">The pattern pool from which to retrieve the pattern object that is referred.</param> public static GuidelineEditorPresetEvent Parse(string s, List <GuidelineEditorPresetPattern> patternPool) { var split = s.Split(", "); var position = MeasuredTimePosition.Parse(split[0]); var duration = MeasuredDuration.Parse(split[1]); var eventInfo = GuidelineEditorPresetEventPatternInfo.Parse($"{split[2]}, {split[3]}", patternPool); return(new GuidelineEditorPresetEvent(position, eventInfo, duration)); }
public void DistanceFrom() { var timePosition = new MeasuredTimePosition(1, 2, 0); var otherTimePosition = new MeasuredTimePosition(2, 1, 0); Assert.AreEqual(new MeasuredDuration(0, 3, 0), timePosition.DistanceFrom(otherTimePosition, CommonTimeSignature), "4/4: 1:2.000 - 2:1.000"); Assert.AreEqual(new MeasuredDuration(0, 3, 0), otherTimePosition.DistanceFrom(timePosition, CommonTimeSignature), "4/4: 2:1.000 - 1:2.000"); Assert.AreEqual(new MeasuredDuration(0, 2, 0), timePosition.DistanceFrom(otherTimePosition, WaltzTimeSignature), "3/4: 1:2.000 - 2:1.000"); Assert.AreEqual(new MeasuredDuration(0, 2, 0), otherTimePosition.DistanceFrom(timePosition, WaltzTimeSignature), "3/4: 2:1.000 - 1:2.000"); Assert.AreEqual(new MeasuredDuration(0, 4, 0), timePosition.DistanceFrom(otherTimePosition, UncommonTimeSignature), "5/4: 1:2.000 - 2:1.000"); Assert.AreEqual(new MeasuredDuration(0, 4, 0), otherTimePosition.DistanceFrom(timePosition, UncommonTimeSignature), "5/4: 2:1.000 - 1:2.000"); }
/// <summary>Parses a <seealso cref="GuidelineEditorPreset"/> from raw data wtih a specified name.</summary> /// <param name="name">The name of the preset.</param> /// <param name="rawData">The raw data of the preset that will be parsed.</param> public static GuidelineEditorPreset Parse(string name, string rawData) { var patternPool = new List <GuidelineEditorPresetPattern>(); var tracks = new GuidelineEditorPresetTrackList(); var timingPoints = new TimingPointList(); var lines = rawData.GetLines().ToList(); lines.RemoveAll(s => s.StartsWith("//")); int currentLineIndex = 0; string currentLine; // Pattern pool for (; (currentLine = lines[currentLineIndex]).Length > 0; currentLineIndex++) { patternPool.Add(GuidelineEditorPresetPattern.Parse(currentLine)); currentLineIndex++; } // Intermediate parameters currentLineIndex++; var split = lines[currentLineIndex].Split('|'); var offset = ToDouble(split[0]); var start = MeasuredTimePosition.Parse(split[1]); var end = MeasuredTimePosition.Parse(split[2]); currentLineIndex++; // Timing points for (; (currentLine = lines[currentLineIndex]).Length > 0; currentLineIndex++) { timingPoints.Add(TimingPoint.Parse(currentLine)); currentLineIndex++; } // Tracks for (currentLineIndex++; currentLineIndex < lines.Count; currentLineIndex++) { // TODO: Consider caring about the track indices var events = new List <GuidelineEditorPresetEvent>(); for (currentLineIndex++; currentLineIndex < lines.Count && (currentLine = lines[currentLineIndex]).Length > 0; currentLineIndex++) { events.Add(GuidelineEditorPresetEvent.Parse(currentLine, patternPool)); } tracks.Add(new GuidelineEditorPresetTrack(events)); } return(new GuidelineEditorPreset(name, offset, start, end, tracks, timingPoints)); }
/// <summary>Gets all the events of this track list and generates a track list that contains the smallest number of tracks where the events are not overlapping in any track.</summary> /// <param name="timingPoints">The timing points based on which to compact the tracks.</param> public GuidelineEditorPresetTrackList CompactTracks(TimingPointList timingPoints) { var result = new GuidelineEditorPresetTrackList(); var unifiedTracks = UnifyTracks(); foreach (var e in unifiedTracks) { bool found = false; for (int i = 0; i < result.Count && !found; i++) { if (found = MeasuredTimePosition.CompareByAbsolutePosition(result.tracks[i].GetEnd(timingPoints), e.TimePosition) < 0) { result.tracks[i].Add(e); } } if (!found) { result.Add(new GuidelineEditorPresetTrack(e)); } } return(result); }
/// <summary>Parses a <seealso cref="GuidelineEditorPresetNote"/> from raw data.</summary> /// <param name="rawData">The raw data of the <seealso cref="GuidelineEditorPresetNote"/> that will be parsed.</param> public static GuidelineEditorPresetNote Parse(string rawData) { var m = rawData.Split(':'); return(new GuidelineEditorPresetNote(MeasuredTimePosition.ParseAsBeatWithFraction(m[0]), ParseSingle(m[1]))); }
/// <summary>Creates a new instance of the <seealso cref="GuidelineEditorPresetNote"/> struct.</summary> /// <param name="position">The position of this note.</param> /// <param name="color">The guideline color to use for this note.</param> public GuidelineEditorPresetNote(MeasuredTimePosition position, GuidelineColor color) { Position = position; Color = color; }
/// <summary>Creates a new instance of the <seealso cref="GuidelineEditorPreset"/> class.</summary> /// <param name="name">The name of the preset.</param> /// <param name="offset">The offset, in seconds, of the preset.</param> /// <param name="start">The starting position from which to generate the guidelines.</param> /// <param name="end">The ending position at which to stop generating the guidelines.</param> /// <param name="startingPoint">The starting <seealso cref="AbsoluteTimingPoint"/> of the preset.</param> public GuidelineEditorPreset(string name, double offset, MeasuredTimePosition start, MeasuredTimePosition end, AbsoluteTimingPoint startingPoint) : this(name, offset, start, end) { TimingPoints.Add(startingPoint); }
/// <summary>Initializes a new instance of the <seealso cref="GuidelineEditorPresetEventPatternInfo"/> class.</summary> /// <param name="pattern">The pattern that this event will use.</param> /// <param name="patternStart">The starting time position of the pattern.</param> public GuidelineEditorPresetEventPatternInfo(GuidelineEditorPresetPattern pattern, MeasuredTimePosition patternStart) { Pattern = pattern; PatternStart = patternStart; }
/// <summary>Initializes a new instance of the <seealso cref="GuidelineEditorPresetEvent"/> class from a given time position, event pattern info and duration.</summary> /// <param name="timePosition">The starting time position of the pattern.</param> /// <param name="eventPatternInfo">The <seealso cref="GuidelineEditorPresetEventPatternInfo"/> to use in the event.</param> /// <param name="duration">The duration of the event.</param> public GuidelineEditorPresetEvent(MeasuredTimePosition timePosition, GuidelineEditorPresetEventPatternInfo eventPatternInfo, MeasuredDuration duration) { TimePosition = timePosition; Duration = duration; EventPatternInfo = eventPatternInfo; }
/// <summary>Initializes a new instance of the <seealso cref="GuidelineEditorPresetEvent"/> class from a given time position and event pattern info. The event's duration defaults to the pattern's measure count.</summary> /// <param name="timePosition">The starting time position of the pattern.</param> /// <param name="eventPatternInfo">The <seealso cref="GuidelineEditorPresetEventPatternInfo"/> to use in the event.</param> public GuidelineEditorPresetEvent(MeasuredTimePosition timePosition, GuidelineEditorPresetEventPatternInfo eventPatternInfo) : this(timePosition, eventPatternInfo, new MeasuredDuration(eventPatternInfo.Pattern.Measures.Count)) { }
/// <summary>Initializes a new instance of the <seealso cref="GuidelineEditorPresetEvent"/> class from a given time position, pattern and duration.</summary> /// <param name="timePosition">The starting time position of the pattern.</param> /// <param name="pattern">The pattern that this event will use.</param> /// <param name="duration">The duration of the event.</param> public GuidelineEditorPresetEvent(MeasuredTimePosition timePosition, GuidelineEditorPresetPattern pattern, MeasuredDuration duration) : this(timePosition, new GuidelineEditorPresetEventPatternInfo(pattern), duration) { }
/// <summary>Initializes a new instance of the <seealso cref="GuidelineEditorPresetEvent"/> class from a given time position and pattern. The event's duration defaults to the pattern's measure count.</summary> /// <param name="timePosition">The starting time position of the pattern.</param> /// <param name="pattern">The pattern that this event will use.</param> public GuidelineEditorPresetEvent(MeasuredTimePosition timePosition, GuidelineEditorPresetPattern pattern) : this(timePosition, new GuidelineEditorPresetEventPatternInfo(pattern), new MeasuredDuration(pattern.Measures.Count)) { }
/// <summary>Compares two <seealso cref="TimingPoint"/>s based on their relative time positions.</summary> /// <param name="left">The left <seealso cref="TimingPoint"/> whose relative time position will be compared.</param> /// <param name="right">The right <seealso cref="TimingPoint"/> whose relative time position will be compared.</param> public static int RelativeComparison(TimingPoint left, TimingPoint right) => MeasuredTimePosition.CompareByAbsolutePosition(left.GetRelativeTimePosition(), right.GetRelativeTimePosition());
/// <summary>Gets the timing point that is applied at the specified relative time.</summary> /// <param name="relativeTime">The relative time at which the current timing point applies.</param> public TimingPoint TimingPointAtTime(MeasuredTimePosition relativeTime) => timingPoints.ElementBefore(new RelativeTimingPoint(relativeTime, 120, new TimeSignature()), TimingPoint.RelativeComparison);
/// <summary>Creates a new instance of the <seealso cref="GuidelineEditorPreset"/> class.</summary> /// <param name="name">The name of the preset.</param> /// <param name="offset">The offset, in seconds, of the preset.</param> /// <param name="start">The starting position from which to generate the guidelines.</param> /// <param name="end">The ending position at which to stop generating the guidelines.</param> /// <param name="presetTracks">The tracks of the preset.</param> /// <param name="presetTimingPoints">The timing points of the preset.</param> public GuidelineEditorPreset(string name, double offset, MeasuredTimePosition start, MeasuredTimePosition end, GuidelineEditorPresetTrackList presetTracks, TimingPointList presetTimingPoints) : this(name, offset, start, end) { Tracks = presetTracks.Clone(); TimingPoints = presetTimingPoints; }