# Logic Pro X 10.5's Autosampler and Peter Schwartz's script



## Ashermusic (May 14, 2020)

I think I am on to something here.

A long time ago, Peter sent me a beat of a script that he called the EXS Legato-izer to use with EXS24 libraries sustain patches to make them flow more smoothly and it worked well. I have used it with Kirk Hunter's EXS24 version of Concert Strings 2 for example.

Well today I experimented. I used Autosampler to capture Hollywood Strings Diamond Violins 1Legato Slur with 2 mic positions and damned if int doesn't sound pretty close in Logic's new Sampler. But since it can't do recorded legato intervals, it isn't as smooth UNTIL (_drum roll_) I add Peter's script in the Scripter MIDI plug-in.

So then I do the same thing with Strezov Sampling's Afflatus Stings Scene's d'Amour Violins 1. Bingo.

Now both these in their original format are pretty demanding, but now I put the two Logic Sampler versions in a Summing Stack and wow, sounds great and flows great (to my ears) and barely denting the CPU meter.


----------



## Ashermusic (May 14, 2020)

Also btw, I Autosampled 2 mic positions (hammer, main) of my favorite piano library, the Embertone Walker 1955 Steinway, which as those of you who own it know is pretty demanding, and again pretty close to the original and not at all resource hungry.


----------



## CT (May 14, 2020)

Jay, not sure if it's just me, but your audio file isn't working. Very curious to hear this though.


----------



## Ashermusic (May 14, 2020)

miket said:


> Jay, not sure if it's just me, but your audio file isn't working. Very curious to hear this though.




You're right it isn't. Not sure why.

EDIT: Fixed.


----------



## Dewdman42 (May 14, 2020)

Nice to hear. It would fun to try to move some stuff over to EXS and see if its more convenient in some way then using PLAY, and I'm curious about Peter's script of course...


----------



## CT (May 14, 2020)

Of course it isn't *perfect*, but especially in-context, I think that would be completely usable.

The plot thickens....


----------



## Ashermusic (May 14, 2020)

Dewdman42 said:


> Nice to hear. It would fun to try to move some stuff over to EXS and see if its more convenient in some way then using PLAY, and I'm curious about Peter's script of course...



Well it certainly takes a lot less CPU than the original. Obviously it takes some time to do and I wouldn't do it for every instrument and every articulation but for a small "quick compose" template with blended libraries, like I said, I think I am on to something.


----------



## Peter Schwartz (May 14, 2020)

Hi Guys,

Jay contacted me today to share his enthusiasm for this script which I wrote maybe 2 years ago. So I just reviewed it, and there's documentation to go along with it. So...

To save everyone the trouble of getting in touch with me to get it, I'm going to post the Script and documentation later *tonight*. In the meantime, please stand by...


----------



## Ashermusic (May 14, 2020)

Peter Schwartz said:


> Hi Guys,
> 
> Jay contacted me today to share his enthusiasm for this script which I wrote maybe 2 years ago. So I just reviewed it, and there's documentation to go along with it. So...
> 
> To save everyone the trouble of getting in touch with me to get it, I'm going to post the Script and documentation later today. In the meantime, please stand by...


 
Whatta guy! Peter is not only brilliant but generous. Proud to call him my friend.


----------



## Peter Schwartz (May 15, 2020)

(Thanks for the very kind compliments Jay!)

OK folks, here ya go. Don't use the file Jay linked to above. Use the one attached to this post instead. In the folder you'll find a Logic 10.4.7 project and a 3 page PDF describing how the scripter works.

The project is loaded up with a stock Logic piano sound so you can easily hear the effect the various controls have on the sound. Will work with any sustaining sound or your money back! 





Enjoy! Stay safe!


----------



## Saxer (May 15, 2020)

Thanks a lot Peter!

This will keep me busy for a couple of years


----------



## jonathanwright (May 15, 2020)

Thanks so much @Peter Schwartz , very generous.

I've just finished Autosampling the old EW Harp, which has come out virtually identical.

I'm about to try out a couple of patches from the ol EW Choirs, so it'll be interesting to see how this works on them.


----------



## joeyf (May 15, 2020)

May I be so silly to ask, I opened the Logic X file, but how do I apply this to a template, when I change the Logic sound the parameters all change, do I have to apply those stated in the manual in a manual fashion. Trying to get my head around this.. Am I making sense? Or do I use Peter's Logic file as a template? I feel so silly.


----------



## Alex Fraser (May 15, 2020)

Brilliant. Thanks, Peter. I've got some old string libraries from a CD ROM that are going to get this script treatment.


----------



## Ashermusic (May 15, 2020)

Peter Schwartz said:


> (Thanks for the very kind compliments Jay!)
> 
> OK folks, here ya go. Don't use the file Jay linked to above. Use the one attached to this post instead. In the folder you'll find a Logic 10.4.7 project and a 3 page PDF describing how the scripter works.
> 
> ...



One suggestion: change the name to Sampler Legato-izer if you are now in Logic 10.5, since there is no longer and EXS24.

I know, I'm pedantic


----------



## Peter Schwartz (May 15, 2020)

Hey, feel free to rename it as you see fit. I'm not going to do any additional work on it. After all, it's free!

As for implementing it, one suggestion is to save the entire setup as a Patch. You can then easily import it into other projects. That said, I haven't updated to 10.5 and probably won't do so for quite some time. So if, as Jay says, there is no longer an EXS-24, I'll leave it to others to figure out how to translate this for use in LPX 10.5.

On a much more basic level, though, you can open this project and save the Scripter setting to your system (click on the name and do a Save As...). Then you can load it into a Scripter plugin as needed.


----------



## Dewdman42 (May 15, 2020)

Saving as patches makes sense. The script only works with EXS/Sampler patches that have the added mod matrix items per your instructions...so it will almost never make sense to use this script without an appropriately modified Sampler/EXS24 patch to go along with it.


----------



## bvaughn0402 (May 15, 2020)

Jay,

Any chance you might put together a quick to the point video of what you are using Sampler for?

I'm not sure I understand what you are doing, but I'm fascinated by what you are doing.

Or is there a video someone has done with what you are doing?

I'm thinking more your general use of Sampler to convert, not necessarily the use of the script (but I'd watch that too).


----------



## Ashermusic (May 16, 2020)

Not Sampler, Auto Sampler. You can find videos on using Auto Sampler in MainStage on YouTube. It is essentially the same.


----------



## Ashermusic (May 16, 2020)

Peter Schwartz said:


> Hey, feel free to rename it as you see fit. I'm not going to do any additional work on it. After all, it's free!
> 
> As for implementing it, one suggestion is to save the entire setup as a Patch. You can then easily import it into other projects. That said, I haven't updated to 10.5 and probably won't do so for quite some time. So if, as Jay says, there is no longer an EXS-24, I'll leave it to others to figure out how to translate this for use in LPX 10.5.
> 
> On a much more basic level, though, you can open this project and save the Scripter setting to your system (click on the name and do a Save As...). Then you can load it into a Scripter plugin as needed.



Fortuntately I still also have 10.4.8 so I guess I could be going back and forth. The bigger issue for me is that the beta Peter sent me gave you the choice of adding the legato with the CC of your choice, in my case cc64 and I am not seeing that option in the newer script.


----------



## Dewdman42 (May 16, 2020)

I can try to tweak it for you, but its not clear to me what you're wanting. Peter's current script sends 3 CC's right now, to tell EXS24 how to adjust attack and release times on the fly. Its relying on overlapping notes to determine when to do that.. How were you wanting to use the sustain pedal? As a way to detect instead of overlapping notes?


----------



## Ashermusic (May 16, 2020)

Dewdman42 said:


> I can try to tweak it for you, but its not clear to me what you're wanting. Peter's current script sends 3 CC's right now, to tell EXS24 how to adjust attack and release times on the fly. Its relying on overlapping notes to determine when to do that.. How were you wanting to use the sustain pedal? As a way to detect instead of overlapping notes?



With the previous version, when I play a converted HS Violins 1 Leg Slur patch, it plays polyphonically and does not sound smooth. When I hold down the stain pedal, it only plays one note at a time and sounds very smooth.


----------



## Dewdman42 (May 16, 2020)

I'll look into it this morning. Looks to me like this script used to have a few more GUI options then it does now...so maybe it was in there, but he took it out for some reason, but anyway I will try to see if I can get something working if it doesn't take too much time...


----------



## Ashermusic (May 16, 2020)

Dewdman42 said:


> I'll look into it this morning. Looks to me like this script used to have a few more GUI options then it does now...so maybe it was in there, but he took it out for some reason, but anyway I will try to see if I can get something working if it doesn't take too much time...



Thanks!


----------



## Dewdman42 (May 16, 2020)

try this:


```
/*
EXS Legato-izer Script 2a
© 2017 - 2020 Peter Schwartz, ALL RIGHTS RESERVED

You may modify the script and distribute it for free (as it was originally offered).
The above credit must also be included in the script’s comments.
*/

var noteon = new Array;

var cc = new ControlChange();
cc.channel = 1;
var    non = new NoteOn();
non.channel = 1;
var    noff = new NoteOff();
noff.channel = 1;
var cSus = 0;

// HandleMIDI
function HandleMIDI(e) {
    e.handleLegato();
}


// default behavior
Event.prototype.handleLegato = function() {
    this.send();
    this.trace();
};


// NoteOn
NoteOn.prototype.handleLegato = function() {

    let ln = noteon.length;
    let mode = GuiParameter(4);

    // no note sustaining or pedaled
    if((mode==0 && ln<=0) || (mode==1 && cSus < 64)) {

        noteon.push(this.pitch);
        this.send();
        this.trace();   
    }

    else {
        noff.pitch = noteon[0];
        noff.sendAfterMilliseconds(GuiParameter(0));
        noff.trace();
        for (i = 2; i < 5; i++) {
            cc.number = i;
            cc.value = GuiParameter(i - 1);
            cc.send();
            cc.trace();
        }
        noteon.pop();
        noteon.push(this.pitch);
        this.send();
        this.trace();
    }

};

// NoteOff
NoteOff.prototype.handleLegato = function() {

    this.send();
    this.trace();

    if (this.pitch == noteon[0]) {
        Trace("********** CLEAR");
        for (i = 2; i < 5; i++) {
            cc.number = i;
            cc.value = 0;
            cc.send();
            cc.trace();
        }
        noteon = [];
    }
};



ControlChange.prototype.handleLegato = function() {

    // if sustain pedal mode
    if(GuiParameter(4)==1 && this.number == 64) {
        cSus = this.value;
        return;  // in this case block sustain pedal
    }

    this.send();
    this.trace();
};



function ParameterChanged(p, v) {
    PluginParameters[p].data = v;   
}

var PluginParameters = [

    {
        name: "Note Overlap ⏱ ",
        type: "lin",
        unit: " ms",
        defaultValue: 81,
        disableAutomation: true,
        numberOfSteps: 500,
        minValue: 0,
        maxValue: 500
  },

    {
        name: "Sample Offset ▶️ ",
        type: "lin",
        defaultValue: 0,
        disableAutomation: true,
        numberOfSteps: 127,
        minValue: 0,
        maxValue: 127
  },

    {
        name: "Attack (Smoothing) 📶 ",
        type: "lin",
        defaultValue: 0,
        disableAutomation: true,
        numberOfSteps: 127,
        minValue: 0,
        maxValue: 127
  },


    {
        name: "Pitch Scoop 🌈 ",
        type: "lin",
        defaultValue: 0,
        disableAutomation: true,
        numberOfSteps: 127,
        minValue: 0,
        maxValue: 127
  },
      {
        name: "Legato Detection",
        type: "menu",
        valueStrings: ["Note Overlap","Sustain Pedal"],
        defaultValue: 0,
        disableAutomation: true
  }
];


// Faster function to get GUI value
function GuiParameter(id) {

    // just in case programmer error
    if(id >= PluginParameters.length) return undefined;
    
    // if script was recently initialized, reload GUI value
    if(PluginParameters[id].data == undefined) {
        PluginParameters[id].data = GetParameter(id);
    }

    return PluginParameters[id].data;
}
```


----------



## Ashermusic (May 16, 2020)

Dewdman42 said:


> /* EXS Legato-izer Script 2a © 2017 - 2020 Peter Schwartz, ALL RIGHTS RESERVED You may modify the script and distribute it for free (as it was originally offered). The above credit must also be included in the script’s comments. */ var noteon = new Array; var cc = new ControlChange(); cc.channel = 1; var non = new NoteOn(); non.channel = 1; var noff = new NoteOff(); noff.channel = 1; var cSus = 0; // HandleMIDI function HandleMIDI(e) { e.handleLegato(); } // default behavior Event.prototype.handleLegato = function() { this.send(); this.trace(); }; // NoteOn NoteOn.prototype.handleLegato = function() { let ln = noteon.length; let mode = GuiParameter(4); // no note sustaining or pedaled if((mode==0 && ln<=0) || (mode==1 && cSus < 64)) { noteon.push(this.pitch); this.send(); this.trace(); } else { noff.pitch = noteon[0]; noff.sendAfterMilliseconds(GuiParameter(0)); noff.trace(); for (i = 2; i < 5; i++) { cc.number = i; cc.value = GuiParameter(i - 1); cc.send(); cc.trace(); } noteon.pop(); noteon.push(this.pitch); this.send(); this.trace(); } }; // NoteOff NoteOff.prototype.handleLegato = function() { this.send(); this.trace(); if (this.pitch == noteon[0]) { Trace("********** CLEAR"); for (i = 2; i < 5; i++) { cc.number = i; cc.value = 0; cc.send(); cc.trace(); } noteon = []; } }; ControlChange.prototype.handleLegato = function() { // if sustain pedal mode if(GuiParameter(4)==1 && this.number == 64) { cSus = this.value; return; // in this case block sustain pedal } this.send(); this.trace(); }; function ParameterChanged(p, v) { PluginParameters[p].data = v; } var PluginParameters = [ { name: "Note Overlap ⏱ ", type: "lin", unit: " ms", defaultValue: 81, disableAutomation: true, numberOfSteps: 500, minValue: 0, maxValue: 500 }, { name: "Sample Offset ▶ ", type: "lin", defaultValue: 0, disableAutomation: true, numberOfSteps: 127, minValue: 0, maxValue: 127 }, { name: "Attack (Smoothing) 📶 ", type: "lin", defaultValue: 0, disableAutomation: true, numberOfSteps: 127, minValue: 0, maxValue: 127 }, { name: "Pitch Scoop 🌈 ", type: "lin", defaultValue: 0, disableAutomation: true, numberOfSteps: 127, minValue: 0, maxValue: 127 }, { name: "Legato Detection", type: "menu", valueStrings: ["Note Overlap","Sustain Pedal"], defaultValue: 0, disableAutomation: true } ]; // Faster function to get GUI value function GuiParameter(id) { // just in case programmer error if(id >= PluginParameters.length) return undefined; // if script was recently initialized, reload GUI value if(PluginParameters[id].data == undefined) { PluginParameters[id].data = GetParameter(id); } return PluginParameters[id].data; }




I tried copying all that into the Scripter. Nope. 

I will stick with the beta he gave me years ago. If it isn't broken, I needn't fix it.


----------



## Dewdman42 (May 16, 2020)

when you say, "nope", what do you mean..what happens? It seemed to work for me. Did you press the "run Script" button after copying it into the script window?


----------



## Ashermusic (May 16, 2020)

Dewdman42 said:


> when you say, "nope", what do you mean..what happens? It seemed to work for me. Did you press the "run Script" button after copying it into the script window?




Thought I did, but maybe I missed  About to teach a Logic class over Zoom, so I will try again later. Thanks.


----------



## Dewdman42 (May 16, 2020)

Also note that I added a GUI element (last one) to choose whether use Note Overlap or Sustain pedal to detect legato, and note overlap is the default. So make sure you change that GUI item to sustain pedal in order to use sustain pedal as you wish to legato-ize it instead of sustain it. Might put some more thought into that, perhaps it can just always be on, with either overlapping notes or sustain pedal always having that effect. Lemme know.


----------



## Dewdman42 (May 16, 2020)

Here's a version that doesn't require a GUI choice to use sustain pedal. Just play it. If you overlap the notes with your fingers, then you get legato and if you use a sustain pedal between notes, also get legato.


```
/*
EXS Legato-izer Script 2c
© 2017 - 2020 Peter Schwartz, ALL RIGHTS RESERVED

You may modify the script and distribute it for free (as it was originally offered).
The above credit must also be included in the script’s comments.
*/

var noteon = new Array;

var cc = new ControlChange();
cc.channel = 1;
var    non = new NoteOn();
non.channel = 1;
var    noff = new NoteOff();
noff.channel = 1;
var cSus = 0;

// HandleMIDI
function HandleMIDI(e) {
    e.handleLegato();
}


// default behavior
Event.prototype.handleLegato = function() {
    this.send();
    this.trace();
};


// NoteOn
NoteOn.prototype.handleLegato = function() {

    let ln = noteon.length;

    // no note sustaining or pedaled
    
    if( ln>0 || cSus > 63 ) {

        noff.pitch = noteon[0];
        noff.sendAfterMilliseconds(GuiParameter(0));
        noff.trace();
        for (i = 2; i < 5; i++) {
            cc.number = i;
            cc.value = GuiParameter(i - 1);
            cc.send();
            cc.trace();
        }
        noteon.pop();
        noteon.push(this.pitch);
        this.send();
        this.trace();
        
   }
   else {
  
        noteon.push(this.pitch);
        this.send();
        this.trace();   
    }
};

// NoteOff
NoteOff.prototype.handleLegato = function() {

    this.send();
    this.trace();

    if (this.pitch == noteon[0]) {
        Trace("********** CLEAR");
        for (i = 2; i < 5; i++) {
            cc.number = i;
            cc.value = 0;
            cc.send();
            cc.trace();
        }
        noteon = [];
    }
};



ControlChange.prototype.handleLegato = function() {

    // if sustain pedal mode
    if(this.number == 64) {
        cSus = this.value;
        this.trace();
        return;  // in this case block sustain pedal
    }

    this.send();
    this.trace();
};



function ParameterChanged(p, v) {
    PluginParameters[p].data = v;   
}

var PluginParameters = [

    {
        name: "Note Overlap ⏱ ",
        type: "lin",
        unit: " ms",
        defaultValue: 81,
        disableAutomation: true,
        numberOfSteps: 500,
        minValue: 0,
        maxValue: 500
  },

    {
        name: "Sample Offset ▶️ ",
        type: "lin",
        defaultValue: 0,
        disableAutomation: true,
        numberOfSteps: 127,
        minValue: 0,
        maxValue: 127
  },

    {
        name: "Attack (Smoothing) 📶 ",
        type: "lin",
        defaultValue: 0,
        disableAutomation: true,
        numberOfSteps: 127,
        minValue: 0,
        maxValue: 127
  },
    {
        name: "Pitch Scoop 🌈 ",
        type: "lin",
        defaultValue: 0,
        disableAutomation: true,
        numberOfSteps: 127,
        minValue: 0,
        maxValue: 127
  }
];


// Faster function to get GUI value
function GuiParameter(id) {

    // just in case programmer error
    if(id >= PluginParameters.length) return undefined;
    
    // if script was recently initialized, reload GUI value
    if(PluginParameters[id].data == undefined) {
        PluginParameters[id].data = GetParameter(id);
    }

    return PluginParameters[id].data;
}
```


----------



## Peter Schwartz (May 16, 2020)

Yes, the old version had more choices. I removed them for simplicity's sake. I also wasn't entirely happy with the way those older features worked. But by all means, have at it to modify it! Have fun!


----------



## Ashermusic (May 16, 2020)

Dewdman42 said:


> Here's a version that doesn't require a GUI choice to use sustain pedal. Just play it. If you overlap the notes with your fingers
> 
> ,
> 
> ...





Ashermusic said:


> Thought I did, but maybe I missed  About to teach a Logic class over Zoom, so I will try again later. Thanks.


 Thanks, works great!


----------



## Kent (May 24, 2020)

Peter Schwartz said:


> (Thanks for the very kind compliments Jay!)
> 
> OK folks, here ya go. Don't use the file Jay linked to above. Use the one attached to this post instead. In the folder you'll find a Logic 10.4.7 project and a 3 page PDF describing how the scripter works.
> 
> ...


thank you!!


----------

