Question about using an inline function from a .js file on the MIDI callbacks
-
Just to make sure, does calling an inline function on the MIDI callbacks use the audio thread for that inline function? My impression is that "inline functions" in HISE are essentially a copy pasted into the script, so having an inline function on the onNoteOn for instance is like placing that script directly on that callback, am I right?
I just want to understand how it works in relation to the audio thread.
-
@VirtualVirgin said in Question about using an inline function from a .js file on the MIDI callbacks:
in HISE are essentially a copy pasted into the script, so having an inline function on the onNoteOn for instance is like placing that script directly on that callback, am I right?
I thought that too, but apparently it's not as straightforward as that. Christoph corrected me on a thread somewhere not too long ago.
-
@d-healey said in Question about using an inline function from a .js file on the MIDI callbacks:
@VirtualVirgin said in Question about using an inline function from a .js file on the MIDI callbacks:
in HISE are essentially a copy pasted into the script, so having an inline function on the onNoteOn for instance is like placing that script directly on that callback, am I right?
I thought that too, but apparently it's not as straightforward as that. Christoph corrected me on a thread somewhere not too long ago.
Does that mean there is a preference for not using inline functions on the MIDI callbacks?
I'm getting a very laggy "reapaintImmediately()" in a onNoteOn inline function. -
@VirtualVirgin Always use inline functions unless you can't. They are more efficient than regular functions. More info here - https://forum.hise.audio/topic/79/scripting-best-practices
You UI script should be deferred so that the MIDI callbacks aren't running on the audio thread. That could be the cause of the lag.
-
@d-healey said in Question about using an inline function from a .js file on the MIDI callbacks:
@VirtualVirgin Always use inline functions unless you can't. They are more efficient than regular functions. More info here - https://forum.hise.audio/topic/79/scripting-best-practices
You UI script should be deferred so that the MIDI callbacks aren't running on the audio thread. That could be the cause of the lag.
I'm afraid I don't understand. Why wouldn't I want the MIDI callbacks on the audio thread?
I want the MIDI processing to be as fast as possible. I'm working only with MIDI anyway, so I have no audio to process. -
@VirtualVirgin said in Question about using an inline function from a .js file on the MIDI callbacks:
Why wouldn't I want the MIDI callbacks on the audio thread?
You would but not in your GUI processor. Check out that link I sent, the part titled "Separate MIDI processing logic from Interface scripts" explains the concept in more detail. ... Note that some of the info in the example script given on that page is a bit out of date.
-
@d-healey said in Question about using an inline function from a .js file on the MIDI callbacks:
@VirtualVirgin said in Question about using an inline function from a .js file on the MIDI callbacks:
Why wouldn't I want the MIDI callbacks on the audio thread?
You would but not in your GUI processor. Check out that link I sent, the part titled "Separate MIDI processing logic from Interface scripts" explains the concept in more detail. ... Note that some of the info in the example script given on that page is a bit out of date.
Oh, but that lag I am talking about here is in the repaint of the GUI.
In this case I need the GUI to be as snappy as possible to react to real-time MIDI input.
The repaints are often happening 50-200 ms late. I need them to be no more than 5. -
@VirtualVirgin Can you provide a minimal snippet to demonstrate the issue?
-
@VirtualVirgin Then it might be that your paintRoutine takes too long because it’s too complex. As @d-healey said a snippet would be helpful
-
@d-healey said in Question about using an inline function from a .js file on the MIDI callbacks:
@VirtualVirgin Can you provide a minimal snippet to demonstrate the issue?
It would be a bit difficult to edit this one down in a way that would demonstrate.
The mechanics are a bit intertwined at this point.Maybe I could give you a demo at some point?
At the moment there is only an inline function on the "onNoteOn"
This is the onNoteOn recorder inline function:
// use Recorder.noteOn() for onNoteOn callback inline function noteOn() { local c = Message.getChannel() - 1; local nn = Message.getNoteNumber(); //channel[c].notesOn[nn] = 1; channel[c].notesOnList.push(nn); channel[c].notesOnList.sort(); channel[c].velocity[nn] = Message.getVelocity(); //channel[c].eId[nn] = Message.getEventId(); //channel[c].timestamp[nn] = Message.getTimestamp(); channel[c].lastPolyCount = channel[c].polyCount; channel[c].polyCount++; channel[c].noteOrder.insert(0,nn); channel[c].lastNoteNumber = channel[c].noteOrder[1]; // count the amount of note ons and save the last one to compare local polyCount = channel[c].polyCount; local lastPolycount = channel[c].lastPolyCount; // record the pitch set to the channel object if (polyCount > 0 && lastPolycount < polyCount) channel[c].pitchSet.push(nn); channel[c].pitchSet.sort(); // pad pitch set recorder (REC) if (chordPads.rec.data.clicked == 1) { local padsSelected = chordPads.device.data.padsSelected; local rows = chordPads.device.data.rows; local columns = chordPads.device.data.columns; local ps = channel[c].pitchSet; local row = padsSelected[0]; local column = padsSelected[1]; local decimal = convertPSToDecimal(ps); local tValue = ps[0]; local chordSymbol = convertDecimalToChordName(decimal, tValue); // input the pitch set just recorded into the pad chordPadDataInputFromPS(ps, chordPads.pads[row][column]); chordPads.pads[row][column].repaintImmediately(); // send the PCS_LUTindex of the ps to the PCS Inspector PCSInspector.data.decimal = decimal; PCSInspector.data.tValue = tValue; PCSInspector.data.chordSymbol = chordSymbol; PCSInspector.repaintImmediately(); // this turns the recorder off at the last pad of the device if (padsSelected == [rows -1, columns -1]) { Console.print("last pad!"); chordPads.rec.data.clicked = 0; chordPads.rec.repaintImmediately(); chordPads.device.data.padsSelected = [0,0]; chordPads.pads[0][0].data.select = 1; chordPads.pads[0][0].repaintImmediately(); chordPads.pads[rows-1][columns-1].data.select = 0; chordPads.pads[rows-1][columns-1].repaintImmediately(); } } ``` The
PCSInspector.repaintImmediately();
and
chordPads.pads[rows-1][columns-1].repaintImmediately();
are very slow (like I said, about 50-200 ms late)
-
@VirtualVirgin said in Question about using an inline function from a .js file on the MIDI callbacks:
It would be a bit difficult to edit this one down
Go the opposite way. Start with a blank project and add just the parts necessary to recreate the issue. This is often the best way to find a solution to a scripting problem.
It looks like you're working a non-deferred script, I would start by deferring it.
-
@d-healey
The benchmark for the onNoteOn only clocks in at
-
@d-healey said in
It looks like you're working a non-deferred script, I would start by deferring it.
Well jeez. That worked!
For some reason I was thinking that "deferring it" was going to make it slower, so was supposed to be used for things that do not need to happen so fast. -
@VirtualVirgin Deferring it puts everything on the UI thread - the slow lane when compared to the realtime thread, but still fast to us mere humans.