RtMidi MIDI 控制信号发送至 Ableton Live

发布于 2024-11-09 13:31:30 字数 3638 浏览 0 评论 0原文

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

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

编辑:我刚刚注意到,当ableton live运行并且我按下一个键时,即使上面的代码(通常运行良好)也会冻结。

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

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

I'm trying to write a C++ app using RtMidi to send control signals via my Tascam FireOne MIDI Controller to Ableton Live. So far, I have it successfully sending Note On + Off Signals, Volume Up + Down Signals, etc. via my MIDI Controller to my digital piano using 'a' and 's' keypresses.

// 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;
}

I tried sending control signals in the same manner as above but this time with control values in the message bytes in place of the note-on or note-off values.

When ableton live is running, I press a key to send a signal but the app locks up and doesn't return to the start of the while loop to receive input from the next keypress.

edit: I've just noticed that even the above code (which usually runs fine) freezes when ableton live is running and I press a key.

further edit: I downloaded a really neat app called MIDI Monitor, which can monitor MIDI data being transferred: http://obds.free.fr/midimon -- my MIDI controller device has two ports -> one for MIDI and one for control. When I'm monitoring control, I can send midi signals and vice versa. However, if, for example, I'm monitoring control and I try to send some CC type data the program locks. Could this be a device driver problem? –

Does anyone know what is going wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

落墨 2024-11-16 13:31:30

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

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

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

Just one comment - your exception handling is a little weird.

I'd wrap the whole code (initialization and all) in a try/catch(RtError &err) block, and lose most of the other try/catch blocks.

In particular, I don't know what your catch(char * str) stuff will achieve, and you have no catch at all if openPort() throws.

烟柳画桥 2024-11-16 13:31:30

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

该参数分别使用MSB和LSB,MSB以半音为单位调节灵敏度,LSB以音分为单位调节灵敏度。有些制造商甚至可能忽略对LSB的调整。

First of all, try sending a different CC and mapping it to some arbitrary control in Ableton, just to see if it's working. The volume controls you are trying to alter behave slightly differently than regular CC's. Specifically, you should check out the MIDI organization's recommended practice for incrementing/decrementing controllers (note that 0x60 == 96), namely when they write:

This parameter uses MSB and LSB separately, with MSB adjusting sensitivity in semitones and LSB adjusting sensitivity in cents. Some manufacturers may even ignore adjustments to the LSB.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文