private void ProcessChords_DetectionSettings_EventsCollection_WithoutPredicate( ContainerType containerType, ChordDetectionSettings settings, ICollection <MidiEvent> midiEvents, Action <Chord> action, ICollection <MidiEvent> expectedMidiEvents) { var chordsCount = midiEvents.GetChords(settings).Count; switch (containerType) { case ContainerType.EventsCollection: { var eventsCollection = new EventsCollection(); eventsCollection.AddRange(midiEvents); Assert.AreEqual( chordsCount, eventsCollection.ProcessChords(action, settings), "Invalid count of processed chords."); var expectedEventsCollection = new EventsCollection(); expectedEventsCollection.AddRange(expectedMidiEvents); MidiAsserts.AreEqual(expectedEventsCollection, eventsCollection, true, "Events are invalid."); Assert.IsTrue( eventsCollection.All(e => midiEvents.Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } break; case ContainerType.TrackChunk: { var trackChunk = new TrackChunk(midiEvents); Assert.AreEqual( chordsCount, trackChunk.ProcessChords(action, settings), "Invalid count of processed chords."); var expectedTrackChunk = new TrackChunk(expectedMidiEvents); MidiAsserts.AreEqual(expectedTrackChunk, trackChunk, true, "Events are invalid."); Assert.IsTrue( trackChunk.Events.All(e => midiEvents.Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } break; case ContainerType.TrackChunks: case ContainerType.File: { ProcessChords_DetectionSettings_TrackChunks_WithoutPredicate( containerType == ContainerType.File, settings, new[] { midiEvents }, action, new[] { expectedMidiEvents }); } break; } }
/// <summary> /// Splits chords contained in the specified <see cref="MidiFile"/> by the specified grid. /// </summary> /// <param name="midiFile"><see cref="MidiFile"/> to split chords in.</param> /// <param name="grid">Grid to split chords by.</param> /// <param name="settings">Settings accoridng to which chords should be detected and built.</param> /// <exception cref="ArgumentNullException"><paramref name="grid"/> is <c>null</c>.</exception> public static void SplitChordsByGrid(this MidiFile midiFile, IGrid grid, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNull(nameof(grid), grid); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().SplitChordsByGrid(grid, tempoMap, settings); }
/// <summary> /// Splits chords contained in the specified <see cref="MidiFile"/> by the specified /// step so every chord will be split at points equally distanced from each other /// starting from the chord's start time. /// </summary> /// <remarks> /// Chords with zero length and chords with length smaller than <paramref name="step"/> /// will not be split. /// </remarks> /// <param name="midiFile"><see cref="MidiFile"/> to split chords in.</param> /// <param name="step">Step to split chords by.</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="step"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void SplitChordsByStep(this MidiFile midiFile, ITimeSpan step, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNull(nameof(step), step); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().SplitChordsByStep(step, tempoMap, settings); }
private void GetChords_DetectionSettings_EventsCollection( ContainerType containerType, ChordDetectionSettings settings, ICollection <MidiEvent> midiEvents, ICollection <Chord> expectedChords) { switch (containerType) { case ContainerType.EventsCollection: { var eventsCollection = new EventsCollection(); eventsCollection.AddRange(midiEvents); var chords = eventsCollection.GetChords(settings); MidiAsserts.AreEqual(expectedChords, chords, "Chords are invalid."); var timedObjets = eventsCollection.GetObjects(ObjectType.Chord, new ObjectDetectionSettings { ChordDetectionSettings = settings }); MidiAsserts.AreEqual(expectedChords, timedObjets, "Chords are invalid from GetObjects."); } break; case ContainerType.TrackChunk: { var trackChunk = new TrackChunk(midiEvents); var chords = trackChunk.GetChords(settings); MidiAsserts.AreEqual(expectedChords, chords, "Chords are invalid."); var timedObjets = trackChunk.GetObjects(ObjectType.Chord, new ObjectDetectionSettings { ChordDetectionSettings = settings }); MidiAsserts.AreEqual(expectedChords, timedObjets, "Chords are invalid from GetObjects."); } break; case ContainerType.TrackChunks: case ContainerType.File: { GetChords_DetectionSettings_TrackChunks( containerType == ContainerType.File, settings, new[] { midiEvents }, expectedChords); } break; } }
private void GetChords_DetectionSettings_TrackChunks( bool wrapToFile, ChordDetectionSettings settings, ICollection <ICollection <MidiEvent> > midiEvents, IEnumerable <Chord> expectedChords) { IEnumerable <Chord> chords; var trackChunks = midiEvents.Select(e => new TrackChunk(e)).ToArray(); if (wrapToFile) { chords = new MidiFile(trackChunks).GetChords(settings); } else { chords = trackChunks.GetChords(settings); } MidiAsserts.AreEqual(expectedChords, chords, "Chords are invalid."); // // TODO: Support events collection indicies in GetObjects if (settings.ChordSearchContext == ChordSearchContext.AllEventsCollections) { IEnumerable <ITimedObject> timedObjects; if (wrapToFile) { timedObjects = new MidiFile(trackChunks).GetObjects(ObjectType.Chord, new ObjectDetectionSettings { ChordDetectionSettings = settings }); } else { timedObjects = trackChunks.GetObjects(ObjectType.Chord, new ObjectDetectionSettings { ChordDetectionSettings = settings }); } MidiAsserts.AreEqual(expectedChords, timedObjects, "Chords are invalid from GetObjects."); } }
private void ProcessChords_DetectionSettings_TrackChunks_WithPredicate( bool wrapToFile, ChordDetectionSettings settings, ICollection <ICollection <MidiEvent> > midiEvents, Action <Chord> action, Predicate <Chord> match, ICollection <ICollection <MidiEvent> > expectedMidiEvents, int expectedProcessedCount) { var trackChunks = midiEvents.Select(e => new TrackChunk(e)).ToList(); if (wrapToFile) { var midiFile = new MidiFile(trackChunks); Assert.AreEqual( expectedProcessedCount, midiFile.ProcessChords(action, match, settings), "Invalid count of processed chords."); MidiAsserts.AreEqual(new MidiFile(expectedMidiEvents.Select(e => new TrackChunk(e))), midiFile, false, "Events are invalid."); Assert.IsTrue( midiFile.GetTrackChunks().SelectMany(c => c.Events).All(e => midiEvents.SelectMany(ee => ee).Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } else { Assert.AreEqual( expectedProcessedCount, trackChunks.ProcessChords(action, match, settings), "Invalid count of processed chords."); MidiAsserts.AreEqual(expectedMidiEvents.Select(e => new TrackChunk(e)), trackChunks, true, "Events are invalid."); Assert.IsTrue( trackChunks.SelectMany(c => c.Events).All(e => midiEvents.SelectMany(ee => ee).Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } }
private void RemoveChords_DetectionSettings_TrackChunks_WithoutPredicate( bool wrapToFile, ChordDetectionSettings settings, ICollection <ICollection <MidiEvent> > midiEvents, ICollection <ICollection <MidiEvent> > expectedMidiEvents) { var trackChunks = midiEvents.Select(e => new TrackChunk(e)).ToList(); var chordsCount = trackChunks.GetChords(settings).Count; if (wrapToFile) { var midiFile = new MidiFile(trackChunks); Assert.AreEqual( chordsCount, midiFile.RemoveChords(settings), "Invalid count of removed chords."); MidiAsserts.AreEqual(new MidiFile(expectedMidiEvents.Select(e => new TrackChunk(e))), midiFile, false, "Events are invalid."); Assert.IsTrue( midiFile.GetTrackChunks().SelectMany(c => c.Events).All(e => midiEvents.SelectMany(ee => ee).Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } else { Assert.AreEqual( chordsCount, trackChunks.RemoveChords(settings), "Invalid count of removed chords."); MidiAsserts.AreEqual(expectedMidiEvents.Select(e => new TrackChunk(e)), trackChunks, true, "Events are invalid."); Assert.IsTrue( trackChunks.SelectMany(c => c.Events).All(e => midiEvents.SelectMany(ee => ee).Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } }
/// <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="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="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 SplitChordsAtDistance(this TrackChunk trackChunk, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, TempoMap tempoMap, ChordDetectionSettings settings = null) { 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); SplitTrackChunkChords(trackChunk, (splitter, chords) => splitter.SplitAtDistance(chords, ratio, lengthType, from, tempoMap), settings); }
/// <summary> /// Splits chords contained in the specified collection of <see cref="TrackChunk"/> into the /// specified number of parts of the equal length. /// </summary> /// <remarks> /// If a chord has zero length, it will be split into the specified number of parts of zero length. /// </remarks> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> to split chords in.</param> /// <param name="partsNumber">The number of parts to split chords into.</param> /// <param name="lengthType">Type of a part's length.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="partsNumber"/> is zero or negative.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value.</exception> public static void SplitChordsByPartsNumber(this IEnumerable <TrackChunk> trackChunks, int partsNumber, TimeSpanType lengthType, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNonpositive(nameof(partsNumber), partsNumber, "Parts number is zero or negative."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); foreach (var trackChunk in trackChunks) { trackChunk.SplitChordsByPartsNumber(partsNumber, lengthType, tempoMap, settings); } }
/// <summary> /// Splits chords contained in the specified <see cref="MidiFile"/> into the specified number of /// parts of the equal length. /// </summary> /// <remarks> /// If a chord has zero length, it will be split into the specified number of parts of zero length. /// </remarks> /// <param name="midiFile"><see cref="MidiFile"/> to split chords in.</param> /// <param name="partsNumber">The number of parts to split chords into.</param> /// <param name="lengthType">Type of a part's length.</param> /// <param name="settings">Settings accoridng to which chords should be detected and built.</param> /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is <c>null</c>.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="partsNumber"/> is zero or negative.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value.</exception> public static void SplitChordsByPartsNumber(this MidiFile midiFile, int partsNumber, TimeSpanType lengthType, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); ThrowIfArgument.IsNonpositive(nameof(partsNumber), partsNumber, "Parts number is zero or negative."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().SplitChordsByPartsNumber(partsNumber, lengthType, tempoMap, settings); }
private void RemoveChords_DetectionSettings_EventsCollection_WithPredicate( ContainerType containerType, ChordDetectionSettings settings, ICollection <MidiEvent> midiEvents, Predicate <Chord> match, ICollection <MidiEvent> expectedMidiEvents, int expectedRemovedCount) { var eventsCollection = new EventsCollection(); eventsCollection.AddRange(midiEvents); switch (containerType) { case ContainerType.EventsCollection: { Assert.AreEqual( expectedRemovedCount, eventsCollection.RemoveChords(match, settings), "Invalid count of removed chords."); var expectedEventsCollection = new EventsCollection(); expectedEventsCollection.AddRange(expectedMidiEvents); MidiAsserts.AreEqual(expectedEventsCollection, eventsCollection, true, "Events are invalid."); Assert.IsTrue( eventsCollection.All(e => midiEvents.Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } break; case ContainerType.TrackChunk: { var trackChunk = new TrackChunk(eventsCollection); Assert.AreEqual( expectedRemovedCount, trackChunk.RemoveChords(match, settings), "Invalid count of removed chords."); var expectedTrackChunk = new TrackChunk(expectedMidiEvents); MidiAsserts.AreEqual(expectedTrackChunk, trackChunk, true, "Events are invalid."); Assert.IsTrue( trackChunk.Events.All(e => midiEvents.Any(ee => object.ReferenceEquals(e, ee))), "There are new events references."); } break; case ContainerType.TrackChunks: case ContainerType.File: { RemoveChords_DetectionSettings_TrackChunks_WithPredicate( containerType == ContainerType.File, settings, new[] { midiEvents }, match, new[] { expectedMidiEvents }, expectedRemovedCount); } break; } }
/// <summary> /// Splits chords contained in the specified collection of <see cref="TrackChunk"/> by the /// specified step so every chord will be split at points equally distanced from each /// other starting from the chord's start time. /// </summary> /// <remarks> /// Chords with zero length and chords with length smaller than <paramref name="step"/> /// will not be split. /// </remarks> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> to split chords in.</param> /// <param name="step">Step to split chords by.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="step"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void SplitChordsByStep(this IEnumerable <TrackChunk> trackChunks, ITimeSpan step, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(step), step); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); foreach (var trackChunk in trackChunks) { trackChunk.SplitChordsByStep(step, tempoMap, settings); } }
/// <summary> /// Splits chords contained in the specified <see cref="TrackChunk"/> by the specified grid. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to split chords in.</param> /// <param name="grid">Grid to split chords by.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="grid"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void SplitChordsByGrid(this TrackChunk trackChunk, IGrid grid, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(grid), grid); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkChords(trackChunk, (splitter, chords) => splitter.SplitByGrid(chords, grid, 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="settings">Settings accoridng to which chords should be detected and built.</param> /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is <c>null</c>.</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 SplitChordsAtDistance(this MidiFile midiFile, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, ChordDetectionSettings settings = null) { 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); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().SplitChordsAtDistance(ratio, lengthType, from, tempoMap, settings); }
private static void SplitTrackChunkChords(TrackChunk trackChunk, Func <ChordsSplitter, IEnumerable <Chord>, IEnumerable <Chord> > splitOperation, ChordDetectionSettings settings) { using (var chordsManager = trackChunk.ManageChords(settings)) { var chords = chordsManager.Chords; var chordsSplitter = new ChordsSplitter(); var newChords = splitOperation(chordsSplitter, chords).ToList(); chords.Clear(); chords.Add(newChords); } }
/// <summary> /// Splits chords contained in the specified <see cref="TrackChunk"/> into the specified number /// of parts of the equal length. /// </summary> /// <remarks> /// If a chord has zero length, it will be split into the specified number of parts of zero length. /// </remarks> /// <param name="trackChunk"><see cref="TrackChunk"/> to split chords in.</param> /// <param name="partsNumber">The number of parts to split chords into.</param> /// <param name="lengthType">Type of a part's length.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="partsNumber"/> is zero or negative.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value.</exception> public static void SplitChordsByPartsNumber(this TrackChunk trackChunk, int partsNumber, TimeSpanType lengthType, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNonpositive(nameof(partsNumber), partsNumber, "Parts number is zero or negative."); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkChords(trackChunk, (splitter, chords) => splitter.SplitByPartsNumber(chords, partsNumber, lengthType, tempoMap), settings); }
/// <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="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="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 SplitChordsAtDistance(this IEnumerable <TrackChunk> trackChunks, double ratio, TimeSpanType lengthType, LengthedObjectTarget from, TempoMap tempoMap, ChordDetectionSettings settings = null) { 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); foreach (var trackChunk in trackChunks) { trackChunk.SplitChordsAtDistance(ratio, lengthType, from, tempoMap, settings); } }
/// <summary> /// Splits chords contained in the specified <see cref="TrackChunk"/> by the specified step so /// every chord will be split at points equally distanced from each other starting from /// the chord's start time. /// </summary> /// <remarks> /// Chords with zero length and chords with length smaller than <paramref name="step"/> /// will not be split. /// </remarks> /// <param name="trackChunk"><see cref="TrackChunk"/> to split chords in.</param> /// <param name="step">Step to split chords by.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="step"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void SplitChordsByStep(this TrackChunk trackChunk, ITimeSpan step, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(step), step); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkChords(trackChunk, (splitter, chords) => splitter.SplitByStep(chords, step, tempoMap), settings); }
/// <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 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); } }
/// <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 chords contained in the specified collection of <see cref="TrackChunk"/> by the /// specified grid. /// </summary> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> to split chords in.</param> /// <param name="grid">Grid to split chords by.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="grid"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void SplitChordsByGrid(this IEnumerable <TrackChunk> trackChunks, IGrid grid, TempoMap tempoMap, ChordDetectionSettings settings = null) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(grid), grid); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); foreach (var trackChunk in trackChunks) { trackChunk.SplitChordsByGrid(grid, tempoMap, settings); } }