Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Incorrect Key Signature Parsing in MEI Files

Abierto
#1,705 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
python
Área
data

Línea de trabajo

Start with the reproduction script, which parses the Bach-JS_Ein_feste_Burg.mei sample through music21's converter.parse and lists pitches for measures 0-1. Check whether the MEI reader in music21's converter/MEI code creates the key signature, and compare the parsed key with the MusicXML version of the same chorale. Done when F and C in the MEI output carry the sharps the key signature defines, and a test covers that MEI key signature case.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Description of the bug:
When parsing MEI files using music21.converter.parse(), key signatures are not being correctly interpreted or applied to the parsed pitches.

Steps to reproduce:

  1. Load an MEI file using music21.converter.parse().
  2. Extract notes and key signatures using the provided script.
  3. Print or inspect the key signatures and note transpositions.

Expected behavior:
Key signatures should be correctly detected and applied, altering the pitch representation according to the key.

Actual behavior:
Key signatures seem to be ignored or incorrectly parsed, resulting in all notes being interpreted as if they were in the key of C, without any transposition applied. For example, pitches F and C are shown without the expected sharps.

Environment:

music21 version: 9.1.0
Python version: 3.12
Operating System: Windows 11

Additional context:
This issue appears to specifically affect MEI file parsing, as similar operations with MusicXML files do not exhibit this behavior.

Code example
Using an MEI file from official score samples: Bach-JS_Ein_feste_Burg.mei. For comparison, the MusicXML file from the Chorale-Corpus featuring the same chorale is also provided as a reference.

As demonstrated in the output DataFrame, the pitches F and C do not include the sharp that's defined in the key signature.

from music21 import converter, note, chord, pitch as pitch_module
import pandas as pd
import matplotlib.pyplot as plt
import requests
import tempfile
import os

def get_file_path(file_source):
    if file_source.startswith(('http://', 'https://')):
        try:
            with requests.get(file_source) as response:
                response.raise_for_status()
                _, file_extension = os.path.splitext(file_source)
                # Ensuring the temporary file is not deleted and is properly closed
                temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=file_extension, mode='wb+')
                temp_file.write(response.content)
                temp_file.flush()  # Ensure all data is written
                temp_file.close()  # Close the file to ensure it's accessible later
                return temp_file.name
        except requests.RequestException as e:
            raise ValueError(f"Error downloading the file: {e}")
    else:
        if os.path.exists(file_source):
            return file_source
        else:
            raise FileNotFoundError("Local file does not exist")

def extract_voice_data(score, measure_range):
    start_measure, end_measure = measure_range
    voice_data = []
    notes_and_chords = score.flatten().notesAndRests.stream()

    for element in notes_and_chords:
        if isinstance(element, (note.Note, chord.Chord)):
            measure_num = element.measureNumber
            if start_measure <= measure_num <= end_measure:
                position_within_measure = element.offset
                duration = element.duration.quarterLength
                pitches = [str(element.pitch)] if isinstance(element, note.Note) else [str(p) for p in element.pitches]
                voice_data.extend([(measure_num, position_within_measure, duration, pitch) for pitch in pitches])

    return voice_data

measure_range = (0, 1)

file_source = 'https://raw.githubusercontent.com/music-encoding/sample-encodings/main/MEI_5.0/Music/Complete_examples/Bach-JS_Ein_feste_Burg.mei'

#MusicXML version for reference
#file_source = 'https://github.com/MarkGotham/Chorale-Corpus/raw/main/Bach,_Johann_Sebastian/Chorales/020/short_score.mxl'

file_path = get_file_path(file_source)
score = converter.parse(file_path)
voice_data = extract_voice_data(score, measure_range)
df = pd.DataFrame(voice_data, columns=['Measure', 'Local Onset', 'Duration', 'Pitch'])
display(df)

Output DataFrame:

Measure Local Onset Duration Pitch
0 0.0 1.0 D5
0 0.0 1.0 A4
0 0.0 1.0 F4
0 0.0 0.5 D4
0 0.5 0.5 C4
1 1.0 1.0 D5
1 1.0 1.0 D4
1 1.0 1.0 F4
1 1.0 1.0 B3
1 2.0 1.0 D5
1 2.0 0.5 D4
1 2.0 0.5 B3
1 2.0 0.5 A3
1 2.5 0.5 E4
1 2.5 0.5 C4
1 2.5 0.5 G3
1 3.0 0.5 A4
1 3.0 1.0 F4
1 3.0 1.0 D4
1 3.0 1.0 F3
1 3.5 0.5 B4
1 4.0 1.0 C5
1 4.0 1.0 G4
1 4.0 1.0 E4
1 4.0 1.0 E3
Lenguaje dominante
Python
Estrellas
2.6k
Forks
459
Merge medio
12 h 54 min
PR fusionados (30 d)
45

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de cuthbertLab/music21

Todos los issues de cuthbertLab/music21

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.