midiOutShortMsg和midiOutSetVolume,立体声输出

时间:2012-08-14 04:59:12

标签: c++ winapi midi

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

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

这两个音符只是说出了正确的发言者。我想如果我可能有两个独立的设备,我可以设置一个播放左声道音符,另一个右边。但是,如果我尝试通过2次调用midiOutOpen打开同一设备的2个句柄,我会在第二次调用时收到MMSYSERR_ALLOCATED错误。

任何建议都非常感谢。

1 个答案:

答案 0 :(得分:6)

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

要设置音符的频道, Note On 事件的频道有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 messages reference。此外,这是控制变更编号的short list


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

  • XG:发送银行选择控件更改消息(控制器号 0 ),值 127 (0x7F)。
  • GM级别2:为您的两个套件使用 10 11 频道(例如,当您发送Note On时,为9和10)。