I believe I found a bug in the latest version of JUCE which seems to have been already in somewhat earlier versions too:
Calling the below method:
midiBuffer->addEvent(juce::MidiMessage::programChange(midiChannel, patchNumber), startSample);
…causes an assertion failure in juce_MidiMessage.cpp line 169 in constructor:
MidiMessage::MidiMessage (const int byte1, const int byte2, const int byte3, const double t) noexcept
The construcor is called via:
MIDITimer::hiResTimerCallback()
…which in turn calls:
void MIDITimerOutputDevice_Impl::sendBufferedMIDIMessages(const double current_time_ms)
…which eventually lead to calling that MidiMessage constructor with the assertion in it.
I believe the program change message is 2 bytes long and the above MidiMessage’s assertion probably assumes it should be 3 bytes long.