1

C++ RtMidi ライブラリを使用して、2 つの同一のデバイス (Novation ランチパッド) から MIDI 入力を読み取っています。
どちらのランチパッドも独自のオブジェクトで「ライブ」し、独自の MIDI ポートを開き、独自のコールバック メソッドを設定する必要があります。ただし、ランチパッドのボタンを押すと、両方のデバイスが MIDI データを同じコールバック関数 (最後に割り当てられた関数) にスローします。
コールバック関数は、クラス固有ではなくオブジェクト固有であると予想していました。多くの調査と試行錯誤の後、コールバック関数が静的に宣言されており(RtMidiのドキュメントで示唆されているように)、オブジェクト全体ではなくクラス全体で宣言されているという事実に問題が関連していると思われます。

ランチパッドによって生成された MIDI イベントが「独自の」コールバック関数に送信されるように、コードを修正するにはどうすればよいですか?

(凝縮された)コードは次のとおりです。

launchpad.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);
}

main.cpp

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;

}

どんな助けでも大歓迎です。ありがとうございました

4

1 に答える 1

3

listenerCallback は、クラス以外の任意の静的 C 関数にすることができます

次に、input->setCallback(&listenerCallback,(void *)this); を使用します。そして、userdataは何が呼び出されているかを教えてくれます

于 2013-11-14T16:25:31.753 に答える