private void SplitByGrid_OneStep_SinglePart(ITimeSpan gridStart, ITimeSpan step, TempoMap tempoMap) { var gridSteps = new[] { step }; var firstTime = TimeConverter.ConvertFrom(gridStart, tempoMap); long secondTime = firstTime; for (int i = 0; i < 5; i++) { secondTime += LengthConverter.ConvertFrom(step, secondTime, tempoMap); } var inputObjects = new[] { ObjectMethods.Create(firstTime, LengthConverter.ConvertFrom(step, firstTime, tempoMap)), ObjectMethods.Create(secondTime, LengthConverter.ConvertFrom(step, secondTime, tempoMap)) }; var data = SplitByGrid_ClonesExpected(inputObjects, gridStart, gridSteps, tempoMap); var stepType = TimeSpanTypes[step.GetType()]; var partLength = data.ActualObjects.First().LengthAs(stepType, tempoMap); Assert.IsTrue(data.ActualObjects.All(o => o.LengthAs(stepType, tempoMap).Equals(partLength)), $"Objects have different length measured as {stepType}."); }
internal static double Divide(ITimeSpan timeSpan1, ITimeSpan timeSpan2) { var metricTimeSpan = timeSpan1 as MetricTimeSpan; if (metricTimeSpan != null) { return(metricTimeSpan.Divide(timeSpan2 as MetricTimeSpan)); } var midiTimeSpan = timeSpan1 as MidiTimeSpan; if (midiTimeSpan != null) { return(midiTimeSpan.Divide(timeSpan2 as MidiTimeSpan)); } var musicalTimeSpan = timeSpan1 as MusicalTimeSpan; if (musicalTimeSpan != null) { return(musicalTimeSpan.Divide(timeSpan2 as MusicalTimeSpan)); } throw new NotSupportedException($"Dividing of time span of the '{timeSpan1.GetType()}' type is not supported."); }
public static ITimeSpan ConvertTo(ITimeSpan timeSpan, TimeSpanType timeSpanType, long time, TempoMap tempoMap) { if (timeSpan.GetType() == TimeSpansTypes[timeSpanType]) { return(timeSpan.Clone()); } return(ConvertTo(ConvertFrom(timeSpan, time, tempoMap), timeSpanType, time, tempoMap)); }
public static ITimeSpan ConvertTo(ITimeSpan timeSpan, Type timeSpanType, long time, TempoMap tempoMap) { if (timeSpan.GetType() == timeSpanType) { return(timeSpan.Clone()); } return(GetConverter(timeSpanType).ConvertTo(ConvertFrom(timeSpan, time, tempoMap), time, tempoMap)); }
public static void Subtract_TimeLength(ITimeSpan timeSpan1, ITimeSpan timeSpan2, TempoMap tempoMap) { var mathTimeSpan = CheckMathTimeSpan(timeSpan1, timeSpan2, MathOperation.Subtract, TimeSpanMode.TimeLength); AreEqual(timeSpan1, TimeConverter.ConvertTo(mathTimeSpan.Add(timeSpan2, TimeSpanMode.TimeLength), timeSpan1.GetType(), tempoMap), $"({timeSpan1} - {timeSpan2}) + {timeSpan2} != {timeSpan1}."); }
public static void Add_LengthLength(ITimeSpan timeSpan1, ITimeSpan timeSpan2, TempoMap tempoMap, long time) { var mathTimeSpan = CheckMathTimeSpan(timeSpan1, timeSpan2, MathOperation.Add, TimeSpanMode.LengthLength); AreEqual(timeSpan1, LengthConverter.ConvertTo(mathTimeSpan.Subtract(timeSpan2, TimeSpanMode.LengthLength), timeSpan1.GetType(), time, tempoMap), $"({timeSpan1} + {timeSpan2}) - {timeSpan2} != {timeSpan1} at time of {time}."); }
/// <summary> /// Resizes <see cref="MidiFile"/> to the specified length. /// </summary> /// <param name="midiFile"><see cref="MidiFile"/> to resize.</param> /// <param name="length">New length of the <paramref name="midiFile"/>.</param> /// <exception cref="ArgumentNullException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="midiFile"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="length"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void Resize(this MidiFile midiFile, ITimeSpan length) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNull(nameof(length), length); if (midiFile.IsEmpty()) { return; } var tempoMap = midiFile.GetTempoMap(); var duration = midiFile.GetDuration <MidiTimeSpan>(); var oldLength = TimeConverter.ConvertTo(duration, length.GetType(), tempoMap); var ratio = TimeSpanUtilities.Divide(length, oldLength); ResizeByRatio(midiFile, ratio); }
/// <summary> /// Resizes <see cref="MidiFile"/> to the specified length. /// </summary> /// <param name="midiFile"><see cref="MidiFile"/> to resize.</param> /// <param name="length">New length of the <paramref name="midiFile"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is null. -or- /// <paramref name="length"/> is null.</exception> public static void Resize(this MidiFile midiFile, ITimeSpan length) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNull(nameof(length), length); var lastTime = midiFile.GetTimedEvents().LastOrDefault()?.Time ?? 0; if (lastTime == 0) { return; } var tempoMap = midiFile.GetTempoMap(); var oldLength = TimeConverter.ConvertTo((MidiTimeSpan)lastTime, length.GetType(), tempoMap); var ratio = TimeSpanUtilities.Divide(length, oldLength); ResizeByRatio(midiFile, ratio); }
private static bool AreTimeSpansEqual(ITimeSpan x, ITimeSpan y) { const long microsecondsEpsilon = 3000; const long ticksEpsilon = 3; const double fractionEpsilon = 0.00001; const double fractionalBeatsEpsilon = 0.1; if (x.GetType() != y.GetType()) { return(false); } if (x is MetricTimeSpan xMetric && y is MetricTimeSpan yMetric) { return(Math.Abs(xMetric.TotalMicroseconds - yMetric.TotalMicroseconds) < microsecondsEpsilon); } if (x is BarBeatTicksTimeSpan xBarBeat && y is BarBeatTicksTimeSpan yBarBeat) { return(xBarBeat.Bars == yBarBeat.Bars && xBarBeat.Beats == yBarBeat.Beats && Math.Abs(xBarBeat.Ticks - yBarBeat.Ticks) < ticksEpsilon); } if (x is BarBeatFractionTimeSpan xBarBeatFraction && y is BarBeatFractionTimeSpan yBarBeatFraction) { return(xBarBeatFraction.Bars == yBarBeatFraction.Bars && Math.Abs(xBarBeatFraction.Beats - yBarBeatFraction.Beats) < fractionalBeatsEpsilon); } if (x is MusicalTimeSpan xMusical && y is MusicalTimeSpan yMusical) { return(Math.Abs(xMusical.Numerator / (double)xMusical.Denominator - yMusical.Numerator / (double)yMusical.Denominator) < fractionEpsilon); } if (x is MidiTimeSpan xMidi && y is MidiTimeSpan yMidi) { return(Math.Abs(xMidi.TimeSpan - yMidi.TimeSpan) < ticksEpsilon); } return(false); }
private static void AreEqual(ITimeSpan expectedTimeSpan, ITimeSpan actualTimeSpan, string message) { var expectedTimeSpanType = expectedTimeSpan.GetType(); var actualTimeSpanType = actualTimeSpan.GetType(); // Assert.IsTrue(expectedTimeSpanType == actualTimeSpanType, $"Type of {expectedTimeSpan} isn't equal to the type of {actualTimeSpan}."); // if (!TimeSpanComparers.TryGetValue(expectedTimeSpanType, out var comparer)) { comparer = EqualityComparer <ITimeSpan> .Default; } Assert.IsTrue(comparer.Equals(expectedTimeSpan, actualTimeSpan), $"Time spans are not equal. Expected: {expectedTimeSpan}. Actual: {actualTimeSpan}. {message}"); }
public static void Resize(this MidiFile midiFile, ITimeSpan length) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNull(nameof(length), length); // TODO: create method to get absolute time (or last time...) var lastTime = midiFile.GetTimedEvents().LastOrDefault()?.Time; if (lastTime.GetValueOrDefault() == 0) { return; } var tempoMap = midiFile.GetTempoMap(); var oldLength = TimeConverter.ConvertTo((MidiTimeSpan)lastTime.Value, length.GetType(), tempoMap); var ratio = TimeSpanUtilities.Divide(length, oldLength); ResizeByRatio(midiFile, ratio); }
public static long ConvertFrom(ITimeSpan timeSpan, long time, TempoMap tempoMap) { return(GetConverter(timeSpan.GetType()).ConvertFrom(timeSpan, time, tempoMap)); }