当前位置:首页>python>Python高手之路: 简易MIDI播放器

Python高手之路: 简易MIDI播放器

  • 2026-10-11 06:42:30
Python高手之路: 简易MIDI播放器

我们打算结合上一篇的键盘驱动实现把键盘变成电子琴的功能。所以首先要让程序播放midi。然后再下一篇把这两个功能组合起来实现一个简易电子琴。本篇只是实现midi播放的功能。

      打开pycharm,在左上方项目栏找到+,新建一个文件,弹出如下菜单,选择python文件,并且起名为midi.py
      安装支持midi播放的第三方库,这里需要装两个,一个是读写midi格式的库mido, 另一个是midi解码播放的后端库python-rtmidi,他是关联电脑内置的midi解码器进行音乐播放用的。
我们这里案例是针对windows系列的。 他会自动关联windows系统内置的midi播放器(软播表解码器)。mac电脑需要多装一个库portmidi,并且在系统设置里把midi输出定向到IAC端口。
但是linux因为系统默认不支持midi解码,所以要在命令行安装音乐底层库,

sudo apt install libportmidi-dev libasound2-dev

然后还需要安装linux上的midi解码器

sudo apt install timidity timidity-daemon

import timeimport midoNoteMap = {    '1' : 60,   '2' : 62,       '3' : 64,       '4' : 65,       '5' : 67,       '6' : 69,       '7' : 70,       '8' : 72}melody = "1 2 3 3 2 1 1 3 2 1 2"print("MIDI player start.")with mido.open_output() as output:    print(f"begin to play {melody}")        for char in melody.split():                if char in NoteMap:                        midi_note = NoteMap[char]                        output.send(mido.Message('note_on', note=midi_note, velocity=100))                        time.sleep(0.4)                        output.send(mido.Message('note_off', note=midi_note, velocity=100))                        time.sleep(0.05)print("stop playing.")
代码比较简单,总共二十多行
  • NoteMap 定义了电子琴do le mi fa so la ti do,8个声音。其他音符可以按照全音半音推即可。这是个字典。
  • melody 定义字符串,保存是little start 的乐谱
  • with mido.open_optput() as output: 是一种优雅开启文件设备的写法,不用关系文件关闭和内存回收。相当于开启了midi设备
  • for char in melody.split(): 遍历字符串melody,并且把字符串用空格分割成了列表,也就是遍历这个列表,每次取出来的放到char里面
  • if char in NoteMap: 判断一下取出来的字符 char,是不是在最开始定义的音符库中,如果不再就忽略了。
  • midi_note =  NoteMap[char] 既然在音符库里,就把音符的数字从字典NoteMap里给取出来,1就是do =60, 2就是le = 62 
    NoteMap[char]使用[]是检索map的用法。
  • output.send前后用了两次, 第一次是使用note_on开始放音,第二次使用note_off停止放音。音符是note 里的值。velocity是强度
  • time_sleep(0.4) 调用的系统暂停的命令,在这这里等待0.4秒。第二次time_sleep(0.05)是为了两个音符之间有一个微小的停顿。
这样就把melody里面每个音符都给演奏出来了。这里用到了map字典,with mido.open_output()优雅开启,for char in 列表 遍历一个列表的循环,melody.split() 用默认分隔符空格来切割字符串成为列表。if char in 列表 判断某个元素是不是在某列表里的判断。

最新文章

随机文章