python 收到来自 Max 的 OSC 消息
python receive OSC message from Max
我是一个相当有经验的 python 用户,但我没有使用 OSC 协议、MAX 和 SuperCollider 的经验。
我正在帮助一个朋友构建一个 python 代码,它应该执行以下操作:
- 通过 OSC 接收来自 MAX 的消息
- 详细说明 python
中的消息
- 将详细消息发送到 SuperCollider
我不清楚的是关于1点和3点。
第 0 部分
我导入以下库
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
第 1 部分
我试图为第 1 点设置一个简单的服务器,因为我一次只从 MAX 接收一个字符串:
def listen2Max(ip,port):
'''
set up server
'''
# dispatcher to receive message
dispatcher = dispatcher.Dispatcher()
dispatcher.map("/filter", print)
# server to listen
server = osc_server.ThreadingOSCUDPServer((ip,port), dispatcher)
print("Serving on {}".format(server.server_address))
server.serve_forever()
但我不知道在这个函数中 return
是什么,我也不知道在 map
中使用 "/filter"
。它是必须在 MAX 中指定的东西吗?
第 2 部分
这实际上是我的强项:我获取 listen2Max 函数返回的字符串消息,执行一些 py 操作并准备一条名为 mymove
的消息发送到 SuperCollider
第 3 部分
对于第 3 点,我设置了一个简单的客户端来将字符串 var mymove
传递给 SuperCollider
def talk2SC(ip,port,mymove):
'''
set up client
'''
client = udp_client.SimpleUDPClient(ip,port)
client.send_message("/filter", mymove)
它应该那样工作吗?
这是完成(至少部分)工作的代码。
请记住,在这种情况下,Max 将字符串发送到 python。我收到的消息是这样的:O-O e8g8 8 1
import argparse
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
def main(path: str, *osc_arguments):
msg = osc_arguments[-1]
print("input message: {}".format(msg))
msgOUT = msg+'whatever'
# output
print("output message: {}".format(msgOUT))
ipOUT = osc_arguments[0][0]
portOUT = osc_arguments[0][1]
pathOUT= osc_arguments[0][2]
talk2SC(ipOUT,portOUT,pathOUT,msgOUT)
def listen2Max(addrIN,addrOUT):
'''
set up server
'''
# input address
ipIN = addrIN[0]
portIN = addrIN[1]
pathIN = addrIN[2]
# output address
portOUT = addrOUT[0]
pathOUT = addrOUT[1]
# dispatcher to receive message
disp = dispatcher.Dispatcher()
disp.map(pathIN, main, ipIN, portOUT, pathOUT)
# server to listen
server = osc_server.ThreadingOSCUDPServer((ipIN,portIN), disp)
print("Serving on {}".format(server.server_address))
server.serve_forever()
def talk2SC(ip,port,path,mymove):
'''
set up client
'''
client = udp_client.SimpleUDPClient(ip,port)
client.send_message(path, mymove)
if __name__ == "__main__":
# generate parser
parser = argparse.ArgumentParser(prog='scacchiOSC', formatter_class=argparse.RawDescriptionHelpFormatter, description='Interprete di messaggi OSC da Max\n')
parser.add_argument("-II","--ipIN", type=str, default="127.0.0.1", help="The ip to listen on")
parser.add_argument("-PI", "--portIN", type=int, default=5005, help="The port to listen on")
parser.add_argument("-UI", "--uripathIN", type=str, default="/filter", help="MAX's URI path")
parser.add_argument("-PO", "--portOUT", type=int, default=5006, help="The port to send messages to")
parser.add_argument("-UO", "--uripathOUT", type=str, default="/filter", help="output URI path")
args = parser.parse_args()
# wrap up inputs
outputAddress = [args.portOUT, args.uripathOUT]
inputAddress = [args.ipIN, args.portIN, args.uripathIN]
# listen to max
listen2Max(inputAddress, outputAddress)
此代码从这样的客户端获取消息:
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
from typing import List, Any
def talk2SC(ip,port,path):
'''
set up client
'''
# maxmsg = 'Nxe6 f4e6'
maxmsg = 'e4 e2e4'
client = udp_client.SimpleUDPClient(ip,port)
client.send_message(path, maxmsg)
if __name__ == '__main__':
talk2SC("127.0.0.1",5005,"/filter")
并像这样将消息发送到服务器:
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
from typing import List, Any
def main(address: str, *osc_arguments):
'''
prende il messaggio di MAX e lo traduce aggiornando la scacchiera
'''
# read message
msg = osc_arguments[0]
# initialize board
print(osc_arguments)
# outputc
def listen2Max(ip,port,path):
'''
set up server
'''
# dispatcher to receive message
disp = dispatcher.Dispatcher()
handler = disp.map(path, main)
# print(handler)
# server to listen
server = osc_server.ThreadingOSCUDPServer((ip,port), disp)
print("Serving on {}".format(server.server_address))
server.serve_forever()
if __name__ == '__main__':
listen2Max("127.0.0.1",5006,"/chmove")
棘手的部分是让它与 Max 通信。幸运的是我找到了答案 here:
- 将每个 Max 消息格式化为
/path "O-O e8g8 8 1"
- 使python监听指定的
/path
如果想要 python 监听每一个路径,可以更改解析器项中的默认路径并使用 "*"
作为默认路径。那么
- Max 的消息可以有任何路径
- 在解析器中会有
parser.add_argument("-UI", "--uripathIN", type=str, default="*", help="MAX's URI path")
现在,我只需要修复 SuperCollider 部分。
我是一个相当有经验的 python 用户,但我没有使用 OSC 协议、MAX 和 SuperCollider 的经验。
我正在帮助一个朋友构建一个 python 代码,它应该执行以下操作:
- 通过 OSC 接收来自 MAX 的消息
- 详细说明 python 中的消息
- 将详细消息发送到 SuperCollider
我不清楚的是关于1点和3点。
第 0 部分
我导入以下库
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
第 1 部分
我试图为第 1 点设置一个简单的服务器,因为我一次只从 MAX 接收一个字符串:
def listen2Max(ip,port):
'''
set up server
'''
# dispatcher to receive message
dispatcher = dispatcher.Dispatcher()
dispatcher.map("/filter", print)
# server to listen
server = osc_server.ThreadingOSCUDPServer((ip,port), dispatcher)
print("Serving on {}".format(server.server_address))
server.serve_forever()
但我不知道在这个函数中 return
是什么,我也不知道在 map
中使用 "/filter"
。它是必须在 MAX 中指定的东西吗?
第 2 部分
这实际上是我的强项:我获取 listen2Max 函数返回的字符串消息,执行一些 py 操作并准备一条名为 mymove
的消息发送到 SuperCollider
第 3 部分
对于第 3 点,我设置了一个简单的客户端来将字符串 var mymove
传递给 SuperCollider
def talk2SC(ip,port,mymove):
'''
set up client
'''
client = udp_client.SimpleUDPClient(ip,port)
client.send_message("/filter", mymove)
它应该那样工作吗?
这是完成(至少部分)工作的代码。
请记住,在这种情况下,Max 将字符串发送到 python。我收到的消息是这样的:O-O e8g8 8 1
import argparse
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
def main(path: str, *osc_arguments):
msg = osc_arguments[-1]
print("input message: {}".format(msg))
msgOUT = msg+'whatever'
# output
print("output message: {}".format(msgOUT))
ipOUT = osc_arguments[0][0]
portOUT = osc_arguments[0][1]
pathOUT= osc_arguments[0][2]
talk2SC(ipOUT,portOUT,pathOUT,msgOUT)
def listen2Max(addrIN,addrOUT):
'''
set up server
'''
# input address
ipIN = addrIN[0]
portIN = addrIN[1]
pathIN = addrIN[2]
# output address
portOUT = addrOUT[0]
pathOUT = addrOUT[1]
# dispatcher to receive message
disp = dispatcher.Dispatcher()
disp.map(pathIN, main, ipIN, portOUT, pathOUT)
# server to listen
server = osc_server.ThreadingOSCUDPServer((ipIN,portIN), disp)
print("Serving on {}".format(server.server_address))
server.serve_forever()
def talk2SC(ip,port,path,mymove):
'''
set up client
'''
client = udp_client.SimpleUDPClient(ip,port)
client.send_message(path, mymove)
if __name__ == "__main__":
# generate parser
parser = argparse.ArgumentParser(prog='scacchiOSC', formatter_class=argparse.RawDescriptionHelpFormatter, description='Interprete di messaggi OSC da Max\n')
parser.add_argument("-II","--ipIN", type=str, default="127.0.0.1", help="The ip to listen on")
parser.add_argument("-PI", "--portIN", type=int, default=5005, help="The port to listen on")
parser.add_argument("-UI", "--uripathIN", type=str, default="/filter", help="MAX's URI path")
parser.add_argument("-PO", "--portOUT", type=int, default=5006, help="The port to send messages to")
parser.add_argument("-UO", "--uripathOUT", type=str, default="/filter", help="output URI path")
args = parser.parse_args()
# wrap up inputs
outputAddress = [args.portOUT, args.uripathOUT]
inputAddress = [args.ipIN, args.portIN, args.uripathIN]
# listen to max
listen2Max(inputAddress, outputAddress)
此代码从这样的客户端获取消息:
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
from typing import List, Any
def talk2SC(ip,port,path):
'''
set up client
'''
# maxmsg = 'Nxe6 f4e6'
maxmsg = 'e4 e2e4'
client = udp_client.SimpleUDPClient(ip,port)
client.send_message(path, maxmsg)
if __name__ == '__main__':
talk2SC("127.0.0.1",5005,"/filter")
并像这样将消息发送到服务器:
from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client
from typing import List, Any
def main(address: str, *osc_arguments):
'''
prende il messaggio di MAX e lo traduce aggiornando la scacchiera
'''
# read message
msg = osc_arguments[0]
# initialize board
print(osc_arguments)
# outputc
def listen2Max(ip,port,path):
'''
set up server
'''
# dispatcher to receive message
disp = dispatcher.Dispatcher()
handler = disp.map(path, main)
# print(handler)
# server to listen
server = osc_server.ThreadingOSCUDPServer((ip,port), disp)
print("Serving on {}".format(server.server_address))
server.serve_forever()
if __name__ == '__main__':
listen2Max("127.0.0.1",5006,"/chmove")
棘手的部分是让它与 Max 通信。幸运的是我找到了答案 here:
- 将每个 Max 消息格式化为
/path "O-O e8g8 8 1"
- 使python监听指定的
/path
如果想要 python 监听每一个路径,可以更改解析器项中的默认路径并使用 "*"
作为默认路径。那么
- Max 的消息可以有任何路径
- 在解析器中会有
parser.add_argument("-UI", "--uripathIN", type=str, default="*", help="MAX's URI path")
现在,我只需要修复 SuperCollider 部分。