Would it be possible/sensible to implement support for the C++11 range based for loops in the MidiBuffer class? At the moment, having to use the MidiBuffer::Iterator etc is somewhat painful and messy.
Yes please… +1
It’s a little bit awkward because it needs to return both a message and time, but I guess the value the iterator produces could be a struct with a buffer pointer, size and time.
or a std::pair<MidiBuffer, int>
?
Not really - you don’t really want to be passing a by-value copy of the message around, because this will often be called on the audio thread
This will be included in JUCE 6 (we got there in the end!)
Hi,
That was a great idea. Can you overload the “->” operator in MidiBufferIterator too?
I’m thinking of this case where I need access to the iterator to jump to a specific sample inside the loop:
for (auto midiMessageIt = midiMessages.begin(); midiMessageIt != midiMessages.end(); ++midiMessageIt) { const MidiMessage m = midiMessageIt->getMessage(); const int mPos = midiMessageIt->samplePosition; if (jump) midiMessageIt=midiMessages.findNextSamplePosition(futureSample); }
Would be slightly cleaner than the current:
for (auto midiMessageIt = midiMessages.begin(); midiMessageIt != midiMessages.end(); ++midiMessageIt) { const MidiMessageMetadata metadata = *midiMessageIt; const MidiMessage m = metadata.getMessage(); const int mPos = metadata.samplePosition; if (jump) midiMessageIt=midiMessages.findNextSamplePosition(futureSample); }
Thanks!
Unfortunately we can’t do this easily - operator->
normally returns a pointer to whatever operator*
returns. In the case of MidiBufferIterator, operator*
returns a temporary, so operator->
(if it existed) would return a pointer to a temporary, so that’s not viable. We could instead keep a copy of MidiMessageMetadata
inside the iterator and return a pointer to that, but that would weigh down the iterator objects and ideally those should be very cheap to copy around.
In the absence of operator->
you can still get at the message with a single line:
const auto message = (*it).getMessage();
Got it. I agree that it is better to keep the iterator object light and that (*it).getMessage()
is simple enough.