我们打算结合上一篇的键盘驱动实现把键盘变成电子琴的功能。所以首先要让程序播放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 列表 判断某个元素是不是在某列表里的判断。