Audio/AudioControl: Lots of fixes
[audiocontrol.git] / Looper.py
index 075e98b..1a31e0e 100644 (file)
--- a/Looper.py
+++ b/Looper.py
@@ -1,48 +1,72 @@
-import socket, struct
-import Actions, 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)
+import Actions, OSC, Events
+
+class Controller(object):
+
+    def __init__(self, context, oscserver, remote):
+        self._context = context
+        self._server = oscserver
+        self._remote = remote
+        self._server.registerHandler(self._remote, self._oscEvent)
+
+    def hit(self, command, index=0):
+        self._server.command(self._remote,"/sl/%d/hit" % index, str(command))
+
+    def get(self, parameter, index=0):
+        if parameter.startswith('global_'):
+            path = "/get"
+            parameter = parameter[7:]
         else:
-            raise RunstimeError, "Invalid OSC argument"
-    return osc_string(url) + osc_string(tag) + argstring
+            path = "/sl/%d/get" % index
+        self._server.command(self._remote, path, parameter, self._server.localUrl(), "")
 
-class OSCSender(object):
+    def set(self, parameter, value, index=0):
+        if parameter.startswith('global_'):
+            path = "/set"
+            parameter = parameter[7:]
+        else:
+            path = "/sl/%d/set" % index
+        self._server.command(self._remote, path, parameter, float(value))
 
-    def __init__(self, host, port):
-        self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-        self._target = (host,port)
+    def _oscEvent(self, path, data):
+        # data = (loop-number, parameter-name, value)
+        if len(data) != 3: return
+        if data[0]<0:
+            param = "global_%s" % data[1]
+        else:
+            param = "%s/%d" % (data[1], data[0])
+        return [ Events.ControlEvent(self._context, param, data[2]) ]
 
-    def command(self, path, *args):
-        if type(args[0]) in (tuple, list) : args = args[0]
-        Logger.log('osc','osc://%s:%s%s %s'
-                   % (self._target[0], self._target[1], path,
-                      ' '.join(map(repr,args))))
-        self._sock.sendto(osc_command(path, *args),self._target)
-        
+    class ParamGetter(object):
 
-class Controller(object) :
+        def __init__(self, controller, parameter, index=0):
+            self._parameter = parameter
+            self._controller = controller
+            self._index = index
 
-    def __init__(self, host, port):
-        self._sender = OSCSender(host,port)
+        def __call__(self):
+            self._controller.get(self._parameter, self._index)
 
-    def hit(self, command, index=0):
-        self._sender.command("/sl/%d/hit" % index, str(command))
+    class ParamSetter(object):
 
+        def __init__(self, controller, parameter, index=0):
+            self._parameter = parameter
+            self._controller = controller
+            self._index = index
 
+        def __call__(self, value):
+            self._controller.set(self._parameter, value, self._index)
+
+    def assignController( self, controller, title, parameter, min, max, stops=[], index=0 ):
+        if parameter.startswith('global_'):
+            event = parameter
+        else:
+            event = "%s/%d" % (parameter, index)
+        controller.assign(title,
+                          self.ParamSetter(self, parameter, index),
+                          self.ParamGetter(self, parameter, index),
+                          Events.Event(self._context, event),
+                          min, max, stops)
+                      
 class Command(Actions.Action):
 
     def __init__(self, name, controller, command):
@@ -52,3 +76,31 @@ class Command(Actions.Action):
 
     def __call__(self, binding):
         self._controller.hit(self._command)
+
+class AssignController(Actions.Action):
+
+    def __init__(self, name, loopController, pedalController, title, parameter, min, max,
+                 stops = [], index=0):
+        Actions.Action.__init__(self, name)
+        self._loopController = loopController
+        self._pedalController = pedalController
+        self._title = title
+        self._parameter = parameter
+        self._min = min
+        self._max = max
+        self._stops = stops
+        self._index = index
+
+    def __call__(self, binding):
+        self._loopController.assignController(self._pedalController,
+                                              self._title,
+                                              self._parameter,
+                                              self._min,
+                                              self._max,
+                                              self._stops,
+                                              self._index)
+
+def register( oscserver,
+              context,
+              remote ):
+    return Controller(context, oscserver, remote)