What Am I missing from Synth.noteOffFromEventId?
-
Hi,
I'm currently trying to get a harmonised chord from single note performances, and am able to get the harmonisation I want, and even shut it off in onNoteOff when using Engine.allNotesOff. But it is causing an issue if you end up bumping two notes into each other in performance. I.e letting go of note1 just after having pressed note2 will result in Note2's harmonies and root being turned off too.
After quite some time reading and re-reading, then re-re-reading the handful of posts here regarding this, I get that I need to use noteOffFromEventId. I also get that I'll need to pass the eventId's into this via an array etc... and make them all artificial. I just can't get it to work properly, and I think I'm missing a simple fundamental. Can anyone jot down here, in the simplest form possible, the following pretty please? How would it look in it's most basic form (1 note triggering 2 pitches, with both being turned off on release. But without cutting off any notes that might have been pressed before the release of note1 comes...) Here's some of my assumptions, but I've tried many other variations on this, so this might not be representative of some of the versions I came up with that got a little closer... I'm loosing the will! thanks all.oninit reg lastNote = []; //declare the arrays needed (this is my assumption, I've also tried this not as an array but rather just passing the Message.getNoteNumber as a variable) reg eventId = []; //declare the arrays needed (this is my assumption) onNote //how should this be handled and look in onNote? Message.ignoreEvent(true); //I think from what I've read I need to make these all artificial with Message.makeArtificial() but I just can't get it there in terms of how the below needs to be written to do this job. Synth.playNote (Message.getNoteNumber, Message.getVelocity); // 1.play the actual triggered pitch Synth.playNote (Message.getNoteNumber + 4, Message.getVelocity);// 2.play for example 4 semitones higher as a maj3rd harmony lastNote = Message.getNoteNumber(); //send collect that stuff in an array/or variable I've tried both (this assumption) eventId = Message.getEventId(); //send collect that stuff in an array once multiple notes are being triggered (this assumption) onNoteOff //how should this be handled? Message.ignoreEvent(true); //this is where I have tried a huge amount variations on a theme, be it turning the lot off, or trying to selectively turn off the incoming notes with noteOffByEventId etc... to no avail... //I assume I need to wrap it up in a for loop and call in the eventIds I just can't get it functioning and am completely lost. ```
-
Here are some notes on your code
Message.getNoteNumber
this is a function call. It must end with()
. Same with.getVelocity
.lastNote = Message.getNoteNumber();
lastNote is an array so you have to specify which array element you want to store the value inside using square brackets[]
. Although for a lastNote you probably don't want to use an array anyway since it's just a single value.reg eventId = []
A midiList would be more suitable than an array here.Here's a working example. There is no need to store the last note and there is no need to ignore events.
HiseSnippet 972.3oc2W80aaaCDmx1pn1cqXsnXnOxG1CNXYF1aYsEXXnIwwtvXwIFQoY6sBVpy1DQhTihxcFC6K09jrOJ8av1QIYaoFg.GisUr4GLLu+v62c72cjdhVwg3Xkl3z7xkQ.w4Sb8VJMy6OmIjjQmPbdn6XVrAzzLQGuLhEGC9DGm5uxJvoYCR5m2+xiYALIG1HhPtRI3vohPgYizIG9ChffgLe3RQXAqO3vQbkruJPkf3otaWRDieMaFbFyZVMWhy8F3KLJsmgYfXzliU9K8lqdmLy9qDwh2F.1E8Hd3FkIlzetHvexpbMlPbbmrIyqmk4OwcrvWrV9lJvmkpftwih0.mZ2Fj5cGfjSAH0HCROx0iqEQlMZr34Atij3AxTFVpKBkLaI09cG29JzBooSH6ZXnFWr1i1Oqa28o3W68csZogYTXAZ3H+X52SGHmIjPGtFvbwlymJhMsQCmlH4FgRRUxyTF3bY68Z8qsZFn3r.pD8bLhN7fpyLvXM3rjv2BZqm41rnrMWAnXgYo0hVMWgfNwnFVPBzVtOMkE1IJfsztgskzujdv9zE6gd7asneHflNcqQTqlYasLyuiWNHK7sWCiYqgwMilsvpUAA18xFvOPskPWslbGaKSABlI1Hr1P7DuLM5daGMhmcNWvPkbjTXNOBxWOTE3aoG1eeSRGImnf+50iNgYXVdXtLztHPaDV33bBr.ajyXkMcOAhu1nhvV4aPYwlEkeR.yTtCxNpHWAVOJQasTSYLxFJNJ4NzV08Vaq1VH9H2IBCed0XrVEXDqT+Sfw7gQep6foSAtYC.a3N7m10IOae3eXV3efqGNIHsQIM3ed5Z5OxV.zWARPaKd8tkKC9is8xfns9xfy4FL7WpYx3HUboM1CBEWpj1pvFguNFG8A+7E1Syhx6qX5JU89WNDSxJ8wiYRzozhiBUIRSIZP8xmCM1tV2xcDEruhqFZ7Q31p+dZq9H14W5B0lqvnmHLJ.FHWfWAgRrX7w37rorj.yJokI1iURUzbkTvKdpeAXzhYy.cQrWYBcjwfOiYijmb3EP.vJxf+hCOEYdLMVmfcrVb2ebQkmWO0MCtTa2H8+tSrq++6I1WnRLB4rwLjD9K3qYwm23gCJ4.FcoDBvM20olcXW15t10YSJk9oK9S7Stxd10N4J6sR4+JwHjw0p2vydajkmd+TIXdKSeyeS7Oefqo8HouWB8ysamtjPbB2a3baI9qvAlU6yWuC97M6fOGrC97s6fOOaG7446fOu3V8wd4xQIFUXVKGJXxfzGN53LPxP1aJSm7WvWgD9F
-
@d-healey Oh that is so beautifully simplistic! That single elegant solution has cleared up a handful of things in my head with working in HISE. Thanks David, you're a hero. Oh yep, well spotted, I did know the () on function call, I just wrote it like that accidently in the snippet direct on my post... silly me!
I think this is one of the final hurdles left on my first foray into porting one of my Kontakt libs into HISE to test the waters. I'm loving the workflow in HISE and really everything about it. It's so much more ergonomic and things seem much more intuitive (once the occasional new language hill is climbed).
Thanks again -
@d-healey Egg on my face... we're not out the woods yet. One follow up... How does this line:
'eventIds.setValue(n, Synth.playNote(n + 4, v));'
Become usable for 2 or more additional voices? I get hanging notes when simply duplicated. Assuming I can just wrap it in a for loop (in onNote and NoteOff) or does the initial declaration have to change? I'll start trouble shooting this myself now, but as I had replied already I thought I'd get this issue in there too so you're not replying endlessly to my Qs!
Thanks,
-
That line stores the eventId indexed with the note number. So if you duplicate that line you are overwriting the effect of each line that goes before it. One simple solution is to use an array of midiLists.
@Christoph-Hart does putting midiLists in a reg array negate the efficiency of using a midiList?
HiseSnippet 1011.3oc2W01aaaCDlx1ZX1cqXcnXXejeXevAKyvJMKq.ECMIN1EFKNwHJMa.EEErTmsIhDoFEk2LF1+q8yX+T5+fsiR9EoT27hw5v57GLLu6dDetS28P5gZEGRRTZhS8ymECDmOw0elzLoyDlPR5eDw49tCXIFPSyMc3rXVRBDPbbp9LqAm50HYedySOjExjbXkIB4BkfCGKhDlUVGt+OHBC6wBfyEQEhd286yUxNpPUJxmptsIwL9krwvILaXUbINeT2.gQo8MLCjPbpcnJXl+D0uHyi+BQh30gfcgGwGeP4l6oBCrL1ZkzYhHLX3h7NgPbbGtpJTMuJ7P2Ah.wR6qpFeVlC5JDEqGNUJSupknmWQ50t.8VCkbJPoZ4T5At9bsH1rxikO2ysuDe4Lhgk8hTIOVRk+nhaGEFgzzJhcIzSiKVhn4dsauME+ZqmzngFFSgoXf8CRneO8EckiERnEWCXxXS5iEIllasM8t53kOownTI2HTRpRdhx.mJatUieqQ8PEmERk3tM.yH7EcqwfwFvIoQuFzMQZMOloki4B.MKLyrQzn9BV+h1urUB5jElBMkaSyZjaEGxlYelMkzult61zoaYerKw3ciX16svryMh4wyw76MnWM2GM5Vm7Mpm+nk43NbV2bFzrXFOdISxH4Mgv6NiXmqhnbRYauzpvPKks40UbaGwWum4.aJyxWrfY2gkAh88kGlbe2CSEm044c6EBTI6KElSiA46RAfLeDA+0y6eDyvrSfysgwECZivRAmifonbV97Xc2ifjKMpXTP6sFVQYBUPZHyTV6vJXN2AVCJMvZGJkIXOcQA0+wDTtsT7AtCEF9j0ywJqgiXk58AGmKC+otcGMB3lUDrlaue58ilaws+94a+8b8QAsr4irM+KxVS+Q1Tf9LPBZawy6ZNR7OusGIFeqOR7TtA29y0LYRrJozC1GhDmqj1pvJiOOAE8ge9L6ayh16nX5055MOsGljqEiOyjpyZKNHRkJMkZCpdcGM6sgGMW6+bGM+AvvdoaOTeAG8EQwgPW4T7rSzhkieNJgMhkFZVXsbu7.kTEOQIE7hunOCLZw3wftH2WaBcfwf2eakkGt+YPHvJ1z9U6eL1rwzXcB1vZg2c9lTq880W5lSWpc.j9gqHc0+eKRelJ0HjiGvvlveEuT.dYIeTajC3tKkPn8hBNUr5a4qaaWmKNJCxV7W3m4N8rqcl6zagy+U1iHFWqdEO+JP19zONyBl2xr+rSc7ecgqodjrqEg3ba2pMIBU3dEmaKweCJXtdL6rAXdzFfY2M.y2tAX1aCv7ca.lGesXrGtbPpQEkOxgFF1M6thNNckLr6MqSm72fpvQCB
-
@d-healey Ah I see, that is certainly doing the trick. I've also placed the NoteOff stuff in a for loop to cut down on lines of code as the stacks of chords grow, like this:
for (i = 0; i < eventIds.length; i++) { Synth.noteOffByEventId(eventIds[i].getValue(n)); }
Or is this a bad idea as it's a loop within a real time callback? From an efficiency perspective, the chords I'm building a large tutti orchestrations, so I might have up to 10 elements to my eventIds array. Am I likely to create overheads by generating that amount of midiLists?
Thanks as always!
-
@BM_FORUM I think a loop in this context should be ok. The number of midiLists is also fine.
-
@d-healey Excellent, thanks for confirming! :thumbs_up_light_skin_tone: