协慌网

登录 贡献 社区

使用钢琴键盘作为电脑键盘

我有RSI问题,并尝试了 30 种不同的电脑键盘,这些都给我带来了痛苦。弹钢琴不会让我感到痛苦。我已经弹钢琴大约 20 年没有任何疼痛问题。我想知道是否有办法从 MIDI 键盘捕捉 MIDI 并输出键盘敲击。我对 MIDI 一无所知,但我想要一些关于如何将这个信号转换成击键的指导。

答案

多年来我没有做任何 MIDI 编程,但你的基本想法非常合理(没有双关语)。

MIDI 是 “事件”(或 “消息”)的流,最基本的两个是 “音符开” 和 “音符关”,它们带有音符编号(0 = C 中间 C 下五个八度,到 127 = G 在中间 C 上方的 G 上方五个八度音阶,半音调)。这些事件在速度敏感(“触敏”)的键盘上带有 “速度” 数字,其力(你猜对了)在 0 到 127 之间。

在速度,和弦和踏板之间,我认为你可以为钢琴键盘提供一个非常好的 “打字” 界面。特别是 Chording 可能是一种非常强大的技术 - 正如我在评论中提到的那样,这就是为什么普通速记员可以使用stenotype 机器来跟上人们连续几个小时说话,甚至顶级打字员也不会通过普通打字机式键盘可以持续任何时间。与机器速记一样,你需要一个关于和弦和和弦序列含义的 “字典”。 (你能告诉我曾经在机器速记的软件方面工作吗?)

要做到这一点,基本的部分是:

  • 接收 MIDI 输入。不要试图自己这样做,使用库。 编辑 :显然,Java Sound API 支持 MIDI ,包括从 MIDI 控制器接收事件。凉。 此页面也可能有用。
  • 将该数据转换为您要发送的击键,例如通过我上面提到的字典。
  • 将击键输出到计算机。

要与软件最广泛地兼容,您必须将其写为键盘设备驱动程序。这是操作系统的插件,用作键盘事件的源,与底层硬件(在您的情况下,钢琴键盘)交谈。对于 Windows 和 Linux,您可能希望使用 C 来实现。

但是,由于您只是生成击键(而不是试图拦截它们,我多年前就试图拦截它们),您可能可以使用操作系统发送人工击键的任何功能。 Windows 有一个用于执行此操作的界面(可能是几个,我正在考虑的是SendInput但我知道有一些类似的 “日志” 界面),我确信其他操作系统也可以。这可能足以满足您的目的 - 这是我开始的地方,因为设备驱动程序路径会很尴尬,您可能不得不使用与 Java 不同的语言。 (我是 Java 的忠实粉丝,但操作系统用来与设备驱动程序通信的接口往往更容易通过 C 和类似的方式使用。)


更新 :更多关于击键和弦的 “字典”:

基本上,字典是一个trie (谢谢,@ Adam),我们搜索最长前缀匹配。细节:

在机器速记中,速记员通过同时按下 stenotype 机器上的多个键来写入,然后将它们全部释放。他们称之为键盘的 “中风”; 就像在钢琴上弹奏和弦一样。经常(但不总是)笔划对应于口语的音节。就像音节一样,有时一个笔画(和弦)本身就有意义,有时它只有跟随笔画的意思。 (认为 “好” 与“好” 后跟“再见”)。虽然他们会受到他们学习的学校的严重影响,但每位速记员都会有自己的“词典”,说明他们用什么笔画来表示什么,他们将在他们的工作生涯中不断磨练的词典。字典将具有条目,其中速记部分(简称“steno”)是一个笔划长或多个笔划长。通常,将存在具有相同起始行程的若干条目,这些条目通过它们的长度和随后的笔划来区分。例如(我不会在这里使用真正的 steno,只是占位符),可能有以下条目:

A     = alpha
A/B   = alphabet
A/B/C = alphabetic
A/C   = air conditioning
B     = bee
B/C   = because
C     = sea
D     = dog
D/D   = Dee Dee

(这些字母不是音符,只是抽象的标记。)

请注意, A启动多个条目,同时请注意您如何翻译C笔划取决于您之前是否看过AB ,或者您是刚刚开始新的。

另请注意(尽管未在上面的极小样本中显示),可能有多种方法可以 “播放” 相同的单词或短语,而不仅仅是一种。速度训练器可以根据手的位置使前一个词更容易从下一个词流到下一个词。那里的音乐有一个明显的类比,你可以使用它来使你的打字流程更类似于播放音乐,以防止这对你的钢琴演奏产生负面影响,并最大限度地提高实际帮助 RSI 的可能性。

在将 steno 转换为标准文本时,我们再次使用 “最长前缀匹配” 搜索:转换算法从写入的第一个笔划开始,并查找以该笔划开始的条目。如果只有一个条目,并且它只有一个笔划,那么我们可以可靠地说 “这是要使用的条目”,输出相应的文本,然后在下一个笔划中重新开始。但更可能的是,该笔划会开始多个不同长度的条目。因此,我们查看下一个笔划,看看是否有条目以这两个笔划开始顺序; 等等,直到我们得到一个匹配。

所以使用上面的字典,假设我们看到了这个序列:

A C B B C A B C A B D

以下是我们如何翻译它:

  1. A是三个不同长度的条目的开始; 看下一招: C
  2. A/C只匹配一个条目; 输出 “空调” 并从下一次开始新鲜: B
  3. B开始两个条目; 看下一招: B
  4. B/B没有任何启动; 采取最长的前一场比赛( B )并输出(“蜜蜂”)
  5. 输出B =“bee”,我们的缓冲区中仍有B笔划。它开始两个条目,所以看下一个笔划: C
  6. B/C匹配一个条目; 输出 “因为”,然后用下一个笔划重新开始: A
  7. A开始三个条目; 看下一招: B
  8. A/B开始两个条目; 看下一招: C
  9. A/B/C仅匹配一个条目; 输出 “字母” 并从下一笔开始新鲜: A
  10. A开始三个条目; 看下一招: B
  11. A/B开始两个条目; 看下一招: D
  12. A/B/D与任何内容都不匹配,因此请使用最长的前一个匹配( A/B )并使用它输出 “alphabet”。这给我们留下了D仍然在缓冲区中。
  13. D开始两个条目,所以我们通常会查看下一个笔划 - 但我们已经处理了所有笔划,因此请单独考虑它。孤立地,它翻译为 “狗”,因此输出。

以上方面要注意:

  • 你有一个你读过但尚未翻译的笔画缓冲区。
  • 您总是希望将最多笔画与您可以使用的单个条目进行匹配。 A/B应翻译为 “字母”,而不是 “alpha” 和 “bee”。
  • (上面没有显示)你可能有不能翻译的笔画序列,因为它们与字典中的任何内容都不匹配。 (Steno 人使用名词 “unranslate” - 例如,在我们的字典中,笔画E将是 “不翻译”。)
  • (上面没有显示)根据更广泛的背景,一些 steno 理论允许同一组笔画意味着不止一件事。斯特诺人称之为 “冲突”。你可能想要在你的项目中禁止它们,事实上当 steno 过去由 stenographer 手动翻译时,冲突很好,因为他们只知道句子中的位置是正确的选择,但是随着时间的推移机器翻译,无冲突的 steno 理论专门出现,以避免必须通过由此产生的翻译文本和 “修复” 冲突。
  • 实时翻译(你正在做的)意味着如果你收到部分匹配,你会想要在等待下一个和弦时保持它 - 但可能只有一个超时,此时你会尽可能地翻译缓冲区中的内容。 (或者你可能不希望超时; 这是你的电话。)
  • 可能最好有中风说 “忽视以前的中风”
  • 可能最好让中风 “完全清除缓冲区而不输出任何东西”

考虑在模拟 usb(或 ps / 2?)键盘的硬件中做一些事情。您将不再依赖于特定的操作系统或特定的操作系统 API。硬件解决方案经得起时间的考验。当其他人都运行 Windows 11 时,不要在 Windows 7 中使用旧的 API 卡住! Arduino很容易学习。

Arduino 有很多信息和帮助。它是为新手打造的硬件黑客平台。只有谷歌推动 Arduino ,它才会变大

编辑:虚拟 USB 键盘软件硬件

对我而言,听起来像是在寻找关于如何自己构建这个的建议,而是更多地询问已经有哪些资源来实现你想要的东西。根据您的操作系统,有许多方法可以实现这一点,而无需从头开始编写您自己的程序:

MIDI 笔画

自由。适用于Mac OS X 10.3 及更高版本 。这个特别配备 “能够使用任何MIDI键盘作为完整的电脑键盘更换。”

Bome 的 MIDI 翻译器

免费 / 明信片(这有点奇怪)。对于Windows 2000 及更高版本,以及 Mac OS X.它最初似乎更倾向于AutoHotkey类型的使用,但进一步看,我认为它可以做你想要的很好。

Max 和 aka.keyboard

自由。对于Mac OS X.不完全是 “开箱即用” 的解决方案,但如果您对基本设备配置感到满意,那应该不会太糟糕。