private void Randomize(LengthedObjectTarget target, IEnumerable <TObject> actualObjects, IBounds bounds, IEnumerable <TimeBounds> expectedBounds, TempoMap tempoMap) { Randomizer.Randomize(actualObjects, bounds, tempoMap, new TSettings { RandomizingTarget = target }); var objectsBounds = actualObjects.Zip(expectedBounds, (o, b) => new { Object = o, Bounds = b }); foreach (var objectBounds in objectsBounds) { var time = objectBounds.Object?.Time; var timeBounds = objectBounds.Bounds; if (time == null) { Assert.IsNull(timeBounds.MinTime, "Min time is not null for null object."); Assert.IsNull(timeBounds.MaxTime, "Max time is not null for null object."); continue; } var minTime = TimeConverter.ConvertFrom(timeBounds.MinTime, tempoMap); var maxTime = TimeConverter.ConvertFrom(timeBounds.MaxTime, tempoMap); Assert.IsTrue(time >= minTime && time <= maxTime, $"Object's time {time} is not in {timeBounds}/[{minTime}; {maxTime}] range."); } }
public void SplitAtDistance_BigDistance(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = CreateInputObjects(1000); var distance = (MidiTimeSpan)1000; var expectedObjects = inputObjects.Select(o => ObjectMethods.Clone(o)); var actualObjects = Splitter.SplitAtDistance(inputObjects, distance, from, tempoMap); ObjectMethods.AssertCollectionsAreEqual(expectedObjects, actualObjects); }
public void SplitAtDistance_Nulls(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = new[] { default(TObject), default(TObject) }; var distance = (MidiTimeSpan)100; var expectedObjects = new[] { default(TObject), default(TObject) }; var actualObjects = Splitter.SplitAtDistance(inputObjects, distance, from, tempoMap); ObjectMethods.AssertCollectionsAreEqual(expectedObjects, actualObjects); }
public void SplitAtDistance_ByRatio_EmptyCollection(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = Enumerable.Empty <TObject>(); var ratio = 0.5; var expectedObjects = Enumerable.Empty <TObject>(); var actualObjects = Splitter.SplitAtDistance(inputObjects, ratio, TimeSpanType.Midi, from, tempoMap); ObjectMethods.AssertCollectionsAreEqual(expectedObjects, actualObjects); }
public void SplitAtDistance_FullLengthRatio(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = CreateInputObjects(1000); var ratio = 1.0; var expectedObjects = inputObjects.Select(o => ObjectMethods.Clone(o)); var actualObjects = Splitter.SplitAtDistance(inputObjects, ratio, TimeSpanType.Midi, from, tempoMap); ObjectMethods.AssertCollectionsAreEqual(expectedObjects, actualObjects); }
public void SplitAtDistance_EmptyCollection(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = Enumerable.Empty <TObject>(); var distance = (MidiTimeSpan)100; var expectedObjects = Enumerable.Empty <TObject>(); var actualObjects = Splitter.SplitAtDistance(inputObjects, distance, from, tempoMap); ObjectMethods.AssertCollectionsAreEqual(expectedObjects, actualObjects); }
public void SplitAtDistance_ByRatio_Nulls(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = new[] { default(TObject), default(TObject) }; var ratio = 0.5; var expectedObjects = new[] { default(TObject), default(TObject) }; var actualObjects = Splitter.SplitAtDistance(inputObjects, ratio, TimeSpanType.Midi, from, tempoMap); ObjectMethods.AssertCollectionsAreEqual(expectedObjects, actualObjects); }
public void SplitAtDistance_FullLengthRatio(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = CreateInputObjects(1000); var ratio = 1.0; var expectedObjects = inputObjects.Select(o => ObjectMethods.Clone(o)); var actualObjects = Splitter.SplitAtDistance(inputObjects, ratio, TimeSpanType.Midi, from, tempoMap); MidiAsserts.AreEqual( expectedObjects.OfType <ITimedObject>(), actualObjects.OfType <ITimedObject>(), true, 0, "Objects are invalid."); }
public void SplitAtDistance_ByRatio_Nulls(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = new[] { default(TObject), default(TObject) }; var ratio = 0.5; var expectedObjects = new[] { default(TObject), default(TObject) }; var actualObjects = Splitter.SplitAtDistance(inputObjects, ratio, TimeSpanType.Midi, from, tempoMap); MidiAsserts.AreEqual( expectedObjects.OfType <ITimedObject>(), actualObjects.OfType <ITimedObject>(), true, 0, "Objects are invalid."); }
public void SplitAtDistance_ByRatio_EmptyCollection(LengthedObjectTarget from) { var tempoMap = TempoMap.Default; var inputObjects = Enumerable.Empty <TObject>(); var ratio = 0.5; var expectedObjects = Enumerable.Empty <TObject>(); var actualObjects = Splitter.SplitAtDistance(inputObjects, ratio, TimeSpanType.Midi, from, tempoMap); MidiAsserts.AreEqual( expectedObjects.OfType <ITimedObject>(), actualObjects.OfType <ITimedObject>(), true, 0, "Objects are invalid."); }
/// <summary> /// Splits chords contained in the specified <see cref="MidiFile"/> at the specified distance /// from a chord's start or end. /// </summary> /// <param name="midiFile"><see cref="MidiFile"/> to split chords in.</param> /// <param name="distance">Distance to split chords at.</param> /// <param name="from">Point of a chord <paramref name="distance"/> should be measured from.</param> /// <param name="notesTolerance">Notes tolerance that defines maximum distance of notes from the /// start of the first note of a chord. Notes within this tolerance will be considered as a chord.</param> /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is null. -or- /// <paramref name="distance"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="notesTolerance"/> is negative.</exception> public static void SplitChordsAtDistance(this MidiFile midiFile, ITimeSpan distance, LengthedObjectTarget from, long notesTolerance = 0) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfNotesTolerance.IsNegative(nameof(notesTolerance), notesTolerance); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().SplitChordsAtDistance(distance, from, tempoMap, notesTolerance); }
/// <summary> /// Splits chords contained in the specified collection of <see cref="TrackChunk"/> at the specified /// distance from a chord's start or end. /// </summary> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> to split chords in.</param> /// <param name="distance">Distance to split chords at.</param> /// <param name="from">Point of a chord <paramref name="distance"/> should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <param name="notesTolerance">Notes tolerance that defines maximum distance of notes from the /// start of the first note of a chord. Notes within this tolerance will be considered as a chord.</param> /// <exception cref="ArgumentNullException"><paramref name="trackChunks"/> is null. -or- /// <paramref name="distance"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="notesTolerance"/> is negative.</exception> public static void SplitChordsAtDistance(this IEnumerable <TrackChunk> trackChunks, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap, long notesTolerance = 0) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfNotesTolerance.IsNegative(nameof(notesTolerance), notesTolerance); foreach (var trackChunk in trackChunks) { trackChunk.SplitChordsAtDistance(distance, from, tempoMap, notesTolerance); } }
/// <summary> /// Splits chords contained in the specified <see cref="TrackChunk"/> at the specified distance /// from a chord's start or end. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to split chords in.</param> /// <param name="distance">Distance to split chords at.</param> /// <param name="from">Point of a chord <paramref name="distance"/> should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <param name="notesTolerance">Notes tolerance that defines maximum distance of notes from the /// start of the first note of a chord. Notes within this tolerance will be considered as a chord.</param> /// <exception cref="ArgumentNullException"><paramref name="trackChunk"/> is null. -or- /// <paramref name="distance"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="notesTolerance"/> is negative.</exception> public static void SplitChordsAtDistance(this TrackChunk trackChunk, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap, long notesTolerance = 0) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfNotesTolerance.IsNegative(nameof(notesTolerance), notesTolerance); SplitTrackChunkChords(trackChunk, (splitter, chords) => splitter.SplitAtDistance(chords, distance, from, tempoMap), notesTolerance); }
/// <summary> /// Splits notes contained in the specified <see cref="TrackChunk"/> at the specified distance /// from a note's start or end. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to split notes in.</param> /// <param name="distance">Distance to split notes at.</param> /// <param name="from">Point of a note <paramref name="distance"/> should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <exception cref="ArgumentNullException"><paramref name="trackChunk"/> is null. -or- /// <paramref name="distance"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> public static void SplitNotesAtDistance(this TrackChunk trackChunk, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkNotes(trackChunk, (splitter, notes) => splitter.SplitAtDistance(notes, distance, from, tempoMap)); }
/// <summary> /// Splits chords contained in the specified <see cref="MidiFile"/> at the specified distance /// from a chord's start or end. /// </summary> /// <param name="midiFile"><see cref="MidiFile"/> to split chords in.</param> /// <param name="distance">Distance to split chords at.</param> /// <param name="from">Point of a chord <paramref name="distance"/> should be measured from.</param> /// <param name="settings">Settings accoridng to which chords should be detected and built.</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="distance"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> public static void SplitChordsAtDistance(this MidiFile midiFile, ITimeSpan distance, LengthedObjectTarget from, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().SplitChordsAtDistance(distance, from, tempoMap, settings); }
/// <summary> /// Splits chords contained in the specified <see cref="MidiFile"/> by the specified ratio of a /// chord's length measuring it from the chord's start or end. For example, 0.5 means splitting /// at the center of a chord. /// </summary> /// <param name="midiFile"><see cref="MidiFile"/> to split chords in.</param> /// <param name="ratio">Ratio of a chord's length to split by. Valid values are from 0 to 1.</param> /// <param name="lengthType">The type a chord's length should be processed according to.</param> /// <param name="from">Point of a chord distance should be measured from.</param> /// <param name="notesTolerance">Notes tolerance that defines maximum distance of notes from the /// start of the first note of a chord. Notes within this tolerance will be considered as a chord.</param> /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="ratio"/> is out of valid range. -or- /// <paramref name="notesTolerance"/> is negative.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value. -or- /// <paramref name="from"/> specified an invalid value.</exception> public static void SplitChordsAtDistance(this MidiFile midiFile, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, long notesTolerance = 0) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsOutOfRange(nameof(ratio), ratio, LengthedObjectsSplitter <Chord> .ZeroRatio, LengthedObjectsSplitter <Chord> .FullLengthRatio, $"Ratio is out of [{LengthedObjectsSplitter<Chord>.ZeroRatio}; {LengthedObjectsSplitter<Chord>.FullLengthRatio}] range."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfNotesTolerance.IsNegative(nameof(notesTolerance), notesTolerance); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().SplitChordsAtDistance(ratio, lengthType, from, tempoMap, notesTolerance); }
/// <summary> /// Splits chords contained in the specified <see cref="TrackChunk"/> by the specified ratio of a /// chord's length measuring it from the chord's start or end. For example, 0.5 means splitting /// at the center of a chord. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to split chords in.</param> /// <param name="ratio">Ratio of a chord's length to split by. Valid values are from 0 to 1.</param> /// <param name="lengthType">The type a chord's length should be processed according to.</param> /// <param name="from">Point of a chord distance should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <param name="notesTolerance">Notes tolerance that defines maximum distance of notes from the /// start of the first note of a chord. Notes within this tolerance will be considered as a chord.</param> /// <exception cref="ArgumentNullException"><paramref name="trackChunk"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="ratio"/> is out of valid range. -or- /// <paramref name="notesTolerance"/> is negative.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value. -or- /// <paramref name="from"/> specified an invalid value.</exception> public static void SplitChordsAtDistance(this TrackChunk trackChunk, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, TempoMap tempoMap, long notesTolerance = 0) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsOutOfRange(nameof(ratio), ratio, LengthedObjectsSplitter <Chord> .ZeroRatio, LengthedObjectsSplitter <Chord> .FullLengthRatio, $"Ratio is out of [{LengthedObjectsSplitter<Chord>.ZeroRatio}; {LengthedObjectsSplitter<Chord>.FullLengthRatio}] range."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfNotesTolerance.IsNegative(nameof(notesTolerance), notesTolerance); SplitTrackChunkChords(trackChunk, (splitter, chords) => splitter.SplitAtDistance(chords, ratio, lengthType, from, tempoMap), notesTolerance); }
private SplittedLengthedObject <TObject> SplitObjectAtDistance(TObject obj, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap) { var time = from == LengthedObjectTarget.Start ? ((MidiTimeSpan)obj.Time).Add(distance, TimeSpanMode.TimeLength) : ((MidiTimeSpan)(obj.Time + obj.Length)).Subtract(distance, TimeSpanMode.TimeLength); return(SplitObject(obj, TimeConverter.ConvertFrom(time, tempoMap))); }
/// <summary> /// Splits objects by the specified ratio of an object's length measuring it from /// the object's start or end. For example, 0.5 means splitting at the center of an object. /// </summary> /// <param name="objects">Objects to split.</param> /// <param name="ratio">Ratio of an object's length to split by. Valid values are from 0 to 1.</param> /// <param name="lengthType">The type an object's length should be processed according to.</param> /// <param name="from">Point of an object distance should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <returns>Objects that are result of splitting <paramref name="objects"/> going in the same /// order as elements of <paramref name="objects"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="objects"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="ratio"/> is out of valid range.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value. -or- /// <paramref name="from"/> specified an invalid value.</exception> public IEnumerable <TObject> SplitAtDistance(IEnumerable <TObject> objects, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(objects), objects); ThrowIfArgument.IsOutOfRange(nameof(ratio), ratio, ZeroRatio, FullLengthRatio, $"Ratio is out of [{ZeroRatio}; {FullLengthRatio}] range."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); foreach (var obj in objects) { if (obj == null) { yield return(default(TObject)); continue; } var distance = obj.LengthAs(lengthType, tempoMap).Multiply(ratio); var parts = SplitObjectAtDistance(obj, distance, from, tempoMap); if (parts.LeftPart != null) { yield return(parts.LeftPart); } if (parts.RightPart != null) { yield return(parts.RightPart); } } }
/// <summary> /// Splits objects at the specified distance from an object's start or end. /// </summary> /// <param name="objects">Objects to split.</param> /// <param name="distance">Distance to split objects at.</param> /// <param name="from">Point of an object <paramref name="distance"/> should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <returns>Objects that are result of splitting <paramref name="objects"/> going in the same /// order as elements of <paramref name="objects"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="objects"/> is null. -or- /// <paramref name="distance"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> public IEnumerable <TObject> SplitAtDistance(IEnumerable <TObject> objects, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(objects), objects); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); foreach (var obj in objects) { if (obj == null) { yield return(default(TObject)); continue; } var parts = SplitObjectAtDistance(obj, distance, from, tempoMap); if (parts.LeftPart != null) { yield return(parts.LeftPart); } if (parts.RightPart != null) { yield return(parts.RightPart); } } }
/// <summary> /// Splits chords contained in the specified collection of <see cref="TrackChunk"/> by the /// specified ratio of a chord's length measuring it from the chord's start or end. /// For example, 0.5 means splitting at the center of a chord. /// </summary> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> to split chords in.</param> /// <param name="ratio">Ratio of a chord's length to split by. Valid values are from 0 to 1.</param> /// <param name="lengthType">The type a chord's length should be processed according to.</param> /// <param name="from">Point of a chord distance should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <param name="notesTolerance">Notes tolerance that defines maximum distance of notes from the /// start of the first note of a chord. Notes within this tolerance will be considered as a chord.</param> /// <exception cref="ArgumentNullException"><paramref name="trackChunks"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="ratio"/> is out of valid range. -or- /// <paramref name="notesTolerance"/> is negative.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value. -or- /// <paramref name="from"/> specified an invalid value.</exception> public static void SplitChordsAtDistance(this IEnumerable <TrackChunk> trackChunks, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, TempoMap tempoMap, long notesTolerance = 0) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsOutOfRange(nameof(ratio), ratio, LengthedObjectsSplitter <Chord> .ZeroRatio, LengthedObjectsSplitter <Chord> .FullLengthRatio, $"Ratio is out of [{LengthedObjectsSplitter<Chord>.ZeroRatio}; {LengthedObjectsSplitter<Chord>.FullLengthRatio}] range."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfNotesTolerance.IsNegative(nameof(notesTolerance), notesTolerance); foreach (var trackChunk in trackChunks) { trackChunk.SplitChordsAtDistance(ratio, lengthType, from, tempoMap, notesTolerance); } }
/// <summary> /// Splits chords contained in the specified <see cref="TrackChunk"/> at the specified distance /// from a chord's start or end. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to split chords in.</param> /// <param name="distance">Distance to split chords at.</param> /// <param name="from">Point of a chord <paramref name="distance"/> should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <param name="settings">Settings accoridng to which chords should be detected and built.</param> /// <exception cref="ArgumentNullException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="trackChunk"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="distance"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> public static void SplitChordsAtDistance(this TrackChunk trackChunk, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkChords(trackChunk, (splitter, chords) => splitter.SplitAtDistance(chords, distance, from, tempoMap), settings); }
/// <summary> /// Splits notes contained in the specified <see cref="TrackChunk"/> by the specified ratio of a /// note's length measuring it from the note's start or end. For example, 0.5 means splitting /// at the center of a note. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to split notes in.</param> /// <param name="ratio">Ratio of a note's length to split by. Valid values are from 0 to 1.</param> /// <param name="lengthType">The type a note's length should be processed according to.</param> /// <param name="from">Point of a note distance should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <param name="noteDetectionSettings">Settings accoridng to which notes should be detected and built.</param> /// <exception cref="ArgumentNullException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="trackChunk"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="ratio"/> is out of valid range.</exception> /// <exception cref="InvalidEnumArgumentException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="lengthType"/> specified an invalid value.</description> /// </item> /// <item> /// <description><paramref name="from"/> specified an invalid value.</description> /// </item> /// </list> /// </exception> public static void SplitNotesAtDistance(this TrackChunk trackChunk, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, TempoMap tempoMap, NoteDetectionSettings noteDetectionSettings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsOutOfRange(nameof(ratio), ratio, LengthedObjectsSplitter <Note> .ZeroRatio, LengthedObjectsSplitter <Note> .FullLengthRatio, $"Ratio is out of [{LengthedObjectsSplitter<Note>.ZeroRatio}; {LengthedObjectsSplitter<Note>.FullLengthRatio}] range."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkNotes(trackChunk, noteDetectionSettings, (splitter, notes) => splitter.SplitAtDistance(notes, ratio, lengthType, from, tempoMap)); }
/// <summary> /// Splits chords contained in the specified collection of <see cref="TrackChunk"/> at the specified /// distance from a chord's start or end. /// </summary> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> to split chords in.</param> /// <param name="distance">Distance to split chords at.</param> /// <param name="from">Point of a chord <paramref name="distance"/> should be measured from.</param> /// <param name="tempoMap">Tempo map used for distances calculations.</param> /// <param name="settings">Settings accoridng to which chords should be detected and built.</param> /// <exception cref="ArgumentNullException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="trackChunks"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="distance"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="from"/> specified an invalid value.</exception> public static void SplitChordsAtDistance(this IEnumerable <TrackChunk> trackChunks, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); foreach (var trackChunk in trackChunks) { trackChunk.SplitChordsAtDistance(distance, from, tempoMap, settings); } }