2011-05-24 70 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