跳到主要内容

MIDI 格式(电子乐器)

MIDI(Musical Instrument Digital Interface,乐器数字接口)格式由 Dave Smith 等工程师于 1983 年提出,是电子乐器与计算机的通信协议标准。MIDI 文件不存储音频波形,而是记录音符、力度、音色编号等控制指令,体积极小(1 分钟音乐约 10KB),音质依赖终端音源库,广泛应用于电子音乐制作、游戏配乐和乐谱编辑。

格式简介

MIDI 是一种数字音乐标准,用于在电子乐器、计算机和其他设备之间传输音乐信息。MIDI 文件不包含实际的音频数据,而是包含音乐事件的指令,如音符、音色、力度、时间等。

MIDI 文件扩展名为 .mid.midi,MIME 类型为 audio/midiaudio/x-midi。MIDI 格式是音乐制作和电子乐器控制的标准格式。

技术特点

核心特性

  • 指令格式:存储音乐事件指令而非音频波形
  • 文件极小:1 分钟音乐通常只有几 KB 到几十 KB
  • 可编辑性:易于编辑和修改
  • 设备控制:可以控制各种 MIDI 设备
  • 标准化:工业标准,广泛支持

MIDI 消息类型

MIDI 消息包括:

  • 音符开/关:Note On/Off(音符、力度)
  • 音色变化:Program Change(音色编号)
  • 控制变化:Control Change(音量、效果等)
  • 音高弯音:Pitch Bend
  • 系统消息:系统专用消息

MIDI 格式版本

  • MIDI 0:单轨格式
  • MIDI 1:多轨格式(标准格式)

文件结构

MIDI 文件由以下部分组成:

[文件头块]                # MThd 标识 + 头信息
- 格式类型(0/1/2)
- 轨道数
- 时间基准
[轨道块 1] # MTrk 标识 + 轨道数据
- 事件列表
[轨道块 2] # 多轨格式的额外轨道
...

关键块说明

  • MThd:文件头,包含格式信息和轨道数
  • MTrk:轨道块,包含 MIDI 事件
  • 事件:包含时间戳和 MIDI 消息

MIDI 事件格式

每个 MIDI 事件包含:

  • 时间增量:相对于上一个事件的时间
  • 状态字节:消息类型(音符、控制等)
  • 数据字节:消息参数(音符编号、力度等)

使用场景

适用场景

  • 音乐制作:电子音乐创作和编曲
  • 游戏配乐:游戏背景音乐和音效
  • 乐谱编辑:数字乐谱制作和编辑
  • 音乐教育:音乐学习和教学
  • 设备控制:MIDI 设备控制和同步
  • 手机铃声:传统手机铃声格式

优缺点

优点:

  • 文件体积极小
  • 易于编辑和修改
  • 可以改变音色和速度
  • 标准化格式,广泛支持
  • 适合音乐制作和编曲

缺点:

  • 不包含音频数据,需要音源
  • 音质依赖音源库质量
  • 不同设备播放效果可能不同
  • 不适合直接播放(需要合成器)

代码示例

Python 读取 MIDI

from mido import MidiFile

# 读取 MIDI 文件
mid = MidiFile('music.mid')
print(f"轨道数: {len(mid.tracks)}")
print(f"时长: {mid.length} 秒")
print(f"时间基准: {mid.ticks_per_beat}")

# 遍历所有消息
for i, track in enumerate(mid.tracks):
print(f"\n轨道 {i}:")
for msg in track:
print(f" {msg}")

Python 创建 MIDI

from mido import MidiFile, MidiTrack, Message

# 创建新的 MIDI 文件
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

# 添加音符(C 大调音阶)
notes = [60, 62, 64, 65, 67, 69, 71, 72] # C4 到 C5
for note in notes:
track.append(Message('note_on', note=note, velocity=64, time=0))
track.append(Message('note_off', note=note, velocity=64, time=480))

# 保存文件
mid.save('output.mid')

Python 使用 music21

from music21 import converter, stream, note

# 读取 MIDI
score = converter.parse('music.mid')

# 分析音乐
key = score.analyze('key')
print(f"调性: {key}")

# 创建简单的 MIDI
s = stream.Stream()
n = note.Note('C4')
n.duration.quarterLength = 1.0
s.append(n)
s.write('midi', fp='output.mid')

JavaScript 处理 MIDI

// 使用 Tone.js 播放 MIDI
import * as Tone from 'tone';

// 创建合成器
const synth = new Tone.Synth().toDestination();

// 播放音符
synth.triggerAttackRelease('C4', '8n');
synth.triggerAttackRelease('E4', '8n', '+0.5');
synth.triggerAttackRelease('G4', '8n', '+1');

使用 Web MIDI API

// 访问 MIDI 设备
navigator.requestMIDIAccess().then((midiAccess) => {
const inputs = midiAccess.inputs;
inputs.forEach((input) => {
input.onmidimessage = (event) => {
console.log('MIDI 消息:', event.data);
};
});
});

相关工具

  • 音乐制作软件
    • FL Studio:专业音乐制作软件
    • Ableton Live:音乐制作和演出软件
    • Logic Pro:macOS 音乐制作软件
    • GarageBand:入门级音乐制作软件
  • 乐谱编辑
    • MuseScore:开源乐谱编辑器
    • Sibelius:专业乐谱软件
  • MIDI 播放器
    • Windows Media Player:支持 MIDI
    • VLC Media Player:支持 MIDI
  • 编程库
    • Python: midomusic21pretty_midi
    • JavaScript: tone.jsmidi-parser-js
    • C/C++: libmidiRtMidi

相关链接

参考