如何用Python分离钢琴MIDI轨的左右手音符?
分离MIDI钢琴轨左右手音符的实现方案
MuseScore自动拆分左右手的逻辑
MuseScore并没有从MIDI文件中读取现成的左右手标识,而是通过启发式规则自动判断:
- 核心依据是音高范围:默认以中央C(MIDI编号60)为分界,低于60的音符归为左手声部,高于或等于的归为右手
- 同时结合音符的时值、小节位置、声部布局逻辑做调整,比如跨中央C的和弦会根据演奏习惯分配到对应声部,避免谱表混乱
在Python中实现左右手分离的两种方法
方法1:基于音高阈值(快速简便)
直接以中央C为分界拆分音符,适合大多数常规钢琴谱:
import mido from mido import MidiFile def split_hands_by_pitch(midi_file_path): mid = MidiFile(midi_file_path) left_hand_notes = [] right_hand_notes = [] # 定位钢琴轨道(program=0对应Acoustic Grand Piano) for track in mid.tracks: is_piano_track = False for msg in track: if msg.type == 'program_change' and msg.program == 0: is_piano_track = True break if not is_piano_track: continue # 遍历轨道提取音符 current_tick = 0 for msg in track: current_tick += msg.time if msg.type == 'note_on' and msg.velocity > 0: note_info = { 'midi_note': msg.note, 'tick_position': current_tick, 'velocity': msg.velocity } if msg.note < 60: left_hand_notes.append(note_info) else: right_hand_notes.append(note_info) return left_hand_notes, right_hand_notes # 使用示例 left_notes, right_notes = split_hands_by_pitch("your_piano_midi.mid")
方法2:匹配MuseScore的精准拆分(适合复杂谱例)
如果需要和MuseScore的拆分结果完全一致,可以借助MuseScore的命令行工具导出为MusicXML,再解析XML获取分声部信息:
- 确保MuseScore已安装并添加到系统环境变量
- 调用命令行导出XML:
mscore input.mid -o output.xml - 用
music21库解析XML提取左右手音符:
from music21 import converter import subprocess def split_hands_via_musescore(midi_file_path): # 临时XML文件路径 temp_xml = "temp_piano_score.xml" # 调用MuseScore导出XML subprocess.run(["mscore", midi_file_path, "-o", temp_xml], check=True) # 解析XML文件 score = converter.parse(temp_xml) left_notes = [] right_notes = [] # 遍历声部提取音符 for part in score.parts: instr_name = part.getInstrument().instrumentName if "Left Hand" in instr_name: for note in part.flat.notes: left_notes.append({ 'midi_note': note.pitch.midi, 'time_offset': note.offset, 'duration': note.duration.quarterLength }) elif "Right Hand" in instr_name: for note in part.flat.notes: right_notes.append({ 'midi_note': note.pitch.midi, 'time_offset': note.offset, 'duration': note.duration.quarterLength }) return left_notes, right_notes
关键说明
- MIDI标准本身没有定义左右手字段,所有拆分都是基于规则的启发式判断
- 部分制谱软件导出的MIDI可能用不同通道区分左右手,但PiJAMA数据集的MIDI是单通道单轨道,无法通过通道识别
- 交叉手段落等复杂情况,音高阈值法会出错,此时优先选择MuseScore导出XML的方案
内容的提问来源于stack exchange,提问作者Santiago Gonzalez
相关产品推荐
相关产品推荐

