Synth.isNote(eventID)



  • OK its sorta a bit of a nicety - but I'd really like to be able to check if a note still exists (and hasn't been processed by some other script processor)

    So unless someone knows a current way to do this and not get this message:

     onNoteOff() - Line xx, column xx: NoteOn with IDxxxx wasn't found
    

    then we'd need to add an api call to Synth.

    As far as I can see this would be in here: ScriptingAPI.cpp

    and should look like this:

    void ScriptingApi::Synth::isNote(int eventId)
    {
    	if (parentMidiProcessor == nullptr)
    		reportScriptError("Can't call this outside of MIDI script processors");
    
    	const HiseEvent e = getProcessor()->getMainController()->getEventHandler().popNoteOnFromEventId((uint16)eventId);
    
    	if (e.isEmpty())
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    

    We'd need to add a method wrapper (so insert that here...):

    API_METHOD_WRAPPER_0(Synth, isSustainPedalDown);
    API_METHOD_WRAPPER_1(Synth, isKeyDown);
    API_METHOD_WRAPPER_1(Synth, isNote);
    API_VOID_METHOD_WRAPPER_1(Synth, setClockSpeed);
    

    and a METHOD API

    ADD_API_METHOD_0(isSustainPedalDown);
    ADD_API_METHOD_1(isKeyDown);
    ADD_API_METHOD_1(isNote);
    ADD_API_METHOD_1(setClockSpeed);
    ADD_API_METHOD_1(setShouldKillRetriggeredNote);
    

    So 3 questions:

    1. is there some really really good reason not to add this?
    2. does any one know if there's anything else that needs doing?
    3. As I dont have a HISE development image at the moment, that I'm not using on time critical development, and as I'm not all signed up to contribute to the HISE code base - does any one fancy implementing this?


  • I asked for this before. If I recall Christoph's response was each script should be responsonsible for handling it's own note ons/offs.

    My usual method is to set a variable that tracks the eventID to default to -1, then whenever a note is played the eventID is set to the ID of the note, and whenever the note is turned off it is reset to -1 (if you're using a MIDIList to track the ID use -99 instead of -1). Whenever I need to turn a note off manually I first check that the ID isn't -1, because if it is the note has already been turned off.

    This has solved 99% of the issues I've had with this situation, however there are some occasions where I think it would be convenient to have a function to check if a note is still active.



  • @d-healey yes this is exactly what I do - but there are still some "escapees" - especially if you play very quickly...and to Christophs point:

    I agree - each script should be responsible for handling it's own note on and off - I'm not asking for a call that handles it for me - just a call that lets me know what the state of the note is - then its up to me to decide what I should do with that....



  • So essentially the problem here is:

    When (as may often be the case) there are a series(at least 2) midi processors in sequence...
    Each of these may need to setArtificial - in my case its a glide script and a mono script...
    As they are doing this they need to handle their own note off activities. But....here's what I think the scenario is:

    Processor 1

    Note on:
    Slot1ID = Message.setArtificial
    Do some processing

    Note off:
    deal with Slot1ID:
    noteOff ByEventId(Slot1ID) // errors with note not found for ID....see below

    Processor 2

    Note on:
    Slot2ID = Message.SetArtificial // (this I think ends the note whos ID is held in Slot1ID above)
    Do some S2 processing

    Note off
    deal with Slot2ID:
    noteOff ByEventId(Slot2ID)

    So the problem here is Processor1's note off activities - a note with an ID = Slot1ID no longer exists, and the call back errors and never completes its processing...it gets worse the more selective these processors are - say only processing notes in a given note num range or velocity...

    Yes we can design a whole new processor that combines the work of P1 and P2 - but this is bad bad bad design - its not modular - its not reusable. We can make P1 and P2 share some processing - again bad for the same reason.

    What I think we need is a way for any MIDI processor to ask - Hey do I still need to handle this ID's note off? - essentially Synth.isNote(EventID)



  • How does the user switch between mono mode and glide?



  • @d-healey said in Synth.isNote(eventID):

    How does the user switch between mono mode and glide?

    There are two independant buttons on the UI that turn these on and off.



  • @Lindon so they are never active at the same time?



  • @d-healey they can be active in any combination
    0 0
    0 1
    1 0
    1 1

    but in the end lets not get hung up on this example - what if I have 4 different MIDI Processors? what then?



  • @Lindon if only one is active at a time we don't have to worry about them interfering with each other.

    If both are active at once how does the instrument decide whether it should play in mono mode or trigger a glide?



  • @d-healey said in Synth.isNote(eventID):

    @Lindon if only one is active at a time we don't have to worry about them interfering with each other.

    If both are active at once how does the instrument decide whether it should play in mono mode or trigger a glide?

    As I say - let not get hung up on this example -- If both are active (and the glide is first) it plays the glide(s) - it even glides chords.... if its followed by the mono then it chokes down to a single (last played) note.

    But as I say - this is just an example - what if I have a MIDI processor that acts based on Velocity - doing a bunch of stuff(including changing the velocity) to MIDI notes with a velocity over 100, and this processor is followed by another - which does something else - this second processor does something to every note (making it Artificial in every instance). Now the first processor doesn't know if its note has been "hijacked" by downstream processors....so it has no idea if it should be handling note off activities...



  • @Lindon I'm focusing on this example because each situation has a different solution and I'm trying to help you get your project working 🙂 While a catch all solution to check active notes would be good, we don't have one, so I want to help you using the techniques that are available at the moment.

    The velocity trigger issue you describe I have solved in my own project using a global variable. I put a script at the top of the chain to record the true velocity before it is changed by other scripts, this can then be picked up by the velocity filter script.

    Another solution to the makeArtificial problem is to not use makeArtificial at all. Instead you generate brand new notes using Synth.playNote(), which solution to use depends on how your scripts interact with each other and which ones are active at a particular moment.



  • @d-healey

    A simple example might help:

    HiseSnippet 2144.3oc6Z80aabbD+NIc1lLVFIAoA4wKDEAj05OGobbrirhojnjKg0eHDksKPPfwIdKIWni2xd2R0v5Jff7b+Bj7TeneI5SMuVf9P+fzGx2f1Y18NdKIORdlV1IswGhc39mYle6LyNyN65Z9rFjf.luldlS62knoeSi5883s2ssM0SqZEM8aYPCNhwI0a3S6x01oeW6f.hilt9hOBmidlkzDe+3C2w101qAItKMsmxnMHGP6P4w8Vq7iott6a6PNk1QY12ob0FLucYtrd.dVzvRqqciysaQNxFm1BFZ5WaOGJm4WmayIAZ5KsCyoe81r+fmb9OkFPOykfMJpUGXjr68YtNHhwd01sM00oVz5NPSS2nVrVXQoV3CLNj5PGzer13cECXFSgp9PegoAuhpvyJ0vSSAcKIQG.BlSOWa9vHCMGgCPYdCgrpdbhW.k2W0b8SJbeOiZTdi1Ii2ER.ufg50MdCM9KarWyljF7Xvtjw9+t2rV5aLgci2zXWlGGZQ7KdUrWrap2Kpu3q3dOq2n68VbxVDU3k.jVXbO32yPF8KdDDOWynCyiMDJBCRtveW2vmzxz0NfiwN2b4rXSpi4Vlqd+6uYyddMPedSlGN7wd4Krb1WrbVS3i1zLOLwOVLyBx9vOgivZd3za1bm96cAwiW0AlZgMkSZ4rYDB3P.gPPy05XeNYaeNsIsA01MONsLQ.RYZsHhdNpWmyH9hYc4k.CGEhMaNILZ9Ieh4GKQGM3wj9U.cd9HAUHbE7hWhEhPBQpJYWWF1M.tgwFtavm45hPO6KxlI6kCML5Tm7HgDl2SrtWw7Ba2djASDr7C6N8NoycB1y.At3JSj4U0ixOtKYPaoEOpGKsAJX0thWWp8JVNILs3tlQDlck3C90SpVwlaCt65g8AyqKAbWvUqdExEPrBoyeFiJjfy4rtIEaO4cFKaTi4ysS3HCQaP922xHTtqEP3Oi5vam+y1vBcAT5+2RnsZyyWzRLvxYA0a.GLU9lmI3I3iDMaaGmc5w4Lu74jxK2JlEsv+LJobPINLgO1icV9bnxEI5t.UBhvIhn3DauVj7PuaXgCslUQbzXFZ2g+jZIwwmXtcGNvxR2Ohkhopvy0JABrDxzw4Ykie1QIvzJRldmRJ7DmZZ3ZWzprMmCGqJI7Vyba944VQnAtymhjpPvPZh6hZhQXtzj20kxU3MDcYWVmtLOnAHfASI2nVksccgXGASjzvwCoSFOE22TsBRyW9UggXOHN.2pEGQDBoum2EEgAkAg.QL3nIgnCFm3B6DJJjz5qON4kRC4kDjO8374kNwHadJF8IeAys1BroiEwDC2Ngv0lewVJJdEVoj4PgS325qCZ3.lKYst9TT0dzwmtm4wGYdvdOZ6SO9yyYdaynv4GPZAKN7zX9Wf4PTCQGgrIN2gm5Hn.+bYMrcMc.lrUrga0ojYZTFfhOzwXDsXQLqzjPFNgl1tAjBiyxDfI9IAYoDvvkICKjfuvzBgg7mxs9IZfRkrGk9oCkICpGDCpGXlOJ3gh162.6blGzkDeRm9Z80iL4PLlS8s8B5xBHa2g0CbOKVJok5Pj.Io84PBT3m4KcOKY1hQoHLXwWNAuquZ5mbJ4UM92SXYJ88fPqhxbvCXmeVH.BXux.VtxXKhjTBirStlqcepWKypUD6hmk.SVwNBO6J44mma17CDYNyJU2WHbXgT3pRuHxDG6Zsh0JIZhGDfGcJfrV9zy5wI4i6VlIaE07fp6HSTcLHrexLszKISuj.wcdwq.1sdEg4XzOxFxCRSIB+7a0nfovRFFqVgwqiQl.hSc1TsMVZxtXrGPEXs4OwYqSBLQeMY9PcXhALolOnXo6A++ae6Ym3Ukow+NNseTUbzY3qfKUEdEqNlfCUhQJS0oS1W9MumQgCEqvZNyHMEvRZy0yygzj5QbxMaMIx7YFVDqStX5ynxEE+NKttYxDmhzbIZEvuQz7UM4sodmi+cfI7e1l9DX6QXxEDlEl.ilPI9SfhIdrkKmgqAwyIkYljUMLyHD+O1sIXklaSn3UxsIXM0aSP+5gjBSkKtWfaEdu.xZx0n.StggrvbMgxQ8hI0lD00coNDeA0WyPbAkpz9C+y+bmxog1qaHpDeTA+9oj3JiQb4M13WkRhE0TOhjKSSEw2zHNWwKgRSQkmwHr5nDHedt.HzNGVQN3SOaK8WqoanmEDV+nenov.iYYrEj+WhHGoti8WOXQ7C9kU410mo4Wvtb5JrKfS5Vm9GEJlu+6vu+1C6HuGcYy+wCUknV9TKwJwR7ud0IwqMSGsgUYqNhDidbfgTie6Ph3FoycLl9tAkieklu4QkGh2Oubhhm533RpwBnhG9Q4gAgDu18bkmJR8wHzRkeWr6tBD9SJvS6vxu84z9k3yocKITdGi5v45DmNQ.jOTz17Y1WPLeDwi3iJ0o8tZ+qq92U63FbP7Ct0CUFWmzgdJ30Gn14SBH66S98mfVY092kY6m3P+3C2GVjIRScadOeg6h7xVFx8XwTaSdIduukd6aseE97jYhvXcZmttjnKeVfw2GxZKBlN3FsGBkGx7Xcay7nMTM5mPfRsa0h3qh8DWPxBvi64CJeBwkXq5.+qKe.33Y6C5IxqGcgdJsWejQ3idfaFM+YUP8oYBeWigeRhWmFP3Lou0.9FMq7h+xLq7Irdbnp8CsAGU7zpPM50gjgMH.R77HtA3AWW.SnIaaEcz45P49hF+G3KbvhXa8vAKFM3+2HiN1M7YOugrPOb+xMD8.5VOw+j3xXbH11rXT8cFFVqYoAmul97FMPS5pE0zRllRyAMaLGzbm4flOcNn4tyAMe1bPy8lJM3IV1tGm0QtcG5n1dh5r002yyF1sH1Yo8eEXcueK
    

    This is your mono script placed before my portamento script....

    as you will see when on alone the porta script will glide happily single notes or chords...but add in the mono script, which does some NoteOff work, and the porta is left thinking that it needs to deal with notes that no longer exist...



  • I'll play around with this and see what I can come up with. Any reason you're using an array to store note IDs instead of a MIDIList?



  • @d-healey yep laziness ☺



  • I found a redundant if statement.

      if (Synth.isLegatoInterval())
                {
                    local dif = LastNote - Message.getNoteNumber();
                    if (AllKeys.getValue() == 1 && Synth.isLegatoInterval() == false)
    

    The second isLegatoInterval() will never be false. This isn't part of the issue though.

    A quick fix to the error you're getting is to alter your port script's note off callback like so:

                        if (Message.isArtificial())
                            Synth.noteOffByEventId(tid);
    

    You'll get some nice new hanging note issues to fix when the mono script is disabled 🙂



  • @d-healey said in Synth.isNote(eventID):

    if (Message.isArtificial())
    Synth.noteOffByEventId(tid);

    Thanks yeah the redundant if statement I know about - being lazy again...

    So this sorta works - in that it fixes the problem if I check in the porta script if mono is running and handle each case slightly differently.

    But this breaks all sorts of encapsulation guidelines I'd really like to keep to....



  • @Lindon so back to my first point/question(s)

    any one know if this is do-able and would be willing to give it a shot?



  • @Lindon I think it's doable, but I think I'd need to rewrite the port script somewhat. Could you give me a breakdown of what the port script should do so I don't have to reverse engineer yours?



  • @d-healey yeah I mean give it a shot at adding in the C++ code to get us to

    Synth.isNote(EventId);



  • @Lindon Oh I meant independent mono and poly scripts working in harmony was doable, I'm sure the isNote thing is doable too but not sure how to tackle it.


Log in to reply
 

20
Online

736
Users

2.9k
Topics

24.7k
Posts