Jump to content

Small script for MIDI EFFECTS SCRIPTER to not pass very low velocity notes.


macdutch

Recommended Posts

Hi, I know this reduces dynamics a bit but especially for EZ-AG button down triggers : This can clean ypour midi right up.

Open SCRIPTER : Empty the window, Paste the script below and save as a Script. Don't forget to click RUN SCRIPT.

// Cleaner EZ-AG and midi guitar triggers
// Don't play midi notes below the threshold setting (sens) -- EZ-AG buttons are 16

var PluginParameters = [
    {name:'Sens', type:'lin', unit:'Vel',
    minValue:0, maxValue:32, defaultValue:16, numberOfSteps:32 } ];

function HandleMIDI(event) {
    MyLevel = GetParameter("Sens"); 
    if(event instanceof NoteOn && event.velocity > MyLevel ){
    //event.trace()
    event.send()
    }
        if(event instanceof NoteOff) {
    //event.trace()
    event.send()
    }
   }
  • Like 2
Link to comment
Share on other sites

5 hours ago, macdutch said:

This can clean ypour midi right up.

Thank you for posting your script.

Pasting your script into Scripter and running the script was successful.

I am a script dummy and have been meaning to get a handle on Scripter but my eyes glaze over whenever I look at scripts. This book https://books.apple.com/us/book/logic-pro-effects/id960808317 has a detailed section on Scripter. Reading the Scripter chapter is now a priority. 

I'll need to spend time with your script and the scripter chapter to better understand what to expect.

Edited by 60s Pop Man
Link to comment
Share on other sites

8 hours ago, 60s Pop Man said:

The Environment Transformer filtered low velocity notes effectively in Logic Pro 9. Unfortunately, something changed with LPX, with use of the transformer resulting in long note releases leading to a MIDI panic. I just checked and that's still occuring.

Indeed. It was my frustration with Transformer and it not keeping settings between sessions or being predictable or functional at times that made me look into Scripter.

Link to comment
Share on other sites

numerous bugs have been creeping into the environment over the years and never corrected.  I personally try to avoid using it unless there is no other way.  There are certain situations where it is currently the only way, then ok...  but still there can be weird things that happen with it sometimes.  Also the environment eats midi timestamps, which is not preferable.  For a great many cases, one of the built in MidiFx or Scripter can be used to handle whatever situation you need to do, and in my opinion that method is preferable.  I think some people choose the environment over Scripter because they feel they could figure out how to do it with the environment easier then with a programming language, and that very well may be the case, I personally find it to be the other way around...I find the environment to be positively difficult to deal with.  But I have at times still used it when it's something I can't do with Scripter.  But I also have an extensive programming background, so I am not the norm.

 However, there are also unique situations where environment is the only way with currently logicPro..in which case, say some hail mary's and go for it...  it often times can work fine too.  Just some odd behavior with certain things.

  • Like 1
Link to comment
Share on other sites

actually that is not true, since some release a version or two ago, its possible now to record the midifx section, including from scripter.

for the future of LogicPro, I think its prudent to look at mainstage.  Mainstage is basically built on the same midi and audio engine as logicPro in many ways.  It even has scripter.  But no environment.  Instead it provides a bunch of menu based things for configuring most of the typical kinds of things that someone would normally do in LP's environment.   Personally I think that is where Apple will go with LP also.  They are stringing it along for now behind hidden secret menu to open it, etc. but in the end they will go down that road with LP like Mainstage already is...  IMHO

Edited by Dewdman42
Link to comment
Share on other sites

2 hours ago, fuzzfilth said:

I agree, and might add that the Environment is currently the only way to change live MIDI data before recording it, as Scripter and MIDI FX all sit after the recording track.

Yeah.. I was hoping to find a way to record WITH scripter on as an active filter and maybe I could do that via environment. Looking at that right now, apart from the obvious detour via IAC driver and record to duplicate track ( That works for MIDI EFFECTS but is not LIVE - pre-sequencer). So many people on youtube saying that MIDI input is a nightmare in Logic...

Link to comment
Share on other sites

Just found out how to do it LIVE in Environment. Opened an old project with Environment trials (and tribulations) from some years back . Didn't work then : Does so now on my Logic 10.7.5 on Monterey Intel. Perplexed but nice that it works now. In order to also let NOTE-OFF's through the filter you have to set a MAP and explicitly filter Notes, otherwise you get all notes sustained... at least from my EZ-AG. I'm sure your mileage may vary on other systems and with different controllers. Time to fetch the old AXON and see what the Godin can do. 

"Open up environment"  has been well hidden : Command-0 ( zero)

Then use these settings below and now all very slight fretnoise and midi-knob-triggers are gone also when recording because it is Pre-Sequencer input. You have to CREATE the transformer from the new menu top left and hook it between Input-View and Sequencer. Good luck!!

Pre-Sequencer Environment settings.png

Link to comment
Share on other sites

@macdutch

Your script is an excellent solution for filtering out low velocity notes!

I increased the max value and number steps to accommodate my playing where a velocity >=40 represent false triggers.

Recording the output is easy as of LPX 10.75.  Clicking the slot below the MIDI FX includes the option to select Record MIDI to Track Here.  The filtered/processed MIDI is recorded as performed!

With the Fishman Triple Play, this is a slam dunk as there are just a few low velocity notes. 

Your script also works well the MIDI Guitar 2 (MG2) app with one caveat - short notes. Low velocity notes are easy to filter out as velocity is part of a MIDI message

  • status (event type i.e. Note and MIDI channel)
  • data byte 1 - pitch
  • data byte 2 - velocity

Note duration is defined by note off which is can't be predicted in real time. Examples of MIDI notes recorded with the MG2 here:

  • velocity 70, duration 66 ticks = false trigger
  • velocity 10, duration 51 ticks = false trigger

Your script, and previously, the Environment Transformer, effectively filters out low velocity notes. Neither can filter short notes in real time. So, a Transform set to eliminate short notes after recording is still a great option.

Again, thank you for sharing your script which has officially sparked my exploration of scripts!

Link to comment
Share on other sites

@Dewdman42 @fuzzfilth @macdutch

The Transformer as shown here used to work great in Logic Pro 9.

In LPX, it was as if all notes were played with long releases or maybe that Note Off wasn't being recognized.  So I resumed using Transform Sets after the fact.

macdutch has resolved this issue by mapping velocity as shown above.

low velo.png

Edited by 60s Pop Man
Link to comment
Share on other sites

On 11/3/2023 at 4:04 PM, 60s Pop Man said:

Recording the output is easy as of LPX 10.75.  Clicking the slot below the MIDI FX includes the option to select Record MIDI to Track Here.  The filtered/processed MIDI is recorded as performed!

With the Fishman Triple Play, this is a slam dunk as there are just a few low velocity notes. 

Your script also works well the MIDI Guitar 2 (MG2) app with one caveat - short notes. Low velocity notes are easy to filter out as velocity is part of a MIDI message

  • status (event type i.e. Note and MIDI channel)
  • data byte 1 - pitch
  • data byte 2 - velocity

Note duration is defined by note off which is can't be predicted in real time. Examples of MIDI notes recorded with the MG2 here:

  • velocity 70, duration 66 ticks = false trigger
  • velocity 10, duration 51 ticks = false trigger

Your script, and previously, the Environment Transformer, effectively filters out low velocity notes. Neither can filter short notes in real time. So, a Transform set to eliminate short notes after recording is still a great option.

Again, thank you for sharing your script which has officially sparked my exploration of scripts!

Thanks for the positive feedback and constructive remarks. I forgot about the RECORD MIDI HERE option.. I KNEW there was something I heard but..forgot. Old age I guess. 

I noticed when recording that too many NOTE-OFFS where send. I left it out ( deactivated with //) and now it records just fine!

// Don't play midi notes below the threshold setting (sens)

var PluginParameters = [
    {name:'Sens', type:'lin', unit:'Vel',
    minValue:0, maxValue:32, defaultValue:16, numberOfSteps:32 } ];

function HandleMIDI(event) {
    MyLevel = GetParameter("Sens"); 
    if(event instanceof NoteOn && event.velocity > MyLevel ){
    //event.trace()
    event.send()
    }
    //    if(event instanceof NoteOff) {
    //event.trace()
   // event.send()
    }  
// }
  • Like 1
Link to comment
Share on other sites

1 hour ago, macdutch said:

Just found out how to do it LIVE in Environment.

My hat is off to ya!

You have just solved a nagging mystery. Mapping velocity (127 on top, the cutoff value below that) works perfectly.

So, your script versus the Environment Transformer: The Transformer would need to be a part of your template or created when needed. Your script is available globally.

Edited by 60s Pop Man
Link to comment
Share on other sites

5 hours ago, 60s Pop Man said:

@Dewdman42 @fuzzfilth @macdutch

The Transformer as shown here used to work great in Logic Pro 9.

In LPX, it was as if all notes were played with long releases or maybe that Note Off wasn't being recognized.  So I resumed using Transform Sets after the fact.

macdutch has resolved this issue by mapping velocity as shown above.

low velo.png

I believe that the problem is that your setting (Velocity: <=40) is filtering Note with velocity of “0” (zero) value, which correspond to a Note Off event. Without NoteOff, the currently playing notes will sustain for ever…

IMHO, that case wouldn’t qualify as a bug…

  • Like 1
Link to comment
Share on other sites

On 11/3/2023 at 9:49 PM, Atlas007 said:

I believe that the problem is that your setting (Velocity: <=40) is filtering Note with velocity of “0” (zero) value, which correspond to a Note Off event. Without NoteOff, the currently playing notes will sustain for ever…

IMHO, that case wouldn’t qualify as a bug…

Not all noteOff's are treated that way.  NoteOff events are noteoff events.  It just so happens that NoteOn events with a velocity=0 are also treated as noteoff by everyone.

so...  the question is when are actual NoteOn's with 0 velocity actually created by Logicpro for some reason rather then using explicit NoteOff events?    Could be happening in the environment for sure...and I know there is some weirdness about notes which are played live vs notes performed from a region.  not sure if that is at play here.

at any rate, its always a good idea to check for Note off events by checking for both explicit NoteOff events as well as checking for NoteOn with velocity=0.  Or in this case at least make sure the script allows zero velocity NoteOn's through just as Atlas said.

  • Like 1
Link to comment
Share on other sites

The issue with "End Of Note" (EON) is a chaotic mess, to say the least. I'll try to sort this out:

- incoming, live MIDI from a MIDI or USB cable can have EON in two flavours, depending on the external source:
1. A real Note Off event (NOff) with Release Velocity
2. A Note On event (NOn) with Velocity 0

- live MIDI created within Logic can have EON in two flavours, depending on the internal source:
1. A real NOff with Release Velocity 64 if you click the Screen Keyboard (Windows>Show Keyboard)
2. A NOn with Velocity 0 if you click on the Environment keyboard (Windows>Open MIDI Environment (cmd-0), Layer Click & Ports)

None of these are actually recorded, Logic records the start of a note (defined by a Note On with Velocity other than 0), the length of the note and either the value of the Release Velocity, if present, or Release Velocity Off, if not present (because of EON being NOn v0).

- MIDI played back from Logic can have EON in two flavours, depending on the target:
1. A NOn with Velocity 0 as long as you route this MIDI through the Environment.
2. A real NOff with Release Velocity, once you send that same MIDI outside to a MIDI or USB cable

Feeling dizzy yet ?

This has even changed undocumented through different Logic versions, one time the Environment Transformer could target actual Note Offs, then with the next update, it couldn't. So you can imagine the nightmare of Environments and Scripts that act on Notes suddenly starting to behave weird between updates.

I have built a Macro which converts all incoming notes to Pitch Bend (or Poly Pressure, works just as well) and then Pitch Bend back to Notes, so there is always one single, defined status of EON, which is NOn V0. I'm sure you can do something similar even easier in Scripter with a conditional branch.

Edited by fuzzfilth
  • Like 1
Link to comment
Share on other sites

On 11/4/2023 at 5:07 AM, Dewdman42 said:

at any rate, its always a good idea to check for Note off events by checking for both explicit NoteOff events as well as checking for NoteOn with velocity=0.  Or in this case at least make sure the script allows zero velocity NoteOn's through just as Atlas said.

My first version did ALL NoteOffs, which sounded ok live but when recorded with the "Record midi here" function too many "Offs" were being recorded because the > 16 filter did not apply to them and of course including a limit will effectively not switch off the note. You are right in bringing up the discrepancy here between actual NoteOn's with ZERO Vel and explicit NoteOff-events. I will investigate further and maybe even try to contact the team at Apple.

If I switch back ON ( in the script editor) the tracing it shows that the Yamaha EZ-AG controller is producing noteoffs at 0 velocity :

///////////////////////// SCRIPT /////////////////////////////////////////////////////

var PluginParameters = [
    {name:'Sens', type:'lin', unit:'Vel',
    minValue:0, maxValue:32, defaultValue:16, numberOfSteps:32 } ];

function HandleMIDI(event) {
    MyLevel = GetParameter("Sens"); 
    if(event instanceof NoteOn && event.velocity > MyLevel ){
       event.trace()
    event.send()
    }
        if(event instanceof NoteOff) {
     event.trace()
   // event.send()
    }

/////////////////////////// TRACE IN CONSOLE ////////////////////////////////////////////////////

[NoteOff channel:1 pitch:64 [E3] velocity:0]
[NoteOn channel:1 pitch:64 [E3] velocity:90]
[NoteOff channel:1 pitch:66 [F#3] velocity:0]
[NoteOn channel:1 pitch:66 [F#3] velocity:100]

Strangely it STARTS with a NoteOff on the note played, then the NoteOn.  Playing ONE C3 Note on the MIDI keyboard (StudioLogic Master) and watching in Environment Click and Ports produces a series like this with the little note symbol and strike through note symbol depicting ON/OFF

The keyboard sends the NOTEOFF with the same velocity as the NoteOn...

NoteOn  1  C3  70
NoteOff   1  C3  70

and SCRIPTER shows up

[NoteOn channel:1 pitch:60 [C3] velocity:70]
[NoteOff channel:1 pitch:60 [C3] velocity:90]. ???!! What?

With the SCRIPTER I do get some rather random VERY short notes like 000 01 that I believe to have been normal notes that got cut off because of a NoteOff signal too much or out of sync because of the inconsistent filtering NoteOn PASS > 16 versus NoteOff PASS ALL. So now I need to look more into Transformer before the Sequencer Input to see if various options there produce cleaner results OR I have to implement the timing feature ( If NoteLength > 000 05 then send note, otherwise NOT).

I enjoy the feedback and ideas. I am trying to settle this once and for all if possible within the constraints of Logic. Thanks for anyone chiming in and alerting me to a blindspot.

Oops , Just saw the lengthy piece from FuzzFilth after clicking send...

Link to comment
Share on other sites

43 minutes ago, fuzzfilth said:

The issue with "End Of Note" (EON) is a chaotic mess, to say the least. I'll try to sort this out:

I have built a Macro which converts all incoming notes to Pitch Bend (or Poly Pressure, works just as well) and then Pitch Bend back to Notes, so there is always one single, defined status of EON, which is NOn V0. I'm sure you can do something similar even easier in Scripter with a conditional branch.

You're way ahead of me. But I do understand the messy handling better now. You built the macro in the environment ? Is it active during recording ( Pre-Sequencer) ? Maybe you'd like to share some of the settings here so I can "try to translate" to javascript for SCRIPTER?

Link to comment
Share on other sites

Yes, an Environment Macro. My Logic X 5.1 does not have the option to record MIDI Fx.

Yes, it sits pre-recording, right after the Physical-In object, before any other MIDI processing. Its structure depends on whether or not you want to work with actual Pitch Bend events or not. If not, it's very simple:

Bildschirmfoto2023-11-04um13_13_09.thumb.png.d536762528631a814ea12481187101fa.png

This picks out any Note event (On or Off), converts it to Pitch Bend (which also is a message with one channel- and two data-bytes), then from PB back to Note. Look closely at the events in the Monitors. Yes, I do lose any real Release Velocity, but haven't lost any sleep over that so far.
You must not send any real Pitch Bend events into this, as this will convert to a cacophony of notes. But hey, I don't know you, maybe this is what floats your boat..

Anyway, to correctly process real PB events too, do this:

Bildschirmfoto2023-11-04um13_15_21.thumb.png.de7e4e33827c6e65c226fff02bac41d6.png

The upper branch is identical except Transformer A now blocks everything but Notes (note the Modes of Transformer A in both pictures). The lower branch passes through everything but Notes, so real PB events can come through unaltered, as seen in the Monitors.

Edited by fuzzfilth
  • Like 1
Link to comment
Share on other sites

On 11/4/2023 at 12:48 PM, macdutch said:

My first version did ALL NoteOffs, which sounded ok live but when recorded with the "Record midi here" function too many "Offs" were being recorded because the > 16 filter did not apply to them and of course including a limit will effectively not switch off the note. You are right in bringing up the discrepancy here between actual NoteOn's with ZERO Vel and explicit NoteOff-events. I will investigate further and maybe even try to contact the team at Apple.

Just to be clear again..  NoteOff events are NoteOff events and it doesn't matter what their velocity is.  

NoteOn events that happen to have velocity = 0 are interpreted to mean the same as NoteOff.

Link to comment
Share on other sites

1 hour ago, Dewdman42 said:

Just to be clear again..  NoteOff events are NoteOff events and it doesn't matter what their velocity is.  

NoteOn events that happen to have velocity = 0 are interpreted to mean the same as NoteOff.

Yes, I understand that. The thing was that I was not filtering any NoteOFFS in one version .

Link to comment
Share on other sites

@fuzzfilth, @Dewdman42, It looks my MIDI guitar controller is generating "Note On event (NOn) with Velocity 0".

removingzero.png.6ccebf5d072b08b0c9ff55dd7bda4656.png

On 11/3/2023 at 9:49 PM, Atlas007 said:

I believe that the problem is that your setting (Velocity: <=40) is filtering Note with velocity of “0” (zero) value, which correspond to a Note Off event. Without NoteOff, the currently playing notes will sustain for ever…

You're right about my Transformer setting filtering out "0" as it fall within the Velocity <=40 setting.  In the past with Logic 9 and probably 8, <=40 removed low velocity notes as intended. That Transformer setup was in my standard template or the Transformer object with its settings was stored off to the side in the Clicks and Ports window ready for hook up.

Something definitely changed with LPX, where that setting started to produce note sustain for whatever reason.

Note: In checking old files, my Transformer setting for Velocity was actually "Inside, 0, 40". Not sure is that is a substantial difference from <=40.

At any rate, Velocity Map, 127, 40 works as expected and is now part of standard template.

  • Like 1
Link to comment
Share on other sites

Use this:


var PluginParameters = [
    {name:'Sens', type:'lin', unit:'Vel',
    minValue:0, maxValue:32, defaultValue:16, numberOfSteps:32 } ];

function HandleMIDI(event) {
    MyLevel = GetParameter("Sens"); 
    if(event instanceof NoteOn && event.velocity > 0 && event.velocity <= MyLevel) {
      Trace("Muting event ");
      event.trace();
      return;
    }
    // everything else
    event.send();
}

 

Link to comment
Share on other sites

47 minutes ago, Dewdman42 said:

Use this:


var PluginParameters = [
    {name:'Sens', type:'lin', unit:'Vel',
    minValue:0, maxValue:32, defaultValue:16, numberOfSteps:32 } ];

function HandleMIDI(event) {
    MyLevel = GetParameter("Sens"); 
    if(event instanceof NoteOn && event.velocity > 0 && event.velocity <= MyLevel) {
      Trace("Muting event ");
      event.trace();
      return;
    }
    // everything else
    event.send();
}

Nice to see a version with a trace for what's left out. I am going to look at note-length next by means of the Process Blocks. I just bought the book "The complete Guide to Logic Pro Scripter" so I hope to make some headway in writing a script that will not only filter lower velocity but also Very short ( fret or dampening) notes. If anybody has already done this please help ;-) I have a busy schedule...

Link to comment
Share on other sites

Note length will not be possible to filter out with scripter because you won’t know the note length until the note off comes through.  Well it’s theoretically possible to script something with lookahead latency and filter out the really short ones that way but then you will need to manually compensate that latency as automatic pdc would not pick it up.

 

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.

×
×
  • Create New...