2011-05-24 67 views
2

我正在尝试使用RtMidi来编写一个C++应用程序,通过我的Tascam FireOne MIDI控制器向Ableton Live发送控制信号。到目前为止,我已经通过我的MIDI控制器使用'a'和's'按键成功向我的数码钢琴发送了音符+关闭信号,音量提高+关闭信号等。RtMidi MIDI控制信号给Ableton Live

// midiout.cpp 

#include <iostream> 
using namespace std; 

#include <signal.h> 
#include <windows.h> 
#include <conio.h> 
#include "RtMidi.h" 

int main() 
{ 
    std::vector<unsigned char> message; 

    int i, keyPress; 
    int nPorts; 
    char input; 

    RtMidiOut *midiout = 0; 

    // midiOUT 
    try { 
     midiout = new RtMidiOut(); 

     // Check available ports. 
     nPorts = midiout->getPortCount(); 
     if (nPorts == 0) { 
      cout << "No ports available!" << endl; 
      goto cleanup; 
     } 

     // List Available Ports 
     cout << "\nPort Count = " << nPorts << endl; 
     cout << "Available Output Ports\n-----------------------------\n"; 
     for(i=0; i<nPorts; i++) 
     { 
      try { 
       cout << " Output Port Number " << i << " : " << midiout->getPortName(i) << endl; 
      } 
      catch(RtError &error) { 
       error.printMessage(); 
       goto cleanup; 
      } 
     } 

     cout << "\nSelect an output port number :" << endl; 
     cin >> keyPress; 

     while(keyPress < 0 || keyPress >= midiout->getPortCount()) 
     { 
      cout << "\nIncorrect selection. Please try again :" << endl; 
      cin >> keyPress; 
     } 

     // Open Selected Port 
     midiout->openPort(keyPress); 

     keyPress = NULL; 

     bool done = false; 

     cout << "Press a key to generate a message, press 'Esc' to exit" << endl; 

     while(!done) 
     { 
      keyPress = _getch(); 
      input = keyPress; 
      cout << input << " is: " << keyPress << endl; 

      switch (keyPress) 
      { 
       case 97 : 
       // Process for keypress = a 
        // Note On: 144, 60, 90 
        message.push_back(144); 
        message.push_back(60); 
        message.push_back(90); 
        midiout->sendMessage(&message); 
        break; 
       case 115 : 
        // Process for keypress = s 
        // Note Off: 128, 60, 90 
        message.push_back(128); 
        message.push_back(60); 
        message.push_back(90); 
        midiout->sendMessage(&message); 
        break; 
       case 27 : 
        // Process for keypress = esc 
        done = true; 
        break; 
      } 
      message.clear(); 
      keyPress = NULL; 
     } 
    } 
    catch(RtError &error) { 
     error.printMessage(); 
     exit(EXIT_FAILURE); 
    } 

    cleanup: 
     delete midiout; 

    return 0; 
} 

我试图以相同的方式如上述发送控制信号,但在代替音符开或音符关值的这一次与控制值的消息中的字节。

当ableton正在运行时,我按一个键发送一个信号,但应用程序锁定并且不会返回到while循环的开始,以接收来自下一个按键的输入。

编辑:我刚刚注意到,即使上面的代码(通常运行正常)时Ableton现场运行冻结和我按一个键。

进一步编辑:我下载了一个非常灵巧的应用程序称为MIDI监视器,可以监视被传输MIDI数据:http://obds.free.fr/midimon - 我的MIDI控制器设备有两个端口 - >一个MIDI和一个用于控制。当我监控控制时,我可以发送MIDI信号,反之亦然。但是,例如,如果我正在监视控制并尝试发送一些CC类型的数据,则该程序将被锁定。这可能是一个设备驱动程序问题? -

有人知道这里出了什么问题吗?

+0

这是否发生在所有设备的端口? – 2011-05-24 14:26:07

回答

0

首先,尝试发送一个不同的CC并将其映射到Ableton中的任意控件,以查看它是否正常工作。您尝试修改的音量控制与常规CC的行为略有不同。具体来说,你应该看看MIDI organization's recommended practice for incrementing/decrementing controllers(注意,0x60的== 96),即当他们写道:

该参数使用MSB和LSB分别地与MSB调整半音敏感性和仙LSB调整灵敏度。有些制造商甚至可能会忽略对LSB的调整。

+0

我下载了一个非常整洁的应用程序,名为MIDI Monitor,它可以监视正在传输的MIDI数据:http://obds.free.fr/midimon/现在继承了kicker - 我的MIDI控制器设备有两个端口 - >一个用于MIDI和一个用于控制。当我监视控制时,我可以发送midi信号,反之亦然,但是,例如,如果我正在监视控制并尝试发送一些CC类型的数据,程序就会锁定。这可能是一个设备驱动程序问题? – kylestephens 2011-05-24 15:15:17

+0

@kosomonova两个MIDI端口可能对应于设备背面的物理MIDI端口(您将连接到键盘或其他设备)以及设备本身,这也是发送/接收MIDI。你应该看到这两个在MIDI监视器的输出窗口中显示为不同的条目。你可能应该为每一个rtmidi输出端口。 – 2011-05-24 15:34:25

1

只有一条评论 - 你的异常处理有点奇怪。

我会将整个代码(初始化和全部)包装在try/catch(RtError &err)块中,并丢失大部分其他try/catch块。

特别是,我不知道你的catch(char * str)的东西会实现什么,而且如果openPort()抛出,你根本就没有抓到。

+0

是的,我接受。很酷,谢谢。 – kylestephens 2011-05-24 15:38:03