hypolydien
Hello,
I have tried to this different ways which are all quite tedious and I am wondering of there would be a faster way.
Lets say I have a bunch of 1/8 notes in a midi recording which I want to come out with a specific staccato feel. I notice in the event inspector that the notes' durations ranges form 190 to 330 ticks. It turns out I like the way the notes around 275 ticks sound. I would like to change the values of all the notes toward that value without having them all exactly 275 long, so the results does not sound so machine-like.
What is strange is that this works if you choose a specific note value in the resolution field. If I select a 1/16 value in the resolution field, select only "Notes Duration" in the "Change" field and adjust the Strenght to %90, I get all the notes' durations going %90 toward the 240 ticks value of a 1/16 note. However, if I type 275 in the resolution field and do the same then the results are completely erratic. Some notes duration values move towards 275 ticks others away from it.
I know I can change all of them to exactly 275 using the event inspector. I know I can use select by filter and select all the ones which are too long and use Process Lenght to change them by percentage towards my desired 275 value, and then start over with all the notes which are too short making them longer. However, if I want to do this with an orchestral arrangement with hundreds of notes, it is a very long and tedious process.
I have tried to copy a note of my desired length to clipboard and then use groove quantize setting Strength Duration towards 90% and turning off Time and Velocity, but the results are also erratic, with some notes values moving towards my desired length an other away from it.
Dos anyone know a quicker way to do this? BTW I am using Sonar Platinum 23.2.0
Thanks for any help,
Jean
Try either one of these CAL routines. The one posted above didn't work at all, at least that was my experience.
RANDOM NOTE LENGTH (CAL Routine);;Randomize duration
;;This script will randomize MIDI note duration based on a user
;;provided range in ticks from 1 to 240 ticks. Checks are
;;provided to prevent zero durations.
;;
;;
(do
(int offset)
(int range 30) ;; Change default input value here
(getInt range "Select +/- range (ticks): " 1 240)
(int new_duration)
(int pos_range range)
(int neg_range (*= range -1))
(forEachEvent
(if (== Event.Kind NOTE)
(do
(= offset (random neg_range pos_range))
(= new_duration Note.Dur)
(+= new_duration offset)
(if (>= new_duration 0) ;; Make sure calculated duration is not zero
(= Note.Dur new_duration)
);end if
);end do
);end if
);end for
);end do
;; RandTime.CAL, written 1991 by Douglas L. Fetter [UID 5476]
;;;
;; This CAL routine was written to humanize the starting times of notes
;; for sequences that have been entered using either Step Record or which
;; have been Quantized. The user will be requested to enter a value for the
;; maximum number of ticks by which a note's start time can be shifted. The
;; start times of all notes found in the From-to-Thru region on the selected
;; track(s) will be shifted by a random value which is within a range of +/-
;; the user entered value. Before performing a shift that will move a note
;; earlier in time, this CAL routine will check to make certain that such a
;; negative shift will not cause a note to be moved earlier than time 1:1:0
;; (the earliest possible time value). If it would try to go earlier, the
;; offset is adjusted so that the note is instead moved just up to 1:1:0,
;; and no further.
;;;
;; Then, since shifting one note later in time and a subsequent note earlier
;; might cause notes of the same key value to become overlapped (a situation
;; which is not handled well by most synths), the duration of shifted notes
;; is adjusted proportionately so as to prevent this routine from creating
;; this situation. As part of this duration shortening process, this CAL
;; routine will check that reduced notes are not made shorter than a user
;; specified value. If they would become too short, an error is reported and
;; the user asked if the CAL program should abort. If abort is selected, the
;; Cakewalk NOW Time will be altered to the point where the error occurred
;; so that the user can take a look at the problem area. The user should do
;; an Edit UNDO operation to restore the data to the values prior to the
;; execution of the aborted RandTime.CAL routine.
;;;
;; Note: the "Processing Note Event" message line was put in to indicate
;; program status to the user. However, since it adds another 15-20% to
;; the program execution time, it can be removed at the user's discretion.
;Prolog
;
(do
(dword SaveTime) ; Storage for setting NOW time if routine aborted
(int Range 15) ; User specified range for +/- to note start times
(int NegRange) ; negative version of Range value
(int Offset) ; random number between NegRange & Range
(int Decrease) ; amount to decrease duration by to avoid overlap
(int MinDur 5) ; User specified note duration minimum value
(int Abort 0) ; 0 => Program Running; 1 => User Requested Abort
(int EventCnt 0) ; Event counter to provide processing status line
(getInt Range "Enter maximum number of ticks to alter note start times +/- by." 0 480)
(= NegRange (* Range -1))
(getInt MinDur "Enter minimum duration (in ticks) a note may be reduced to." 1 480)
)
RANDOM NOTE LENGTH & START TIME (CAL Routine);Body
;
(if (== Abort 1) ; test if user has aborted note processing
(message "RandTime.CAL Aborted by User; Please Wait for Routine to Complete")
; provide message for user while routine continues thru remaining events
(if (!= Event.Kind NOTE) ; else test if event kind is a note
NIL ; do nothing if event type is not a note
(do ; else process events that are notes
(= Offset (random NegRange Range)) ; offset is a random value within +/- Range
(message "RandTime.CAL Processing Note Event #" (++ EventCnt) "with Offset of " Offset)
(if (< Offset 0) ; check if minus Offset that will shift note earlier
(do ; do these steps for a minus Offset
(if (> (* Offset -1) Event.Time)
; check if it moves start time before 1:1:0
(do ; if moves earlier than the earliest possible time
(= Offset Event.Time) ; make it equal to start time
(*= Offset -1) ; restore it to negative (this moves it to 1:1:0)
) ; close moves earlier than the earliest possible time
NIL ; no problem if negative shift not before 1:1:0
) ; close check if it moves start time before 1:1:0
) ; close do these steps for a minus Offset
NIL ; no extra check needed if shift is positive
) ; close check if minus Offset that will shift note earlier
(= Decrease (+ Range Offset))
(if (<= (+ Decrease MinDur) Note.Dur) ; check decreased duration to Min
(-= Note.Dur Decrease) ; reduce duration if passes user's minimum
; else an error, so check with user for abort
(getInt Abort "ERROR: A Duration went less than User Minimum; Enter 1 to Abort!" 0 1)
) ; close check decreased duration to Min
(if (== Abort 0) ; check if program to be aborted
(+= Event.Time Offset) ; if not, perform shift of note's start time
(= SaveTime Event.Time) ; if aborted, then save event time for later
) ; close check if program to be aborted
) ; close of process events that are notes
) ; close test if event type is a note
) ; close test if user has aborted note processing
;Epilog
;
(if (== Abort 0) ; check if program was aborted
NIL ; if not aborted, nothing to do in epilog
(do ; else, set Now time to point when abort occurred & display message
(= Now SaveTime)
(pause "RandTime.CAL Aborted by User; Use UNDO to Restore Original Values > Hit Enter <")
)
) ; close check if program was aborted
Jerry
www.jerrygerber.com