summaryrefslogtreecommitdiffstats
path: root/src/clients/python
diff options
context:
space:
mode:
Diffstat (limited to 'src/clients/python')
-rw-r--r--src/clients/python/Makefile.am4
-rwxr-xr-xsrc/clients/python/OSC.py374
-rw-r--r--src/clients/python/omecho.py40
-rw-r--r--src/clients/python/omsynth.py635
-rw-r--r--src/clients/python/scripts/Makefile.am2
-rwxr-xr-xsrc/clients/python/scripts/flatten.py232
-rw-r--r--src/clients/python/scripts/sillysinepatch.py41
7 files changed, 0 insertions, 1328 deletions
diff --git a/src/clients/python/Makefile.am b/src/clients/python/Makefile.am
deleted file mode 100644
index 017b1f4b..00000000
--- a/src/clients/python/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-SUBDIRS = scripts
-
-EXTRA_DIST = omecho.py omsynth.py OSC.py
-
diff --git a/src/clients/python/OSC.py b/src/clients/python/OSC.py
deleted file mode 100755
index 74eb5880..00000000
--- a/src/clients/python/OSC.py
+++ /dev/null
@@ -1,374 +0,0 @@
-#!/usr/bin/python
-#
-# Open SoundControl for Python
-# Copyright (C) 2002 Daniel Holth, Clinton McChesney
-# Modified by Leonard Ritter
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# For questions regarding this module contact
-# Daniel Holth <dholth@stetson.edu> or visit
-# http://www.stetson.edu/~ProctoLogic/
-
-import socket
-import struct
-import math
-import sys
-import string
-
-
-def hexDump(bytes):
- """Useful utility; prints the string in hexadecimal"""
- for i in range(len(bytes)):
- sys.stdout.write("%2x " % (ord(bytes[i])))
- if (i+1) % 8 == 0:
- print repr(bytes[i-7:i+1])
-
- if(len(bytes) % 8 != 0):
- print string.rjust("", 11), repr(bytes[i-7:i+1])
-
-
-class OSCMessage:
- """Builds typetagged OSC messages."""
- def __init__(self):
- self.address = ""
- self.typetags = ","
- self.message = ""
-
- def setAddress(self, address):
- self.address = address
-
- def setMessage(self, message):
- self.message = message
-
- def setTypetags(self, typetags):
- self.typetags = typetags
-
- def clear(self):
- self.address = ""
- self.clearData()
-
- def clearData(self):
- self.typetags = ","
- self.message = ""
-
- def append(self, argument, typehint = None):
- """Appends data to the message,
- updating the typetags based on
- the argument's type.
- If the argument is a blob (counted string)
- pass in 'b' as typehint."""
-
- if typehint == 'b':
- binary = OSCBlob(argument)
- else:
- binary = OSCArgument(argument)
-
- self.typetags = self.typetags + binary[0]
- self.rawAppend(binary[1])
-
- def rawAppend(self, data):
- """Appends raw data to the message. Use append()."""
- self.message = self.message + data
-
- def getBinary(self):
- """Returns the binary message (so far) with typetags."""
- address = OSCArgument(self.address)[1]
- typetags = OSCArgument(self.typetags)[1]
- return address + typetags + self.message
-
- def __repr__(self):
- return self.getBinary()
-
-def readString(data):
- length = string.find(data,"\0")
- nextData = int(math.ceil((length+1) / 4.0) * 4)
- return (data[0:length], data[nextData:])
-
-
-def readBlob(data):
- length = struct.unpack(">i", data[0:4])[0]
- nextData = int(math.ceil((length) / 4.0) * 4) + 4
- return (data[4:length+4], data[nextData:])
-
-
-def readInt(data):
- if(len(data)<4):
- print "Error: too few bytes for int", data, len(data)
- rest = data
- integer = 0
- else:
- integer = struct.unpack(">i", data[0:4])[0]
- rest = data[4:]
-
- return (integer, rest)
-
-
-
-def readLong(data):
- """Tries to interpret the next 8 bytes of the data
- as a 64-bit signed integer."""
- high, low = struct.unpack(">ll", data[0:8])
- big = (long(high) << 32) + low
- rest = data[8:]
- return (big, rest)
-
-
-
-def readFloat(data):
- if(len(data)<4):
- print "Error: too few bytes for float", data, len(data)
- rest = data
- float = 0
- else:
- float = struct.unpack(">f", data[0:4])[0]
- rest = data[4:]
-
- return (float, rest)
-
-
-def OSCBlob(next):
- """Convert a string into an OSC Blob,
- returning a (typetag, data) tuple."""
-
- if type(next) == type(""):
- length = len(next)
- padded = math.ceil((len(next)) / 4.0) * 4
- binary = struct.pack(">i%ds" % (padded), length, next)
- tag = 'b'
- else:
- tag = ''
- binary = ''
-
- return (tag, binary)
-
-
-def OSCArgument(next):
- """Convert some Python types to their
- OSC binary representations, returning a
- (typetag, data) tuple."""
-
- if type(next) == type(""):
- OSCstringLength = math.ceil((len(next)+1) / 4.0) * 4
- binary = struct.pack(">%ds" % (OSCstringLength), next)
- tag = "s"
- elif type(next) == type(42.5):
- binary = struct.pack(">f", next)
- tag = "f"
- elif type(next) == type(13):
- binary = struct.pack(">i", next)
- tag = "i"
- else:
- binary = ""
- tag = ""
-
- return (tag, binary)
-
-
-def parseArgs(args):
- """Given a list of strings, produces a list
- where those strings have been parsed (where
- possible) as floats or integers."""
- parsed = []
- for arg in args:
- print arg
- arg = arg.strip()
- interpretation = None
- try:
- interpretation = float(arg)
- if string.find(arg, ".") == -1:
- interpretation = int(interpretation)
- except:
- # Oh - it was a string.
- interpretation = arg
- pass
- parsed.append(interpretation)
- return parsed
-
-
-
-def decodeOSC(data):
- """Converts a typetagged OSC message to a Python list."""
- table = {"i":readInt, "f":readFloat, "s":readString, "b":readBlob}
- decoded = []
- address, rest = readString(data)
- typetags = ""
-
- if address == "#bundle":
- time, rest = readLong(rest)
- decoded.append(address)
- decoded.append(time)
- while len(rest)>0:
- length, rest = readInt(rest)
- decoded.append(decodeOSC(rest[:length]))
- rest = rest[length:]
-
- elif len(rest)>0:
- typetags, rest = readString(rest)
- decoded.append(address)
- decoded.append(typetags)
- if(typetags[0] == ","):
- for tag in typetags[1:]:
- value, rest = table[tag](rest)
- decoded.append(value)
- else:
- print "Oops, typetag lacks the magic ,"
-
- # return only the data
- return address,decoded[2:]
-
-
-class CallbackManager:
- """This utility class maps OSC addresses to callables.
-
- The CallbackManager calls its callbacks with a list
- of decoded OSC arguments, including the address and
- the typetags as the first two arguments."""
-
- def __init__(self):
- self.callbacks = {}
- self.addCallback(self.unbundler, "#bundle")
-
- def handle(self, data, source = None):
- """Given OSC data, tries to call the callback with the
- right address."""
- decoded = decodeOSC(data)
- self.dispatch(decoded)
-
- def dispatch(self, message):
- """Sends decoded OSC data to an appropriate calback"""
- try:
- address = message[0]
- self.callbacks[address](message)
- except KeyError, e:
- # address not found
- print "no handler for '%s'" % address
- pass
- except None, e:
- print "Exception in", address, "callback :", e
-
- return
-
- def addCallback(self, callback, name):
- """Adds a callback to our set of callbacks,
- or removes the callback with name if callback
- is None."""
- if callback == None:
- del self.callbacks[name]
- else:
- self.callbacks[name] = callback
-
- def unbundler(self, messages):
- """Dispatch the messages in a decoded bundle."""
- # first two elements are #bundle and the time tag, rest are messages.
- for message in messages[2:]:
- self.dispatch(message)
-
-
-if __name__ == "__main__":
- hexDump("Welcome to the OSC testing program.")
- print
- message = OSCMessage()
- message.setAddress("/foo/play")
- message.append(44)
- message.append(11)
- message.append(4.5)
- message.append("the white cliffs of dover")
- hexDump(message.getBinary())
-
- print "Making and unmaking a message.."
-
- strings = OSCMessage()
- strings.append("Mary had a little lamb")
- strings.append("its fleece was white as snow")
- strings.append("and everywhere that Mary went,")
- strings.append("the lamb was sure to go.")
- strings.append(14.5)
- strings.append(14.5)
- strings.append(-400)
-
- raw = strings.getBinary()
-
- hexDump(raw)
-
- print "Retrieving arguments..."
- data = raw
- for i in range(6):
- text, data = readString(data)
- print text
-
- number, data = readFloat(data)
- print number
-
- number, data = readFloat(data)
- print number
-
- number, data = readInt(data)
- print number
-
- hexDump(raw)
- print decodeOSC(raw)
- print decodeOSC(message.getBinary())
-
- print "Testing Blob types."
-
- blob = OSCMessage()
- blob.append("","b")
- blob.append("b","b")
- blob.append("bl","b")
- blob.append("blo","b")
- blob.append("blob","b")
- blob.append("blobs","b")
- blob.append(42)
-
- hexDump(blob.getBinary())
-
- print decodeOSC(blob.getBinary())
-
- def printingCallback(stuff):
- sys.stdout.write("Got: ")
- for i in stuff:
- sys.stdout.write(str(i) + " ")
- sys.stdout.write("\n")
-
- print "Testing the callback manager."
-
- c = CallbackManager()
- c.add(printingCallback, "/print")
-
- c.handle(message.getBinary())
- message.setAddress("/print")
- c.handle(message.getBinary())
-
- print1 = OSCMessage()
- print1.setAddress("/print")
- print1.append("Hey man, that's cool.")
- print1.append(42)
- print1.append(3.1415926)
-
- c.handle(print1.getBinary())
-
- bundle = OSCMessage()
- bundle.setAddress("")
- bundle.append("#bundle")
- bundle.append(0)
- bundle.append(0)
- bundle.append(print1.getBinary(), 'b')
- bundle.append(print1.getBinary(), 'b')
-
- bundlebinary = bundle.message
-
- print "sending a bundle to the callback manager"
- c.handle(bundlebinary)
diff --git a/src/clients/python/omecho.py b/src/clients/python/omecho.py
deleted file mode 100644
index c0d2d3b1..00000000
--- a/src/clients/python/omecho.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/python
-#
-# Python bindings for Om
-# Copyright (C) 2005 Leonard Ritter
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import omsynth
-import os,time,sys
-
-def main(om):
- om.setEnvironment(omsynth.Environment())
- om.engine.activate()
- om.engine.register_client(om.getAddressAsString())
- om.request.all_objects(om.getAddressAsString())
-
- om.request.all_objects()
- time.sleep(3)
- om.getEnvironment().printPatch()
- om.getEnvironment().printConnections()
- print "omecho will now monitor and mirror changes in the structure"
- print "hit return to exit when youre done"
- sys.stdin.readline()
- om.engine.unregister_client(om.getAddressAsString())
- os._exit(0)
-
-if __name__ == "__main__":
- omsynth.startClient(main)
diff --git a/src/clients/python/omsynth.py b/src/clients/python/omsynth.py
deleted file mode 100644
index d7cfa5ab..00000000
--- a/src/clients/python/omsynth.py
+++ /dev/null
@@ -1,635 +0,0 @@
-#!/usr/bin/python
-#
-# Python bindings for Om
-# Copyright (C) 2005 Leonard Ritter
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import os,sys,thread,time
-
-from OSC import OSCMessage, decodeOSC
-
-from twisted.internet.protocol import DatagramProtocol
-from twisted.internet import reactor
-
-OM_CALL_TIMEOUT = 5
-OM_CALL_POLLTIME = 0.1
-
-class TreeElement:
- def __init__(self,environment,parent,name):
- self.environment = environment
- self.parent = parent
- self.name = name
- self.metadata = {}
-
- def __del__(self):
- print "'%s': gone" % self.name
-
- def removeChild(self, child):
- pass
-
- def remove(self):
- self.parent.removeChild(self.name)
- self.parent = None
- del self
-
- def getParent(self):
- return self.parent
-
- def getName(self):
- return self.name
-
- def getPath(self):
- if self.parent:
- return self.parent.getPath() + "/" + self.name
- else:
- return self.name
-
- def getDepth(self):
- if self.parent:
- return self.parent.getDepth() + 1
- else:
- return 0
-
- def setMetaData(self,key,value):
- if (not self.metadata.has_key(value)) or (self.metadata[key] != value):
- print "||| '%s': '%s' = '%s'" % (self.getPath(), key, value)
- self.metadata[key] = value
-
-class Port(TreeElement):
- def __init__(self,environment,parent,name):
- TreeElement.__init__(self,environment,parent,name)
- self.porttype = ""
- self.direction = ""
- self.hint = ""
- self.defaultvalue = 0.0
- self.minvalue = 0.0
- self.maxvalue = 0.0
- self.value = 0.0
- self.connections = {}
- print "*** '%s': new port" % self.getPath()
-
- def remove(self):
- for connection in self.getConnections():
- connection.remove()
- TreeElement.remove(self)
-
- def getConnections(self):
- return self.connections
-
- def addConnection(self,target,connection):
- self.connections[target] = connection
-
- def removeConnection(self,target):
- del self.connections[target]
-
- def setPortType(self,porttype):
- if self.porttype != porttype:
- print "*** '%s': changing porttype from '%s' to '%s'" % (self.getPath(), self.porttype, porttype)
- self.porttype = porttype
-
- def setDirection(self,direction):
- if self.direction != direction:
- print "*** '%s': changing direction from '%s' to '%s'" % (self.getPath(), self.direction, direction)
- self.direction = direction
-
- def setHint(self,hint):
- if self.hint != hint:
- print "*** '%s': changing hint from '%s' to '%s'" % (self.getPath(), self.hint, hint)
- self.hint = hint
-
- def setDefaultValue(self,defaultvalue):
- if self.defaultvalue != defaultvalue:
- print "*** '%s': changing defaultvalue from '%.3f' to '%.3f'" % (self.getPath(), self.defaultvalue, defaultvalue)
- self.defaultvalue = defaultvalue
-
- def setMinValue(self,minvalue):
- if self.minvalue != minvalue:
- print "*** '%s': changing minvalue from '%.3f' to '%.3f'" % (self.getPath(), self.minvalue, minvalue)
- self.minvalue = minvalue
-
- def setMaxValue(self,maxvalue):
- if self.maxvalue != maxvalue:
- print "*** '%s': changing maxvalue from '%.3f' to '%.3f'" % (self.getPath(), self.maxvalue, maxvalue)
- self.maxvalue = maxvalue
-
- def setValue(self,value):
- if self.value != value:
- print "*** '%s': changing value from '%.3f' to '%.3f'" % (self.getPath(), self.value, value)
- self.value = value
-
-class Node(TreeElement):
- def __init__(self,environment,parent,name):
- TreeElement.__init__(self,environment,parent,name)
- self.ports = {}
- self.polyphonic = 0
- self.plugintype = ""
- self.libname = ""
- self.pluginlabel = ""
- print "+++ '%s': new node" % self.getPath()
-
- def remove(self):
- for port in self.getPorts():
- port.remove()
- TreeElement.remove(self)
-
- def removeChild(self, child):
- del self.ports[child]
-
- def getPorts(self):
- return self.ports.values()
-
- def setPluginLabel(self,pluginlabel):
- if pluginlabel != self.pluginlabel:
- print "+++ '%s': changing pluginlabel from '%s' to '%s'" % (self.getPath(), self.pluginlabel, pluginlabel)
- self.pluginlabel = pluginlabel
-
- def setLibName(self,libname):
- if libname != self.libname:
- print "+++ '%s': changing libname from '%s' to '%s'" % (self.getPath(), self.libname, libname)
- self.libname = libname
-
- def setPluginType(self,plugintype):
- if plugintype != self.plugintype:
- print "+++ '%s': changing plugintype from '%s' to '%s'" % (self.getPath(), self.plugintype, plugintype)
- self.plugintype = plugintype
-
- def setPolyphonic(self,polyphonic):
- if polyphonic != self.polyphonic:
- print "+++ '%s': changing polyphony from %i to %i" % (self.getPath(), self.polyphonic, polyphonic)
- self.polyphonic = polyphonic
-
- def hasPort(self,name):
- return self.ports.has_key(name)
-
- def getPort(self,name,mustexist=False):
- if not self.hasPort(name):
- if mustexist:
- return None
- self.ports[name] = self.environment.getPortClass()(self.environment,self,name)
- return self.ports[name]
-
-class Patch(Node):
- def __init__(self,environment,parent,name):
- Node.__init__(self,environment,parent,name)
- self.nodes = {}
- self.patches = {}
- self.poly = 0
- self.enabled = False
- print "### '%s': new patch" % self.getPath()
-
- def remove(self):
- for patch in self.getPatches():
- patch.remove()
- for node in self.getNodes():
- node.remove()
- Node.remove(self)
-
- def removeChild(self, child):
- if self.hasNode(child):
- del self.nodes[child]
- elif self.hasPatch(child):
- del self.patches[child]
- else:
- Node.removeChild(self,child)
-
- def getPatches(self):
- return self.patches.values()
-
- def getNodes(self):
- return self.nodes.values()
-
- def getEnabled(self):
- return self.enabled
-
- def setEnabled(self,enabled):
- if enabled != self.enabled:
- print "### '%s': changing enabled from %s to %s" % (self.getPath(), str(self.enabled), str(enabled))
- enabled = self.enabled
-
- def getPoly(self):
- return self.poly
-
- def setPoly(self,poly):
- if poly != self.poly:
- print "### '%s': changing polyphony from %i to %i" % (self.getPath(), self.poly, poly)
- self.poly = poly
-
- def hasNode(self,name):
- return self.nodes.has_key(name)
-
- def getNode(self,name,mustexist=False):
- if not self.hasNode(name):
- if mustexist:
- return None
- self.nodes[name] = self.environment.getNodeClass()(self.environment,self,name)
- return self.nodes[name]
-
- def hasPatch(self,name):
- return self.patches.has_key(name)
-
- def getPatch(self,name,mustexist=False):
- if not self.hasPatch(name):
- if mustexist:
- return None
- self.patches[name] = self.environment.getPatchClass()(self.environment,self,name)
- return self.patches[name]
-
-class Connection:
- def __init__(self,environment,srcport,dstport):
- self.environment = environment
- self.srcport = srcport
- self.dstport = dstport
- self.srcport.addConnection(self.dstport,self)
- self.dstport.addConnection(self.srcport,self)
- print ">>> '%s'->'%s': new connection" % (self.srcport.getPath(),self.dstport.getPath())
-
- def __del__(self):
- print "connection gone"
-
- def remove(self):
- self.srcport.removeConnection(self.dstport)
- self.dstport.removeConnection(self.srcport)
- del self
-
- def getSrcPort(self):
- return self.srcport
-
- def getDstPort(self):
- return self.dstport
-
- def getPortPair(self):
- return self.srcport, self.dstport
-
-class Environment:
- def __init__(self):
- self.omPatch = self.getPatchClass()(self,None,"")
- self.enabled = False
- self.connections = {}
-
- def getConnectionClass(self):
- return Connection
-
- def getPatchClass(self):
- return Patch
-
- def getNodeClass(self):
- return Node
-
- def getPortClass(self):
- return Port
-
- def getConnection(self,srcportpath,dstportpath,mustexist=False):
- srcport = self.getPort(srcportpath,True)
- if not srcport:
- return None
- dstport = self.getPort(dstportpath,True)
- if not dstport:
- return None
- if not self.connections.has_key((srcport,dstport)):
- if mustexist:
- return None
- self.connections[(srcport,dstport)] = self.getConnectionClass()(self,srcport,dstport)
- return self.connections[(srcport,dstport)]
-
- def getConnections(self):
- return self.connections.values()
-
- def getPatch(self,path,mustexist=False):
- elements = path.split("/")
- currentPatch = None
- for element in elements:
- if element == "":
- currentPatch = self.omPatch
- else:
- currentPatch = currentPatch.getPatch(element,mustexist)
- if not currentPatch:
- break
- return currentPatch
-
- def getNode(self,path,mustexist=False):
- elements = path.split("/")
- basepath = "/".join(elements[:-1])
- nodename = elements[-1]
- patch = self.getPatch(basepath,True)
- if patch:
- return patch.getNode(nodename,mustexist)
- return None
-
- def getPort(self,path,mustexist=False):
- elements = path.split("/")
- basepath = "/".join(elements[:-1])
- portname = elements[-1]
- node = self.getNode(basepath,True)
- if node:
- return node.getPort(portname,mustexist)
- patch = self.getPatch(basepath,True)
- if patch:
- return patch.getPort(portname,mustexist)
- return None
-
- def getObject(self,path):
- patch = self.getPatch(path,True)
- if patch:
- return patch
- node = self.getNode(path,True)
- if node:
- return node
- return self.getPort(path,True)
-
- def printPatch(self,patch=None):
- if not patch:
- patch = self.omPatch
- print patch.getDepth()*' ' + "### " + patch.getPath()
- for node in patch.getNodes():
- print node.getDepth()*' ' + "+++ " + node.getPath()
- for port in node.getPorts():
- print port.getDepth()*' ' + "*** " + port.getPath()
- for port in patch.getPorts():
- print port.getDepth()*' ' + "*** " + port.getPath()
- for subpatch in patch.getPatches():
- self.printPatch(subpatch)
-
- def printConnections(self):
- for connection in self.getConnections():
- print ">>> %s -> %s" % (connection.getSrcPort().getPath(), connection.getDstPort().getPath())
-
- #~ /om/engine_enabled - Notification engine's DSP has been enabled.
- def __om__engine_enabled(self):
- self.enabled = True
-
- #~ /om/engine_disabled - Notification engine's DSP has been disabled.
- def __om__engine_disabled(self):
- self.enabled = False
-
- #~ /om/new_node - Notification of a new node's creation.
- #~ * path (string) - Path of the new node
- #~ * polyphonic (integer-boolean) - Node is polyphonic (1 for yes, 0 for no)
- #~ * type (string) - Type of plugin (LADSPA, DSSI, Internal, Patch)
- #~ * lib-name (string) - Name of library if a plugin (ie cmt.so)
- #~ * plug-label (string) - Label of plugin in library (ie adsr_env)
-
- #~ * New nodes are sent as a blob. The first message in the blob will be this one (/om/new_node), followed by a series of /om/new_port commands, followed by /om/new_node_end.
- def __om__new_node(self,path,polyphonic,plugintype,libname,pluginlabel):
- node = self.getNode(path)
- node.setPolyphonic(polyphonic)
- node.setPluginType(plugintype)
- node.setLibName(libname)
- node.setPluginLabel(pluginlabel)
-
- def __om__new_node_end(self):
- pass
-
- #~ /om/node_removal - Notification of a node's destruction.
- #~ * path (string) - Path of node (which no longer exists)
- def __om__node_removal(self,path):
- node = self.getNode(path)
- node.remove()
-
- #~ /om/new_port - Notification of a node's destruction.
-
- #~ * path (string) - Path of new port
- #~ * type (string) - Type of port (CONTROL or AUDIO)
- #~ * direction (string) - Direction of data flow (INPUT or OUTPUT)
- #~ * hint (string) - Hint (INTEGER, LOGARITHMIC, TOGGLE, or NONE)
- #~ * default-value (float) - Default (initial) value
- #~ * min-value (float) - Suggested minimum value
- #~ * min-value (float) - Suggested maximum value
-
- #~ * Note that in the event of loading a patch, this message could be followed immediately by a control change, meaning the default-value is not actually the current value of the port (ahem, Lachlan).
- #~ * The minimum and maximum values are suggestions only, they are not enforced in any way, and going outside them is perfectly fine. Also note that the port ranges in om_gtk are not these ones! Those ranges are set as metadata.
- def __om__new_port(self,path,porttype,direction,hint,defaultvalue,minvalue,maxvalue):
- port = self.getPort(path)
- port.setPortType(porttype)
- port.setDirection(direction)
- port.setHint(hint)
- port.setDefaultValue(defaultvalue)
- port.setMinValue(minvalue)
- port.setMaxValue(maxvalue)
-
- #~ /om/port_removal - Notification of a port's destruction.
- #~ * path (string) - Path of port (which no longer exists)
- def __om__port_removal(self,path):
- port = self.getPort(path)
- port.remove()
-
- #~ /om/patch_destruction - Notification of a patch's destruction.
- #~ * path (string) - Path of patch (which no longer exists)
- def __om__patch_destruction(self,path):
- patch = self.getPatch(path)
- patch.remove()
-
- #~ /om/patch_enabled - Notification a patch's DSP processing has been enabled.
- #~ * path (string) - Path of enabled patch
- def __om__patch_enabled(self,path):
- patch = self.getPatch(path)
- patch.setEnabled(True)
-
- #~ /om/patch_disabled - Notification a patch's DSP processing has been disabled.
- #~ * path (string) - Path of disabled patch
- def __om__patch_disabled(self,path):
- patch = self.getPatch(path)
- patch.setEnabled(False)
-
- #~ /om/new_connection - Notification a new connection has been made.
- #~ * src-path (string) - Path of the source port
- #~ * dst-path (string) - Path of the destination port
- def __om__new_connection(self,srcpath,dstpath):
- self.getConnection(srcpath,dstpath)
-
- #~ /om/disconnection - Notification a connection has been unmade.
- #~ * src-path (string) - Path of the source port
- #~ * dst-path (string) - Path of the destination port
- def __om__disconnection(self,srcpath,dstpath):
- connection = self.getConnection(srcpath,dstpath)
- portpair = connection.getPortPair()
- connection.remove()
- del self.connections[portpair]
-
- #~ /om/metadata/update - Notification of a piece of metadata.
- #~ * path (string) - Path of the object associated with metadata (can be a node, patch, or port)
- #~ * key (string)
- #~ * value (string)
- def __om__metadata__update(self,path,key,value):
- object = self.getObject(path)
- object.setMetaData(key,value)
-
- #~ /om/control_change - Notification the value of a port has changed
- #~ * path (string) - Path of port
- #~ * value (float) - New value of port
- #~ * This will only send updates for values set by clients of course - not values changing because of connections to other ports!
- def __om__control_change(self,path,value):
- port = self.getPort(path)
- port.setValue(value)
-
- #~ /om/new_patch - Notification of a new patch
- #~ * path (string) - Path of new patch
- #~ * poly (int) - Polyphony of new patch (not a boolean like new_node)
- def __om__new_patch(self,path,poly):
- patch = self.getPatch(path)
- patch.setPoly(poly)
-
-class SocketError:
- pass
-
-class Call:
- pass
-
-class ClientProxy:
- def __init__(self, om, name, is_async = False):
- self.name = name
- self.om = om
- self.is_async = is_async
-
- def __call__(self, *args):
- if (self.is_async):
- self.om.sendMsg(self.name, *args)
- return True
-
- result = self.om.sendMsgBlocking(self.name, *args)
- if not result:
- return None
- if result[0] == "/om/response/ok":
- return True
- print "ERROR: %s" % result[1][1]
- return False
-
- def __getattr__(self, name):
- if (name[:2] == "__") and (name[-2:] == "__"): # special function
- raise AttributeError, name
- if name in self.__dict__:
- raise AttributeError, name
- if name == 'async':
- return ClientProxy(self.om, self.name, True)
- else:
- return ClientProxy(self.om, self.name + '/' + name)
-
-class Client(DatagramProtocol, ClientProxy):
- def __init__(self):
- ClientProxy.__init__(self, self, "/om")
-
- def startProtocol(self):
- self.transport.connect("127.0.0.1", 16180)
- host = self.transport.getHost()
- self.host = host.host
- self.port = host.port
- self.environment = None
- self.handlers = {}
- self.calls = {}
- #print "opened port at %s" % (str((self.host,self.port)))
- self.nextPacketNumber = 1
-
- def setEnvironment(self, environment):
- self.handlers = {}
- self.environment = environment
- for name in dir(self.environment):
- element = getattr(self.environment,name)
- if (type(element).__name__ == 'instancemethod') and (element.__name__[:6] == "__om__"):
- handlername = element.__name__.replace("__","/")
- print "registering handler for '%s'" % handlername
- self.handlers[handlername] = element
-
- def getEnvironment(self):
- return self.environment
-
- def connectionRefused(self):
- print "Noone listening, aborting."
- os._exit(-1)
-
- def messageReceived(self, (msg, args)):
- if msg == "/om/error":
- print "ERROR: %r" % args
- return
- if msg == "/om/response/ok":
- omcall = self.calls[args[0]]
- omcall.result = (msg,args)
- omcall.done = True
- return
- if msg == "/om/response/error":
- omcall = self.calls[args[0]]
- omcall.result = (msg,args)
- omcall.done = True
- return
- if msg == "#bundle":
- for arg in args:
- self.messageReceived(arg)
- return
- if self.handlers.has_key(msg):
- try:
- self.handlers[msg](*args)
- except:
- a,b,c = sys.exc_info()
- sys.excepthook(a,b,c)
- print "with '%s'" % repr((msg,args))
- return
- print "no handler for '%s'" % repr((msg,args))
-
- def datagramReceived(self, data, (host, port)):
- self.messageReceived(decodeOSC(data))
-
- def getPacketNumber(self):
- packetNumber = self.nextPacketNumber
- self.nextPacketNumber = (self.nextPacketNumber + 1)
- return packetNumber
-
- def sendMsg(self,msg,*args):
- packetNumber = self.getPacketNumber()
- print "Sending %r (#%i)..." % (msg,packetNumber)
- omcall = Call()
- omcall.result = None
- omcall.done = False
- self.calls[packetNumber] = omcall
- message = OSCMessage()
- message.setAddress(msg)
- message.append(packetNumber)
- for arg in args:
- message.append(arg)
- self.transport.write(message.getBinary())
- time.sleep(0.01)
- return True
-
- def sendMsgBlocking(self,msg,*args):
- packetNumber = self.getPacketNumber()
- print "Sending %r (#%i)..." % (msg,packetNumber)
- omcall = Call()
- omcall.result = None
- omcall.done = False
- self.calls[packetNumber] = omcall
- message = OSCMessage()
- message.setAddress(msg)
- message.append(packetNumber)
- for arg in args:
- message.append(arg)
- self.transport.write(message.getBinary())
- now = time.time()
- while not omcall.done:
- time.sleep(OM_CALL_POLLTIME)
- distance = time.time() - now
- if distance > OM_CALL_TIMEOUT:
- print "timeout"
- break
- del self.calls[packetNumber]
- return omcall.result
-
- def getAddressAsString(self):
- return "osc.udp://%s:%d" % (self.host, self.port)
-
-
-
-def startClient(func):
- om = Client()
- reactor.listenUDP(0, om)
- thread.start_new_thread(func,(om,))
- reactor.run()
diff --git a/src/clients/python/scripts/Makefile.am b/src/clients/python/scripts/Makefile.am
deleted file mode 100644
index 3e070601..00000000
--- a/src/clients/python/scripts/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-EXTRA_DIST = sillysinepatch.py
-
diff --git a/src/clients/python/scripts/flatten.py b/src/clients/python/scripts/flatten.py
deleted file mode 100755
index eaf8084d..00000000
--- a/src/clients/python/scripts/flatten.py
+++ /dev/null
@@ -1,232 +0,0 @@
-#!/usr/bin/python
-
-###############################################################################
-#
-# flatten.py - a python script that merges all subpatches in an Om patch
-# into the parent patch
-#
-# Copyright (C) 2005 Lars Luthman
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-###############################################################################
-
-import omsynth
-import os,time,sys
-
-
-def getPatchBounds(patch):
- """Returns the smallest rectangle that contains all modules in the patch."""
- min_x = None
- min_y = None
- max_x = None
- max_y = None
- for node in patch.getNodes():
- x = node.metadata['module-x']
- y = node.metadata['module-y']
- if (x != None):
- if (min_x == None or float(x) < min_x):
- min_x = float(x)
- if (max_x == None or float(x) > max_x):
- max_x = float(x)
- if (y != None):
- if (min_y == None or float(y) < min_y):
- min_y = float(y)
- if (max_y == None or float(y) > max_y):
- max_y = float(y)
- if min_x == None:
- min_x = 0
- max_x = 0
- if min_y == None:
- min_y = 0
- max_y = 0
-
- return (min_x, min_y, max_x, max_y)
-
-
-def cloneNode(om, node, patch):
- """Copy a node into a patch, return the new node's name."""
-
- # create a node with a free name in the parent
- names = []
- for node2 in patch.getNodes():
- names.append(node2.getName())
- for patch2 in patch.getPatches():
- names.append(patch2.getName())
- names.sort()
- name = node.getName()
- for name2 in names:
- if name2 == name:
- name = name + '_'
- om.synth.create_node.async(patch.getPath() + '/' + name,
- node.plugintype, node.libname,
- node.pluginlabel, node.polyphonic)
-
- # copy port values
- for port in node.getPorts():
- path = '%s/%s/%s' % (patch.getPath(), name, port.getName())
- om.synth.set_port_value_slow.async(path, port.value)
- om.metadata.set.async(path, 'user-min', '%f' % port.minvalue)
- om.metadata.set.async(path, 'user-max', '%f' % port.maxvalue)
- return name
-
-
-def flatten(om, patch):
- """Merge all subpatches into the parent patch."""
-
- # something is wrong, we don't have a patch
- if patch == None:
- return
-
- # iterate over all subpatches
- for subpatch in patch.getPatches():
- flatten(om, subpatch)
- lookup = {}
-
- # copy all nodes from the subpatch to the parent patch
- for node in subpatch.getNodes():
- lookup[node.getName()] = cloneNode(om, node, patch)
-
- # copy all connections
- for node in subpatch.getNodes():
- for port in node.getPorts():
- if port.direction == 'OUTPUT':
- for target in port.getConnections().keys():
- targetname = '%s/%s' % (lookup[target.getParent().getName()], target.getName())
- om.synth.connect.async(patch.getPath() + '/' +
- lookup[node.getName()] + '/' +
- port.getName(),
- patch.getPath() + '/' +
- targetname)
-
- # make external connections
- for node in subpatch.getNodes():
- if node.libname == '':
- lbl = node.pluginlabel
-
- if lbl == 'audio_input' or lbl == 'control_input':
- port1 = node.getPort('in')
- for port2 in port1.getConnections().keys():
- dst = '%s/%s/%s' % (patch.getPath(), lookup[port2.getParent().getName()], port2.getName())
- port4 = subpatch.getPort(node.getName())
- conns = port4.getConnections().keys()
- if len(conns) == 0:
- portValue = port4.value
- om.synth.set_port_value_slow.async(dst, portValue)
- else:
- for port3 in port4.getConnections().keys():
- src = port3.getPath()
- om.synth.connect.async(src, dst)
-
- if lbl == 'audio_output' or lbl == 'control_output':
- port2 = node.getPort('out', True)
- for port1 in port2.getConnections().keys():
- src = '%s/%s/%s' % (patch.getPath(), lookup[port1.getParent().getName()], port1.getName())
- port3 = subpatch.getPort(node.getName())
- for port4 in port3.getConnections().keys():
- dst = port4.getPath()
- om.synth.connect.async(src, dst)
-
- # destroy all input and output nodes from the subpatch
- for node in subpatch.getNodes():
- if node.libname == '':
- lbl = node.pluginlabel
- if (lbl == 'audio_input' or lbl == 'control_input' or
- lbl == 'audio_output' or lbl == 'control_output'):
- om.synth.destroy_node.async('%s/%s' % (patch.getPath(),
- lookup[node.getName()]))
-
- # calculate where to move all the new nodes
- (min_x, min_y, max_x, max_y) = getPatchBounds(subpatch)
- sub_x = subpatch.metadata['module-x']
- if sub_x == None:
- sub_x = 0
- sub_y = subpatch.metadata['module-y']
- if sub_y == None:
- sub_y = 0
- x_offset = float(sub_x)
- if min_x != None:
- x_offset = float(sub_x) - min_x
- y_offset = float(sub_y)
- if min_y != None:
- y_offset = float(sub_y) - min_y
-
- # move the new nodes
- for node in subpatch.getNodes():
- x = float(node.metadata['module-x'])
- if x == None:
- x = 0
- om.metadata.set.async('%s/%s' % (patch.getPath(),
- lookup[node.getName()]),
- 'module-x', '%f' % (x + x_offset))
- y = float(node.metadata['module-y'])
- if y == None:
- y = 0
- om.metadata.set.async('%s/%s' % (patch.getPath(),
- lookup[node.getName()]),
- 'module-y', '%f' % (y + y_offset))
-
- # move the old nodes in the patch
- x_offset = 0
- if min_x != None and max_x != None:
- x_offset = max_x - min_x
- y_offset = 0
- if min_y != None and max_y != None:
- y_offset = max_y - min_y
- for node in patch.getNodes():
- if node.getName() not in lookup.values():
- x = node.metadata['module-x']
- if x != None and float(x) > float(sub_x):
- om.metadata.set.async(node.getPath(), 'module-x',
- '%f' % (float(x) + x_offset))
- y = node.metadata['module-y']
- if y != None and float(y) > float(sub_y):
- om.metadata.set.async(node.getPath(), 'module-y',
- '%f' % (float(y) + y_offset))
- # destroy the subpatch
- om.synth.destroy_patch(subpatch.getPath())
-
-
-def main(om):
- om.setEnvironment(omsynth.Environment())
- om.engine.activate.async()
- om.engine.load_plugins.async()
- om.request.all_objects(om.getAddressAsString())
-
- # wait for all the data to arrive (there should be a cleaner way)
- time.sleep(3)
-
- patch = om.getEnvironment().getPatch(sys.argv[1], True);
- flatten(om, patch)
-
- os._exit(0)
-
-
-if len(sys.argv) > 1:
- if sys.argv[1] == "--name":
- print "Flatten patch"
- os._exit(0)
- elif sys.argv[1] == "--shortdesc":
- print "Merge the contents of all subpatches into the parent patch";
- os._exit(0)
- elif sys.argv[1] == "--signature":
- print "%p";
- os._exit(0)
- else:
- omsynth.startClient(main)
-
-else:
- print "Which patch do you want to flatten?"
- os._exit(0)
diff --git a/src/clients/python/scripts/sillysinepatch.py b/src/clients/python/scripts/sillysinepatch.py
deleted file mode 100644
index ac51a080..00000000
--- a/src/clients/python/scripts/sillysinepatch.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/python
-#
-# Python bindings for Om
-# Copyright (C) 2005 Leonard Ritter
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import omsynth
-import os,time,sys
-
-def main(om):
- om.setEnvironment(omsynth.Environment())
- om.engine.activate()
- om.engine.load_plugins()
- om.engine.register_client(om.getAddressAsString())
- om.request.all_objects(om.getAddressAsString())
- om.synth.create_patch("/silly_sine", 1)
- om.synth.create_node("/silly_sine/output", "Internal", "", "audio_output", 0)
- om.synth.create_node("/silly_sine/sine", "LADSPA", "cmt.so", "sine_fcac", 0)
- om.synth.set_port_value("/silly_sine/sine/Frequency", 440.0)
- om.synth.set_port_value("/silly_sine/sine/Amplitude", 1.0)
- om.synth.connect("/silly_sine/sine/Output", "/silly_sine/output/out")
- om.synth.enable_patch("/silly_sine")
- om.engine.enable()
- om.engine.unregister_client(om.getAddressAsString())
- os._exit(0)
-
-if __name__ == "__main__":
- omsynth.startClient(main)