Trigger a binding from an expression?

I’ve been trying to come up with a way to use an expression to trigger a binding. For example, i’d like to use the new is_pitch_class_held expression to start a Media player when i play a certain chord. I thought i might be able to do something with a conditional binding, but would still need to trigger the binding somehow. Is there any way to finagle an expression as the source of a binding ?

Thanks for any insights,

  • JIm

Hi Jim,

Have you tried something like this? It checks the incoming notes and fires when it sees the first simple C chord.

Cheers,

Dave

Hi Dave,

That’s what i was trying to do - but i think the problem is that the binding only fires if the C chord is already held when the Any note is played. In fact, i just proved that to myself – the binding triggers if i’m holding a C chord and then hit any other note. So the problem is how to get it to trigger at the time of playing the chord. (By the way the source needs to be Onscreen keyboard (out), not Onscreen keyboard (in) – i’m never sure which to use when and just try them both to see what works.)

But thanks for looking at it, maybe we’ll come up with something. @Brad ?

Well, it seems that when they are grouped the condition can’t true up on a chord strike. Maybe if you tried separating the chord notes like this. This makes it more tactile IMO. It will only fire when the conditions are met so the last note to be pressed will also be the trigger note. This works here very well.

is_pitch_class_held("C") == 1 && is_pitch_class_held("E") == 1 && is_pitch_class_held("G") == 1

1 Like

What would be ideal here, and something I’ve been thinking about, is for the binding expression to have memory so it can recall things it’s seen in the past.

I’m still in half-work/half-holiday mode, but when I get back into it, perhaps I can enhance the expressions to have variables that are persisted across invocation calls. I think this might be feasible, but I need to look at it.

1 Like

That would be really awesome, I guess this would cover most of the needs otherwise requiring the scripting language.

Sounds like a useful idea, though i’m not clear how that would help trigger the binding - what’s needed would be something like “Condition becomes true” as a Source for the binding.

But i have come up with a quirky fix for what i was trying to do. First, a binding to send some random unused note (i used 21) to the onscreen keyboard when one of the notes in the chord is played. Second, a binding to play the media file when note 21 is received while the chord is held, with a 100 msec delay before executing to give the chord notes time to be recognized (and allow some slop in my playing!). A bit of a kluge, but it works.

– Jim

1 Like

Not sure I’m following. The option “Condition becomes true” does control when the target of the binding is triggered. Can you post an example of what you mean?

Well, some of it but the binding expression implementation is always going to be somewhat limited - UI thread only, not control flow statements, not particularly fast (interpreted) etc…

I use the conditions as control flow, basically providing an if-then, works great. Also, I only use scripts on controls (cc and program changes), not notes, so speed is not that critical.

But I agree that if it is notes, then speed is top priority.

I’m wondering if something like LET from Excel (LET function - Microsoft Support) might be an inspiration. Maybe consider global variables (e.g. names prefixed with #) as well as local variables. Yes, would give something like functions with side effects, so use with care - but with great power comes great responsibility.

Was OP question answered? I’ve a Fishman on a Guitar that can input midi notes to Cantabile. What I’d like, for example, is when Cantabile registers a Cmaj chord (CEG) from Fishman, play a Cmaj pad sound on a VSTi. My concern is the timing issues mentioned. Obviously, all the strings are not strummed at exactly the same time.

What would the syntax be for that? Was the “persisted” invocation calls implemented?

I’ve been trying to solve this myself but can’t get the bindings to fire with the is_pitch_class_held expression.

Hi easteelreath
Obviously the notes or rather the chords must be held simultaneously in order to be recognised.
With the expression is_pitch_class_held a chord must be with the notes pressed simultaneously in order to be recognised.
With guitars I think it’s a bit tricky, unless you intervene on the individual pressed notes, to make sure that there is some kind of sustain that lasts just long enough for a guitar chord to be displayed.
That might be an idea!

1 Like

The midi input from the Fishman is definitely holding the notes as the Note On midi events are visible in midi monitor when a chord is strummed. The Note Off events appear when the guitar string vibrations are dampened.

This is the Fishman Output for a Dmaj chord. There are two Ds, and A, and an F#. The Note Offs are when I stop the strings from vibrating.
image

Here is the onscreen keyboard holding a Dmaj (Easier to deal with to provide examples)
image

Here is supposed to be the expression to evaluate if a Dmaj is held

This binding is supposed to send a D4 to a VSTi midi input. I’m just trying to recognize when a particular chord is played then act. What is my error?

If the “Fire:” is “Always,” the VSTi plays a D4 with every note. The Condition is not working as written to recognize the Dmaj.

The routing diagram is below. Binding is supposed to evaluate what is going into the Midi Node rack, then send midi to OP-X when Dmaj chord is held.

I don’t think that the pitch class held function can work with the MIDI guitar input whereas a keyboard device can. This is because the held note messages are logged as (held) in the MIDI monitor and differ from MIDI note On messages lacking a note OFF message generated by the guitar pickup system. Not sure of a workaround but thinking about it. Maybe @brad has some observations …

Dave

1 Like

Thanks Dave (as always). I did some trial and error this morning and noted that the any_pitch_class_held function works. Those functions are related to the Onscreen Keyboard State, so the Onscreen Keyboard may have to be involved in some manner. But once again, “any_pitch_class_held” works and “is_pitch_class_held” does not.

Glad you found a way forward, I should have tested further. I know more now thanks to you!

Dave

I did not find a way forward for the chord evaluation. The “any_pitch_class_held” works for a single note in the evaluation string but the “is_pitch_class_held” does not work for a complete chord (all the notes in the chord string.

Did you try using the and operator like this with multiple any_pitch_class_held statements? e.g. an A chord

any_pitch_class_held("A") == 1 && any_pitch_class_held("C#") == 1 && any_pitch_class_held("E") == 1