dev/osc/ OscToMidiExample1
Osc to Midi
This takes in osc messages on a specified port, and for those matching the signals my TourBoxToOsc script generates, outputs a midi cc with value 127 and the cc number based on which knob or button the event came from. The commented out code in the middle is there to facilitate creating the ableton.txt file by pressing each button in order.
#!/usr/bin/env python3
import sys, os
from rtmidi import MidiIn, MidiOut
from pythonosc.osc_message import OscMessage
from datetime import datetime
import socket
def get_ip():
# workaround since reaper doesn't receive packets if sent to localhost rather than 192.168.0.x
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0)
try:
# doesn't even have to be reachable
s.connect(('10.254.254.254', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return IP
def dump(*xs):
print(f"dump {xs}")
def main():
port = int(os.getenv("port",7001))
host = os.getenv("host","localhost")
if host == "localhost":
host = get_ip()
midiout = MidiOut()
ports = midiout.get_ports()
for i,x in enumerate(ports):
if "ableton_control_1" in x:
midiout.open_port(i)
print(f"Opened {i}: {x}")
break
else:
print(f"Didn't find Ableton port")
exit(1)
ableton = Ableton(midiout)
print(f"{host=} {port=}")
#i = 0
#d = set()
#m = []
with socket.socket(socket.AF_INET,socket.SOCK_DGRAM) as s:
s.bind((host,port))
while True:
#i += 1
#if i > 60:
# break
data = s.recv(256*1024)
now = datetime.now().strftime("%c")
l = len(data)
print(f"{now} : {l} bytes received")
message = OscMessage(data)
address = message.address
params = message.params
#if not address in d:
# d.add(address)
# m.append(address)
print(f"{address=} {params=}")
ableton(address,params)
print()
#with open("ableton.txt","wt") as f:
# f.write("\n".join(m))
def fmt(x):
'turn numbers into strings, and add "quotes" to strings'
if type(x) in (int,float):
return str(x)
elif type(x) is str:
if '"' in x and not "'" in x:
return f"'{x}'"
else:
x = x.replace('"',r'\"')
return f'"{x}"'
def dump(*xs):
print(xs)
return
n,*ys = xs
print(f"{n}: {', '.join(map(fmt,ys))}")
class Ableton:
def __init__(self,midiout):
self.midiout = midiout
with open("ableton.txt") as f:
a = f.read().rstrip().splitlines()
self.d = {}
for i,line in enumerate(a):
self.d[line] = i
def __call__(self,address,params):
print(f"{address}: {', '.join(map(fmt,params))}")
if address in self.d:
i = self.d[address]
a = [ 0xB0, i, 0x7F ]
print(f"Sending {i=} {a=}")
a = bytes(a)
self.midiout.send_message(a)
if __name__ == "__main__":
main()
ableton.txt
tour/knob/cw
tour/knob/ccw
tour/dial/cw
tour/dial/ccw
tour/vdial/cw
tour/vdial/ccw
tour/dpad/up
tour/dpad/down
tour/dpad/right
tour/dpad/left
tour/button/2a
tour/button/00
tour/button/03
tour/button/23
tour/button/22
tour/button/02
tour/button/01