如何将Midi文件转换为按键(在Python中)? [英] How to convert midi files to keypresses (in Python)?

查看:528
本文介绍了如何将Midi文件转换为按键(在Python中)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试读取MIDI文件,然后将每个音符(MIDI编号)转换为键盘上的模拟按键(A,f,h,J,t ...).

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...).

我可以使用python-midi库读取任何MIDI文件,如下所示:

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

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

我也可以像这样用pywin32模拟按键:

and I can also simulate keypresses with pywin32 like this:

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

但是我不知道如何将Midi数字(位于midi文件中)实际转换为按键.

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

更准确地说,我正在尝试根据 virtualpiano.net 将MIDI数字转换为音符,然后将音符转换为按键. >(61键),以便程序可以通过按键盘上的相应按钮来弹钢琴(您可以在钢琴的设置中按键盘辅助键来查看哪个键是哪个按钮)

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.

感谢您的帮助. (Windows 10 64位(32位Python 2.7))

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

推荐答案

如果查看正在使用的midi模块,您会发现有些常量可用于将笔记转换为它们. MIDI号,反之亦然.

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

使用read_midifile()打开MIDI文件将返回一个如下所示的Pattern对象(摘自示例):

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=[])])])

NoteOnEvent包含可以检索的定时,MIDI数字/音高和力度:

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'

现在所有这些都很有趣,但是您实际上并不需要将MIDI编号转换为音符,只需将其转换为

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/.

中音C等于MIDI 60,此音符对应于虚拟钢琴键盘上的第25键,可以通过按字母t来激活它.下一个音符Cs_5是大写T (<shift>-t)的MIDI 61.从那里,您可以算出MIDI编号到支持的虚拟钢琴键的映射.是这样的:

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 (<shift>-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
)

您将面临的下一个问题是发送关键事件.请注意,在MIDI中,多个音符可以同时播放,也可以在时间上重叠.这意味着您可能需要能够同时发送多个按键事件.

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.

这篇关于如何将Midi文件转换为按键(在Python中)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆