我正在使用 C++ RtMidi 库从两个相同的设备(Novation 启动板)读取 MIDI 输入。
两个启动板都“生活”在自己的对象中,打开自己的 MIDI 端口,并且(应该)设置自己的回调方法。但是,如果我按下启动板上的按钮,两个设备都会将 MIDI 数据扔到同一个回调函数中(最后分配的那个)。
我希望回调函数是特定于对象的,而不是特定于类的。经过大量研究和修补后,我怀疑该问题与回调函数被声明为静态(如 RtMidi 文档所建议)并因此声明为类范围而不是对象范围的事实有关。
如何修复代码,以便将启动板生成的 MIDI 事件发送到它们的“自己的”回调函数?
这是(浓缩的)代码:
启动板.cpp
class launchpad {
public:
launchpad(int paramPortId, std::string paramPosition);
private:
static void listenerCallback(double deltatime, std::vector< unsigned char > *message, void *userData);
static std::string position;
};
std::string launchpad::position;
void launchpad::listenerCallback(double deltatime, std::vector< unsigned char > *message, void *userData) {
unsigned int nBytes = message->size();
for (unsigned int i = 0; i < nBytes; i++)
std::cout << position << "Byte " << i << " = " << (int) message->at(i) << ", ";
if (nBytes > 0)
std::cout << "stamp = " << deltatime << std::endl;
}
launchpad::launchpad(int paramPortId, std::string paramPosition) {
RtMidiIn *input = new RtMidiIn();
launchpad::position = paramPosition;
std::cout << "Launchpad found at port # " << paramPortId << " assigned position: " << position << std::endl;
input->setCallback(&listenerCallback);
input->openPort(paramPortId);
}
主文件
int main(int argc, char *argv[]) {
RtMidiIn *infoDevice;
launchpad *leftLaunchpad = 0;
launchpad *rightLaunchpad = 0;
int launchpadIndex = 0;
infoDevice = new RtMidiIn();
unsigned int nPorts = infoDevice->getPortCount();
string portName;
for (unsigned int i = 0; i < nPorts; i++) {
portName = infoDevice->getPortName(i);
if (portName == "Launchpad") {
if (launchpadIndex == 0) {
leftLaunchpad = new launchpad(i, "left");
launchpadIndex++;
} else if (launchpadIndex == 1) {
rightLaunchpad = new launchpad(i, "right");
launchpadIndex++;
}
}
}
char input;
std::cin.get(input);
return 0;
}
任何帮助是极大的赞赏。谢谢