; ------------------------------------------------------------------------------------------------- ; Invert Chord.cal ; ------------------------------------------------------------------------------------------------- ; ; Author: Eric von Bayer ; Email: CAL @ ericvonbayer.us (remove the spaces) ; WWW: http://www.ericvonbayer.us ; Dates: January 2005 - January 2005 ; Version: 1.1 ; Description: ; ; Script to do the first inversion of a chord ; ; ------------------------------------------------------------------------------------------------- ; Make Sure we're new enough ; ------------------------------------------------------------------------------------------------- (do (if (< VERSION 40) (do (pause "This CAL program requires CAL version 4.0 or higher") (exit) ) ) ; ------------------------------------------------------------------------------------------------- ; Config Section ; ------------------------------------------------------------------------------------------------- (word wNoteDur 16) ; Duration of note to tolerate as being the same (16th Note) ; ------------------------------------------------------------------------------------------------- ; Main processing loop ; ------------------------------------------------------------------------------------------------- (dword dInitTime -999999) (dword dLastTime dInitTime) (dword dThrsTime dInitTime) (int iLastChan 0) (int iLastKey 0) (int iMaxKey 0) (int iLastVel 0) (word wLastDur 0) ; Calculate the tolerance (dword dTicksTol (/ (* TIMEBASE 4) wNoteDur ) ) ; Get the last index (dword dLastIndex 0) (dword dCountIndex 0) (forEachEvent (= dLastIndex (index) ) ) (forEachEvent (do ; Only process notes (if (== Event.Kind NOTE) (do ; See if we don't match the last time (if (|| (<= dThrsTime Event.Time ) (== dLastTime dInitTime) ) (do ; Make sure we're not the first event (if (!= dLastTime dInitTime) (do ; Transpose the key till it is > iMaxKey (if we had more than one note) (if (!= iLastKey iMaxKey ) (do (while (<= iLastKey iMaxKey ) (+= iLastKey 12) ) ) ) ; Insert the bottom note 1 octave above its old value (insert dLastTime iLastChan NOTE iLastKey iLastVel wLastDur ) ) ) ; Update the info for a new note (= dLastTime Event.Time) (= iLastChan Event.Chan) (= iLastKey Note.Key) (= iMaxKey Note.Key) (= iLastVel Note.Vel) (= wLastDur Note.Dur) ; Update the time threshold (= dThrsTime (+ Event.Time dTicksTol ) ) ; Delete the lowest note (delete) ) (do ; We match the last time ; Are we a lower key? (if (< Note.Key iLastKey ) (do ; Make sure we're not the first event (if (!= dLastTime dInitTime) (do (insert dLastTime iLastChan NOTE iLastKey iLastVel wLastDur ) ) ) ; Save the new information (don't update the threshold) (= dLastTime Event.Time) (= iLastChan Event.Chan) (= iLastKey Note.Key) (= iLastVel Note.Vel) (= wLastDur Note.Dur) ; Delete the lowest note (delete) ) ) ; Track the highest note of a chord (if (> Note.Key iMaxKey ) (do (= iMaxKey Note.Key ) ) ) ) ) ) ) ; If we have an event and we're on the last event, write it out (if (&& (== dCountIndex dLastIndex ) (!= dLastTime dInitTime) ) (do ; Transpose the key till it is > iMaxKey (if we had more than one note) (if (!= iLastKey iMaxKey ) (do (while (<= iLastKey iMaxKey ) (+= iLastKey 12) ) ) ) (insert dLastTime iLastChan NOTE iLastKey iLastVel wLastDur ) ) ) ; Increment the index counter (++ dCountIndex) ) ) )