A technical support community for Apple Logic Pro users.

 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Keyswitches

Sat May 01, 2021 10:36 am

here is an example script that is able to also send CC switches...

function HandleMIDI(event) {

    if( ! (event instanceof NoteOn) ) {
        event.send();
        return;
    }

    if(event.articulationID == undefined
            || event.articulationID < 1) {
        event.send();
        return;
    }
   
    switch(event.articulationID) {
    case 1:
        Staccato(event);
        break;
    case 2:
        Legato(event);
        break;
    case 3:
        Spiccato(event);
        break;
    default:
        event.send();
    }
}



function Staccato(event) {
    sendSwitch("C-2", event);
    sendSwitch("D0", event);
    sendCC(58, 13, event);
    sendSwitch("D#0", event);
    sendSwitch("D#1", event); 
   
    event.send();
}

function Spiccato(event) {
    sendSwitch("C-2", event);
    sendSwitch("D0", event);
    sendSwitch("D1", event);
    sendSwitch("C-1", event);
    sendSwitch("D#0", event);
    sendSwitch("D#2", event); 
   
    event.send();
}

function Legato(event) {
    sendSwitch("C-2", event);
    sendSwitch("D0", event);
    sendSwitch("D1", event);
    sendSwitch("C-1", event);
    sendSwitch("D#0", event);
    sendSwitch("D#3", event); 
   
    event.send();
}

var ks = new NoteOn;

function sendSwitch(ksName, ev) {
    ks.channel = ev.channel;
    ks.pitch = MIDI.noteNumber(ksName);
    ks.velocity = 100;
    ks.send();
    ks.velocity = 0;
    ks.send();
}

var cc = new ControlChange;

function sendCC(num, val, event) {
    cc.number = num;
    cc.value = val;
    cc.channel = event.channel;
    cc.send();
}


That is accomplished by simply adding a sendCC function like this:

var cc = new ControlChange;

function sendCC(num, val, event) {
    cc.number = num;
    cc.value = val;
    cc.channel = event.channel;
    cc.send();
}
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Keyswitches

Sat May 01, 2021 10:44 am

here is an example Script where the keyswitches are only sent when the articulationID changes since the last note (on the same channel):


var lastArtID = new Array(17);
for (let chan=1; chan<=16; chan++) {
    lastArtID[chan] = 0;
}


function HandleMIDI(event) {

    if( ! (event instanceof NoteOn) ) {
        event.send();
        return;
    }

    if(event.articulationID == undefined
            || event.articulationID < 1) {
        lastArtID[event.channel = 0];
        event.send();
        return;
    }
   
   
    if(event.articulationID == lastArtID[event.channel]) {
        event.send();
        return;
    }
   
    lastArtID[event.channel] = event.articulationID;
   
   
    switch(event.articulationID) {
    case 1:
        Staccato(event);
        break;
    case 2:
        Legato(event);
        break;
    case 3:
        Spiccato(event);
        break;
    default:
        event.send();
    }
}



function Staccato(event) {
    sendSwitch("C-2", event);
    sendSwitch("D0", event);
    sendCC(58, 13, event);
    sendSwitch("D#0", event);
    sendSwitch("D#1", event); 
   
    event.send();
}

function Spiccato(event) {
    sendSwitch("C-2", event);
    sendSwitch("D0", event);
    sendSwitch("D1", event);
    sendSwitch("C-1", event);
    sendSwitch("D#0", event);
    sendSwitch("D#2", event); 
   
    event.send();
}

function Legato(event) {
    sendSwitch("C-2", event);
    sendSwitch("D0", event);
    sendSwitch("D1", event);
    sendSwitch("C-1", event);
    sendSwitch("D#0", event);
    sendSwitch("D#3", event); 
   
    event.send();
}

var ks = new NoteOn;

function sendSwitch(ksName, ev) {
    ks.channel = ev.channel;
    ks.pitch = MIDI.noteNumber(ksName);
    ks.velocity = 100;
    ks.send();
    ks.velocity = 0;
    ks.send();
}

var cc = new ControlChange;

function sendCC(num, val, event) {
    cc.number = num;
    cc.value = val;
    cc.channel = event.channel;
    cc.send();
}


One other comment to make is that LogicPro articulation set behavior for handling notes without articulationID is to play the keyswitches found (if found at all) in the first item of the articulationSet list. This hidden behavior is often not desired, in fact I usually make sure to program my Articulation Set so that the first item on the list is a dummy entry with no keyswitches to make sure. In any case, whatever you desired behavior is, you may have to modify any of these example scripts accordingly to handle that specific situation exactly as you desire.
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Keyswitches

Sat May 01, 2021 10:47 am

-
Last edited by Dewdman42 on Sun May 02, 2021 1:22 pm, edited 1 time in total.
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Keyswitches

Sun May 02, 2021 1:18 pm

While we're on this topic I'd like to mention another approach with Scripter, which is not as easy to "understand" as the example given in the OP, but in some ways easier to reuse once you have it.

Consider this example:


// Define KS array
var KS = [];

// array index represents articulationID
KS[1] = ["C-1","D-1","C0"];        // sustain
KS[2] = ["C#0","D#0","E0","F0"];   // staccato
// etc


/***************************************************
 ************** DO NOT EDIT BELOW HERE *************
 ***************************************************/
 
var lastArtID = new Array(17);
for( let chan=1; chan<=16; chan++) {
    lastArtID[chan] = 0;
}

var ks = new NoteOn;

function HandleMIDI(event) {

    // Everything other then NoteOn
    if( !(event instanceof NoteOn)) {
        event.send();
        return;
    }
   
    // default articulationID
    if(event.articulationID == undefined) {
        event.articulationID = 0;
    }
   
    // Track last articulationID
    let last = lastArtID[event.channel];
    lastArtID[event.channel] = event.articulationID;
   
    // If same artID as last note, skip keyswitching
    if(event.articulationID == last
            || KS[event.articulationID] == undefined) {
           
        event.send();
        return;
    }
   
    // send keyswitches
    let ksList = KS[event.articulationID];
    for(let k=0; k<ksList.length; k++) {
        sendSwitch(ksList[k], event);
    }
     
    // send actual note   
    event.send();

}

// Function to send a single keyswitch

var ks = new NoteOn;
function sendSwitch(pitchName, evt) {
        ks.pitch = MIDI.noteNumber(pitchName);
        ks.channel = evt.channel;
        ks.velocity = 100;
        ks.send();
        ks.velocity = 0;
        ks.send();   
}


In the above example you can just modify the array entries at the top of the script for the keyswitches you want. Easy. the rest of the script can just be copy and pasted to work for any use case.

Here is a slightly more complex version that also supports intermixing Keyswitches and CC switches for those of you that insist you need CC switches or simply want to learn more about scripting:


// Define KS array
var KS = [];

// array index represents articulationID
KS[1] = ["C-1","D-1","C0"];        // sustain
KS[2] = ["C#0","D#0","E0","F0"];   // staccato
KS[3] = ["C0",[58,5]];             // use case with CC58=5
// etc


/***************************************************
 ************** DO NOT EDIT BELOW HERE *************
 ***************************************************/
 
var lastArtID = new Array(17);
for( let chan=1; chan<=16; chan++) {
    lastArtID[chan] = 0;
}

function HandleMIDI(event) {

    // Everything other then NoteOn
    if( !(event instanceof NoteOn)) {
        event.send();
        return;
    }
   
    // default articulationID
    if(event.articulationID == undefined) {
        event.articulationID = 0;
    }
   
    // Track last articulationID
    let last = lastArtID[event.channel];
    lastArtID[event.channel] = event.articulationID;
   
    // If same artID as last note, skip keyswitching
    if(event.articulationID == last
            || KS[event.articulationID] == undefined) {
           
        event.send();
        return;
    }
   
    // send keyswitches
    let ksList = KS[event.articulationID];
    for(let k=0; k<ksList.length; k++) {
   
        if(Array.isArray(ksList[k])) {
            sendCC(ksList[k], event);
        }
        else {
            sendSwitch(ksList[k], event);
        }
    }
     
    // send actual note   
    event.send();
}

// Function to send a single keyswitch

var ks = new NoteOn;
function sendSwitch(pitchName, evt) {
        ks.pitch = MIDI.noteNumber(pitchName);
        ks.channel = evt.channel;
        ks.velocity = 100;
        ks.send();
        ks.velocity = 0;
        ks.send();   
}

// Function to send a single CC switch

var cc = new ControlChange;
function sendCC(ccArray, evt) {
    cc.number = ccArray[0];
    cc.value = ccArray[1];
    cc.channel = evt.channel;
    cc.send();
}
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Keyswitches

Sun May 02, 2021 1:21 pm

Sending Keyswitches by Automation

Another interesting way to send keyswitches from Scripter is to use automation points instead of articulationID. This is sometimes preferable because you can see a graph with labels on an automation lane showing the articulations in effect.

artlane.jpg
artlane.jpg (51.09 KiB) Viewed 1473 times


Here is a simple example script doing something like that. This example is considerably more complicated then the above example, but it may get you started...

var articulation = [];

articulation[1] =  {word:"Articulation 1",  pitch:"C0"};
articulation[2] =  {word:"Articulation 2",  pitch:"C#0"};
articulation[3] =  {word:"Articulation 3",  pitch:"D0"};
articulation[4] =  {word:"Articulation 4",  pitch:"D#0"};
articulation[5] =  {word:"Articulation 5",  pitch:"E0"};
articulation[6] =  {word:"Articulation 6",  pitch:"F0"};
articulation[7] =  {word:"Articulation 7",  pitch:"F#0"};
articulation[8] =  {word:"Articulation 8",  pitch:"G0"};
articulation[9] =  {word:"Articulation 9",  pitch:"G#0"};
articulation[10] = {word:"Articulation 10", pitch:"A0"};

var VELOCITY=1;

/***************************************************************
 ***************** DO NOT EDIT BELOW HERE **********************
 ***************************************************************/


function HandleMIDI(event) {
    event.ksSend();   
}
Event.prototype.ksSend = function() {
    this.send();
};
NoteOn.prototype.ksSend = function() {
    SwitchMap.send(this);
};

var wordFlg=-1;

/*************************************************
 * Setup SwitchMap object with pre-created
 * events based on the user provided articulation
 * array
 *************************************************/

var SwitchMap = {map:[]};

/*************************************************
 * send function that will be called for all
 * NoteOn events to potenetially send keyswitches
 ***/
SwitchMap.send = function (event) {

    if( wordFlg >= 0 ) {
   
        var node = this.map[wordFlg];
   
        // If switches are defined, send them
        if(node != undefined) {
            for(var s=0;s<node.length;s++) {
                var e = node[s];
                e.channel = event.channel;
                e.port = event.port;
                e.send();
            }
        }
       
        wordFlg = -1;
    }
   
    // Send main note event
    event.send();
};

/***********************************************
 * init function to load up the switches defined
 * in articulation[] array, preallocate events
 ***/
SwitchMap.init = function() {

    this.map = [];
    for (var a = 1; a < articulation.length; a++) {
        var userArt = articulation[a];
        if (userArt != undefined) {       
            this.configure(a, userArt);
        }
    }
};

/**********************************************
 * use this function to configure each
 * user provided entry
 **/
SwitchMap.configure = function(artid, ksconfig) {
   
        // make sure wrapped by array
        if(this.map[artid] == undefined) this.map[artid] = [];
       
        var on = new NoteOn;
        if(typeof ksconfig.pitch == "string") {
            on.pitch = MIDI.noteNumber(ksconfig.pitch);
        }
        else {
            on.pitch = ksconfig.pitch;
        }
       
        if(ksconfig.velocity == undefined) {
            on.velocity = VELOCITY;
        }
        else {
            on.velocity = ksconfig.velocity;
        }
        this.map[artid].push(on);
       
        var off = new NoteOff;
        off.pitch = on.pitch;
        off.velocity = on.velocity;
        this.map[artid].push(off);   
 };

/************************************************
 * Callback called by LogicPro at the right time
 ***/
function Initialize() {
    SwitchMap.init();
}


function ParameterChanged(id, val) {
    if(id==0) {
        wordFlg=val;
    }
}
 
// build words array for automation
var words = ["Reset"];
for(var i=1;i<articulation.length;i++) {
    words.push(articulation[i].word);
}

var PluginParameters = [];
PluginParameters.push({
    type: "menu",
    name: "Your Articulation Lane",
    defaultValue: 0,
    hidden: true,
    disableAutomation: false,
    valueStrings: words
});
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
User avatar
D4rkKn1ght
Posts: 5
Joined: Fri Apr 30, 2021 6:01 pm

Re: TIP: Scripter Keyswitches

Thu May 27, 2021 9:05 pm

Hey Dewdman42 - I just want to really thank you for this. Not many replies on here, but this is SUPER useful and saved me. Basically I didn't think ahead before buying my first VSL instrument (Synchron Strings Pro) and then realised, "wait a minute, how can I build Articulation Sets for this when it has more than 3 required Keyswitches for some of the articulations?"

So this semi tutorial really saved me. I didn't/don't want to (at least not yet) go the X-DAW route. I've only just done some preliminary tests modifying your first example and it seems to be working for me.

I'll come back with any questions if I run into any problems and hopefully you can educate me further. But thanks again!

P.S. If I did want to do some reading to understand the code you've used in your first example better - as in to actually understand more of what's going on there, can you point me somewhere I can do that?
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Scripter Keyswitches

Thu May 27, 2021 10:28 pm

There is not much information out there about scripter other then what is in the logicpro effects manual (from the help menu) start there. Feel free to ask questions here or start a thread with general questions about scripter on the forum, some others May chime in too. Glad it’s helpful!
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
ravez
Posts: 4
Joined: Mon May 24, 2021 2:07 pm

Re: TIP: Keyswitches

Mon May 31, 2021 2:31 pm

Dewdman42 wrote:
Sending Keyswitches by Automation

Another interesting way to send keyswitches from Scripter is to use automation points instead of articulationID. This is sometimes preferable because you can see a graph with labels on an automation lane showing the articulations in effect.

artlane.jpg

Here is a simple example script doing something like that. This example is considerably more complicated then the above example, but it may get you started...

var articulation = [];

articulation[1] =  {word:"Articulation 1",  pitch:"C0"};
articulation[2] =  {word:"Articulation 2",  pitch:"C#0"};
articulation[3] =  {word:"Articulation 3",  pitch:"D0"};
articulation[4] =  {word:"Articulation 4",  pitch:"D#0"};
articulation[5] =  {word:"Articulation 5",  pitch:"E0"};
articulation[6] =  {word:"Articulation 6",  pitch:"F0"};
articulation[7] =  {word:"Articulation 7",  pitch:"F#0"};
articulation[8] =  {word:"Articulation 8",  pitch:"G0"};
articulation[9] =  {word:"Articulation 9",  pitch:"G#0"};
articulation[10] = {word:"Articulation 10", pitch:"A0"};

var VELOCITY=1;

/***************************************************************
 ***************** DO NOT EDIT BELOW HERE **********************
 ***************************************************************/


function HandleMIDI(event) {
    event.ksSend();   
}
Event.prototype.ksSend = function() {
    this.send();
};
NoteOn.prototype.ksSend = function() {
    SwitchMap.send(this);
};

var wordFlg=-1;

/*************************************************
 * Setup SwitchMap object with pre-created
 * events based on the user provided articulation
 * array
 *************************************************/

var SwitchMap = {map:[]};

/*************************************************
 * send function that will be called for all
 * NoteOn events to potenetially send keyswitches
 ***/
SwitchMap.send = function (event) {

    if( wordFlg >= 0 ) {
   
        var node = this.map[wordFlg];
   
        // If switches are defined, send them
        if(node != undefined) {
            for(var s=0;s<node.length;s++) {
                var e = node[s];
                e.channel = event.channel;
                e.port = event.port;
                e.send();
            }
        }
       
        wordFlg = -1;
    }
   
    // Send main note event
    event.send();
};

/***********************************************
 * init function to load up the switches defined
 * in articulation[] array, preallocate events
 ***/
SwitchMap.init = function() {

    this.map = [];
    for (var a = 1; a < articulation.length; a++) {
        var userArt = articulation[a];
        if (userArt != undefined) {       
            this.configure(a, userArt);
        }
    }
};

/**********************************************
 * use this function to configure each
 * user provided entry
 **/
SwitchMap.configure = function(artid, ksconfig) {
   
        // make sure wrapped by array
        if(this.map[artid] == undefined) this.map[artid] = [];
       
        var on = new NoteOn;
        if(typeof ksconfig.pitch == "string") {
            on.pitch = MIDI.noteNumber(ksconfig.pitch);
        }
        else {
            on.pitch = ksconfig.pitch;
        }
       
        if(ksconfig.velocity == undefined) {
            on.velocity = VELOCITY;
        }
        else {
            on.velocity = ksconfig.velocity;
        }
        this.map[artid].push(on);
       
        var off = new NoteOff;
        off.pitch = on.pitch;
        off.velocity = on.velocity;
        this.map[artid].push(off);   
 };

/************************************************
 * Callback called by LogicPro at the right time
 ***/
function Initialize() {
    SwitchMap.init();
}


function ParameterChanged(id, val) {
    if(id==0) {
        wordFlg=val;
    }
}
 
// build words array for automation
var words = ["Reset"];
for(var i=1;i<articulation.length;i++) {
    words.push(articulation[i].word);
}

var PluginParameters = [];
PluginParameters.push({
    type: "menu",
    name: "Your Articulation Lane",
    defaultValue: 0,
    hidden: true,
    disableAutomation: false,
    valueStrings: words
});


hi, i tried this and it works, but couldn't get multiple keyswitches per articulation to work, like for example in Synchron player when you have different dimesions so you need to send a C0 and C#1 to activate a cell. What would be the correct syntax to get that to work? i tried:
articulation[1] =  {word:"Articulation 1",  pitch:["C0","C#1"]}; 

but doesn't work
thanks
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Scripter Keyswitches

Mon May 31, 2021 2:37 pm

Guess I have to improve the script a little bit to support multiple keyswitches from automation....let me try that, hang on...
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Scripter Keyswitches

Mon May 31, 2021 3:15 pm

Try this one, I made it more simple to understand as well, though technically speaking slightly less efficient but not enough to be worried about:

/**************************************************************
 * Example Script that convert automation lane to keyswitches
 *
 * Note this example only works for a single midi channel,
 * Otherwise seperate automation lanes will need to be defined
 * for each midi channel in the articulation[] array
 **************************************************************/

var articulation = [];

// Array of keyswiches per articulation

articulation[1] =  {word:"Articulation 1",  ks:["C0","C1"]};
articulation[2] =  {word:"Articulation 2",  ks:["C#0",[58,5]]};
articulation[3] =  {word:"Articulation 3",  ks:["D0"]};
articulation[4] =  {word:"Articulation 4",  ks:["D#0"]};
articulation[5] =  {word:"Articulation 5",  ks:["E0"]};
articulation[6] =  {word:"Articulation 6",  ks:["F0"]};
articulation[7] =  {word:"Articulation 7",  ks:["F#0"]};
articulation[8] =  {word:"Articulation 8",  ks:["G0"]};
articulation[9] =  {word:"Articulation 9",  ks:["G#0"]};
articulation[10] = {word:"Articulation 10", ks:["A0"]};

/***************************************************************
 ***************** DO NOT EDIT BELOW HERE **********************
 ***************************************************************/

var lastArtID = -1;
var currentArtID = -1;

function HandleMIDI(event) {

    // Everything other then NoteOn
    if( !(event instanceof NoteOn)) {
        event.send();
        return;
    }
     
    // If same artID as last note, skip keyswitching
    if(currentArtID == lastArtID
            || articulation[currentArtID] == undefined
            || articulation[currentArtID].ks == undefined) {
           
        event.send();
        return;
    }
   
    // remember new artID
    lastArtID = currentArtID;
   
    // send keyswitches
    let ksList = articulation[currentArtID].ks;
   
    for(let k=0; k<ksList.length; k++) {
   
        if(Array.isArray(ksList[k])) {
            sendCC(ksList[k], event);
        }
        else {
            sendSwitch(ksList[k], event);
        }
    }
     
    // send actual note   
    event.send();
}

// Function to send a single keyswitch

var ks = new NoteOn;
function sendSwitch(pitchName, evt) {
        ks.pitch = MIDI.noteNumber(pitchName);
        ks.channel = evt.channel;
        ks.velocity = 100;
        ks.send();
        ks.velocity = 0;
        ks.send();   
}

// Function to send a single CC switch

var cc = new ControlChange;
function sendCC(ccArray, evt) {
    cc.number = ccArray[0];
    cc.value = ccArray[1];
    cc.channel = evt.channel;
    cc.send();
}

function ParameterChanged(id, val) {
    if(id==0) {
        currentArtID=val;
    }
}
 
 
// build words array for automation
var words = ["Reset"];
for(var i=1;i<articulation.length;i++) {
    words.push(articulation[i].word);
}

var PluginParameters = [];
PluginParameters.push({
    type: "menu",
    name: "Your Articulation Lane",
    defaultValue: 0,
    hidden: true,
    disableAutomation: false,
    valueStrings: words
});
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
ravez
Posts: 4
Joined: Mon May 24, 2021 2:07 pm

Re: TIP: Scripter Keyswitches

Mon May 31, 2021 3:21 pm

Amazing :D that works, thanks!
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Scripter Keyswitches

Mon May 31, 2021 3:23 pm

Another comment I want to make as a general heads up:

These scripts send NoteOn keyswitches followed immediately by the corresponding NoteOff.


This is slightly different then the way ArticulationSet's work. When you use the ArticulationSet to send keyswitches:

The NoteOff is not sent until a new articulationID is encountered, it leaves the NoteOn hanging open until then.


In theory, this only matters for instruments which pay attention to that aspect, which most sample instruments do not. Most sample instruments simply listen for the NoteOn of a keyswitch, which triggers an articulation and that's it. the NoteOff could come immediately now, or much later and it won't matter. But indeed there are occasionally some libraries which keep track of which keyswitches are currently "open", meaning the NoteOn has turned on a certain feature and as long as that keyswitch note is held down and sustaining, the feature is activated until the keyswitch note is released. In that case, these scripts will not currently work...but ArticulationSet's work that way.

I don't believe most of you will need to do anything about this, but if you are using one of those instruments that uses held keyswitches for some purpose, then these scripts (so far) are not for you.

It is possible to script things to be more like ArticulationSet's, but introduces more complexity that I am specifically trying to leave out for the sake of learning.
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram
 
User avatar
D4rkKn1ght
Posts: 5
Joined: Fri Apr 30, 2021 6:01 pm

Re: TIP: Scripter Keyswitches

Mon Jun 07, 2021 5:27 pm

Hey Dewdman42. Could you please speak a bit more about the default behaviour of an instrument when no articulation is selected in an articulation set? You briefly spoke about it above - setting a dummy first entry in the art. set without any keyswitches. I thought I knew what you meant and tried that, but it didn't work for me. I would actually get no sound. Testing this with Synchron Player by the way.

As you know, when an art. set is chosen for a particular track/instrument, it has a little drop-down menu added to its GUI window too. So in my art. set I made my first articulation an empty one called Dummy, adding no other details to it. No keyswitches etc. So then when I have Synchron Player open, the dropdown at the top is set to 'Dummy' by default, but as I click through the available articulations in the GUI to audition them and play around and see what I like, there is no sound. Without the dummy entry, there is sound, but as you say, it defaults to the first articulation in the art. set. Even if you choose a different articulation from that dropdown menu, it's basically forcing you to use your art. set to hear any of the articulations and if you haven't made entries for all the articulations (for Synchron Strings it would be a massive task that I don't want to do) - then you're out of luck.

Any light you can shed on this? Any ways around it?
 
User avatar
Dewdman42
Topic Author
Posts: 3276
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: TIP: Scripter Keyswitches

Mon Jun 07, 2021 5:32 pm

are you talking about the behavior of the articulation set or the behavior of the scripts on this thread?

but articulation sets do end up sending the first articulation OUTPUT section if no articulation is present in the note. You should be hearing something, so maybe share a project to show what you mean.

The Scripts above, which are instead of the output section of articulation set....do work slightly differently as of now. If no articulationID is present on a note, it is assumed to be zero. ifs you don't have keyswitches defined for articulation zero, then it will just send the note itself with no keyswitching...which means it will continue with whatever articulation is currently in effect.
OSX 10.15 (Catalina) on OpenCore - Logic Pro 10.6.1, VePro7, Mainstage3
5,1 MacPro 3.46ghz x 12 128gb ram