Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_bad_key_sig_throws_key_signature_error(self, bad_key_sig):
with pytest.raises(KeySignatureError):
MetaSpec_key_signature().decode(MetaMessage('key_signature'),
bad_key_sig)
"""
mid = read_file(HEADER_ONE_TRACK + """
4d 54 72 6b # MTrk
00 00 00 17
00 ff 00 00 # sequence_number with no data bytes (should be 2).
00 ff 21 00 # midi_port with no data bytes (should be 1).
00 ff 00 02 00 01 # sequence_number with correct number of data bytes (2).
00 ff 21 01 01 # midi_port with correct number of data bytes (1).
00 ff 2f 00
""")
assert mid.tracks[0] == [
MetaMessage('sequence_number', number=0),
MetaMessage('midi_port', port=0),
MetaMessage('sequence_number', number=1),
MetaMessage('midi_port', port=1),
MetaMessage('end_of_track'),
]
def test_meta_messages():
# TODO: should this raise IOError?
mid = read_file(HEADER_ONE_TRACK + """
4d 54 72 6b # MTrk
00 00 00 0c # Chunk size
00 ff 03 04 54 65 73 74 # track_name name='Test'
00 ff 2f 00 # end_of_track
""")
track = mid.tracks[0]
assert track[0] == MetaMessage('track_name', name='Test')
assert track[1] == MetaMessage('end_of_track')
def test_midifile_repr():
midifile = MidiFile(type=1, ticks_per_beat=123, tracks=[
MidiTrack([
Message('note_on', channel=1, note=2, time=3),
Message('note_off', channel=1, note=2, time=3)]),
MidiTrack([
MetaMessage('sequence_number', number=5),
Message('note_on', channel=2, note=6, time=9),
Message('note_off', channel=2, note=6, time=9)]),
])
midifile_eval = eval(repr(midifile))
for track, track_eval in zip(midifile.tracks, midifile_eval.tracks):
for m1, m2 in zip(track, track_eval):
assert m1 == m2
def test_meta_message_repr():
msg = MetaMessage('end_of_track', time=10)
msg_eval = eval(repr(msg))
assert msg == msg_eval
def print_tracks(self, meta_only=False):
"""Prints out all messages in a .midi file.
May take argument meta_only to show only meta messages.
Use:
print_tracks() -> will print all messages
print_tracks(meta_only=True) -> will print only MetaMessages
"""
for i, track in enumerate(self.tracks):
print('=== Track {}'.format(i))
for msg in track:
if not isinstance(msg, MetaMessage) and meta_only:
pass
else:
print('{!r}'.format(msg))
def build_meta_message(meta_type, data, delta=0):
# TODO: handle unknown type.
try:
spec = _META_SPECS[meta_type]
except KeyError:
return UnknownMetaMessage(meta_type, data)
else:
msg = MetaMessage(spec.type, time=delta)
# This adds attributes to msg:
spec.decode(msg, data)
return msg
__setattr__ = _setattr
def bytes(self):
spec = _META_SPEC_BY_TYPE[self.type]
data = spec.encode(self)
return ([0xff, spec.type_byte] + encode_variable_int(len(data)) + data)
def _get_value_names(self):
"""Used by BaseMessage.__repr__()."""
spec = _META_SPEC_BY_TYPE[self.type]
return spec.attributes + ['time']
class UnknownMetaMessage(MetaMessage):
def __init__(self, type_byte, data=None, time=0):
if data is None:
data = ()
else:
data = tuple(data)
vars(self).update({
'type': 'unknown_meta',
'type_byte': type_byte,
'data': data,
'time': time})
def __repr__(self):
fmt = 'UnknownMetaMessage(type_byte={}, data={}, time={})'
return fmt.format( self.type_byte, self.data, self.time)
attribute is set to the number of seconds slept since the
previous message.
By default you will only get normal MIDI messages. Pass
meta_messages=True if you also want meta messages.
You will receive copies of the original messages, so you can
safely modify them without ruining the tracks.
"""
sleep = time.sleep
for msg in self:
sleep(msg.time)
if isinstance(msg, MetaMessage) and not meta_messages:
continue
else:
yield msg
return ([0xff, self._spec.type_byte]
+ encode_variable_int(len(data))
+ data)
def __repr__(self):
attributes = []
for name in self._spec.attributes:
attributes.append('{}={!r}'.format(name, getattr(self, name)))
attributes = ' '.join(attributes)
if attributes:
attributes = (' {}'.format(attributes))
return ''.format(self.type,
attributes, self.time)
class UnknownMetaMessage(MetaMessage):
def __init__(self, type_byte, data=None, time=0):
if data is None:
data = []
self.type = 'unknown_meta'
self._type_byte = type_byte
self._data = data
self.time = time
def __repr__(self):
return ('').format(
self._type_byte,
self._data,
self.time)