; ------------------------------------------------------------------------------------------------- ; Real Drums.cal ; ------------------------------------------------------------------------------------------------- ; ; Author: Eric von Bayer ; Email: CAL @ ericvonbayer.us (remove the spaces) ; WWW: http://www.ericvonbayer.us ; Dates: January 2005 ; Version: 1.0 ; Description: ; ; This CAL will prevent the curse of the octopus drummer. It will keep only drum hits that don't ; violate having only two arms. Idea by Lars. Any notes within a priority group will be first ; come first serve (the earlier of two notes will be kept.) Any notes with differing priority will ; be dropped in favor of the lower priority. This script is based on the GM drum mapping. (do ; ------------------------------------------------------------------------------------------------- ; Make Sure we're new enough ; ------------------------------------------------------------------------------------------------- (if (< VERSION 40) (do (pause "This CAL program requires CAL version 4.0 or higher") (exit) ) ) ; ------------------------------------------------------------------------------------------------- ; Config Section ; ------------------------------------------------------------------------------------------------- (word wNoteDur 32) ; Duration of note to tolerate as being the same (32nd Note) ; ------------------------------------------------------------------------------------------------- ; Main processing loop ; ------------------------------------------------------------------------------------------------- ; Calculate the tolerance (dword dTicksTol (/ (* TIMEBASE 4) wNoteDur ) ) ; Get the last index (dword dLastIndex 0) (dword dCountIndex 1) (forEachEvent (++ dLastIndex ) ) ; Note Buffers (int iPri1 -1) (int iChan1 0) (int iKey1 0) (int iVel1 0) (dword dStart1 0) (dword dDur1 0) (int iPri2 -1) (int iChan2 0) (int iKey2 0) (int iVel2 0) (dword dStart2 0) (dword dDur2 0) ; Temporaries (int iNotePri -1) (dword dNoteTol 0) (forEachEvent (do ; If we have the last event or our event is over the tolerance, write our notes (if (|| (== dCountIndex dLastIndex) (> Event.Time dNoteTol) ) (do ; Insert note 1 (if (!= iPri1 -1) (do (insert dStart1 iChan1 NOTE iKey1 iVel1 dDur1) (= iPri1 -1) ) ) ; Insert note 2 (if (!= iPri2 -1) (do (insert dStart2 iChan2 NOTE iKey2 iVel2 dDur2) (= iPri2 -1) ) ) ) ) ; Only process notes (if (== Event.Kind NOTE) (do ; Get the new note priority (= iNotePri -1) (switch Note.Key 38 (= iNotePri 1) ; Acoustic Snare 40 (= iNotePri 1) ; Electric Snare 41 (= iNotePri 2) ; Low Floor Tom 43 (= iNotePri 3) ; High Floor Tom 45 (= iNotePri 4) ; Low Tom 47 (= iNotePri 5) ; Low-Mid Tom 48 (= iNotePri 6) ; High-Mid Tom 50 (= iNotePri 7) ; High Tom 37 (= iNotePri 8) ; Side Stick 49 (= iNotePri 9) ; Crash Cymbal 1 57 (= iNotePri 9) ; Crash Cymbal 2 51 (= iNotePri 10) ; Ride Cymbal 1 59 (= iNotePri 10) ; Ride Cymbal 2 46 (= iNotePri 11) ; Open Hi-hat 42 (= iNotePri 12) ; Closed Hi-hat 53 (= iNotePri 13) ; Ride Bell ) ; If we're a new note grouping, set the tolerance (if (&& (>= Event.Time dNoteTol) (!= iNotePri -1) ) (do (= dNoteTol (+ Event.Time dTicksTol) ) ) ) ; Only process notes witha priority (if (!= iNotePri -1) (do ; We Have a higher priority note than key1 (if (|| (< iNotePri iPri1) (== iPri1 -1) ) (do ; Move highest priority to second key (= iPri2 iPri1) (= iKey2 iKey1) (= iChan2 iChan1) (= iVel2 iVel1) (= dStart2 dStart1) (= dDur2 dDur1) ; Update highest priority (= iPri1 iNotePri) (= iKey1 Note.Key) (= iChan1 Event.Chan) (= iVel1 Note.Vel) (= dStart1 Event.Time) (= dDur1 Note.Dur) ; else if it is higher priority than key2 ) (if (|| (< iNotePri iPri2) (== iPri2 -1) ) (do ; Update highest priority (= iPri2 iNotePri) (= iKey2 Note.Key) (= iChan2 Event.Chan) (= iVel2 Note.Vel) (= dStart2 Event.Time) (= dDur2 Note.Dur) ) ) ) ; Kill the note (delete) ) ) ) ) ; Increment the index counter (++ dCountIndex) ) ) )