Android 原始midi值和字节c++;

Android 原始midi值和字节c++;,android,c++,midi,usb-otg,Android,C++,Midi,Usb Otg,我使用superpowered,我需要将midi音符发送到控制器midi。 问题是我看到一个函数send(int deviceID,unsigned char*data,int bytes) 在他们的源代码中说: deviceID:设备标识符。 数据:原始MIDI数据。 字节数:字节数 字节 我不知道需要在数据和字节上精确地设置哪些值才能工作。 原始midi可以是0x80-0x48-0x00(C4音符开始,音高=72,) 例如,字节1001nnnn0kkkk(事件注释)? 诸如此类: Super

我使用superpowered,我需要将midi音符发送到控制器midi。
问题是我看到一个函数
send(int deviceID,unsigned char*data,int bytes)
在他们的源代码中说:

deviceID:设备标识符。
数据:原始MIDI数据。
字节数:字节数 字节

我不知道需要在数据和字节上精确地设置哪些值才能工作。
原始midi可以是
0x80-0x48-0x00
(C4音符开始,音高=72,)
例如,字节
1001nnnn0kkkk
(事件注释)?
诸如此类:

SuperpoweredUSBMIDI::发送(设备ID,重新解释(0x80-0x48-0x00),1001nn0kkk)

这个问题总是会崩溃,我无法调试或获取错误,因为我使用带有otg的手机来复制错误。
当我找到解决办法时,我会尽快提出

我是markdown的新手,很抱歉有任何错误和我的英语语法

编辑:我正在使用GitHub上的示例项目进行测试,特别是simpleusb项目。()

我做了一些小的修改和工作,但具体来说,我尝试了很多方法,什么都没有。我认为,如果我很好地插入值,这个简单的宏观变化至少可以起作用
simpleusb.cpp

#include <jni.h>
#include <math.h>
#include <SuperpoweredCPU.h>
#include <AndroidIO/SuperpoweredUSBAudio.h>
#include <malloc.h>
#include <pthread.h>

// Called when the application is initialized. You can initialize SuperpoweredUSBSystem
// at any time btw. Although this function is marked __unused, it's due Android Studio's
// annoying warning only. It's definitely used.
__unused jint JNI_OnLoad (
        JavaVM * __unused vm,
        void * __unused reserved
) {
    SuperpoweredUSBSystem::initialize(NULL, NULL, NULL, NULL, NULL);
    return JNI_VERSION_1_6;
}

// Called when the application is closed. You can destroy SuperpoweredUSBSystem at any time btw.
// Although this function is marked __unused, it's due Android Studio's annoying warning only.
// It's definitely used.
__unused void JNI_OnUnload (
        JavaVM * __unused vm,
        void * __unused reserved
) {
    SuperpoweredUSBSystem::destroy();
}

// A helper structure for sine wave output.
typedef struct sineWaveOutput {
    float mul;
    unsigned int step;
} sineWaveOutput;

// This is called periodically for audio I/O. Audio is always 32-bit floating point,
// regardless of the bit depth preference. (SuperpoweredUSBAudioProcessingCallback)
static bool audioProcessing (
        void *clientdata,
        int __unused deviceID,
        float *audioIO,
        int numberOfSamples,
        int samplerate,
        int __unused numInputChannels,
        int numOutputChannels
) {
    // If audioIO is NULL, then it's the very last call, IO is closing.
    if (!audioIO) {
        // Free memory for sine wave struct.
        free(clientdata);
        return true;
    }
    sineWaveOutput *swo = (sineWaveOutput *)clientdata;
    if (swo->mul == 0.0f) swo->mul = (2.0f * float(M_PI) * 300.0f) / float(samplerate);

    // Output sine wave on all output channels.
    for (int n = 0; n < numberOfSamples; n++) {
        float v = sinf(swo->step++ * swo->mul) * 0.5f;
        for (int c = 0; c < numOutputChannels; c++) *audioIO++ = v;
    }

    return true; // Return false for silence, true if we put audio output into audioIO.
}

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int latestMidiCommand = -1;
static int latestMidiChannel = 0;
static int latestMidiNumber = 0;
static int latestMidiValue = 0;

// This is called when some MIDI data is coming in.
// We are doing some primitive MIDI data processing here.
static void onMidiReceived (
        void * __unused clientdata,
        int __unused deviceID,
        unsigned char *data,
        int bytes
) {
    while (bytes > 0) {
        if (*data > 127) {
            int command = *data >> 4;
            switch (command) {
                case 8: // note off
                case 9: // note on
                case 11: // control change
                    pthread_mutex_lock(&mutex);
                    // store incoming MIDI data
                    latestMidiCommand = command;
                    latestMidiChannel = *data++ & 15;
                    latestMidiNumber = *data++;
                    latestMidiValue = *data++;
                    pthread_mutex_unlock(&mutex);
                    bytes -= 3;
                    break;
                default:
                    data++;
                    bytes--;
            }
        } else {
            data++;
            bytes--;
        }
    }
}

// Beautifying the ugly Java-C++ bridge (JNI) with these macros.
#define PID com_superpowered_simpleusb_SuperpoweredUSBAudio // Java package name and class name. Don't forget to update when you copy this code.
#define MAKE_JNI_FUNCTION(r, n, p) extern "C" JNIEXPORT r JNICALL Java_ ## p ## _ ## n
#define JNI(r, n, p) MAKE_JNI_FUNCTION(r, n, p)

// This is called by the SuperpoweredUSBAudio Java object when a USB device is connected.
JNI(jint, onConnect, PID) (
        JNIEnv *env,
        jobject __unused obj,
        jint deviceID,
        jint fd,
        jbyteArray rawDescriptor
) {
    jbyte *rd = env->GetByteArrayElements(rawDescriptor, NULL);
    int dataBytes = env->GetArrayLength(rawDescriptor);
    int r = SuperpoweredUSBSystem::onConnect(deviceID, fd, (unsigned char *)rd, dataBytes);
    env->ReleaseByteArrayElements(rawDescriptor, rd, JNI_ABORT);

    // r is 0 if SuperpoweredUSBSystem can't do anything with the connected device.
    // r & 2 is true if the device has MIDI. Start receiving events.
    if (r & 2) {
        SuperpoweredUSBMIDI::startIO(deviceID, NULL, onMidiReceived);


//TODO HERE IT'S THE PROBLEM: error: integer literal is too large to be represented in any integer type
        SuperpoweredUSBMIDI::send(deviceID, reinterpret_cast<unsigned char *>(0x80 - 0x48 - 0x00), 100100010011100000000011);
//FINISH PROBLEM






    }

    // r & 1 is true if the device has audio. Start output.
    if (r & 1) {
        // allocate struct for sine wave oscillator
        sineWaveOutput *swo = (sineWaveOutput *)malloc(sizeof(sineWaveOutput));
        if (swo) {
            swo->mul = 0.0f;
            swo->step = 0;
            SuperpoweredCPU::setSustainedPerformanceMode(true);

            // Our preferred settings: 44100 Hz, 16 bits, 0 input channels, 256 output channels,
            // low latency. Superpowered will set up the audio device as close as it can to these.
            SuperpoweredUSBAudio::easyIO (
                    deviceID,                    // deviceID
                    44100,                       // sampling rate
                    16,                          // bits per sample
                    0,                           // numInputChannels
                    256,                         // numOutputChannels
                    SuperpoweredUSBLatency_Low,  // latency
                    swo,                         // clientData
                    audioProcessing              // SuperpoweredUSBAudioProcessingCallback
            );
        }
    }
    return r;
}

// This is called by the SuperpoweredUSBAudio Java object when a USB device is disconnected.
JNI(void, onDisconnect, PID) (
        JNIEnv * __unused env,
        jobject __unused obj,
        jint deviceID
) {
    SuperpoweredUSBSystem::onDisconnect(deviceID);
    SuperpoweredCPU::setSustainedPerformanceMode(false);
}

#undef PID
#define PID com_superpowered_simpleusb_MainActivity

// This is called by the MainActivity Java object periodically.
JNI(jintArray, getLatestMidiMessage, PID) (
        JNIEnv *env,
        jobject __unused obj
) {
    jintArray ints = env->NewIntArray(4);
        jint *i = env->GetIntArrayElements(ints, 0);
    pthread_mutex_lock(&mutex);
    i[0] = latestMidiCommand;
    i[1] = latestMidiChannel;
    i[2] = latestMidiNumber;
    i[3] = latestMidiValue;
    pthread_mutex_unlock(&mutex);
    env->ReleaseIntArrayElements(ints, i, 0);
    return ints;
}
@RequiresApi(api = Build.VERSION_CODES.M)
public class MainActivity extends AppCompatActivity implements SuperpoweredUSBAudioHandler {

    private Handler handler;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {



        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.text);



        SuperpoweredUSBAudio usbAudio = new SuperpoweredUSBAudio(getApplicationContext(), this);
        usbAudio.check();

        // Update UI every 40 ms.
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                int[] midi = getLatestMidiMessage();
                switch (midi[0]) {
                    case 8: textView.setText(String.format(Locale.ENGLISH, "Note Off, CH %d, %d, %d",
                            midi[1] + 1, midi[2], midi[3]));




                            break;
                    case 9: textView.setText(String.format(Locale.ENGLISH, "Note On, CH %d, %d, %d",
                            midi[1] + 1, midi[2], midi[3]));





                            break;
                    case 11: textView.setText(String.format(Locale.ENGLISH, "Control Change, CH %d, %d, %d",
                            midi[1] + 1, midi[2], midi[3]));
                            break;
                }
                handler.postDelayed(this, 40);
            }
        };
        handler = new Handler();
        handler.postDelayed(runnable, 40);

/*Not look, only for testing purposes and for remember what use.
        byte[] buffer = new byte[32];
        int numBytes = 0;
        int channel = 6; // MIDI channels 1-16 are encoded as 0-15.
        buffer[numBytes++] = (byte)(0x90 + (channel - 1)); // note on
        buffer[numBytes++] = (byte)60; // pitch is middle C
        buffer[numBytes++] = (byte)127; // max velocity
        int offset = 0;*/

    }

    public void onUSBAudioDeviceAttached(int deviceIdentifier) {
    }

    public void onUSBMIDIDeviceAttached(int deviceIdentifier) {
    }

    public void onUSBDeviceDetached(int deviceIdentifier) {
    }

    // Function implemented in the native library.
    private native int[] getLatestMidiMessage();



    static {
        System.loadLibrary("SuperpoweredExample");
    }






}
错误我最终无法生成应用程序:

Build command failed.
Error while executing process D:\Users\ramoc\AppData\Local\Android\sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build F:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\.externalNativeBuild\cmake\debug\arm64-v8a --target SuperpoweredExample}
[1/2] Building CXX object CMakeFiles/SuperpoweredExample.dir/simpleusb.cpp.o
FAILED: D:\Users\ramoc\AppData\Local\Android\sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=aarch64-none-linux-android --gcc-toolchain=D:/Users/ramoc/AppData/Local/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot=D:/Users/ramoc/AppData/Local/Android/sdk/ndk-bundle/sysroot  -DSuperpoweredExample_EXPORTS -IF:/PROYECTOFIN/SuperpoweredUSBExample/simpleusb/src/main/jni/src/main/jni -IF:/PROYECTOFIN/SuperpoweredUSBExample/simpleusb/../../../Superpowered -isystem D:/Users/ramoc/AppData/Local/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/include -isystem D:/Users/ramoc/AppData/Local/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/include -isystem D:/Users/ramoc/AppData/Local/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/include/backward -isystem D:/Users/ramoc/AppData/Local/Android/sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security  -fsigned-char -IF:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\..\..\..\Superpowered -O0 -fno-limit-debug-info  -fPIC -MD -MT CMakeFiles/SuperpoweredExample.dir/simpleusb.cpp.o -MF CMakeFiles\SuperpoweredExample.dir\simpleusb.cpp.o.d -o CMakeFiles/SuperpoweredExample.dir/simpleusb.cpp.o -c F:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\src\main\jni\simpleusb.cpp
F:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\src\main\jni\simpleusb.cpp:129:100: error: integer literal is too large to be represented in any integer type
        SuperpoweredUSBMIDI::send(deviceID, reinterpret_cast<unsigned char *>(0x80 - 0x48 - 0x00), 100100010011100000000011);
                                                                                                   ^
F:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\src\main\jni\simpleusb.cpp:129:100: warning: implicit conversion from 'unsigned long long' to 'int' changes value from 7976667151972931595 to 887068683 [-Wconstant-conversion]
        SuperpoweredUSBMIDI::send(deviceID, reinterpret_cast<unsigned char *>(0x80 - 0x48 - 0x00), 100100010011100000000011);
        ~~~~~~~~~~~~~~~~~~~                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
ninja: build stopped: subcommand failed.
Build命令失败。
执行进程D:\Users\ramoc\AppData\Local\Android\sdk\cmake\3.6.4111459\bin\cmake.exe时出错,参数为{--build F:\PROYECTOFIN\SuperpoweredExample\simpleusb\.externalNativeBuild\cmake\debug\arm64-v8a--target SuperpoweredExample}
[1/2]构建CXX对象CMakeFiles/SuperpoweredExample.dir/simpleusb.cpp.o
失败:D:\Users\ramoc\AppData\Local\Android\sdk\ndk bundle\toolschains\llvm\prebuilded\windows-x86\u 64\bin\clang++.exe--target=aarch64 none-linux-Android--gcc-toolschain=D:/Users/ramoc/AppData/Local/Android/sdk/ndk bundle/toolschains/aarch64-linux-Android-4.9/prebuild/windows-x86\u 64--sysroot=D:/Users/ramoc/AppData/Local/Android/sdk/ndk bundle/sysroot-DSuperpoweredExample\u EXPORTS-IF:/PROYECTOFIN/superpoweredexample/simpleusb/src/main/jni-IF:/PROYECTOFIN/superpoweredexample/simpleusb/../../Superpowered-isystemD:/Users/ramoc/AppData/Local/Android/sdk/ndk bundle/sources/cxx stl/gnu libstdc++/4.9/include-isystem D:/Users/ramoc/AppData/Local/Android/sdk/ndk bundle/sources/cxx stl/gnu libstdc++/4.9/libs/arm64-v8a/include-isystem D:/Users/ramoc/AppData/Local/Android/sdk/ndk bundle/sources/cxx stl/gnu libstdc++/4.9/include/backward-isystemD:/Users/ramoc/AppData/Local/Android/sdk/ndk bundle/sysroot/usr/include/aarch64 linux-Android-D\u-Android\u-API\u=21-g-DANDROID-ffunction sections-funwind tables-fstack-protector-strong-无规范前缀-Wa,--noexecstack-Wformat-Werror=格式安全性-fsigned char-IF:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\F:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\src\main\jni\simpleusb.cpp
F:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\src\main\jni\simpleusb.cpp:129:100:错误:整数文本太大,无法用任何整数类型表示
SuperpoweredUSBMIDI::send(设备ID,重新解释(0x80-0x48-0x00),100100010011100000000011);
^
F:\PROYECTOFIN\SuperpoweredUSBExample\simpleusb\src\main\jni\simpleusb.cpp:129:100:警告:从“unsigned long long”到“int”的隐式转换将值从7976667151972931595更改为887068683[-Wconstant conversion]
SuperpoweredUSBMIDI::send(设备ID,重新解释(0x80-0x48-0x00),100100010011100000000011);
~~~~~~~~~~~~~~~~~~~                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~
生成1个警告和1个错误。
忍者:构建停止:子命令失败。

可能是为了文档,对jni非常陌生,或者现在对我来说太复杂,无法100%理解。

好的,下面是
send
的意思:

send(int deviceID, unsigned char *data, int bytes);
deviceId
发送一个指向名为
data
的缓冲区的指针,该缓冲区具有一定数量的
字节

所以当你说: SuperpoweredUSBMIDI::send(设备ID,重新解释(0x80-0x48-0x00),100100010011100000000011)

实际上,您要说的是“减去这3个数字:
0x80-0x48-0x00
”,然后将该数字重新解释为指向内存中某个缓冲区的指针。内存中的缓冲区包含我希望您读取的
100100011100000000011
字节数据

要解决此问题,我们将发送如下数据:

unsigned char* send_buffer[32] = {0}; // zero out buffer to use as scratch
send_buffer[0] = 0x90;
send_buffer[1] = 0x48;
send_buffer[2] = 0x00;

SuperpoweredUSBMIDI::send(deviceID, send_buffer, 3);

我认为midi在序列中附加了一个校验和值(字节)——这是在您的代码中还是在库代码中完成的

消息应该是一个无符号字符数组,并传递数组的地址(名称)
这就是我在编写midi时在C中所做的。

显示您的代码!编辑。。。很抱歉我迟到了到底是什么原因?代码中没有
send()
调用。由于编辑和现在这样,我无法构建应用程序并说出上面提到的错误,我现在将所有错误都放在了构建最佳状态。如果我没有弄错的话,当r&2是真的时,它会运行,在我的应用程序运行的情况下,我只放了一个midi设备(启动板),检测到它,并立即将midi音符发送到设备。非常感谢,明天我会尝试,但现在我更好地理解它,最终应用程序运行,但我尝试了,设备没有得到midi值(没有LED)我放了一个测试发送midi的按钮,什么都没有。别担心,谢谢(:,也许是另一个问题,因为你的解释