Jump to content

Script: Auto Hold/Sustain


Recommended Posts

 

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},
     
];

 

  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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? 

Screen Shot 2023-01-18 at 10.34.52 AM.png

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...