public long ConvertFrom(ITime time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); var mathTime = time as MathTime; if (mathTime == null) { throw new ArgumentException($"Time is not an instance of the {nameof(MathTime)}.", nameof(time)); } var result = mathTime.Time != null ? TimeConverter.ConvertFrom(mathTime.Time, tempoMap) : mathTime.MidiTime; switch (mathTime.Operation) { case MathOperation.Sum: return(result + LengthConverter.ConvertFrom(mathTime.Offset, result, tempoMap)); case MathOperation.Subtract: return(result - LengthConverter.ConvertFrom(mathTime.Offset, result, tempoMap.Flip(result))); } throw new NotImplementedException($"Conversion from the {nameof(MathTime)} with {mathTime.Operation} operation is not implemented."); }
/// <summary> /// Sets new time signature that will last from the specified time until next change of /// time signature. /// </summary> /// <param name="time">Time to set the new time signature at.</param> /// <param name="timeSignature">New time signature that will last from the specified /// time until next change of time signature.</param> /// <exception cref="ArgumentNullException"><paramref name="time"/> is null. -or- /// <paramref name="timeSignature"/> is null.</exception> public void SetTimeSignature(ITimeSpan time, TimeSignature timeSignature) { ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(timeSignature), timeSignature); SetTimeSignature(TimeConverter.ConvertFrom(time, TempoMap), timeSignature); }
/// <summary> /// Sets new tempo that will last from the specified time until next change of tempo. /// </summary> /// <param name="time">Time to set the new tempo at.</param> /// <param name="tempo">New tempo that will last from the specified time until next change /// of tempo.</param> /// <exception cref="ArgumentNullException"><paramref name="time"/> is null. -or- /// <paramref name="tempo"/> is null.</exception> public void SetTempo(ITimeSpan time, Tempo tempo) { ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempo), tempo); SetTempo(TimeConverter.ConvertFrom(time, TempoMap), tempo); }
/// <summary> /// Removes all changes of tempo that occured between the specified times. /// </summary> /// <param name="startTime">Start of time range to remove changes of tempo in.</param> /// <param name="endTime">End of time range to remove changes of tempo in.</param> /// <exception cref="ArgumentNullException"><paramref name="startTime"/> is null. -or- /// <paramref name="endTime"/> is null.</exception> public void ClearTempo(ITimeSpan startTime, ITimeSpan endTime) { ThrowIfArgument.IsNull(nameof(startTime), startTime); ThrowIfArgument.IsNull(nameof(endTime), endTime); ClearTempo(TimeConverter.ConvertFrom(startTime, TempoMap), TimeConverter.ConvertFrom(endTime, TempoMap)); }
/// <summary> /// Converts length from the specified length type to <see cref="long"/>. /// </summary> /// <param name="length">Length to convert.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as <see cref="long"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or- /// <paramref name="time"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> public static long ConvertFrom(ITimeSpan length, ITimeSpan time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(TimeSpanConverter.ConvertFrom(length, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
/// <summary> /// Sets time of the specified timed event. /// </summary> /// <param name="timedEvent">Timed event to set time to.</param> /// <param name="time">Time to set to <paramref name="timedEvent"/>.</param> /// <param name="tempoMap">Tempo map that will be used for time conversion.</param> /// <returns>An input <paramref name="timedEvent"/> with new time.</returns> /// <exception cref="ArgumentNullException"><paramref name="timedEvent"/> is null. -or- /// <paramref name="time"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> public static TimedEvent SetTime(this TimedEvent timedEvent, ITimeSpan time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(timedEvent), timedEvent); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); timedEvent.Time = TimeConverter.ConvertFrom(time, tempoMap); return(timedEvent); }
/// <summary> /// Adds a <see cref="MidiEvent"/> into a <see cref="TimedEventsCollection"/> with the specified /// absolute time. /// </summary> /// <param name="eventsCollection"><see cref="TimedEventsCollection"/> to add an event into.</param> /// <param name="midiEvent">Event to add into the <paramref name="eventsCollection"/>.</param> /// <param name="time">Absolute time that will be assigned to the <paramref name="midiEvent"/> /// when it will be placed into the <paramref name="eventsCollection"/>.</param> /// <param name="tempoMap">Tempo map used to place <paramref name="midiEvent"/> into the /// <paramref name="eventsCollection"/> with the specified time.</param> /// <exception cref="ArgumentNullException"><paramref name="eventsCollection"/> is null. -or- /// <paramref name="midiEvent"/> is null. -or- <paramref name="time"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> public static void AddEvent(this TimedEventsCollection eventsCollection, MidiEvent midiEvent, ITimeSpan time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(eventsCollection), eventsCollection); ThrowIfArgument.IsNull(nameof(midiEvent), midiEvent); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); eventsCollection.AddEvent(midiEvent, TimeConverter.ConvertFrom(time, tempoMap)); }
/// <summary> /// Converts length from <see cref="long"/> to the specified length type. /// </summary> /// <param name="length">Length to convert.</param> /// <param name="lengthType">Type that will represent the length of an object.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as an instance of time span defined by <paramref name="lengthType"/>.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is negative.</exception> /// <exception cref="ArgumentNullException"><paramref name="time"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value.</exception> public static ITimeSpan ConvertTo(long length, TimeSpanType lengthType, ITimeSpan time, TempoMap tempoMap) { ThrowIfLengthArgument.IsNegative(nameof(length), length); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(TimeSpanConverter.ConvertTo(length, lengthType, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
/// <summary> /// Converts length from <see cref="long"/> to the specified length type. /// </summary> /// <typeparam name="TTimeSpan">Type that will represent the length of an object.</typeparam> /// <param name="length">Length to convert.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as an instance of <typeparamref name="TTimeSpan"/>.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is negative.</exception> /// <exception cref="ArgumentNullException"><paramref name="time"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="NotSupportedException"><typeparamref name="TTimeSpan"/> is not supported.</exception> public static TTimeSpan ConvertTo <TTimeSpan>(long length, ITimeSpan time, TempoMap tempoMap) where TTimeSpan : ITimeSpan { ThrowIfLengthArgument.IsNegative(nameof(length), length); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(TimeSpanConverter.ConvertTo <TTimeSpan>(length, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
/// <summary> /// Converts length from one length type to another one. /// </summary> /// <typeparam name="TLength">Type that will represent the length of an object.</typeparam> /// <param name="length">Length to convert.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as an instance of <typeparamref name="TLength"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or- /// <paramref name="time"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> /// <exception cref="NotSupportedException"><typeparamref name="TLength"/> is not supported.</exception> public static TLength ConvertTo <TLength>(ILength length, ITime time, TempoMap tempoMap) where TLength : ILength { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(ConvertTo <TLength>(length, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
/// <summary> /// Resizes group of notes to the specified length treating all notes as single object. /// </summary> /// <param name="notes">Notes to resize.</param> /// <param name="length">New length of the notes collection.</param> /// <param name="distanceCalculationType">Type of distance calculations.</param> /// <param name="tempoMap"></param> /// <exception cref="ArgumentNullException"><paramref name="notes"/> is null. -or- /// <paramref name="length"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> /// <exception cref="ArgumentException"><see cref="TimeSpanType.BarBeat"/> used for <paramref name="distanceCalculationType"/> /// with relative resizing.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="distanceCalculationType"/> specified an /// invalid value.</exception> public static void ResizeNotes(this IEnumerable <Note> notes, ITimeSpan length, TimeSpanType distanceCalculationType, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(notes), notes); ThrowIfArgument.IsNull(nameof(length), length); ThrowIfArgument.IsInvalidEnumValue(nameof(distanceCalculationType), distanceCalculationType); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); if (distanceCalculationType == TimeSpanType.BarBeat) { throw new ArgumentException("BarBeat length type is not supported for relative resizing.", nameof(distanceCalculationType)); } if (!notes.Any()) { return; } // var minStartTime = long.MaxValue; var maxEndTime = 0L; foreach (var note in notes.Where(n => n != null)) { var noteStartTime = note.Time; var noteEndTime = noteStartTime + note.Length; minStartTime = Math.Min(minStartTime, noteStartTime); maxEndTime = Math.Max(maxEndTime, noteEndTime); } var totalLength = maxEndTime - minStartTime; // var oldLength = LengthConverter.ConvertTo(totalLength, distanceCalculationType, minStartTime, tempoMap); var newLength = LengthConverter.ConvertTo(length, distanceCalculationType, minStartTime, tempoMap); var ratio = TimeSpanUtilities.Divide(newLength, oldLength); var startTime = TimeConverter.ConvertTo(minStartTime, distanceCalculationType, tempoMap); foreach (var note in notes.Where(n => n != null)) { var noteLength = note.LengthAs(distanceCalculationType, tempoMap); var noteTime = note.TimeAs(distanceCalculationType, tempoMap); var scaledShiftFromStart = noteTime.Subtract(startTime, TimeSpanMode.TimeTime).Multiply(ratio); note.Time = TimeConverter.ConvertFrom(startTime.Add(scaledShiftFromStart, TimeSpanMode.TimeLength), tempoMap); var scaledLength = noteLength.Multiply(ratio); note.Length = LengthConverter.ConvertFrom(scaledLength, note.Time, tempoMap); } }
public override PatternActionResult Invoke(long time, PatternContext context) { var tempoMap = context.TempoMap; context.SaveTime(time); var convertedTime = TimeConverter.ConvertFrom(((MidiTimeSpan)time).Subtract(Step, TimeSpanMode.TimeLength), tempoMap); return(new PatternActionResult(Math.Max(convertedTime, 0))); }
public override PatternActionResult Invoke(long time, PatternContext context) { var tempoMap = context.TempoMap; context.SaveTime(time); var convertedTime = TimeConverter.ConvertFrom(new MathTime(time, Step, MathOperation.Subtract), tempoMap); return(new PatternActionResult(Math.Max(convertedTime, 0))); }
/// <summary> /// Sets time and length of the specified note. /// </summary> /// <param name="note">Note to set time and length to.</param> /// <param name="time">Time to set to <paramref name="note"/>.</param> /// <param name="length">Length to set to <paramref name="note"/>.</param> /// <param name="tempoMap">Tempo map that will be used for time and length conversion.</param> /// <returns>An input <paramref name="note"/> with new time and length.</returns> /// <exception cref="ArgumentNullException"><paramref name="note"/> is null. -or- /// <paramref name="time"/> is null. -or- <paramref name="length"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> public static Note SetTimeAndLength(this Note note, ITimeSpan time, ITimeSpan length, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(note), note); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(length), length); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); note.Time = TimeConverter.ConvertFrom(time, tempoMap); note.Length = LengthConverter.ConvertFrom(length, note.Time, tempoMap); return(note); }
/// <summary> /// Filters collection of <see cref="ITimedObject"/> to return objects at the specified time. /// </summary> /// <typeparam name="TObject">The type of the elements of <paramref name="objects"/>.</typeparam> /// <param name="objects">A collection to filter.</param> /// <param name="time">Time to filter objects by.</param> /// <param name="tempoMap">Tempo map to filter <paramref name="objects"/> by <paramref name="time"/>.</param> /// <returns>A collection that contains objects from the input sequence that are at the specified time.</returns> /// <remarks> /// Note that changes made on the objects returned by this method will not be saved to an underlying /// data source (events collection, track chunk, file). To change properties of timed objects and /// save them you need to use a manager appropriate for an object's type. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="objects"/> is null. -or- <paramref name="time"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> public static IEnumerable <TObject> AtTime <TObject>(this IEnumerable <TObject> objects, ITimeSpan time, TempoMap tempoMap) where TObject : ITimedObject { ThrowIfArgument.IsNull(nameof(objects), objects); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); var convertedTime = TimeConverter.ConvertFrom(time, tempoMap); return(AtTime(objects, convertedTime)); }
/// <summary> /// Sets time and length of the specified chord. /// </summary> /// <param name="chord">Chord to set time and length to.</param> /// <param name="time">Time to set to <paramref name="chord"/>.</param> /// <param name="length">Length to set to <paramref name="chord"/>.</param> /// <param name="tempoMap">Tempo map that will be used for time and length conversion.</param> /// <returns>An input <paramref name="chord"/> with new time and length.</returns> /// <exception cref="ArgumentNullException"><paramref name="chord"/> is null. -or- /// <paramref name="time"/> is null. -or- <paramref name="length"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> public static Chord SetTimeAndLength(this Chord chord, ITimeSpan time, ITimeSpan length, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(chord), chord); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(length), length); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); chord.Time = TimeConverter.ConvertFrom(time, tempoMap); chord.Length = LengthConverter.ConvertFrom(length, chord.Time, tempoMap); return(chord); }
/// <summary> /// Filters collection of <see cref="ILengthedObject"/> to return objects at the specified time. /// </summary> /// <typeparam name="TObject">The type of the elements of <paramref name="objects"/>.</typeparam> /// <param name="objects">A collection to filter.</param> /// <param name="time">Time to filter objects by.</param> /// <param name="tempoMap">Tempo map to filter <paramref name="objects"/> by <paramref name="time"/>.</param> /// <param name="matchBy">Part of an object which have to be at <paramref name="time"/>.</param> /// <returns>A collection that contains objects from the input sequence that are at the specified time.</returns> /// <remarks> /// Note that changes made on the objects returned by this method will not be saved to an underlying /// data source (events collection, track chunk, file). To change properties of lengthed objects and /// save them you need to use a manager appropriate for an object's type. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="objects"/> is null. -or- <paramref name="time"/> is null. -or- /// <paramref name="tempoMap"/> is null. -or- One of the objects is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="matchBy"/> specified an invalid value.</exception> public static IEnumerable <TObject> AtTime <TObject>(this IEnumerable <TObject> objects, ITime time, TempoMap tempoMap, LengthedObjectPart matchBy) where TObject : ILengthedObject { ThrowIfArgument.IsNull(nameof(objects), objects); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfArgument.IsInvalidEnumValue(nameof(matchBy), matchBy); var convertedTime = TimeConverter.ConvertFrom(time, tempoMap); return(AtTime(objects, convertedTime, matchBy)); }
private static Tuple <TimeSignature, short> GetTimeSignatureAndTicksPerQuarterNote(long bars, TempoMap tempoMap) { var ticksPerQuarterNoteTimeDivision = tempoMap.TimeDivision as TicksPerQuarterNoteTimeDivision; if (ticksPerQuarterNoteTimeDivision == null) { throw new ArgumentException("Time division of the tempo map is not supported.", nameof(tempoMap)); } var ticks = TimeConverter.ConvertFrom(new BarBeatTicksTimeSpan(bars), tempoMap); var timeSignature = tempoMap.TimeSignature.AtTime(ticks); var ticksPerQuarterNote = ticksPerQuarterNoteTimeDivision.TicksPerQuarterNote; return(Tuple.Create(timeSignature, ticksPerQuarterNote)); }
public static void ShiftEvents(this TrackChunk trackChunk, ITimeSpan distance, TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); var convertedDistance = TimeConverter.ConvertFrom(distance, TempoMap.Create(timeDivision)); var firstEvent = trackChunk.Events.FirstOrDefault(); if (firstEvent == null) { return; } firstEvent.DeltaTime += convertedDistance; }
private static void ResizeNotesByRatio(IEnumerable <Note> notes, double ratio, TimeSpanType distanceCalculationType, TempoMap tempoMap, ITimeSpan startTime) { foreach (var note in notes) { var noteLength = note.LengthAs(distanceCalculationType, tempoMap); var noteTime = note.TimeAs(distanceCalculationType, tempoMap); var scaledShiftFromStart = noteTime.Subtract(startTime, TimeSpanMode.TimeTime).Multiply(ratio); note.Time = TimeConverter.ConvertFrom(startTime.Add(scaledShiftFromStart, TimeSpanMode.TimeLength), tempoMap); var scaledLength = noteLength.Multiply(ratio); note.Length = LengthConverter.ConvertFrom(scaledLength, note.Time, tempoMap); } }
public long ConvertFrom(ILength length, long time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfTimeArgument.IsNegative(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); var metricLength = length as MetricLength; if (metricLength == null) { throw new ArgumentException($"Length is not an instance of the {nameof(MetricLength)}.", nameof(length)); } var startTime = TimeConverter.ConvertTo <MetricTime>(time, tempoMap); var endTime = new MetricTime(startTime.TotalMicroseconds + metricLength.TotalMicroseconds); return(TimeConverter.ConvertFrom(endTime, tempoMap) - time); }
private static long ConvertFromTimeLength(MathTimeSpan mathTimeSpan, long time, TempoMap tempoMap) { var convertedTimeSpan1 = TimeConverter.ConvertFrom(mathTimeSpan.TimeSpan1, tempoMap); switch (mathTimeSpan.Operation) { case MathOperation.Add: return(convertedTimeSpan1 + LengthConverter.ConvertFrom(mathTimeSpan.TimeSpan2, convertedTimeSpan1, tempoMap)); case MathOperation.Subtract: return(convertedTimeSpan1 - LengthConverter.ConvertFrom(mathTimeSpan.TimeSpan2, convertedTimeSpan1, tempoMap.Flip(convertedTimeSpan1))); default: throw new ArgumentException($"{mathTimeSpan.Operation} is not supported by the converter.", nameof(mathTimeSpan)); } }
/// <summary> /// Gets points in time of the current grid. /// </summary> /// <param name="tempoMap">Tempo map used to get grid's times.</param> /// <returns>Collection of points in time of the current grid.</returns> /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception> public IEnumerable <long> GetTimes(TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); if (!Steps.Any()) { yield break; } var time = TimeConverter.ConvertFrom(Start, tempoMap); yield return(time); while (true) { foreach (var step in Steps) { time += LengthConverter.ConvertFrom(step, time, tempoMap); yield return(time); } } }
/// <summary> /// Gets points in time of the current grid. /// </summary> /// <param name="tempoMap">Tempo map used to get grid's times.</param> /// <returns>Collection of points in time of the current grid.</returns> /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception> public IEnumerable <long> GetTimes(TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(Times.Select(t => TimeConverter.ConvertFrom(t, tempoMap))); }
/// <summary> /// Removes all changes of tempo that occured since the specified time. /// </summary> /// <param name="startTime">Time to remove changes of tempo since.</param> /// <exception cref="ArgumentNullException"><paramref name="startTime"/> is null.</exception> public void ClearTempo(ITime startTime) { ThrowIfArgument.IsNull(nameof(startTime), startTime); ClearTempo(TimeConverter.ConvertFrom(startTime, TempoMap)); }
public long ConvertFrom(ILength length, ITime time, TempoMap tempoMap) { return(ConvertFrom(length, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
public ILength ConvertTo(long length, ITime time, TempoMap tempoMap) { return(ConvertTo(length, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
/// <summary> /// Removes all changes of time signature that occured since the specified time. /// </summary> /// <param name="startTime">Time to remove changes of time signature since.</param> /// <exception cref="ArgumentNullException"><paramref name="startTime"/> is null.</exception> public void ClearTimeSignature(ITimeSpan startTime) { ThrowIfArgument.IsNull(nameof(startTime), startTime); ClearTimeSignature(TimeConverter.ConvertFrom(startTime, TempoMap)); }