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_handle_any_whitespace(tmpdir):
path = tmpdir.join("test.syx").strpath
with open(path, 'wt') as outfile:
outfile.write('F0 01 02 \t F7\n F0 03 04 F7\n')
assert read_syx_file(path) == [Message('sysex', data=[1, 2]),
Message('sysex', data=[3, 4])]
def test_pitchwheel():
"""Check if pitchwheel type check and encoding is working."""
msg = Message('pitchwheel', pitch=MIN_PITCHWHEEL)
bytes = msg.bytes()
assert bytes[1] == bytes[2]
msg = Message('pitchwheel', pitch=MAX_PITCHWHEEL)
bytes = msg.bytes()
assert bytes[1] == bytes[2] == 127
def test_decode_sysex():
assert Message.from_str('sysex data=(1,2,3)').data == (1, 2, 3)
def test_track_repr():
track = MidiTrack([
Message('note_on', channel=1, note=2, time=3),
Message('note_off', channel=1, note=2, time=3),
])
track_eval = eval(repr(track))
for m1, m2 in zip(track, track_eval):
assert m1 == m2
def build_message(spec, bytes):
"""Build message from bytes.
This is used by Parser and MidiFile. bytes is a full list
of bytes for the message including the status byte. For sysex
messages, the end byte is not included. Examples:
build_message(spec, [0x80, 20, 100])
build_message(spec, [0xf0, 1, 2, 3])
No type or value checking is done, so you need to do that before you
call this function. 0xf7 is not allowed as status byte.
"""
message = Message.__new__(Message)
attrs = message.__dict__
message.__dict__.update({
'type': spec.type,
'_spec': spec,
'time': 0,
})
# This could be written in a more general way, but most messages
# are note_on or note_off so doing it this way is faster.
if spec.type in ['note_on', 'note_off']:
message.__dict__.update({
'channel': bytes[0] & 0x0f,
'note': bytes[1],
'velocity': bytes[2],
})
return message
def freeze_message(msg):
"""Freeze message.
Returns a frozen version of the message. Frozen messages are
immutable, hashable and can be used as dictionary keys.
Will return None if called with None. This allows you to do things
like::
msg = freeze_message(port.poll())
"""
if isinstance(msg, Frozen):
# Already frozen.
return msg
elif isinstance(msg, Message):
class_ = FrozenMessage
elif isinstance(msg, UnknownMetaMessage):
class_ = FrozenUnknownMetaMessage
elif isinstance(msg, MetaMessage):
class_ = FrozenMetaMessage
elif msg is None:
return None
else:
raise ValueError('first argument must be a message or None')
frozen = class_.__new__(class_)
vars(frozen).update(vars(msg))
return frozen
def reset_messages():
"""Yield "All Notes Off" and "Reset All Controllers" for all channels"""
ALL_NOTES_OFF = 123
RESET_ALL_CONTROLLERS = 121
for channel in range(16):
for control in [ALL_NOTES_OFF, RESET_ALL_CONTROLLERS]:
yield Message('control_change', channel=channel, control=control)
def panic_messages():
"""Yield "All Sounds Off" for all channels.
This will mute all sounding notes regardless of
envelopes. Useful when notes are hanging and nothing else
helps.
"""
ALL_SOUNDS_OFF = 120
for channel in range(16):
yield Message('control_change',
channel=channel, control=ALL_SOUNDS_OFF)
self.notes.append(message.note)
elif message.type == 'note_off':
if message.note in self.notes:
self.notes.remove(message.note)
# Select a new note to play.
if self.notes:
note = self.select(self.notes)
else:
note = None
if note == self.current_note:
return # Same note as before, no change.
if self.current_note is not None:
off = Message('note_off',
note=self.current_note,
velocity=message.velocity)
send(off)
self.current_note = None
if note is not None:
on = Message('note_on',
note=note,
velocity=message.velocity)
send(on)
self.current_note = note