public static ProcessResultArray <Clip> Apply(SetPitchOptions options, params Clip[] clips) { var resultClips = ClipUtilities.CreateEmptyPlaceholderClips(clips); int[] pitches; if (options.PitchValues.Length > 0) { pitches = options.PitchValues; } else { pitches = options.By.Notes.Select(x => x.Pitch).ToArray(); } if (pitches.Length == 0) { return(new ProcessResultArray <Clip>(clips, "SetPitch did nothing, since neither pitches or -by clip was specified.")); } for (var i = 0; i < clips.Length; i++) { var clip = clips[i]; var resultClip = resultClips[i]; var pitchIx = 0; foreach (var note in clip.Notes) { var repitchedNote = new NoteEvent(note) { Pitch = pitches[pitchIx++ % pitches.Length] }; ClipUtilities.AddNoteCutting(resultClip, repitchedNote); } } return(new ProcessResultArray <Clip>(resultClips)); }
public static Clip AddEchoes(Clip clip, decimal[] lengths, int[] echoes) { var lengthIx = 0; var echoIx = 0; var newNotes = new List <NoteEvent>(); foreach (var noteEvent in clip.Notes) { var delayTime = lengths[lengthIx++ % lengths.Length]; var echoCount = Math.Max(echoes[echoIx++ % echoes.Length], 2); var velocityFalloff = (int)Math.Round((noteEvent.Velocity - 10) / (echoCount - 1)); if (noteEvent.Duration > delayTime) { noteEvent.Duration = delayTime; } for (var i = 0; i < echoCount; i++) { var echoedNote = noteEvent with { }; echoedNote.Start += delayTime * i; echoedNote.Velocity -= velocityFalloff * i; newNotes.Add(echoedNote); } } foreach (var newNote in newNotes) { ClipUtilities.AddNoteCutting(clip, newNote); } // todo: handle wrapping echoes outside the length of the clip return(clip); }
public static ProcessResultArray <Clip> Apply(SetLengthOptions options, params Clip[] clips) { var resultClips = ClipUtilities.CreateEmptyPlaceholderClips(clips); for (var index = 0; index < clips.Length; index++) { var clip = clips[index]; var resultClip = resultClips[index]; var lengthCounter = 0; foreach (var note in clip.Notes) { ClipUtilities.AddNoteCutting(resultClip, new NoteEvent(note) { Duration = options.Lengths[lengthCounter++ % options.Lengths.Length] }); } } return(new ProcessResultArray <Clip>(resultClips)); }
public static ProcessResult <Clip[]> Apply(RemapOptions options, params Clip[] clips) { var resultClips = ClipUtilities.CreateEmptyPlaceholderClips(clips); for (var i = 0; i < clips.Length; i++) { var clip = clips[i]; var resultClip = resultClips[i]; var sourcePitches = clip.Notes.Select(x => x.Pitch).Distinct().OrderBy(x => x).ToList(); var destPitches = options.To.Count > 0 ? options.To.Notes.Select(x => x.Pitch).Distinct().OrderBy(x => x).ToList() : Enumerable.Range(36, Math.Min(sourcePitches.Count, 128 - 36)).ToList(); var inc = 1f; if (destPitches.Count < sourcePitches.Count) { inc = (float)destPitches.Count / sourcePitches.Count; } var map = new Dictionary <int, int>(); var destIx = 0f; foreach (var sourcePitch in sourcePitches) { map[sourcePitch] = destPitches[(int)Math.Floor(destIx)]; destIx += inc; } foreach (var note in clip.Notes) { var remappedNote = note with { Pitch = map[note.Pitch] }; ClipUtilities.AddNoteCutting(resultClip, remappedNote); } } return(new ProcessResult <Clip[]>(resultClips)); } }