midiOutShortMsg 和 midiOutSetVolume 以立体声输出

midiOutShortMsg and midiOutSetVolume with output in stereo

本文关键字:立体声 输出 midiOutSetVolume midiOutShortMsg      更新时间:2023-10-16

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

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

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

任何建议非常感谢。

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

要设置音符的通道,"注意"事件具有 4 位通道:

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

因此,对左扬声器使用通道 0,对右扬声器使用通道 1

若要设置通道的声像,请将控制更改消息输出到该通道:

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) 的银行选择控件更改消息(控制器编号 0)。
  • GM 级别 2:为您的两个套件使用通道 1011(即发送 Note On 时为 9 和 10)。