PrettyMIDI 快速上手教程:读取、改写与合成 .mid 文件
2026/8/24 17:53:07 网站建设 项目流程

PrettyMIDI 快速上手教程:读取、改写与合成 .mid 文件

【免费下载链接】pretty-midiUtility functions for handling MIDI data in a nice/intuitive way.项目地址: https://gitcode.com/gh_mirrors/pr/pretty-midi

PrettyMIDI 是一个 Python 库,能把.mid文件解析成以秒为单位计时的 Python 对象,也可以反向写出 MIDI 文件、渲染成音频波形。它解决的是"从乐谱数据里提取信息、再修改保存"这类问题,适合做音乐数据处理、音频算法或刚接触 MIDI 的开发者。本文走一遍安装、读取音符、音高换算和音频合成这几个常用用法。

三步跑起来:一条命令安装加一段可运行代码

先装包:

pip install pretty-midi

仓库里自带了示例文件example.mid,本地没有它的话执行:

git clone https://gitcode.com/gh_mirrors/pr/pretty-midi

然后直接把下面这段代码复制运行,它会打印速度估计、画出一张钢琴卷帘、再渲染出音频:

import pretty_midi import scipy.io.wavfile pm = pretty_midi.PrettyMIDI('example.mid') print('tempo ~', pm.estimate_tempo()) # 经验估计的整体速度 roll = pm.get_piano_roll(fs=10) # 钢琴卷帘矩阵,可直接绘图 audio = pm.fluidsynth() # 用包内 TimGM6mb.sf2 渲染 scipy.io.wavfile.write('out.wav', 44100, audio)

能听到声音,说明环境就绪。

从 .mid 文件里把所有音符读出来

PrettyMIDI对象按"轨道"组织:instruments是乐器列表,每个乐器的notes是音符列表。Note对象有四个字段:velocity(力度)、pitch(音高编号)、start/end(起止秒数)。

pm = pretty_midi.PrettyMIDI('example.mid') for inst in pm.instruments: for n in inst.notes: print(inst, n.pitch, n.start, n.end)

所有时间都以秒为单位,不需要自己换算 MIDI tick,这是这个库最省事的地方。

音高与频率互相换算

拿到 MIDI 音高编号后,经常要换成物理频率(Hz)或反过来。两个工具函数直接调用即可:

print(pretty_midi.note_number_to_hz(60)) # 中音 C4 → 261.63 Hz print(pretty_midi.hz_to_note_number(440)) # A4 的频率 → 音高编号 69

反过来,如果手里只有音名字符串,note_name_to_number('C4')note_number_to_name(60)可以完成名称与编号的互换;program_to_instrument_name()则用来查某个音色编号对应的乐器名。

从零合成一个 C 大调和弦并保存

不需要现成的.mid文件,也可以手工组装一个。核心思路是:创建PrettyMIDI对象 → 加一个乐器 → 往乐器里塞音符 → 调用write()

pm = pretty_midi.PrettyMIDI() piano = pretty_midi.Instrument(program=0) # GM 音色 0 = 钢琴 pm.instruments.append(piano) for name in ['C4', 'E4', 'G4']: # C 大和弦的三个音 piano.notes.append(pretty_midi.Note( velocity=100, pitch=pretty_midi.note_name_to_number(name), start=0, end=0.6)) # 每个音响 0.6 秒 pm.write('chord.mid')

注意Note的第一个参数是velocity(力度),不是音高——参数顺序写反是新手最常见的错误。

进阶:把 MIDI 渲染成能播放的 wav 🎵

.mid本身只是指令数据,不含任何声音。要得到波形,synthesize()用正弦波叠加出一个"电子琴"版本;音质更高的是fluidsynth(),它调用 FluidSynth 配合音色库(soundfont)渲染,需要先pip install pyfluidsynth。包内已自带TimGM6mb.sf2,不用额外下载音色文件:

audio = pm.fluidsynth() # 44100 Hz 的 float 波形 scipy.io.wavfile.write('out.wav', 44100, audio)

鼓声轨在synthesize()中会被忽略,含打击乐的文件建议走 fluidsynth 这条路。

常见坑与 FAQ

Q:note.pitch是 60 就代表 C4 吗?是。MIDI 音高是 0–127 的整数编号,60 = C4(中音 C),每大 1 升一个半音。要频率用note_number_to_hz(),不要拿velocity当频率用,那是力度。

Q:estimate_tempo()返回的不是 BPM?它返回 QPM(每秒四分音符数),与 BPM 差一个 60 倍。换算用pretty_midi.qpm_to_bpm(),或直接读pm.tempo

Q:write()之后为什么没有 wav?write()只负责保存.mid。想要音频,必须再走一遍synthesize()fluidsynth()

继续深入

  • 官方文档:docs/
  • 可运行的示例脚本(和弦目录、芯片音合成、音频对齐、钢琴卷帘反演):examples/
  • 测试用例,可对照 API 的标准用法:tests/
  • 交互式教程:Tutorial.ipynb

PrettyMIDI 的核心工作流就是"读进来、按任务改、存出去或渲染",上面的代码基本覆盖了日常 90% 的需求。

【免费下载链接】pretty-midiUtility functions for handling MIDI data in a nice/intuitive way.项目地址: https://gitcode.com/gh_mirrors/pr/pretty-midi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询