2007
01.07

I recently wrote a guitar tuner app called FrequentZ that uses the short MIDI functions of Windows to generate it’s tones. I thought I would show everyone how it’s done in case you would like to incorporate some MIDI functionality into your own software. The best resource for Windows MIDI programming on the web is found here, so if you want to do something more complex, see that reference first. But, if your goals are more modest like mine were then you can probably get by with just a few of the MIDI functions that Windows has to offer. All of the code will be in masm32.

Here is the basic code you’ll need to generate some tones:

...
;## Include the multimedia libraries
include   winmm.inc
includelib   winmm.lib

.data
AGUITAR         dd  0000018C0h  ;## Acoustic Guitar
dwMidiMessage   dd  0007F2890h  ;## E Note

.data?
hMidi   HANDLE  ?

.code
...
;## Open a handle to the MIDI device
invoke  MIDIOutOpen, ADDR hMidi, MIDI_MAPPER, 0, 0, 0
mov     hMidi, eax

;## Change patch number
invoke  MIDIOutShortMsg, hMidi, AGUITAR

;## Create a note-off MIDI message
mov     eax, dwMidiMessage
mov     edx, 0FFFFFF80h
and     edx, eax
mov     dwMidiOffMessage, edx 

;## Send a message to play the note
invoke  MIDIOutShortMsg, hMidi, dwMidiMessage
invoke  Sleep, 2000        
invoke  MIDIOutShortMsg, hMidi, dwMidiOffMessage

;## Close the handle
invoke  MIDIOutClose, hMidi
...

So here’s what’s happening. We declare two 32-bit values to hold the MIDI patch number we want to use (AGUITAR) and the note we want to play (E). In the main code we first open a handle to the Windows MIDI mapper device by calling MIDIOutOpen and then change the patch number to 24 wich is supposed to sound like an acoustic guitar. Next, we create a MIDI message to turn the note off. We do this by ANDing the 32-bit MIDI note-on message with a bitmask that will leave everything the same except change the last byte to 128 (80h). The bitwise AND operator compares bits and returns a 1 if both the source AND destination bits are 1. Otherwise it returns 0. It works like this for us:

90h 1 0 0 1 0 0 0 0
80h 1 0 0 0 0 0 0 0
= 1 0 0 0 0 0 0 0

And because the remaining 24 bits of the destination value are all 1’s (FFFFFF), the rest of the MIDI message is preserved.

Finally, we send the message to play the note using MIDIOutShortMsg, sleep for a couple of seconds to make sure the note has time to play and then turn the note back off with another call. Last thing to do is to close the handle when you’re finished. It’s a good idea to look all of these functions up in the Windows multimedia API because they have a description in there about how the MIDI message byte order should be arranged. The other thing to note is that if you are triggering these notes from a GUI element like a button, then you should really fire off a second thread to handle playing the note. Otherwise, your GUI interface will hang because of the Sleep call. That’s very annoying.

No Comment.

Add Your Comment