receive and react to MIDI input

elsjaako elsjaako at
Thu Jan 29 20:33:15 CET 2009

Hi all. I want to write an application that reads midi notes and then
does something (specifically, play sound files, but that doesn't
really matter for this question). I'm on windows.

I went on MSDN and tried to get it to work, and I found myself getting
pretty far (considering how little I know about all this), but I
finally got stuck.

I get en error referring to a Null pointer.

What I tried to do is make it run MidiSigReceived every time a signal
is received. I will add the processing as soon as I got this step
working. I do not have my keyboard plugged in, so my computer should
not receive signals. MidiSigReceived is run once though, and only
after that does the error occur.

What I think the problem is is that midiInID has to be of type
HMIDIIN. Somewhere in the relevant .h file, I found:

DECLARE_HANDLE I couldn't find in the headers, so I looked on the
Internet and found:

#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef
struct name##__ *name
#define DECLARE_HANDLE(name) typedef HANDLE name

I think this means that the following could be said:

typedef void *HANDLE;
struct HMIDIIN##__ { int unused; }; typedef struct HMIDIIN##__

but what exactly that means is I think beyond my C abilities. It seems
that a HMIDIIN is a pointer to a structure with one element: unnamed.
My attempts to figure it out didn't change the error at all. I find it
even more confusing considering midiInOpen requires a pointer to such
an object.

The relevant MSDN page:

This is what I have:


from ctypes import *
from ctypes.wintypes import *

winmm = windll.LoadLibrary("winmm")

#structures and such
CALLBACK_FUNCTION = 196608 # hex 30000
class MIDIOUTCAPS (Structure):
    _fields_ = [("wMid",WORD),
                ("szPname",WCHAR * MAXPNAMELEN),

# The next part defines the callback function

def MidiSigReceived(a,b,c,d,e):
    print a,b,c,d,e

midi_get = CMPFUNC(MidiSigReceived)

midiInID = c_long() #The ID of the Midi connection, so we can close it

winmm.midiInOpen(byref(midiInID), # reference to the connection ID
                 0, # Midi device to use
                 midi_get, # callback function
                 0, # instance data
                 CALLBACK_FUNCTION) # Callback flag, makes it use the
callback, change it to 0 to remove error

# Close the connection

Or, as far as I could understand, you could use the HMIDIIN thing:

class MIDIHANDLESTRUCT (Structure):
    _fields_ = [("unused",c_long)]

midiInID = HMIDIIN()

If anyone could help, I would greatly appreciate it.

Bart de Waal

More information about the Python-list mailing list