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:
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.