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


当前回答

你可以用一个Teenys微控制器快速破解自己的USB键盘。

事实上,他们有如何制作USB键盘的示例代码。

你可以用两种方法来解决这个问题:

找一架旧钢琴,把开关直接连接到小钢琴上 添加额外的逻辑以连接到MIDI端口和必要的解码。

其他回答

有一个程序叫做GlovePIE。您可以用一种简单的脚本语言对它进行编程,而且我相信它支持MIDI。我不确定这是否符合“Java”的范畴,但它仍然是一个伟大的程序。我用它来控制使用PS3控制器的机器人。它非常强大。

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

MIDI是一连串的“事件”(或“信息”),其中最基本的两个是“开启”和“关闭”,它们都带有音符号(0 = C中C低5个八度,到127 = G中C以上G高5个八度,为半音)。这些事件在速度敏感(“触摸敏感”)的键盘上携带一个“速度”数字,其力度(你猜对了)在0到127之间。

Between velocity, chording, and the pedals, I'd think you could come up with quite a good "typing" interface for the piano keyboard. Chording in particular could be a very powerful technique — as I mentioned in the comments, it's why rank-and-file stenographers can use a stenotype machine to keep up with people talking for hours in a row, when even top-flight typists wouldn't be able to for any length of time via normal typewriter-style keyboards. As with machine stenography, you'd need a "dictionary" of the meanings of chords and sequences of chords. (Can you tell I used to work in the software side of machine stenography?)

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

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

为了最广泛地与软件兼容,您必须将其作为键盘设备驱动程序编写。这是操作系统的一个插件,用作键盘事件的源,与底层硬件(在您的例子中是钢琴键盘)通信。对于Windows和Linux,你可能会想要使用C语言。

However, since you're just generating keystrokes (not trying to intercept them, which I was trying to do years ago), you may be able to use whatever features the operating system has for sending artificial keystrokes. Windows has an interface for doing that (probably several, the one I'm thinking of is SendInput but I know there's some "journal" interface that does something similar), and I'm sure other operating systems do as well. That may well be sufficient for your purposes — it's where I'd start, because the device driver route is going to be awkward and you'd probably have to use a different language for it than Java. (I'm a big fan of Java, but the interfaces that operating systems use to talk to device drivers tend to be more easily consumed via C and similar.)


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

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

In machine stenography, the stenographer writes by pressing multiple keys on the stenotype machine at the same time, then releasing them all. They call this a "stroke" of the keyboard; it's like playing a chord on the piano. Strokes frequently (but not always) correspond to a syllable of spoken language. Like syllables, sometimes one stroke (chord) has meaning all on its own, other times it only has meaning combined with following strokes. (Think "good" vs. "good" followed by "bye"). Although they'll be heavily influenced by the school at which they studied, each stenographer will have their own "dictionary" of what strokes they use to mean what, a dictionary they will continuously hone over the course of their working lives. The dictionary will have entries where the stenographic part ("steno", for short) is one stroke long, or multiple strokes long. Frequently, there will be several entries with the same starting stroke which are differentiated by their length and by the subsequent strokes. For instance (and I won't use real steno here, just placeholders), there may be these entries:

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笔画取决于您之前是否看过A、B,或者您正在从头开始。

Also note that (although not shown in the very small sample above), there may be multiple ways to "play" the same word or phrase, rather than just one. Stenographers do that to make it easier to flow from a preceding word to the next depending on hand position. There's an obvious analogy to music there, and you could use that to make your typing flow more akin to playing music, in order to both prevent this from negatively affecting your piano playing and to maximize the likelihood of this actually helping with the RSI.

When translating steno into standard text, again we use a "longest-prefix match" search: The translation algorithm starts with the first stroke ever written, and looks for entries starting with that stroke. If there is only one entry, and it's one stroke long, then we can reliably say "that's the entry to use", output the corresponding text, and then start fresh with the next stroke. But more likely, that stroke starts multiple entries of varying lengths. So we look at the next stroke and see if there are entries that start with those two strokes in order; and so on until we get a match.

根据上面的字典,假设我们看到了这个序列:

A C B B C A B C A B D

我们是这样翻译的:

A is the start of three entries of varying lengths; look at next stroke: C A/C matches only one entry; output "air conditioning" and start fresh with next stroke: B B starts two entries; look at next stroke: B B/B doesn't start anything; take the longest previous match (B) and output that ("bee") Having output B = "bee", we still have a B stroke in our buffer. It starts two entries, so look at the next stroke: C B/C matches one entry; output "because" and start fresh with the next stroke: A A starts three entries; look at the next stroke: B A/B starts two entries; look at the next stroke: C A/B/C only matches one entry; output "alphabetic" and start fresh with the next stroke: A A starts three entries; look at next stroke: B A/B starts two entries; look at next stroke: D A/B/D doesn't match anything, so take the longest previous match (A/B) and use it to output "alphabet". That leaves us with D still in the buffer. D starts two entries, so we would normally look at the next stroke — but we've processed all the strokes, so consider it in isolation. In isolation, it translates as "dog" so output that.

以上各方面要注意:

You have a buffer of strokes you've read but haven't translated yet. You always want to match the most strokes against a single entry that you can. A/B should be translated as "alphabet", not "alpha" and "bee". (Not shown above) You may well have sequences of strokes that you can't translate, because they don't match anything in the dictionary. (Steno people use the noun "untranslate" -- e.g., with our dictionary, the strokes E would be an "untranslate".) (Not shown above) Some theories of steno allow the same set of strokes to mean more than one thing, based on a broader context. Steno people call these "conflicts". You probably want to disallow them in your project, and in fact when steno used to be translated manually by the stenographer, conflicts were fine because they'd know just by where in the sentence they were what the right choice was, but with the rise of machine translation, conflict-free theories of steno arose specifically to avoid having to go through the resulting translated text and "fix" conflicts. Translating in real time (which you'd be doing) means that if you receive a partial match, you'll want to hold onto it while waiting for the next chord — but probably only up to a timeout, at which point you'd translate what you have in the buffer as best you can. (Or maybe you don't want a timeout; it's your call.) Probably best to have a stroke that says "disregard the previous stroke" Probably best to have a stroke that says "completely clear the buffer without outputting anything"

我同意Brian O'Dell的回答——如果这是我的项目,我会用硬件来做。它的优点是与平台和硬件无关——你的盒子取代了对MIDI-USB接口和PC API的需求。

mbed是一个非常容易学习的快速原型平台,与Arduino IMHO相比具有多种优势(在线编译器,512 KB闪存,96 MHz, c++语言)。它有一个USB键盘接口和一个预先为您编写的USB Midi接口。

社区是非常友好和愿意帮助的,有很多现有的项目同时使用MIDI和USB隐藏仿真-搜索Youtube“mbed MIDI”或类似的。

您可以使用一个简单的AutoIt脚本来读取MIDI事件,请参阅MIDI输入。

您还需要MIDI UDF和模拟按键。

读取MIDI事件应该很容易,但不同的MIDI控制器(仪器)具有不同的功能。首先试着找出你的MIDI钢琴能做什么,然后看看你如何能最好地将这些功能映射到模拟qwerty键盘上。

如果你愿意,你可以在屏幕上或托盘上有一些东西来帮助你看到你正在做什么(也就是说,对于Shift, Ctrl和Alt模拟)。

许多键盘都有一个串行端口(RS-232)连接器,向计算机发送MIDI信号。我使用一个名为“梁”的程序将串口通信转换为键盘敲击。

“梁”有一个“映射”功能,允许您将每个键一个接一个地映射到相应的击键。

这可能是你正在寻找的简单解决方案!