DctSys Posted January 16, 2023 Share Posted January 16, 2023 Simple but handy script for MainStage: Play a note/chord or arpeggio and it holds all the notes until you play the next group of notes. It effectively automates the way a piano player might use the Sustain pedal. Play a chord in this layer then play something in a different layer while the original chord sustains. There's one parameter - the gap (in beats) that's needed between notes so that the new note is considered a new group, and cuts off all the old notes. //----------------------------------------------------------------------------- // Auto Hold //----------------------------------------------------------------------------- var NeedsTimingInfo = true; var activeNotes = []; var then=0; function HandleMIDI(event) { if (event instanceof NoteOn) { var now = event.beatPos; if(now-then>GetParameter("Cluster Duration")) { for(i=0;i<activeNotes.length;i++) { var off = new NoteOff(activeNotes); //Trace(off); off.send(); } activeNotes=[]; } // add note to array activeNotes.push(event); //Trace(event); event.send(); then=now; } else if (event instanceof NoteOff) { //Ignore Note Off's } // pass non-note events through else { event.send(); } } //----------------------------------------------------------------------------- var PluginParameters = [ {name:"Cluster Duration", type:"log", minValue:0.25, maxValue:4, numberOfSteps:4, defaultValue:1}, ]; 1 Quote Link to comment Share on other sites More sharing options...
David Nahmani Posted January 17, 2023 Share Posted January 17, 2023 Thanks a lot for sharing your script, that sounds like a great tool, however I wasn't able to make it work in Logic Pro? It sustains every chord but doesn't stop them from sounding when I play a new chord. Quote Link to comment Share on other sites More sharing options...
DctSys Posted January 17, 2023 Author Share Posted January 17, 2023 I don't have logic to test in, and MainStage is obviously different in a few subtle ways, but did you have a clock running - either record or playback? Without a clock then all the notes are arriving at the "same" time, so will all just get added. There needs to be a full beat between the last note of a group and the start of the next group and obviously that can't happen if there are no beats. Quote Link to comment Share on other sites More sharing options...
gacki Posted January 17, 2023 Share Posted January 17, 2023 It always sends the same Note Off for me: E6 with velocity 100 - regardless of they keys that were pressed before... Quote Link to comment Share on other sites More sharing options...
David Nahmani Posted January 18, 2023 Share Posted January 18, 2023 15 hours ago, DctSys said: did you have a clock running - either record or playback? Yes, I tried both recording and playing. 9 hours ago, gacki said: It always sends the same Note Off for me: E6 with velocity 100 - regardless of they keys that were pressed before... Interesting: I don't get any Note Off events here? Quote Link to comment Share on other sites More sharing options...
DctSys Posted January 18, 2023 Author Share Posted January 18, 2023 That is odd... The trace() you oncommented should only see noteOn's. That's where its picked up a new note and added it to the list of currently playing notes. NoteOff's should appear if you uncomment line 17. That's not working somehow. That's where a new chord has been detected and its clearing the old one. You could also add a Trace(event); after line 14. That's the interesting on as that's where a NoteOn which SHOULD trigger noteOff's has been detected. I checked the Logic Doc's for the timing stuff fin Logic and its identical to MainStage... weird. 1 Quote Link to comment Share on other sites More sharing options...
gacki Posted January 19, 2023 Share Posted January 19, 2023 Some debugging. This function doesn't work: var off = new NoteOff(activeNotes); Here's my trace: Trace(activeNotes); var off = new NoteOff(activeNotes); Trace(off); I'm running the script, pressing a single key (C4) and then after a while a second key (A3): [NoteOn channel:1 pitch:72 [C4] velocity:88] [NoteOff channel:1 pitch:100 [E6] velocity:0] activeNotes correctly gives me the last pressed note, but off always contains the E6 instead. Digging further down shows that generating a simple NoteOff also results in the E6; so this is just the default. Simply using activeNotes to generate a NoteOff fails; one needs to address the elements explicitely. The following modified function works for me: for(i=0;i<activeNotes.length;i++) { var off = new NoteOff; off.pitch = activeNotes[i].pitch; //Trace(off); off.send(); } This is verified to work in Mainstage 3.5.3 and in Logic 10.6.3. Auto Hold debug.pst 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.