PyPd

PyPd is a set of LGPLv3 Python classes for interfacing with the Pure Data DSP patching system.

Download the latest version: PyPd-20.tar.gz

or check out the sourcecode with bazaar:

	

Documentation

Pd.py provides a cross platform way to launch Pd in a Python subprocess and communicate with it using sockets (netsend and netreceive), and stderr. Socket communications with Pd are accomplished by instantiating the [patches/python-interface] abstraction in your Pd patch to be loaded. Use the Send() method to send messages to Pd, and catch methods by overriding PdMessage(). You can also create methods to catch specific Pd messages using methods called Pd_xxx to catch all messages starting with the atom "xxx" for example.



		Start Pure Data in a subprocess.
		
		>>> from time import time, sleep
		>>> from os import path, getcwd
		>>> 
		>>> start = time()
		>>> # launching pd
		>>> pd = Pd(nogui=False)
		>>> pd.Send(["test message", 1, 2, 3])
		>>> 
		>>> def Pd_hello(self, message):
		... 	print "Pd called Pd_hello(%s)" % message
		...
		>>> pd.Pd_hello = Pd_hello
		>>> 
		>>> sentexit = False
		>>> # running a bunch of stuff for up to 20 seconds
		>>> while time() - start < 20 and pd.Alive():
		... 	if time() - start > 0.5 and not sentexit:
		... 		pd.Send(["exit"])
		... 		sentexit = True
		... 	pd.Update()
		...
		...
		Pd called Pd_hello(['this', 'is', 'my', 'message', 'to', 'python'])
		untrapped message: ['this', 'is', 'another', 'message']
		untrapped stderr output: "connecting to port 30322"
		untrapped stderr output: "python-connected: 0"
		untrapped stderr output: "python-connected: 1"
		untrapped stderr output: "from-python: test message 1 2 3"
		untrapped stderr output: "closing audio..."
		untrapped stderr output: "pd_gui: pd process exited"
		untrapped stderr output: "closing MIDI..."...
		Pd died!
		>>> pd.Exit()
	

PdParser.py provides a way to parse Pd patches and extract information from them.



	Parse Pd files using user defined filters.
	
	>>> p = PdParser("patches/parser-test.pd")
	>>> def found(canvasStack, type, action, bits):
	...   print "canvasStack:", canvasStack, "type:", type, "action:", action, "arguments:", bits
	... 
	>>> p.add_filter_method(found, canvas="REFERENCE", type="#X", action="text")
	>>> p.add_filter_method(found, canvas="semicolon-test", type="#X", action="msg")
	>>> p.add_filter_method(found, object="osc~")
	>>> p.parse()
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 135 336 Tags: tag_one \, tag_two
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 115 301 Description: Some kind of verbose description here.
	
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 114 121 Name: thing
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 114 174 Argument 0: first argument (required)
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 114 194 Argument 1: second argument (optional)
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 114 214 Inlet 0: my first inlet is blah
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 114 234 Inlet 1: msg1 : what this message does. msg2
	: what this other message does \, default 0 which is the default
	
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 114 278 Outlet 0: what comes out the second outlet.
	canvasStack: ['patches/parser-test.pd', 'REFERENCE'] type: #X action: text arguments: 113 141 Summary: what this thing does is blah blah blah
	canvasStack: ['patches/parser-test.pd'] type: #X action: obj arguments: 471 83 osc~ 220
	canvasStack: ['patches/parser-test.pd', 'semicolon-test'] type: #X action: msg arguments: 10 18 this is a message box \, with comments \, and also \;
	semicolons! yes it is. it's like this: yo. test \; test \; test \;
	
	canvasStack: ['patches/parser-test.pd'] type: #X action: obj arguments: 633 213 osc~ 440
	49