SysEx 不会发送字节“AD”

Posted

技术标签:

【中文标题】SysEx 不会发送字节“AD”【英文标题】:SysEx will not send byte "AD" 【发布时间】:2015-01-04 03:11:03 【问题描述】:

好的,在用两种不同语言(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

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

Sysex 不喜欢 AD 字节吗?

【问题讨论】:

【参考方案1】:

MIDI 大多只有 7 位

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

正如它所说,SysEx 消息

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

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

当控制器支持超出[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

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

确定 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 信息 Pitch Bend 是 LSB 在前的。也许规范甚至在某处说东西应该是小尾数,我不知道。

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;
   

【讨论】:

AD 代表音板上推子的某个位置。 范围是 0-1023。从宏来看,它是以 128 为基数,每个数字编码为两位十六进制。现在说得通了。【参考方案2】:

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

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

【讨论】:

以上是关于SysEx 不会发送字节“AD”的主要内容,如果未能解决你的问题,请参考以下文章

Alesis QS MIDI Sysex 数据转换

使用 Arduino 发送 MIDI SysEx 消息?

MIDI 蓝牙 LE、SYSEX 消息不完整

如何从音量级别创建 MIDI Sysex Master Volume 消息?

ALSA 音序器:使用高速 MIDI 避免输入缓冲区溢出

我应该处理 WSASend() 可能不会发送所有数据的事实吗?