python编程midi键盘按键_如何将Midi文件转换为按键(在Python中)?

1586010002-jmsa.png

I'm trying to read a MIDI file and then convert each note (midi number) to a simulated keypress on the keyboard (A,f,h,J,t...).

I'm able to read any MIDI file with the python-midi library like this:

pattern = midi.read_midifile("example.mid")

and I can also simulate keypresses with pywin32 like this:

shell = win32com.client.Dispatch("WScript.Shell")

shell.SendKeys(key)

But I have no idea on how to actually convert midi numbers (that are in midi files) to keypresses.

To be more precise I'm trying to convert MIDI numbers to notes and then notes to keypresses according to virtualpiano.net (61-key) so that the program would play that piano by pressing the corresponding button on the keyboard (you can press key assist in settings of the piano to see which key is what button)

Of course I would also have to wait between keypresses but that's easy enough.

Any help is appreciated. (Windows 10 64-bit (32-bit Python 2.7))

解决方案

If you take a look at the midi module that you are using, you will see that there are some constants that can be used to convert notes to their MIDI number and vice versa.

>>> import midi

>>> midi.C_0 # note C octave 0

0

>>> midi.G_3 # G octave 3

43

>>> midi.Gs_4 # G# octave 4

56

>>> midi.A_8 # A octave 8

105

>>> midi.NOTE_VALUE_MAP_SHARP[0]

C_0

>>> midi.NOTE_VALUE_MAP_SHARP[56]

Gs_4

>>> midi.NOTE_VALUE_MAP_SHARP[105]

A_8

Opening a MIDI file with read_midifile() returns a Pattern object which looks like this (taken from the examples):

>>> midi.read_midifile('example.mid')

midi.Pattern(format=1, resolution=220, tracks=\

[midi.Track(\

[midi.NoteOnEvent(tick=0, channel=0, data=[43, 20]),

midi.NoteOffEvent(tick=100, channel=0, data=[43, 0]),

midi.EndOfTrackEvent(tick=1, data=[])])])

The NoteOnEvent contains timing, MIDI number/pitch and velocity which you can retrieve:

>>> on = midi.NoteOnEvent(tick=0, channel=0, data=[43, 20])

>>> on.pitch

43

>>> midi.NOTE_VALUE_MAP_SHARP[on.pitch]

'G_3'

Now all of that is interesting, but you don't really need to convert the MIDI number to a note, you just need to convert it to the keyboard key for that note as used by http://virtualpiano.net/.

Middle C is equal to MIDI 60 and this note corresponds to the 25th key on the virtualpiano keyboard which is activated by pressing the letter t. The next note, Cs_5, is MIDI 61 which is uppercase T (-t). From there you can work out the mapping for the MIDI numbers to the supported virtualpiano keys; it's this:

midi_to_vk = (

[None]*36 +

list('1!2@34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm') +

[None]*31

)

The next problem that you will face is sending the key events. Note that in MIDI multiple notes can be played simultaneously, or can overlap in time. This means that you might need to be able to send more than one key press event at the same time.

I don't think that you can handle the velocity using a computer keyboard. There is also the issue of timing, but you said that that's not a problem for you.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值