The below gives you some CAL script program and (programming links)
http://www.hexachord.net/cal/ http://www.svpworld.com/cakewalk_cal/cal.asp http://forum.cakewalk.com/printable.asp?m=961016 http://www.ericvonbayer.us/music/#soft (look down the page)
I have not tried the below script...but it appears to cover a number of issues....Does anyone use this?
; MULTIFIX.CAL by
John Cowles - 12/05/94 ; Version 2.00 - 12/06/94 (25% speed increase, added mods counter, tightened docs)
; Version 2.01 - 12/06/94 (fix evaluation stack overflow)
; Version 2.02 - 12/09/94 (changed to agree with Cakewalk's idea of duration<g>!)
; Version 3.00 - 12/10/94 (speed increase - can now fix multiple continuous multistruck and duplicate notes)
; INTERNET:
cowles@hydra.convex.com - CIS: 72074,451
;
; This program fixes multistruck, overlapped, and duplicate
; notes on a single track. It is designed to correct the effects of
; running a "humanize" program which modifies note times and
; durations by less than a 64th note, and to remove duplicate
; notes which have been entered by a defective input device,
; or by inadvertantly pasting a track over itself. It even does a
; fair job of fixing a track which has been pasted over itself and
; then "humanized".
;
; The program runs on one track at a time (the one where the cursor
; is currently at), and if you have NOT set From and Thru markers,
; it will run on the entire track.
;
; The program may take several minutes to run, and there
; is a progress message printed out in the message bar at the bottom.
;
; I have tried to take into account the various permutations of multistruck
; notes. If this does not cover the particular situation you have (or
; if the program misbehaves!) please contact me and I'll try to
; remedy the situation.
;
; Note that MULTIFIX assumes that every note on the track goes to
; a single channel. If this is NOT the case, you should take great care!
;
; In the following three cases of two notes of the same key beginning at
; the same time, 'X' means event deleted, and 'K' means event kept
; (note that the difference in ending times is less than a 64th note):
;
; Action Event Duration
;
; K ################## (Type 1)
; X ##################
;
; K ################## (Type 2)
; X #################
;
; X ################# (Type 3)
; K ##################
;
; When two notes overlap by less than a 64th note (TIMEBASE / 16), then
; the first note is shortened so that it ends 2 ticks before the second
; note begins - i.e.:
; ######### (Type 4)
; ##########
; becomes:
; #######
; ##########
;
; An overlap of greater than a 64th note is changed to a single note - i.e.:
; ########### (Type 5)
; #############
; becomes:
; #################
; Please note that you may not like this behavior, and may wish to modify the
; program to act differently (perhaps by changing the variable "scaletime"
; to a value greater than a 64th note).
;
; If an enclosed note is less than a 64th note, then two notes are made
; as follows:
; ################### (Type 6)
; ##
; becomes:
; #######
; ############
;
; and:
; ###################
; ## ##
; becomes:
; ###
; ########
; ########
; This happens because of an anomaly when Cakewalk saves files as SMF's
; rather than .WRK files, and the file contains overlapped notes (of Type 4).
;
; An enclosed note greater than a 64th note is deleted. (Type 7)
; In this case also, you may not like the behavior, and may wish to modify the
; program to act differently (perhaps by changing the variable "scaletime"
; to a value greater than a 64th note).
;
; Because it is possible to modify a single note multiple times, there are a few
; cases where you will see a modification count greater than the original number
; of notes.
;
; This routine can not handle duplicate note events if the events are offset by
; greater than a 64th note (but you may wish to try anyway, by modifying
; the "scaletime" variable to a value greater than a 64th note).
;
; If you have notes in your sequence which you wish to maintain at a duration less
; than a 64th note, then you may wish to shorten the "scaletime" variable by
; dividing it by 32, rather than 16, to give an initial value equivalent to a 128th note.
(do
(int ckey 0)
(int first 1)
(int nosave 0)
(int nowrite 1)
(int mods 0)
(int both 0)
(int notechan 0)
(int notevel 0)
(int lowkey 127)
(int highkey 0)
(int nexthigh 127)
(dword eventend 0)
(dword noteend 0)
(dword tempend 0)
(dword scaletime 7)
(dword notestart 0)
(= scaletime (/ TIMEBASE 16)) ; number of ticks for a 64th note
(= scaletime 60)
(if ( == From Thru ) ; if From and Thru are not set, do the entire track
(do
(= From 0)
(= Thru End)
)
)
; (TrackSelect 0 -1) ; insure that only one track is selected (otherwise
; the last notes of a track are written to the next track)
; Find the lowest and highest notes on the track
(= lowkey 127)
(= highkey 0)
(forEachEvent
(if (== Event.Kind NOTE)
(do
(if (< Note.Key lowkey)
(= lowkey Note.Key)
)
(if (> Note.Key highkey)
(= highkey Note.Key)
)
)
)
)
(= ckey lowkey) ; set key search parameters
(++ highkey)
;begin main body of program
(while (< ckey highkey)
(do
(message "Key From, To, Current = " lowkey highkey ckey "Modifications= " mods)
(forEachEvent
(if (&& (== Event.Kind NOTE) (== Note.Key ckey))
(do
(= eventend (+ Event.Time Note.Dur)) ; use this a lot - save it
(if (== first 0) ; if NOT first
(do
; (pause notestart noteend Event.Time eventend mods)
(if (== Event.Time notestart) ; duplicate start times
(do
(if (> eventend noteend)
(do
(++ mods)
(= noteend eventend) ; make buffer note duration equal
; to the longest of the two
)
)
(= both 1)
) ; else NOT duplicate start times
(do
(if (< (- Event.Time notestart) scaletime) ; then got a duplicate of some sort
(do
(= both 1)
(if (> eventend noteend)
(do
(++ mods)
(= noteend eventend) ; make buffer note duration equal
; to the longest of the two
)
)
)
) ; end if < - Event.Time notestart scaletime
(if (&& (== both 0) (<= Event.Time noteend)) ; then - got a multistruck note
(do
(if (<= eventend noteend) ; then - got an enclosed note
(if (< (- noteend eventend) scaletime) ; then - extraneous
(= both 1)
(do ; else - short enclosed note - make two notes
(+= mods 2)
(= tempend noteend)
(= noteend (- Event.Time 2))
(= Note.Dur (- tempend Event.Time))
(= eventend (+ Event.Time Note.Dur))
)
) ; end if < enclosure amount scaletime
(do ;else - got an overlapped note
(++ mods)
(if (> (- noteend Event.Time) scaletime) ; then - big
; overlap - join
(do
(= noteend (+ Event.Time Note.Dur))
(= both 1)
)
(do
(++ mods)
(= noteend (- Event.Time 2)) ; else - small overlap
; - make two notes
)
) ; end if > - noteend Event.time scaletime
)
) ; end if < eventend noteend
)
) ; end if < Event.Time noteend
)
) ; end if == Event.Time notestart
)
(= first 0) ; else if first time for this key
) ; end if == first 0
(delete) ; current event
(if (== both 1)
(do
(= both 0)
(= nosave 1)
(= nowrite 1)
(++ mods)
)
)
(if (== nowrite 0) ; then insert previous event
(insert notestart notechan NOTE ckey notevel (- noteend notestart))
) ; end if == nowrite 0
(if (== nosave 0) ;then save current event
(do
(= notestart Event.Time)
(= notechan Event.Chan)
(= notevel Note.Vel)
(= noteend eventend)
)
) ; end if == nosave 0
(= nowrite 0)
(= nosave 0)
)
(do ; else != Note.Key ckey
(if (> Note.Key ckey)
(if (< Note.Key nexthigh)
(= nexthigh Note.Key)
)
)
)
) ; if == Note.Key ckey
) ; end forEachEvent
; if first is not still set, we have found at least one event, and must
; put it back
(if (== first 0)
(insert notestart notechan NOTE ckey notevel (- noteend notestart))
) ; end if == first 0
(= first 1)
(= nowrite 1)
(= ckey nexthigh)
(= nexthigh highkey)
)
) ; end while ckey
(pause "There were " mods "modifications.")
)