`music21.midi.MidiEvent.getBytes()` confuses `SEQUENCER_SPECIFIC_META_EVENT` (0x7F) with `POLY_MODE_ON` (also 0x7F)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 55/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Ferma
- Stack tecnologico
- python
- Ambito
- audio-video-rtc
Direzione di ricerca
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.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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:
...
- Lingua principale
- Python
- Stelle
- 2.6k
- Fork
- 459
- Merge medio
- 1g 9h
- PR unite (30g)
- 38
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
-
`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 12 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
-
Keyboard braille: extractHeading passes a KeySignature where a TimeSignature is expected (isinstance tested on the container)Forse già presa @wolfgang-aura l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
cuthbertLab/music21#1986 · 1 commento ·
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 72/100
SwiftKickMobile/skai#84 ·
-
Lychee link check failedAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
jxxghp/MoviePilot#7070 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
flop-labs/technocore-chat#997 ·
I maintainer di solito rispondono entro 1 giorno
-
tunneld on Windows: Wi-Fi devices are not discovered because uvicorn runs on a ProactorEventLoopAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
doronz88/pymobiledevice3#2051 ·
I maintainer di solito rispondono entro 1 giorno