如何通过Pygame.midi获取MIDI按键的音名及对应八度?
如何给MIDI按键音名添加八度标识?
现有一段读取MIDI按键音名的Python代码:
import pygame.midi def number_to_note(number): notes = ['c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#', 'a', 'a#', 'b'] return notes[number%12] def readInput(input_device): while True: if input_device.poll(): event = input_device.read(1)[0] data = event[0] timestamp = event[1] note_number = data[1] velocity = data[2] print(number_to_note(note_number)) note = number_to_note(note_number) if __name__ == '__main__': pygame.midi.init() my_input = pygame.midi.Input(1) readInput(my_input)
这段代码仅能输出按键对应的基础音名(如a#),无法获取包含八度的完整音名(如A#4)。要实现这个功能,只需利用MIDI音符编号的规则做简单计算:
修改思路
MIDI音符编号范围是0-127,其中C0对应编号12,每12个连续编号对应一个完整八度。因此八度值可以通过(音符编号 // 12) - 1计算得出,再将基础音名格式化后与八度值拼接即可。
修改后的完整代码
import pygame.midi def number_to_note(number): # 将音名改为首字母大写格式,符合通用记谱习惯 notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] # 计算八度:MIDI编号12对应C0,整除12后减1得到正确八度值 octave = (number // 12) - 1 # 返回拼接好的完整音名+八度 return f"{notes[number % 12]}{octave}" def readInput(input_device): while True: if input_device.poll(): event = input_device.read(1)[0] data = event[0] note_number = data[1] # 打印完整的带八度的音名 print(number_to_note(note_number)) if __name__ == '__main__': pygame.midi.init() # 注意:设备编号1需根据你的实际MIDI设备调整 # 可用pygame.midi.get_count()查看可用设备数量,再选择正确编号 my_input = pygame.midi.Input(1) try: readInput(my_input) finally: # 程序结束时清理资源,避免设备占用 my_input.close() pygame.midi.quit()
关键修改点说明
- 音名格式调整:将原小写音名改为首字母大写,符合音乐记谱的通用规范(如
A#而非a#)。 - 八度计算逻辑:通过
(number // 12) - 1得到正确的八度值,确保MIDI编号69对应标准音高A4。 - 资源清理:添加
try...finally块,确保程序结束时能正确关闭MIDI设备并退出pygame.midi,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Andrei Vechar
相关产品推荐
相关产品推荐

