You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Python或命令行将MIDI Type 1文件转换为MIDI Type 0?

Great question! Converting MIDI Type 1 files to Type 0 is totally feasible with Python, and I’ll walk you through two solid approaches: using a dedicated library with a reusable function, and a command-line ready script you can run directly. Let’s dive in:

Using the mido Python Library

mido is a lightweight, well-documented library for working with MIDI files across all major platforms. It handles the heavy lifting of parsing and writing MIDI data, making conversion straightforward.

First, install the library:

pip install mido

Here’s a robust conversion function that properly handles parallel tracks in Type 1 files (critical for accurate timing):

import mido

def convert_type1_to_type0(input_path, output_path):
    # Load the input MIDI file
    mid = mido.MidiFile(input_path)
    
    # Check if the file is already Type 0
    if mid.type != 1:
        print(f"Warning: Input file is already Type {mid.type} — no conversion needed.")
        return
    
    # Collect all messages with their absolute time from the start of the file
    all_messages = []
    for track in mid.tracks:
        current_absolute_time = 0
        for msg in track:
            current_absolute_time += msg.time
            # Skip end-of-track messages until the final track
            if not isinstance(msg, mido.MetaMessage) or msg.type != 'end_of_track':
                # Store absolute time and a copy of the message (resetting its relative time)
                all_messages.append((current_absolute_time, msg.copy(time=0)))
    
    # Sort messages by their absolute time to maintain proper playback order
    all_messages.sort(key=lambda x: x[0])
    
    # Create a new Type 0 MIDI file (single track)
    new_mid = mido.MidiFile(type=0)
    new_track = mido.MidiTrack()
    new_mid.tracks.append(new_track)
    
    # Convert absolute times back to relative times for the single track
    previous_time = 0
    for abs_time, msg in all_messages:
        msg.time = abs_time - previous_time
        new_track.append(msg)
        previous_time = abs_time
    
    # Add the final end-of-track marker
    new_track.append(mido.MetaMessage('end_of_track'))
    
    # Save the converted file
    new_mid.save(output_path)
    print(f"Success! Converted {input_path} to Type 0 MIDI at {output_path}")

# Example usage
convert_type1_to_type0("your_input_file.mid", "your_output_file.mid")

This script ensures all parallel tracks from the Type 1 file are merged into a single track with correct timing, which is essential for proper playback of the Type 0 file.

Command-Line Ready Conversion Script

If you want to run conversions directly from the terminal without modifying code, use this version with command-line argument support:

import mido
import argparse

def convert_type1_to_type0(input_path, output_path):
    mid = mido.MidiFile(input_path)
    
    if mid.type != 1:
        print(f"Warning: Input file is already Type {mid.type} — no conversion needed.")
        return
    
    all_messages = []
    for track in mid.tracks:
        current_absolute_time = 0
        for msg in track:
            current_absolute_time += msg.time
            if not isinstance(msg, mido.MetaMessage) or msg.type != 'end_of_track':
                all_messages.append((current_absolute_time, msg.copy(time=0)))
    
    all_messages.sort(key=lambda x: x[0])
    
    new_mid = mido.MidiFile(type=0)
    new_track = mido.MidiTrack()
    new_mid.tracks.append(new_track)
    
    previous_time = 0
    for abs_time, msg in all_messages:
        msg.time = abs_time - previous_time
        new_track.append(msg)
        previous_time = abs_time
    
    new_track.append(mido.MetaMessage('end_of_track'))
    new_mid.save(output_path)
    print(f"Conversion complete: {input_path} → {output_path}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Convert MIDI Type 1 files to Type 0.')
    parser.add_argument('input', help='Path to your input Type 1 MIDI file')
    parser.add_argument('output', help='Path to save the converted Type 0 MIDI file')
    args = parser.parse_args()
    
    convert_type1_to_type0(args.input, args.output)

Save this as midi_type_converter.py, then run it like this:

python midi_type_converter.py path/to/input.mid path/to/output.mid

内容的提问来源于stack exchange,提问作者user11253780

火山引擎 最新活动