X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=OSC.py;fp=OSC.py;h=e248b474b138e76460428bfb9a5ff249e175d94e;hb=811a95d9a6a797149cdfc6a8ad9c6b2a779a87bc;hp=0000000000000000000000000000000000000000;hpb=8aab1c96c67b95d25fb175495894c38f82143cc9;p=audiocontrol.git diff --git a/OSC.py b/OSC.py new file mode 100644 index 0000000..e248b47 --- /dev/null +++ b/OSC.py @@ -0,0 +1,88 @@ +import socket, struct +import Events, Logger + +def osc_string(s) : + n = (len(s)+1)%4 + if n : return s+'\0'*(5-n) + else : return s+'\0' + + +def osc_command(url,*args): + tag="," + argstring="" + for arg in args : + if type(arg) is int: + tag += 'i' + argstring += struct.pack(">I",arg) + elif type(arg) is str: + tag += 's' + argstring += osc_string(arg) + elif type(arg) is float: + tag += 'f' + argstring += struct.pack(">f",arg) + else: + raise RunstimeError, "Invalid OSC argument" + return osc_string(url) + osc_string(tag) + argstring + + +def osc_getstr(data): + i = data.index('\0') + s = data[:i] + n = (i+1)%4 + if n : data = data[i+(5-n):] + else : data = data[i+1:] + return (s,data) + + +def osc_parse(data): + url,data = osc_getstr(data) + tag,data = osc_getstr(data) + values = [] + for code in tag[1:]: + if code == 'i': + values.append(struct.unpack(">i",data[:4])[0]) + data = data[4:] + elif code == 's': + v,data = osc_getstr(data) + values.append(v) + elif code == 'f': + values.append(struct.unpack(">f",data[:4])[0]) + data = data[4:] + else: + raise RuntimeError, "Unknown OSC parameter type received" + return (url, values) + + +class OSCServer(Events.EventSource): + + def __init__(self, addr, context): + Events.EventSource.__init__(self, + socket.socket(socket.AF_INET, socket.SOCK_DGRAM), + context) + self._addr = addr + self.fd().bind(addr) + self._handlers = {} + + def registerHandler(self, addr, cb): + self._handlers[addr] = cb + + def command(self, target, path, *args): + if args and type(args[0]) in (tuple, list) : args = args[0] + Logger.log('osc','osc://%s:%s%s %s' + % (target[0], target[1], path, + ' '.join(map(repr,args)))) + self.fd().sendto(osc_command(path, *args),target) + + def readEvents(self): + data, addr = self.fd().recvfrom(1024) + path, args = osc_parse(data) + Logger.log('oscrcv','osc://%s:%s%s %s' % (addr[0], addr[1], path, + ' '.join(map(repr,args)))) + handler = self._handlers.get(addr) + if handler: + return handler(path, args) + else: + return [] + + def localUrl(self): + return 'osc://%s:%s' % self._addr