\documentclass{article} \title{pdlua} \author{Claude Heiland-Allen \\ \tt{claude@mathr.co.uk}} \begin{document} \maketitle \begin{abstract} Pd (aka Pure-data) is a real-time visual programming environment primarily used for multimedia processing. Lua is a powerful, fast, light-weight, embeddable scripting language. pdlua is a Lua embedding for Pd. \end{abstract} \section{Classes and objects} \begin{verbatim} -- example1.pd_lua local example1 = pd.Class:new():register("example1") function example1:initialize(sel, atoms) return true end \end{verbatim} {\tt pd} is a package automatically available to scripts loaded by pdlua. pdlua uses a prototype-based object system and {\tt pd.Class} is the prototype for classes that define patchable objects in Pd. To create a new class, use the {\tt :new()} method. This creates an anonymous class, which needs to be registered with Pd using the {\tt :register()} method. The new class {\tt example1} cannot be instantiated yet, as the default {\tt :initialize()} method returns {\tt false}, indicating to pdlua that the Pd object should not be created. With the code above, {\tt example1} can be created in Pd, but it will have neither inlets nor outlets. \section{Inlets and methods} \begin{verbatim} -- example2.pd_lua local example2 = pd.Class:new():register("example2") function example2:initialize(sel, atoms) self.inlets = 3 return true end \end{verbatim} Setting {\tt self.inlets} in the {\tt :initialize()} method will give the created objects some inlets, in this case three of them. Not very interesting yet, as sending messages to these inlets will result in errors as there are no methods to respond to messages at these inlets. Messages arriving at the Pd object's inlets are dispatched to the Lua object's {\tt :in\_*()} methods. There are five predefined selectors: \begin{itemize} \item {\tt bang} \item {\tt float} \item {\tt symbol} \item {\tt pointer} \item {\tt list} \end{itemize} They can be used like this: \begin{verbatim} function example2:in_1_bang() pd.post("inlet 1 got a bang") end function example2:in_1_float(f) pd.post("inlet 1 got a float: " .. f) end function example2:in_1_symbol(s) pd.post("inlet 1 got a symbol: " .. s) end function example2:in_1_pointer(p) pd.post("inlet 1 got a pointer) end function example2:in_1_list(atoms) pd.post("inlet 1 got a list: " .. #atoms .. " elements") end \end{verbatim} In the above, the methods are defined for the leftmost inlet. To add methods for the other inlets, replace {\tt :in\_1\_*()} with {\tt :in\_2\_*()} for the second inlet, or {\tt :in\_3\_*()} for the third, and so on. It is possible to add methods for other selectors: \begin{verbatim} function example2:in_2_baabaa(atoms) pd.post("inlet 2 got a baabaa: " .. #atoms .. " elements") end function example2:in_2_moomoo(atoms) pd.post("inlet 2 got a moomoo: " .. #atoms .. " elements") end \end{verbatim} It is also possible to add methods that catch any selector: \begin{verbatim} function example2:in_3(sel, atoms) pd.post("inlet 3 got a " .. sel .. ": .. #atoms .. " elements") end \end{verbatim} Or methods that catch messages at any inlet: \begin{verbatim} function example2:in_n_float(i, f) pd.post("inlet " .. i .. " got a float: " .. f) end function example2:in_n_quack(i, atoms) pd.post("inlet " .. i .. " got a quack: " .. #atoms .. " elements") end \end{verbatim} Or even catch any message at any inlet: \begin{verbatim} function example2:in_n(i, sel, atoms) pd.post("inlet " .. i .. " got a " .. sel .. ": " .. #atoms .. " elements") end \end{verbatim} The more specific methods are called before the more general methods: \begin{itemize} \item {\tt :in\_1\_selector()} \item {\tt :in\_n\_selector()} \item {\tt :in\_1()} \item {\tt :in\_n()} \item {\tt :error("no method found")} \end{itemize} \section{Outlets} \section{Sends} \section{Receives} \section{Values} \section{Tables} \section{Clocks} \section{Paths} \end{document}