1

我正在编写 C++ 代码来输出 midi 消息。我需要它在立体声中工作,以便通过左声道/扬声器播放一些音符,通过右声道播放其他音符。如果我调用 midiOutSetVolume(midiOutHandle, 0xFFFF),然后调用 midiOutShortMsg,每次调用间隔几百毫秒,则音符会通过左侧扬声器。同样,如果我在调用 midiOutShortMsg 之前首先调用 midiOutSetVolume(midiOutHandle, 0xFFFF0000) ,那么一切都会从正确的扬声器中出来。但是,如果我尝试通过执行以下操作同时通过左扬声器和右扬声器输出一个音符:

midiOutSetVolume(midiOutHandle, 0xFFFF);
midiOutShortMsg(...);
midiOutSetVolume(midiOutHandle, 0xFFFF0000);
midiOutShortMsg(...);

两个音符都只是从正确的扬声器中出来。我想如果我可能有 2 个独立的设备手柄,我可以设置一个来播放左声道音符,另一个用于播放右声道。但是,如果我尝试通过对 midiOutOpen 的 2 次调用打开同一设备的 2 个句柄,我会在第二次调用时收到 MMSYSERR_ALLOCATED 错误。

非常感谢任何建议。

4

1 回答 1

6

您应该使用两个通道并在每个通道上设置声像。然后在通道 0 上为左扬声器播放您的音符,在通道 1 上为右扬声器播放您的音符。

要设置音符的通道,您的Note On事件有 4 个通道位:

1001nnnn (Note On)
nnnn = channel number (0..15)

因此,将通道0用于左扬声器,将通道1用于右扬声器。

要设置通道的声像,请将Control Change消息输出到该通道:

Status byte: 1011nnnn (Control Change)
nnnn = channel number (0..15)

First data byte - Controller number: 0ccccccc
Second data byte - Controller value: 0vvvvvvv
ccccccc = 10 (0x0A) for Pan
vvvvvvv = 0..127 (left = 0, right = 127)

将通道 0 的声像设置为 0,将通道 1 的声像设置为 127。

有关更多详细信息,请参阅MIDI 消息参考。此外,这里是控制变更编号的简短列表


更新:使用同步打击乐器需要 MIDI 标准 XG 或 GM 2 级。在此处阅读它们。您使用哪种方法取决于您设备的 MIDI 标准:

  • XG:发送值为127 (0x7F)的Bank Select Control Change 消息(控制器编号0 )。
  • GM Level 2: Use channels 10 and 11 for your two kits (ie. 9 and 10 when you send Note On).
于 2012-08-14T05:21:08.913 回答