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(HMIDIIN);

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
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif


I think this means that the following could be said:

typedef void *HANDLE;
struct HMIDIIN##__ { int unused; }; typedef struct HMIDIIN##__
*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:
http://msdn.microsoft.com/en-us/library/ms709430(VS.85).aspx



This is what I have:

#imports

from ctypes import *
from ctypes.wintypes import *

winmm = windll.LoadLibrary("winmm")

#structures and such
MAXPNAMELEN = 32
MMVERSION = UINT
CALLBACK_FUNCTION = 196608 # hex 30000
class MIDIOUTCAPS (Structure):
    _fields_ = [("wMid",WORD),
                ("wPid",WORD),
                ("vDriverVersion",MMVERSION),
                ("szPname",WCHAR * MAXPNAMELEN),
                ("dwSupport",DWORD)]

# The next part defines the callback function
CMPFUNC = CFUNCTYPE(None, c_long, UINT, DWORD, DWORD, DWORD)

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
again

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
winmm.midiInClose(midiInID)

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

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

HMIDIIN = POINTER(MIDIHANDLESTRUCT)
midiInID = HMIDIIN()

If anyone could help, I would greatly appreciate it.

Bart de Waal
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to