Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
            }
        }
Пример #3
0
        /// <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());
            }
        }
Пример #4
0
        /// <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);
            }
        }
Пример #5
0
 private static NoteHolder CreateNoteHolder(Note note, NotesMergingSettings settings)
 {
     return(new NoteHolder(note.Clone(),
                           VelocityMergers[settings.VelocityMergingPolicy](),
                           VelocityMergers[settings.OffVelocityMergingPolicy]()));
 }