def test_copy_invalid_argument(): with raises(ValueError): Message('note_on').copy(zzzzzzzzzzzz=2) with raises(ValueError): # note_on doesn't take program. Message('note_on').copy(program=2)
def make_cc_message(channel, control): return Message.from_dict({ 'type': 'control_change', 'time': 0, 'control': control, 'value': 64, 'channel': channel })
def make_note_on_message(channel, note): return Message.from_dict({ 'type': 'note_on', 'time': 0, 'note': note, 'velocity': 60, 'channel': channel })
def test_relevant_msg(outputs): note_on_messages = [make_note_on_message(0, n) for n in [0, 64, 127]] note_on_messages.append(make_note_on_message(1, 72)) for m in note_on_messages: assert outputs.filter(m) cc_messages = [make_cc_message(0, 2)] for m in cc_messages: assert outputs.filter(m) pitchwheel_message = Message.from_dict({ 'type': 'pitchwheel', 'time': 0, 'channel': 0, 'pitch': 352 }) assert pitchwheel_message.type == 'pitchwheel' assert outputs.filter(pitchwheel_message)
def test_copy_can_have_same_type(): Message('start').copy(type='start')
def pan_background() -> Message: return Message('control_change', control=PAN_CONTROL, value=PAN_BACKGROUND)
def test_copy_cant_change_type(): with raises(ValueError): Message('start').copy(type='stop')
def test_msg_time_equality(): # Since 1.1.18 time is included in comparison. assert Message('clock', time=0) == Message('clock', time=0) assert Message('clock', time=0) != Message('clock', time=1)
def test_copy(): assert Message('start').copy(time=1) == Message('start', time=1)
def test_from_dict_default_values(): msg = Message('note_on', channel=0, note=0, time=0) data = {'type': 'note_on'} assert Message.from_dict(data) == msg
def test_dict_sysex_data(): msg = Message('sysex', data=(1, 2, 3)) data = msg.dict() assert data == {'type': 'sysex', 'data': [1, 2, 3], 'time': 0} assert isinstance(data['data'], list)
def test_encode_songpos(): assert 'F2 00 00' == Message('songpos', pos=MIN_SONGPOS).hex() assert 'F2 7F 7F' == Message('songpos', pos=MAX_SONGPOS).hex()
def pan_foreground() -> Message: return Message('control_change', control=PAN_CONTROL, value=PAN_FOREGROUND)
def test_encode_pitchwheel(): assert 'E0 00 00' == Message('pitchwheel', pitch=MIN_PITCHWHEEL).hex() assert 'E0 00 40' == Message('pitchwheel', pitch=0).hex() assert 'E0 7F 7F' == Message('pitchwheel', pitch=MAX_PITCHWHEEL).hex()
def test_decode_pitchwheel(): assert Message.from_hex('E0 00 00').pitch == MIN_PITCHWHEEL assert Message.from_hex('E0 00 40').pitch == 0 assert Message.from_hex('E0 7F 7F').pitch == MAX_PITCHWHEEL
def test_repr(): msg = Message('note_on', channel=1, note=2, time=3) msg_eval = eval(repr(msg)) assert msg == msg_eval
def test_set_type(): """Can't change the type of a message.""" with raises(AttributeError): Message('note_on').type = 'note_off'
def test_from_hex_sysex_data_type(): msg = Message.from_hex('F0 01 02 03 F7') assert isinstance(msg.data, SysexData)
def test_copy_handles_data_generator(): msg1 = Message('sysex') msg2 = msg1.copy(data=(i for i in range(3))) assert msg2.data == (0, 1, 2) assert isinstance(msg2.data, SysexData)
def vol_foreground() -> Message: return Message('control_change', control=VOL_CONTROL, value=VOL_FOREGROUND)
def test_compare_with_nonmessage(): with raises(TypeError): Message('clock') == 'not a message'
def test_sysex_data_accepts_different_types(): assert Message('sysex', data=(0, 1, 2)).data == (0, 1, 2) assert Message('sysex', data=[0, 1, 2]).data == (0, 1, 2) assert Message('sysex', data=range(3)).data == (0, 1, 2) assert Message('sysex', data=bytearray([0, 1, 2])).data == (0, 1, 2) assert Message('sysex', data=b'\x00\x01\x02').data == (0, 1, 2)
def test_decode_songpos(): assert Message.from_hex('F2 00 00').pos == MIN_SONGPOS assert Message.from_hex('F2 7F 7F').pos == MAX_SONGPOS
def open_inst(index, is_out): names = backend.get_output_names() if is_out else backend.get_input_names() name = names[index] print("opening", '[out]' if is_out else ' [in]', name) if is_out: return backend.open_output(name) else: return backend.open_input(name) vo = open_inst(0, is_out=True) with open_inst(1, is_out=False) as vi: for note_in in vi: print('[input]', vi, note_in) if note_in.type in ['note_on', 'note_off']: octave = int(note_in.note / 12) key = note_in.note % 12 # print(type(octave * 12 + dorian[key]), type(dorian[key]), type(octave), "yo") note_out = Message( note_in.type, note=octave * 12 + dorian[key], velocity=note_in.velocity, time=note_in.time, channel=10) # this is Ableton's channel # minus 1 vo.send(note_out) else: vo.send(note_in)
def test_sysex_data_is_sysexdata_object(): assert isinstance(Message.from_hex('F0 00 F7').data, SysexData)
def vol_background() -> Message: return Message('control_change', control=VOL_CONTROL, value=VOL_BACKGROUND)