Skip to content

Commit c18e3b2

Browse files
committed
changed line termination
1 parent 02d3566 commit c18e3b2

1 file changed

Lines changed: 143 additions & 143 deletions

File tree

examples/seq-midi-loop8.py

Lines changed: 143 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,143 @@
1-
#!/usr/bin/env python3
2-
3-
"""
4-
This code provides functions for handling MIDI input and output.
5-
6-
It will loop over the last 8 notes received, tempo synced.
7-
8-
Functions:
9-
- handle_inport: Reads MIDI messages from the input port and places them in a queue.
10-
- handle_outport: Retrieves MIDI messages from a queue and sends them to the output port.
11-
- handle_clock: Handles clock messages and compute the current quarter note time.
12-
13-
"""
14-
15-
import mido
16-
import time
17-
import threading
18-
import queue
19-
from collections import deque
20-
21-
# Initialize a deque with a maximum length of 8
22-
msg_deque = deque(maxlen=8)
23-
24-
# MIDI Clock handling defaults
25-
clock_bpm = 125
26-
clock_id = 0
27-
clock_s = 0.02
28-
last_time = None
29-
30-
# MIDI I/O
31-
inport = mido.open_input('MIDI In')
32-
outport = mido.open_output('MIDI Out')
33-
34-
def handle_inport(inport, msg_deque, clock_queue):
35-
"""
36-
Reads MIDI messages from the input port and places them in the queue.
37-
38-
Args:
39-
inport (mido.ports.BaseInput): The input port to read messages from.
40-
msg_queue (queue.Queue): The queue to put received messages in.
41-
42-
Returns:
43-
None
44-
"""
45-
last_time = None
46-
while True:
47-
for msg in inport.iter_pending():
48-
if msg.type == "note_on":
49-
print("Received:", msg, msg.type)
50-
msg_deque.append(msg) # Append the message to the deque
51-
print("Deque:", list(msg_deque))
52-
if msg.type == "clock" or msg.type == "start" or msg.type == "stop":
53-
handle_clock(msg, clock_queue)
54-
55-
def handle_outport(outport, msg_deque, clock_queue):
56-
"""
57-
Continuously tries to retrieve messages from the msg_queue.
58-
Sends the retrieved messages to the outport.
59-
60-
Args:
61-
outport (mido.ports.BaseInput): The output port to write messages to.
62-
msg_queue (queue.Queue): The queue to get received messages in.
63-
64-
Returns:
65-
None
66-
"""
67-
global clock_s, clock_bpm
68-
69-
seq = 0
70-
while True:
71-
try:
72-
msg = clock_queue.get(timeout=1) # Get a clock message from the queue with a timeout
73-
# wait for a quarter note. 24 clocks per beat
74-
if msg % (24/4) == 0:
75-
l = len(msg_deque)
76-
# if the queue is not empty start to iterate
77-
if l > 0:
78-
note_num = (1+seq) % l
79-
note_on = msg_deque[note_num]
80-
print("Sending:", note_num, note_on)
81-
outport.send(note_on) # Send the note on to the outport
82-
time.sleep(clock_s/4) # Wait a little
83-
# build the note off message
84-
note_off = mido.Message('note_off', note=note_on.note, velocity=0, channel=note_on.channel)
85-
outport.send(note_off) # Send the message to the outport
86-
seq = seq + 1
87-
clock_queue.task_done() # Mark the task as done
88-
except queue.Empty:
89-
continue # Continue if the queue is empty
90-
91-
def handle_clock(msg, clock_queue):
92-
"""
93-
The handle_clock function is designed to handle MIDI clock messages by:
94-
95-
Incrementing a global clock message counter (clock_id).
96-
Calculating the time interval between consecutive clock messages.
97-
Smoothing these intervals using an exponential moving average.
98-
Printing the smoothed interval every 24 clock messages (equivalent to one quarter note).
99-
Sending a message in the clock_queue so that handle_outport can send synchronized notes
100-
"""
101-
global clock_id, clock_bpm, clock_s, last_time, outport
102-
103-
# copy the clock messages to outport
104-
outport.send(msg)
105-
# handle clock
106-
if msg.type == "clock":
107-
current_time = time.time()
108-
clock_id += 1
109-
if last_time is not None:
110-
interval = 24 * (current_time - last_time)
111-
clock_s = 0.05*interval + 0.95*clock_s
112-
clock_queue.put(clock_id)
113-
if clock_id % 24 == 0:
114-
print(f"Interval: {clock_s:.6f} seconds")
115-
last_time = current_time
116-
117-
def main():
118-
global inport, outport
119-
120-
clock_queue = queue.Queue()
121-
122-
# Thread to handle input and put messages in the queue
123-
inport_thread = threading.Thread(target=handle_inport, args=(inport, msg_deque, clock_queue))
124-
inport_thread.daemon = True
125-
126-
# Thread to handle output and get messages from the queue
127-
outport_thread = threading.Thread(target=handle_outport, args=(outport, msg_deque, clock_queue))
128-
outport_thread.daemon = True
129-
130-
# Start the threads
131-
inport_thread.start()
132-
outport_thread.start()
133-
134-
# Keep the main thread running to prevent the program from exiting
135-
print("Ready...")
136-
try:
137-
while True:
138-
time.sleep(1)
139-
except KeyboardInterrupt:
140-
print("Exiting...")
141-
142-
if __name__ == "__main__":
143-
main()
1+
#!/usr/bin/env python3
2+
3+
"""
4+
This code provides functions for handling MIDI input and output.
5+
6+
It will loop over the last 8 notes received, tempo synced.
7+
8+
Functions:
9+
- handle_inport: Reads MIDI messages from the input port and places them in a queue.
10+
- handle_outport: Retrieves MIDI messages from a queue and sends them to the output port.
11+
- handle_clock: Handles clock messages and compute the current quarter note time.
12+
13+
"""
14+
15+
import mido
16+
import time
17+
import threading
18+
import queue
19+
from collections import deque
20+
21+
# Initialize a deque with a maximum length of 8
22+
msg_deque = deque(maxlen=8)
23+
24+
# MIDI Clock handling defaults
25+
clock_bpm = 125
26+
clock_id = 0
27+
clock_s = 0.02
28+
last_time = None
29+
30+
# MIDI I/O
31+
inport = mido.open_input('MIDI In')
32+
outport = mido.open_output('MIDI Out')
33+
34+
def handle_inport(inport, msg_deque, clock_queue):
35+
"""
36+
Reads MIDI messages from the input port and places them in the queue.
37+
38+
Args:
39+
inport (mido.ports.BaseInput): The input port to read messages from.
40+
msg_queue (queue.Queue): The queue to put received messages in.
41+
42+
Returns:
43+
None
44+
"""
45+
last_time = None
46+
while True:
47+
for msg in inport.iter_pending():
48+
if msg.type == "note_on":
49+
print("Received:", msg, msg.type)
50+
msg_deque.append(msg) # Append the message to the deque
51+
print("Deque:", list(msg_deque))
52+
if msg.type == "clock" or msg.type == "start" or msg.type == "stop":
53+
handle_clock(msg, clock_queue)
54+
55+
def handle_outport(outport, msg_deque, clock_queue):
56+
"""
57+
Continuously tries to retrieve messages from the msg_queue.
58+
Sends the retrieved messages to the outport.
59+
60+
Args:
61+
outport (mido.ports.BaseInput): The output port to write messages to.
62+
msg_queue (queue.Queue): The queue to get received messages in.
63+
64+
Returns:
65+
None
66+
"""
67+
global clock_s, clock_bpm
68+
69+
seq = 0
70+
while True:
71+
try:
72+
msg = clock_queue.get(timeout=1) # Get a clock message from the queue with a timeout
73+
# wait for a quarter note. 24 clocks per beat
74+
if msg % (24/4) == 0:
75+
l = len(msg_deque)
76+
# if the queue is not empty start to iterate
77+
if l > 0:
78+
note_num = (1+seq) % l
79+
note_on = msg_deque[note_num]
80+
print("Sending:", note_num, note_on)
81+
outport.send(note_on) # Send the note on to the outport
82+
time.sleep(clock_s/8) # Wait a little
83+
# build the note off message
84+
note_off = mido.Message('note_off', note=note_on.note, velocity=0, channel=note_on.channel)
85+
outport.send(note_off) # Send the message to the outport
86+
seq = seq + 1
87+
clock_queue.task_done() # Mark the task as done
88+
except queue.Empty:
89+
continue # Continue if the queue is empty
90+
91+
def handle_clock(msg, clock_queue):
92+
"""
93+
The handle_clock function is designed to handle MIDI clock messages by:
94+
95+
Incrementing a global clock message counter (clock_id).
96+
Calculating the time interval between consecutive clock messages.
97+
Smoothing these intervals using an exponential moving average.
98+
Printing the smoothed interval every 24 clock messages (equivalent to one quarter note).
99+
Sending a message in the clock_queue so that handle_outport can send synchronized notes
100+
"""
101+
global clock_id, clock_bpm, clock_s, last_time, outport
102+
103+
# copy the clock messages to outport
104+
outport.send(msg)
105+
# handle clock
106+
if msg.type == "clock":
107+
current_time = time.time()
108+
clock_id += 1
109+
if last_time is not None:
110+
interval = 24 * (current_time - last_time)
111+
clock_s = 0.05*interval + 0.95*clock_s
112+
clock_queue.put(clock_id)
113+
if clock_id % 24 == 0:
114+
print(f"Interval: {clock_s:.6f} seconds")
115+
last_time = current_time
116+
117+
def main():
118+
global inport, outport
119+
120+
clock_queue = queue.Queue()
121+
122+
# Thread to handle input and put messages in the queue
123+
inport_thread = threading.Thread(target=handle_inport, args=(inport, msg_deque, clock_queue))
124+
inport_thread.daemon = True
125+
126+
# Thread to handle output and get messages from the queue
127+
outport_thread = threading.Thread(target=handle_outport, args=(outport, msg_deque, clock_queue))
128+
outport_thread.daemon = True
129+
130+
# Start the threads
131+
inport_thread.start()
132+
outport_thread.start()
133+
134+
# Keep the main thread running to prevent the program from exiting
135+
print("Ready...")
136+
try:
137+
while True:
138+
time.sleep(1)
139+
except KeyboardInterrupt:
140+
print("Exiting...")
141+
142+
if __name__ == "__main__":
143+
main()

0 commit comments

Comments
 (0)