Here's a draft version. Improvements welcome! There are a few to-be-deleted announcements for debugging. This one is special purpose in that it also adds keyswitch notes for legato as done by VSL solo and chamber strings for Gigagstudio ... your own legato patches will need whatever special keyswitch notes there should be.
;;;SET_LEGATO.CAL
;;;BY William Copper
;;;
;;;Add legato key-switch notes and adjust note start times
;;;and duration and previous note duration.
;;;
;;; Prolog
(do
(int notecount 0) ;; count of all notes processed
(int kscount 0) ;; count of keyswitches added
(int note_num 0 ) ;; from each note event
(int note_vel 0 ) ;; from each note event
(int note_chan 0) ;; current key channel
(dword note_time 0 ) ;; "
(dword note_dur 0 ) ;; "
(dword note_end 0 ) ;; each note event end time = note_time + note_dur
(int keybase 24) ;; base keyswitch note (24=C1 at -1 octave setting)
;; adjust as necessary for another global octave setting
(int keymax 12) ;; max keyswitch delta (12=octave)
(int key_interval 0) ;; delta to be added to keybase for keyswitch note
(int key_abs 0 ) ;; absolute value of key interval
(int key_note ) ;; new keyswitch note
(int prev_note_num 0 ) ;; previous key note
(dword ks_time 0) ;; insert time for new key switch
(dword new_time 0) ;; insert time for replacement note
(dword prev_note_dur 0) ;; previous note duration
(dword prev_note_end 0) ;; previous note end time
(dword legato_time 200) ;; discernment interval between end of previous note
;; and start of next note
(dword legato_setback 20) ;; shift back in ticks for new legato start time
(getInt keybase "Keyswitch base note (24=C1 at -1 octave): " 0 127)
(getInt keymax "Keyswitch maximum (12=octave, 24 max) : " 0 24 )
(getInt legato_time "Legato time interval minimum (4000 max): " 0 4000)
(getInt legato_setback "Legato time setback interval (480 max): " 0 480 )
)
;;; Body
(do
(if (== Event.Kind NOTE)
(do
(= note_num Note.Key )
(= note_chan Event.Chan )
(= note_vel Note.Vel )
(= note_time Event.Time )
(= note_dur Note.Dur )
(= note_end (+ note_time note_dur ))
(+= notecount 1 )
(= new_time (- note_time legato_setback ) )
(= ks_time (- new_time 3 ))
;; test for interval vs legato_time
(if (>= legato_time (- note_time prev_note_end) )
(do
(+= kscount 1 )
(= key_interval (- note_num prev_note_num) )
(pause "added ks " kscount " for interval " key_interval )
;; get absolute value of key interval for test
(if (> 0 key_interval ) (= key_abs (- 0 key_interval )))
(if (>= keymax key_abs)
(= key_note (+ keybase key_interval))
;;else
(= key_note keybase)
) ;;end if
;;test for negative time value
(if (<= 0 (- note_time legato_setback))
(do
(delete)
;; insert keyswitch velocity 1, duration 1 3 ticks earlier
(insert ks_time note_chan NOTE key_note 1 1 )
(insert new_time note_chan NOTE note_num
note_vel note_dur )
) ;; end do
) ;; end if
) ;;end do
;; else
(do
(delete)
(insert new_time note_chan NOTE note_num note_vel
(- note_dur legato_setback) )
(insert ks_time note_chan NOTE keybase 1 1 ) ;; (non legato note)
)
)
(= prev_note_end note_end)
(= prev_note_dur note_dur)
(= prev_note_num note_num)
)
) ;; else do nothing
)
;;; Epilog
(do
(pause "Note count " notecount " Keyswitch count " kscount )
)