RtMidi MIDI控制信号到Ableton Live

RtMidi MIDI control signals to Ableton Live

本文关键字:Ableton Live 信号 MIDI 控制 RtMidi      更新时间:2023-10-16

我正试图使用RtMidi编写一个C++应用程序,通过我的Tascam FireOne MIDI控制器向Ableton Live发送控制信号。到目前为止,我已经成功地通过我的MIDI控制器使用"a"answers"s"键将Note On+Off Signals、Volume Up+Down Signals等发送到我的数字钢琴。

// 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 Portsn-----------------------------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 live运行时,我按下一个键发送信号,但应用程序锁定,不会返回到while循环的开始以接收下一个按键的输入。

edit:我刚刚注意到,即使是上面的代码(通常运行良好)在运行ableton live并按键时也会冻结。

进一步编辑:我下载了一个非常整洁的应用程序,名为MIDI Monitor,它可以监控正在传输的MIDI数据:http://obds.free.fr/midimon--我的MIDI控制器设备有两个端口->一个用于MIDI,一个用于控制。当我监视控制时,我可以发送midi信号,反之亦然。然而,例如,如果我正在监视控制,并且我试图发送一些CC类型的数据,程序就会锁定。这可能是设备驱动程序的问题吗

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

只有一条注释-您的异常处理有点奇怪。

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

特别是,我不知道你的catch(char * str)会达到什么效果,如果openPort()投球,你根本就没有接球机会。

首先,尝试发送一个不同的CC,并将其映射到Ableton中的某个任意控件,看看它是否有效。您试图更改的音量控制与常规CC的行为略有不同。具体来说,您应该查看MIDI组织推荐的递增/递减控制器的做法(注意0x60==96),即当它们写入时:

此参数分别使用MSB和LSB,MSB以半音调整灵敏度,LSB以分调整灵敏度。一些制造商甚至可能忽略对LSB的调整。