I need to store MIDI keyboard activity.
This is my current render callback:
void getNextAudioBlock(const AudioSourceChannelInfo& bufferToFill) override {
bufferToFill.clearActiveBufferRegion();
MidiBuffer incomingMidi;
midiCollector.removeNextBlockOfMessages(incomingMidi, bufferToFill.numSamples);
//midiFromKeyboard.addEvents(incomingMidi, 0/*startSample*/, bufferToFill.numSamples, 0/*sampleDeltaToAdd*/);
// ^ ADD
// add events from playing midi-file
if (midifileIsLoaded && !isPaused) {
int sampleDeltaToAdd = -samplesPlayed;
incomingMidi.addEvents(*midiBuffer, samplesPlayed, bufferToFill.numSamples, sampleDeltaToAdd);
samplesPlayed += bufferToFill.numSamples;
if (samplesPlayed >= totalSamples) {
samplesPlayed = 0;
isPaused = true;
}
}
// pass these messages to the keyboard state so that it can update the component
// to show on-screen which keys are being pressed on the physical midi keyboard.
const bool injectIndirectEvents = true; // add midi messages generated by clicking on the on-screen keyboard.
keyboardState.processNextMidiBuffer(incomingMidi, 0 /*startSample*/, bufferToFill.numSamples, injectIndirectEvents);
synth.renderNextBlock(*bufferToFill.buffer, incomingMidi, 0 /*startSample*/, bufferToFill.numSamples);
}
I’m considering:
MidiBuffer midiFromKeyboard;
… and adding the line marked ADD above.
Is this healthy?
Just asking because potentially this buffer could grow huge, say I am playing & recording for an hour. So adding data in a render callback is surely going to occasionally force a malloc and memcpy of a big chunk of memory.
Maybe a better architecture might be to hold a vector of outstanding mini-buffers (each render callback that detects MIDI keyboard activity would add a new element) and periodically empty this vector into the main buffer on a separate thread.
There is just going to be some awkwardness involved with 2 threads playing with this vector.
Any guidance / suggestion / debate gratefully received!
π
