A technical support community for Apple Logic Pro users.

 
michaelrasbury
Topic Author
Posts: 22
Joined: Mon Oct 12, 2020 11:36 am

Scripter- Humanize Notation Program Quantized Note Length

Tue Feb 09, 2021 4:18 am

Can someone create a simple and clear script for Logic’s Scripter that does the following if even possible?

The script will assume that MIDI notes have been imported from a notation program or all note lengths has been quantized so all note values have perfectly quantized lengths (like MIDI looks exported from Finale.)

It will rely on a Logic Articulation Set that has at a minimum the following articulations:

No. Articulation
1 Sustain
2 Legato
3 Marcato
4 Staccato
5 Staccatissimo
6 Tenuto


-If the articulation is marked Legato it will sound a 5% longer MIDI note or 105% of the original length MIDI note to the instrument.

-If the articulation is marked Marcato it will sound a 15% shorter MIDI note or 85% of the original length MIDI note to the instrument.

-If the articulation is marked Staccato it will sound a 50% shorter MIDI note or 50% of the original length MIDI note to the instrument.

-If the articulation is marked Staccatissimo it will sound a 75% shorter MIDI note or 25% of the original length MIDI note to the instrument.

-If the articulation is marked Tenuto it will sound a 5% shorter MIDI note or 95% of the original length MIDI note to the instrument.

-All other notes of any other articulation or without articulations will sound a 15% shorter MIDI note or 85% of the original length MIDI note.
 
User avatar
Atlas007
Posts: 9502
Joined: Mon Dec 14, 2009 11:58 pm
Location: Montreal

Re: Scripter- Humanize Notation Program Quantized Note Length

Tue Feb 09, 2021 10:17 pm

Possible, I'd say yes.
Simple, I doubt...
LogicPro 10.6.1 ( & 9.1.8),MainStage3.5.1
MBPro 17", Core2Duo, 8G, OSX 10.12.6
MacPro, Xeon 6Cores, 64GB, OSX 10.15.7
ULN8, MOTU MIDI TP-AV, C4, MCU Pro, KorgNano, Novation SLMkII
AAS, NI, Celemony, Spectrasonics, Korg, etc...
PC, iPad3(V-Control & LogicRemote), AtariST(Notator SL), Several vintage gear
 
ValliSoftware
Posts: 891
Joined: Mon May 19, 2014 10:46 am

Re: Scripter- Humanize Notation Program Quantized Note Length

Wed Feb 10, 2021 9:51 pm

michaelrasbury wrote:
Can someone create a simple and clear script for Logic’s Scripter that does the following if even possible?

The script will assume that MIDI notes have been imported from a notation program or all note lengths has been quantized so all note values have perfectly quantized lengths (like MIDI looks exported from Finale.)

It will rely on a Logic Articulation Set that has at a minimum the following articulations:

No. Articulation
1 Sustain
2 Legato
3 Marcato
4 Staccato
5 Staccatissimo
6 Tenuto


-If the articulation is marked Legato it will sound a 5% longer MIDI note or 105% of the original length MIDI note to the instrument.

-If the articulation is marked Marcato it will sound a 15% shorter MIDI note or 85% of the original length MIDI note to the instrument.

-If the articulation is marked Staccato it will sound a 50% shorter MIDI note or 50% of the original length MIDI note to the instrument.

-If the articulation is marked Staccatissimo it will sound a 75% shorter MIDI note or 25% of the original length MIDI note to the instrument.

-If the articulation is marked Tenuto it will sound a 5% shorter MIDI note or 95% of the original length MIDI note to the instrument.

-All other notes of any other articulation or without articulations will sound a 15% shorter MIDI note or 85% of the original length MIDI note.

Scripter.png
Scripter.png (22.64 KiB) Viewed 1245 times

In Scripter you get events as they happen. For your request on changing the note length depending on a articulation that was set before hand, this isn't possible in Scripter for shorten the length.
Notice that you get NoteOn-NoteOff pairs. When you subtract the NoteOff-NoteOn positions, you get the length but the only problem is the note has already played at least the length of the NoteOff until you send the NoteOff then it stops. the only thing you can do is make the note longer, not shorter.

CoreMidi.png
CoreMidi.png (132.43 KiB) Viewed 1245 times

If you look at CoreMidi, you get two events and the starting position and the duration of the note is in a single event. Once you receive a CoreMidi event you'll have the length then you can readjust the duration to the desired length based the articulation you've set before hand, either shorter or longer.
Using CoreMidi requires a Objective-C or Swift application to be written.
MacBook Pro 10.8.5 2.2 GHz Intel Core 2 Duo 6GB Ram - Logic Pro X (10.2)
MacMini 10.13.6 2GHz Intel Core i7 16GB Ram - GarageBand 10.4.5 Logic Pro X (10.4.8)
iPad Mini iOS 12 - iOS GarageBand 2.0.1
Qosimo X70-A 10.13.6 Intel® Core™ i7-4700MQ Processor 32GB DDR3L 1600MHz memory, 2-500GB 7200rpm hard drives - Logic Pro X (10.4.8)
MacMini M1 11.2.3 Apple M1 16GB Ram 1TB SSD Logic Pro X (10.6.1) Rosetta 2 not installed
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 11, 2021 8:16 am

Presuming you have articulation id’s To specify how to handle for each note...

Regarding shortening notes in scripter that could only be possible using lookahead processing which is trickier to say the least, but yes could be possible. It would necessarily add a large amount of latency which you would then have to manually compensate for by using negative track delay.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
ValliSoftware
Posts: 891
Joined: Mon May 19, 2014 10:46 am

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 11, 2021 10:48 am

Dewdman42 wrote:
Presuming you have articulation id’s To specify how to handle for each note...

Regarding shortening notes in scripter that could only be possible using lookahead processing which is trickier to say the least, but yes could be possible. It would necessarily add a large amount of latency which you would then have to manually compensate for by using negative track delay.

moss.gif
moss.gif (1.96 MiB) Viewed 1210 times
MacBook Pro 10.8.5 2.2 GHz Intel Core 2 Duo 6GB Ram - Logic Pro X (10.2)
MacMini 10.13.6 2GHz Intel Core i7 16GB Ram - GarageBand 10.4.5 Logic Pro X (10.4.8)
iPad Mini iOS 12 - iOS GarageBand 2.0.1
Qosimo X70-A 10.13.6 Intel® Core™ i7-4700MQ Processor 32GB DDR3L 1600MHz memory, 2-500GB 7200rpm hard drives - Logic Pro X (10.4.8)
MacMini M1 11.2.3 Apple M1 16GB Ram 1TB SSD Logic Pro X (10.6.1) Rosetta 2 not installed
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 11, 2021 11:25 am

I will post a simple example later this afternoon
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 11, 2021 12:39 pm

Here is a very short and very simple example of using Lookahead to shorten midi notes to 50% of their original length:

var NeedsTimingInfo = true;

var LOOKAHEAD = 500;   // ms

var noteOns = [];

function HandleMIDI(event) {

    // NoteOff
    if( event instanceof NoteOff) {
   
        if(noteOns[event.pitch] == undefined) {
            // error, where was the NoteOn?
            event.sendAfterMilliseconds(LOOKAHEAD);
            return;
        }
       
        let duration = msFromBeats(event.beatPos - noteOns[event.pitch]);
        noteOns[event.pitch] = undefined;
       
        let shorten = duration * 0.50;
        let delay = LOOKAHEAD - shorten;
       
        if(delay < 0) {
            event.send();
        }
        else {   
            event.sendAfterMilliseconds(delay);
        }
    }
   
    // NoteOn
    else if (event instanceof NoteOn) {
        noteOns[event.pitch] = event.beatPos;
        event.sendAfterMilliseconds(LOOKAHEAD);   
    }
   
    // All other event types
    else {       
        event.sendAfterMilliseconds(LOOKAHEAD);   
    }
}

function msFromBeats(beats) {
    let info = GetTimingInfo();
    return Math.round( 60000 * (beats/info.tempo));
};


I intentionally kept this script as simple as possible in order to demonstrate the concept. In order to test it, set the track to -500ms negative track delay. On playback you'll hear the note durations cut in half.

Here are some challenges, some easier then others, which would probably need to be added to a robust script for this purpose:

  1. If you hit STOP exactly in between the time when the NoteOff has come in, but has not actually been played yet with the lookahead delay, then it will never get played, and there might be hanging notes. There are ways this could be handled in Scripter that I don't want to get into right now, but if you get any hanging notes..that's why.

  2. the noteOns[] array in the above example really should be a two dimensional array that tracks each midi channel separately, but if you're only using the script for one channel at a time, then it doesn't matter.

  3. if you have any notes that need to be shortened by more than 500ms, then there is not enough lookahead available to handle that situation because LogicPro track delay can only be set up to -500ms. You can alternatively use Expert Sleepers Latency Fixer, which will provide room to shorten notes by up to a second and then LatencyFixer will handle the negative track delay compensation by faking out the PDC system, it can handle up to 1sec. But really 500ms of "shortening" should be more than enough. If and when you have a note that has to be shortened by more than the lookahead amount, the above script will simply shorten it by the lookahead amount. But might run into problems shortening staccatisimo by a factor of 75% on on longer notes...

  4. This script may or may not have problems when you have overlapping notes... (ie, two note Ons of a given pitch before either of their matching NoteOff's come through). I didn't test for that, but something to watch out for that might require more complicated scripting to handle it right.
Last edited by Dewdman42 on Thu Feb 11, 2021 5:55 pm, edited 8 times in total.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 11, 2021 12:43 pm

Here's a more complete version that handles different factors per articulationID, handles lengthening the legatos too. Better check for NoteOff.

var NeedsTimingInfo = true;

var LOOKAHEAD = 500;   // ms

// articulationID based duration adjustments
var factors = [0, 1.05, 0.85, 0.50, 0.25, 0.95];

var noteOns = [];

function HandleMIDI(event) {

    // NoteOff
    if( isNoteOff(event) ) {
   
        if(noteOns[event.pitch] == undefined) {
            // error, where was the NoteOn?
            event.sendAfterMilliseconds(LOOKAHEAD);
            return;
        }
       
        let duration = msFromBeats(event.beatPos - noteOns[event.pitch]);
        noteOns[event.pitch] = undefined;
       
        let factor = 0.85;  //default
        if(event.articulationID != undefined && event.articulationID > 0
                && factors[event.articulationID] != undefined) {
            factor = factors[event.articulationID];
        }
       
        let shorten = duration * (1-factor);

        let delay = LOOKAHEAD - shorten;
       
        if(delay < 0) {
            event.send();
        }
        else {   
            event.sendAfterMilliseconds(delay);
        }
    }
   
    // NoteOn
    else if (event instanceof NoteOn) {
        noteOns[event.pitch] = event.beatPos;
        event.sendAfterMilliseconds(LOOKAHEAD);   
    }
   
    // All other event types
    else {       
        event.sendAfterMilliseconds(LOOKAHEAD);   
    }
}

function msFromBeats(beats) {
    let info = GetTimingInfo();
    return Math.round( 60000 * (beats/info.tempo));
};

function isNoteOff(event) {
    if(event instanceof NoteOff) {
        return true;
    }
    else if(event instanceof NoteOn && event.velocity < 1) {
        return true;
    }
    return false;
}



Note that for the staccatisimo articulation that is shortening the length by 75% will have problems when applied to notes of longer duration since the lookahead of 500ms may not be sufficient.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
michaelrasbury
Topic Author
Posts: 22
Joined: Mon Oct 12, 2020 11:36 am

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 5:35 am

[SoundCloud][/SoundCloud]Hey- sorry I didn't see your reply. I just tested this a various speeds with a -500ms offset and it seemed to work well EXCEPT and ironically, there doesn't seem to be an audible difference between the staccato and the staccatisimo lengths at least when listening. I think what is happening is like you said, the staccatisimo articulation can only be applied to an already short note. I assume it would need to be assigned to a note shorter than 500ms. I may try to alter this script by adding other articulations/lengths, but I'm not sure I quite understand... It looks like you set up an array of lengths, and then told the script to check for sequentially what articulation ID/number was chosen starting with "greater than zero?" I guess if I add any new articulations, they will need to be sequentially starting at ID 7 after tenuto, and then I will need to add the new lengths to the end of the array. Am I thinking correctly? Also after running some more tests, it's like the staccato and staccatissimo articulations don't work back to back. I could keep shortening the staccato time and hear it get a short as 25, I think. I'm not sure really but thought I'd share!
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 8:45 am

Yes you can add more articulation ids as needed

You could also try increasing the lookahead to more then 500ms but then you’ll need another solution for negative track delay since logicpro can only do 500ms in the track delay setting. You can use expert sleepers latency fixer to get as much as 1000ms of negative track delay and you might be able to stack those to get more. But why do you need to apply staccato to long note durations?

Please describe exactly the scenario why back to back it stopped working.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
michaelrasbury
Topic Author
Posts: 22
Joined: Mon Oct 12, 2020 11:36 am

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 10:57 am

http://michaelrasbury.org/HumanizeFinale.zip

I have dropped a zipped folder on my server that includes a Logic Project, the script, and the articulation set if you just want to open it on your end. I will also try to explain the test. I loaded sampler and used its test tone so that there is no decay at the end of the tone. I set up a four measure MIDI region. The BPM was initially at 120, but I found even speeding things up to 220 yielded the same results, although faster of course. There is a -500.0ms track delay in the drop down menu.
    The first measure has eight exact eighth notes. The first two have the staccato articulation chosen, the second two have the staccatissimo articulation, the next two go back to staccato and the final two have the staccatissimo articulation. The staccatissimo ones don't work as you thought they might not.
    The second measure is four exact quarter notes with the first two using the marcato articulation and the second two using the tenuto articulation. These seem to work as expected.
    The third measure contains four exact quarter notes alternating between adjacent pitches and use the legato articulation. These don't seem to be longer than 100 percent as I would expect to hear the two pitches overlap a little when triggering. I went back to the script and changed the length in the array from 1.05 to 1.20 and observed the notes seem to never be able to last past 1 or full length.
    The fourth measure uses two exact half notes and has the sustain articulation chosen. These sound unaltered as expected.
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 11:40 am

found a typo in the script earlier. In the array of durations, you need an entry for 100% sustains. My mistake in what I posted. So change that line to include a "1" for 100% on sustains, at the second position in the array like this:

// articulationID based duration adjustments
var factors = [0, 1, 1.05, 0.85, 0.50, 0.25, 0.95];


The first position in the array is array index 0 and articulationID=0 means no articulation ID. You could alternatively design your articulation set in such a way that articulationID=0 means use 100%, which is not a terrible idea, so that the default is full sustain.

// articulationID based duration adjustments
var factors = [1, 1, 1.05, 0.85, 0.50, 0.25, 0.95];


In this example, no articulationID is the same as "sustain", both being 100%

hope that makes sense.

Try that again, probably things were out of wack because of not having a complete array before...
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 11:53 am

If you need more than 500ms of lookahead, then look into using the following plugin, INSTEAD OF using the track negative delay setting:

https://www.expert-sleepers.co.uk/downl ... _1_0_3.tgz

latency fixer will let you report up to 1000ms of latency to LogicPro and then LogicPro will automatically use p plugin delay compensation. You have to change the line in the script that specifies the lookahead amount also to 1000.

var LOOKAHEAD = 500;   // ms


It might even be possible, but I'm not sure, to stack up multiple instances of that LatencyFixer plugin to get even more lookahead delay if you want.

That would essentially make it possible to apply staccatisimo, as a percentage, to longer held notes and still work properly. That is unlikely scenario of happening though honestly. The thing is that whatever the resulting duration will be, after applying the %, the amount that is cut out cannot exceed 500ms (or 1000ms if you use the plugin). Realistically you are talking mostly about quarter notes or less from Finale I would think. But a quarter note is 500ms at 120BPM. So that would still work, but if the tempo is....wait for it...I guess 25% slower. (maybe) .then the amount cut out would exceed 500ms.

another thing you might consider is doing it differently instead of an actual percentage. because I would contend that a staccato eighth note should sound about the same as a staccato quarter note, if you know what I mean. Staccato is staccato, not really a percentage of the value coming from finale. So you might want to redo your script to have it specify that actual duration, in fractions of a beat, for each articulation type. Same issue though, the amount cut out of the duration cannot exceed the lookahead value, whatever it is.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 11:56 am

If you decide you want to use fractions of a beat as the data, let me know, there will be some calculations needed to convert between lookahead ms and beats.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 11:59 am

and the more I think about it, fractions of the beat might also not be the right way to specify articulation durations...because at faster or slower tempos....I think staccato probably still sounds about the same with most instruments. Other articulations may vary depending on tempo too though...so perhaps it could get a little complicated if you really want to do it right...but I'll leave that as an experiment for you to think about and we can revisit some of the math later if you decide you want to try.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
michaelrasbury
Topic Author
Posts: 22
Joined: Mon Oct 12, 2020 11:36 am

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 1:40 pm

I will try all this out. By the way, I put the latency fixer into my components folder and it doesn't show as an available plugin in Logic for whatever reason. It doesn't even show in the plugin manager....
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Thu Feb 25, 2021 2:18 pm

Restart the computer
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
User avatar
Atlas007
Posts: 9502
Joined: Mon Dec 14, 2009 11:58 pm
Location: Montreal

Re: Scripter- Humanize Notation Program Quantized Note Length

Sat Feb 27, 2021 12:32 am

Might not be relevant, but I wonder if MIDI Meaning could be somehow useful...
LogicPro 10.6.1 ( & 9.1.8),MainStage3.5.1
MBPro 17", Core2Duo, 8G, OSX 10.12.6
MacPro, Xeon 6Cores, 64GB, OSX 10.15.7
ULN8, MOTU MIDI TP-AV, C4, MCU Pro, KorgNano, Novation SLMkII
AAS, NI, Celemony, Spectrasonics, Korg, etc...
PC, iPad3(V-Control & LogicRemote), AtariST(Notator SL), Several vintage gear
 
User avatar
Dewdman42
Posts: 3096
Joined: Tue Sep 09, 2014 3:01 pm
Location: Salt Lake City, UT

Re: Scripter- Humanize Notation Program Quantized Note Length

Sat Feb 27, 2021 10:49 am

That could work depending how translation from Finale to LogicPro...
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list
 
michaelrasbury
Topic Author
Posts: 22
Joined: Mon Oct 12, 2020 11:36 am

Re: Scripter- Humanize Notation Program Quantized Note Length

Sat Feb 27, 2021 2:03 pm

The documentation says that MIDI meaning function only works once you enable it. It will not read imported articulations or articulations that were put in logic before enabling changes.