java - SysEx 将不会发送字节 "AD"

标签 java windows macos cocoa midi

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

本质上,我正在尝试发送以下 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 的 channel 关闭。

然后,为了仅对 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 大多只有 7 位

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

正如它所说,SysEx 消息

  • F0开头
  • 只能包含[00 .. 7F]范围内的字节
  • F7 除外,它结束 SysEx 消息。

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

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

确定范围

下表有助于确定范围。

                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

其意义在于特定 Controller 支持的值范围,而不是实际值。例如,如果 Controller 支持值范围 [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 转换为 MIDI 的 byte[]

这假设您的 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;
}   

关于java - SysEx 将不会发送字节 "AD",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27761981/

相关文章:

堆中的Java最大对象大小

java - 出现错误 "org.apache.jasper.el.JspMethodNotFoundException"

c++ - 测量 C++ 中函数调用的执行时间

objective-c - 程序内存的内容 (Mac)

使用 "string"时出现 C++ 链接错误

java - 如果在数据库中找不到数据则插入数据,否则更新数据

java - 如何使用 Jconsole 监控 Java 程序?

python - 没有名为 '_pywrap_tensorflow_internal' 的模块

c - Windows 有 sigaltstack 和 sigaction 的替代品吗?

python - PyCharm Python 项目 没有那个文件或目录