3

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

我可以像这样使用 python-midi 库读取任何 MIDI 文件:

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

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

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

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

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

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

任何帮助表示赞赏。(Windows 10 64 位(32 位 Python 2.7))

4

3 回答 3

2

如果您查看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

打开一个 MIDI 文件,read_midifile()返回一个Pattern如下所示的对象(取自示例):

>>> 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 编号/音高和速度:

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

现在所有这些都很有趣,但是您实际上不需要将 MIDI 编号转换为音符,只需将其转换为http://virtualpiano.net/使用的该音符的键盘键。

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

midi_to_vk = (
    [None]*36 +
    list('1!2@34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm') +
    [None]*31
)

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

我认为您无法使用计算机键盘处理速度。还有时间问题,但你说这对你来说不是问题。

于 2016-01-27T10:04:45.490 回答
0

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

于 2016-01-26T11:09:51.307 回答
0

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

以下是维基百科的一些元素:

... GM 指定音符编号 69 播放 A440,这反过来将中间 C 固定为音符编号 60 ...

(来自MIDI - 通用 MIDI

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

(来自MIDI 调音标准 - 频率值

最后从C (音符) - 八度指定

Scientific designation  |Octave name |    Frequency (Hz) |    Other names
C4                      | One-lined  |           261.626 |    Middle C

来自维基百科的分区和钢琴键盘上的 C4 图像

所以 C 4是 midi 音符 69,midi 音符用半音 (*) 分隔。因为你在一个八度中有 12 个半音,所以你会在 midi note 81 处得到 C 5 ,而著名的 A440(midi note 69)在科学记数法中是 A 4 。

以表格为例

Midi note | Scientific notation
60        | C4
62        | D4
64        | E4
65        | F4
67        | G4
69        | A4
70        | B4
71        | C5

你会在 midi 66 处得到 F♯<sub>4...

(*) 这就是音乐上所谓的平等气质。Midi 允许更精细的音高定义,但它远远超出了这个答案。

于 2016-01-27T08:42:59.663 回答