I’m writing C++ code to output midi messages. I need this to work in stereo, so that some notes are played through the left channel/speaker, others through the right. If I call midiOutSetVolume(midiOutHandle, 0xFFFF) followed by several calls to midiOutShortMsg, with each call separated by a few hundred milliseconds, the notes come through the left speaker. Likewise if I first call midiOutSetVolume(midiOutHandle, 0xFFFF0000) before the calls to midiOutShortMsg everything comes out the right speaker. However if I attempt to simultaneously output one note through the left speaker and one through the right by doing the following:
midiOutSetVolume(midiOutHandle, 0xFFFF);
midiOutShortMsg(...);
midiOutSetVolume(midiOutHandle, 0xFFFF0000);
midiOutShortMsg(...);
Both notes simply come out the right speaker. I thought if I perhaps had 2 separate handles to the device I could set one to play the left channel notes, the other the right. However if I try and open 2 handles to the same device via 2 calls to midiOutOpen I get an MMSYSERR_ALLOCATED error on the second call.
Any advice much appreciated.
You should use two channels and set the pan on each channel. Then play your notes for the left speaker on channel 0, and your notes for the right speaker on channel 1.
To set the channel of a note, your Note On event has 4 bits for the channel:
So use channel 0 for your left speaker and channel 1 for your right speaker.
To set the pan of a channel, output a Control Change message to that channel:
Set the pan of channel 0 to 0, and the pan of channel 1 to 127.
See the MIDI messages reference for more detail. Also, here is a short list of Control Change numbers.
UPDATE: Using simultaneous percussion kits requires MIDI standard XG or GM Level 2. Read about them here. Which method you use depends on your device’s MIDI standard: