镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

MusicXML import drops piano-family MIDI programs when the instrument name isn't recognized #2084

Open

Description

@bramtayl

music21 version

10.5.0

Problem summary

When a part's <midi-program> is one music21 maps to Piano (MusicXML programs 1–6), the importer replaces that instrument with the one made from <instrument-name>. That makes sense when the name is recognized, since exporters often write piano as a default program. But when the name isn't recognized, the replacement is a plain Instrument with no midiProgram, so the program is lost. Other programs are kept.

Steps to reproduce

from music21 import converter, instrument

def score(midi_program):
    return f'''<score-partwise version="4.0">
  <part-list><score-part id="P1"><part-name>Music</part-name>
    <score-instrument id="P1-I1"><instrument-name>Doubler</instrument-name></score-instrument>
    <midi-instrument id="P1-I1"><midi-program>{midi_program}</midi-program></midi-instrument>
  </score-part></part-list>
  <part id="P1"><measure number="1">
    <attributes><divisions>1</divisions></attributes>
    <note><pitch><step>C</step><octave>4</octave></pitch><duration>4</duration><type>whole</type></note>
  </measure></part>
</score-partwise>'''

for midi_program in (41, 1, 2):
    parsed = converter.parse(score(midi_program), format='musicxml')
    print(midi_program, [(type(i).__name__, i.midiProgram)
                         for i in parsed.recurse().getElementsByClass(instrument.Instrument)])

Expected vs. actual behavior

Expected a midiProgram of 40, 0 and 1. Actual:

41 [('Violin', 40)]
1 [('Instrument', None)]
2 [('Instrument', None)]

More information

The replacement is in MeasureParser's score-part handling (musicxml/xmlToM21.py):

# 2. midiProgram is Piano (often this is encoded only as piano for convenience)
if inst_from_name.midiProgram == i.midiProgram or isinstance(i, instrument.Piano):
    i = inst_from_name

This isn't asking to remove the piano rule, only to not lose the program when the name doesn't give an instrument, for example by only replacing when the name was recognized, or by keeping i.midiProgram on the replacement.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions