/// <summary> /// Merges nearby notes in the specified <see cref="MidiFile"/>. /// </summary> /// <param name="midiFile"><see cref="MidiFile"/> to merge nearby notes in.</param> /// <param name="settings">Settings according to which notes should be merged.</param> /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is <c>null</c>.</exception> public static void MergeNotes(this MidiFile midiFile, NotesMergingSettings settings = null) { ThrowIfArgument.IsNull(nameof(midiFile), midiFile); var tempoMap = midiFile.GetTempoMap(); midiFile.GetTrackChunks().MergeNotes(tempoMap, settings); }
/// <summary> /// Merges nearby notes in the specified collection of <see cref="TrackChunk"/>. /// </summary> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> to merge nearby notes in.</param> /// <param name="tempoMap">Tempo map used to calculate distances between notes.</param> /// <param name="settings">Settings according to which notes should be merged.</param> /// <param name="filter">Filter for notes to merge.</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> public static void MergeNotes(this IEnumerable <TrackChunk> trackChunks, TempoMap tempoMap, NotesMergingSettings settings = null, Predicate <Note> filter = null) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); foreach (var trackChunk in trackChunks.Where(c => c != null)) { trackChunk.MergeNotes(tempoMap, settings, filter); } }
/// <summary> /// Merges nearby notes in the specified collection of notes. /// </summary> /// <param name="notes">Collection of notes to merge notes in.</param> /// <param name="tempoMap">Tempo map used to calculate distances between notes.</param> /// <param name="settings">Settings according to which notes should be merged.</param> /// <returns>Collection of notes which produced from the input one by merging nearby notes.</returns> /// <exception cref="ArgumentNullException"><paramref name="notes"/> is null.</exception> public IEnumerable <Note> Merge(IEnumerable <Note> notes, TempoMap tempoMap, NotesMergingSettings settings = null) { ThrowIfArgument.IsNull(nameof(notes), notes); settings = settings ?? new NotesMergingSettings(); var currentNotes = new Dictionary <NoteId, NoteHolder>(); var toleranceType = settings.Tolerance.GetType(); foreach (var note in notes.Where(n => n != null).OrderBy(n => n.Time)) { var noteId = note.GetNoteId(); NoteHolder currentNoteHolder; if (!currentNotes.TryGetValue(noteId, out currentNoteHolder)) { currentNotes.Add(noteId, currentNoteHolder = CreateNoteHolder(note, settings)); continue; } var currentEndTime = currentNoteHolder.EndTime; var distance = Math.Max(0, note.Time - currentEndTime); var convertedDistance = LengthConverter.ConvertTo((MidiTimeSpan)distance, toleranceType, currentEndTime, tempoMap); if (convertedDistance.CompareTo(settings.Tolerance) <= 0) { var endTime = Math.Max(note.Time + note.Length, currentEndTime); currentNoteHolder.EndTime = endTime; currentNoteHolder.MergeVelocities(note); } else { yield return(currentNotes[noteId].GetResultNote()); currentNotes[noteId] = CreateNoteHolder(note, settings); } } foreach (var note in currentNotes.Values) { yield return(note.GetResultNote()); } }
/// <summary> /// Merges nearby notes in the specified <see cref="TrackChunk"/>. /// </summary> /// <param name="trackChunk"><see cref="TrackChunk"/> to merge nearby notes in.</param> /// <param name="tempoMap">Tempo map used to calculate distances between notes.</param> /// <param name="settings">Settings according to which notes should be merged.</param> /// <param name="filter">Filter for notes to merge.</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> public static void MergeNotes(this TrackChunk trackChunk, TempoMap tempoMap, NotesMergingSettings settings = null, Predicate <Note> filter = null) { ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); using (var notesManager = trackChunk.ManageNotes()) { var notes = notesManager.Notes; var notesMerger = new NotesMerger(); var newNotes = notesMerger.Merge(notes.Where(n => filter == null || filter(n)), tempoMap, settings) .ToList(); notes.Clear(); notes.Add(newNotes); } }
private static NoteHolder CreateNoteHolder(Note note, NotesMergingSettings settings) { return(new NoteHolder(note.Clone(), VelocityMergers[settings.VelocityMergingPolicy](), VelocityMergers[settings.OffVelocityMergingPolicy]())); }