Event data inside of External c++ node
-
I have this node.
I'm looking to pick up on event data inside of the c++ node.
I have managed this for the Note number using:auto& v = voiceData.get(); v.midiNote = e.getNoteNumber();
Inside of the hise event callback.
But for events created in the on_note() such as:
// Detune Event globalRouting.setEventData( EventID , 0, DetuneAmount);
What would be the procedure to get hold of these inside of a node?
I'm not very familiar with Hise's event system.I'm trying to get polyphonic pitch bends on my c++ node, which is handling it's pitch internally currently.
-
-
@griffinboy hmm currently the event data system does not work with hardcoded FX or custom C++ nodes (it's on my list to support this at some time, but it's not trivial to communicate this over the DLL boundaries).
I would recommend to add another parameter called FreqRatio that you can use to detune the sample playback, then modulate it from something in scriptnode (eg. the mpe node that will pick up the correct pitch bend message for the channel that started the note).
This snippet uses the inbuilt oscillator and the control node in MPE mode to change the pitch.
EDIT: If you want to use the event data system, you can also use the event_data_reader node instead of the midi_control node.
-
Get the event reader node in scriptnode and plug it into your c++ node.
You need to add another parameter for it, and your c++ node needs to be polyphonic.
-
This post is deleted! -
Thanks.
It's the polyphony that is giving me a headache!
Simply sticking a pitch parameter on my node I would assume would control all voices at once.
edit*
Actually... it seems to kind of work. I need to investigate the polyphony source code! I must not understand how it's working. -
-
@griffinboy said in Event data inside of External c++ node:
I must not understand how it's working.
The secret ingredient is this template container class:
https://docs.hise.dev/scriptnode/snex_api/containers/polydata.html
Relevant part:
// If you want to change the data through a parameter callback // it's recommended to use the iterator. template void setParameter(double value) { // the iterator will either loop through // all data elements if it's outside a // voice rendering (most likely caused by a UI callback) // or just one element of the active voice (most likely used // by modulation inside the audio rendering). for(auto& d: data) d = (float)value; }
So if you're modulating a parameter that is changing a PolyData object through a cable connection, it will change only the data for the current voice if the source event is happening in the audio rendering (like the control node) OR change all voices if the source event is outside of the audio rendering context (like when moving a slider).
Be aware that this is multithreading-safe, so if you call this from the UI thread while the audio is rendering, it will still correctly detect that it should change all voices (it achieves this by registering the audio thread ID to the polyvoice manager that you will give it in the prepare call)