foxicoot Posted August 8, 2024 Posted August 8, 2024 Hi everyone 👋 I need help with writing a CAL script which moves all the notes in one MIDI track to 6 other MIDI tracks. I need all C's and C#'s to be moved to track 2, all D's and D#'s to be moved to track 3, all E's and B's to be moved to track 4, all F's and F#'s to be moved to track 5, all G's and G#'s to be moved to track 6, and all A's and A#'s to be moved to track 7. I'm trying to create a rainbow color theme for MIDI files in Synthesia to enhance the user's sightreading ability. I asked ChatGPT to write the CAL script but it failed over and over again. It kept getting errors like "CAL Error 004: Unknown Procedure and" and "CAL Error 003: Wrong number of arguments if". Is there a way to do this with CAL? Here's the first script it gave me: (do (include "need20.cal") ; Ensure we're running in CAL 2.0 or later. (int i) ; Counter for iteration ; Iterate over all selected events in track 1. (forEachEvent (if (and (== Event.Kind NOTE) (or (== Event.Track 1))) ; Only consider notes from track 1 (begin ; Move C notes (MIDI note numbers 0, 12, 24, ...) to track 2 (if (== (mod Event.Note 12) 0) (setEvent Track 2) ) ; Move C# notes (MIDI note numbers 1, 13, 25, ...) to track 2 (if (== (mod Event.Note 12) 1) (setEvent Track 2) ) ; Move D notes (MIDI note numbers 2, 14, 26, ...) to track 3 (if (== (mod Event.Note 12) 2) (setEvent Track 3) ) ; Move D# notes (MIDI note numbers 3, 15, 27, ...) to track 3 (if (== (mod Event.Note 12) 3) (setEvent Track 3) ) ; Move E notes (MIDI note numbers 4, 16, 28, ...) to track 4 (if (== (mod Event.Note 12) 4) (setEvent Track 4) ) ; Move B notes (MIDI note numbers 11, 23, 35, ...) to track 4 (if (== (mod Event.Note 12) 11) (setEvent Track 4) ) ; Move F notes (MIDI note numbers 5, 17, 29, ...) to track 5 (if (== (mod Event.Note 12) 5) (setEvent Track 5) ) ; Move F# notes (MIDI note numbers 6, 18, 30, ...) to track 5 (if (== (mod Event.Note 12) 6) (setEvent Track 5) ) ; Move G notes (MIDI note numbers 7, 19, 31, ...) to track 6 (if (== (mod Event.Note 12) 7) (setEvent Track 6) ) ; Move G# notes (MIDI note numbers 8, 20, 32, ...) to track 6 (if (== (mod Event.Note 12) 😎 (setEvent Track 6) ) ; Move A notes (MIDI note numbers 9, 21, 33, ...) to track 7 (if (== (mod Event.Note 12) 9) (setEvent Track 7) ) ; Move A# notes (MIDI note numbers 10, 22, 34, ...) to track 7 (if (== (mod Event.Note 12) 10) (setEvent Track 7) ) ) ) ) ) Does anyone know how to do this properly? Thanks!
Gswitz Posted September 25, 2024 Posted September 25, 2024 I would not use a script probably. You can select all notes in a row hitting the keyboard note.
Heinz Hupfer Posted September 26, 2024 Posted September 26, 2024 Hi:) In "*\Cakewalk Content\Sonar\CAL Scripts" is a script which splits notes to tracks, I attached the file, but here's the script itself: ; ; Split Note to Tracks.cal ; ; This routine modifies a source track, splitting it by note# into ; separate destination tracks. Only notes are split ... all other ; track parameters (Controllers, Tempos, Meters and Markers), ; if any, remain in the source track. ; ; Use this routine for splitting up a drum machine or other type ; of instrument track where voices are assigned by note number. ; ; = Courtesy Red Nile Productions 1993 (714)498-7515 CIS:70044,2733 ; ; = Modified 12/10/93 by Greg Hendershott at user's request to ; have this display notes as names (like C#5) rather than numbers ; in the track names. Caveat: The note names always use sharps ; and assume BaseOctave=0. (do (if (< VERSION 20) (do (pause "This CAL program requires CAL version 2.0 or higher") (exit) ) ) (include "need20.cal") ; Require version 2.0 or higher of CAL (int nOctave) (int nSrcTrk 1) (int nDestTrk (+ nSrcTrk 1)) (int nDestChan 0) (int nDestPort 1) (int nNote 0) (int bEvent FALSE) (getInt nSrcTrk "Source Track?" 1 256) (-- nSrcTrk) ; CAL uses 0..255 (getInt nDestTrk "First Destination Track?" 1 256) (-- nDestTrk) ; CAL uses 0..255 (getInt nDestChan "Destination Channel?" 0 16) (-- nDestChan) ; CAL uses -1..15 (getInt nDestPort "Destination Port?" 1 16) (-- nDestPort) ; 0 .. 15 ; If markers not set, select entire range (if (== From Thru) (do (= From 0) (= Thru End) ) ) ; Select only source track (TrackSelect 0 -1) (TrackSelect 1 nSrcTrk) ; Set filter params. Split notes only .. ; Controllers stay in source track. (ResetFilter 0 TRUE) (SetFilterKind 0 NOTE TRUE) (SetFilterKind 0 KEYAFT FALSE) (SetFilterKind 0 CONTROL FALSE) (SetFilterKind 0 PATCH FALSE) (SetFilterKind 0 CHANAFT FALSE) (SetFilterKind 0 WHEEL FALSE) (while (< nNote 127) (do ; Check for note events at current note # ... (forEachEvent (if (&& (== Event.Kind NOTE) (== Note.Key nNote)) (= bEvent TRUE) ) ) ; If there are note events, paste them to the destination track (if (== bEvent TRUE) (do ; Status message (message "Note # " nNote " --> Track " (+ 1 nDestTrk)) ; Set up filter .. item 0, NOTE, in the range nNote..nNote (SetFilterRange 0 0 TRUE nNote nNote) ; Cut/Paste the filtered events to the destintation track (EditCut From Thru TRUE TRUE FALSE FALSE FALSE FALSE) (EditPasteToTrack From 1 1 TRUE FALSE FALSE FALSE nDestTrk) ; Name dest track (= nOctave (/ nNote 12)) (switch (% nNote 12) 0 (TrackName (format "Split Note C" nOctave) nDestTrk) 1 (TrackName (format "Split Note C#" nOctave) nDestTrk) 2 (TrackName (format "Split Note D" nOctave) nDestTrk) 3 (TrackName (format "Split Note D#" nOctave) nDestTrk) 4 (TrackName (format "Split Note E" nOctave) nDestTrk) 5 (TrackName (format "Split Note F" nOctave) nDestTrk) 6 (TrackName (format "Split Note F#" nOctave) nDestTrk) 7 (TrackName (format "Split Note G" nOctave) nDestTrk) 8 (TrackName (format "Split Note G#" nOctave) nDestTrk) 9 (TrackName (format "Split Note A" nOctave) nDestTrk) 10 (TrackName (format "Split Note A#" nOctave) nDestTrk) 11 (TrackName (format "Split Note B" nOctave) nDestTrk) ) ; Set forced channel & port, and unmute it (TrackChannel nDestChan nDestTrk) (TrackPort nDestPort nDestTrk) (TrackActive TRUE nDestTrk) (++ nDestTrk) (= bEvent FALSE) ) ) ; Else (++ nNote) ) ) ) Greetz;) Bassman. Split Note to Tracks.cal
Matthew Mahler Posted 1 hour ago Posted 1 hour ago (edited) I had ChatGPT help me write this CAL script to convert drum loop MIDI files from the general midi (GM) map to the addictive drums 2 (AD2). I hope it helps anyone else looking to do the same thing. Here is the code in case you want to see it. ; GM_to_AD2_if_chain.cal ; Minimal GM -> AD2 remapper using core CAL syntax only. (do ; --- duplicate-collision tracker for 1-tick nudge (optional) --- (int lastTime) (int lastNote) (int lastChan) lastTime -999999) lastNote -1) lastChan -1) (forEachEvent (if (== Event.Kind NOTE) (do ; ---- REMAP CHAIN ---- Note.Key (if (== Note.Key 46) 54 ; Open Hi-Hat (if (== Note.Key 42) 49 ; Closed Hi-Hat (if (== Note.Key 44) 48 ; Pedal Hi-Hat (if (== Note.Key 36) 36 ; Kick (if (== Note.Key 38) 38 ; Snare (center) - unchanged (if (== Note.Key 37) 42 ; Rimshot / SideStick (if (== Note.Key 40) 41 ; Snare (rim) (if (== Note.Key 48) 71 ; Tom 1 (High) (if (== Note.Key 47) 69 ; Tom 2 (if (== Note.Key 45) 67 ; Tom 3 (Low) (if (== Note.Key 43) 65 ; Tom 4 (Floor) (if (== Note.Key 49) 77 ; Crash 1 (if (== Note.Key 57) 79 ; Crash 2 (if (== Note.Key 55) 81 ; Splash (if (== Note.Key 52) 89 ; China (if (== Note.Key 51) 60 ; Ride (if (== Note.Key 59) 84 ; Ride 2 (if (== Note.Key 53) 61 ; Ride Bell (if (== Note.Key 39) 41 ; Hand Clap Note.Key ; else: leave unchanged ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ; ---- 1-tick nudge if exact duplicate lands on same tick & channel ---- (if (== Event.Time lastTime) (if (== Note.Key lastNote) (if (== Event.Chan lastChan) Event.Time (+ Event.Time 1)) ) ) ) lastTime Event.Time) lastNote Note.Key) lastChan Event.Chan) ) ) ) ) Drums GM to AD2.CAL Edited 56 minutes ago by Matthew Mahler
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now