Juce plugin host assert in MidiMessageCollector

I build and run the Juce Plugin Host application, unmodified (latest tip). When I press a key on the midi keyboard, this assert goes off:

void MidiMessageCollector::addMessageToQueue (const MidiMessage& message)
{
    // you need to call reset() to set the correct sample rate before using this object
    jassert (sampleRate != 44100.0001);

I guess it’s just because you’ve not got an audio device running?

What if we are building a midi effect plugin with no audio needed?

I’ve got the same problem: prepareToPlay() is never called in the AudioProcessor (which I assume is normal because there is no audio involved). And the following assert gets triggered as soon as the first midi message is received:

void MidiMessageCollector::addMessageToQueue (const MidiMessage& message)
{
    const ScopedLock sl (midiCallbackLock);

   #if JUCE_DEBUG
    jassert (hasCalledReset); // you need to call reset() to set the correct sample rate before using this object
   #endif

I’m probably missing something but I don’t see what. Where am I supposed to call reset()?

1 Like

I am on Windows 10 using Juce 6.0.7 and I am getting the same jasset thrown. My Plugin works fine in Ableton or in the Juce PluginHost. It won’t run standalone.

void MidiMessageCollector::addMessageToQueue (const MidiMessage& message)

{
const ScopedLock sl (midiCallbackLock);

#if JUCE_DEBUG
jassert (hasCalledReset); // you need to call reset() to set the correct sample rate before using this object
#endif

I’m on Windows10 using Juce 7 and have the same problem with a standalone application running as a midi effect / without audio input/output. As soon as my application starts I get this exception. Disabling the midi input completly with setMidiInputDeviceEnabled(deviceID, false) works for me but I’d like to be able to recieve Midi input.

You may be using the wrong class, as the documentation states:

Collects incoming realtime MIDI messages and turns them into blocks suitable for processing by a block-based audio callback.

Note the end portion of the description, suitable for processing by a block-based audio callback, clearly states it is inteded to be used with a block-based audio callback.

I’m never actively intiliazing anything related to Midi Input nor to a MidiMessageCollector. All I’m doing is accessing the juce::StandalonePluginHolder::getInstance()->deviceManager and then directly send Midi Messages with getDefaultMidiOutput()->sendMessageNow(). I don’t even use Midi Input at the moment.

I don’t wan’t to use audio or processBlock() at all and thats why I have the standalone application configured as a Midi Effect since that way I don’t even have to configure an audio device in the audio/midi settings panel.
I get the exceptions after starting the application (in debug mode) and I’m sure it should be possible somehow to use Midi Input with the application configured as a Midi Effect without getting these exceptions. Any hints are very welcome!

Sorry for the misunderstanding. If your not using it directly, we need to determine why it is being used. What is the call stack when you get the assert?

No problem at all and thanks for the reply.

The call stack is:

juce::MidiMessageCollector::addMessageToQueue(const juce::MidiMessage &) juce_MidiMessageCollector.cpp:54
juce::AudioProcessorPlayer::handleIncomingMidiMessage(juce::MidiInput *, const juce::MidiMessage &) juce_AudioProcessorPlayer.cpp:412
juce::AudioDeviceManager::handleIncomingMidiMessageInt(juce::MidiInput *, const juce::MidiMessage &) juce_AudioDeviceManager.cpp:1171
juce::AudioDeviceManager::CallbackHandler::handleIncomingMidiMessage(juce::MidiInput *, const juce::MidiMessage &) juce_AudioDeviceManager.cpp:99
juce::MidiDataConcatenator::pushMidiData<…>(const void *, int, double, juce::MidiInput *, juce::MidiInputCallback &) juce_MidiDataConcatenator.h:96
juce::Win32MidiService::Win32InputWrapper::pushMidiData(const void *, int, double) juce_Midi_windows.cpp:509
juce::Win32MidiService::MidiInCollector::handleMessage(const unsigned char *, unsigned int) juce_Midi_windows.cpp:184
juce::Win32MidiService::MidiInCollector::midiInCallback(HMIDIIN__ *, unsigned int, unsigned long long, unsigned long long, unsigned long long) juce_Midi_windows.cpp:261
<unknown> 0x00007ffc2c1056f9
<unknown> 0x00007ffc2c0cd38b
<unknown> 0x00007ffc2c0cd97b
<unknown> 0x00007ffc2c0cd56f
<unknown> 0x00007ffc6d75257d
<unknown> 0x00007ffc6e98aa58

from Thread-14-[wdmaud.drv thread] (22980). I have this exception only since I started sending Midi messages and for that I’m importing:

#include <juce_audio_utils/juce_audio_utils.h>
#include <juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h>

In order to access juce::StandalonePluginHolder::getInstance()->deviceManager and store a reference to the juce::AudioDeviceManager manager

A quick glance at the AudioProcessorPlayer code, makes it seem like this is indeed a limitation imposed by the Standalone code. The MidiMessageCollector requires a call to it’s reset function with a sample rate, and this is done in AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* const device). Ie. The Standalone Plugin build option does not support MIDI without an audio device inialized. While not ideal, it seems like one solution might be to configure the audio device with defaults, and have it pick a suitable device, thus hiding that from the user.

Thanks for the help, yeah I guess this will be necessary. At moment I’ll just keep having Midi input disabled alltogether.

Sorry to drudge up an old thread.

I’m hitting the assertion in a Standalone build of a plugin (with no changes to the standalone window) since updating to JUCE 7.0.10.

This is the full stack trace on Mac:

juce::MidiMessageCollector::addMessageToQueue(const juce::MidiMessage &) juce_MidiMessageCollector.cpp:54
juce::AudioProcessorPlayer::handleIncomingMidiMessage(juce::MidiInput *, const juce::MidiMessage &) juce_AudioProcessorPlayer.cpp:412
juce::AudioDeviceManager::handleIncomingMidiMessageInt(juce::MidiInput *, const juce::MidiMessage &) juce_AudioDeviceManager.cpp:1171
juce::AudioDeviceManager::CallbackHandler::handleIncomingMidiMessage(juce::MidiInput *, const juce::MidiMessage &) juce_AudioDeviceManager.cpp:99
<lambda>::operator()(const juce::universal_midi_packets::BytestreamMidiView &) const juce_UMPU32InputHandler.h:85
juce::universal_midi_packets::Midi1ToBytestreamTranslator::dispatch<…>(const juce::universal_midi_packets::View &, double, <lambda> &) juce_UMPMidi1ToBytestreamTranslator.h:76
<lambda>::operator()(const juce::universal_midi_packets::View &) const juce_UMPConverters.h:175
void juce::universal_midi_packets::Conversion::midi2ToMidi1DefaultTranslation<void juce::universal_midi_packets::ToBytestreamConverter::convert<juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&>(juce::universal_midi_packets::View const&, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&)::'lambda'(juce::universal_midi_packets::View const&)>(juce::universal_midi_packets::View const&, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&) juce_UMPConversion.h:222
juce::universal_midi_packets::ToBytestreamConverter::convert<…>(const juce::universal_midi_packets::View &, double, <lambda> &) juce_UMPConverters.h:173
<lambda>::operator()(const juce::universal_midi_packets::View &, double) const juce_UMPDispatcher.h:188
void juce::universal_midi_packets::Dispatcher::dispatch<void juce::universal_midi_packets::ToBytestreamDispatcher::dispatch<juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(juce::universal_midi_packets::View const&, double)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(unsigned int)::operator()(unsigned int) const juce_UMPDispatcher.h:58
void juce::universal_midi_packets::Dispatcher::dispatch<void juce::universal_midi_packets::ToBytestreamDispatcher::dispatch<juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(juce::universal_midi_packets::View const&, double)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(unsigned int) std::__1::for_each[abi:v15006]<unsigned int const*, void juce::universal_midi_packets::Dispatcher::dispatch<void juce::universal_midi_packets::ToBytestreamDispatcher::dispatch<juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(juce::universal_midi_packets::View const&, double)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(unsigned int)>(juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&), juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&), void juce::universal_midi_packets::Dispatcher::dispatch<void juce::universal_midi_packets::ToBytestreamDispatcher::dispatch<juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(juce::universal_midi_packets::View const&, double)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(unsigned int)) for_each.h:26
void juce::universal_midi_packets::Dispatcher::dispatch<void juce::universal_midi_packets::ToBytestreamDispatcher::dispatch<juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&)::'lambda'(juce::universal_midi_packets::View const&, double)>(unsigned int const*, unsigned int const*, double, juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(unsigned int const*, unsigned int const*, double)::'lambda'(juce::universal_midi_packets::BytestreamMidiView const&)&&) juce_UMPDispatcher.h:52
juce::universal_midi_packets::ToBytestreamDispatcher::dispatch<…>(const unsigned int *, const unsigned int *, double, <lambda> &&) juce_UMPDispatcher.h:186
juce::universal_midi_packets::U32ToBytestreamHandler::pushMidiData(const unsigned int *, const unsigned int *, double) juce_UMPU32InputHandler.h:83
juce::CoreMidiHelpers::Receiver::dispatch(const MIDIEventList *, double) const juce_CoreMidi_mac.mm:645
juce::CoreMidiHelpers::Receiver::dispatch(const MIDIEventList *, double) const juce_CoreMidi_mac.mm:702
juce::CoreMidiHelpers::MidiPortAndCallback::handlePackets<…>(const MIDIEventList *) juce_CoreMidi_mac.mm:750
juce::CoreMidiHelpers::CreatorFunctions::newMidiInputProc(const MIDIEventList *, void *, void *) juce_CoreMidi_mac.mm:860
invocation function for block in juce::CoreMidiHelpers::CreatorFunctions<(juce::CoreMidiHelpers::ImplementationStrategy)0>::createInputPort(juce::universal_midi_packets::PacketProtocol, unsigned int, __CFString const*, void*, unsigned int*) juce_CoreMidi_mac.mm:815
MIDI::MIDI_1UP_Deliverer::operator()(const MIDI::EventList *) 0x00000001c1a269b0
MIDIProcess::MIDIInPortThread::Run() 0x00000001c1a41e14
CADeprecated::XThread::RunHelper(void *) 0x00000001c1a292e4
CADeprecated::CAPThread::Entry(CADeprecated::CAPThread *) 0x00000001c1a2a610
_pthread_start 0x00000001a955ffa8