E
elsjaako
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
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