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

如何使用music21从.mxl文件提取音符的音高与时长数据?

Extracting Note Pitch and Duration from .mxl Files with music21

Hey there! I totally get where you're coming from—diving into music analysis with Python and music21 can feel a bit overwhelming at first, especially when you're hunting for specific data like note pitches and durations from .mxl files. Let me walk you through a straightforward way to do this, step by step.

Step 1: Make sure music21 is installed

First things first, if you haven’t already, install the library using pip:

pip install music21

Step 2: Load your .mxl file and extract notes

music21’s converter module handles .mxl files seamlessly. We’ll load the file, then traverse its structure to pull out every note (including individual notes within chords, since chords are just groups of notes played together).

Here’s a complete working example you can copy-paste and test:

from music21 import converter, note, chord

# Load the .mxl file (replace "your_file.mxl" with your actual file path)
score = converter.parse("your_file.mxl")

# Initialize a list to store our note data
note_data = []

# Traverse all elements in the flattened score structure
for element in score.flat:
    # Handle single notes
    if isinstance(element, note.Note):
        pitch_name = element.pitch.nameWithOctave  # e.g., "C4"
        midi_pitch = element.pitch.midi            # e.g., 60
        duration = element.duration.quarterLength  # relative to a quarter note (1.0)
        note_data.append({
            "pitch_name": pitch_name,
            "midi_pitch": midi_pitch,
            "duration": duration
        })
    # Handle chords (split into individual notes)
    elif isinstance(element, chord.Chord):
        for pitch in element.pitches:
            pitch_name = pitch.nameWithOctave
            midi_pitch = pitch.midi
            duration = element.duration.quarterLength  # all notes in a chord share the same duration
            note_data.append({
                "pitch_name": pitch_name,
                "midi_pitch": midi_pitch,
                "duration": duration
            })

# Print the extracted data
for idx, entry in enumerate(note_data, 1):
    print(f"Note {idx}: Pitch = {entry['pitch_name']} (MIDI {entry['midi_pitch']}), Duration = {entry['duration']} quarter notes")

Key details to keep in mind:

  • score.flat: This flattens the score’s nested structure (like parts, measures, voices) into a single list of elements, so you don’t have to write nested loops to dig through each section.
  • duration.quarterLength: This measures duration relative to a quarter note (valued at 1.0). For example:
    • Eighth note = 0.5
    • Half note = 2.0
    • Whole note = 4.0
  • Chords are broken down into individual notes because each pitch in a chord has the same duration as the chord itself—this way you get a complete list of every sounding pitch.

Optional: Target specific parts

If you only want notes from a particular part (e.g., piano left hand), you can access parts directly instead of flattening the entire score:

# Get the second part (index 1, adjust based on your score's structure)
piano_left_hand = score.parts[1]
for element in piano_left_hand.flat:
    # Same note/chord handling logic as above
    pass

That should cover exactly what you need to pull out basic note data from your .mxl files. If you run into weird edge cases (like grace notes or rests), let me know and we can tweak the code to handle those!

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

火山引擎 最新活动