Hi all,
I am working on a project for a course Im doing which uses PD (in windows) to program a device which understands system exclusive MIDI messages. After discovering that sysex out doesn't seem to be fully implemented under windows yet I went ahead and wrote an external to do it. All is working fine but at the moment I have to hard-code the midi device number into the code.
What I would like to be able to do is to use the device which is selected in PD's midi settings. I've searched the lists but can't seem to find anything related to this. Could anyone tell me how I do this?
p.s. just in case anyone is wondering why I don't just patch the PD source tree (which would be easier of course): I don't want people to have to use a custom build. I would prefer that they can just link in an external at run-time. Also, this is just a small part of a larger project which we want packaged in one external.
Many thanks in advance,
Padraig Kitterick
Padraig Kitterick wrote:
What I would like to be able to do is to use the device which is selected in PD's midi settings. I've searched the lists but can't seem to find anything related to this. Could anyone tell me how I do this?
That's exactly the device you get when you read/write midi. Am I missing something? Or are you expecting the device to identify itself the way usb and firewire peripherals do?
Martin
Padraig Kitterick wrote:
What I would like to be able to do is to use the device which is selected in PD's midi settings. I've searched the lists but can't seem to find anything related to this. Could anyone tell me how I do this?
That's exactly the device you get when you read/write midi. Am I missing something?
That's what I expected too but no matter what I tried it would never send the midi sysex messages. However, if I added midiOutOpen() and midiOutClose() functions (which I shouldn't have to do as PD will have already opened the midi device) it worked fine.
At first I thought it was because the code was in an external but today I patched the 0.37-1test6 branch and the behaviour was the same: sending the messages without first opening the device didn't work. I had to explicitly open and close the device, which also requires I specify a device number...
As far as I can tell, it all comes down to the midi device handle. Calling the midiOutOpen() sets up the handle to that particular midi device. When I patched the source I made sure I was using the same handle as the other midi functions in the source too so it should work fine.
Just to let you know: the sys_putmidibyte() function which is implemented in 0.37-1test6 is a very similar function (using midiOutShortMsg() instead of midiOutLongMsg()) and it doesn't work either. My guess is that both are using the wrong device handle, or that the handle hasn't been set.
_Padraig
Or are you expecting the device to identify itself the way usb and firewire peripherals do?
Martin
PD-dev mailing list PD-dev@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-dev
I'm guessing, but s_midi_mmio.c has
static HMIDIOUT hMidiOut[MAXMIDIOUTDEV]; /* output device */
Declaring the array static here makes it visible only to the functions in the file s_midi_mmio.c
Martin
Padraig Kitterick wrote:
Padraig Kitterick wrote:
What I would like to be able to do is to use the device which is selected in PD's midi settings. I've searched the lists but can't seem to find anything related to this. Could anyone tell me how I do this?
That's exactly the device you get when you read/write midi. Am I missing something?
That's what I expected too but no matter what I tried it would never send the midi sysex messages. However, if I added midiOutOpen() and midiOutClose() functions (which I shouldn't have to do as PD will have already opened the midi device) it worked fine.
At first I thought it was because the code was in an external but today I patched the 0.37-1test6 branch and the behaviour was the same: sending the messages without first opening the device didn't work. I had to explicitly open and close the device, which also requires I specify a device number...
As far as I can tell, it all comes down to the midi device handle. Calling the midiOutOpen() sets up the handle to that particular midi device. When I patched the source I made sure I was using the same handle as the other midi functions in the source too so it should work fine.
Just to let you know: the sys_putmidibyte() function which is implemented in 0.37-1test6 is a very similar function (using midiOutShortMsg() instead of midiOutLongMsg()) and it doesn't work either. My guess is that both are using the wrong device handle, or that the handle hasn't been set.
I agree. When I gave up on the external and patched the source I added my own function sys_midisysexout() to s_midi_mmio.c, added the function declaration to the s_stuff.h header file and added my sysexout object next to the midiout object in x_midi.c
Technically I should then have access to the 'hMidiOut' handle, but I only think that handle means something immediately after you call midiOutOpen() within the same function. Otherwise it is just an empty struct (this would also explain why sys_putmidibyte() isn't working either).
Obviously if I need to call midiOutOpen() I need a device number, which is where the problem starts.
One thing I noticed: when you open pd's midi settings dialog it always lists the currently selected output device first. I could use midi_getdevs() to grab this first device id and use it in midiOutOpen().
Fingers crossed!
_Padraig
Martin Peach wrote:
I'm guessing, but s_midi_mmio.c has
static HMIDIOUT hMidiOut[MAXMIDIOUTDEV]; /* output device */
Declaring the array static here makes it visible only to the functions in the file s_midi_mmio.c
Martin
Padraig Kitterick wrote:
Padraig Kitterick wrote:
What I would like to be able to do is to use the device which is selected in PD's midi settings. I've searched the lists but can't seem to find anything related to this. Could anyone tell me how I do this?
That's exactly the device you get when you read/write midi. Am I missing something?
That's what I expected too but no matter what I tried it would never send the midi sysex messages. However, if I added midiOutOpen() and midiOutClose() functions (which I shouldn't have to do as PD will have already opened the midi device) it worked fine.
At first I thought it was because the code was in an external but today I patched the 0.37-1test6 branch and the behaviour was the same: sending the messages without first opening the device didn't work. I had to explicitly open and close the device, which also requires I specify a device number...
As far as I can tell, it all comes down to the midi device handle. Calling the midiOutOpen() sets up the handle to that particular midi device. When I patched the source I made sure I was using the same handle as the other midi functions in the source too so it should work fine.
Just to let you know: the sys_putmidibyte() function which is implemented in 0.37-1test6 is a very similar function (using midiOutShortMsg() instead of midiOutLongMsg()) and it doesn't work either. My guess is that both are using the wrong device handle, or that the handle hasn't been set.
PD-dev mailing list PD-dev@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-dev
It works! Just as I suspected, the 'hMidiOut' device handle is only relevant when you have just called midiOutOpen(). However, pd's sys_get_midi_params() function will return a list of device parameters (obviosly including device number) for all devices, and the currently selected device is always the first in the list. Now I can call midiOutOpen() and pass it the correct device number.
So now 'sysexout' object works fine, using whatever device is selected in the midi device menu. The next task is getting this to work in an external form...
The only problem is that sys_get_midi_params() is declared in s_midi.c as 'static void'. To call it from s_midi_mmio.c I had to change this to 'void'. This shouldn't really affect much but makes the patch a little more complex than I had hoped.
What is good is that its now clear why the existing sys_putmidibyte() isn't working. Hopefully this will help to fix this too.
Thanks for your help :)
_Padraig
Martin Peach wrote:
I'm guessing, but s_midi_mmio.c has
static HMIDIOUT hMidiOut[MAXMIDIOUTDEV]; /* output device */
Declaring the array static here makes it visible only to the functions in the file s_midi_mmio.c
Martin
Padraig Kitterick wrote:
Padraig Kitterick wrote:
What I would like to be able to do is to use the device which is selected in PD's midi settings. I've searched the lists but can't seem to find anything related to this. Could anyone tell me how I do this?
That's exactly the device you get when you read/write midi. Am I missing something?
That's what I expected too but no matter what I tried it would never send the midi sysex messages. However, if I added midiOutOpen() and midiOutClose() functions (which I shouldn't have to do as PD will have already opened the midi device) it worked fine.
At first I thought it was because the code was in an external but today I patched the 0.37-1test6 branch and the behaviour was the same: sending the messages without first opening the device didn't work. I had to explicitly open and close the device, which also requires I specify a device number...
As far as I can tell, it all comes down to the midi device handle. Calling the midiOutOpen() sets up the handle to that particular midi device. When I patched the source I made sure I was using the same handle as the other midi functions in the source too so it should work fine.
Just to let you know: the sys_putmidibyte() function which is implemented in 0.37-1test6 is a very similar function (using midiOutShortMsg() instead of midiOutLongMsg()) and it doesn't work either. My guess is that both are using the wrong device handle, or that the handle hasn't been set.
PD-dev mailing list PD-dev@iem.at http://iem.at/cgi-bin/mailman/listinfo/pd-dev