diff --git a/pdlua/tutorial/examples/dial.pd b/pdlua/tutorial/examples/dial.pd index 8612693..4052b01 100644 --- a/pdlua/tutorial/examples/dial.pd +++ b/pdlua/tutorial/examples/dial.pd @@ -1,4 +1,4 @@ -#N canvas 433 315 876 306 12; +#N canvas 542 350 734 300 12; #X obj 40 50 dial; #X floatatom 40 10 5 0 0 0 - phase -, f 5; #X obj 200 70 tgl 15 0 empty empty empty 17 7 0 10 #fcfcfc #000000 @@ -6,35 +6,31 @@ #X text 200 40 clock; #X obj 200 94 metro 1000; #X floatatom 200 152 5 0 0 0 - - -, f 5; -#X msg 200 210 0; -#X obj 200 180 s phase; -#X text 400 40 random speedometer; -#X obj 400 70 tgl 15 0 empty empty empty 17 7 0 10 #fcfcfc #000000 +#X msg 150 210 0; +#X obj 200 260 s phase; +#X text 350 40 random speedometer; +#X obj 350 70 tgl 15 0 empty empty empty 17 7 0 10 #fcfcfc #000000 #000000 0 1; -#X floatatom 400 152 5 0 0 0 - - -, f 5; -#X obj 400 239 line; -#X obj 400 274 s phase; -#X obj 400 123 expr phase = random(-100 \, 100)/300.; -#X msg 400 210 \$1 100; -#X obj 400 94 metro 100; -#X obj 200 123 expr phase = phase + 1/60.; -#X obj 200 240 t f f; +#X floatatom 350 152 5 0 0 0 - - -, f 5; +#X obj 350 219 line; +#X obj 350 264 s phase; +#X msg 350 190 \$1 100; +#X obj 350 94 metro 100; #X obj 20 12 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc #000000 #000000; #X floatatom 40 210 5 0 0 0 - - -, f 5; -#X obj 40 274 v phase; -#X obj 40 238 change; -#X obj 680 70 adc~; -#X obj 740 70 tgl 15 0 empty empty empty 17 7 0 10 #fcfcfc #000000 +#X obj 40 264 v phase; +#X obj 570 70 adc~; +#X obj 630 70 tgl 15 0 empty empty empty 17 7 0 10 #fcfcfc #000000 #000000 0 1; -#X obj 680 274 s phase; -#X text 680 40 dB meter; -#X obj 680 123 env~; -#X obj 680 99 *~ 0.5; -#X obj 680 186 expr ($f1-50)/100; -#X floatatom 680 152 5 0 0 0 - - -, f 5; -#X text 700 206 0..100 dB -> -0.5..+0.5 phase, f 16; -#X msg 740 94 \; pd dsp \$1; +#X obj 570 264 s phase; +#X text 570 40 dB meter; +#X obj 570 123 env~; +#X obj 570 99 *~ 0.5; +#X obj 570 186 expr ($f1-50)/100; +#X floatatom 570 152 5 0 0 0 - - -, f 5; +#X text 590 206 0..100 dB -> -0.5..+0.5 phase, f 16; +#X msg 630 94 \; pd dsp \$1; #N canvas 767 395 479 405 colors-and-size 0; #X text 120 70 black on white; #X text 120 100 white on black; @@ -74,29 +70,28 @@ color (face), f 40; #X connect 22 0 9 0; #X restore 90 10 pd colors-and-size; #X text 230 10 <--- click to open; -#X connect 0 0 19 0; +#X obj 200 123 expr phase + 1/60.; +#X obj 350 123 expr random(-100 \, 100)/300.; +#X connect 0 0 16 0; #X connect 1 0 0 0; #X connect 2 0 4 0; -#X connect 4 0 16 0; +#X connect 4 0 30 0; #X connect 5 0 7 0; -#X connect 6 0 17 0; -#X connect 9 0 15 0; -#X connect 10 0 14 0; +#X connect 6 0 7 0; +#X connect 9 0 14 0; +#X connect 10 0 13 0; #X connect 11 0 12 0; -#X connect 13 0 10 0; -#X connect 14 0 11 0; -#X connect 15 0 13 0; -#X connect 16 0 5 0; -#X connect 17 0 20 0; -#X connect 17 1 12 0; -#X connect 18 0 0 0; -#X connect 19 0 21 0; -#X connect 21 0 20 0; -#X connect 22 0 27 0; -#X connect 22 1 27 0; -#X connect 23 0 31 0; -#X connect 26 0 29 0; -#X connect 27 0 26 0; -#X connect 28 0 24 0; -#X connect 29 0 28 0; -#X connect 32 0 0 0; +#X connect 13 0 11 0; +#X connect 14 0 31 0; +#X connect 15 0 0 0; +#X connect 16 0 17 0; +#X connect 18 0 23 0; +#X connect 18 1 23 0; +#X connect 19 0 27 0; +#X connect 22 0 25 0; +#X connect 23 0 22 0; +#X connect 24 0 20 0; +#X connect 25 0 24 0; +#X connect 28 0 0 0; +#X connect 30 0 5 0; +#X connect 31 0 10 0; diff --git a/pdlua/tutorial/pd-lua-intro.pdf b/pdlua/tutorial/pd-lua-intro.pdf index ad36215..200b0f2 100644 Binary files a/pdlua/tutorial/pd-lua-intro.pdf and b/pdlua/tutorial/pd-lua-intro.pdf differ diff --git a/tutorial/18-graphics1.png b/tutorial/18-graphics1.png index 6e894dc..748711f 100644 Binary files a/tutorial/18-graphics1.png and b/tutorial/18-graphics1.png differ diff --git a/tutorial/18-graphics2.png b/tutorial/18-graphics2.png index fb29a10..234332c 100644 Binary files a/tutorial/18-graphics2.png and b/tutorial/18-graphics2.png differ diff --git a/tutorial/18-graphics3.png b/tutorial/18-graphics3.png index 2501fc6..b36aaf8 100644 Binary files a/tutorial/18-graphics3.png and b/tutorial/18-graphics3.png differ diff --git a/tutorial/18-graphics4.png b/tutorial/18-graphics4.png index b9aa326..e97027a 100644 Binary files a/tutorial/18-graphics4.png and b/tutorial/18-graphics4.png differ diff --git a/tutorial/18-graphics5.png b/tutorial/18-graphics5.png index f45d87c..d679f81 100644 Binary files a/tutorial/18-graphics5.png and b/tutorial/18-graphics5.png differ diff --git a/tutorial/18-graphics6.png b/tutorial/18-graphics6.png index 0297434..3ff5462 100644 Binary files a/tutorial/18-graphics6.png and b/tutorial/18-graphics6.png differ diff --git a/tutorial/pd-lua-intro.html b/tutorial/pd-lua-intro.html index dc83757..6974f8f 100644 --- a/tutorial/pd-lua-intro.html +++ b/tutorial/pd-lua-intro.html @@ -704,7 +704,7 @@ pd-lua-intro
-

A Quick Introduction to Pd-Lua

Albert Gräf <aggraef@gmail.com>
Computer Music Dept., Institute of Art History and Musicology
Johannes Gutenberg University (JGU) Mainz, Germany
August 2024

This document is licensed under CC BY-SA 4.0. Other formats: Markdown source, PDF
Permanent link: https://agraef.github.io/pd-lua/tutorial/pd-lua-intro.html

Why Pd-Lua?

Pd's facilities for data structures, iteration, and recursion are somewhat limited, thus sooner or later you'll probably run into a problem that can't be easily solved by a Pd abstraction any more. At this point you'll have to consider writing an external object (or just external, for short) in a "real" programming language instead. Pd externals are usually programmed using C, the same programming language that Pd itself is written in. But novices may find C difficult to learn, and the arcana of Pd's C interface may also be hard to master.

Enter Pd-Lua, the Pd programmer's secret weapon, which lets you develop your externals in the Lua scripting language. Pd-Lua was originally written by Claude Heiland-Allen and has since been maintained by a number of other people in the Pd community. Lua, from PUC Rio, is open-source (under the MIT license), mature, very popular, and supported by a large developer community. It is a small programming language, but very capable, and is generally considered to be relatively easy to learn. For programming Pd externals, you'll also need to learn a few bits and pieces which let you interface your Lua functions to Pd, as explained in this tutorial, but programming externals in Lua is still quite easy and a lot of fun. Using Pd-Lua, you can program your own externals ranging from little helper objects to full-blown synthesizers, sequencers, and algorithmic composition tools. It gives you access to Pd arrays and tables, as well as a number of other useful facilities such as clocks and receivers, which we'll explain in some detail. Pd-Lua also ships with a large collection of instructive examples which you'll find helpful when exploring its possibilities.

Pd-Lua was originally designed for control processing, so we used to recommend Faust for doing dsp instead. We still do, but Faust isn't for everyone; being a purely functional language, Faust follows a paradigm which most programmers aren't very familiar with. Fortunately, thanks to the work of Timothy Schoen, the most recent Pd-Lua versions now also provide support for signal processing and even graphics. So it is now possible to create pretty much any kind of Pd object in Lua, including dsp objects. (However, Faust will almost certainly execute dsp code much more efficiently than Pd-Lua, as it generates highly optimized native code for just this purpose.)

Note that we can't possibly cover Pd or the Lua language themselves here, so you'll have to refer to other online resources to learn about those. In particular, check out the Lua website, which has extensive documentation available, and maybe have a look at Derek Banas' video tutorial for a quick overview of Lua. For Pd, we recommend the Pd FLOSS Manual at https://flossmanuals.net/ to get started.

Installation

Pd-Lua works inside any reasonably modern Pd flavor. This encompasses vanilla Pd, of course, but also Purr Data which includes an up-to-date version of Pd-Lua for Lua 5.4 and has it enabled by default, so you should be ready to go immediately; no need to install anything else. The same is true for plugdata (version 0.6.3 or later), a Pd flavor which can also run as a plug-in inside a DAW.

With vanilla Pd, you can install the pdlua package from Deken. There's also an official Debian package, maintained by IOhannes Zmölnig. You can also compile Pd-Lua from source, using the author's Github repository. Compilation instructions are in the README, and you'll also find some Mac and Windows binaries there. In either case, after installing Pd-Lua you also have to add pdlua to Pd's startup libraries.

If all is well, you should see a message like the following in the Pd console (note that for vanilla Pd you'll have to switch the log level to 2 or more to see that message):

This will also tell you the Lua version that Pd-Lua is using, so that you can install a matching version of the stand-alone Lua interpreter if needed. Lua should be readily available from your package repositories on Linux, and for Mac and Windows you can find binaries on the Lua website. In the following we generally assume that you're using Lua 5.3 or later (using Lua versions older than 5.3 is not recommended).

If all is not well and you do not see that message, then most likely Pd-Lua refused to load because the Lua library is missing. This shouldn't happen if you installed Pd-Lua from a binary package, but if it does then you may have to manually install the right version of the Lua library to make Pd-Lua work. Make sure that you install the package with the Lua library in it; on Debian, Ubuntu and their derivatives this will be something like liblua5.4-0.

A basic example

With that out of the way, let's have a look at the most essential parts of a Lua external. To make an external, say foo, loadable by Pd-Lua, you need to put it into a Lua script, which is simply a text file with the right name (which must be the same as the object name, foo in this case) and extension (which needs to be .pd_lua), so the file name will be foo.pd_lua in this example.

Any implementation of an object must always include:

Here is a prototypical example (this is the contents of the foo.pd_lua file):