Incorrect Key Signature Parsing in MEI Files
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 25/100
Direzione di ricerca
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.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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:
- Load an MEI file using music21.converter.parse().
- Extract notes and key signatures using the provided script.
- 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 |
- Lingua principale
- Python
- Stelle
- 2.6k
- Fork
- 459
- Merge medio
- 1g 7h
- PR unite (30g)
- 40
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di cuthbertLab/music21
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
cuthbertLab/music21#2084 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
cuthbertLab/music21#2082 ·
I maintainer di solito rispondono entro 1 giorno
-
`TypeError` in `ChordReducer.run()` on multi-part `stream.Score` without instrument `partId`sAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
cuthbertLab/music21#2074 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
cuthbertLab/music21#2055 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Slur bezier-x/y from start element gets overwritten by stop element's valuesForse di nuovo libera @bingliscodes l’ha presa 8 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
cuthbertLab/music21#2019 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di cuthbertLab/music21
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
aws-samples/sample-per-model-bedrock#243 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
FuRongJun-1999/dsh-memory#404 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
bug frontend
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
PennyLaneAI/catalyst#3337 ·
I maintainer di solito rispondono entro 1 giorno
-
Workflow.schedule stops when a cron deadline passes before sleepForse già presa @HuaTNA l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno