pdlua-0.7.3/0000755000175000017500000000000012651233745013070 5ustar zmoelnigzmoelnigpdlua-0.7.3/doc/0000755000175000017500000000000012651233745013635 5ustar zmoelnigzmoelnigpdlua-0.7.3/doc/luax.txt0000644000175000017500000000344711674625145015362 0ustar zmoelnigzmoelnigpdluax ==== The pdluax class allows "volatile" loading of Lua source code files that define Pd object behaviour. The [pdluax foo] object loads "foo.pd_luax" at object creation time. Advantages ---------- + You can edit "foo.pd_luax" and new [pdluax foo] objects will reflect the changes in the file. + Good for rapid development/testing cycles. + Good for live coding. + No need to restart Pd if you made a little mistake. Disadvantages ------------- - Reloading the file each time is slower. - Syntax is different to the syntax expected by the Lua loader (see below for discussion). - There is no "reload" functionality, so you can have multiple objects called [pdluax foo] but that have different behaviours. - Data shared between objects must be accessible globally. - The above two points mean some mistakes/changes mean you have to restart Pd anyway. How To Write Code For pdluax -------------------------- The last expression/statement in the file should be of the form: return function (self, sel, atoms) -- code here end This function is executed in the context of the 'initialize' method of the pdluax class, and has the same arguments: 'self' is the object to be created. 'sel' is the name of the class. 'atoms' are the creation arguments. To add methods to the new object you need to add code inside the returned function. There are two syntaxes for this: function self:in_1_float(f) ... end or self.in_1_float = function(self, f) ... end If using the second form, remember the self argument. If you need a shared state between objects, you need to use a global name. Try to pick something unique to avoid conflicts with other scripts. You also need to ensure that you don't clobber this state - remember the script can be executed more than once. pdlua-0.7.3/doc/Makefile0000644000175000017500000000006711674625145015303 0ustar zmoelnigzmoelnigall: pdlua.pdf %.pdf: %.tex pdflatex $< pdflatex $< pdlua-0.7.3/doc/pdlua.tex0000644000175000017500000000763012461454037015470 0ustar zmoelnigzmoelnig\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} pdlua-0.7.3/doc/internal.txt0000644000175000017500000000356611674625145016227 0ustar zmoelnigzmoelnigInternal Stuff ============== This is a developer document, not a user document. You probably don't need to read this. Private/Internal Variables -------------------------- Everything that the user shouldn't dabble with starts with '_'. For example 'pd._constructor', 'self._object', etc. This includes everything that messes with pointers, for many purposes have a stub: function f(self, ...) return _f(self._object, ...) end Things that the user can use shouldn't start with '_'. Everything in pdlua should be in the 'pd' global table. Table Indices ------------- As per Lua conventions, Lua tables start at index 1. See: lua.c/pdlua_pushatomtable() (C->Lua) lua.c/pdlua_popatomtable() (Lua->C) (makes additional assumptions) Inlet/Outlet Numbers -------------------- C code uses 0,1,... Lua code uses 1,2,... Translations are performed in: lua.c/pdlua_dispatch() (C->Lua) lua.c/pdlua_outlet() (Lua->C) Pointers -------- Pointers are all Light User Data values. This means there is no type safety, make sure you're using the right pointers! pd._classes :: string => Lua object (class prototypes) object._class :: t_class* pd._objects :: t_pdlua* => Lua object (object instances) object._object :: t_pdlua* pd._clocks :: t_clock* => Lua object (clock instances) clock._clock :: t_clock* pdtable._array :: PDLUA_ARRAY_ELEM* Pointer atoms are also stored as Light User Data. It's possible for things to crash if they are used/stored/etc, as far as I understand the way Pd uses them. Architecture Issues ------------------- :initialize() is called before the object is created. :postinitialize() is called after the object is created. Other Issues ------------ "#t does not invoke the __len metamethod when t is a table." See end of: http://lua-users.org/wiki/GeneralizedPairsAndIpairs This means pd.Table will remain ugly, with :length() :set() :get() pdlua-0.7.3/doc/lua.txt0000644000175000017500000000700311674625145015162 0ustar zmoelnigzmoelnigpdlua === The Lua loader included in -lib pdlua allows externals for Pd to be written in the Lua programming language. If you try to create an object [foo] in Pd, Pd checks if the class "foo" exists. If it doesn't, it tries to load an external file that "probably" will contain code for "foo". The Lua loader adds support for loading "foo.pd_lua" when you try to create [foo]. Class Creation -------------- The first expression/statement in the file should be of the form: local foo = pd.Class:new():register("foo") This creates a new Pd class called "foo". The 'local' declaration is optional, but recommended -- without it, 'foo' is global, which means any Lua code can modify it (possibly by accident). Object Initialization --------------------- Then you can add methods to the Pd class. The most important one is 'initialize', which is executed when a new object is created. function foo:initialize(sel, atoms) -- code end or equivalently: foo.initialize = function (self, sel, atoms) -- code end 'sel' is usually (always?) the class name, 'atoms' are the creation arguments in a Lua table. An example: Pd :: [foo a b 1 2 3 c] sel == "foo" atoms == { "a", "b", 1, 2, 3, "c" } Being a method, 'initialize' has a 'self' variable (which is the object to be created), and if you want your objects to have inlets or outlets you need need to set those fields in this method (Pd doesn't support changing the number of inlets or outlets after an object is created): self.inlets = 1 self.outlets = atoms[1] The default inlet/outlet counts are 0. The return value of 'initialize' is used to allow objects to fail to create (for example, if the creation arguments are bad). Most of the time you will 'return true', but if you really can't create then you can 'return false'. If you need to do things after the Pd object is created, but before control is returned to Pd, you can use the 'postinitialize' method: function foo:postinitialize() -- code end Object Finalization ------------------- The 'finalize' method is called when the object is deleted by Pd. You can clean up stuff here if needed. The default implementation does nothing. Inlet Methods ------------- FIXME: write about inlet methods/dispatching FIXME: for now, see examples/*.pd_lua and src/pd.lua Sending To Outlets ------------------ FIXME: write about self:outlet(outletNumber, selector, atoms) FIXME: for now, see examples/*.pd_lua and src/pd.lua Sending To Receivers -------------------- You can send messages to receivers like this: pd.send("receiver", "selector", { "a", "message", 1, 2, 3 } See examples/lsend.pd_lua for details. Receivers --------- You can bind methods to receivers, to get messages from [send receiver] and "; receiver message". See examples/lreceive.pd_lua for details. Remember to clean up your receivers in object:finalize(), or weird things will happen. Clocks ------ You can bind methods to clocks, for timing based on Pd's logical clock. See examples/ldelay.pd_lua for details. Remember to clean up your clocks in object:finalize(), or weird things will happen. Miscellaneous Object Methods ---------------------------- Execute a Lua file using Pd's path to find it: self:dofile("filename") Report an error to Pd's console: self:error("message") Miscellaneous Functions ----------------------- Print a string to Pd's console: pd.post("a string") Note that pd.post() should not really be used for errors. FIXME: add pd.error() for error messages pdlua-0.7.3/pdlua-help.pd0000644000175000017500000002174511674625145015464 0ustar zmoelnigzmoelnig#N canvas 576 203 637 279 10; #X declare -stdpath doc/examples/pdlua; #X declare -stdpath extra/pdlua/examples; #X msg 44 58; #X text 70 57 << more methods will come (maybe); #X text 53 99 << global interface to pdlua; #X text 113 20 << load and run a Lua file (searches Pd's path); #X msg 17 21 load hello.lua; #X text 17 191 See also:; #X obj 37 216 hello; #X text 15 135 Side-effects:; #X obj 17 101 pdlua; #X obj 87 216 pdluax hello; #X text 29 157 [pdlua] registers a loader that allows Pd classes written in Lua to be loaded.; #X obj 282 109 declare -stdpath doc/examples/pdlua; #N canvas 128 92 621 356 pdlua_HOWTO 0; #X obj 13 3 cnv 15 500 140 empty empty pdlua_HOWTO 20 12 0 14 -135137 -66577 0; #X obj 13 144 cnv 15 500 160 empty empty Class_Creation 20 12 0 14 -203904 -66577 0; #X obj 13 305 cnv 15 500 300 empty empty Object_Initialization 20 12 0 14 -261234 -66577 0; #X obj 13 606 cnv 15 500 120 empty empty empty 20 12 0 14 -135137 -66577 0; #X obj 13 727 cnv 15 500 170 empty empty empty 20 12 0 14 -203904 -66577 0; #X obj 13 1601 cnv 15 500 100 empty empty Sending_To_Receivers 20 12 0 14 -261234 -66577 0; #X obj 13 1702 cnv 15 500 120 empty empty Receivers 20 12 0 14 -135137 -66577 0; #X text 31 28 The Lua loader included in -lib pdlua allows externals for Pd to be written in the Lua programming language. (http://www.lua.org/) ; #X text 31 70 If you try to create an object [foo] in Pd \, Pd checks if the class "foo" exists. If it doesn't \, it tries to load an external file that "probably" will contain code for "foo". The Lua loader adds support for loading "foo.pd_lua" when you try to create [foo].; #X obj 13 898 cnv 15 500 70 empty empty Object_Finalization 20 12 0 14 -261234 -66577 0; #X text 31 216 This creates a new Pd class called "foo". The 'local' declaration is optional \, but recommended -- without it \, 'foo' is global \, which means any Lua code can modify it (possibly by accident). ; #X text 31 164 The first expression/statement in the text file "foo.pd_lua" should be of the form:; #X obj 13 969 cnv 15 500 400 empty empty Inlet_Methods 20 12 0 14 -135137 -66577 0; #X text 31 418 or equivalently:; #X obj 13 1370 cnv 15 500 230 empty empty Sending_To_Outlets 20 12 0 14 -203904 -66577 0; #X text 31 326 Then you can add methods to the Pd class. The most important one is 'initialize' \, which is executed when a new object is created: ; #X text 47 514 [foo a b 1 2 3 c]; #X text 31 485 'sel' is usually (always?) the class name \, 'atoms' are the creation arguments in a Lua table. For example a Pd object ; #X text 32 532 would have sel equal to "foo" and the atoms:; #X text 31 605 Being a method \, 'initialize' has a 'self' variable (which is the object to be created) \, and if you want your objects to have inlets or outlets you need need to set those fields in this method (Pd doesn't support changing the number of inlets or outlets after an object is created):; #X text 31 712 The default inlet/outlet counts are 0; #X text 31 732 The return value of 'initialize' is used to allow objects to fail to create (for example \, if the creation arguments are bad). Most of the time you will 'return true' \, but if you really can't create then you can 'return false'.; #X text 31 920 The 'finalize' method is called when the object is deleted by Pd. You can clean up stuff here if needed. The default implementation does nothing.; #X text 31 1620 You can send messages to receivers like this:; #X text 31 567 where <> should be curly brackets \, but Pd won't print them in a comment.; #X text 30 1661 (again the <> represent curly brackets); #X text 32 1782 Remember to clean up your receivers in object:finalize() \, or weird things will happen.; #X obj 13 1823 cnv 15 500 120 empty empty Clocks 20 12 0 14 -203904 -66577 0; #X obj 13 1944 cnv 15 500 140 empty empty Miscellaneous_Object_Methods 20 12 0 14 -261234 -66577 0; #X text 32 1843 You can bind methods to clocks \, for timing based on Pd's logical clock.; #X text 32 1886 Remember to clean up your clocks in object:finalize() \, or weird things will happen.; #X text 31 1964 Execute a Lua file using Pd's path to find it:; #X text 31 2001 Report an error to Pd's console:; #X obj 13 2086 cnv 15 500 80 empty empty Miscellaneous_Functions 20 12 0 14 -135137 -66577 0; #X text 31 2109 Print a string to Pd's console:; #X text 31 2146 Note that pd.post() should not really be used for errors. ; #X obj 9 2176 pdlua; #X obj 9 30 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 31 1724 You can bind methods to receivers \, to get messages from [send receiver] and " \; receiver message".; #X obj 479 1900 bng 15 250 50 0 empty empty empty 17 7 0 10 -13381 -4034 -1; #X obj 48 195 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 57 197 local foo = pd.Class:new():register("foo"); #X obj 48 368 cnv 15 400 50 empty empty empty 20 12 0 14 -204786 -66577 0; #X obj 48 437 cnv 15 400 50 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 55 367 function foo:initialize(sel \, atoms); #X text 56 380 -- code; #X text 56 394 end; #X text 56 436 foo.initialize = function (self \, sel \, atoms); #X text 55 450 -- code; #X text 56 463 end; #X obj 48 844 cnv 15 400 50 empty empty empty 20 12 0 14 -204786 -66577 0; #X obj 48 679 cnv 15 400 30 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 48 551 <"a" \, "b" \, 1 \, 2 \, 3 \, "c">; #X text 56 677 self.inlets = 1; #X text 55 843 function foo:postinitialize(); #X text 55 857 -- code; #X text 56 872 end; #X obj 48 1982 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X obj 48 2025 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X obj 48 2126 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 56 1982 self:dofile("filename"); #X text 56 2025 self:error("message"); #X text 56 2126 pd.post("a string"); #X obj 479 1663 bng 15 250 50 0 empty empty empty 17 7 0 10 -4034 -257985 -1; #X floatatom 602 1789 5 0 0 0 - - -; #X msg 514 1614 1000; #X msg 552 1614 100; #X text 32 1761 See doc/examples/lreceive.pd_lua for details.; #X text 32 1682 See doc/examples/lsend.pd_lua for details.; #X text 32 1871 See doc/examples/ldelay.pd_lua for details.; #X obj 479 1685 lsend splat-1; #X obj 514 1667 lsend splat-2; #X obj 479 1760 lreceive splat- 1 2 3; #X obj 479 1870 ldelay 1000; #X text 75 2173 modified from doc/examples/pdlua/lua.txt; #X text 31 994 Each inlet should have at least one method that will be called when an item it can handle arrives at that input.; #X obj 48 1080 cnv 15 400 50 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 55 1084 function foo:in_1_float(f); #X text 54 1097 -- code; #X text 56 1110 end; #X obj 48 1153 cnv 15 400 50 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 54 1170 -- code; #X text 56 1183 end; #X obj 48 1227 cnv 15 400 50 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 54 1244 -- code; #X text 56 1257 end; #X text 32 1206 A "gimme" method for [foo] accepts any input:; #X text 55 1231 function foo:in_1(sel \, atoms); #X obj 48 1428 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 55 1432 self:outlet(2 \, "bang" \, <>); #X text 29 1451 (as usual <> should be curly brackets); #X text 31 1407 This will cause the second outlet to emit a bang:; #X obj 48 1498 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 31 1477 This will cause the second outlet to emit a float: ; #X text 55 1502 self:outlet(2 \, "float" \, <123>); #X obj 48 1548 cnv 15 400 40 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 31 1526 This will cause the first outlet to emit a list:; #X text 55 1569 self:outlet(1 \, "list" \, somelist); #X text 55 1552 self.somelist = ; #X text 32 1132 A "stop" method for inlet 2 of [foo]:; #X text 55 1157 function foo:in_2_stop(); #X text 31 1024 The name of the method is constructed as "in_n_selector" where n is the inlet number (starting from 1) and selector is a type such as "float" or "bang" \, or a selector name such as "start". Here is a float method for [foo] inlet 1:; #X obj 48 1639 cnv 15 460 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 55 1639 pd.send("receiver" \, "selector" \, <"a" \, "message" \, 1 \, 2 \, 3>; #X obj 48 1301 cnv 15 400 50 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 54 1318 -- code; #X text 56 1331 end; #X text 32 1280 A method for symbols on any input:; #X text 55 1305 function foo:in_n_symbol(i \, s); #X text 31 786 If you need to do things after the Pd object is created \, but before control is returned to Pd \, (such as registering receivers or clocks) you can use the 'postinitialize' method:; #X text 75 2186 by mrpeach 2011/10/06; #X text 31 2046 This will allow the object to be highlighted from Pd's menu using Find->Find Last Error.; #X text 56 693 self.outlets = 2; #X text 31 1389 Use self:outlet(outlet_number \, type \, table); #X connect 37 0 36 0; #X connect 63 0 70 0; #X connect 65 0 71 0; #X connect 66 0 71 0; #X connect 72 0 73 0; #X connect 72 1 64 0; #X connect 73 0 39 0; #X restore 282 90 pd pdlua_HOWTO; #X obj 282 129 declare -stdpath extra/pdlua/examples; #X connect 0 0 8 0; #X connect 4 0 8 0; pdlua-0.7.3/pd.lua0000644000175000017500000002157512461454037014206 0ustar zmoelnigzmoelnig--[[ pdlua -- a Lua embedding for Pd Copyright (C) 2007,2008 Claude Heiland-Allen Copyright (C) 2012 Martin Peach martin.peach@sympatico.ca 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --]] -- storage for Pd C<->Lua interaction pd._classes = { } pd._objects = { } pd._clocks = { } pd._receives = { } -- add a path to Lua's "require" search paths pd._setrequirepath = function(path) pd._packagepath = package.path pd._packagecpath = package.cpath if (pd._iswindows) then package.path = path .. "\\?;" .. path .. "\\?.lua;" .. package.path package.cpath = path .. "\\?.dll;" .. package.cpath else package.path = path .. "/?;" .. path .. "/?.lua;" .. package.path package.cpath = path .. "/?.so;" .. package.cpath end end -- reset Lua's "require" search paths pd._clearrequirepath = function() package.path = pd._packagepath package.cpath = pd._packagecpath end -- constructor dispatcher pd._constructor = function (name, atoms) if nil ~= pd._classes[name] then local o = pd._classes[name]:new():construct(name, atoms) if o then pd._objects[o._object] = o return o._object end end return nil end -- destructor dispatcher pd._destructor = function (object) if nil ~= pd._objects[object] then pd._objects[object]:destruct() end end -- inlet method dispatcher pd._dispatcher = function (object, inlet, sel, atoms) if nil ~= pd._objects[object] then pd._objects[object]:dispatch(inlet, sel, atoms) end end -- clock method dispatcher pd._clockdispatch = function (c) if nil ~= pd._clocks[c] then local m = pd._clocks[c]._method pd._clocks[c]._target[m](pd._clocks[c]._target) end end --whoami method dispatcher pd._whoami = function (object) if nil ~= pd._objects[object] then return pd._objects[object]:whoami() end end --class method dispatcher pd._get_class = function (object) if nil ~= pd._objects[object] then return pd._objects[object]:get_class() end end -- prototypical OO system pd.Prototype = { } function pd.Prototype:new(o) o = o or {} setmetatable(o, self) self.__index = self return o end -- clocks pd.Clock = pd.Prototype:new() function pd.Clock:register(object, method) if nil ~= object then if nil ~= object._object then self._clock = pd._createclock(object._object, method) self._target = object self._method = method pd._clocks[self._clock] = self return self end end return nil end function pd.Clock:destruct() pd._clocks[self._clock] = nil pd._clockfree(self._clock) self._clock = nil end function pd.Clock:dispatch() local m = self._target[self._method] if type(m) == "function" then return m(self._target) else self._target:error( "no method for `" .. self._method .. "' at clock of Lua object `" .. self._name .. "'" ) end end function pd.Clock:set(systime) pd._clockset(self._clock, systime) end function pd.Clock:delay(delaytime) pd._clockdelay(self._clock, delaytime) end function pd.Clock:unset() pd._clockunset(self._clock) end -- tables pd.Table = pd.Prototype:new() function pd.Table:sync(name) self.name = name self._length, self._array = pd._getarray(name) if self._length < 0 then return nil else return self end end function pd.Table:destruct() self._length = -3 self._array = nil end function pd.Table:get(i) if type(i) == "number" and 0 <= i and i < self._length then return pd._readarray(self._length, self._array, i) else return nil end end function pd.Table:set(i, f) if type(i) == "number" and type(f) == "number" and 0 <= i and i < self._length then return pd._writearray(self._length, self._array, i, f) else return nil end end function pd.Table:length() if self._length >= 0 then return self._length else return nil end end function pd.Table:redraw() pd._redrawarray(self.name) end -- receivers function pd._receivedispatch(receive, sel, atoms) if nil ~= pd._receives[receive] then pd._receives[receive]:dispatch(sel, atoms) end end pd.Receive = pd.Prototype:new() function pd.Receive:register(object, name, method) if nil ~= object then if nil ~= object._object then self._receive = pd._createreceive(object._object, name) self._name = name self._target = object self._method = method pd._receives[self._receive] = self return self end end return nil end function pd.Receive:destruct() pd._receives[self._receive] = nil pd._receivefree(self._receive) self._receive = nil self._name = nil self._target = nil self._method = nil end function pd.Receive:dispatch(sel, atoms) self._target[self._method](self._target, sel, atoms) end -- patchable objects pd.Class = pd.Prototype:new() function pd.Class:register(name) if nil ~= pd._classes[name] then -- already registered return pd._classes[name] -- return existing else self._class = pd._register(name) -- register new class pd._classes[name] = self -- record registration self._name = name if name == "pdlua" then self._scriptname = "pd.lua" else self._scriptname = name .. ".pd_lua" end -- mrpeach 20111027 return self -- return new end end function pd.Class:construct(sel, atoms) self._object = pd._create(self._class) self.inlets = 0 self.outlets = 0 if self:initialize(sel, atoms) then pd._createinlets(self._object, self.inlets) pd._createoutlets(self._object, self.outlets) self:postinitialize() return self else return nil end end function pd.Class:destruct() pd._objects[self] = nil self:finalize() pd._destroy(self._object) end function pd.Class:dispatch(inlet, sel, atoms) local m = self["in_" .. inlet .. "_" .. sel] if type(m) == "function" then if sel == "bang" then return m(self) end if sel == "float" then return m(self, atoms[1]) end if sel == "symbol" then return m(self, atoms[1]) end if sel == "pointer" then return m(self, atoms[1]) end if sel == "list" then return m(self, atoms) end return m(self, atoms) end m = self["in_n_" .. sel] if type(m) == "function" then if sel == "bang" then return m(self, inlet) end if sel == "float" then return m(self, inlet, atoms[1]) end if sel == "symbol" then return m(self, inlet, atoms[1]) end if sel == "pointer" then return m(self, inlet, atoms[1]) end if sel == "list" then return m(self, inlet, atoms) end return m(self, inlet, atoms) end m = self["in_" .. inlet] if type(m) == "function" then return m(self, sel, atoms) end m = self["in_n"] if type(m) == "function" then return m(self, inlet, sel, atoms) end self:error( "no method for `" .. sel .. "' at inlet " .. inlet .. " of Lua object `" .. self._name .. "'" ) end function pd.Class:outlet(outlet, sel, atoms) pd._outlet(self._object, outlet, sel, atoms) end function pd.Class:initialize(sel, atoms) end function pd.Class:postinitialize() end function pd.Class:finalize() end function pd.Class:dofile(file) return pd._dofile(self._object, file) end function pd.Class:error(msg) pd._error(self._object, msg) end function pd.Class:whoami() return self._scriptname or self._name end function pd.Class:get_class() -- accessor for t_class* return self._class or nil end local lua = pd.Class:new():register("pdlua") -- global controls (the [pdlua] object only) function lua:initialize(sel, atoms) self.inlets = 1 self.outlets = 0 -- FIXME: might be nice to have errors go here? return true end function lua:in_1_load(atoms) -- execute a script self:dofile(atoms[1]) end local luax = pd.Class:new():register("pdluax") -- classless lua externals (like [pdluax foo]) function luax:initialize(sel, atoms) -- motivation: pd-list 2007-09-23 local f, pathname = self:dofile(atoms[1] .. ".pd_luax") if nil ~= f then self._scriptname = pathname .. '/' .. atoms[1] .. ".pd_luax" -- mrpeach 20120201 local atomstail = { } -- munge for better lua<->luax compatibility for i,_ in ipairs(atoms) do if i > 1 then atomstail[i-1] = atoms[i] end end return f(self, atoms[1], atomstail) else return false -- error message already output by dofile() end end -- fin pd.lua pdlua-0.7.3/Makefile0000644000175000017500000004225412461460670014535 0ustar zmoelnigzmoelnig## Pd library template version 1.0.14 # For instructions on how to use this template, see: # http://puredata.info/docs/developer/MakefileTemplate LIBRARY_NAME = pdlua # add your .c source files, one object per file, to the SOURCES # variable, help files will be included automatically, and for GUI # objects, the matching .tcl file too SOURCES = pdlua.c ## the source directory: either 'src/' (if it exists) or '.' PDLUA_SRCPATH=$(firstword $(patsubst src/%,src,$(wildcard src/*)) .) # list all pd objects (i.e. myobject.pd) files here, and their helpfiles will # be included automatically PDOBJECTS = $(PDLUA_SRCPATH)/pd.lua $(PDLUA_SRCPATH)/hello.lua $(PDLUA_SRCPATH)/hello.pd_lua $(PDLUA_SRCPATH)/hello.pd_luax # example patches and related files, in the 'examples' subfolder EXAMPLES = $(patsubst examples/%,%,$(wildcard examples/*)) # manuals and related files, in the 'manual' subfolder MANUAL = $(patsubst doc/%,%,$(wildcard doc/*)) # if you want to include any other files in the source and binary tarballs, # list them here. This can be anything from header files, test patches, # documentation, etc. README.txt and LICENSE.txt are required and therefore # automatically included EXTRA_DIST = # unit tests and related files here, in the 'unittests' subfolder UNITTESTS = VPATH=$(PDLUA_SRCPATH) HELPPATCHES= $(PDLUA_SRCPATH)/pdlua-help.pd \ $(PDLUA_SRCPATH)/pdluax-help.pd \ $(PDLUA_SRCPATH)/hello-help.pd #------------------------------------------------------------------------------# # # things you might need to edit if you are using other C libraries # #------------------------------------------------------------------------------# LIBRARY_META=$(PDLUA_SRCPATH)/$(LIBRARY_NAME)-meta.pd ALL_CFLAGS = -I"$(PD_INCLUDE)" ALL_LDFLAGS = SHARED_LDFLAGS = ALL_LIBS = #------------------------------------------------------------------------------# # # you shouldn't need to edit anything below here, if we did it right :) # #------------------------------------------------------------------------------# # these can be set from outside without (usually) breaking the build CFLAGS = -Wall -W -g LDFLAGS = LIBS = LUA_CFLAGS = -I/usr/include/lua LUA_LIBS = -llua # get library version from meta file LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_META)) ALL_CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"' PD_INCLUDE = $(PD_PATH)/include/pd # where to install the library, overridden below depending on platform prefix = /usr/local libdir = $(prefix)/lib pkglibdir = $(libdir)/pd-externals objectsdir = $(pkglibdir) INSTALL = install INSTALL_PROGRAM = $(INSTALL) -p -m 644 INSTALL_DATA = $(INSTALL) -p -m 644 INSTALL_DIR = $(INSTALL) -p -m 755 -d ALLSOURCES_ := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \ $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows) ALLSOURCES=$(ALLSOURCES_:%=$(PDLUA_SRCPATH)/%) DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION) UNAME := $(shell uname -s) ifeq ($(UNAME),Darwin) CPU := $(shell uname -p) ifeq ($(CPU),arm) # iPhone/iPod Touch SOURCES += $(SOURCES_iphoneos) EXTENSION = pd_darwin SHARED_EXTENSION = dylib OS = iphoneos PD_PATH = /Applications/Pd-extended.app/Contents/Resources IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin CC=$(IPHONE_BASE)/gcc CPP=$(IPHONE_BASE)/cpp CXX=$(IPHONE_BASE)/g++ ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6 OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer ALL_CFLAGS := $(IPHONE_CFLAGS) $(ALL_CFLAGS) ALL_LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT) SHARED_LDFLAGS += -arch armv6 -dynamiclib -undefined dynamic_lookup $(ISYSROOT) ALL_LIBS += -lc $(LIBS_iphoneos) STRIP = strip -x DISTBINDIR=$(DISTDIR)-$(OS) else # Mac OS X SOURCES += $(SOURCES_macosx) EXTENSION = pd_darwin SHARED_EXTENSION = dylib OS = macosx PD_PATH = /Applications/Pd-extended.app/Contents/Resources OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast # build universal 32-bit on 10.4 and 32/64 on newer ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8) FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4 else SOURCES += $(SOURCES_iphoneos) # Starting with Xcode 4.0, the PowerPC compiler is not installed by default ifeq ($(wildcard /usr/llvm-gcc-4.2/libexec/gcc/powerpc*), ) FAT_FLAGS = -arch i386 -arch x86_64 -mmacosx-version-min=10.5 else FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 endif endif ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include # if the 'pd' binary exists, check the linking against it to aid with stripping BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd) ALL_LDFLAGS += $(FAT_FLAGS) -headerpad_max_install_names -bundle $(BUNDLE_LOADER) \ -undefined dynamic_lookup -L/sw/lib SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \ -install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0 ALL_LIBS += -lc $(LIBS_macosx) STRIP = strip -x DISTBINDIR=$(DISTDIR)-$(OS) # install into ~/Library/Pd on Mac OS X since /usr/local isn't used much pkglibdir=$(HOME)/Library/Pd endif endif # Tho Android uses Linux, we use this fake uname to provide an easy way to # setup all this things needed to cross-compile for Android using the NDK ifeq ($(UNAME),ANDROID) CPU := arm SOURCES += $(SOURCES_android) EXTENSION = so SHARED_EXTENSION = so OS = android PD_PATH = /usr NDK_BASE := /opt/android-ndk NDK_PLATFORM_LEVEL ?= 5 NDK_ABI=arm NDK_COMPILER_VERSION = 4.6 NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-$(NDK_ABI) NDK_UNAME:=$(shell uname -s | tr '[A-Z]' '[a-z]') ifeq ($(NDK_ABI),x86) HOST = i686-linux-android NDK_TOOLCHAIN = $(NDK_ABI)-$(NDK_COMPILER_VERSION) else HOST = $(NDK_ABI)-linux-androideabi NDK_TOOLCHAIN = $(HOST)-$(NDK_COMPILER_VERSION) endif NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/$(NDK_TOOLCHAIN)/prebuilt/$(NDK_UNAME)-$(NDK_PROCESSOR) CC := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-gcc --sysroot=$(NDK_SYSROOT) LD := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ld OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer CFLAGS += LDFLAGS += -rdynamic -shared SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared LIBS += -lc $(LIBS_android) STRIP := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-strip) \ --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq ($(UNAME),Linux) CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -fPIC ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq ($(UNAME),GNU) # GNU/Hurd, should work like GNU/Linux for basically all externals CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -fPIC ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq ($(UNAME),GNU/kFreeBSD) # Debian GNU/kFreeBSD, should work like GNU/Linux for basically all externals CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -fPIC ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME))) CPU := $(shell uname -m) SOURCES += $(SOURCES_cygwin) EXTENSION = dll SHARED_EXTENSION = dll OS = cygwin PD_PATH = $(shell cygpath $$PROGRAMFILES)/pd OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += ALL_LDFLAGS += -rdynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) ALL_LIBS += -lc -lpd $(LIBS_cygwin) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS) endif ifeq (MINGW,$(findstring MINGW,$(UNAME))) CPU := $(shell uname -m) SOURCES += $(SOURCES_windows) EXTENSION = dll SHARED_EXTENSION = dll OS = windows PD_PATH = $(shell cd "$$PROGRAMFILES/pd" && pwd) # MinGW doesn't seem to include cc so force gcc CC=gcc OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer ALL_CFLAGS += -mms-bitfields ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import SHARED_LDFLAGS += -shared ALL_LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" \ -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 -liberty $(LIBS_windows) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS) endif # in case somebody manually set the HELPPATCHES above HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd) ALL_CFLAGS := $(CPPFLAGS) $(ALL_CFLAGS) $(CFLAGS) $(LUA_CFLAGS) $(OPT_CFLAGS) ALL_LDFLAGS := $(LDFLAGS) $(LUA_LDFLAGS) $(ALL_LDFLAGS) ALL_LIBS := $(LIBS) $(LUA_LIBS) $(ALL_LIBS) SHARED_SOURCE ?= $(wildcard lib$(LIBRARY_NAME).c) SHARED_HEADER ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h) SHARED_LIB ?= $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION)) SHARED_TCL_LIB = $(wildcard lib$(LIBRARY_NAME).tcl) .PHONY = install libdir_install single_install install-doc install-examples install-manual install-unittests clean distclean dist etags $(LIBRARY_NAME) TAGS_PD TAGS_SOURCES all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) %.o: %.c $(CC) $(ALL_CFLAGS) -o $@ -c $< %.$(EXTENSION): %.o $(SHARED_LIB) $(CC) $(ALL_LDFLAGS) -o $@ $^ $(ALL_LIBS) chmod a-x $@ # this links everything into a single binary file $(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(SHARED_SOURCE:.c=.o) $(CC) $(ALL_LDFLAGS) -o $@.$(EXTENSION) $^ $(ALL_LIBS) chmod a-x $@.$(EXTENSION) $(SHARED_LIB): $(SHARED_SOURCE:.c=.o) $(CC) $(SHARED_LDFLAGS) -o $@ $^ $(ALL_LIBS) install: libdir_install # The meta and help files are explicitly installed to make sure they are # actually there. Those files are not optional, then need to be there. libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual install-unittests $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_DATA) $(LIBRARY_META) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(SOURCES))" || (\ $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \ $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION)))) test -z "$(strip $(SHARED_LIB))" || \ $(INSTALL_DATA) $(SHARED_LIB) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \ $(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(PDOBJECTS))" || \ $(INSTALL_DATA) $(PDOBJECTS) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(SHARED_TCL_LIB))" || \ $(INSTALL_DATA) $(SHARED_TCL_LIB) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) # install library linked as single binary single_install: $(LIBRARY_NAME) install-doc install-examples install-manual install-unittests $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION) install-doc: $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \ $(INSTALL_DATA) $(HELPPATCHES) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_DATA) README $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt $(INSTALL_DATA) COPYING $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt install-examples: test -z "$(strip $(EXAMPLES))" || \ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \ for file in $(EXAMPLES); do \ $(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \ done install-manual: test -z "$(strip $(MANUAL))" || \ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/doc && \ for file in $(MANUAL); do \ $(INSTALL_DATA) doc/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/doc; \ done install-unittests: test -z "$(strip $(UNITTESTS))" || \ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests && \ for file in $(UNITTESTS); do \ $(INSTALL_DATA) unittests/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests; \ done clean: -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCE:.c=.o) -rm -f -- $(SOURCES:.c=.$(EXTENSION)) -rm -f -- $(LIBRARY_NAME).o -rm -f -- $(LIBRARY_NAME).$(EXTENSION) -rm -f -- $(SHARED_LIB) distclean: clean -rm -f -- $(DISTBINDIR).tar.gz -rm -rf -- $(DISTBINDIR) -rm -f -- $(DISTDIR).tar.gz -rm -rf -- $(DISTDIR) -rm -f -- $(ORIGDIR).tar.gz -rm -rf -- $(ORIGDIR) $(DISTBINDIR): $(INSTALL_DIR) $(DISTBINDIR) libdir: all $(DISTBINDIR) $(INSTALL_DATA) $(LIBRARY_META) $(DISTBINDIR) $(INSTALL_DATA) $(ALLSOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) $(DISTBINDIR) $(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR) test -z "$(strip $(EXTRA_DIST))" || \ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTBINDIR) # tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR) $(DISTDIR): $(INSTALL_DIR) $(DISTDIR) $(ORIGDIR): $(INSTALL_DIR) $(ORIGDIR) dist: $(DISTDIR) $(INSTALL_DATA) Makefile $(DISTDIR) $(INSTALL_DATA) README $(DISTDIR) $(INSTALL_DATA) COPYING $(DISTDIR) $(INSTALL_DATA) $(LIBRARY_META) $(DISTDIR) test -z "$(strip $(ALLSOURCES))" || \ $(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR) test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \ $(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl)) $(DISTDIR) test -z "$(strip $(wildcard $(LIBRARY_NAME).c))" || \ $(INSTALL_DATA) $(LIBRARY_NAME).c $(DISTDIR) test -z "$(strip $(SHARED_HEADER))" || \ $(INSTALL_DATA) $(SHARED_HEADER) $(DISTDIR) test -z "$(strip $(SHARED_SOURCE))" || \ $(INSTALL_DATA) $(SHARED_SOURCE) $(DISTDIR) test -z "$(strip $(SHARED_TCL_LIB))" || \ $(INSTALL_DATA) $(SHARED_TCL_LIB) $(DISTDIR) test -z "$(strip $(PDOBJECTS))" || \ $(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR) test -z "$(strip $(HELPPATCHES))" || \ $(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR) test -z "$(strip $(EXTRA_DIST))" || \ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTDIR) test -z "$(strip $(EXAMPLES))" || \ $(INSTALL_DIR) $(DISTDIR)/examples && \ for file in $(EXAMPLES); do \ $(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \ done test -z "$(strip $(MANUAL))" || \ $(INSTALL_DIR) $(DISTDIR)/doc && \ for file in $(MANUAL); do \ $(INSTALL_DATA) doc/$$file $(DISTDIR)/doc; \ done test -z "$(strip $(UNITTESTS))" || \ $(INSTALL_DIR) $(DISTDIR)/unittests && \ for file in $(UNITTESTS); do \ $(INSTALL_DATA) unittests/$$file $(DISTDIR)/unittests; \ done tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR) # make a Debian source package dpkg-source: debclean make distclean dist mv $(DISTDIR) $(ORIGDIR) tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR) rm -f -- $(DISTDIR).tar.gz rm -rf -- $(DISTDIR) $(ORIGDIR) cd .. && dpkg-source -b $(LIBRARY_NAME) etags: TAGS TAGS_PD: $(wildcard $(PD_INCLUDE)/*.h) etags $^ TAGS_SOURCES: $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) etags -a $^ TAGS: TAGS_PD TAGS_SOURCES etags -a *.h etags -a --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl showsetup: @echo "CC: $(CC)" @echo "CFLAGS: $(CFLAGS)" @echo "LDFLAGS: $(LDFLAGS)" @echo "LIBS: $(LIBS)" @echo "ALL_CFLAGS: $(ALL_CFLAGS)" @echo "ALL_LDFLAGS: $(ALL_LDFLAGS)" @echo "ALL_LIBS: $(ALL_LIBS)" @echo "PD_INCLUDE: $(PD_INCLUDE)" @echo "PD_PATH: $(PD_PATH)" @echo "objectsdir: $(objectsdir)" @echo "LIBRARY_NAME: $(LIBRARY_NAME)" @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)" @echo "SOURCES: $(SOURCES)" @echo "SHARED_HEADER: $(SHARED_HEADER)" @echo "SHARED_SOURCE: $(SHARED_SOURCE)" @echo "SHARED_LIB: $(SHARED_LIB)" @echo "SHARED_TCL_LIB: $(SHARED_TCL_LIB)" @echo "PDOBJECTS: $(PDOBJECTS)" @echo "ALLSOURCES: $(ALLSOURCES)" @echo "ALLSOURCES TCL: $(wildcard $(ALLSOURCES:.c=.tcl))" @echo "UNAME: $(UNAME)" @echo "CPU: $(CPU)" @echo "OS: $(OS)" @echo "pkglibdir: $(pkglibdir)" @echo "DISTDIR: $(DISTDIR)" @echo "ORIGDIR: $(ORIGDIR)" @echo "NDK_TOOLCHAIN: $(NDK_TOOLCHAIN)" @echo "NDK_BASE: $(NDK_BASE)" @echo "NDK_SYSROOT: $(NDK_SYSROOT)" @echo "" @echo "EXAMPLES: $(EXAMPLES)" @echo "MANUAL: $(MANUAL)" @echo "EXTRA: $(EXTRA_DIST)" @echo "foo: $(PDLUA_SRCPATH)" pdlua-0.7.3/hello-help.pd0000644000175000017500000000044311674625145015452 0ustar zmoelnigzmoelnig#N canvas 43 60 476 189 10; #X obj 34 62 hello; #X obj 94 62 hello; #X obj 154 62 hello; #X obj 214 62 hello; #X text 33 95 See also:; #X text 32 14 [lua] registers a loader that allows [hello] to be defined by a source file "hello.pd_lua".; #X obj 49 125 pdlua; #X obj 93 125 pdluax hello; pdlua-0.7.3/pdlua.c0000644000175000017500000015634012651233504014343 0ustar zmoelnigzmoelnig/* This is a version hacked by Martin Peach 20110120 martin.peach@sympatico.ca */ /* Reformmatted the code and added some debug messages. Changed the name of the class to pdlua */ /** @file lua.c * @brief pdlua -- a Lua embedding for Pd. * @author Claude Heiland-Allen * @date 2008 * @version 0.6~svn * * Copyright (C) 2007,2008 Claude Heiland-Allen * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* various C stuff, mainly for reading files */ #include #include #include #include // for open #include // for open #ifdef _MSC_VER #include #include // for open #define read _read #define close _close #define ssize_t int #define snprintf _snprintf #else #include // for open #include #endif /* we use Lua */ #include #include #include /* we use Pd */ #include "m_pd.h" #include "s_stuff.h" // for sys_register_loader() #include "m_imp.h" // for struct _class /* BAD: support for Pd < 0.41 */ #if PD_MAJOR_VERSION == 0 # if PD_MINOR_VERSION >= 41 # define PDLUA_PD41 /* use new garray support that is 64-bit safe */ # define PDLUA_ARRAYGRAB garray_getfloatwords # define PDLUA_ARRAYTYPE t_word # define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)].w_float) # elif PD_MINOR_VERSION >= 40 # define PDLUA_PD40 /* use old garray support, not 64-bit safe */ # define PDLUA_ARRAYGRAB garray_getfloatarray # define PDLUA_ARRAYTYPE t_float # define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)]) # elif PD_MINOR_VERSION >= 39 # define PDLUA_PD39 /* use old garray support, not 64-bit safe */ # define PDLUA_ARRAYGRAB garray_getfloatarray # define PDLUA_ARRAYTYPE t_float # define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)]) # else # error "Pd version is too old, please upgrade" # endif #else # error "Pd version is too new, please file a bug report" #endif /* BAD: end of bad section */ /* If defined, PDLUA_DEBUG lets pdlua post a lot of text */ //#define PDLUA_DEBUG post #ifndef PDLUA_DEBUG //static void PDLUA_DEBUG(const char *fmt, ...) {;} # define PDLUA_DEBUG(x,y) # define PDLUA_DEBUG2(x,y0,y1) # define PDLUA_DEBUG3(x,y0,y1,y2) #else # define PDLUA_DEBUG2 PDLUA_DEBUG # define PDLUA_DEBUG3 PDLUA_DEBUG #endif /** Global Lua interpreter state, needed in the constructor. */ static lua_State *L; /** State for the Lua file reader. */ typedef struct pdlua_readerdata { int fd; /**< File descriptor to read from. */ char buffer[MAXPDSTRING]; /**< Buffer to read into. */ } t_pdlua_readerdata; /** Pd object data. */ typedef struct pdlua { t_object pd; /**< We are a Pd object. */ int inlets; /**< Number of inlets. */ struct pdlua_proxyinlet *in; /**< The inlets themselves. */ int outlets; /**< Number of outlets. */ t_outlet **out; /**< The outlets themselves. */ t_canvas *canvas; /**< The canvas that the object was created on. */ } t_pdlua; /** Proxy inlet object data. */ typedef struct pdlua_proxyinlet { t_pd pd; /**< Minimal Pd object. */ struct pdlua *owner; /**< The owning object to forward inlet messages to. */ unsigned int id; /**< The number of this inlet. */ } t_pdlua_proxyinlet; /** Proxy receive object data. */ typedef struct pdlua_proxyreceive { t_pd pd; /**< Minimal Pd object. */ struct pdlua *owner; /**< The owning object to forward received messages to. */ t_symbol *name; /**< The receive-symbol to bind to. */ } t_pdlua_proxyreceive; /** Proxy clock object data. */ typedef struct pdlua_proxyclock { t_pd pd; /**< Minimal Pd object. */ struct pdlua *owner; /**< Object to forward messages to. */ t_clock *clock; /** Pd clock to use. */ } t_pdlua_proxyclock; /* prototypes*/ static const char *pdlua_reader (lua_State *L, void *rr, size_t *size); /** Proxy inlet 'anything' method. */ static void pdlua_proxyinlet_anything (t_pdlua_proxyinlet *p, t_symbol *s, int argc, t_atom *argv); /** Proxy inlet initialization. */ static void pdlua_proxyinlet_init (t_pdlua_proxyinlet *p, struct pdlua *owner, unsigned int id); /** Register the proxy inlet class with Pd. */ static void pdlua_proxyinlet_setup (void); /** Proxy receive 'anything' method. */ static void pdlua_proxyreceive_anything (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv); /** Proxy receive allocation and initialization. */ static t_pdlua_proxyreceive *pdlua_proxyreceive_new (struct pdlua *owner, t_symbol *name); /** Proxy receive cleanup and deallocation. */ static void pdlua_proxyreceive_free (t_pdlua_proxyreceive *r /**< The proxy receive to free. */); /** Register the proxy receive class with Pd. */ static void pdlua_proxyreceive_setup (void); /** Proxy clock 'bang' method. */ static void pdlua_proxyclock_bang (t_pdlua_proxyclock *c); /** Proxy clock allocation and initialization. */ static t_pdlua_proxyclock *pdlua_proxyclock_new (struct pdlua *owner); /** Register the proxy clock class with Pd. */ static void pdlua_proxyclock_setup (void); /** Dump an array of atoms into a Lua table. */ static void pdlua_pushatomtable (int argc, t_atom *argv); /** Pd object constructor. */ static t_pdlua *pdlua_new (t_symbol *s, int argc, t_atom *argv); /** Pd object destructor. */ static void pdlua_free (t_pdlua *o ); static void pdlua_stack_dump (lua_State *L); /** a handler for the open item in the right-click menu (mrpeach 20111025) */ /** Here we find the lua code for the object and open it in an editor */ static void pdlua_menu_open (t_pdlua *o); /** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */ static int pdlua_class_new (lua_State *L); /** Lua object creation. */ static int pdlua_object_new (lua_State *L); /** Lua object inlet creation. */ static int pdlua_object_createinlets (lua_State *L); /** Lua object outlet creation. */ static int pdlua_object_createoutlets (lua_State *L); /** Lua object receive creation. */ static int pdlua_receive_new (lua_State *L); /** Lua object receive destruction. */ static int pdlua_receive_free (lua_State *L); /** Lua object clock creation. */ static int pdlua_clock_new (lua_State *L); /** Lua proxy clock delay. */ static int pdlua_clock_delay (lua_State *L); /** Lua proxy clock set. */ static int pdlua_clock_set (lua_State *L); /** Lua proxy clock unset. */ static int pdlua_clock_unset (lua_State *L); /** Lua proxy clock destruction. */ static int pdlua_clock_free (lua_State *L); /** Lua object destruction. */ static int pdlua_object_free (lua_State *L); /** Dispatch Pd inlet messages to Lua objects. */ static void pdlua_dispatch (t_pdlua *o, unsigned int inlet, t_symbol *s, int argc, t_atom *argv); /** Dispatch Pd receive messages to Lua objects. */ static void pdlua_receivedispatch (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv); /** Dispatch Pd clock messages to Lua objects. */ static void pdlua_clockdispatch(t_pdlua_proxyclock *clock); /** Convert a Lua table into a Pd atom array. */ static t_atom *pdlua_popatomtable (lua_State *L, int *count, t_pdlua *o); /** Send a message from a Lua object outlet. */ static int pdlua_outlet (lua_State *L); /** Send a message from a Lua object to a Pd receiver. */ static int pdlua_send (lua_State *L); /** Set a [value] object's value. */ static int pdlua_setvalue (lua_State *L); /** Get a [value] object's value. */ static int pdlua_getvalue (lua_State *L); /** Get a [table] object's array. */ static int pdlua_getarray (lua_State *L); /** Read from a [table] object's array. */ static int pdlua_readarray (lua_State *L); /** Write to a [table] object's array. */ static int pdlua_writearray (lua_State *L); /** Redraw a [table] object's graph. */ static int pdlua_redrawarray (lua_State *L); /** Post to Pd's console. */ static int pdlua_post (lua_State *L); /** Report an error from a Lua object to Pd's console. */ static int pdlua_error (lua_State *L); static void pdlua_setrequirepath (lua_State *L, const char *path); static void pdlua_clearrequirepath (lua_State *L); /** Run a Lua script using Pd's path. */ static int pdlua_dofile (lua_State *L); /** Initialize the pd API for Lua. */ static void pdlua_init (lua_State *L); /** Pd loader hook for loading and executing Lua scripts. */ static int pdlua_loader_legacy (t_canvas *canvas, char *name); /** Start the Lua runtime and register our loader hook. */ #ifdef _WIN32 __declspec(dllexport) #endif void pdlua_setup (void); /* end prototypes*/ /* globals */ struct pdlua_proxyinlet; struct pdlua_proxyreceive; struct pdlua_proxyclock; /** Proxy inlet class pointer. */ static t_class *pdlua_proxyinlet_class; /** Proxy receive class pointer. */ static t_class *pdlua_proxyreceive_class; /** Proxy clock class pointer. */ static t_class *pdlua_proxyclock_class; /** Lua file reader callback. */ static const char *pdlua_reader ( lua_State *L, /**< Lua interpreter state. */ void *rr, /**< Lua file reader state. */ size_t *size /**< How much data we have read. */ ) { t_pdlua_readerdata *r = rr; ssize_t s; PDLUA_DEBUG("pdlua_reader: fd is %d", r->fd); s = read(r->fd, r->buffer, MAXPDSTRING-2); PDLUA_DEBUG("pdlua_reader: s is %ld", s);//////// if (s <= 0) { *size = 0; return NULL; } else { *size = s; return r->buffer; } } /** Proxy inlet 'anything' method. */ static void pdlua_proxyinlet_anything ( t_pdlua_proxyinlet *p, /**< The proxy inlet that received the message. */ t_symbol *s, /**< The message selector. */ int argc, /**< The message length. */ t_atom *argv /**< The atoms in the message. */ ) { pdlua_dispatch(p->owner, p->id, s, argc, argv); } /** Proxy inlet initialization. */ static void pdlua_proxyinlet_init ( t_pdlua_proxyinlet *p, /**< The proxy inlet to initialize. */ struct pdlua *owner, /**< The owning object. */ unsigned int id /**< The inlet number. */ ) { p->pd = pdlua_proxyinlet_class; p->owner = owner; p->id = id; } /** Register the proxy inlet class with Pd. */ static void pdlua_proxyinlet_setup(void) { pdlua_proxyinlet_class = class_new(gensym("pdlua proxy inlet"), 0, 0, sizeof(t_pdlua_proxyinlet), 0, 0); class_addanything(pdlua_proxyinlet_class, pdlua_proxyinlet_anything); } /** Proxy receive 'anything' method. */ static void pdlua_proxyreceive_anything( t_pdlua_proxyreceive *r, /**< The proxy receive that received the message. */ t_symbol *s, /**< The message selector. */ int argc, /**< The message length. */ t_atom *argv /**< The atoms in the message. */ ) { pdlua_receivedispatch(r, s, argc, argv); } /** Proxy receive allocation and initialization. */ static t_pdlua_proxyreceive *pdlua_proxyreceive_new ( struct pdlua *owner, /**< The owning object. */ t_symbol *name /**< The symbol to bind to. */ ) { t_pdlua_proxyreceive *r = malloc(sizeof(t_pdlua_proxyreceive)); r->pd = pdlua_proxyreceive_class; r->owner = owner; r->name = name; pd_bind(&r->pd, r->name); return r; } /** Proxy receive cleanup and deallocation. */ static void pdlua_proxyreceive_free(t_pdlua_proxyreceive *r /**< The proxy receive to free. */) { pd_unbind(&r->pd, r->name); r->pd = NULL; r->owner = NULL; r->name = NULL; free(r); } /** Register the proxy receive class with Pd. */ static void pdlua_proxyreceive_setup() { pdlua_proxyreceive_class = class_new(gensym("pdlua proxy receive"), 0, 0, sizeof(t_pdlua_proxyreceive), 0, 0); class_addanything(pdlua_proxyreceive_class, pdlua_proxyreceive_anything); } /** Proxy clock 'bang' method. */ static void pdlua_proxyclock_bang(t_pdlua_proxyclock *c /**< The proxy clock that received the message. */) { pdlua_clockdispatch(c); } /** Proxy clock allocation and initialization. */ static t_pdlua_proxyclock *pdlua_proxyclock_new ( struct pdlua *owner /**< The object to forward messages to. */ ) { t_pdlua_proxyclock *c = malloc(sizeof(t_pdlua_proxyclock)); c->pd = pdlua_proxyclock_class; c->owner = owner; c->clock = clock_new(c, (t_method) pdlua_proxyclock_bang); return c; } /** Register the proxy clock class with Pd. */ static void pdlua_proxyclock_setup(void) { pdlua_proxyclock_class = class_new(gensym("pdlua proxy clock"), 0, 0, sizeof(t_pdlua_proxyclock), 0, 0); } /** Dump an array of atoms into a Lua table. */ static void pdlua_pushatomtable ( int argc, /**< The number of atoms in the array. */ t_atom *argv /**< The array of atoms. */ ) { int i; PDLUA_DEBUG("pdlua_pushatomtable: stack top %d", lua_gettop(L)); lua_newtable(L); for (i = 0; i < argc; ++i) { lua_pushnumber(L, i+1); switch (argv[i].a_type) { case A_FLOAT: lua_pushnumber(L, argv[i].a_w.w_float); break; case A_SYMBOL: lua_pushstring(L, argv[i].a_w.w_symbol->s_name); break; case A_POINTER: /* FIXME: check experimentality */ lua_pushlightuserdata(L, argv[i].a_w.w_gpointer); break; default: error("lua: zomg weasels!"); lua_pushnil(L); break; } lua_settable(L, -3); } PDLUA_DEBUG("pdlua_pushatomtable: end. stack top %d", lua_gettop(L)); } /** Pd object constructor. */ static t_pdlua *pdlua_new ( t_symbol *s, /**< The construction message selector. */ int argc, /**< The construction message atom count. */ t_atom *argv /**< The construction message atoms. */ ) { int i; PDLUA_DEBUG("pdlua_new: s->s_name is %s", s->s_name); for (i = 0; i < argc; ++i) { switch (argv[i].a_type) { case A_FLOAT: PDLUA_DEBUG2("argv[%d]: %f", i, argv[i].a_w.w_float); break; case A_SYMBOL: PDLUA_DEBUG2("argv[%d]: %s", i, argv[i].a_w.w_symbol->s_name); break; default: error("pdlua_new: bad argument type"); // should never happen return NULL; } } PDLUA_DEBUG("pdlua_new: start with stack top %d", lua_gettop(L)); lua_getglobal(L, "pd"); lua_getfield(L, -1, "_constructor"); lua_pushstring(L, s->s_name); pdlua_pushatomtable(argc, argv); PDLUA_DEBUG("pdlua_new: before lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L)); if (lua_pcall(L, 2, 1, 0)) { error("pdlua_new: error in constructor for `%s':\n%s", s->s_name, lua_tostring(L, -1)); lua_pop(L, 2); /* pop the error string and the global "pd" */ return NULL; } else { t_pdlua *object = NULL; PDLUA_DEBUG("pdlua_new: done lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L)); if (lua_islightuserdata(L, -1)) { object = lua_touserdata(L, -1); lua_pop(L, 2);/* pop the userdata and the global "pd" */ PDLUA_DEBUG2("pdlua_new: before returning object %p stack top %d", object, lua_gettop(L)); return object; } else { lua_pop(L, 2);/* pop the userdata and the global "pd" */ PDLUA_DEBUG("pdlua_new: done FALSE lua_islightuserdata(L, -1)", 0); return NULL; } } } /** Pd object destructor. */ static void pdlua_free( t_pdlua *o /**< The object to destruct. */) { PDLUA_DEBUG("pdlua_free: stack top %d", lua_gettop(L)); lua_getglobal(L, "pd"); lua_getfield (L, -1, "_destructor"); lua_pushlightuserdata(L, o); if (lua_pcall(L, 1, 0, 0)) { error("lua: error in destructor:\n%s", lua_tostring(L, -1)); lua_pop(L, 1); /* pop the error string */ } lua_pop(L, 1); /* pop the global "pd" */ PDLUA_DEBUG("pdlua_free: end. stack top %d", lua_gettop(L)); return; } static void pdlua_stack_dump (lua_State *L) { int i; int top = lua_gettop(L); for (i = 1; i <= top; i++) { /* repeat for each level */ int t = lua_type(L, i); switch (t) { case LUA_TSTRING: /* strings */ printf("`%s'", lua_tostring(L, i)); break; case LUA_TBOOLEAN: /* booleans */ printf(lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TNUMBER: /* numbers */ printf("%g", lua_tonumber(L, i)); break; default: /* other values */ printf("%s", lua_typename(L, t)); break; } printf(" "); /* put a separator */ } printf("\n"); /* end the listing */ } /** a handler for the open item in the right-click menu (mrpeach 20111025) */ /** Here we find the lua code for the object and open it in an editor */ static void pdlua_menu_open(t_pdlua *o) { const char *name; const char *path; char pathname[FILENAME_MAX]; t_class *class; PDLUA_DEBUG("pdlua_menu_open stack top is %d", lua_gettop(L)); /** Get the scriptname of the object */ lua_getglobal(L, "pd"); lua_getfield(L, -1, "_whoami"); lua_pushlightuserdata(L, o); if (lua_pcall(L, 1, 1, 0)) { error("lua: error in whoami:\n%s", lua_tostring(L, -1)); lua_pop(L, 2); /* pop the error string and the global "pd" */ return; } name = luaL_checkstring(L, -1); PDLUA_DEBUG3("pdlua_menu_open: L is %p, name is %s stack top is %d", L, name, lua_gettop(L)); if (name) { if (name[strlen(name)-1] == 'x') { /* pdluax is a class, the particular file should loadable by name alone, we hope */ sprintf(pathname, "%s", name); lua_pop(L, 2); /* pop name and the global "pd" */ } else { lua_getglobal(L, "pd"); lua_getfield(L, -1, "_get_class"); lua_pushlightuserdata(L, o); if (lua_pcall(L, 1, 1, 0)) { error("lua: error in get_class:\n%s", lua_tostring(L, -1)); lua_pop(L, 4); /* pop the error string, global "pd", name, global "pd"*/ return; } class = (t_class *)lua_touserdata(L, -1); path = class->c_externdir->s_name; sprintf(pathname, "%s/%s", path, name); lua_pop(L, 4); /* pop class, global "pd", name, global "pd"*/ } #if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43 post("Opening %s for editing", pathname); #else logpost(NULL, 3, "Opening %s for editing", pathname); #endif sys_vgui("::pd_menucommands::menu_openfile {%s}\n", pathname); } PDLUA_DEBUG("pdlua_menu_open end. stack top is %d", lua_gettop(L)); } /** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */ static int pdlua_class_new(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Class name string. * \par Outputs: * \li \c 1 Pd class pointer. * */ { const char *name; t_class *c; name = luaL_checkstring(L, 1); PDLUA_DEBUG3("pdlua_class_new: L is %p, name is %s stack top is %d", L, name, lua_gettop(L)); c = class_new(gensym((char *) name), (t_newmethod) pdlua_new, (t_method) pdlua_free, sizeof(t_pdlua), CLASS_NOINLET, A_GIMME, 0); /* a class with a "menu-open" method will have the "Open" item highlighted in the right-click menu */ class_addmethod(c, (t_method)pdlua_menu_open, gensym("menu-open"), A_NULL);/* (mrpeach 20111025) */ /**/ lua_pushlightuserdata(L, c); PDLUA_DEBUG("pdlua_class_new: end stack top is %d", lua_gettop(L)); return 1; } /** Lua object creation. */ static int pdlua_object_new(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd class pointer. * \par Outputs: * \li \c 2 Pd object pointer. * */ { PDLUA_DEBUG("pdlua_object_new: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_class *c = lua_touserdata(L, 1); if (c) { PDLUA_DEBUG("pdlua_object_new: path is %s", c->c_externdir->s_name); t_pdlua *o = (t_pdlua *) pd_new(c); if (o) { o->inlets = 0; o->in = NULL; o->outlets = 0; o->out = NULL; o->canvas = canvas_getcurrent(); lua_pushlightuserdata(L, o); PDLUA_DEBUG("pdlua_object_new: success end. stack top is %d", lua_gettop(L)); return 1; } } } PDLUA_DEBUG("pdlua_object_new: fail end. stack top is %d", lua_gettop(L)); return 0; } /** Lua object inlet creation. */ static int pdlua_object_createinlets(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * \li \c 2 Number of inlets. * */ { int i; PDLUA_DEBUG("pdlua_object_createinlets: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua *o = lua_touserdata(L, 1); if (o) { o->inlets = luaL_checknumber(L, 2); o->in = malloc(o->inlets * sizeof(t_pdlua_proxyinlet)); for (i = 0; i < o->inlets; ++i) { pdlua_proxyinlet_init(&o->in[i], o, i); inlet_new(&o->pd, &o->in[i].pd, 0, 0); } } } PDLUA_DEBUG("pdlua_object_createinlets: end. stack top is %d", lua_gettop(L)); return 0; } /** Lua object outlet creation. */ static int pdlua_object_createoutlets(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * \li \c 2 Number of outlets. * */ { int i; PDLUA_DEBUG("pdlua_object_createoutlets: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua *o = lua_touserdata(L, 1); if (o) { o->outlets = luaL_checknumber(L, 2); if (o->outlets > 0) { o->out = malloc(o->outlets * sizeof(t_outlet *)); for (i = 0; i < o->outlets; ++i) o->out[i] = outlet_new(&o->pd, 0); } else o->out = NULL; } } PDLUA_DEBUG("pdlua_object_createoutlets: end stack top is %d", lua_gettop(L)); return 0; } /** Lua object receive creation. */ static int pdlua_receive_new(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * \li \c 2 Receive name string. * \par Outputs: * \li \c 1 Pd receive pointer. * */ { PDLUA_DEBUG("pdlua_receive_new: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua *o = lua_touserdata(L, 1); if (o) { const char *name = luaL_checkstring(L, 2); if (name) { t_pdlua_proxyreceive *r = pdlua_proxyreceive_new(o, gensym((char *) name)); /* const cast */ lua_pushlightuserdata(L, r); PDLUA_DEBUG("pdlua_receive_new: success end. stack top is %d", lua_gettop(L)); return 1; } } } PDLUA_DEBUG("pdlua_receive_new: fail end. stack top is %d", lua_gettop(L)); return 0; } /** Lua object receive destruction. */ static int pdlua_receive_free(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd recieve pointer. * */ { PDLUA_DEBUG("pdlua_receive_free: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua_proxyreceive *r = lua_touserdata(L, 1); if (r) pdlua_proxyreceive_free(r); } PDLUA_DEBUG("pdlua_receive_free: end. stack top is %d", lua_gettop(L)); return 0; } /** Lua object clock creation. */ static int pdlua_clock_new(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * \par Outputs: * \li \c 1 Pd clock pointer. * */ { PDLUA_DEBUG("pdlua_clock_new: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua *o = lua_touserdata(L, 1); if (o) { t_pdlua_proxyclock *c = pdlua_proxyclock_new(o); lua_pushlightuserdata(L, c); PDLUA_DEBUG("pdlua_clock_new: success end. stack top is %d", lua_gettop(L)); return 1; } } PDLUA_DEBUG("pdlua_clock_new: fail end. stack top is %d", lua_gettop(L)); return 0; } /** Lua proxy clock delay. */ static int pdlua_clock_delay(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd clock pointer. * \li \c 2 Number of milliseconds to delay. * */ { PDLUA_DEBUG("pdlua_clock_delay: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua_proxyclock *c = lua_touserdata(L, 1); if (c) { double delaytime = luaL_checknumber(L, 2); clock_delay(c->clock, delaytime); } } PDLUA_DEBUG("pdlua_clock_delay: end. stack top is %d", lua_gettop(L)); return 0; } /** Lua proxy clock set. */ static int pdlua_clock_set(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd clock pointer. * \li \c 2 Number to set the clock. * */ { PDLUA_DEBUG("pdlua_clock_set: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua_proxyclock *c = lua_touserdata(L, 1); if (c) { double systime = luaL_checknumber(L, 2); clock_set(c->clock, systime); } } PDLUA_DEBUG("pdlua_clock_set: end. stack top is %d", lua_gettop(L)); return 0; } /** Lua proxy clock unset. */ static int pdlua_clock_unset(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd clock pointer. * */ { PDLUA_DEBUG("pdlua_clock_unset: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua_proxyclock *c = lua_touserdata(L, 1); if (c) clock_unset(c->clock); } PDLUA_DEBUG("pdlua_clock_unset: end. stack top is %d", lua_gettop(L)); return 0; } /** Lua proxy clock destruction. */ static int pdlua_clock_free(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd clock pointer. * */ { PDLUA_DEBUG("pdlua_clock_free: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua_proxyclock *c = lua_touserdata(L, 1); if (c) { clock_free(c->clock); free(c); } } PDLUA_DEBUG("pdlua_clock_free: end. stack top is %d", lua_gettop(L)); return 0; } /** Lua object destruction. */ static int pdlua_object_free(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * */ { int i; PDLUA_DEBUG("pdlua_object_free: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { t_pdlua *o = lua_touserdata(L, 1); if (o) { if (o->in) free(o->in); if(o->out) { for (i = 0; i < o->outlets; ++i) outlet_free(o->out[i]); free(o->out); o->out = NULL; } } } PDLUA_DEBUG("pdlua_object_free: end. stack top is %d", lua_gettop(L)); return 0; } /** Dispatch Pd inlet messages to Lua objects. */ static void pdlua_dispatch ( t_pdlua *o, /**< The object that received the message. */ unsigned int inlet, /**< The inlet that the message arrived at. */ t_symbol *s, /**< The message selector. */ int argc, /**< The message length. */ t_atom *argv /**< The atoms in the message. */ ) { PDLUA_DEBUG("pdlua_dispatch: stack top %d", lua_gettop(L)); lua_getglobal(L, "pd"); lua_getfield (L, -1, "_dispatcher"); lua_pushlightuserdata(L, o); lua_pushnumber(L, inlet + 1); /* C has 0.., Lua has 1.. */ lua_pushstring(L, s->s_name); pdlua_pushatomtable(argc, argv); if (lua_pcall(L, 4, 0, 0)) { pd_error(o, "lua: error in dispatcher:\n%s", lua_tostring(L, -1)); lua_pop(L, 1); /* pop the error string */ } lua_pop(L, 1); /* pop the global "pd" */ PDLUA_DEBUG("pdlua_dispatch: end. stack top %d", lua_gettop(L)); return; } /** Dispatch Pd receive messages to Lua objects. */ static void pdlua_receivedispatch ( t_pdlua_proxyreceive *r, /**< The proxy receive that received the message. */ t_symbol *s, /**< The message selector. */ int argc, /**< The message length. */ t_atom *argv /**< The atoms in the message. */ ) { PDLUA_DEBUG("pdlua_receivedispatch: stack top %d", lua_gettop(L)); lua_getglobal(L, "pd"); lua_getfield (L, -1, "_receivedispatch"); lua_pushlightuserdata(L, r); lua_pushstring(L, s->s_name); pdlua_pushatomtable(argc, argv); if (lua_pcall(L, 3, 0, 0)) { pd_error(r->owner, "lua: error in receive dispatcher:\n%s", lua_tostring(L, -1)); lua_pop(L, 1); /* pop the error string */ } lua_pop(L, 1); /* pop the global "pd" */ PDLUA_DEBUG("pdlua_receivedispatch: end. stack top %d", lua_gettop(L)); return; } /** Dispatch Pd clock messages to Lua objects. */ static void pdlua_clockdispatch( t_pdlua_proxyclock *clock) /**< The proxy clock that received the message. */ { PDLUA_DEBUG("pdlua_clockdispatch: stack top %d", lua_gettop(L)); lua_getglobal(L, "pd"); lua_getfield (L, -1, "_clockdispatch"); lua_pushlightuserdata(L, clock); if (lua_pcall(L, 1, 0, 0)) { pd_error(clock->owner, "lua: error in clock dispatcher:\n%s", lua_tostring(L, -1)); lua_pop(L, 1); /* pop the error string */ } lua_pop(L, 1); /* pop the global "pd" */ PDLUA_DEBUG("pdlua_clockdispatch: end. stack top %d", lua_gettop(L)); return; } /** Convert a Lua table into a Pd atom array. */ static t_atom *pdlua_popatomtable ( lua_State *L, /**< Lua interpreter state. * \par Inputs: * \li \c -1 Table to convert. * */ int *count, /**< Where to store the array length. */ t_pdlua *o /**< Object reference for error messages. */ ) { int i; int ok = 1; t_float f; const char *s; void *p; size_t sl; t_atom *atoms = NULL; PDLUA_DEBUG("pdlua_popatomtable: stack top %d", lua_gettop(L)); if (lua_istable(L, -1)) { #if LUA_VERSION_NUM < 502 *count = lua_objlen(L, -1); #else // 5.2 style *count = lua_rawlen(L, -1); #endif // LUA_VERSION_NUM < 502 if (*count > 0) atoms = malloc(*count * sizeof(t_atom)); i = 0; lua_pushnil(L); while (lua_next(L, -2) != 0) { if (i == *count) { pd_error(o, "lua: error: too many table elements"); ok = 0; break; } switch (lua_type(L, -1)) { case (LUA_TNUMBER): f = lua_tonumber(L, -1); SETFLOAT(&atoms[i], f); break; case (LUA_TSTRING): s = lua_tolstring(L, -1, &sl); if (s) { if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)"); SETSYMBOL(&atoms[i], gensym((char *) s)); } else { pd_error(o, "lua: error: null string in table"); ok = 0; } break; case (LUA_TLIGHTUSERDATA): /* FIXME: check experimentality */ p = lua_touserdata(L, -1); SETPOINTER(&atoms[i], p); break; default: pd_error(o, "lua: error: table element must be number or string or pointer"); ok = 0; break; } lua_pop(L, 1); ++i; } if (i != *count) { pd_error(o, "lua: error: too few table elements"); ok = 0; } } else { pd_error(o, "lua: error: not a table"); ok = 0; } lua_pop(L, 1); PDLUA_DEBUG("pdlua_popatomtable: end. stack top %d", lua_gettop(L)); if (ok) return atoms; if (atoms) free(atoms); return NULL; } /** Send a message from a Lua object outlet. */ static int pdlua_outlet(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * \li \c 2 Outlet number. * \li \c 3 Message selector string. * \li \c 4 Message atom table. * */ { t_pdlua *o; int out; size_t sl; const char *s; t_symbol *sym; int count; t_atom *atoms; PDLUA_DEBUG("pdlua_outlet: stack top %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { o = lua_touserdata(L, 1); if (o) { if (lua_isnumber(L, 2)) out = lua_tonumber(L, 2) - 1; /* C has 0.., Lua has 1.. */ else { pd_error(o, "lua: error: outlet must be a number"); lua_pop(L, 4); /* pop all the arguments */ return 0; } if (0 <= out && out < o->outlets) { if (lua_isstring(L, 3)) { s = lua_tolstring(L, 3, &sl); sym = gensym((char *) s); /* const cast */ if (s) { if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)"); lua_pushvalue(L, 4); atoms = pdlua_popatomtable(L, &count, o); if (count == 0 || atoms) outlet_anything(o->out[out], sym, count, atoms); else pd_error(o, "lua: error: no atoms??"); if (atoms) { free(atoms); lua_pop(L, 4); /* pop all the arguments */ return 0; } } else pd_error(o, "lua: error: null selector"); } else pd_error(o, "lua: error: selector must be a string"); } else pd_error(o, "lua: error: outlet out of range"); } else error("lua: error: no object to outlet from"); } else error("lua: error: bad arguments to outlet"); lua_pop(L, 4); /* pop all the arguments */ PDLUA_DEBUG("pdlua_outlet: end. stack top %d", lua_gettop(L)); return 0; } /** Send a message from a Lua object to a Pd receiver. */ static int pdlua_send(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Receiver string. * \li \c 2 Message selector string. * \li \c 3 Message atom table. * */ { size_t receivenamel; const char *receivename; t_symbol *receivesym; size_t selnamel; const char *selname; t_symbol *selsym; int count; t_atom *atoms; PDLUA_DEBUG("pdlua_send: stack top is %d", lua_gettop(L)); if (lua_isstring(L, 1)) { receivename = lua_tolstring(L, 1, &receivenamel); receivesym = gensym((char *) receivename); /* const cast */ if (receivesym) { if (strlen(receivename) != receivenamel) error("lua: warning: symbol munged (contains \\0 in body)"); if (lua_isstring(L, 2)) { selname = lua_tolstring(L, 2, &selnamel); selsym = gensym((char *) selname); /* const cast */ if (selsym) { if (strlen(selname) != selnamel) error("lua: warning: symbol munged (contains \\0 in body)"); lua_pushvalue(L, 3); atoms = pdlua_popatomtable(L, &count, NULL); if ((count == 0 || atoms) && (receivesym->s_thing)) typedmess(receivesym->s_thing, selsym, count, atoms); else error("lua: error: no atoms??"); if (atoms) { free(atoms); PDLUA_DEBUG("pdlua_send: success end. stack top is %d", lua_gettop(L)); return 0; } } else error("lua: error: null selector"); } else error("lua: error: selector must be a string"); } else error("lua: error: null receive name"); } else error("lua: error: receive name must be string"); PDLUA_DEBUG("pdlua_send: fail end. stack top is %d", lua_gettop(L)); return 0; } /** Set a [value] object's value. */ static int pdlua_setvalue(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Value name string. * \li \c 2 Value number. * \par Outputs: * \li \c 1 success (usually depends on a [value] existing or not). */ { const char *str = luaL_checkstring(L, 1); t_float val = luaL_checknumber(L, 2); int err = value_setfloat(gensym(str), val); PDLUA_DEBUG("pdlua_setvalue: stack top is %d", lua_gettop(L)); lua_pushboolean(L, !err); PDLUA_DEBUG("pdlua_setvalue: end. stack top is %d", lua_gettop(L)); return 1; } /** Get a [value] object's value. */ static int pdlua_getvalue(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Value name string. * \par Outputs: * \li \c 1 Value number, or nil for failure. * */ { const char *str = luaL_checkstring(L, 1); t_float val; int err = value_getfloat(gensym(str), &val); PDLUA_DEBUG("pdlua_getvalue: stack top is %d", lua_gettop(L)); if (!err) lua_pushnumber(L, val); else lua_pushnil(L); PDLUA_DEBUG("pdlua_getvalue: end. stack top is %d", lua_gettop(L)); return 1; } /** Get a [table] object's array. */ static int pdlua_getarray(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Table name string. * \par Outputs: * \li \c 1 Table length, or < 0 for failure. * \li \c 2 Table pointer, or nil for failure. * */ { t_garray *a; int n; PDLUA_ARRAYTYPE *v; const char *str = luaL_checkstring(L, 1); PDLUA_DEBUG("pdlua_getarray: stack top is %d", lua_gettop(L)); if (!(a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) { lua_pushnumber(L, -1); PDLUA_DEBUG("pdlua_getarray: end 1. stack top is %d", lua_gettop(L)); return 1; } else if (!PDLUA_ARRAYGRAB(a, &n, &v)) { lua_pushnumber(L, -2); PDLUA_DEBUG("pdlua_getarray: end 2. stack top is %d", lua_gettop(L)); return 1; } else { lua_pushnumber(L, n); lua_pushlightuserdata(L, v); PDLUA_DEBUG("pdlua_getarray: end 3. stack top is %d", lua_gettop(L)); return 2; } } /** Read from a [table] object's array. */ static int pdlua_readarray(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Table length number. * \li \c 2 Table array pointer. * \li \c 3 Table index number. * \par Outputs: * \li \c 1 Table element value, or nil for index out of range. * */ { int n = luaL_checknumber(L, 1); PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL; int i = luaL_checknumber(L, 3); PDLUA_DEBUG("pdlua_readarray: stack top is %d", lua_gettop(L)); if (0 <= i && i < n && v) { lua_pushnumber(L, PDLUA_ARRAYELEM(v, i)); PDLUA_DEBUG("pdlua_readarray: end 1. stack top is %d", lua_gettop(L)); return 1; } PDLUA_DEBUG("pdlua_readarray: end 2. stack top is %d", lua_gettop(L)); return 0; } /** Write to a [table] object's array. */ static int pdlua_writearray(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Table length number. * \li \c 2 Table array pointer. * \li \c 3 Table index number. * \li \c 4 Table element value number. * */ { int n = luaL_checknumber(L, 1); PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL; int i = luaL_checknumber(L, 3); t_float x = luaL_checknumber(L, 4); PDLUA_DEBUG("pdlua_writearray: stack top is %d", lua_gettop(L)); if (0 <= i && i < n && v) PDLUA_ARRAYELEM(v, i) = x; PDLUA_DEBUG("pdlua_writearray: end. stack top is %d", lua_gettop(L)); return 0; } /** Redraw a [table] object's graph. */ static int pdlua_redrawarray(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Table name string. * */ { t_garray *a; const char *str = luaL_checkstring(L, 1); PDLUA_DEBUG("pdlua_redrawarray: stack top is %d", lua_gettop(L)); if ((a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) garray_redraw(a); PDLUA_DEBUG("pdlua_redrawarray: end. stack top is %d", lua_gettop(L)); return 0; } /** Post to Pd's console. */ static int pdlua_post(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Message string. * */ { const char *str = luaL_checkstring(L, 1); PDLUA_DEBUG("pdlua_post: stack top is %d", lua_gettop(L)); post("%s", str); PDLUA_DEBUG("pdlua_post: end. stack top is %d", lua_gettop(L)); return 0; } /** Report an error from a Lua object to Pd's console. */ static int pdlua_error(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * \li \c 2 Message string. * */ { t_pdlua *o; const char *s; PDLUA_DEBUG("pdlua_error: stack top is %d", lua_gettop(L)); if (lua_islightuserdata(L, 1)) { o = lua_touserdata(L, 1); if (o) { s = luaL_checkstring(L, 2); if (s) pd_error(o, "%s", s); else pd_error(o, "lua: error: null string in error function"); } else error("lua: error: null object in error function"); } else error("lua: error: bad arguments to error function"); PDLUA_DEBUG("pdlua_error: end. stack top is %d", lua_gettop(L)); return 0; } static void pdlua_setrequirepath ( /* FIXME: documentation (is this of any use at all?) */ lua_State *L, const char *path ) { PDLUA_DEBUG("pdlua_setrequirepath: stack top %d", lua_gettop(L)); lua_getglobal(L, "pd"); lua_pushstring(L, "_setrequirepath"); lua_gettable(L, -2); lua_pushstring(L, path); if (lua_pcall(L, 1, 0, 0) != 0) { error("lua: internal error in `pd._setrequirepath': %s", lua_tostring(L, -1)); lua_pop(L, 1); } lua_pop(L, 1); PDLUA_DEBUG("pdlua_setrequirepath: end. stack top %d", lua_gettop(L)); } static void pdlua_clearrequirepath ( /* FIXME: documentation (is this of any use at all?) */ lua_State *L ) { PDLUA_DEBUG("pdlua_clearrequirepath: stack top %d", lua_gettop(L)); lua_getglobal(L, "pd"); lua_pushstring(L, "_clearrequirepath"); lua_gettable(L, -2); if (lua_pcall(L, 0, 0, 0) != 0) { error("lua: internal error in `pd._clearrequirepath': %s", lua_tostring(L, -1)); lua_pop(L, 1); } lua_pop(L, 1); PDLUA_DEBUG("pdlua_clearrequirepath: end. stack top %d", lua_gettop(L)); } /** Run a Lua script using Pd's path. */ static int pdlua_dofile(lua_State *L) /**< Lua interpreter state. * \par Inputs: * \li \c 1 Pd object pointer. * \li \c 2 Filename string. * \par Outputs: * \li \c * Determined by the script. * */ { char buf[MAXPDSTRING]; char *ptr; t_pdlua_readerdata reader; int fd; int n; const char *filename; t_pdlua *o; PDLUA_DEBUG("pdlua_dofile: stack top %d", lua_gettop(L)); n = lua_gettop(L); if (lua_islightuserdata(L, 1)) { o = lua_touserdata(L, 1); if (o) { filename = luaL_optstring(L, 2, NULL); fd = canvas_open(o->canvas, filename, "", buf, &ptr, MAXPDSTRING, 1); if (fd >= 0) { PDLUA_DEBUG("pdlua_dofile path is %s", buf); //pdlua_setpathname(o, buf);/* change the scriptname to include its path */ pdlua_setrequirepath(L, buf); reader.fd = fd; #if LUA_VERSION_NUM < 502 if (lua_load(L, pdlua_reader, &reader, filename)) #else // 5.2 style if (lua_load(L, pdlua_reader, &reader, filename, NULL)) #endif // LUA_VERSION_NUM < 502 { close(fd); pdlua_clearrequirepath(L); lua_error(L); } else { if (lua_pcall(L, 0, LUA_MULTRET, 0)) { pd_error(o, "lua: error running `%s':\n%s", filename, lua_tostring(L, -1)); lua_pop(L, 1); close(fd); pdlua_clearrequirepath(L); } else { /* succeeded */ close(fd); pdlua_clearrequirepath(L); } } } else pd_error(o, "lua: error loading `%s': canvas_open() failed", filename); } else error("lua: error in object:dofile() - object is null"); } else error("lua: error in object:dofile() - object is wrong type"); lua_pushstring(L, buf); /* return the path as well so we can open it later with pdlua_menu_open() */ PDLUA_DEBUG("pdlua_dofile end. stack top is %d", lua_gettop(L)); return lua_gettop(L) - n; } /** Initialize the pd API for Lua. */ static void pdlua_init(lua_State *L) /**< Lua interpreter state. */ { lua_newtable(L); lua_setglobal(L, "pd"); lua_getglobal(L, "pd"); lua_pushstring(L, "_iswindows"); #ifdef _WIN32 lua_pushboolean(L, 1); #else lua_pushboolean(L, 0); #endif // _WIN32 lua_settable(L, -3); lua_pushstring(L, "_register"); lua_pushcfunction(L, pdlua_class_new); lua_settable(L, -3); lua_pushstring(L, "_create"); lua_pushcfunction(L, pdlua_object_new); lua_settable(L, -3); lua_pushstring(L, "_createinlets"); lua_pushcfunction(L, pdlua_object_createinlets); lua_settable(L, -3); lua_pushstring(L, "_createoutlets"); lua_pushcfunction(L, pdlua_object_createoutlets); lua_settable(L, -3); lua_pushstring(L, "_destroy"); lua_pushcfunction(L, pdlua_object_free); lua_settable(L, -3); lua_pushstring(L, "_outlet"); lua_pushcfunction(L, pdlua_outlet); lua_settable(L, -3); lua_pushstring(L, "_createreceive"); lua_pushcfunction(L, pdlua_receive_new); lua_settable(L, -3); lua_pushstring(L, "_receivefree"); lua_pushcfunction(L, pdlua_receive_free); lua_settable(L, -3); lua_pushstring(L, "_createclock"); lua_pushcfunction(L, pdlua_clock_new); lua_settable(L, -3); lua_pushstring(L, "_clockfree"); lua_pushcfunction(L, pdlua_clock_free); lua_settable(L, -3); lua_pushstring(L, "_clockset"); lua_pushcfunction(L, pdlua_clock_set); lua_settable(L, -3); lua_pushstring(L, "_clockunset"); lua_pushcfunction(L, pdlua_clock_unset); lua_settable(L, -3); lua_pushstring(L, "_clockdelay"); lua_pushcfunction(L, pdlua_clock_delay); lua_settable(L, -3); lua_pushstring(L, "_dofile"); lua_pushcfunction(L, pdlua_dofile); lua_settable(L, -3); lua_pushstring(L, "send"); lua_pushcfunction(L, pdlua_send); lua_settable(L, -3); lua_pushstring(L, "getvalue"); lua_pushcfunction(L, pdlua_getvalue); lua_settable(L, -3); lua_pushstring(L, "setvalue"); lua_pushcfunction(L, pdlua_setvalue); lua_settable(L, -3); lua_pushstring(L, "_getarray"); lua_pushcfunction(L, pdlua_getarray); lua_settable(L, -3); lua_pushstring(L, "_readarray"); lua_pushcfunction(L, pdlua_readarray); lua_settable(L, -3); lua_pushstring(L, "_writearray"); lua_pushcfunction(L, pdlua_writearray); lua_settable(L, -3); lua_pushstring(L, "_redrawarray"); lua_pushcfunction(L, pdlua_redrawarray); lua_settable(L, -3); lua_pushstring(L, "post"); lua_pushcfunction(L, pdlua_post); lua_settable(L, -3); lua_pushstring(L, "_error"); lua_pushcfunction(L, pdlua_error); lua_settable(L, -3); lua_pop(L, 1); PDLUA_DEBUG("pdlua_init: end. stack top is %d", lua_gettop(L)); } /** Pd loader hook for loading and executing Lua scripts. */ static int pdlua_loader_fromfd ( int fd, /**< file-descriptor of .pd_lua file */ const char *name, /**< The name of the script (without .pd_lua extension). */ const char *dirbuf /**< The name of the directory the .pd_lua files lives in */ ) { t_pdlua_readerdata reader; PDLUA_DEBUG("pdlua_loader: stack top %d", lua_gettop(L)); class_set_extern_dir(gensym(dirbuf)); pdlua_setrequirepath(L, dirbuf); reader.fd = fd; #if LUA_VERSION_NUM < 502 if (lua_load(L, pdlua_reader, &reader, name) || lua_pcall(L, 0, 0, 0)) #else // 5.2 style if (lua_load(L, pdlua_reader, &reader, name, NULL) || lua_pcall(L, 0, 0, 0)) #endif // LUA_VERSION_NUM < 502 { error("lua: error loading `%s':\n%s", name, lua_tostring(L, -1)); lua_pop(L, 1); pdlua_clearrequirepath(L); class_set_extern_dir(&s_); PDLUA_DEBUG("pdlua_loader: script error end. stack top %d", lua_gettop(L)); return 0; } pdlua_clearrequirepath(L); class_set_extern_dir(&s_); PDLUA_DEBUG("pdlua_loader: end. stack top %d", lua_gettop(L)); return 1; } static int pdlua_loader_legacy ( t_canvas *canvas, /**< Pd canvas to use to find the script. */ char *name /**< The name of the script (without .pd_lua extension). */ ) { char dirbuf[MAXPDSTRING]; char *ptr; int fd; int result = 0; fd = canvas_open(canvas, name, ".pd_lua", dirbuf, &ptr, MAXPDSTRING, 1); if (fd>=0) { result=pdlua_loader_fromfd(fd, name, dirbuf); sys_close(fd); } return result; } static int pdlua_loader_pathwise ( t_canvas *canvas, /**< Pd canvas to use to find the script. */ const char *objectname, /**< The name of the script (without .pd_lua extension). */ const char *path /**< The directory to search for the script */ ) { char dirbuf[MAXPDSTRING]; char *ptr; int fd; int result = 0; if(!path) { /* we already tried all paths, so skip this */ return 0; } fd = sys_trytoopenone(path, objectname, ".pd_lua", dirbuf, &ptr, MAXPDSTRING, 1); /* TODO: try loading /.pd_lua */ if (fd>=0) { result=pdlua_loader_fromfd(fd, objectname, dirbuf); sys_close(fd); } return result; } /** Start the Lua runtime and register our loader hook. */ #ifdef _WIN32 __declspec(dllexport) #endif void pdlua_setup(void) { char pd_lua_path[MAXPDSTRING]; t_pdlua_readerdata reader; int fd; int result; char* pdluaver = "pdlua 0.7.3 (GPL) 2014-2016 Martin Peach et al., based on"; char* luaver = "lua 0.6~svn (GPL) 2008 Claude Heiland-Allen "; char compiled[MAXPDSTRING]; char luaversionStr[MAXPDSTRING]; const lua_Number *luaversion = lua_version (NULL); int lvm, lvl; #ifndef BUILD_DATE # define BUILD_DATE __DATE__" "__TIME__ #endif snprintf(compiled, MAXPDSTRING-1, "pdlua: compiled for pd-%d.%d on %s", PD_MAJOR_VERSION, PD_MINOR_VERSION, BUILD_DATE); lvm = (*luaversion)/100; lvl = (*luaversion) - (100*lvm); snprintf(luaversionStr, MAXPDSTRING-1, "Using lua version %d.%d", lvm, lvl); #if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43 post(pdluaver); post(luaver); post(compiled); post(luaversionStr); #else logpost(NULL, 3, pdluaver); logpost(NULL, 3, luaver); logpost(NULL, 3, compiled); logpost(NULL, 3, luaversionStr); #endif pdlua_proxyinlet_setup(); PDLUA_DEBUG("pdlua pdlua_proxyinlet_setup done", 0); pdlua_proxyreceive_setup(); PDLUA_DEBUG("pdlua pdlua_proxyreceive_setup done", 0); pdlua_proxyclock_setup(); PDLUA_DEBUG("pdlua pdlua_proxyclock_setup done", 0); #if LUA_VERSION_NUM < 502 L = lua_open(); #else // 5.2 style L = luaL_newstate(); #endif // LUA_VERSION_NUM < 502 PDLUA_DEBUG("pdlua lua_open done L = %p", L); luaL_openlibs(L); PDLUA_DEBUG("pdlua luaL_openlibs done", 0); pdlua_init(L); PDLUA_DEBUG("pdlua pdlua_init done", 0); /* "pd.lua" is the Lua part of pdlua, want to keep the C part minimal */ /* canvas_open can't find pd.lua unless we give the path to pd beforehand like pd -path /usr/lib/extra/pdlua */ /* To avoid this we can use c_externdir from m_imp.h, struct _class: t_symbol *c_externdir; */ /* c_externdir is the directory the extern was loaded from and is also the directory contining pd.lua */ sprintf(pd_lua_path, "%s/pd.lua", pdlua_proxyinlet_class->c_externdir->s_name); /* the full path to pd.lua */ PDLUA_DEBUG("pd_lua_path %s", pd_lua_path); fd = open(pd_lua_path, O_RDONLY); /* fd = canvas_open(canvas_getcurrent(), "pd", ".lua", buf, &ptr, MAXPDSTRING, 1); looks all over and rarely succeeds */ PDLUA_DEBUG ("pd.lua loaded from %s", pd_lua_path); PDLUA_DEBUG("pdlua canvas_open done fd = %d", fd); PDLUA_DEBUG("pdlua_setup: stack top %d", lua_gettop(L)); if (fd >= 0) { /* pd.lua was opened */ reader.fd = fd; #if LUA_VERSION_NUM < 502 result = lua_load(L, pdlua_reader, &reader, "pd.lua"); #else // 5.2 style result = lua_load(L, pdlua_reader, &reader, "pd.lua", NULL); // mode bt for binary or text #endif // LUA_VERSION_NUM < 502 PDLUA_DEBUG ("pdlua lua_load returned %d", result); if (0 == result) { result = lua_pcall(L, 0, 0, 0); PDLUA_DEBUG ("pdlua lua_pcall returned %d", result); } if (0 != result) //if (lua_load(L, pdlua_reader, &reader, "pd.lua") || lua_pcall(L, 0, 0, 0)) { error("lua: error loading `pd.lua':\n%s", lua_tostring(L, -1)); error("lua: loader will not be registered!"); error("lua: (is `pd.lua' in Pd's path list?)"); lua_pop(L, 1); } else { int maj=0,min=0,bug=0; sys_getversion(&maj,&min,&bug); if((maj==0) && (min<47)) /* before Pd<0.47, the loaders had to iterate over each path themselves */ sys_register_loader((loader_t)pdlua_loader_legacy); else /* since Pd>=0.47, Pd tries the loaders for each path */ sys_register_loader((loader_t)pdlua_loader_pathwise); } close(fd); } else { error("lua: error loading `pd.lua': canvas_open() failed"); error("lua: loader will not be registered!"); } PDLUA_DEBUG("pdlua_setup: end. stack top %d", lua_gettop(L)); } /* EOF */ pdlua-0.7.3/pdlua-meta.pd0000644000175000017500000000057712651233016015446 0ustar zmoelnigzmoelnig#N canvas 10 10 200 200 10; #N canvas 360 159 420 300 META 0; #X text 10 10 META this is a prototype of a libdir meta file; #X text 10 30 NAME pdlua; #X text 10 50 LICENSE GNU GPL; #X text 10 70 DESCRIPTION lua loader for pd; #X text 10 90 AUTHOR Claude Heiland-Allen \, Frank Barknecht \, Martin Peach \, IOhannes m zmölnig; #X text 10 110 VERSION 0.7.3; #X restore 10 20 pd META; pdlua-0.7.3/COPYING0000644000175000017500000004313311674625145014132 0ustar zmoelnigzmoelnig GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pdlua-0.7.3/pdluax-help.pd0000644000175000017500000000650311674625145015647 0ustar zmoelnigzmoelnig#N canvas 15 212 532 190 10; #X obj 134 144 hello; #X text 31 122 See also:; #X obj 33 88 pdluax hello; #X obj 123 88 pdluax hello; #X obj 213 88 pdluax hello; #X obj 303 88 pdluax hello; #X obj 88 144 pdlua; #X text 31 16 [pdluax foo] loads the source file "foo.pd_luax" on each object creation. Less efficient than the loader ([foo] loads "foo.pd_lua" just once for all time) but more flexible when developing or live-coding. ; #N canvas 9 90 607 714 pdluax_HOWTO 0; #X obj 16 4 cnv 15 600 100 empty empty pdluax_HOWTO 20 12 0 14 -261682 -66577 0; #X obj 16 105 cnv 15 600 140 empty empty Advantages 20 12 0 14 -204786 -66577 0; #X obj 16 246 cnv 15 600 200 empty empty Disadvantages 20 12 0 14 -204800 -66577 0; #X obj 17 448 cnv 15 600 470 empty empty How_To_Write_Code_For_pdluax 20 12 0 14 -203904 -66577 0; #X text 32 34 The pdluax class allows "volatile" loading of Lua source code files that define Pd object behaviour.; #X text 32 69 The [pdluax foo] object loads "foo.pd_luax" at object creation time.; #X text 32 127 + You can edit "foo.pd_luax" and new [pdluax foo] objects will reflect the changes in the file.; #X text 32 163 + Good for rapid development/testing cycles.; #X text 32 185 + Good for live coding.; #X text 32 206 + No need to restart Pd if you made a little mistake. ; #X text 32 273 - Reloading the file each time is slower.; #X text 32 293 - Syntax is different to the syntax expected by the Lua loader (see below for discussion).; #X text 32 326 - There is no "reload" functionality \, so you can have multiple objects called [pdluax foo] but that have different behaviours. ; #X text 32 368 - Data shared between objects must be accessible globally. ; #X text 32 387 - The above two points mean some mistakes/changes mean you have to restart Pd anyway.; #X text 32 473 The last expression/statement in the file should be of the form:; #X obj 60 520 cnv 15 400 60 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 72 524 return function (self \, sel \, atoms); #X text 74 541 -- code here; #X text 73 561 end; #X text 32 585 This function is executed in the context of the 'initialize' method of the pdluax class \, and has the same arguments:; #X text 71 628 'self' is the object to be created.; #X text 70 645 'sel' is the name of the class.; #X text 70 663 'atoms' are the creation arguments.; #X obj 60 730 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 75 731 function self:in_1_float(f) ... end; #X obj 60 780 cnv 15 400 20 empty empty empty 20 12 0 14 -204786 -66577 0; #X text 61 753 or:; #X text 75 781 self.in_1_float = function(self \, f) ... end; #X text 31 805 If using the second form \, remember the self argument. ; #X text 31 830 If you need a shared state between objects \, you need to use a global name. Try to pick something unique to avoid conflicts with other scripts. You also need to ensure that you don't clobber this state - remember the script can be executed more than once.; #X obj 12 36 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 12 924 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X text 33 931 by mrpeach 2011/10/06; #X text 33 918 modified from doc/examples/pdlua/luax.txt; #X text 31 684 To add methods to the new object you need to add code _inside_ the returned function. There are two syntaxes for this:; #X connect 31 0 32 0; #X restore 228 120 pd pdluax_HOWTO; pdlua-0.7.3/hello.pd_lua0000644000175000017500000000033511674625145015365 0ustar zmoelnigzmoelnigpd.post("Hello, universe!") local Hello = pd.Class:new():register("hello") function Hello:initialize(name, atoms) pd.post("Hello, world!") return true end function Hello:finalize() pd.post("Bye bye, world!") end pdlua-0.7.3/hello.pd_luax0000644000175000017500000000011711674625145015553 0ustar zmoelnigzmoelnigreturn function(self, sel, atoms) pd.post("Hello, world!") return true end pdlua-0.7.3/examples/0000755000175000017500000000000012651233745014706 5ustar zmoelnigzmoelnigpdlua-0.7.3/examples/complex.pd_luax0000644000175000017500000000032111674625145017732 0ustar zmoelnigzmoelnigrequire("complex") return function (self, sel, atoms) for k,v in pairs(complex) do pd.post("complex." .. tostring(k) .. " = " .. tostring(v)) end self.inlets = 0 self.outlets = 0 return true end pdlua-0.7.3/examples/ldelay-help.pd0000644000175000017500000000102411674625145017433 0ustar zmoelnigzmoelnig#N canvas 0 0 450 300 10; #X obj 187 150 ldelay 1000; #X msg 259 89 500; #X msg 272 112 1000; #X msg 197 107 1500; #X obj 187 76 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 187 199 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 139 108 stop; #X text 17 17 Reimplementation of [delay] in Lua to prove clocks work... ; #X obj 351 265 delay 1000; #X text 278 266 see also:; #X connect 0 0 5 0; #X connect 1 0 0 1; #X connect 2 0 0 1; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 6 0 0 0; pdlua-0.7.3/examples/reverb.pd0000644000175000017500000000655011674625145016531 0ustar zmoelnigzmoelnig#N canvas 0 0 690 613 10; #X obj 388 33 inlet~; #X obj 448 33 inlet~; #X obj 399 215 outlet~; #X obj 459 215 outlet~; #X obj 13 53 delread~ \$0-A 29.4118; #X obj 32 73 delread~ \$0-B 23.5294; #X obj 121 94 delread~ \$0-C 18.3734; #X obj 138 113 delread~ \$0-D 17.6471; #X obj 205 51 delread~ \$0-E 15.1322; #X obj 223 73 delread~ \$0-F 14.1176; #X obj 311 96 delread~ \$0-G 12.7274; #X obj 327 118 delread~ \$0-H 12.4706; #X obj 204 221 +~; #X obj 310 222 +~; #X obj 246 221 -~; #X obj 350 221 -~; #X obj 203 277 +~; #X obj 247 278 +~; #X obj 291 279 -~; #X obj 330 279 -~; #X obj 14 221 +~; #X obj 120 222 +~; #X obj 56 221 -~; #X obj 160 221 -~; #X obj 13 277 +~; #X obj 57 278 +~; #X obj 101 279 -~; #X obj 141 278 -~; #X obj 272 349 -~; #X obj 311 349 -~; #X obj 13 347 +~; #X obj 57 348 +~; #X obj 101 349 +~; #X obj 141 348 +~; #X obj 184 347 -~; #X obj 228 348 -~; #X obj 587 53 clip 0 100; #X obj 512 339 / 282.843; #X obj 13 397 *~ 0; #X obj 57 398 *~ 0; #X obj 101 399 *~ 0; #X obj 141 398 *~ 0; #X obj 184 397 *~ 0; #X obj 228 398 *~ 0; #X obj 272 399 *~ 0; #X obj 311 399 *~ 0; #X obj 587 31 inlet; #X obj 310 174 +~; #X obj 341 175 +~; #X obj 540 28 inlet; #X obj 125 20 unpack f f f f f f f f; #X obj 13 435 delwrite~ \$0-A 1000; #X obj 23 455 delwrite~ \$0-B 1000; #X obj 33 475 delwrite~ \$0-C 1000; #X obj 43 495 delwrite~ \$0-D 1000; #X obj 53 515 delwrite~ \$0-E 1000; #X obj 63 535 delwrite~ \$0-F 1000; #X obj 73 555 delwrite~ \$0-G 1000; #X obj 83 575 delwrite~ \$0-H 1000; #X connect 0 0 47 1; #X connect 1 0 48 1; #X connect 4 0 20 0; #X connect 4 0 22 0; #X connect 5 0 20 1; #X connect 5 0 22 1; #X connect 6 0 21 0; #X connect 6 0 23 0; #X connect 7 0 21 1; #X connect 7 0 23 1; #X connect 8 0 12 0; #X connect 8 0 14 0; #X connect 9 0 12 1; #X connect 9 0 14 1; #X connect 10 0 47 0; #X connect 11 0 48 0; #X connect 12 0 16 0; #X connect 12 0 18 0; #X connect 13 0 18 1; #X connect 13 0 16 1; #X connect 14 0 17 0; #X connect 14 0 19 0; #X connect 15 0 17 1; #X connect 15 0 19 1; #X connect 16 0 30 1; #X connect 16 0 34 1; #X connect 17 0 31 1; #X connect 17 0 35 1; #X connect 18 0 32 1; #X connect 18 0 28 1; #X connect 19 0 33 1; #X connect 19 0 29 1; #X connect 20 0 24 0; #X connect 20 0 26 0; #X connect 21 0 26 1; #X connect 21 0 24 1; #X connect 22 0 25 0; #X connect 22 0 27 0; #X connect 23 0 25 1; #X connect 23 0 27 1; #X connect 24 0 30 0; #X connect 24 0 34 0; #X connect 25 0 31 0; #X connect 25 0 35 0; #X connect 26 0 32 0; #X connect 26 0 28 0; #X connect 27 0 33 0; #X connect 27 0 29 0; #X connect 28 0 44 0; #X connect 29 0 45 0; #X connect 30 0 38 0; #X connect 31 0 39 0; #X connect 32 0 40 0; #X connect 33 0 41 0; #X connect 34 0 42 0; #X connect 35 0 43 0; #X connect 36 0 37 0; #X connect 37 0 45 1; #X connect 37 0 44 1; #X connect 37 0 43 1; #X connect 37 0 42 1; #X connect 37 0 41 1; #X connect 37 0 40 1; #X connect 37 0 39 1; #X connect 37 0 38 1; #X connect 38 0 51 0; #X connect 39 0 52 0; #X connect 40 0 53 0; #X connect 41 0 54 0; #X connect 42 0 55 0; #X connect 43 0 56 0; #X connect 44 0 57 0; #X connect 45 0 58 0; #X connect 46 0 36 0; #X connect 47 0 2 0; #X connect 47 0 13 0; #X connect 47 0 15 0; #X connect 48 0 3 0; #X connect 48 0 15 1; #X connect 48 0 13 1; #X connect 49 0 50 0; #X connect 50 0 4 0; #X connect 50 1 5 0; #X connect 50 2 6 0; #X connect 50 3 7 0; #X connect 50 4 8 0; #X connect 50 5 9 0; #X connect 50 6 10 0; #X connect 50 7 11 0; pdlua-0.7.3/examples/shared.pd_lua0000644000175000017500000000156011674625145017347 0ustar zmoelnigzmoelniglocal Shared = pd.Class:new():register("shared") local sharedStore = { } function Shared:initialize(sel, atoms) if type(atoms[1]) == "string" then if sharedStore[atoms[1]] == nil then sharedStore[atoms[1]] = { sel = "bang", msg = { }, count = 1 } else sharedStore[atoms[1]].count = sharedStore[atoms[1]].count + 1 end self.name = atoms[1] self.inlets = 2 self.outlets = 1 return true else return false end end function Shared:in_1_bang() self:outlet(1, sharedStore[self.name].sel, sharedStore[self.name].msg) end function Shared:in_2(s, m) local c = sharedStore[self.name].count sharedStore[self.name] = { sel = s, msg = m, count = c } end function Shared:finalize() sharedStore[self.name].count = sharedStore[self.name].count - 1 if sharedStore[self.name].count == 0 then sharedStore[self.name] = nil end end pdlua-0.7.3/examples/peekbag.pd_lua0000644000175000017500000000266212363413060017466 0ustar zmoelnigzmoelnig-- contributed by Frank Barknecht local PeekBag = pd.Class:new():register("peekbag") function PeekBag:initialize(name, atoms) self.inlets = 2 self.outlets = 1 self.bag = {} self.add = false return true end function PeekBag:in_1_float(f) if self.add then table.insert(self.bag, f) else -- for i=table.getn(self.bag),1,-1 do for i = #(self.bag), 1, -1 do if self.bag[i]==f then table.remove(self.bag, i) break end end end end function PeekBag:in_1_list(l) if type(l[2]) == "number" then self:in_2_float(l[2]) end if type(l[1]) == "number" then self:in_1_float(l[1]) end end function PeekBag:in_1_clear(l) self.bag = {} self.add = false end function PeekBag:in_1_flush(l) self:in_1_bang() self:in_1_clear() end function PeekBag:in_2_float(f) if f == 0 then self.add = false else self.add = true end end function PeekBag:in_1_bang() -- print all values of array for i,v in ipairs(self.bag) do self:outlet(1, "float", {v}) end end function PeekBag:in_1_aslist() -- print all values of array as list -- if table.getn(self.bag) == 1 then if #(self.bag) == 1 then self:outlet(1, "float", {self.bag[1]}) -- elseif table.getn(self.bag) > 1 then elseif #(self.bag) > 1 then self:outlet(1, "list", self.bag) end end pdlua-0.7.3/examples/llist-rdrip.pd_lua0000644000175000017500000000220511754221357020337 0ustar zmoelnigzmoelnig--[[ llist-rdrip Output a list as a sequence of elements in reverse order author Martin Peach 20120419 --]] -- Pd class local LlistRdrip = pd.Class:new():register("llist-rdrip") local selectormap = {string = "symbol", number="float", userdata="pointer"} -- for lua/Pd type conversion function LlistRdrip:initialize(name, atoms) self.inlets = 1 self.outlets = 1 return true end function LlistRdrip:in_1(sel, atoms) -- anything --pd.post("sel is " .. sel); --pd.post("number of atoms is ".. #atoms) --for i,v in ipairs(atoms) do -- pd.post(i .. " = " .. v) --end if sel == "list" then -- the usual case for i = #atoms, 1, -1 do -- map lua types to pd selectors self:outlet(1, selectormap[type(atoms[i])], {atoms[i]}) end elseif sel == "float" or sel == "symbol" or sel == "pointer" or sel == "bang" then -- single element "lists" self:outlet(1, sel, {atoms[1]}) else -- messages are lists beginning with a selector self:outlet(1, selectormap[type(sel)], {sel}) for i = #atoms , 1 , -1 do self:outlet(1, selectormap[type(atoms[i])], {atoms[i]}) end end end -- end of llist-rdrip pdlua-0.7.3/examples/list-unpack.pd_lua0000644000175000017500000000303112363413052020312 0ustar zmoelnigzmoelnig--[[ list-unpack Like [unpack] for any kind of type. Argument specifies number of outlets. pointers untested rsp. not supported. --Written by Frank Barknecht --Fixed for pdlua-0.2svn by Clahde Heiland-Allen --]] -- Some footils -- -- outlet selectors local selectors = {"float", "list", "symbol", "bang", "pointer"} -- check if item x is in table t: local function contains(t, x) for _,v in ipairs(t) do if v == x then return true end end return false end -- Pd class local ListUnpack = pd.Class:new():register("list-unpack") function ListUnpack:initialize(name, atoms) self.inlets = 1 if atoms[1] == nil then self.outlets = 1 return true elseif type(atoms[1]) == "number" and atoms[1] >= 0 then self.outlets = math.max(atoms[1], 1) return true else pd.post("list-unpack: First arg must be a positive float or empty") return false end end function ListUnpack:Outlet(num, atom) -- a better outlet: automatically selects selector -- map lua types to pd selectors local selectormap = {string = "symbol", number="float", userdata="pointer"} self:outlet(num, selectormap[type(atom)], {atom}) end function ListUnpack:in_1(sel, atoms) if not contains(selectors, sel) then -- also unpack selector of anythings table.insert(atoms, 1, sel) end -- local size = math.min(self.outlets, table.getn(atoms)) local size = math.min(self.outlets, #(atoms)) for i=size, 1, -1 do self:Outlet(i, atoms[i]) end end pdlua-0.7.3/examples/lexpr.pd_lua0000644000175000017500000000716311674625145017240 0ustar zmoelnigzmoelniglocal lexpr = pd.Class:new():register("lexpr") local function sandbox(e, f) -- only supports nullary f() with one return local g = getfenv(f) setfenv(f, e) local r = f() setfenv(f, g) return r end local lexpr_globals = { abs = math.abs, acos = math.acos, asin = math.asin, atan = math.atan, atan2 = math.atan2, ceil = math.ceil, cos = math.cos, cosh = math.cosh, deg = math.deg, exp = math.exp, floor = math.floor, fmod = math.fmod, log = math.log, log10 = math.log10, max = math.max, min = math.min, int = function (x) i,f = math.modf(x) ; return i end, wrap = function (x) i,f = math.modf(x) ; return f end, pi = math.pi, pow = math.pow, rad = math.rad, sin = math.sin, sinh = math.sinh, sqrt = math.sqrt, tan = math.tan, tanh = math.tanh, val = function (s) return (pd.getvalue(s) or 0) end, choose = function (b,t,f) if b then return t else return f end end } function lexpr:readexpr(atoms) local vname = { } local context = { } local expr local i local k local v local j = 1 local inlets local f local phase = "vars" for k,v in pairs(lexpr_globals) do context[k] = v end for i,v in ipairs(atoms) do if phase == "vars" then -- create variables if v == "->" then inlets = i - 1 phase = "expr" expr = "" else if type(v) == "string" then vname[j] = v context[v] = 0 j = j + 1 else self:error("lexpr: variable names must be symbols") return -1 end end else if phase == "expr" then -- build string expr = expr .. " " .. v else self:error("lexpr: internal error parsing expression") return -1 end end end f = assert(loadstring("return {" .. expr .. " }")) local outlets = #(sandbox(context, f)) return inlets, vname, context, f, outlets end function lexpr:initialize(sel, atoms) self.vname = { } self.context = { } self.hot = { } self.f = function () return 0 end function self:in_1_bang() local r = sandbox(self.context, self.f) local i for i = self.outlets,1,-1 do if type(r[i]) == "number" then self:outlet(i, "float", { r[i] }) else if type(r[i]) == "string" then self:outlet(i, "symbol", { r[i] }) else self:error("calculated a " .. type(r[i]) .. " but expected a number or a string") end end end end function self:in_n_float(i, f) self.context[self.vname[i]] = f if self.hot[i] then self:in_1_bang() end end function self:in_n_symbol(i, s) self.context[self.vname[i]] = s if self.hot[i] then self:in_1_bang() end end function self:in_n_hot(i, atoms) if type(atoms[1]) == "number" then self.hot[i] = atoms[1] ~= 0 else self:error("hot method expects a float") end end function self:in_1_lexpr(atoms) local inlets local vname local context local f local outlets inlets, vname, context, f, outlets = self:readexpr(atoms) if (inlets == self.inlets) and (outlets == self.outlets) then self.vname = vname self.context = context self.f = f else self:error("new expression has different inlet/outlet count") end end self.inlets, self.vname, self.context, self.f, self.outlets = self:readexpr(atoms) if self.inlets < 1 then pd.post("lexpr: error: would have no inlets") return false end if self.outlets < 1 then pd.post("lexpr: error: would have no outlets") return false end for i = 1,self.inlets,1 do self.hot[i] = i == 1 end return true end pdlua-0.7.3/examples/peekbag-help.pd0000644000175000017500000000253511674625145017567 0ustar zmoelnigzmoelnig#N canvas 229 223 555 414 10; #X msg 96 243 60 64; #X msg 147 243 60 0; #X msg 191 243 62 64; #X msg 238 243 62 0; #X obj 96 370 print; #X text 141 371 Output is in the printout window.; #X msg 238 289 clear; #X text 148 26 - COLLECTION OF NUMBERS; #X text 32 94 The bag object takes (value \, flag) pairs. If the flag is true (nonzero) \, the value is added to the collection \; if false \, it's removed. The collection may have many copies of the same value. You can output the collection (and empty it) with a "flush" message \, or just empty it with "clear." You can use this to mimic a sustain pedal \, for example.; #X msg 237 266 flush; #X text 287 243 <-- add or delete elements; #X text 291 266 <-- output them; #X text 293 290 <-- start over; #X obj 96 340 peekbag; #X obj 65 309 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 86 27 peekbag; #X text 81 64 like; #X obj 124 64 bag; #X text 159 64 but with a bang for taking a peek.; #X msg 237 309 aslist; #X text 295 311 <-- get elements in a single list.; #X text 33 177 Use a "bang" to take a peek at the bag's content without clearing it \, use "aslist" to get the bag's elements in a single list. ; #X connect 0 0 13 0; #X connect 1 0 13 0; #X connect 2 0 13 0; #X connect 3 0 13 0; #X connect 6 0 13 0; #X connect 9 0 13 0; #X connect 13 0 4 0; #X connect 14 0 13 0; #X connect 19 0 13 0; pdlua-0.7.3/examples/lfloat2bytes.pd_lua0000644000175000017500000000267711754221357020521 0ustar zmoelnigzmoelnig--[[ lfloat2bytes Output a float as a sequence of bytes author Martin Peach 20120420 --]] -- Pd class local lfloat2bytes = pd.Class:new():register("lfloat2bytes") local digitstr = "%g" -- defaut format string gives up to 6 significant digits function lfloat2bytes:initialize(name, atoms) self.inlets = 1 self.outlets = 1 if (#atoms > 0) then --pd.post(#atoms .. " args") --pd.post("atom 1: " .. atoms[1]) --pd.post(type(atoms[1])) if (type(atoms[1]) ~= "number") then self:error("lfloat2bytes: Digit count not a number") elseif (atoms[1] > 0) and (atoms[1] <= 24) then digitstr = "%0." .. atoms[1] .. "g" else self:error("lfloat2bytes: Digit count out of range") end end return true end -- lfloat2bytes:drip: output characters from buf as floats on [0..255] function lfloat2bytes:drip(buf) --pd.post(buf.. " size " .. #buf) local i = 1, b local len = #buf for i = 1, len do self:outlet(1, "float", {string.byte(buf, i)}) end end function lfloat2bytes:in_1(sel, atoms) -- anything --pd.post("sel is " .. sel); --pd.post("number of atoms is ".. #atoms) --for i,v in ipairs(atoms) do -- pd.post(i .. " = " .. v) --end local buf if sel == "float" then -- the usual case --buf = tostring(atoms[1]) buf = string.format(digitstr, atoms[1]) self:drip(buf) else -- reject non-floats self:error("lfloat2bytes: input not a float") end end -- end of lfloat2bytes pdlua-0.7.3/examples/lreceive-help.pd0000644000175000017500000000117211674625145017763 0ustar zmoelnigzmoelnig#N canvas 0 0 540 307 10; #X obj 27 41 lreceive lreceive- 25 10; #X obj 27 76 print lreceive-LEFT; #X obj 190 76 print lreceive-RIGHT; #X obj 26 252 send lreceive-25; #X msg 26 196 foo bar 1 2 3; #X msg 146 196 123 bar 1 2 3; #X obj 146 252 send lreceive-27; #X obj 272 252 send; #X floatatom 295 204 5 24 35 2 n - -; #X obj 295 226 makefilename lreceive-%d; #X symbolatom 272 171 10 0 0 0 - - -; #X obj 272 143 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X connect 0 0 1 0; #X connect 0 1 2 0; #X connect 4 0 3 0; #X connect 5 0 6 0; #X connect 8 0 9 0; #X connect 9 0 7 1; #X connect 10 0 7 0; #X connect 11 0 10 0; pdlua-0.7.3/examples/list-unpack-test-gem.pd0000644000175000017500000000074411725437660021220 0ustar zmoelnigzmoelnig#N canvas 67 452 450 300 10; #X declare -lib Gem; #X obj 22 42 gemhead; #X obj 222 124 gemwin; #X msg 266 46 create; #X msg 274 76 destroy; #X obj 222 46 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 22 70 list-unpack 3; #X obj 108 102 print gem3; #X obj 65 123 print gem2; #X obj 22 143 print gem1; #X obj 144 203 import Gem; #X connect 0 0 5 0; #X connect 2 0 1 0; #X connect 3 0 1 0; #X connect 4 0 1 0; #X connect 5 0 8 0; #X connect 5 1 7 0; #X connect 5 2 6 0; pdlua-0.7.3/examples/ltabdump.pd_lua0000644000175000017500000000147011674625145017711 0ustar zmoelnigzmoelniglocal LTabDump = pd.Class:new():register("ltabdump") function LTabDump:initialize(sel, atoms) self.inlets = 1 self.outlets = 2 if type(atoms[1]) == "string" then self.name = atoms[1] else self.name = nil end return true end -- output table length and data function LTabDump:in_1_bang() -- need to sync each time before accessing if ... -- ... control-flow has gone outside of our scope local t = pd.Table:new():sync(self.name) if t ~= nil then local l = t:length() local a = { } local i for i = 1,l do a[i] = t:get(i-1) end -- copied above before outlet() to avoid race condition self:outlet(2, "float", { l }) self:outlet(1, "list", a) end end -- choose a table name, then output function LTabDump:in_1_symbol(s) self.name = s self:in_1_bang() end pdlua-0.7.3/examples/requirer.pd_lua0000644000175000017500000000114011725437660017731 0ustar zmoelnigzmoelniglocal R = pd.Class:new():register("requirer") function R:initialize(sel, atoms) if type(atoms[1]) ~= "string" then pd.post(self._name .. ": Missing module name") return false end pd.post (self._name .. ": Looking for " .. atoms[1]) require(atoms[1]) -- load the module if _G[atoms[1]] == nil then pd.post (self._name .. ": No such module (" .. atoms[1] .. ")") else -- print out module contents for k,v in pairs(_G[atoms[1]]) do pd.post(atoms[1].. "." .. tostring(k) .. " = " .. tostring(v)) end end self.inlets = 0 self.outlets = 0 return true end pdlua-0.7.3/examples/reverb-calculator.pd_lua0000644000175000017500000000245511674625145021521 0ustar zmoelnigzmoelniglocal R = pd.Class:new():register("reverb-calculator") function R:initialize(sel, atoms) if type(atoms[1]) ~= "number" then return false end self.count = math.max(atoms[1], 1) self.inlets = 1 self.outlets = 1 return true end local gcd = function(m, n) while m ~= 0 do m, n = math.mod(n, m), m end return n end function R:fundamental(nx, ny, nz) if (nx == 0 and ny == 0 and nz == 0) then return false end if (nx == 0 and ny == 0 and nz == 1) then return true end if (nx == 0 and ny == 1 and nz == 0) then return true end if (nx == 1 and ny == 0 and nz == 0) then return true end return gcd(gcd(nx, ny), nz) == 1 end function R:delay(lx, ly, lz, nx, ny, nz) return 1000 / ((340/2) * math.sqrt((nx*nx)/(lx*lx)+(ny*ny)/(ly*ly)+(nz*nz)/(lz*lz))) end function R:in_1_list(atoms) local lx = atoms[1] local ly = atoms[2] local lz = atoms[3] local delays = { } for nx = 0, 16 do for ny = 0, 16 do for nz = 0, 16 do if self:fundamental(nx, ny, nz) then table.insert(delays, self:delay(lx, ly, lz, nx, ny, nz)) end end end end table.sort(delays, function (a, b) return a > b end) local out = { } local j = 1 for i = 1, self.count do out[i] = delays[j] repeat j = j + 1 until delays[j] ~= delays[j-1] end self:outlet(1, "list", out) end pdlua-0.7.3/examples/requirer-help.pd0000644000175000017500000000107711725437660020027 0ustar zmoelnigzmoelnig#N canvas 592 156 450 300 10; #X obj 144 118 requirer complex; #X obj 146 173 requirer sqlite3; #X text 57 27 This should find the package next to the .pd_lua?; #X text 57 54 Or should it look next to the containing .pd patch?; #X text 56 142 This only "works" because of a dirty dirty hack...; #X text 52 242 TODO: some kind of "my location" necessary for .pd_lua scripts to access?; #X text 45 90 If it fails a list of paths searched will appear in the Pd console.; #X obj 56 220 requirer string; #X text 155 220 built-in modules are found OK; #X obj 57 200 requirer math; pdlua-0.7.3/examples/llist-drip-help.pd0000644000175000017500000000221111743054211020226 0ustar zmoelnigzmoelnig#N canvas 390 515 588 334 10; #X declare -lib pdlua; #X obj 199 247 llist-drip; #X obj 89 10 import pdlua; #X msg 99 130 1 2 3 a b c; #X msg 121 152 list twig branch root; #X floatatom 77 109 5 0 0 0 - - -; #X obj 199 274 print dripped; #X symbolatom 36 68 10 0 0 0 - - -; #X obj 36 44 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 56 89 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 187 218 alpha; #X msg 165 196 list alpha; #X text 227 42 [llist-drip] outputs any input as a sequence; #X text 375 292 by Martin Peach \, 2012_04_03; #X msg 143 174 alpha beta gamma 1.234 -2; #X text 307 173 <- a message is interpreted as a list; #X text 259 152 <- a true list; #X text 239 196 <- a list with one element is still a list; #X text 229 217 <- a message is taken to be a oone-element list; #X text 178 130 <- a list beginning with a float is still a list; #X text 137 81 <- any single items are passed through unchanged; #X connect 0 0 5 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 6 0 0 0; #X connect 7 0 6 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 13 0 0 0; pdlua-0.7.3/examples/lsymbol2bytes.pd_lua0000644000175000017500000000206411754221357020707 0ustar zmoelnigzmoelnig--[[ lsymbol2bytes Output a symbol as a sequence of bytes author Martin Peach 20120420 --]] -- Pd class local Lsymbol2Bytes = pd.Class:new():register("lsymbol2bytes") function Lsymbol2Bytes:initialize(name, atoms) self.inlets = 1 self.outlets = 1 return true end -- Lsymbol2Bytes:drip: output possibly multibyte characters from buf and output them as floats on [0..255] function Lsymbol2Bytes:drip(buf) --pd.post(buf.. " size " .. #buf) local i = 1, b local len = #buf for i = 1, len do self:outlet(1, "float", {string.byte(buf, i)}) end end function Lsymbol2Bytes:in_1(sel, atoms) -- anything --pd.post("sel is " .. sel); --pd.post("number of atoms is ".. #atoms) --for i,v in ipairs(atoms) do -- pd.post(i .. " = " .. v) --end local buf if sel == "symbol" then -- the usual case buf = tostring(atoms[1]) self:drip(buf) elseif #atoms == 0 then -- a selector buf = tostring(sel) self:drip(buf) else -- reject non-symbols self:error("lsymbol2bytes: input not a symbol") end end -- end of lsymbol2bytes pdlua-0.7.3/examples/ldemux-help.pd0000644000175000017500000000266111674625145017467 0ustar zmoelnigzmoelnig#N canvas 31 53 510 441 10; #X floatatom 371 118 5 0 0 0 - - -; #X floatatom 250 103 5 0 0 0 - - -; #X msg 252 73 symbol x; #X msg 252 49 list a b c; #X msg 251 27 a b c; #X floatatom 108 212 5 0 0 0 - - -; #X floatatom 64 258 5 0 0 0 - - -; #X floatatom 64 214 5 0 0 0 - - -; #X floatatom 50 92 5 0 0 0 - - -; #X floatatom 57 137 5 0 0 0 - - -; #X floatatom 102 141 5 0 0 0 - - -; #X floatatom 148 139 5 0 0 0 - - -; #X obj 64 235 ldemux zwei; #X floatatom 131 262 5 0 0 0 - - -; #X floatatom 109 309 5 0 0 0 - - -; #X floatatom 65 355 5 0 0 0 - - -; #X floatatom 65 308 5 0 0 0 - - -; #X floatatom 106 356 5 0 0 0 - - -; #X obj 65 332 ldemux; #X obj 250 141 ldemux 6 ---------; #X text 20 72 2nd arg gives default outlet; #X obj 51 112 ldemux 3 2; #X obj 219 286 print lu1; #X obj 286 282 print lu2; #X obj 307 252 print lu3; #X obj 324 225 print lu4; #X obj 329 194 print lu5; #X obj 366 175 print lu6; #X text 169 346 outlet number starts from 1 like Lua!; #X connect 0 0 19 1; #X connect 1 0 19 0; #X connect 2 0 19 0; #X connect 3 0 19 0; #X connect 4 0 19 0; #X connect 5 0 12 1; #X connect 7 0 12 0; #X connect 8 0 21 0; #X connect 12 0 6 0; #X connect 12 1 13 0; #X connect 14 0 18 1; #X connect 16 0 18 0; #X connect 18 0 15 0; #X connect 18 1 17 0; #X connect 19 0 22 0; #X connect 19 1 23 0; #X connect 19 2 24 0; #X connect 19 3 25 0; #X connect 19 4 26 0; #X connect 19 5 27 0; #X connect 21 0 9 0; #X connect 21 1 10 0; #X connect 21 2 11 0; pdlua-0.7.3/examples/ltextfile-drip.pd_lua0000644000175000017500000002025512153315417021026 0ustar zmoelnigzmoelnig--[[ -- ltextfile-drip -- Output a text file as a sequence of symbols (sentences) -- author Martin Peach 20120913 --]] -- Pd class local LTextFileDrip = pd.Class:new():register("ltextfile-drip") local file ourTextFile = nil local words = {} local wordIndex = 0 local playbackIndex = 0 local ourSentence, ourRemainingLine = nil local ourLine = nil function LTextFileDrip:initialize(name, atoms) --pd.post("LTextFileDrip:initialize-> name is " .. name); --pd.post("number of atoms is ".. #atoms) --for i,v in ipairs(atoms) do -- pd.post(i .. " = " .. v) --end if #atoms > 0 then self:openOurTextFile(atoms[1]) end if ourTextFile == nil then pd.post("LTextFileDrip:initialize: unable to open " .. atoms[1]) end self.inlets = 1 self.outlets = 3 return true end -- LTextFileDrip:openOurTextFile: open a text file using name as a path function LTextFileDrip:openOurTextFile(name) if ourTextFile ~= nil then --pd.post("LTextFileDrip:openOurTextFile: closing old file") ourTextFile:close() ourTextFile = nil end --pd.post("LTextFileDrip:openOurTextFile ( " .. name .. " )") ourTextFile = io.open(name) if ourTextFile == nil then pd.post("LTextFileDrip:openOurTextFile: Unable to open " .. name) end ourRemainingLine = nil end function LTextFileDrip:rewindOurTextFile() -- pd.post("LTextFileDrip:rewind") if ourTextFile == nil then pd.post("LTextFileDrip:rewindOurTextFile: no open file") else ourTextFile:seek("set") --sets the position to the beginning of the file (and returns 0) wordIndex = 0 playbackIndex = 0 end end -- LTextFileDrip:drip: accumulate a line of words from ourTextFile and output them as symbols, one per bang function LTextFileDrip:drip() local ourPunc local repeatCount = 0 if ourTextFile == nil then pd.post("LTextFileDrip:drip: no open file") return end -- if wordIndex == 0 then -- read another line repeat repeatCount = repeatCount + 1 --pd.post("repeat number " .. repeatCount) if ourRemainingLine == nil then --pd.post ("1> ourRemainingLine is nil") ourLine = ourTextFile:read() if ourLine == nil then self:outlet(3, "bang", {}) -- end of file return end --pd.post ("1> ourLine is [" .. ourLine .. "] len: " .. ourLine:len()) -- strip CR LF s,e = ourLine:find("[\n\r]") if s then --pd.post("1> CR or LF at " .. s) ourLine = ourLine:sub(1,s-1) .. " " else ourLine = ourLine .. " " end elseif ourRemainingLine:len() == 0 then -- read another line --pd.post ("2> ourRemainingLine length 0") ourLine = ourTextFile:read() if ourLine == nil then self:outlet(3, "bang", {}) -- end of file return end --pd.post ("2> ourLine is [" .. ourLine .. "] len: " .. ourLine:len()) s,e = ourLine:find("[\n\r]") if s then --pd.post("2> CR or LF at " .. s) ourLine = ourLine:sub(1,s-1) .. " " else ourLine = ourLine .. " " end --pd.post("Not setting ourLine from ourRemainingLine, whose length is precisely " .. ourRemainingLine:len()) else cstart,cend = ourRemainingLine:find("[,.;!?:]") if cstart == nil then -- no punctuation in remainingLine, add next line from ourTextFile --pd.post("3> Adding a new line to ourRemainingLine") ourLine = ourTextFile:read() if ourLine == nil then -- no more lines self:outlet(3, "bang", {}) -- end of file return end --pd.post ("3> ourLine is [" .. ourLine .. "] len: " .. ourLine:len()) s,e = ourLine:find("[\n\r]") if s then --pd.post("3> CR or LF at " .. s) ourLine = ourLine:sub(1,s-1) .. " " else ourLine = ourLine .. " " end --ourLine = ourLine:gsub("[\n\r]", " ") if (ourLine:len() == 1) then -- an empty line --pd.post("BLANK LINE (1)") ourLine = "." -- replace blank line with punctuation to force a chop end ourLine = ourRemainingLine .. ourLine else -- remainingLine has punctuation --pd.post("4> ourRemainingLine contains punctuation") ourLine = ourRemainingLine end ourRemainingLine = nil end -- if ourRemainingLine == nil ourPunc = nil if ourLine ~= nil then -- line has content if ourLine:len() > 0 then wordIndex = 0 --pd.post("LTextFileDrip:drip: <" .. ourLine .. ">") --pd.post("LTextFileDrip:drip: len" .. ourLine:len()) --pd.post("LTextFileDrip:drip: 1st char" .. ourLine:byte(1)) if ((ourLine:len() == 1) and (ourLine:byte(1) == 13)) then -- a blank line --pd.post("BLANK LINE (2)") ourSentence = ourRemainingLine ourRemainingLine = nil else -- find a comma, period, semicolon, exclamation or question mark cstart,cend = ourLine:find("[,.;!?:]") if cstart ~= nil then -- take the line before the mark --pd.post("LTextFileDrip:drip: cstart " .. string.format ('%d', cstart) .. " cend " .. string.format('%d', cend)) ourPunc = ourLine:sub(cend, cend) --pd.post("LTextFileDrip:drip: punctuation: " .. ourPunc) ourSentence = ourLine:sub(1, cend) -- leave punctuation if ourRemainingLine ~= nil then ourSentence = ourRemainingLine .. ourSentence end ourRemainingLine = ourLine:sub(cend+1) --pd.post("LTextFileDrip:drip punctuation found: ourSentence is " .. ourSentence) --pd.post("LTextFileDrip:drip punctuation found: ourRemainingLine is " .. ourRemainingLine) else -- no mark, take the whole line if ourRemainingLine ~= nil then ourRemainingLine = ourRemainingLine .. ourLine --pd.post("LTextFileDrip:drip more to come: ourRemainingLine is " .. ourRemainingLine) --for c = 1, ourRemainingLine:len() do pd.post("_" .. ourRemainingLine:byte(c) .. "_") end else ourRemainingLine = ourLine --pd.post("LTextFileDrip:drip first: ourRemainingLine is " .. ourRemainingLine) end end -- if cstart ~= nil end -- if ((ourLine:len() == 1) and (ourLine:byte(1) == 13)) end -- if ourLine:len() > 0 if ourSentence ~= nil then if ourSentence:gmatch("%w+") then if ((ourSentence:len() == 1) and (ourSentence:byte(1) <= 32)) then --pd.post("BLANK LINE (3)") wordIndex = 0 -- skip blank line else wordIndex = 1 end -- for w in ourSentence:gmatch("%w+") do -- wordIndex = wordIndex + 1 -- words[wordIndex] = w --pd.post("wordIndex " .. wordIndex .. " for length " .. ourSentence:len() .. " starts with " .. ourSentence:byte(1)) end end playbackIndex = 1 else -- bang through outlet 3 serves as end of file notification self:outlet(3, "bang", {}) end -- if ourLine ~= nil -- end until ((wordIndex ~= 0) or (ourLine == nil)) if ourPunc ~= nil then self:outlet(2, "symbol", {ourPunc}) -- output punctuation end if wordIndex > 0 then -- output sentence as a single symbol if ourSentence ~= nil then len = ourSentence:len() --pd.post ("ourSentence:len() is " .. len) if len > 0 then --pd.post("ourSentence is not zero-length") --pd.post("ourSentence [" .. ourSentence .. "]") --pd.post("starts with " .. ourSentence:byte(1)) self:outlet(1, "symbol", {ourSentence}) -- output entire line else --pd.post("ourSentence is zero-length") self:outlet(1, "bang", {}) -- an empty line end end wordIndex = 0 -- no more words ourSentence = nil -- no more sentence end end function LTextFileDrip:in_1(sel, atoms) -- anything -- pd.post("LTextFileDrip:in-> sel is " .. sel); -- pd.post("number of atoms is ".. #atoms) -- for i,v in ipairs(atoms) do -- pd.post(i .. " = " .. v) -- end if sel == "bang" then -- output the next sentence self:drip() elseif sel == "open" then -- open a file self:openOurTextFile(atoms[1]) elseif sel == "rewind" then -- rewind the file self:rewindOurTextFile() elseif sel == "symbol" then -- assume it's a file name self:openOurTextFile(atoms[1]) elseif #atoms == 0 then -- a selector self:error("LTextFileDrip:in_1: input not known") else -- reject non-symbols self:error("LTextFileDrip:in_1: input not a symbol or bang") end end -- end of ltextfile-drip pdlua-0.7.3/examples/shared.pd_luax0000644000175000017500000000174611674625145017545 0ustar zmoelnigzmoelnigif sharedluaxstore == nil then sharedluaxstore = { } -- initialize store only once end return function (self, sel, atoms) if type(atoms[1]) == "string" then if sharedluaxstore[atoms[1]] == nil then sharedluaxstore[atoms[1]] = { sel = "bang", msg = { }, count = 1 } else sharedluaxstore[atoms[1]].count = sharedluaxstore[atoms[1]].count + 1 end self.name = atoms[1] self.inlets = 2 self.outlets = 1 self.in_1_bang = function(self) local s = sharedluaxstore[self.name] self:outlet(1, s.sel, s.msg) end self.in_2 = function(self, s, m) local c = sharedluaxstore[self.name].count sharedluaxstore[self.name] = { sel = s, msg = m, count = c } end self.finalize = function (self) sharedluaxstore[self.name].count = sharedluaxstore[self.name].count - 1 if sharedluaxstore[self.name].count == 0 then sharedluaxstore[self.name] = nil end end return true else return false end end pdlua-0.7.3/examples/lurn.pd_lua0000644000175000017500000000300611674625145017056 0ustar zmoelnigzmoelnig-- urn class: random selection without repetitions. -- fbar 2007 -- urn interface: local urn = {} function urn.new(size) assert(size > 0, "Error: size of urn must be greater than 0") local t = {size=size, last=size} for i=1,size do t[i] = i end return t end function urn.get(u) if u.last > 0 then local i = math.random(u.last) local res = u[i] u[i] = u[u.last] u.last = u.last - 1 return res else return nil end end function urn.reset(u) u.last = u.size for i=1,u.size do u[i] = i end end -- Pd class: local M = pd.Class:new():register("lurn") function M:initialize(name, atoms) if type(atoms[1]) == "number" and atoms[1] >= 1 then self.u = urn.new(math.floor(math.max(atoms[1]), 1)) else self.u = urn.new(1) end self.inlets = 2 self.outlets = 2 return true end function M:finalize() self.u = nil end function M:in_2_float(f) if f >= 1 then self.u = urn.new(math.floor(f)) else self:error("size of urn too small. needs to be 1 at least") end end function M:in_1_clear(atoms) urn.reset(self.u) end function M:in_1_seed(atoms) if type(atoms[1]) == "number" then math.randomseed(atoms[1]) else self:error("seed needs a number") end end function M:in_1_bang() local f = urn.get(self.u) if type(f) == "number" then self:outlet(1, "float", {f - 1}) else self:outlet(2, "bang", {}) end end pdlua-0.7.3/examples/lexpr-help.pd0000644000175000017500000001170411674625145017321 0ustar zmoelnigzmoelnig#N canvas 0 22 936 656 10; #X floatatom 110 102 5 0 0 0 - - -; #X floatatom 110 56 5 0 0 0 - - -; #X floatatom 202 56 5 0 0 0 - - -; #X floatatom 294 57 5 0 0 0 - - -; #X obj 72 53 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 26 232 5 0 0 0 - - -; #X floatatom 205 236 5 0 0 0 - - -; #X floatatom 385 235 5 0 0 0 - - -; #X floatatom 26 278 5 0 0 0 - - -; #X obj 26 255 lexpr phi rho gamma -> 100*cos(phi) + gamma*sin(rho) ; #X msg 115 205 lexpr foo bar baz -> foo * bar / baz; #X msg 115 181 lexpr x y z -> x+y+z; #X text 12 11 First come variable names \, then -> surrounded by spaces \, then an expression (in Lua syntax).; #X obj 110 77 lexpr a b c -> min(a \, b \, c); #X text 14 122 Messages can change the expression (provided inlet count stays the same). This resets the state of all variables. Note: weird tricks are needed for commas in messages :(; #X obj 86 441 lexpr a b c -> a + b + c; #X msg 190 412 hot \$1; #X obj 190 392 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 270 412 hot \$1; #X obj 270 392 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 110 412 hot \$1; #X obj 110 392 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X floatatom 86 367 5 0 0 0 - - -; #X floatatom 167 367 5 0 0 0 - - -; #X floatatom 249 367 5 0 0 0 - - -; #X obj 68 387 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 86 469 5 0 0 0 - - -; #X text 13 305 Eaxh inlet supports a "hot " method \, that makes the inlet hot or not. By default only the first inlet is hot. Sending a bang to the first inlet always performs the calculation \, no matter if that inlet is set to be cold.; #X text 22 491 Multiple outlets are supported \, with multiple expressions separated by commas.; #X obj 82 546 lexpr a b -> a + b \, a - b; #X floatatom 82 528 5 0 0 0 - - -; #X floatatom 252 528 5 0 0 0 - - -; #X floatatom 82 568 5 0 0 0 - - -; #X floatatom 252 568 5 0 0 0 - - -; #N canvas 2 22 450 300 \$0-weird-tricks-to-get-commas-in-messages 0 ; #X obj 58 231 lexpr a b -> max(a \, b) \, min(a \, b); #X floatatom 32 194 5 0 0 0 - - -; #X floatatom 33 273 5 0 0 0 - - -; #X floatatom 284 198 5 0 0 0 - - -; #X floatatom 284 275 5 0 0 0 - - -; #X obj 123 148 makefilename %c; #X msg 123 128 44; #X obj 123 68 makefilename %c; #X msg 123 48 44; #X msg 123 88 lexpr a b -> min(a \$1 b) \$1 max(a \$1 b); #X msg 123 168 lexpr a b -> max(a \$1 b) \$1 min(a \$1 b); #X text 28 18 This is really ugly \, but it seems to work...; #X connect 0 0 2 0; #X connect 0 1 4 0; #X connect 1 0 0 0; #X connect 3 0 0 1; #X connect 5 0 10 0; #X connect 6 0 5 0; #X connect 7 0 9 0; #X connect 8 0 7 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X restore 27 606 pd \$0-weird-tricks-to-get-commas-in-messages; #X text 502 5 New in pdlua-0.5: interaction with Pd [value] objects. ; #X obj 608 70 value \$0-foo; #X floatatom 608 45 5 0 0 0 - - -; #X obj 528 97 lexpr x y -> val("\$0-foo") * x / y; #X floatatom 528 72 5 0 0 0 - - -; #X floatatom 763 72 5 0 0 0 - - -; #X floatatom 528 129 5 0 0 0 - - -; #X text 504 161 Trying to access a [value] that doesn't exist returns 0:; #X obj 539 224 lexpr z -> z + val("\$0-bar"); #X floatatom 539 202 5 0 0 0 - - -; #X floatatom 539 253 5 0 0 0 - - -; #X obj 508 384 lexpr scale name -> scale * val(name); #X obj 782 319 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 672 343 symbol \$0-foo; #X obj 672 319 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 782 343 symbol \$0-baz; #X floatatom 792 377 5 0 0 0 - - -; #X obj 792 399 value \$0-baz; #X floatatom 508 354 5 0 0 0 - - -; #X floatatom 508 415 5 0 0 0 - - -; #X text 505 292 New in lexpr for pdlua-0.5: inputs can be symbols. ; #X obj 511 531 lexpr left right -> "" .. left .. right; #X symbolatom 511 497 10 0 0 0 - - -; #X symbolatom 781 497 10 0 0 0 - - -; #X symbolatom 511 570 0 0 0 0 - - -; #X text 501 471; #X text 494 446 New in lexpr for pdlua-0.5: outputs can be symbols too. The inital "" is to make sure that we have a string.; #X floatatom 737 496 5 0 0 0 - - -; #X floatatom 594 497 5 0 0 0 - - -; #X connect 1 0 13 0; #X connect 2 0 13 1; #X connect 3 0 13 2; #X connect 4 0 13 0; #X connect 5 0 9 0; #X connect 6 0 9 1; #X connect 7 0 9 2; #X connect 9 0 8 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 13 0 0 0; #X connect 15 0 26 0; #X connect 16 0 15 1; #X connect 17 0 16 0; #X connect 18 0 15 2; #X connect 19 0 18 0; #X connect 20 0 15 0; #X connect 21 0 20 0; #X connect 22 0 15 0; #X connect 23 0 15 1; #X connect 24 0 15 2; #X connect 25 0 15 0; #X connect 29 0 32 0; #X connect 29 1 33 0; #X connect 30 0 29 0; #X connect 31 0 29 1; #X connect 37 0 36 0; #X connect 38 0 41 0; #X connect 39 0 38 0; #X connect 40 0 38 1; #X connect 43 0 45 0; #X connect 44 0 43 0; #X connect 46 0 54 0; #X connect 47 0 50 0; #X connect 48 0 46 1; #X connect 49 0 48 0; #X connect 50 0 46 1; #X connect 51 0 52 0; #X connect 53 0 46 0; #X connect 56 0 59 0; #X connect 57 0 56 0; #X connect 58 0 56 1; #X connect 62 0 56 1; #X connect 63 0 56 0; pdlua-0.7.3/examples/list-pak-help.pd0000644000175000017500000000170311674625145017711 0ustar zmoelnigzmoelnig#N canvas 188 72 556 526 10; #X obj 106 244 list-pak; #X obj 106 277 print list-pak; #X floatatom 106 202 5 0 0 0 - - -; #X msg 147 197 bang; #X msg 149 219 symbol x; #X obj 306 301 print list-pak; #X floatatom 306 176 5 0 0 0 - - -; #X msg 306 129 bang; #X msg 306 152 symbol x; #X floatatom 338 239 5 0 0 0 - - -; #X floatatom 383 243 5 0 0 0 - - -; #X obj 306 268 list-pak 3; #X msg 380 221 any; #X msg 338 217 bang; #X obj 103 385 list-pak -3; #X text 101 367 Don't do this:; #X text 76 32 list-pak; #X text 84 58 Like [pack] for any kind of type. Argument specifies number of inlets. All inlets are hot as in Max' [pak].; #X text 83 94 Stored elements default to 0; #X text 101 467 Frank Barknecht \, 2007; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 6 0 11 0; #X connect 7 0 11 0; #X connect 8 0 11 0; #X connect 9 0 11 1; #X connect 10 0 11 2; #X connect 11 0 5 0; #X connect 12 0 11 2; #X connect 13 0 11 1; pdlua-0.7.3/examples/luametro.pd_lua0000644000175000017500000000665011674625145017736 0ustar zmoelnigzmoelnig-- reimplementation of [metro] with a twist -- fbar 2007 -- we need an urn: local urn = {} function urn.new(size) assert(size > 0, "Error: size of urn must be greater than 0") local t = {size=size, last=size} for i=1,size do t[i] = i end return t end function urn.get(u) if u.last > 0 then local i = math.random(u.last) local res = u[i] u[i] = u[u.last] u.last = u.last - 1 return res else return nil end end function urn.reset(u) u.last = u.size for i=1,u.size do u[i] = i end end local modes = {"alea", "series", "sequence", "rota"} local function contains(t,x) for k,v in pairs(t) do if v == x then return true end end return false end -- pd: local M = pd.Class:new():register("luametro") function M:initialize(name, atoms) self.periods = {} self.i = 1 self.mode = "sequence" self.direction = 1 self.u = urn.new(math.max(1, #atoms)) if not self:setperiods(atoms) then return false end self.inlets = 2 self.outlets = 2 return true end function M:postinitialize() self.clock = pd.Clock:new():register(self, "tick") end function M:finalize() self.clock:destruct() end function M:setperiods(periods) self.periods = {} for i,j in ipairs(periods) do if type(j) == "number" then self.periods[i] = math.max(0.01, j) else self:error("non-number in period list!") return false end end -- start over at front: self.i = 1 return true end function M:in_2(sel, atoms) if sel == "list" or sel == "float" then self:setperiods(atoms) end end function M:in_1_float(f) if f ~= 0 then self:tick() else self.clock:unset() end end function M:in_1_bang() self.i = 1 self:tick() end function M:in_1_start() self.i = 1 self:tick() end function M:in_1_stop() self.clock:unset() end function M:in_1_mode(atoms) if type(atoms[1]) == "number" then self.mode = modes[atoms[1]] if self.mode == "series" then self.u = urn.new(#self.periods) end self.i = 1 elseif type(atoms[1]) == "string" then if contains(modes, atoms[1]) then self.mode = atoms[1] else self:error("no such mode: " .. atoms[1]) end end pd.post("Mode set to: " .. self.mode) end function M:tick() self:outlet(1, "bang", {}) -- pd.post("selection: " .. tostring(self.i)) if type(self.periods[self.i]) == "number" then self.clock:delay(self.periods[self.i]) end if self.mode == "sequence" then self.i = self.i + 1 if self.i > #self.periods then self.i = 1 self:outlet(2, "bang", {}) end elseif self.mode == "alea" then self.i = math.random(#self.periods) elseif self.mode == "series" then local f = urn.get(self.u) if not f then urn.reset(self.u) f = urn.get(self.u) self:outlet(2, "bang", {}) end self.i = f elseif self.mode == "rota" then self.i = self.i + self.direction if self.i > #self.periods or self.i < 1 then self.direction = -self.direction self.i = self.i + self.direction self:outlet(2, "bang", {}) end else self:error("Unknown mode") end end pdlua-0.7.3/examples/lsend-help.pd0000644000175000017500000000076712363422162017271 0ustar zmoelnigzmoelnig#N canvas 0 0 450 300 10; #X obj 55 142 lsend lsend-x; #X obj 49 188 r lsend-x; #X obj 158 189 r lsend-y; #X msg 141 87 symbol lsend-x; #X msg 149 107 symbol lsend-y; #X floatatom 69 112 5 0 0 0 - - -; #X msg 32 57 foo bar 1 2 4 8; #X obj 48 224 print lsend-x; #X obj 158 224 print lsend-y; #X symbolatom 55 87 10 0 0 0 - - -; #X text 21 23 Test send support...; #X connect 1 0 7 0; #X connect 2 0 8 0; #X connect 3 0 0 1; #X connect 4 0 0 1; #X connect 5 0 0 0; #X connect 6 0 0 0; #X connect 9 0 0 0; pdlua-0.7.3/examples/mutator.pd_lua0000644000175000017500000000040611674625145017572 0ustar zmoelnigzmoelnigMutator = pd.Class:new():register("mutator") function Mutator:initialize() self.inlets = 1 return true end function Mutator:in_1_bang() pd.post("Radiation Alert!") Mutatee.in_1_bang = function(self) pd.post("Oh noes! I've been mutated!") end end pdlua-0.7.3/examples/ltabdump-help.pd0000644000175000017500000000345211674625145020000 0ustar zmoelnigzmoelnig#N canvas 0 0 450 300 10; #X obj 102 201 ltabdump \$0-tab-A; #X obj 102 241 print ltabdump; #X floatatom 218 242 5 0 0 0 - - -; #X obj 11 34 table \$0-tab-B 8; #X obj 11 14 table \$0-tab-A 4; #N canvas 18 116 450 300 \$0-fill-tables 0; #X obj 27 37 inlet; #X obj 27 61 t b b; #X obj 220 134 until; #X obj 220 177 random 16; #X obj 220 155 t b b; #X obj 219 205 tabwrite \$0-tab-B; #X obj 311 166 f 0; #X obj 350 151 + 1; #X obj 350 174 mod 8; #X msg 223 112 8; #X obj 30 134 until; #X obj 30 177 random 16; #X obj 30 155 t b b; #X obj 121 166 f 0; #X obj 160 151 + 1; #X msg 33 112 4; #X obj 160 174 mod 4; #X obj 29 205 tabwrite \$0-tab-A; #X connect 0 0 1 0; #X connect 1 0 15 0; #X connect 1 1 9 0; #X connect 2 0 4 0; #X connect 3 0 5 0; #X connect 4 0 3 0; #X connect 4 1 6 0; #X connect 6 0 7 0; #X connect 6 0 5 1; #X connect 7 0 8 0; #X connect 8 0 6 1; #X connect 9 0 2 0; #X connect 10 0 12 0; #X connect 11 0 17 0; #X connect 12 0 11 0; #X connect 12 1 13 0; #X connect 13 0 14 0; #X connect 13 0 17 1; #X connect 14 0 16 0; #X connect 15 0 10 0; #X connect 16 0 13 1; #X restore 171 39 pd \$0-fill-tables; #X obj 171 12 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 193 14 loadbang; #X obj 102 82 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 132 99 symbol \$0-tab-A; #X obj 132 179 symbol \$0-tab-C; #X obj 132 161 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 132 121 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 132 81 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 132 139 symbol \$0-tab-B; #X connect 0 0 1 0; #X connect 0 1 2 0; #X connect 6 0 5 0; #X connect 7 0 5 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 11 0 10 0; #X connect 12 0 14 0; #X connect 13 0 9 0; #X connect 14 0 0 0; pdlua-0.7.3/examples/dispatchertest.pd_lua0000644000175000017500000000064711674625145021134 0ustar zmoelnigzmoelniglocal DispatcherTest = pd.Class:new():register("dispatchertest") function DispatcherTest:initialize(name, atoms) self.inlets = 3 return true end function DispatcherTest:in_1_float(f) pd.post("float: " .. f) end function DispatcherTest:in_2_symbol(s) pd.post("symbol: " .. s) end function DispatcherTest:in_3(sel, atoms) pd.post(sel .. ":") for i,v in ipairs(atoms) do pd.post(i .. " = " .. v) end end pdlua-0.7.3/examples/lsend.pd_lua0000644000175000017500000000064311674625145017207 0ustar zmoelnigzmoelnig-- test send support local LSend = pd.Class:new():register("lsend") function LSend:initialize(name, atoms) if type(atoms[1]) ~= "string" then pd.post("lsend needs a symbol") return false else self.sendto = atoms[1] end self.inlets = 2 self.outlets = 0 return true end function LSend:in_2_symbol(s) self.sendto = s end function LSend:in_1(sel, atoms) pd.send(self.sendto, sel, atoms) end pdlua-0.7.3/examples/complex.pd_lua0000644000175000017500000000037711674625145017555 0ustar zmoelnigzmoelnigrequire("complex") local C = pd.Class:new():register("complex") function C:initialize(sel, atoms) for k,v in pairs(complex) do pd.post("complex." .. tostring(k) .. " = " .. tostring(v)) end self.inlets = 0 self.outlets = 0 return true end pdlua-0.7.3/examples/dispatchertest-help.pd0000644000175000017500000000032711674625145021214 0ustar zmoelnigzmoelnig#N canvas 0 0 450 300 10; #X obj 98 174 dispatchertest; #X floatatom 98 42 5 0 0 0 - - -; #X symbolatom 144 75 10 0 0 0 - - -; #X msg 191 110 a b c 1 2 3; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 0 2; pdlua-0.7.3/examples/lsymbol-drip.pd_lua0000644000175000017500000000272311743054211020503 0ustar zmoelnigzmoelnig--[[ lsymbol-drip Output a symbol as a sequence of characters author Martin Peach 20120403 --]] -- Pd class local LsymbolDrip = pd.Class:new():register("lsymbol-drip") function LsymbolDrip:initialize(name, atoms) self.inlets = 1 self.outlets = 1 return true end -- LsymbolDrip:drip: accumulate possibly multibyte characters from buf and output them as symbols function LsymbolDrip:drip(buf) --pd.post(buf.. " size " .. #buf) local i = 1, j, b local len = #buf while i <= len do j = i -- character is one byte long b = string.byte(buf, i) --pd.post("*b is " .. b .. " i is " .. i) while b > 0x7f and j < len do -- multibyte characters have their high bit set j = j + 1 b = string.byte(buf, j) --pd.post("_b is " .. b .. " j is " .. j) end if j ~= i and j < len then j = j - 1 end -- j was pointing to the next character self:outlet(1, "symbol", {string.sub(buf, i, j)}) i = j + 1 -- start of next character end end function LsymbolDrip:in_1(sel, atoms) -- anything --pd.post("sel is " .. sel); --pd.post("number of atoms is ".. #atoms) --for i,v in ipairs(atoms) do -- pd.post(i .. " = " .. v) --end local buf if sel == "symbol" then -- the usual case buf = tostring(atoms[1]) self:drip(buf) elseif #atoms == 0 then -- a selector buf = tostring(sel) self:drip(buf) else -- reject non-symbols self:error("lsymbol-drip: input not a symbol") end end -- end of lsymbol-drip pdlua-0.7.3/examples/ltabfill-help.pd0000644000175000017500000000203311674625145017753 0ustar zmoelnigzmoelnig#N canvas 0 0 453 328 10; #X obj 82 239 ltabfill \$0-table w -> sin(2*pi*w*x); #X obj 33 192 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 331 196 5 0 0 2 w - -; #X obj 82 159 symbol \$0-table-1; #X obj 94 205 symbol \$0-table-2; #X obj 94 184 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 82 136 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 254 134 table \$0-table-1 333; #X obj 254 157 table \$0-table-2 555; #X text 15 17 [ltabfill] is a clone of [lexpr] that writes a function to a table. The first argument and inlet is the name of the table \, then the usual [lexpr] stuff follows. There is an additional implicit parameter to the expression \, named 'x' \, which ranges from [0..1) no matter the size of the array. Note: you might have to close/reopen the table displays for them to refresh correctly.; #X text 14 280 See also:; #X obj 53 299 lexpr x -> x; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 5 0 4 0; #X connect 6 0 3 0; pdlua-0.7.3/examples/simplecounter-help.pd0000644000175000017500000000245511674625145021063 0ustar zmoelnigzmoelnig#N canvas 0 0 450 300 10; #X text 21 17 these three are equivalent \, default start count is 0; #X obj 22 78 simplecounter; #X floatatom 22 113 5 0 0 0 - - -; #X obj 22 50 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 152 116 5 0 0 0 - - -; #X obj 152 53 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 152 81 simplecounter 0; #X floatatom 287 113 5 0 0 0 - - -; #X obj 287 50 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 287 78 simplecounter foo; #X text 19 141 the first creation argument (when a float) is start count; #X floatatom 17 252 5 0 0 0 - - -; #X obj 17 189 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 140 252 5 0 0 0 - - -; #X obj 140 189 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 17 217 simplecounter 10; #X obj 140 217 simplecounter -20; #X floatatom 284 250 5 0 0 0 - - -; #X obj 284 187 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 284 215 simplecounter 10 foo; #X text 18 157 further creation arguments are ignored; #X connect 1 0 2 0; #X connect 3 0 1 0; #X connect 5 0 6 0; #X connect 6 0 4 0; #X connect 8 0 9 0; #X connect 9 0 7 0; #X connect 12 0 15 0; #X connect 14 0 16 0; #X connect 15 0 11 0; #X connect 16 0 13 0; #X connect 18 0 19 0; #X connect 19 0 17 0; pdlua-0.7.3/examples/list-pak.pd_lua0000644000175000017500000000235112363413036017612 0ustar zmoelnigzmoelnig--[[ list-pak Like [pack] for any kind of type. Argument specifies number of inlets. All inlets are hot (as in Max' [pak]) --Written by Frank Barknecht --]] -- Some footils -- -- selectors local selectors = {"float", "list", "symbol", "bang", "pointer"} -- check if item x is in table t: local function contains(t, x) for _,v in ipairs(t) do if v == x then return true end end return false end -- Pd class local ListPak = pd.Class:new():register("list-pak") function ListPak:initialize(name, atoms) self.outlets = 1 self.stored = {} if atoms[1] == nil then self.inlets = 1 elseif type(atoms[1]) == "number" and atoms[1] >= 0 then self.inlets = math.max(atoms[1], 1) else pd.post("list-pak: First arg must be a positive float or empty") return false end for i=1,self.inlets do table.insert(self.stored, 0) end return true end function ListPak:in_n(i, sel, atoms) if not contains(selectors, sel) then -- insert selector self.stored[i] = sel else -- if table.getn(atoms) > 0 then if #(atoms) > 0 then self.stored[i] = atoms[1] end end self:outlet(1, "list", self.stored) end pdlua-0.7.3/examples/simplecounter.pd_lua0000644000175000017500000000054311674625145020772 0ustar zmoelnigzmoelniglocal SimpleCounter = pd.Class:new():register("simplecounter") function SimpleCounter:initialize(sel, atoms) self.inlets = 1 self.outlets = 1 self.count = 0 if type(atoms[1]) == "number" then self.count = atoms[1] end return true end function SimpleCounter:in_1_bang() self:outlet(1, "float", {self.count}) self.count = self.count + 1 end pdlua-0.7.3/examples/ldelay2.pd_lua0000644000175000017500000000170311674625145017434 0ustar zmoelnigzmoelnig-- test multiple clocks local LDelay = pd.Class:new():register("ldelay2") function LDelay:initialize(name, atoms) if type(atoms[1]) ~= "number" or atoms[1] < 0 then self.delay = 1000 else self.delay = atoms[1] end self.inlets = 2 self.outlets = 2 return true end function LDelay:postinitialize() self.clock1 = pd.Clock:new():register(self, "trigger1") self.clock2 = pd.Clock:new():register(self, "trigger2") end function LDelay:finalize() self.clock1:destruct() self.clock2:destruct() end function LDelay:in_2_float(f) self.delay = math.max(0, f) end function LDelay:in_1_float(f) self:in_2_float(f) self:in_1_bang() end function LDelay:in_1_bang() self.clock1:delay(self.delay) self.clock2:delay(self.delay * 2) end function LDelay:in_1_stop() self.clock1:unset() self.clock2:unset() end function LDelay:trigger1() self:outlet(1, "bang", {}) end function LDelay:trigger2() self:outlet(2, "bang", {}) end pdlua-0.7.3/examples/lurn-help.pd0000644000175000017500000001223511674625145017147 0ustar zmoelnigzmoelnig#N canvas 457 204 823 609 10; #X msg 81 156 bang; #X obj 104 275 print urne; #X obj 125 251 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 155 158 seed 10; #X msg 157 181 clear; #X floatatom 139 231 5 0 0 0 - - -; #X text 78 41 generates random numbers without repetition; #X text 37 23 urne: Unique Random Generator; #X text 352 177 bang: output next random number without repetitions. ; #X text 351 200 clear: put all numbers back into urn.; #X text 351 224 seed NUM: seed random number generator; #X text 331 157 Inlet 0:; #X text 332 258 Inlet 1:; #X text 335 319 Outlet 0:; #X text 361 338 random number; #X text 337 371 Outlet 1:; #X text 373 279 int - set range of random numbers and reset the urn. ; #X text 333 125 Arguments: int - range of random numbers in urn (optional) ; #X text 83 68 Clone of the Max object [urn]. Stops when all values have been chosen and bangs right outlet. Send "clear" message to make it start over.; #X msg 83 371 bang; #N canvas 0 0 450 300 display 0; #X obj 46 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 63 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 80 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 97 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 114 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 156 135 list append 0; #X obj 46 134 list append 1; #N canvas 0 0 450 300 count 0; #X obj 158 193 + 1; #X obj 122 158 until; #X obj 122 194 f; #X obj 122 101 inlet; #X msg 167 157 0; #X obj 122 120 t a b; #X obj 122 224 outlet; #X connect 0 0 2 1; #X connect 1 0 2 0; #X connect 2 0 0 0; #X connect 2 0 6 0; #X connect 3 0 5 0; #X connect 4 0 2 1; #X connect 5 0 1 0; #X connect 5 1 4 0; #X restore 156 90 pd count; #X obj 46 160 route 0 1 2 3 4 5 6 7 8 9; #X obj 131 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 148 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 165 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 182 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 199 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 46 36 inlet; #X obj 156 37 inlet; #X obj 156 64 max 1; #X connect 5 0 8 0; #X connect 6 0 8 0; #X connect 7 0 5 0; #X connect 8 0 0 0; #X connect 8 1 1 0; #X connect 8 2 2 0; #X connect 8 3 3 0; #X connect 8 4 4 0; #X connect 8 5 9 0; #X connect 8 6 10 0; #X connect 8 7 11 0; #X connect 8 8 12 0; #X connect 8 9 13 0; #X connect 14 0 6 0; #X connect 15 0 16 0; #X connect 16 0 7 0; #X coords 0 -1 1 1 180 40 1 40 170; #X restore 83 519 pd display; #X text 363 389 bang \, when an empty urn receives a bang into first inlet.; #X msg 101 395 clear \, bang; #X obj 127 448 t b b; #X obj 127 468 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 256 493 f 10; #X floatatom 150 425 5 0 0 0 - - -; #N canvas 0 0 450 300 display 0; #X obj 46 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 63 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 80 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 97 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 114 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 156 135 list append 0; #X obj 46 134 list append 1; #N canvas 0 0 450 300 count 0; #X obj 158 193 + 1; #X obj 122 158 until; #X obj 122 194 f; #X obj 122 101 inlet; #X msg 167 157 0; #X obj 122 120 t a b; #X obj 122 224 outlet; #X connect 0 0 2 1; #X connect 1 0 2 0; #X connect 2 0 0 0; #X connect 2 0 6 0; #X connect 3 0 5 0; #X connect 4 0 2 1; #X connect 5 0 1 0; #X connect 5 1 4 0; #X restore 156 90 pd count; #X obj 46 160 route 0 1 2 3 4 5 6 7 8 9; #X obj 131 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 148 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 165 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 182 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 199 191 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 46 36 inlet; #X obj 156 37 inlet; #X obj 156 66 max 1; #X connect 5 0 8 0; #X connect 6 0 8 0; #X connect 7 0 5 0; #X connect 8 0 0 0; #X connect 8 1 1 0; #X connect 8 2 2 0; #X connect 8 3 3 0; #X connect 8 4 4 0; #X connect 8 5 9 0; #X connect 8 6 10 0; #X connect 8 7 11 0; #X connect 8 8 12 0; #X connect 8 9 13 0; #X connect 14 0 6 0; #X connect 15 0 16 0; #X connect 16 0 7 0; #X coords 0 -1 1 1 180 40 1 40 170; #X restore 81 300 pd display; #X obj 254 273 f 10; #X obj 254 247 b; #X text 365 425 Use the second outlet to make the urn refill automatically if it gets empty as show in the second example with a combined "clear \, bang" message.; #X obj 100 492 print urne_auto; #X obj 81 230 lurn 10; #X obj 83 425 lurn 10; #X connect 0 0 32 0; #X connect 3 0 32 0; #X connect 4 0 29 0; #X connect 4 0 32 0; #X connect 5 0 32 1; #X connect 19 0 33 0; #X connect 22 0 33 0; #X connect 23 0 22 0; #X connect 23 0 24 0; #X connect 23 1 25 0; #X connect 25 0 20 1; #X connect 26 0 25 0; #X connect 26 0 33 1; #X connect 28 0 27 1; #X connect 29 0 28 0; #X connect 32 0 1 0; #X connect 32 0 27 0; #X connect 32 1 2 0; #X connect 33 0 20 0; #X connect 33 0 31 0; #X connect 33 1 23 0; pdlua-0.7.3/examples/reverb-calculator-help.pd0000644000175000017500000000355111674625145021604 0ustar zmoelnigzmoelnig#N canvas 0 0 513 360 10; #X obj 117 203 reverb-calculator 8; #X obj 13 229 reverb; #X floatatom 89 169 5 0 0 0 - - -; #X obj 15 146 noise~; #X obj 14 185 *~; #X obj 62 115 vline~; #X obj 18 265 dac~; #X obj 70 263 print reverb; #X obj 11 7 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1 ; #X obj 8 60 t b b; #X obj 158 24 spigot; #X obj 197 -4 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 25 166 noise~; #X obj 25 205 *~; #X obj 10 28 metro 1000; #X obj 158 47 t b b b; #X floatatom 158 146 5 0 0 0 - - -; #X obj 158 172 pack f f f; #X obj 158 71 random 1000; #X obj 251 71 random 1000; #X obj 340 70 random 1000; #X floatatom 251 146 5 0 0 0 - - -; #X floatatom 341 148 5 0 0 0 - - -; #X obj 157 97 expr $f1*$f1/100000+1; #X obj 251 121 expr $f1*$f1/100000+1; #X obj 341 101 expr $f1*$f1/100000+1; #X msg 10 89 0.5 1 \, 0 1 1; #X obj 84 4 f 0; #X obj 115 4 + 1; #X obj 84 62 sel 0; #X obj 115 24 mod 5; #X text 255 174 room dimensions in meters; #X text 79 148 decay (%); #X text 98 245 delay times in ms; #X obj 212 22 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X connect 0 0 1 2; #X connect 0 0 7 0; #X connect 1 0 6 0; #X connect 1 1 6 1; #X connect 2 0 1 3; #X connect 3 0 4 0; #X connect 4 0 1 0; #X connect 5 0 4 1; #X connect 5 0 13 1; #X connect 8 0 14 0; #X connect 9 0 26 0; #X connect 9 1 27 0; #X connect 10 0 15 0; #X connect 11 0 10 1; #X connect 12 0 13 0; #X connect 13 0 1 1; #X connect 14 0 9 0; #X connect 15 0 18 0; #X connect 15 1 19 0; #X connect 15 2 20 0; #X connect 16 0 17 0; #X connect 17 0 0 0; #X connect 18 0 23 0; #X connect 19 0 24 0; #X connect 20 0 25 0; #X connect 21 0 17 1; #X connect 22 0 17 2; #X connect 23 0 16 0; #X connect 24 0 21 0; #X connect 25 0 22 0; #X connect 26 0 5 0; #X connect 27 0 28 0; #X connect 27 0 29 0; #X connect 28 0 30 0; #X connect 29 0 10 0; #X connect 30 0 27 1; #X connect 34 0 15 0; pdlua-0.7.3/examples/ldelay2-help.pd0000644000175000017500000000114411674625145017520 0ustar zmoelnigzmoelnig#N canvas 256 192 450 300 10; #X msg 259 89 500; #X msg 272 112 1000; #X msg 197 107 1500; #X obj 187 76 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 187 199 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 139 108 stop; #X obj 351 265 delay 1000; #X text 278 266 see also:; #X obj 187 150 ldelay2 1000; #X obj 266 199 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 17 17 Testing multiple clocks in one object...; #X connect 0 0 8 1; #X connect 1 0 8 1; #X connect 2 0 8 0; #X connect 3 0 8 0; #X connect 5 0 8 0; #X connect 8 0 4 0; #X connect 8 1 9 0; pdlua-0.7.3/examples/lreceive.pd_lua0000644000175000017500000000202711674625145017676 0ustar zmoelnigzmoelnig-- test receive support local LReceive = pd.Class:new():register("lreceive") function LReceive:initialize(name, atoms) if type(atoms[1]) ~= "string" then pd.post("lreceive needs a prefix for the receive names!") return false else self.prefix = atoms[1] end if type(atoms[2]) ~= "number" or atoms[2] < 1 then self.start = 1 else self.start = math.floor(atoms[2]) end if type(atoms[3]) ~= "number" or atoms[3] < 1 then self.count = 1 else self.count = math.floor(atoms[3]) end self.receives = { } self.inlets = 0 self.outlets = 2 return true end function LReceive:postinitialize() local i = 0 while (i < self.count) do local n = self.start + i self.receives[i+1] = pd.Receive:new():register(self, self.prefix .. n, "receive_" .. n) self["receive_" .. n] = function (self, sel, atoms) self:outlet(2, "float", { n }) self:outlet(1, sel, atoms) end i = i + 1 end end function LReceive:finalize() for _,r in ipairs(self.receives) do r:destruct() end end pdlua-0.7.3/examples/lfloat2bytes-help.pd0000644000175000017500000000144611754221357020577 0ustar zmoelnigzmoelnig#N canvas 494 466 616 332 10; #X declare -lib pdlua; #X obj 23 8 import pdlua; #X obj 86 80 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 161 278 print bytes; #X text 390 282 by Martin Peach 2012_04_20; #X msg 39 54 3.14159; #X floatatom 101 59 5 0 0 0 - - -; #X obj 86 101 f; #X obj 126 114 atan; #X msg 126 90 1; #X obj 126 140 * 4; #X floatatom 158 157 12 0 0 0 - - -; #X text 173 242 The optional argument sets the number of significant digits (default = 6).; #X text 173 212 [lfloat2bytes] spits out the characters of a string representation of a float as bytes.; #X obj 161 193 lfloat2bytes 12; #X connect 1 0 6 0; #X connect 4 0 13 0; #X connect 5 0 6 1; #X connect 6 0 13 0; #X connect 7 0 9 0; #X connect 8 0 7 0; #X connect 9 0 10 0; #X connect 9 0 13 0; #X connect 13 0 2 0; pdlua-0.7.3/examples/revalue-help.pd0000644000175000017500000000313311674625145017627 0ustar zmoelnigzmoelnig#N canvas 0 0 558 379 10; #X obj 109 166 revalue; #X obj 155 203 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 109 205 5 0 0 0 - - -; #X obj 83 121 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 109 121 5 0 0 0 - - -; #X floatatom 110 268 5 0 0 0 - - -; #X obj 83 267 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 110 297 value \$0-foo; #X floatatom 110 331 5 0 0 0 - - -; #X floatatom 240 268 5 0 0 0 - - -; #X obj 213 267 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 240 331 5 0 0 0 - - -; #X obj 240 297 value \$0-bar; #X obj 155 142 symbol \$0-foo; #X obj 185 122 symbol \$0-bar; #X obj 155 120 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 185 100 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 215 80 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 215 102 symbol \$0-oof; #X obj 294 167 revalue \$0-foo; #X obj 294 143 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 294 199 5 0 0 0 - - -; #X text 23 23 Interface to Pd's native [value]. Behaves like [value] but with a settable name \, and another outlet to report if there is no [value] with the current name.; #X connect 0 0 2 0; #X connect 0 1 1 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 5 0 7 0; #X connect 6 0 7 0; #X connect 7 0 8 0; #X connect 9 0 12 0; #X connect 10 0 12 0; #X connect 12 0 11 0; #X connect 13 0 0 1; #X connect 14 0 0 1; #X connect 15 0 13 0; #X connect 16 0 14 0; #X connect 17 0 18 0; #X connect 18 0 0 1; #X connect 19 0 21 0; #X connect 20 0 19 0; pdlua-0.7.3/examples/llist-rdrip-help.pd0000644000175000017500000000223411754221357020426 0ustar zmoelnigzmoelnig#N canvas 392 517 588 334 10; #X declare -lib pdlua; #X obj 89 10 import pdlua; #X msg 99 130 1 2 3 a b c; #X msg 121 152 list twig branch root; #X floatatom 77 109 5 0 0 0 - - -; #X obj 199 274 print dripped; #X symbolatom 36 68 10 0 0 0 - - -; #X obj 36 44 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 56 89 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 187 218 alpha; #X msg 165 196 list alpha; #X msg 143 174 alpha beta gamma 1.234 -2; #X text 307 173 <- a message is interpreted as a list; #X text 259 152 <- a true list; #X text 239 196 <- a list with one element is still a list; #X text 229 217 <- a message is taken to be a oone-element list; #X text 178 130 <- a list beginning with a float is still a list; #X text 137 81 <- any single items are passed through unchanged; #X text 375 292 by Martin Peach \, 2012_04_19; #X text 196 37 [llist-rdrip] outputs any input as a reverse sequence ; #X obj 199 247 llist-rdrip; #X connect 1 0 19 0; #X connect 2 0 19 0; #X connect 3 0 19 0; #X connect 5 0 19 0; #X connect 6 0 5 0; #X connect 7 0 19 0; #X connect 8 0 19 0; #X connect 9 0 19 0; #X connect 10 0 19 0; #X connect 19 0 4 0; pdlua-0.7.3/examples/revalue.pd_lua0000644000175000017500000000141411674625145017542 0ustar zmoelnigzmoelniglocal Revalue = pd.Class:new():register("revalue") function Revalue:initialize(sel, atoms) self.inlets = 2 self.outlets = 2 if type(atoms[1]) == "string" then self.name = atoms[1] else self.name = nil end return true end -- get a value or report if it doesn't exist function Revalue:in_1_bang() if self.name ~= nil then local r = pd.getvalue(self.name) if r ~= nil then self:outlet(1, "float", { r }) return end end self:outlet(2, "bang", { }) end -- set a value or report if it doesn't exist function Revalue:in_1_float(f) if self.name ~= nil then if pd.setvalue(self.name, f) then return end end self:outlet(2, "bang", { }) end -- set the [value] name function Revalue:in_2_symbol(s) self.name = s end pdlua-0.7.3/examples/mutatee.pd_lua0000644000175000017500000000026711674625145017550 0ustar zmoelnigzmoelnigMutatee = pd.Class:new():register("mutatee") function Mutatee:initialize() self.inlets = 1 return true end function Mutatee:in_1_bang() pd.post("I'm happy and carefree!") end pdlua-0.7.3/examples/dumptypes.pd_luax0000644000175000017500000000042711674625145020324 0ustar zmoelnigzmoelnig-- dump Lua types for atoms, just to see what we get for pointers return function(self, sel, atoms) self.inlets = 1 function self:in_1(sel, atoms) pd.post(sel .. "[") for _,v in ipairs(atoms) do pd.post(type(v)) end pd.post("]") end return true end pdlua-0.7.3/examples/lpipe-help.pd0000644000175000017500000000064711674625145017304 0ustar zmoelnigzmoelnig#N canvas 343 338 450 300 10; #X obj 114 179 lpipe; #X obj 114 214 print; #X obj 114 127 unpack 0 0; #X msg 135 95 0 0 \, 1000 1000 \, 2000 2000 \, 500 500; #X msg 114 65 4000 4000; #X msg 56 65 250 250; #X msg 50 128 a b c d; #X floatatom 179 183 5 0 0 0 - - -; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 2 1 0 1; #X connect 2 1 7 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 2 0; #X connect 6 0 0 0; pdlua-0.7.3/examples/errors.pd_lua0000644000175000017500000000030611674625145017412 0ustar zmoelnigzmoelnig-- no methods, deliberately: test the error reporting! local errors = pd.Class:new():register("errors") function errors:initialize(sel, atoms) self.inlets = 4 self.outlets = 0 return true end pdlua-0.7.3/examples/lsymbol-drip-help.pd0000644000175000017500000000656111743054211020574 0ustar zmoelnigzmoelnig#N canvas 535 299 684 437 10; #X declare -lib pdlua; #X obj 23 8 import pdlua; #X obj 166 218 lsymbol-drip; #X msg 24 59 what; #X symbolatom 121 157 10 0 0 0 - - -; #X obj 91 141 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 73 108 symbol qwertyuiop; #X obj 166 253 print dripped; #X text 234 284 by Martin Peach 2012_04_03; #X text 258 218 [lsymbol-drip] spits out the characters of a symbol. ; #X msg 45 80 why not; #X text 98 79 <- but a message is rejected; #X text 58 59 <- a lone selector is taken to be a symbol; #X text 216 181 <- unicode should be handled correctly; #X obj 43 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 237 286 sel a b c d e f g h i j k l m n o p q r s t u v w x y z; #X obj 63 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 83 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 103 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 123 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 143 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 163 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 183 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 203 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 223 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 243 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 263 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 283 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 303 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 323 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 343 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 363 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 383 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 403 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 423 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 443 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 463 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 483 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 503 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 523 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 543 314 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 146 181 symbol zéyé; #X text 430 404 by Martin Peach 2012_04_03; #X msg 121 130 set Who; #X symbolatom 564 314 10 0 0 0 - - -; #X connect 1 0 6 0; #X connect 1 0 14 0; #X connect 2 0 1 0; #X connect 3 0 1 0; #X connect 4 0 3 0; #X connect 5 0 1 0; #X connect 9 0 1 0; #X connect 14 0 13 0; #X connect 14 1 15 0; #X connect 14 2 16 0; #X connect 14 3 17 0; #X connect 14 4 18 0; #X connect 14 5 19 0; #X connect 14 6 20 0; #X connect 14 7 21 0; #X connect 14 8 22 0; #X connect 14 9 23 0; #X connect 14 10 24 0; #X connect 14 11 25 0; #X connect 14 12 26 0; #X connect 14 13 27 0; #X connect 14 14 28 0; #X connect 14 15 29 0; #X connect 14 16 30 0; #X connect 14 17 31 0; #X connect 14 18 32 0; #X connect 14 19 33 0; #X connect 14 20 34 0; #X connect 14 21 35 0; #X connect 14 22 36 0; #X connect 14 23 37 0; #X connect 14 24 38 0; #X connect 14 25 39 0; #X connect 14 26 43 0; #X connect 40 0 1 0; #X connect 42 0 3 0; pdlua-0.7.3/examples/lsymbol2bytes-help.pd0000644000175000017500000000147211754221357020776 0ustar zmoelnigzmoelnig#N canvas 536 461 616 315 10; #X declare -lib pdlua; #X obj 23 8 import pdlua; #X msg 24 59 what; #X symbolatom 121 157 10 0 0 0 - - -; #X obj 91 141 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 73 108 symbol qwertyuiop; #X msg 45 80 why not; #X text 98 79 <- but a message is rejected; #X text 58 59 <- a lone selector is taken to be a symbol; #X text 216 181 <- unicode should be handled correctly; #X msg 146 181 symbol zéyé; #X msg 121 130 set Who; #X obj 166 218 lsymbol2bytes; #X text 258 218 [lsymbol2bytes] spits out the characters of a symbol as bytes.; #X obj 166 253 print bytes; #X text 407 261 by Martin Peach 2012_04_20; #X connect 1 0 11 0; #X connect 2 0 11 0; #X connect 3 0 2 0; #X connect 4 0 11 0; #X connect 5 0 11 0; #X connect 9 0 11 0; #X connect 10 0 2 0; #X connect 11 0 13 0; pdlua-0.7.3/examples/shared-help.pd0000644000175000017500000000232411674625145017433 0ustar zmoelnigzmoelnig#N canvas 0 22 450 300 10; #X obj 20 71 shared foo; #X obj 139 72 shared foo; #X obj 22 191 shared bar; #X obj 141 194 shared bar; #X obj 141 241 print bar; #X obj 139 115 print foo; #X floatatom 85 28 5 0 0 0 - - -; #X symbolatom 204 29 10 0 0 0 - - -; #X obj 139 28 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 20 28 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 87 158 5 0 0 0 - - -; #X symbolatom 206 159 10 0 0 0 - - -; #X obj 141 158 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 22 158 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 289 72 shared foo; #X obj 289 28 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 354 27 a b c; #X obj 291 194 shared bar; #X obj 291 158 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 356 158 d e f; #X connect 0 0 5 0; #X connect 1 0 5 0; #X connect 2 0 4 0; #X connect 3 0 4 0; #X connect 6 0 0 1; #X connect 7 0 1 1; #X connect 8 0 1 0; #X connect 9 0 0 0; #X connect 10 0 2 1; #X connect 11 0 3 1; #X connect 12 0 3 0; #X connect 13 0 2 0; #X connect 14 0 5 0; #X connect 15 0 14 0; #X connect 16 0 14 1; #X connect 17 0 4 0; #X connect 18 0 17 0; #X connect 19 0 17 1; pdlua-0.7.3/examples/ldemux.pd_lua0000644000175000017500000000134411674625145017377 0ustar zmoelnigzmoelnig-- contributed by Frank Barknecht local LDemux = pd.Class:new():register("ldemux") function LDemux:initialize(name, atoms) local n = atoms[1] or 2 -- default to 2 outlets. if type(n) ~= "number" or n < 2 then pd.post("ldemux: wrong outlet-count argument, using 2 outlets instead") n = 2 end self.outlets = n self.inlets = 2 self.to = 1 -- second arg, if a number, selects default outlet if type(atoms[2]) == "number" then self:in_2_float(atoms[2]) end return true end function LDemux:in_2_float(f) -- clip selection between left- and rightmost outlet self.to = math.max(1, math.min(self.outlets, f)) end function LDemux:in_1(s, m) self:outlet(self.to, s, m) end pdlua-0.7.3/examples/simplecounter.pd_luax0000644000175000017500000000042611674625145021162 0ustar zmoelnigzmoelnigreturn function (self, sel, atoms) self.inlets = 1 self.outlets = 1 self.count = 0 if type(atoms[1]) == "number" then self.count = atoms[1] end function self:in_1_bang() self:outlet(1, "float", {self.count}) self.count = self.count + 1 end return true end pdlua-0.7.3/examples/complex-help.pd0000644000175000017500000000071611725437660017637 0ustar zmoelnigzmoelnig#N canvas 470 713 450 282 10; #X obj 143 142 complex; #X obj 144 114 pdluax complex; #X text 55 55 These two attempt to load a lua module named "complex". ; #X text 64 206 Several different Lua modules named 'complex' are available \, for example: http://philippe.castagliola.free.fr/LUA/complex.html ; #X text 56 165 If they fail the paths searched will be shown in the Pd console.; #X text 56 71 If they succeed they will print a list of items in the module.; pdlua-0.7.3/examples/list-unpack-help.pd0000644000175000017500000000216711674625145020424 0ustar zmoelnigzmoelnig#N canvas 168 175 727 437 10; #X msg 246 129 1 2 3; #X msg 149 129 1; #X obj 149 221 list-unpack 3; #X obj 149 302 print lu0; #X obj 192 282 print lu1; #X obj 235 262 print lu2; #X msg 389 128 a b c; #X msg 461 128 1 2 3 4; #X msg 179 129 symbol x; #X msg 295 128 list a b c; #X text 272 103 lists; #X text 153 106 float; #X text 192 105 symbol; #X text 385 105 anything; #X text 461 105 too long; #X obj 340 221 list-unpack; #X obj 429 221 list-unpack 0; #X obj 339 330 list-unpack -1; #X text 58 53 Like [unpack] for any kind of type. Argument specifies number of outlets. Pointers untested rsp. not supported; #X text 42 25 [list-unpack]; #X text 64 389 2007 Frank Barknecht; #X obj 341 267 list-unpack 28 -----------------------------------; #X text 337 244 Second arg is ignored and can be used for stretching ; #X text 338 196 Default number of outlets is 1 \, even if you want 0:; #X text 338 302 But these won't create:; #X obj 339 353 list-unpack three; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 2 1 4 0; #X connect 2 2 5 0; #X connect 6 0 2 0; #X connect 7 0 2 0; #X connect 8 0 2 0; #X connect 9 0 2 0; pdlua-0.7.3/examples/dispatchertest.pd_luax0000644000175000017500000000053111674625145021314 0ustar zmoelnigzmoelnigreturn function (self, sel, atoms) self.inlets = 3 function self:in_1_float(f) pd.post("float: " .. f) end function self:in_2_symbol(s) pd.post("symbol: " .. s) end function self:in_3_foo(atoms) pd.post("foo(") for i,v in ipairs(atoms) do pd.post(" " .. i .. " = " .. v) end pd.post(")") end return true end pdlua-0.7.3/examples/nop.pd_lua0000644000175000017500000000026111674625145016672 0ustar zmoelnigzmoelniglocal Nop = pd.Class:new():register("nop") function Nop:initialize() self.inlets = 1 self.outlets = 1 return true end function Nop:in_1(s, m) self:outlet(1, s, m) end pdlua-0.7.3/examples/ltabfill.pd_lua0000644000175000017500000000743511674625145017701 0ustar zmoelnigzmoelniglocal ltabfill = pd.Class:new():register("ltabfill") local function sandbox(e, f, x) -- only supports unary f() with one return local g = getfenv(f) setfenv(f, e) local r = f(x) setfenv(f, g) return r end local ltabfill_globals = { abs = math.abs, acos = math.acos, asin = math.asin, atan = math.atan, atan2 = math.atan2, ceil = math.ceil, cos = math.cos, cosh = math.cosh, deg = math.deg, exp = math.exp, floor = math.floor, fmod = math.fmod, log = math.log, log10 = math.log10, max = math.max, min = math.min, int = function (x) i,f = math.modf(x) ; return i end, wrap = function (x) i,f = math.modf(x) ; return f end, pi = math.pi, pow = math.pow, rad = math.rad, sin = math.sin, sinh = math.sinh, sqrt = math.sqrt, tan = math.tan, tanh = math.tanh, val = function (s) return (pd.getvalue(s) or 0) end } function ltabfill:readexpr(atoms) local vname = { } local context = { } local expr local i local k local v local j = 2 local inlets local f local phase = "table" for k,v in pairs(ltabfill_globals) do context[k] = v end for i,v in ipairs(atoms) do if phase == "table" then if type(v) == "string" then self.tabname = v phase = "vars" else self:error("ltabfill: table name must be a symbol") return -1 end else if phase == "vars" then -- create variables if v == "->" then inlets = i - 1 phase = "expr" expr = "" else if type(v) == "string" then vname[j] = v context[v] = 0 j = j + 1 else self:error("ltabfill: variable names must be symbols") return -1 end end else if phase == "expr" then -- build string expr = expr .. " " .. v else self:error("ltabfill: internal error parsing expression") return -1 end end end end f = assert(loadstring("return function(x) return " .. expr .. " end"))() return inlets, vname, context, f, 0 end function ltabfill:initialize(sel, atoms) self.tabname = nil self.vname = { } self.context = { } self.hot = { } self.f = function (x) return 0 end function self:in_1_bang() if self.tabname ~= nil then local t = pd.Table:new():sync(self.tabname) if t ~= nil then local i local l = t:length() for i = 1,l do local y = sandbox(self.context, self.f, (i-1)/l) t:set(i-1, y) end t:redraw() end end end function self:in_1_symbol(s) self.tabname = s if self.hot[1] then self:in_1_bang() end end function self:in_1_float(f) self:error("table name expected, got a float") end function self:in_n_float(i, f) self.context[self.vname[i]] = f if self.hot[i] then self:in_1_bang() end end function self:in_n_symbol(i, s) self.context[self.vname[i]] = s if self.hot[i] then self:in_1_bang() end end function self:in_n_hot(i, atoms) if type(atoms[1]) == "number" then self.hot[i] = atoms[1] ~= 0 else self:error("hot method expects a float") end end function self:in_1_ltabfill(atoms) local inlets local vname local context local f local outlets inlets, vname, context, f, outlets = self:readexpr(atoms) if (inlets == self.inlets) and (outlets == self.outlets) then self.vname = vname self.context = context self.f = f else self:error("new expression has different inlet/outlet count") end end self.inlets, self.vname, self.context, self.f, self.outlets = self:readexpr(atoms) if self.inlets < 1 then pd.post("ltabfill: error: would have no inlets") return false end for i = 1,self.inlets,1 do self.hot[i] = i == 1 end return true end pdlua-0.7.3/examples/errors-help.pd0000644000175000017500000000033311674625145017477 0ustar zmoelnigzmoelnig#N canvas 0 22 450 300 10; #X obj 58 171 errors; #X msg 31 64 moo; #X msg 100 100 list moo baa; #X msg 130 132 1; #X msg 70 67 symbol baa; #X connect 1 0 0 0; #X connect 2 0 0 2; #X connect 3 0 0 3; #X connect 4 0 0 1; pdlua-0.7.3/examples/swarm-help.pd0000644000175000017500000003767311674625145017335 0ustar zmoelnigzmoelnig#N canvas 0 0 453 370 10; #N canvas 0 0 450 300 \$0-swarm-visualisation 0; #X obj 155 111 bng 8 250 50 0 \$0-bang-s \$0-1-r empty 17 7 0 10 -258113 -1 -1; #X obj 164 85 bng 8 250 50 0 \$0-bang-s \$0-2-r empty 17 7 0 10 -258113 -1 -1; #X obj 150 139 bng 8 250 50 0 \$0-bang-s \$0-3-r empty 17 7 0 10 -258113 -1 -1; #X obj 121 102 bng 8 250 50 0 \$0-bang-s \$0-4-r empty 17 7 0 10 -258113 -1 -1; #X obj 118 102 bng 8 250 50 0 \$0-bang-s \$0-5-r empty 17 7 0 10 -258113 -1 -1; #X obj 129 145 bng 8 250 50 0 \$0-bang-s \$0-6-r empty 17 7 0 10 -258113 -1 -1; #X obj 129 147 bng 8 250 50 0 \$0-bang-s \$0-7-r empty 17 7 0 10 -258113 -1 -1; #X obj 128 101 bng 8 250 50 0 \$0-bang-s \$0-8-r empty 17 7 0 10 -258113 -1 -1; #X obj 128 94 bng 8 250 50 0 \$0-bang-s \$0-9-r empty 17 7 0 10 -258113 -1 -1; #X obj 97 124 bng 8 250 50 0 \$0-bang-s \$0-10-r empty 17 7 0 10 -258113 -1 -1; #X obj 172 134 bng 8 250 50 0 \$0-bang-s \$0-11-r empty 17 7 0 10 -258113 -1 -1; #X obj 125 146 bng 8 250 50 0 \$0-bang-s \$0-12-r empty 17 7 0 10 -258113 -1 -1; #X obj 125 96 bng 8 250 50 0 \$0-bang-s \$0-13-r empty 17 7 0 10 -258113 -1 -1; #X obj 94 126 bng 8 250 50 0 \$0-bang-s \$0-14-r empty 17 7 0 10 -258113 -1 -1; #X obj 116 101 bng 8 250 50 0 \$0-bang-s \$0-15-r empty 17 7 0 10 -258113 -1 -1; #X obj 107 107 bng 8 250 50 0 \$0-bang-s \$0-16-r empty 17 7 0 10 -258113 -1 -1; #X obj 126 147 bng 8 250 50 0 \$0-bang-s \$0-17-r empty 17 7 0 10 -4034 -1 -1; #X obj 125 148 bng 8 250 50 0 \$0-bang-s \$0-18-r empty 17 7 0 10 -258113 -1 -1; #X obj 156 119 bng 8 250 50 0 \$0-bang-s \$0-19-r empty 17 7 0 10 -258113 -1 -1; #X obj 103 92 bng 8 250 50 0 \$0-bang-s \$0-20-r empty 17 7 0 10 -258113 -1 -1; #X obj 156 122 bng 8 250 50 0 \$0-bang-s \$0-21-r empty 17 7 0 10 -258113 -1 -1; #X obj 117 146 bng 8 250 50 0 \$0-bang-s \$0-22-r empty 17 7 0 10 -258113 -1 -1; #X obj 116 104 bng 8 250 50 0 \$0-bang-s \$0-23-r empty 17 7 0 10 -258113 -1 -1; #X obj 130 155 bng 8 250 50 0 \$0-bang-s \$0-24-r empty 17 7 0 10 -258113 -1 -1; #X obj 118 100 bng 8 250 50 0 \$0-bang-s \$0-25-r empty 17 7 0 10 -258113 -1 -1; #X obj 159 82 bng 8 250 50 0 \$0-bang-s \$0-26-r empty 17 7 0 10 -258113 -1 -1; #X obj 126 157 bng 8 250 50 0 \$0-bang-s \$0-27-r empty 17 7 0 10 -258113 -1 -1; #X obj 125 157 bng 8 250 50 0 \$0-bang-s \$0-28-r empty 17 7 0 10 -258113 -1 -1; #X obj 119 147 bng 8 250 50 0 \$0-bang-s \$0-29-r empty 17 7 0 10 -258113 -1 -1; #X obj 150 125 bng 8 250 50 0 \$0-bang-s \$0-30-r empty 17 7 0 10 -258113 -1 -1; #X obj 150 125 bng 8 250 50 0 \$0-bang-s \$0-31-r empty 17 7 0 10 -258113 -1 -1; #X obj 155 103 bng 8 250 50 0 \$0-bang-s \$0-32-r empty 17 7 0 10 -258113 -1 -1; #X coords 0 -1 1 1 200 200 2 0 0; #X restore 220 31 pd \$0-swarm-visualisation; #X obj 15 202 + 100; #X obj 84 201 + 100; #X obj 25 255 pack f f s; #X obj 31 231 makefilename \$0-%d-r; #X msg 25 279 \; \$3 pos \$1 \$2; #X obj 13 4 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1 ; #X obj 29 57 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 75 72 randomize; #X obj 85 178 * 100; #X obj 16 179 * 100; #X obj 17 132 swarm 2 32; #X obj 17 157 unpack f f; #X obj 133 256 list prepend; #X obj 120 336 dac~; #N canvas 0 0 1009 708 \$0-audio 0; #X obj 9 74 unpack f f; #X obj 7 97 * 200; #X obj 6 121 + 300; #X obj 5 143 osc~; #X obj 71 102 * 0.5; #X obj 69 129 + 0.5; #X obj 137 28 route 1 2 3 4; #X obj 5 174 *~ 0; #X obj 127 77 unpack f f; #X obj 125 100 * 200; #X obj 124 124 + 300; #X obj 123 146 osc~; #X obj 189 105 * 0.5; #X obj 187 132 + 0.5; #X obj 123 177 *~ 0; #X obj 198 220 *~ 0.25; #X obj 236 78 unpack f f; #X obj 234 101 * 200; #X obj 233 125 + 300; #X obj 232 147 osc~; #X obj 298 106 * 0.5; #X obj 296 133 + 0.5; #X obj 232 178 *~ 0; #X obj 354 81 unpack f f; #X obj 352 104 * 200; #X obj 351 128 + 300; #X obj 350 150 osc~; #X obj 416 109 * 0.5; #X obj 414 136 + 0.5; #X obj 350 181 *~ 0; #X obj 490 76 unpack f f; #X obj 488 99 * 200; #X obj 487 123 + 300; #X obj 486 145 osc~; #X obj 552 104 * 0.5; #X obj 550 131 + 0.5; #X obj 486 176 *~ 0; #X obj 608 79 unpack f f; #X obj 606 102 * 200; #X obj 605 126 + 300; #X obj 604 148 osc~; #X obj 670 107 * 0.5; #X obj 668 134 + 0.5; #X obj 604 179 *~ 0; #X obj 679 222 *~ 0.25; #X obj 717 80 unpack f f; #X obj 715 103 * 200; #X obj 714 127 + 300; #X obj 713 149 osc~; #X obj 779 108 * 0.5; #X obj 777 135 + 0.5; #X obj 713 180 *~ 0; #X obj 835 83 unpack f f; #X obj 833 106 * 200; #X obj 832 130 + 300; #X obj 831 152 osc~; #X obj 897 111 * 0.5; #X obj 895 138 + 0.5; #X obj 831 183 *~ 0; #X obj 618 30 route 5 6 7 8; #X obj 137 7 inlet; #X obj 9 294 unpack f f; #X obj 7 317 * 200; #X obj 6 341 + 300; #X obj 5 363 osc~; #X obj 71 322 * 0.5; #X obj 69 349 + 0.5; #X obj 5 394 *~ 0; #X obj 127 297 unpack f f; #X obj 125 320 * 200; #X obj 124 344 + 300; #X obj 123 366 osc~; #X obj 189 325 * 0.5; #X obj 187 352 + 0.5; #X obj 123 397 *~ 0; #X obj 198 440 *~ 0.25; #X obj 236 298 unpack f f; #X obj 234 321 * 200; #X obj 233 345 + 300; #X obj 232 367 osc~; #X obj 298 326 * 0.5; #X obj 296 353 + 0.5; #X obj 232 398 *~ 0; #X obj 354 301 unpack f f; #X obj 352 324 * 200; #X obj 351 348 + 300; #X obj 350 370 osc~; #X obj 416 329 * 0.5; #X obj 414 356 + 0.5; #X obj 350 401 *~ 0; #X obj 490 296 unpack f f; #X obj 488 319 * 200; #X obj 487 343 + 300; #X obj 486 365 osc~; #X obj 552 324 * 0.5; #X obj 550 351 + 0.5; #X obj 486 396 *~ 0; #X obj 608 299 unpack f f; #X obj 606 322 * 200; #X obj 605 346 + 300; #X obj 604 368 osc~; #X obj 670 327 * 0.5; #X obj 668 354 + 0.5; #X obj 604 399 *~ 0; #X obj 679 442 *~ 0.25; #X obj 717 300 unpack f f; #X obj 715 323 * 200; #X obj 714 347 + 300; #X obj 713 369 osc~; #X obj 779 328 * 0.5; #X obj 777 355 + 0.5; #X obj 713 400 *~ 0; #X obj 835 303 unpack f f; #X obj 833 326 * 200; #X obj 832 350 + 300; #X obj 831 372 osc~; #X obj 897 331 * 0.5; #X obj 895 358 + 0.5; #X obj 831 403 *~ 0; #X obj 137 248 route 9 10 11 12; #X obj 618 250 route 13 14 15 16; #X obj 4 514 unpack f f; #X obj 2 537 * 200; #X obj 1 561 + 300; #X obj 0 583 osc~; #X obj 66 542 * 0.5; #X obj 64 569 + 0.5; #X obj 0 614 *~ 0; #X obj 122 517 unpack f f; #X obj 120 540 * 200; #X obj 119 564 + 300; #X obj 118 586 osc~; #X obj 184 545 * 0.5; #X obj 182 572 + 0.5; #X obj 118 617 *~ 0; #X obj 193 660 *~ 0.25; #X obj 231 518 unpack f f; #X obj 229 541 * 200; #X obj 228 565 + 300; #X obj 227 587 osc~; #X obj 293 546 * 0.5; #X obj 291 573 + 0.5; #X obj 227 618 *~ 0; #X obj 349 521 unpack f f; #X obj 347 544 * 200; #X obj 346 568 + 300; #X obj 345 590 osc~; #X obj 411 549 * 0.5; #X obj 409 576 + 0.5; #X obj 345 621 *~ 0; #X obj 485 516 unpack f f; #X obj 483 539 * 200; #X obj 482 563 + 300; #X obj 481 585 osc~; #X obj 547 544 * 0.5; #X obj 545 571 + 0.5; #X obj 481 616 *~ 0; #X obj 603 519 unpack f f; #X obj 601 542 * 200; #X obj 600 566 + 300; #X obj 599 588 osc~; #X obj 665 547 * 0.5; #X obj 663 574 + 0.5; #X obj 599 619 *~ 0; #X obj 674 662 *~ 0.25; #X obj 712 520 unpack f f; #X obj 710 543 * 200; #X obj 709 567 + 300; #X obj 708 589 osc~; #X obj 774 548 * 0.5; #X obj 772 575 + 0.5; #X obj 708 620 *~ 0; #X obj 830 523 unpack f f; #X obj 828 546 * 200; #X obj 827 570 + 300; #X obj 826 592 osc~; #X obj 892 551 * 0.5; #X obj 890 578 + 0.5; #X obj 826 623 *~ 0; #X obj 4 734 unpack f f; #X obj 2 757 * 200; #X obj 1 781 + 300; #X obj 0 803 osc~; #X obj 66 762 * 0.5; #X obj 64 789 + 0.5; #X obj 0 834 *~ 0; #X obj 122 737 unpack f f; #X obj 120 760 * 200; #X obj 119 784 + 300; #X obj 118 806 osc~; #X obj 184 765 * 0.5; #X obj 182 792 + 0.5; #X obj 118 837 *~ 0; #X obj 193 880 *~ 0.25; #X obj 231 738 unpack f f; #X obj 229 761 * 200; #X obj 228 785 + 300; #X obj 227 807 osc~; #X obj 293 766 * 0.5; #X obj 291 793 + 0.5; #X obj 227 838 *~ 0; #X obj 349 741 unpack f f; #X obj 347 764 * 200; #X obj 346 788 + 300; #X obj 345 810 osc~; #X obj 411 769 * 0.5; #X obj 409 796 + 0.5; #X obj 345 841 *~ 0; #X obj 485 736 unpack f f; #X obj 483 759 * 200; #X obj 482 783 + 300; #X obj 481 805 osc~; #X obj 547 764 * 0.5; #X obj 545 791 + 0.5; #X obj 481 836 *~ 0; #X obj 603 739 unpack f f; #X obj 601 762 * 200; #X obj 600 786 + 300; #X obj 599 808 osc~; #X obj 665 767 * 0.5; #X obj 663 794 + 0.5; #X obj 599 839 *~ 0; #X obj 674 882 *~ 0.25; #X obj 712 740 unpack f f; #X obj 710 763 * 200; #X obj 709 787 + 300; #X obj 708 809 osc~; #X obj 774 768 * 0.5; #X obj 772 795 + 0.5; #X obj 708 840 *~ 0; #X obj 830 743 unpack f f; #X obj 828 766 * 200; #X obj 827 790 + 300; #X obj 826 812 osc~; #X obj 892 771 * 0.5; #X obj 890 798 + 0.5; #X obj 826 843 *~ 0; #X obj 132 468 route 17 18 19 20; #X obj 613 470 route 21 22 23 24; #X obj 132 689 route 25 26 27 28; #X obj 613 690 route 29 30 31 32; #X obj 418 910 outlet~; #X text 360 4 stupid copy and paste \, but whatever...; #X obj 410 887 *~ 0.125; #X connect 0 0 1 0; #X connect 0 1 4 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 7 0; #X connect 4 0 5 0; #X connect 5 0 7 1; #X connect 6 0 0 0; #X connect 6 1 8 0; #X connect 6 2 16 0; #X connect 6 3 23 0; #X connect 6 4 59 0; #X connect 7 0 15 0; #X connect 8 0 9 0; #X connect 8 1 12 0; #X connect 9 0 10 0; #X connect 10 0 11 0; #X connect 11 0 14 0; #X connect 12 0 13 0; #X connect 13 0 14 1; #X connect 14 0 15 0; #X connect 15 0 243 0; #X connect 16 0 17 0; #X connect 16 1 20 0; #X connect 17 0 18 0; #X connect 18 0 19 0; #X connect 19 0 22 0; #X connect 20 0 21 0; #X connect 21 0 22 1; #X connect 22 0 15 0; #X connect 23 0 24 0; #X connect 23 1 27 0; #X connect 24 0 25 0; #X connect 25 0 26 0; #X connect 26 0 29 0; #X connect 27 0 28 0; #X connect 28 0 29 1; #X connect 29 0 15 0; #X connect 30 0 31 0; #X connect 30 1 34 0; #X connect 31 0 32 0; #X connect 32 0 33 0; #X connect 33 0 36 0; #X connect 34 0 35 0; #X connect 35 0 36 1; #X connect 36 0 44 0; #X connect 37 0 38 0; #X connect 37 1 41 0; #X connect 38 0 39 0; #X connect 39 0 40 0; #X connect 40 0 43 0; #X connect 41 0 42 0; #X connect 42 0 43 1; #X connect 43 0 44 0; #X connect 44 0 243 0; #X connect 45 0 46 0; #X connect 45 1 49 0; #X connect 46 0 47 0; #X connect 47 0 48 0; #X connect 48 0 51 0; #X connect 49 0 50 0; #X connect 50 0 51 1; #X connect 51 0 44 0; #X connect 52 0 53 0; #X connect 52 1 56 0; #X connect 53 0 54 0; #X connect 54 0 55 0; #X connect 55 0 58 0; #X connect 56 0 57 0; #X connect 57 0 58 1; #X connect 58 0 44 0; #X connect 59 0 30 0; #X connect 59 1 37 0; #X connect 59 2 45 0; #X connect 59 3 52 0; #X connect 59 4 119 0; #X connect 60 0 6 0; #X connect 61 0 62 0; #X connect 61 1 65 0; #X connect 62 0 63 0; #X connect 63 0 64 0; #X connect 64 0 67 0; #X connect 65 0 66 0; #X connect 66 0 67 1; #X connect 67 0 75 0; #X connect 68 0 69 0; #X connect 68 1 72 0; #X connect 69 0 70 0; #X connect 70 0 71 0; #X connect 71 0 74 0; #X connect 72 0 73 0; #X connect 73 0 74 1; #X connect 74 0 75 0; #X connect 75 0 243 0; #X connect 76 0 77 0; #X connect 76 1 80 0; #X connect 77 0 78 0; #X connect 78 0 79 0; #X connect 79 0 82 0; #X connect 80 0 81 0; #X connect 81 0 82 1; #X connect 82 0 75 0; #X connect 83 0 84 0; #X connect 83 1 87 0; #X connect 84 0 85 0; #X connect 85 0 86 0; #X connect 86 0 89 0; #X connect 87 0 88 0; #X connect 88 0 89 1; #X connect 89 0 75 0; #X connect 90 0 91 0; #X connect 90 1 94 0; #X connect 91 0 92 0; #X connect 92 0 93 0; #X connect 93 0 96 0; #X connect 94 0 95 0; #X connect 95 0 96 1; #X connect 96 0 104 0; #X connect 97 0 98 0; #X connect 97 1 101 0; #X connect 98 0 99 0; #X connect 99 0 100 0; #X connect 100 0 103 0; #X connect 101 0 102 0; #X connect 102 0 103 1; #X connect 103 0 104 0; #X connect 104 0 243 0; #X connect 105 0 106 0; #X connect 105 1 109 0; #X connect 106 0 107 0; #X connect 107 0 108 0; #X connect 108 0 111 0; #X connect 109 0 110 0; #X connect 110 0 111 1; #X connect 111 0 104 0; #X connect 112 0 113 0; #X connect 112 1 116 0; #X connect 113 0 114 0; #X connect 114 0 115 0; #X connect 115 0 118 0; #X connect 116 0 117 0; #X connect 117 0 118 1; #X connect 118 0 104 0; #X connect 119 0 61 0; #X connect 119 1 68 0; #X connect 119 2 76 0; #X connect 119 3 83 0; #X connect 119 4 120 0; #X connect 120 0 90 0; #X connect 120 1 97 0; #X connect 120 2 105 0; #X connect 120 3 112 0; #X connect 120 4 237 0; #X connect 121 0 122 0; #X connect 121 1 125 0; #X connect 122 0 123 0; #X connect 123 0 124 0; #X connect 124 0 127 0; #X connect 125 0 126 0; #X connect 126 0 127 1; #X connect 127 0 135 0; #X connect 128 0 129 0; #X connect 128 1 132 0; #X connect 129 0 130 0; #X connect 130 0 131 0; #X connect 131 0 134 0; #X connect 132 0 133 0; #X connect 133 0 134 1; #X connect 134 0 135 0; #X connect 135 0 243 0; #X connect 136 0 137 0; #X connect 136 1 140 0; #X connect 137 0 138 0; #X connect 138 0 139 0; #X connect 139 0 142 0; #X connect 140 0 141 0; #X connect 141 0 142 1; #X connect 142 0 135 0; #X connect 143 0 144 0; #X connect 143 1 147 0; #X connect 144 0 145 0; #X connect 145 0 146 0; #X connect 146 0 149 0; #X connect 147 0 148 0; #X connect 148 0 149 1; #X connect 149 0 135 0; #X connect 150 0 151 0; #X connect 150 1 154 0; #X connect 151 0 152 0; #X connect 152 0 153 0; #X connect 153 0 156 0; #X connect 154 0 155 0; #X connect 155 0 156 1; #X connect 156 0 164 0; #X connect 157 0 158 0; #X connect 157 1 161 0; #X connect 158 0 159 0; #X connect 159 0 160 0; #X connect 160 0 163 0; #X connect 161 0 162 0; #X connect 162 0 163 1; #X connect 163 0 164 0; #X connect 164 0 243 0; #X connect 165 0 166 0; #X connect 165 1 169 0; #X connect 166 0 167 0; #X connect 167 0 168 0; #X connect 168 0 171 0; #X connect 169 0 170 0; #X connect 170 0 171 1; #X connect 171 0 164 0; #X connect 172 0 173 0; #X connect 172 1 176 0; #X connect 173 0 174 0; #X connect 174 0 175 0; #X connect 175 0 178 0; #X connect 176 0 177 0; #X connect 177 0 178 1; #X connect 178 0 164 0; #X connect 179 0 180 0; #X connect 179 1 183 0; #X connect 180 0 181 0; #X connect 181 0 182 0; #X connect 182 0 185 0; #X connect 183 0 184 0; #X connect 184 0 185 1; #X connect 185 0 193 0; #X connect 186 0 187 0; #X connect 186 1 190 0; #X connect 187 0 188 0; #X connect 188 0 189 0; #X connect 189 0 192 0; #X connect 190 0 191 0; #X connect 191 0 192 1; #X connect 192 0 193 0; #X connect 193 0 243 0; #X connect 194 0 195 0; #X connect 194 1 198 0; #X connect 195 0 196 0; #X connect 196 0 197 0; #X connect 197 0 200 0; #X connect 198 0 199 0; #X connect 199 0 200 1; #X connect 200 0 193 0; #X connect 201 0 202 0; #X connect 201 1 205 0; #X connect 202 0 203 0; #X connect 203 0 204 0; #X connect 204 0 207 0; #X connect 205 0 206 0; #X connect 206 0 207 1; #X connect 207 0 193 0; #X connect 208 0 209 0; #X connect 208 1 212 0; #X connect 209 0 210 0; #X connect 210 0 211 0; #X connect 211 0 214 0; #X connect 212 0 213 0; #X connect 213 0 214 1; #X connect 214 0 222 0; #X connect 215 0 216 0; #X connect 215 1 219 0; #X connect 216 0 217 0; #X connect 217 0 218 0; #X connect 218 0 221 0; #X connect 219 0 220 0; #X connect 220 0 221 1; #X connect 221 0 222 0; #X connect 222 0 243 0; #X connect 223 0 224 0; #X connect 223 1 227 0; #X connect 224 0 225 0; #X connect 225 0 226 0; #X connect 226 0 229 0; #X connect 227 0 228 0; #X connect 228 0 229 1; #X connect 229 0 222 0; #X connect 230 0 231 0; #X connect 230 1 234 0; #X connect 231 0 232 0; #X connect 232 0 233 0; #X connect 233 0 236 0; #X connect 234 0 235 0; #X connect 235 0 236 1; #X connect 236 0 222 0; #X connect 237 0 121 0; #X connect 237 1 128 0; #X connect 237 2 136 0; #X connect 237 3 143 0; #X connect 237 4 238 0; #X connect 238 0 150 0; #X connect 238 1 157 0; #X connect 238 2 165 0; #X connect 238 3 172 0; #X connect 238 4 239 0; #X connect 239 0 179 0; #X connect 239 1 186 0; #X connect 239 2 194 0; #X connect 239 3 201 0; #X connect 239 4 240 0; #X connect 240 0 208 0; #X connect 240 1 215 0; #X connect 240 2 223 0; #X connect 240 3 230 0; #X connect 243 0 241 0; #X restore 133 282 pd \$0-audio; #X obj 13 33 metro 40; #X text 181 309 boids-style swarm in pd with Lua; #X connect 1 0 3 0; #X connect 2 0 3 1; #X connect 3 0 5 0; #X connect 4 0 3 2; #X connect 6 0 16 0; #X connect 7 0 11 0; #X connect 8 0 11 0; #X connect 9 0 2 0; #X connect 10 0 1 0; #X connect 11 0 12 0; #X connect 11 0 13 0; #X connect 11 1 4 0; #X connect 11 1 13 1; #X connect 12 0 10 0; #X connect 12 1 9 0; #X connect 13 0 15 0; #X connect 15 0 14 0; #X connect 15 0 14 1; #X connect 16 0 11 0; pdlua-0.7.3/examples/llist-drip.pd_lua0000644000175000017500000000217611743054211020153 0ustar zmoelnigzmoelnig--[[ llist-drip Output a list as a sequence of elements, same as [list-abs/list-drip] author Martin Peach 20120403 --]] -- Pd class local LlistDrip = pd.Class:new():register("llist-drip") local selectormap = {string = "symbol", number="float", userdata="pointer"} -- for lua/Pd type conversion function LlistDrip:initialize(name, atoms) self.inlets = 1 self.outlets = 1 return true end function LlistDrip:in_1(sel, atoms) -- anything --pd.post("sel is " .. sel); --pd.post("number of atoms is ".. #atoms) --for i,v in ipairs(atoms) do -- pd.post(i .. " = " .. v) --end if sel == "list" then -- the usual case for i=1, #atoms do -- map lua types to pd selectors self:outlet(1, selectormap[type(atoms[i])], {atoms[i]}) end elseif sel == "float" or sel == "symbol" or sel == "pointer" or sel == "bang" then -- single element "lists" self:outlet(1, sel, {atoms[1]}) else -- messages are lists beginning with a selector self:outlet(1, selectormap[type(sel)], {sel}) for i=1, #atoms do self:outlet(1, selectormap[type(atoms[i])], {atoms[i]}) end end end -- end of llist-drip pdlua-0.7.3/examples/ldelay.pd_lua0000644000175000017500000000142611674625145017354 0ustar zmoelnigzmoelnig-- reimplementation of [delay] in Lua to test clock support local LDelay = pd.Class:new():register("ldelay") function LDelay:initialize(name, atoms) if type(atoms[1]) ~= "number" or atoms[1] < 0 then self.delay = 1000 else self.delay = atoms[1] end self.inlets = 2 self.outlets = 1 return true end function LDelay:postinitialize() self.clock = pd.Clock:new():register(self, "trigger") end function LDelay:finalize() self.clock:destruct() end function LDelay:in_2_float(f) self.delay = math.max(0, f) end function LDelay:in_1_float(f) self:in_2_float(f) self:in_1_bang() end function LDelay:in_1_bang() self.clock:delay(self.delay) end function LDelay:in_1_stop() self.clock:unset() end function LDelay:trigger() self:outlet(1, "bang", {}) end pdlua-0.7.3/examples/nop-test-gem.pd0000644000175000017500000000057211725437660017561 0ustar zmoelnigzmoelnig#N canvas 243 69 450 300 10; #X declare -lib Gem; #X obj 73 129 nop; #X obj 73 76 gemhead; #X obj 73 194 cube; #X obj 202 194 gemwin; #X obj 202 109 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 247 111 create; #X msg 249 150 destroy; #X obj 188 45 import Gem; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 3 0; pdlua-0.7.3/examples/ltextfile-drip-help.pd0000644000175000017500000000422612153315417021113 0ustar zmoelnigzmoelnig#N canvas 480 515 796 478 10; #X msg 145 184 open test.txt; #X obj 184 223 openpanel; #X obj 122 208 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 95 66 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 125 165 5 0 0 0 - - -; #X msg 163 202 open tewt.txt; #X obj 553 336 print EOF; #X msg 203 242 rewind; #X text 393 323 bang when no more lines; #X text 252 241 rewind file to zero; #X text 477 274 argument is a file name to be opened; #X text 227 430 written in pd_lua by Martin Peach 2012/09/17; #X text 239 183 open a file by name; #X text 249 201 nonexistent file prints an error; #X text 245 222 choose a file to open; #X obj 201 380 s word; #X obj 63 8 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1 ; #X obj 126 15 + 500; #X obj 126 -8 random 700; #X obj -7 1 r ready; #X msg 20 70 stop; #X obj -7 25 t b b; #X obj -7 49 delay 1000; #X text 213 142 ltextfile-drip reads a text file. Incoming bangs cause it to spit out sentences from the file in sequence.; #X obj 251 342 print dripped->; #X obj 154 66 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 319 388 print punctuation->; #X obj 95 134 spigot; #X obj 128 112 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X floatatom 194 58 5 0 0 0 - - -; #X obj 251 307 ltextfile-drip ../a_modest_proposal_gutenberg_1080.txt ; #X obj 95 92 delay 10; #X symbolatom 252 363 80 0 0 0 - - -; #X obj 63 38 metro 20000; #X obj 144 341 route bang; #X obj 144 401 print empty_line; #X obj 20 156 delay 60000; #X connect 0 0 30 0; #X connect 1 0 30 0; #X connect 2 0 1 0; #X connect 3 0 31 0; #X connect 3 0 36 0; #X connect 4 0 30 0; #X connect 5 0 30 0; #X connect 7 0 30 0; #X connect 16 0 33 0; #X connect 18 0 17 0; #X connect 19 0 21 0; #X connect 20 0 36 0; #X connect 21 0 22 0; #X connect 21 1 20 0; #X connect 22 0 3 0; #X connect 25 0 30 0; #X connect 27 0 30 0; #X connect 28 0 27 1; #X connect 29 0 31 1; #X connect 30 0 24 0; #X connect 30 0 32 0; #X connect 30 0 34 0; #X connect 30 1 26 0; #X connect 30 2 6 0; #X connect 30 2 7 0; #X connect 31 0 27 0; #X connect 33 0 30 0; #X connect 34 0 35 0; #X connect 34 0 3 0; #X connect 34 1 15 0; #X connect 36 0 3 0; pdlua-0.7.3/examples/nop-help.pd0000644000175000017500000000046011674625145016760 0ustar zmoelnigzmoelnig#N canvas 0 22 450 300 10; #X obj 131 138 nop; #X obj 131 179 print nop; #X floatatom 94 47 5 0 0 0 - - -; #X symbolatom 131 80 10 0 0 0 - - -; #X msg 160 103 foo foo foo foo foo; #X text 165 139 <---- (should) do nothing!; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; pdlua-0.7.3/examples/mutator-help.pd0000644000175000017500000000051311674625145017656 0ustar zmoelnigzmoelnig#N canvas 0 22 450 300 10; #X obj 91 98 mutator; #X obj 82 150 mutatee; #X obj 71 13 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 71 39 t b b b b b; #X obj 171 100 print checkpoint-charlie; #X connect 2 0 3 0; #X connect 3 0 1 0; #X connect 3 1 4 0; #X connect 3 2 0 0; #X connect 3 3 4 0; #X connect 3 4 1 0; pdlua-0.7.3/examples/luametro-help.pd0000644000175000017500000000350711674625145020021 0ustar zmoelnigzmoelnig#N canvas 0 0 636 570 10; #X obj 144 423 t b b; #X obj 144 449 timer; #X floatatom 144 474 5 0 0 0 - - -; #X obj 144 319 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 95 311 stop; #X msg 96 288 bang; #X obj 169 395 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 293 335 5 0 0 0 - - -; #X msg 293 312 1000; #X msg 332 311 500; #X msg 367 420 1000 a 2000; #X msg 365 399 list error bug; #X msg 366 334 750 250 500 250; #X obj 144 498 print; #X text 369 377 Only floats allowed in period list; #X text 43 14 lmetro; #X msg 96 333 start; #X text 294 290 lists or floats set new periods; #X obj 307 457 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 174 320 mode alea; #X msg 173 293 mode junk; #X obj 144 360 luametro 500 125 500 250; #X msg 176 339 mode 2; #X text 89 34 Like [metro] in Pd \, but allows more than one period. The periods will be evaluated in sequence from left to right as default. Min. period length is 0.01 msec.; #X text 86 90 With "mode" you can set the mode the metro uses to select delay periods. Four modes are available:; #X text 115 128 1: alea - select randomly; #X text 114 148 2: series - select randomly without repetitions; #X text 113 167 3: sequence - select in sequence from left to right (default mode); #X text 113 197 4: rota - go left to right \, then turn around and select right to left.; #X text 94 244 "mode 2" or "mode series" work both.; #X connect 0 0 1 0; #X connect 0 1 1 1; #X connect 1 0 2 0; #X connect 2 0 13 0; #X connect 3 0 21 0; #X connect 4 0 21 0; #X connect 5 0 21 0; #X connect 7 0 21 1; #X connect 8 0 7 0; #X connect 9 0 7 0; #X connect 10 0 21 1; #X connect 11 0 21 1; #X connect 12 0 21 1; #X connect 16 0 21 0; #X connect 19 0 21 0; #X connect 20 0 21 0; #X connect 21 0 6 0; #X connect 21 0 0 0; #X connect 21 1 18 0; #X connect 22 0 21 0; pdlua-0.7.3/examples/swarm.pd_lua0000644000175000017500000000551311674625145017234 0ustar zmoelnigzmoelnig-- see also: http://www.vergenet.net/~conrad/boids/pseudocode.html local swarm = pd.Class:new():register("swarm") function swarm:initialize(sel, atoms) -- constructor if type(atoms[1]) ~= "number" or atoms[1] < 2 then return false end if type(atoms[2]) ~= "number" or atoms[2] < 3 then return false end self.dim = math.floor(atoms[1]) self.count = math.floor(atoms[2]) self.cluster = 0.05 -- magic values look ok in the help patch.. self.distance2 = 0.2 self.similar2 = 0.1 self.friction = 0.96 self.flock = { } self:in_1_randomize() self.inlets = 2 self.outlets = 2 return true end function swarm:in_1_randomize() -- randomize positions, no movement for i = 1, self.count do self.flock[i] = { x = { }, dx = { } } for j = 1, self.dim do self.flock[i].x[j] = math.random() - 0.5 self.flock[i].dx[j] = 0 end self.flock[i].w = math.random() + 0.5 end end function swarm:in_1_bang() -- update and output local c = self:center() for i = 1, self.count do f = self.flock[i] -- update local v1 = self:rule1(c, f) local v2 = self:rule2(i, f) local v3 = self:rule3(i, f) for k = 1, self.dim do f.dx[k] = f.dx[k] + v1[k] + v2[k] + v3[k] end for k = 1, self.dim do f.dx[k] = f.dx[k] * self.friction end for k = 1, self.dim do f.x[k] = f.x[k] + f.dx[k] end self:outlet(2, "float", { i }) -- output self:outlet(1, "list", f.x) end end function swarm:center() -- center of mass local c = { } local w = 0 for k = 1, self.dim do c[k] = 0 end for i = 1, self.count do w = w + self.flock[i].w for k = 1, self.dim do c[k] = c[k] + self.flock[i].w * self.flock[i].x[k] end end for k = 1, self.dim do c[k] = c[k] / w end return c end function swarm:rule1(c, f) -- clustering local v = { } for k = 1, self.dim do v[k] = self.cluster * (c[k] - (1 + f.w) * f.x[k]) end return v end function swarm:rule2(i, f) -- avoidance local v = { } for k = 1, self.dim do v[k] = 0 end for j = 1, self.count do if i ~= j then g = self.flock[j] local d = { } local m = 0 for k = 1, self.dim do d[k] = g.x[k] - f.x[k] ; m = m + d[k] * d[k] end if m < self.distance2 then for k = 1, self.dim do v[k] = v[k] - d[k] end end end end for k = 1, self.dim do v[k] = 0.01 * v[k] end return v end function swarm:rule3(i, f) -- similarity local v = { } for k = 1, self.dim do v[k] = 0 end for j = 1, self.count do if i ~= j then g = self.flock[j] local d = { } local m = 0 for k = 1, self.dim do d[k] = g.dx[k] - f.dx[k] ; m = m + d[k] * d[k] end if m < self.similar2 then for k = 1, self.dim do v[k] = v[k] + d[k] end end end end for k = 1, self.dim do v[k] = 0.004 * v[k] end return v end -- exercise: make the right inlet control individual elements pdlua-0.7.3/examples/lpipe.pd_lua0000644000175000017500000000366211674625145017217 0ustar zmoelnigzmoelnig-- reimplementation of [pipe] for any message -- claude(+fbar) 2008 local M = pd.Class:new():register("lpipe") function M:initialize(name, atoms) self.inlets = 2 self.outlets = 1 self.nextID = 0 return true end function M:in_2_float(f) self.deltatime = math.max(0, f) end function M:in_1(sel, atoms) -- we need unique method names for our clock callbacks self.nextID = self.nextID + 1 local id = "trigger" .. self.nextID local clock = pd.Clock:new():register(self, id) -- the clock callback outlets the data and cleans up self[id] = function(self) self:outlet(1, sel, atoms) clock:destruct() self[id] = nil end -- now start the clock clock:delay(self.deltatime) end pdlua-0.7.3/README0000644000175000017500000000270312461454037013750 0ustar zmoelnigzmoelnigpdlua -- a Lua embedding for Pd Copyright (C) 2007,2008,2009 Claude Heiland-Allen 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Lua 5.1 is highly recommended, other versions are untested and unsupported - use at your own risk. Compilation Instructions: 1. edit Makefile.static to configure your PLATFORM and PDINCLUDE 2. run "make -f Makefile.static" 3. use it like "pd -path src -lib lua" Alternatively, for the brave: aclocal autoheader automake -a -c autoconf ./configure make make install Additional notes for mingw (thanks to David Shimamomto): Copy the following files to the same directory as 'Makefile.static': 1. lua-5.1.3.tar.gz 2. m_pd.h 3. pd.dll Edit Makefile.static to have "PDINCLUDE = -I./" (without quotes). To install, copy the following files to 'extra': 1. src/lua.dll 2. src/pd.lua pdlua-0.7.3/hello.lua0000644000175000017500000000002711674625145014700 0ustar zmoelnigzmoelnigpd.post("Hello, you!")