SysEx 不会发送字节 "AD"

SysEx will not send byte "AD"

好的,在用两种不同语言(Java 和 Cocoa)编写的两个不同程序(我自己的和 QLab)中,在两个不同的系统(Mac 和 PC)上尝试这个会产生相同的结果.所以我很困惑。

本质上,我正在尝试发送以下 Sysex 消息:

F0 43 10 3E 12 01 00 33 00 00 00 00 AD 00 00 00 AD F7

当我发送它时,我的 Midi 监控程序(又是两个不同的)要么说它已发送:

F0 43 10 3E 12 01 00 33 00 00 00 00 F7

然后发送了这个:

Aftertouch Ch14 C-2 0
Invalid 1 Byte
Invalid 1 Byte

或者另一个只是说了三个触后,然后通道从 Java.

关闭

那么,仅对 Mac 程序进行故障排除时,我发送了以下消息:

F0 43 10 3E 12 01 00 33 00 00 00 00 00 00 00 00 AD F7

它说我发送了这个:

F0 43 10 3E 12 01 00 33 00 00 00 00 00 00 00 00 F7

然后是这个:

Invalid 1 Byte

如果有帮助,我正在尝试向 Yamaha LS9 发送消息 kInputFader。

Sysex不喜欢AD字节吗?

好吧,一时忘了这是 MIDI。如果我错了请纠正我,但除了 header,Sysex 消息只能包含 00-7F(0-127 dec)。

来源:http://beatwise.proboards.com/thread/1705/sysex-hardware-clips-help

MIDI 大多只有 7 位

看看这个table:http://midi.org/techspecs/midimessages.php

如其所说,SysEx 消息

  • F0
  • 开头
  • 可能只包含 [00 .. 7F]
  • 范围内的字节
  • 除了 F7 结束 SysEx 信息。

MIDI 主要是以字节发送的 7 位编码。只有少数特殊字节如消息的起始字节设置了高位。

当控制器支持的值超出[0..127]范围时,需要将值拆分成多个字节。

确定范围

以下table有助于识别范围。

                Range                         |Data|Bytes
     unsigned     |           signed          |Bits|req'd
------------------+---------------------------+----+------
 0 ..         127 |         -64 ..         63 |  7 |  1
 0 ..       16383 |       -8192 ..       8191 | 14 |  2
 0 ..     2097151 |    -1048576 ..    1048575 | 21 |  3
 0 ..   134217728 |   -67108864 ..   67108863 | 26 |  4
 0 .. 17179869184 | -8589934592 .. 8589934591 | 34 |  5

重要的是特定控制器支持的值范围,而不是实际值。例如,如果控制器支持值范围 [0..1023],则始终需要 2 个字节,即使要发送的值是 0,而 0 只需要一个字节。

确定 Java 程序的长度

如果你知道maxValue,你可以用下面的算法确定长度:

public static int getDataLengthUnsigned(final int maxValue) {
    int ret = 1;
    while ((1 << (ret * 7)) <= maxValue) ret++;
    return ret;
}

int 转换为 byte[] 用于 MIDI

这假定您的 MIDI 设备以 Little Endian 格式处理消息。通常情况是这样,因为 MIDI 消息弯音是 LSB 在前。也许规范甚至在某处说东西应该是 Little Endian,我不知道。

public static byte[] encodeAsSysExUnsigned(int value, final int maxValue) {
    if (value > maxValue || value < 0)
        throw new IllegalArgumentException(String.format("Value %d out of range [0 .. %d]", value, maxValue));
    final int dataLength = getDataLengthUnsigned(maxValue);
    final byte[] sysExData = new byte[dataLength];
    for (int i = 0; i < dataLength; i++, value >>>= 7)
        sysExData[i] = (byte) (value & 0x7F);
    return sysExData;
}