public static ProcessResult <Clip[]> Apply(QuantizeOptions options, params Clip[] clips) { var maxLen = clips.Max(x => x.Length); if (options.By != null) { if (options.By.Length < maxLen) { ClipUtilities.EnlargeClipByLooping(options.By, maxLen); } options.Divisions = options.By.Notes.Select(x => x.Start).Distinct().ToArray(); } else { var currentPos = 0m; var quantizePositions = new List <decimal>(); var i = 0; while (currentPos <= maxLen) { quantizePositions.Add(currentPos); currentPos += options.Divisions[i % options.Divisions.Length]; i++; } options.Divisions = quantizePositions.ToArray(); } options.Amount = Math.Clamp(options.Amount, 0, 1); var resultClips = new Clip[clips.Length]; for (var i = 0; i < clips.Length; i++) { var clip = clips[i]; var resultClip = new Clip(clip.Length, clip.IsLooping); foreach (var note in clip.Notes) { var constrainedNote = note with { }; var newStart = ClipUtilities.FindNearestNoteStartInDecimalSet(note, options.Divisions); constrainedNote.Start += (newStart - constrainedNote.Start) * options.Amount; resultClip.Add(constrainedNote); } resultClips[i] = resultClip; } return(new ProcessResult <Clip[]>(resultClips)); }