`music21.midi.MidiEvent.getBytes()` confuses `SEQUENCER_SPECIFIC_META_EVENT` (0x7F) with `POLY_MODE_ON` (also 0x7F)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 55/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Estancado
- Stack tecnológico
- python
- Área
- audio-video-rtc
Línea de trabajo
The bug is in getBytes() in music21/midi/init.py, which dispatches on the raw enum value so SEQUENCER_SPECIFIC_META_EVENT (0x7F) matches ChannelModeMessages.POLY_MODE_ON and crashes when channel is None. Reproduce with the snippet in the issue, then make the branch checks also verify the enum class of self.type. Done when the snippet no longer raises and a MidiFile read-then-write round trip succeeds.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
music21 version
9.5.0
Operating System(s) checked
OS agnostic
(I am on Ubuntu 24.04, though, but that should be irrelevant.)
Problem summary
music21.midi.MidiEvent.getBytes() confuses SEQUENCER_SPECIFIC_META_EVENT (0x7F) with POLY_MODE_ON (also 0x7F) and will therefore cause a TypeError if the former does not care about channels (i.e self.channel == None).
Steps to reproduce
from music21 import midi
ev = midi.MidiEvent(type=midi.MetaEvents.SEQUENCER_SPECIFIC_META_EVENT, channel=None)
print(ev)
b = ev.getBytes()
FYI: Actually I encountered this issue not by instantiating a MidiEvent manually but by writing a MidiFile which comes with some SEQUENCER_SPECIFIC_META_EVENT's.
mf = midi.MidiFile()
mf.open(inputfile)
mf.read()
mf.close()
# write the contents back immediately without touching anything
mf.open(outputfile, 'wb')
mf.write()
mf.close()
Expected vs. actual behavior
EXPECTED BEHAVIOUR:
music21.midi.MidiEvent.getBytes() should process all MIDI events correctly without triggering any exception.
ACTUAL BEHAVIOUR:
File "/foo/bar/lib/python3.12/site-packages/music21/midi/__init__.py", line 982, in getBytes
channelMode = bytes([0xB0 + self.channel - 1])
~~~~~^~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
More information
The current code of music21.midi.MidiEvent.getBytes() checks the event type essentially by looking at its value only:
def getBytes(self):
if self.type in ChannelVoiceMessages:
...
elif self.type in ChannelModeMessages:
channelMode = bytes([0xB0 + self.channel - 1])
...
elif self.type in SysExEvents:
...
elif self.type in MetaEvents:
...
else:
...
However:
class ChannelModeMessages(_ContainsEnum):
...
POLY_MODE_ON = 0x7F
...
class MetaEvents(_ContainsEnum):
...
SEQUENCER_SPECIFIC_META_EVENT = 0x7F
...
Apparently, getBytes() will mistake a SEQUENCER_SPECIFIC_META_EVENT as a POLY_MODE_ON, and will then fail immediately if self.channel is null.
Therefore, it is probably more appropriate to also check the event class, in addition to the event type value:
if isinstance(self.type, ChannelVoiceMessages) and self.type in ChannelVoiceMessages:
...
elif isinstance(self.type, ChannelModeMessages) and self.type in ChannelModeMessages:
...
elif isinstance(self.type, SysExEvents) and self.type in SysExEvents:
...
elif isinstance(self.type, MetaEvents) and self.type in MetaEvents:
...
- Lenguaje dominante
- Python
- Estrellas
- 2.6k
- Forks
- 459
- Merge medio
- 1 d 7 h
- PR fusionados (30 d)
- 40
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de cuthbertLab/music21
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
cuthbertLab/music21#2084 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
cuthbertLab/music21#2082 ·
Los mantenedores suelen responder en 1 día
-
`TypeError` in `ChordReducer.run()` on multi-part `stream.Score` without instrument `partId`sAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
cuthbertLab/music21#2074 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
cuthbertLab/music21#2055 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
Slur bezier-x/y from start element gets overwritten by stop element's valuesQuizá libre de nuevo @bingliscodes la tomó hace 10 días y no hay ningún pull request abierto. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
cuthbertLab/music21#2019 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
Todos los issues de cuthbertLab/music21
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
ok-oldking/ok-wuthering-waves#1785 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
healthchecks/healthchecks#1349 ·
-
deployment release-lag
Dificultad 1/5 Menos de una hora Aptitud para principiantes 68/100
nolte/kamerplanter#2374 ·
Los mantenedores suelen responder en 1 día
-
bug v1 v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
modelcontextprotocol/python-sdk#3725 ·
Los mantenedores suelen responder en 1 día
-
batchterms() drops queries without a similar() clause, misaligning results with inputsPosiblemente ocupada @MohammadHijjawi97 la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
Los mantenedores suelen responder en 1 día