midiInput oddity (on win32)


#1

Hi Jules!

I’ve got some code that listens to MIDI input, through doing this:

MidiInput *lpMidiInput = MidiInput::openDevice(lId, MyHandlerClass);

It then calls lpMidiInput->start()

… and I can capture lots of incoming MIDI events. In my test-case, these are MIDI sync events getting generated by cubase (pumping data out to a MIDI yoke port that my app is listening to for MIDI sync info).

I then call lpMidiInput->stop()

… and at some point later delete the lpMidiInput object.

When testing in the debugger, I get this in the debugger log:

The thread ‘Juce Midi’ (0x9bc) has exited with code 0 (0x0).
mytest.exe has triggered a breakpoint

And find myself in juce_win32_midi.cpp at this code (on the assertion … validityInt is zero):

    void handle (const uint32 message, const uint32 timeStamp) throw()
    {
        jassert (validityInt == 0x12345678);
        if (validityInt != 0x12345678)
            return;

The value of message is 0x000000f8 (i.e. timing clock).

If I go-up one line in the call stack, I can see that uMsg == MIM_DATA.

When seems to happen is that, at some point after the code calls midiInStop here…

    void stop() throw()
    {
        if (isStarted)
        {
            stopThread (5000);

            midiInReset (hIn);
            midiInStop (hIn);

… there can be a couple of MIDI messages left in the system, that aren’t delivered until the object is deleted. Strange?!

Putting a breakpoint in the stop code can cause those events never to appear.

So, there seems to be some timing-related weirdness going on, and looking at the forum, I might be the first person to have seen this in Juce. :slight_smile:

The juce midi input handling code for win32 looks entirely sensible to me, so I admit to being a bit stumped. I wonder if this is showing-up a small bug in MIDI Yoke, or something like that.

Any ideas what to do about this? AFAIK, the way you have written the code means that nothing should crash, but the assertions whenever I stop are somewhat annoying in this instance. :slight_smile:

Thanks in advance,

Pete


#2

Hi, we just got the same problem, it looks like Some MIDI drivers call midiInCallback() after midiInReset() and midiInStop()

It happened with MidiOverLan + MidiOx here

For now we just made a dirty fix with a static list of running midi threads and a lock to check if the thread is really valid.


#3

Agh… bunch of hackers!

This is why I put the validityInt stuff in there, but I guess it’s not working as well as it should. Maybe just tweaking the stop() method like this will sort it out?

[code] void stop() throw()
{
if (isStarted)
{
stopThread (5000);

        midiInReset (hIn);
        midiInStop (hIn);
        validityInt = 0;[/code]

#4

Hi Jules,

No, that doesn’t work I’m afraid. :frowning:

I suspect that as Thomas says, it’ll require the juce_win32_Midi.cpp file to be modified to operate some sort of dirty list. FWIW, the validityInt is of course private, not static, so when the callback occurs after the object has been deleted, this could point to any old bit of memory.

If only people wrote clean drivers, eh? :frowning:

Pete


#5

FWIW, I have for now temporarily disabled the two assertions related to validityInt in the juce_win32_Midi.cpp file, just to avoid the assertions getting in the way when I’m debugging my app… :slight_smile:

Pete


#6

Ok, I’ve checked-in a version that uses a static list instead… Should be a bit more robust.


#7

Hi Jules,

That updated version seems OK to me after some testing.

Many thanks!! :slight_smile:

Pete


#8