Skip to content

Commit c041f8a

Browse files
authored
Merge pull request #53 from adafruit/useful-repr
Give all MIDIMessage objects a useful repr()
2 parents 100b723 + f89b137 commit c041f8a

22 files changed

+60
-36
lines changed

adafruit_midi/channel_pressure.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ChannelPressure(MIDIMessage):
2828
:param int pressure: The pressure, 0-127.
2929
"""
3030

31+
_message_slots = ["pressure", "channel"]
3132
_STATUS = 0xD0
3233
_STATUSMASK = 0xF0
3334
LENGTH = 2

adafruit_midi/control_change.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class ControlChange(MIDIMessage):
3030
3131
"""
3232

33+
_message_slots = ["control", "value", "channel"]
3334
_STATUS = 0xB0
3435
_STATUSMASK = 0xF0
3536
LENGTH = 3

adafruit_midi/midi_continue.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
class Continue(MIDIMessage):
2626
"""Continue MIDI message."""
2727

28+
_message_slots = []
29+
2830
_STATUS = 0xFB
2931
_STATUSMASK = 0xFF
3032
LENGTH = 1

adafruit_midi/midi_message.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,20 @@ def from_bytes(cls, msg_bytes):
285285
representation of the MIDI message."""
286286
return cls()
287287

288+
def __str__(self):
289+
"""Print an instance"""
290+
cls = self.__class__
291+
if slots := getattr(cls, "_message_slots", None):
292+
# pylint: disable=not-an-iterable
293+
args = ", ".join(
294+
f"{name}={repr(getattr(self, name, None))}" for name in slots
295+
)
296+
else:
297+
args = "..."
298+
return f"{self.__class__.__name__}({args})"
299+
300+
__repr__ = __str__
301+
288302

289303
# DO NOT try to register these messages
290304
class MIDIUnknownEvent(MIDIMessage):
@@ -296,6 +310,7 @@ class MIDIUnknownEvent(MIDIMessage):
296310
or because it is not imported.
297311
"""
298312

313+
_message_slots = ["status"]
299314
LENGTH = -1
300315

301316
def __init__(self, status):
@@ -316,6 +331,8 @@ class MIDIBadEvent(MIDIMessage):
316331

317332
LENGTH = -1
318333

334+
_message_slots = ["msg_bytes", "exception"]
335+
319336
def __init__(self, msg_bytes, exception):
320337
self.data = bytes(msg_bytes)
321338
self.exception_text = repr(exception)

adafruit_midi/mtc_quarter_frame.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class MtcQuarterFrame(MIDIMessage):
4141
:param value: The quarter frame value for the specified type.
4242
"""
4343

44+
_message_slots = ["msgtype", "value"]
45+
4446
_STATUS = 0xF1
4547
_STATUSMASK = 0xFF
4648
LENGTH = 2

adafruit_midi/note_off.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class NoteOff(MIDIMessage): # pylint: disable=duplicate-code
3131
3232
"""
3333

34+
_message_slots = ["note", "velocity", "channel"]
3435
_STATUS = 0x80
3536
_STATUSMASK = 0xF0
3637
LENGTH = 3

adafruit_midi/note_on.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class NoteOn(MIDIMessage):
3131
to a Note Off, defaults to 127.
3232
"""
3333

34+
_message_slots = ["note", "velocity", "channel"]
35+
3436
_STATUS = 0x90
3537
_STATUSMASK = 0xF0
3638
LENGTH = 3

adafruit_midi/pitch_bend.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class PitchBend(MIDIMessage):
2929
bend from 0 through 8192 (midpoint, no bend) to 16383.
3030
"""
3131

32+
_message_slots = ["pitch_bend", "channel"]
3233
_STATUS = 0xE0
3334
_STATUSMASK = 0xF0
3435
LENGTH = 3

adafruit_midi/polyphonic_key_pressure.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class PolyphonicKeyPressure(MIDIMessage):
3030
:param int pressure: The pressure, 0-127.
3131
"""
3232

33+
_message_slots = ["note", "pressure", "channel"]
3334
_STATUS = 0xA0
3435
_STATUSMASK = 0xF0
3536
LENGTH = 3

adafruit_midi/program_change.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ProgramChange(MIDIMessage):
2828
:param int patch: The new program/patch number to use, 0-127.
2929
"""
3030

31+
_message_slots = ["patch", "channel"]
3132
_STATUS = 0xC0
3233
_STATUSMASK = 0xF0
3334
LENGTH = 2

adafruit_midi/start.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Start(MIDIMessage):
2828
_STATUS = 0xFA
2929
_STATUSMASK = 0xFF
3030
LENGTH = 1
31+
_message_slots = []
3132

3233

3334
Start.register_message_type()

adafruit_midi/stop.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Stop(MIDIMessage):
2828
_STATUS = 0xFC
2929
_STATUSMASK = 0xFF
3030
LENGTH = 1
31+
_message_slots = []
3132

3233

3334
Stop.register_message_type()

adafruit_midi/system_exclusive.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class SystemExclusive(MIDIMessage):
3232
This message can only be parsed if it fits within the input buffer in :class:MIDI.
3333
"""
3434

35+
_message_slots = ["manufacturer_id", "data"]
3536
_STATUS = 0xF0
3637
_STATUSMASK = 0xFF
3738
LENGTH = -1

adafruit_midi/timing_clock.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class TimingClock(MIDIMessage):
3434
_STATUS = 0xF8
3535
_STATUSMASK = 0xFF
3636
LENGTH = 1
37+
_slots = []
3738

3839

3940
TimingClock.register_message_type()

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
#
55
# SPDX-License-Identifier: MIT
66

7+
import datetime
78
import os
89
import sys
9-
import datetime
1010

1111
sys.path.insert(0, os.path.abspath(".."))
1212

examples/midi_inoutdemo.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@
44
# midi_inoutdemo - demonstrates receiving and sending MIDI events
55

66
import usb_midi
7-
import adafruit_midi
87

9-
# TimingClock is worth importing first if present as it
10-
# will make parsing more efficient for this high frequency event
11-
# Only importing what is used will save a little bit of memory
8+
import adafruit_midi
129

1310
# pylint: disable=unused-import
14-
from adafruit_midi.timing_clock import TimingClock
1511
from adafruit_midi.channel_pressure import ChannelPressure
1612
from adafruit_midi.control_change import ControlChange
13+
from adafruit_midi.midi_message import MIDIUnknownEvent
1714
from adafruit_midi.note_off import NoteOff
1815
from adafruit_midi.note_on import NoteOn
1916
from adafruit_midi.pitch_bend import PitchBend
@@ -22,8 +19,12 @@
2219
from adafruit_midi.start import Start
2320
from adafruit_midi.stop import Stop
2421
from adafruit_midi.system_exclusive import SystemExclusive
22+
from adafruit_midi.timing_clock import TimingClock
23+
24+
# TimingClock is worth importing first if present as it
25+
# will make parsing more efficient for this high frequency event
26+
# Only importing what is used will save a little bit of memory
2527

26-
from adafruit_midi.midi_message import MIDIUnknownEvent
2728

2829
midi = adafruit_midi.MIDI(
2930
midi_in=usb_midi.ports[0],

examples/midi_intest1.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,28 @@
22
# SPDX-License-Identifier: MIT
33

44
import time
5+
56
import usb_midi
7+
68
import adafruit_midi
79

8-
# A subset of messages/events
910
# pylint: disable=unused-import
10-
from adafruit_midi.timing_clock import TimingClock
11-
1211
# from adafruit_midi.channel_pressure import ChannelPressure
1312
from adafruit_midi.control_change import ControlChange
1413
from adafruit_midi.note_off import NoteOff
1514
from adafruit_midi.note_on import NoteOn
1615
from adafruit_midi.pitch_bend import PitchBend
17-
16+
from adafruit_midi.timing_clock import TimingClock
1817

1918
# 0 is MIDI channel 1
2019
midi = adafruit_midi.MIDI(midi_in=usb_midi.ports[0], in_channel=0)
2120

22-
print("Midi input test with pauses")
21+
print("Midi input test")
2322

2423
# Convert channel numbers at the presentation layer to the ones musicians use
2524
print("Input channel:", midi.in_channel + 1)
2625

27-
# play with the pause to simulate code doing other stuff
28-
# in the loop
29-
pauses = [0] * 10 + [0.010] * 10 + [0.100] * 10 + [1.0] * 10
30-
3126
while True:
32-
for pause in pauses:
33-
msg = midi.receive()
34-
if msg is not None:
35-
print(time.monotonic(), msg)
36-
if pause:
37-
time.sleep(pause)
27+
msg = midi.receive()
28+
if msg is not None:
29+
print(time.monotonic(), msg)

examples/midi_memorycheck.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
#
1111
# E: 8,21: Module 'gc' has no 'mem_free' member (no-member)
1212

13-
import time
14-
import random
1513
import gc
14+
import random
15+
import time
1616

1717
gc.collect()
1818
print(gc.mem_free())

examples/midi_simpletest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
22
# SPDX-License-Identifier: MIT
33
# simple_test
4-
import time
54
import random
5+
import time
6+
67
import usb_midi
8+
79
import adafruit_midi
810
from adafruit_midi.control_change import ControlChange
911
from adafruit_midi.note_off import NoteOff

tests/test_MIDIMessage_unittests.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
# pylint: disable=invalid-name
66

7-
import unittest
8-
9-
107
import os
8+
import unittest
119

1210
verbose = int(os.getenv("TESTVERBOSE", "2"))
1311

tests/test_MIDI_unittests.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
# pylint: disable=invalid-name
66

7+
import os
8+
import random
79
import unittest
810
from unittest.mock import Mock, call
911

10-
import random
11-
import os
12-
1312
verbose = int(os.getenv("TESTVERBOSE", "2"))
1413

1514
# pylint: disable=wrong-import-position
@@ -21,6 +20,9 @@
2120
# Borrowing the dhalbert/tannewt technique from adafruit/Adafruit_CircuitPython_Motor
2221
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
2322

23+
# Import after messages - opposite to other test file
24+
import adafruit_midi
25+
2426
# Full monty
2527
from adafruit_midi.channel_pressure import ChannelPressure
2628
from adafruit_midi.control_change import ControlChange
@@ -29,9 +31,6 @@
2931
from adafruit_midi.pitch_bend import PitchBend
3032
from adafruit_midi.system_exclusive import SystemExclusive
3133

32-
# Import after messages - opposite to other test file
33-
import adafruit_midi
34-
3534
# pylint: enable=wrong-import-position
3635

3736

tests/test_note_parser.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
#
33
# SPDX-License-Identifier: MIT
44

5-
import unittest
6-
75
import os
6+
import unittest
87

98
verbose = int(os.getenv("TESTVERBOSE", "2"))
109

0 commit comments

Comments
 (0)