Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将midi文件转换为按键(在Python中)?_Python_Keypress_Midi_Piano_Sound Synthesis - Fatal编程技术网

如何将midi文件转换为按键(在Python中)?

如何将midi文件转换为按键(在Python中)?,python,keypress,midi,piano,sound-synthesis,Python,Keypress,Midi,Piano,Sound Synthesis,我试图读取一个MIDI文件,然后将每个音符(MIDI编号)转换为键盘上的模拟按键(a、f、h、J、t…) 我可以通过python MIDI库读取任何MIDI文件,如下所示: pattern = midi.read_midifile("example.mid") shell = win32com.client.Dispatch("WScript.Shell") shell.SendKeys(key) 我还可以用pywin32模拟按键,如下所示: patt

我试图读取一个MIDI文件,然后将每个音符(MIDI编号)转换为键盘上的模拟按键(a、f、h、J、t…)

我可以通过python MIDI库读取任何MIDI文件,如下所示:

pattern = midi.read_midifile("example.mid")
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys(key)
我还可以用pywin32模拟按键,如下所示:

pattern = midi.read_midifile("example.mid")
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys(key)
但我不知道如何将midi数字(midi文件中的数字)转换成按键

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

当然,我也必须在按键之间等待,但这很容易


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

首先检查问题。这是关于如何模拟按键的一般想法,它看起来可能很多,但它只是一个键的大列表。然后,要将midi转换为键盘按钮,您需要在音符和键盘按钮之间创建字典映射。

我知道,您真正需要的是一种将midi音符编号转换为标准符号音符的方法

以下是维基百科中的一些内容:

。。。GM指定69号音符播放A440,而A440又将中间C固定为60号音符

(来自

从midi音符编号(d)到频率(f)的转换由以下公式给出:
f=2(d-69)/12*440 Hz

(来自)

最后从

C4是midi音符69,midi音符用一个半音(*)隔开。一个八度音阶中有12个半音,在midi音符81中得到C5,而著名的A440(midi音符69)是科学记数法中的A4

以表格为例

Midi音符|科学记数法
60 | C4
62 | D4
64 | E4
65 | F4
67 | G4
69 | A4
70 | B4
71 | C5
你会得到F♯4在midi 66


(*)这在音乐上被称为“等音律”。Midi允许更精细的音高定义,但这远远超出了这个答案。

如果你看看你正在使用的
Midi
模块,你会发现有一些常量可以用来将音符转换为Midi编号,反之亦然

>>> 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文件将返回一个
模式
对象,该对象如下所示(取自示例):

NoteOnEvent
包含可检索的计时、MIDI数字/音高和速度:

>>> on = midi.NoteOnEvent(tick=0, channel=0, data=[43, 20])
>>> on.pitch
43
>>> midi.NOTE_VALUE_MAP_SHARP[on.pitch]
'G_3'
现在,所有这些都很有趣,但您并不需要将MIDI数字转换为音符,您只需要将其转换为所使用的该音符的键盘键

中间C相当于MIDI 60,此音符对应于virtualpiano键盘上的第25个键,可通过按字母
t
激活。下一个音符Cs_5是MIDI 61,大写字母
t
(.t)
。从这里,您可以计算出MIDI号码到支持的virtualpiano键的映射;它是这样的:

midi_to_vk = (
    [None]*36 +
    list('1!2@34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm') +
    [None]*31
)
您将面临的下一个问题是发送按键事件。请注意,在MIDI中,多个音符可以同时播放,也可以在时间上重叠。这意味着您可能需要能够同时发送多个按键事件


我认为你不能用电脑键盘来处理速度。还有计时的问题,但你说这对你来说不是问题。

如果我正确理解了你的问题,你需要能够识别MIDI文件中的音符。你可以用很难的方法来做(直接解析文件)或者使用现有的库,例如。我说过“我可以用python MIDI库读取任何MIDI文件”,我可以。这样做没有问题。实际上我提到了与您完全相同的库。问题是我找不到任何关于如何将MIDI数字转换为C#-36或A-40等音符的文档(或任何正确的名称)我知道如何模拟按键。你说的字典就是问题所在。所有关于midi到音符转换的网站都有一个我不懂的键表。比如:音符a#八度4是这个和那个midi数字,但实际上。C-5、a#-2和其他“正常”音符不在虚拟钢琴上,它有像C-61和a#-45这样的音符我认为MIDI音符编号映射在
python MIDI
模块中是不同的。如果我理解正确,这个模块将MIDI 60映射到C_5而不是C_4。
导入MIDI;打印MIDI。C_5
显示60,应该等于中间C。但是,如middl所列在科学名称中,e C是C4。也许我遗漏了什么?可能是有些是从八度1开始的,而有些是从八度1开始的吗?