private static void SplitTrackChunkNotes(TrackChunk trackChunk, NoteDetectionSettings noteDetectionSettings, Func <NotesSplitter, IEnumerable <Note>, IEnumerable <Note> > splitOperation) { using (var notesManager = trackChunk.ManageNotes(noteDetectionSettings)) { var notes = notesManager.Notes; var notesSplitter = new NotesSplitter(); var newNotes = splitOperation(notesSplitter, notes).ToList(); notes.Clear(); notes.Add(newNotes); } }
private void GetNotes_DetectionSettings_EventsCollection( ContainerType containerType, NoteDetectionSettings settings, ICollection <MidiEvent> midiEvents, ICollection <Note> expectedNotes) { switch (containerType) { case ContainerType.EventsCollection: { var eventsCollection = new EventsCollection(); eventsCollection.AddRange(midiEvents); var notes = eventsCollection.GetNotes(settings); MidiAsserts.AreEqual(expectedNotes, notes, "Notes are invalid."); var timedObjects = eventsCollection.GetObjects(ObjectType.Note, new ObjectDetectionSettings { NoteDetectionSettings = settings }); MidiAsserts.AreEqual(expectedNotes, timedObjects, "Notes are invalid from GetObjects."); } break; case ContainerType.TrackChunk: { var trackChunk = new TrackChunk(midiEvents); var notes = trackChunk.GetNotes(settings); MidiAsserts.AreEqual(expectedNotes, notes, "Notes are invalid."); var timedObjects = trackChunk.GetObjects(ObjectType.Note, new ObjectDetectionSettings { NoteDetectionSettings = settings }); MidiAsserts.AreEqual(expectedNotes, timedObjects, "Notes are invalid from GetObjects."); } break; case ContainerType.TrackChunks: case ContainerType.File: { GetNotes_DetectionSettings_TrackChunks( containerType == ContainerType.File, settings, new[] { midiEvents }, expectedNotes); } break; } }
private void GetNotes_DetectionSettings_TrackChunks( bool wrapToFile, NoteDetectionSettings settings, ICollection <ICollection <MidiEvent> > midiEvents, IEnumerable <Note> expectedNotes) { IEnumerable <Note> notes; var trackChunks = midiEvents.Select(e => new TrackChunk(e)).ToArray(); if (wrapToFile) { notes = new MidiFile(trackChunks).GetNotes(settings); } else { notes = trackChunks.GetNotes(settings); } MidiAsserts.AreEqual(expectedNotes, notes, "Notes are invalid."); // // TODO: Support events collection indicies in GetObjects if (settings.NoteSearchContext == NoteSearchContext.AllEventsCollections) { IEnumerable <ITimedObject> timedObjects; if (wrapToFile) { timedObjects = new MidiFile(trackChunks).GetObjects(ObjectType.Note, new ObjectDetectionSettings { NoteDetectionSettings = settings }); } else { timedObjects = trackChunks.GetObjects(ObjectType.Note, new ObjectDetectionSettings { NoteDetectionSettings = settings }); } MidiAsserts.AreEqual(expectedNotes, timedObjects, "Notes are invalid from GetObjects."); } }
private void GetObjects_NotesAndRests( RestSeparationPolicy restSeparationPolicy, IEnumerable <ITimedObject> inputObjects, IEnumerable <ITimedObject> outputObjects, NoteDetectionSettings noteDetectionSettings = null) { GetObjects( inputObjects, outputObjects, ObjectType.Note | ObjectType.Rest, new ObjectDetectionSettings { RestDetectionSettings = new RestDetectionSettings { RestSeparationPolicy = restSeparationPolicy }, NoteDetectionSettings = noteDetectionSettings ?? new NoteDetectionSettings() }); }
/// <summary> /// Splits notes contained in the specified <see cref="TrackChunk"/> by the specified step so /// every note will be split at points equally distanced from each other starting from /// the note's start time. /// </summary> /// <remarks> /// Notes with zero length and notes with length smaller than <paramref name="step"/> /// will not be split. /// </remarks> /// <param name="trackChunk"><see cref="TrackChunk"/> to split notes in.</param> /// <param name="step">Step to split notes by.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="step"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void SplitNotesByStep(this TrackChunk trackChunk, ITimeSpan step, TempoMap tempoMap, NoteDetectionSettings noteDetectionSettings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(step), step); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkNotes(trackChunk, noteDetectionSettings, (splitter, notes) => splitter.SplitByStep(notes, step, tempoMap)); }
/// <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 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> /// <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="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 SplitNotesAtDistance(this TrackChunk trackChunk, ITimeSpan distance, LengthedObjectTarget from, TempoMap tempoMap, NoteDetectionSettings noteDetectionSettings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsInvalidEnumValue(nameof(from), from); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkNotes(trackChunk, noteDetectionSettings, (splitter, notes) => splitter.SplitAtDistance(notes, distance, from, tempoMap)); }
/// <summary> /// Splits notes contained in the specified <see cref="TrackChunk"/> by the specified grid. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to split notes in.</param> /// <param name="grid">Grid to split notes by.</param> /// <param name="tempoMap">Tempo map used to calculate times to split by.</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="grid"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="tempoMap"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static void SplitNotesByGrid(this TrackChunk trackChunk, IGrid grid, TempoMap tempoMap, NoteDetectionSettings noteDetectionSettings = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(grid), grid); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); SplitTrackChunkNotes(trackChunk, noteDetectionSettings, (splitter, notes) => splitter.SplitByGrid(notes, grid, tempoMap)); }
/// <summary> /// Splits notes contained in the specified <see cref="TrackChunk"/> into the specified number /// of parts of the equal length. /// </summary> /// <remarks> /// If a note 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 notes in.</param> /// <param name="partsNumber">The number of parts to split notes 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="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="partsNumber"/> is zero or negative.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value.</exception> public static void SplitNotesByPartsNumber(this TrackChunk trackChunk, int partsNumber, TimeSpanType lengthType, TempoMap tempoMap, NoteDetectionSettings noteDetectionSettings = 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); SplitTrackChunkNotes(trackChunk, noteDetectionSettings, (splitter, notes) => splitter.SplitByPartsNumber(notes, partsNumber, lengthType, tempoMap)); }