How to get event ids for artificial events?
-
This should record as many event ids per key as needed --I didn't set a max number.
Here's what I got!
function onNoteOn() { Message.ignoreEvent(true); note = Message.getNoteNumber(); if (keyDown.getValue(note) == 1) keyVoiceCount[note]++; g_group_allows[G_START] = 1; eventIds[note][keyVoiceCount[note]] = Synth.playNote(note, 64); eventTimeStamp[note][keyVoiceCount[note]] = Engine.getUptime(); keyDown.setValue(note, 1); } function onNoteOff() { if (pedal == 0) { keyDown.setValue(Message.getNoteNumber(), 0); note = Message.getNoteNumber(); for (v = 0; v <= keyVoiceCount[note]; v++) { Synth.noteOffByEventId(eventIds[note][v]); if (delayedEventIds[note][v]) { Synth.noteOffByEventId(delayedEventIds[note][v]); delayedEventIds[note][v] = 0; }; eventTimeStamp[note][v] = 0; }; keyVoiceCount[note] = 0; }; } function onTimer() { for (n = 0; n < 128; n++) { for (v = 0; v <= keyVoiceCount[n]; v++) { if (eventTimeStamp[n][v]) { playPos = (Engine.getUptime() - eventTimeStamp[n][v]) * 1000; playPos = Engine.getQuarterBeatsForMilliSeconds(playPos); if (playPos > 4 && !delayedEventIds[n][v]) { g_group_allows[G_START] = 1; delayedEventIds[n][v] = Synth.playNote(n, 64); }; }; }; }; } function onController() { if (Message.getControllerNumber() == 64) { if (Message.getControllerValue() > 5) { pedal = 1; //Console.print("pedal down"); } else { pedal = 0; for (n = 0; n < 128; n++) { if (Synth.isKeyDown(n) == 0 && keyDown.getValue(n) == 1) { keyDown.setValue(n, 0); for (v = 0; v <= keyVoiceCount[n]; v++) { Synth.noteOffByEventId(eventIds[n][v]); eventIds[n][v] = 0; Synth.noteOffByEventId(delayedEventIds[n][v]); delayedEventIds[n][v] = 0; eventTimeStamp[n][v] = 0; }; keyVoiceCount[n] = 0; }; }; }; }; }
So basically now you can have multiple parallel sequences of artificial events on the same key, which are note off'd correctly by the pedal.
Before, I did this by using
Synth.addNote()
to schedule the sequence of artificial events, but I was running into some problems there.This is with Retrigger set to "Do nothing"
Man, this was a lot of work! Maybe I should have just done the "Kill Duplicate" option and just NOT allowed overlapping swells on the same key haha :face_with_tongue:
-
Maybe I should have just done the "Kill Duplicate" option and just NOT allowed overlapping swells on the same key haha
Looks like you're having fun though :)
-
Yep, I'm learning a lot :)
-
Yep, I'm learning a lot
Make sure you use the
reserve
function for all those arrays to avoid allocating items in the MIDI callbacks:https://docs.hise.audio/scripting/scripting-api/array/index.html#reserve
-
@Christoph-Hart Would an array of MIDI lists be more efficient?
-
For a multi-dimensional array, would
reserve
make sense used this way?delayedEventIds.reserve(128); // note slots delayedEventIds[n].reserve(16); // reserve 16 voices per note slot delayedEventIds[n][v] = Synth.playNote(n, 64);
-
Yes. You might need to initialise the element at
delayedEventIds[n]
as array before calling reserve, but then it should work.@d-healey the efficiency of the MIDI list gets interesting as soon as it helps you avoid writing for loops, so
- searching for an item
- clearing all items
It will speed up things a bit.
The nested for loop in this example will most likely be the bottleneck, so I would start optimizing there on a higher level though...
-
Cool, yep it gets initialized in the
onInit