I have a plugin that is using the MidiKeyboardState noteOn and noteOff methods.
At the end of the timercallback method I placed in the editor I use keyboardState.processNextMidiBuffer() to send all the note on and off events to a buffer I created in the plugin processor. This buffer then gets swapped with the midiMessages buffer in the processBlock message of the processor.
Every now and then I get a MidiMessage exception if the plugin runs for more than a minute and in debugging the following code appears:
What determines the datasize of the midiMessage?
Should I be locking the midibuffer at any point to avoid this?
The timerCallback() method in the plugin processor is refreshing at a rate of 100Hz.
Any suggestions?
That assertion is raised when the parameter dataSize is zero or less, so I imagine at some point you are attempting to create a MidiMessage with sizeof used to determine dataSize. But are you checking to make sure sizeof is greater than zero before creating the message?
Could it be the intermittency of the error is not time-based, but input-based - it happens when you stop passing midi input in?
This is likely the cause of the problem. Normally the MidiKeyboardState would be a member of the AudioProcessor, and you’d call processNextMidiBuffer directly inside AudioProcessor::processBlock.
Exception thrown at 0x00007FFEC20BFAAD (ntdll.dll) in JucePresetManager.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
I believe this is pointer related but the problem is the MidiKeyboardComponent contructor in the PluginEditor is not accepting a std::unique_ptrjuce::MidiKeyboardState
A brief outline of what I have:
In PluginProcessor.h declared keyboardstate as a private variable.
Could you post the whole call stack? not just the crash point? this may contain the forensic evidence needed to reason about this problem. you know, this kind of thing…
A8Manager.exe!juce::detail::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 263 C++
A8Manager.exe!juce::MessageManager::runDispatchLoop() Line 112 C++
A8Manager.exe!juce::JUCEApplicationBase::main() Line 269 C++
A8Manager.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 288 C++
[External Code]
If you break in the debugger at the beginning of the CustomMidiKeyboardComponent constructor, does the MidiKeyboardState argument definitely reference a valid object? Is it possible that you’re passing dereferencing a null pointer and passing that accidentally?
This gives a different exception than before with the following call stack that breaks at:
|>|JucePresetManager.exe!std::unique_ptr<juce::MidiKeyboardState,std::default_delete<juce::MidiKeyboardState>>::get() Line 3219|C++
I don’t fully understand pointers to be honest I have just referenced and deferenced until I got something that ran and I cannot find any example in these forums of the constructor of a midiKeyboardComponent in a PluginEditor which I feel is all I need to know now.
Allright so I’ve decided to go back to my original setup of having the keyboardState in the editor. This gives a datasize exception after some time fo running the plugin. I may need to override the keyboardstate methods involved to check for the datasize of the message. I know ideally the keyboardstate should be in the processor but the results of this structure are different exceptions. The only JUCE example I see is one of an audio app and there is no official example of a plugin using keyboardState that I can find so I’ll have to wing it. Thanks for everyone who reached out I’ve got something that works but is by no means the textbook way to do things.
@reuk , that’s helped me a lot. In the PluginEditor I was using audioProcessor.keyboardState to access the keyboardState in the PluginProcessor but this did not work in the contructor of the PluginEditor. Replacing this with p.keyboardState worked for some reason my guess is the audioProcessor identifier isn’t defined yet at that point. Thanks for everyone’s help. All good now.