2012-08-14 34 views
1

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

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

两个注释简单的问世右扬声器。我想,如果我可能有两个单独的手柄,我可以设置一个播放左声道音符,另一个是正确的。但是,如果我尝试通过2次调用打开2个手柄到相同的设备midiOutOpen我第二次调用时收到MMSYSERR_ALLOCATED错误。

任何意见非常赞赏。

回答

6

您应该使用两个通道并在每个通道上设置pan。然后发挥你的笔记左扬声器上的通道0,是您在通道右侧扬声器1.

笔记要设置一个音符的通道,你注意在事件有通道4位:

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

所以使用通道您的左扬声器和渠道你的右扬声器。

要设置的信道的油锅,输出一个控制变更消息到信道:

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


UPDATE:使用同时打击乐器音色需要对他们here MIDI标准XG或GM级别2.读。哪种方法您使用取决于设备的MIDI标准:

  • XG:发送银行选择控制变更消息(控制数)与价值(0x7F的)。
  • GM等级2:使用渠道和您的两个包(即9和10,当你发送音符开)。
+0

非常感谢您的回复。我实际上使用的是打击乐器,它们被设置为频道10,因此不能使用多个频道。我试着设定音量,而不是设定音量,但结果是一样的,一切都结束了。 – fhevol 2012-08-14 19:01:36

+0

是否可以设置另一个打击乐器的频道?您的方法可以使用标准的GM仪器完美工作如果我可以得到2个频道打击乐器我在那里。 – fhevol 2012-08-14 19:30:26

+0

@AndrewKlinkhamer:可以,这取决于你的MIDI设备。答案已更新。 – Scotty 2012-08-16 02:55:48

相关问题