使用 MIDI SysEx 消息的 5 个数据字节构造 0-999.9 之间的数字

逆向工程 调试 硬件 修补 嵌入式 数学
2021-06-23 09:16:24

我正在将 MIDI 消息发送到带有 LCD 屏幕的专有唱盘。普通软件通过 MIDI SysEx 发送更新以在 LCD 上显示当前速度。MIDI 正在 MKL25Z128VLK4、Cortex-M0+/ARMv6-M 设备上接收。(我确实在挖掘了它所使用的芯片类型的内脏之后拆卸了固件 .bin,但结果是大约 30k 行组装)如果不拆焊就无法访问 LCD 型号

在这一点上,我可以成功更新屏幕,但我无法从给定的数字中找出模式,我希望其他人有这方面的经验。

这是我迄今为止发现的:

将单个字节设置为 9-126 之间的任何值会导致 00.0

  BPM   B1    B2    B3    B4
 00.0   0     0     0     0
 00.0   0     0     0     1
 00.0   0     0     0     2
 00.0   0     0     0     3
 00.0   0     0     0     4
 00.0   0     0     0     5
 00.0   0     0     0     6
 00.0   0     0     0     7
 00.0   0     0     0     8
 00.0   0     0     0    16
 00.0   0     0     0    32
 00.0   0     0     0    64
 00.1   0     0     0   127
 00.1   0     0     1     0
 00.3   0     0     2     0
 00.4   0     0     3     0
 00.6   0     0     4     0
 00.8   0     0     5     0
 00.9   0     0     6     0
 01.1   0     0     7     0
 01.2   0     0     8     0
 00.0   0     0    16     0
 00.0   0     0    32     0
 00.0   0     0    64     0
 02.4   0     0   127     0
 02.5   0     1     0     0
 05.1   0     2     0     0
 07.6   0     3     0     0
 10.2   0     4     0     0
 12.8   0     5     0     0
 16.3   0     6     0     0
 17.9   0     7     0     0
 20.4   0     8     0     0
 00.0   0    16     0     0
 00.0   0    32     0     0
 00.0   0    64     0     0
 38.4   0   127     0     0
 40.9   1     0     0     0
 81.9   2     0     0     0
122.8   3     0     0     0
163.8   4     0     0     0
204.8   5     0     0     0
245.7   6     0     0     0
286.7   7     0     0     0
327.6   8     0     0     0
 00.0  16     0     0     0
 00.0  32     0     0     0
 00.0  64     0     0     0
614.4 127     0     0     0

打开多个字节将它们加在一起有时会产生奇怪的结果

 40.9   1     0     0     0
 00.1   0     0     1     0
 41.1   1     0     1     0

 81.9   2     0     0     0
 00.1   0     0     1     0
 82.0   2     0     1     0

我想知道是否有一些我不太熟悉的浮点或按位数学,如果是的话,用于计算的实数和数据类型是什么?我觉得理解这一点对于解决这个问题至关重要,而无需大量查找表或将其分解并编写我自己的控制器

1个回答

二进制

MIDI 数据字节为 7 位,这意味着它们可以具有从 0 到 127 的十进制值。

在 7 位二进制数中:

  • 右边的位代表十进制值 1。
  • 左边的下一位代表十进制值 2。
  • 左边的下一位代表 4、8、16、32 和 64 的十进制值。

从 0 到 127 的十进制值可以用七位表示,其中每一位是 0 或 1。

binary   decimal
0000001  1 = 1
0000010  2 = 2
0000011  3 = 2 + 1
0000100  4 = 4
0000101  5 = 4 + 1
0000110  6 = 4 + 2
0000111  7 = 4 + 2 + 1
0001000  8 = 8
0001001  9 = 8 + 1
...
1111111  127 = 64 + 32 + 16 + 8 + 4 + 2 + 1

图案

从你描述的结果来看,我怀疑转盘只关心每个字节的最低 4 位。换句话说,只有十进制值为 1、2、4 和 8 的位才会对速度显示产生影响。这意味着只有字节值 0 到 15 有用。

我怀疑转盘正在使用以下模式:

B1  B2  B3  B4  tempo  display
 0   0   0   0   .00     .0
 0   0   0   1   .01      "
 0   0   0   2   .02      "
 0   0   0   3   .03      "
 0   0   0   4   .04      "
 0   0   0   5   .05      "
 0   0   0   6   .06      "
 0   0   0   7   .07      "
 0   0   0   8   .08      "
 0   0   0   9   .09      "
 0   0   0  10   .10     .1
 0   0   0  11   .11      "
 0   0   0  12   .12      "
 0   0   0  13   .13      "
 0   0   0  14   .14      "
 0   0   0  15   .15      "
 0   0   1   0   .16      "
 0   0   1   1   .17      "
 0   0   1   2   .18      "
 0   0   1   3   .19      "
 0   0   1   4   .20     .2
...

字节值以 0.01 为单位表示速度值,但是当唱盘显示速度时,它隐藏了最后一位数字。

这个隐藏的数字解释了为什么打开多个字节并不总是产生由单个字节值显示的速度总和。

B1  B2  B3  B4  tempo  display
 1   0   0   0  40.96   40.9
 0   0   1   0    .16     .1
 1   0   1   0  41.12   41.1

按位数学

当只使用一些位时,按位数学确实很有用。

例如,这里有一些 Javascript 可以将速度转换为所需的字节值:

t = 123.4;

v = 100 * t;

b1 = (v >> 12) & 15;
b2 = (v >> 8) & 15;
b3 = (v >> 4) & 15;
b4 = v & 15;

console.log(b1, b2, b3, b4);

x & 15按位 AND,在这种情况下,只保留最低的四位。

x >> 4右移,在这种情况下,将值右移 4 位,丢弃最低的 4 位。这与除以 16 并丢弃余数具有相同的效果。

这是将字节值转换为显示速度的一些 Javascript:

b1 = 3;
b2 = 0;
b3 = 3;
b4 = 4;

b1 = b1 & 15;
b2 = b2 & 15;
b3 = b3 & 15;
b4 = b4 & 15;

v = 16*16*16*b1 + 16*16*b2 + 16*b3 + b4;

t = parseInt(v / 10) / 10;

console.log(t);

在您的网络浏览器中,您可以转到 about:blank,然后按 F12 并转到控制台输入这些小的 Javascript 计算。(为了您的安全,请在地址框中输入 about:blank,如果您不理解陌生人的代码,请不要运行它。)