receive and react to MIDI input

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
 
E

elsjaako

There is a Python MIDI module, i think it is pyMIDI, have you checked
it out?

Thank you for the responce. Unfortunately, that package is for OS X
(it doesn't say that clearly on the website). But it might indeed be
worthwhile to mention that I'd be more than happy to use a library, or
a finished product (I asked for that elsewhere, nobody had any good
ideas)
 
E

elsjaako

I think this means that the following could be said:

typedef void *HANDLE;
struct HMIDIIN##__ { int unused; }; typedef struct HMIDIIN##__
*HMIDIIN;
I figured this problem out (I'm sure there will be more...):

A handle should just be a c_void_p ...
 
E

elsjaako

Thank you for the responce. Unfortunately, that package is for OS X
(it doesn't say that clearly on the website). But it might indeed be
worthwhile to mention that I'd be more than happy to use a library, or
a finished product (I asked for that elsewhere, nobody had any good
ideas)

Never mind. I was wrong. It still doesnt work. Just managed to get a
normal error instead of WindowsError: exception: access violation
reading 0x00000000
 
E

elsjaako

Never mind. I was wrong. It still doesnt work. Just managed to get a
normal error instead of WindowsError: exception: access violation
reading 0x00000000

Finally got it to work! I will soon packige it and publish it
somewhere, so that the next person doesn't have to get frustrated
(hint: use WINCFUNCTYPE)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top