Iterate midiBuffer to heavy?

Hi, I have a an AudioProcessor that incapsulates an AudioProcessorGraph. I want to send allNotesOff, allControllersOff and allSoundsOff to processors in chain and I do it in processBlock of my AudioProcessor this way:

midiMessages.clear();

for (int ch = 1; ch <= 16; ch++)
    {
        midiMessages.addEvent(MidiMessage::allNotesOff        (ch),      0);
        midiMessages.addEvent(MidiMessage::allControllersOff(ch),      0);
        midiMessages.addEvent(MidiMessage::allSoundOff       (ch),      0);
    }

In my chain I added some MidiProcessors that I created: They take midiBuffer, iterate messages received and do something with those messages (transpose, filter etc.), here an example:

void MidiChannelFilter::processBlock (AudioBuffer<float>&, MidiBuffer& midiBuffer)
{
    MidiBuffer newMidiBuffer;

    for (const MidiMessageMetadata metadata : midiBuffer)
    {
        const MidiMessage message = metadata.getMessage();
        const int ch = message.getChannel();
        const int metadataPosition = metadata.samplePosition;
        
        if (ch >= 1 && ch <= 16)
        {
            for (MidiChannel channel : channels)
            {
                if ( (ch != channel.channel) ) { continue; }
                
                if ( (!(bool)channel.filtered.getValue())            ||
                     (leaveNoteOff && message.isNoteOff())           ||
                     (leaveSustainOff && message.isSustainPedalOff()) )
                {
                    newMidiBuffer.addEvent(message, metadataPosition);
                }
            }
        }
        
    }
    
    midiBuffer.swapWith(newMidiBuffer);
}

All works, but I noticed that when this midi processor is getting the allNotesOff, allControlsOff and allSoundsOff it requires a lot of cpu usage to iterate throw messages especially at 32 or 64 samples (that is the samplesPerBlock that I use to process all other audio processors without problems!) and often the CPU usage is exceeded and all the process is blocked for a while…

Am I wrong in something? I cannot think that iterate throw midi messages could be so heavy, but if I comment all codes from for (const MidiMessageMetadata metadata : midiBuffer) there are no problems…

Has anyone else encountered this problem? :blush:

midiBuffer.swapWith(newMidiBuffer);
From the doc: This is a quick operation, because no memory allocating or copying is done, it just swaps the internal state of the two buffers.
the issue is that you swap with a midi buffer allocated on the stack so recipe for problems.

1 Like

M… But I don’t think the problem is that… I commented that line and compiled and the problem remains…

I would avoid creating the MIDI buffer on the stack as well as it will allocate in the audio thread which can lead to some CPU issue.