diff options
author | Frank Barknecht <fbar@users.sourceforge.net> | 2004-04-23 16:26:21 +0000 |
---|---|---|
committer | Frank Barknecht <fbar@users.sourceforge.net> | 2004-04-23 16:26:21 +0000 |
commit | 28e7d308d91556ec078f708b6c4ac855ac340fcc (patch) | |
tree | b406f3f4e426f3bb03acce88bb5027babd9b4a6b /doc | |
parent | 35994ca3a4ef6a136a16cac63b4f68540d0434e1 (diff) |
This commit was generated by cvs2svn to compensate for changes in r1632,
which included commits to RCS files with non-trunk default branches.
svn path=/trunk/abstractions/rradical/; revision=1633
Diffstat (limited to 'doc')
-rw-r--r-- | doc/Makefile | 13 | ||||
-rw-r--r-- | doc/README.txt | 19 | ||||
-rw-r--r-- | doc/caregui.png | bin | 0 -> 1659 bytes | |||
-rw-r--r-- | doc/communslider.pd | 8 | ||||
-rw-r--r-- | doc/communslider.png | bin | 0 -> 5279 bytes | |||
-rw-r--r-- | doc/default.css | 328 | ||||
-rw-r--r-- | doc/memento.png | bin | 0 -> 152685 bytes | |||
-rw-r--r-- | doc/moresliders.pd | 13 | ||||
-rw-r--r-- | doc/moresliders.png | bin | 0 -> 5468 bytes | |||
-rw-r--r-- | doc/osccontrol.pd | 27 | ||||
-rw-r--r-- | doc/osccontrol.png | bin | 0 -> 8056 bytes | |||
-rw-r--r-- | doc/rradicalpd.html | 335 | ||||
-rw-r--r-- | doc/rradicalpd.pdf | bin | 0 -> 273129 bytes | |||
-rw-r--r-- | doc/rradicalpd.png | bin | 0 -> 33929 bytes | |||
-rw-r--r-- | doc/rradicalpd.rst | 366 | ||||
-rw-r--r-- | doc/rradicalpd.tex | 511 | ||||
-rw-r--r-- | doc/substates.pd | 17 | ||||
-rw-r--r-- | doc/substates.png | bin | 0 -> 6219 bytes |
18 files changed, 1637 insertions, 0 deletions
diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..2fc91bb --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,13 @@ +REST = rradicalpd + +all: html tex pdf + +tex: + rest2latex --documentclass=scrartcl $(REST).rst $(REST).tex + +pdf: tex + pdflatex $(REST).tex + +html: + rest2html $(REST).rst $(REST).html + diff --git a/doc/README.txt b/doc/README.txt new file mode 100644 index 0000000..3d47aa6 --- /dev/null +++ b/doc/README.txt @@ -0,0 +1,19 @@ +===================================== + RRADical Pd - Conference Material +===================================== + +This folder contains an introduction to Rapid And Reuseable Application +Development (RRADical) with Pure Data as will be presented at the Linux +Audio Conference 2 in ZKM Karlsruhe. The main text is in rradicalpd.rst and +is a simple textfile using reStructuredText markup. You can either read +this file or convert it to HTML, Tex, XML, PDF and many more using the +Python-Docutils tool collection. HTML, Tex and PDF renderings are +included. The *.pd files are example patches for Pd. + +The text is full of spelling errors, needs some serious proof reading and +does not yet cover the last third of the talk which will be a practical +walkthrough to building a RRADical Pd patch. For that, just look ate the +"usecases" folder in the RRADical patch collection, which is included in +the archive rradical-wip-040325.tgz + +-- Frank Barknecht <fbar@footils.org>, 2004 diff --git a/doc/caregui.png b/doc/caregui.png Binary files differnew file mode 100644 index 0000000..b1d6680 --- /dev/null +++ b/doc/caregui.png diff --git a/doc/communslider.pd b/doc/communslider.pd new file mode 100644 index 0000000..64585ce --- /dev/null +++ b/doc/communslider.pd @@ -0,0 +1,8 @@ +#N canvas 186 212 371 285 10; +#X obj 35 25 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 3800 1; +#X obj 129 76 commun /volume \$0; +#X obj 127 131 originator /mypatch \$0; +#X obj 21 174 careGUI; +#X connect 0 0 1 0; +#X connect 1 0 0 0; diff --git a/doc/communslider.png b/doc/communslider.png Binary files differnew file mode 100644 index 0000000..9cffa9d --- /dev/null +++ b/doc/communslider.png diff --git a/doc/default.css b/doc/default.css new file mode 100644 index 0000000..024a382 --- /dev/null +++ b/doc/default.css @@ -0,0 +1,328 @@ + +HTML { + background: #ffffff; + color: #000; + font-family: Verdana, Helvetica, Arial, Tahoma, sans-serif; + font-size: 8pt; +} + +BODY{ + padding: 5px; + font-family: Verdana, Helvetica, Arial, Tahoma, sans-serif; + font-size: 8pt; +} + +.footer { + background:#EEEEEE; + width: 650px; +} + +.bordered { + padding: 5px; +} + + +H1 { + color: #600; + border: solid 1px; + font-family: monospace; + padding: 5px; + background:#EEEEEE; +} + +H2 { + font-family: Courier, monospace; + border: solid 1px; + color: #000; + padding: 4px; +} + +H3 { + font-family: Courier, monospace; + border: solid 1px; + color: #000; + padding: 4px; +} + +pre { + color: #333333; + padding: 3px; + background:#EEEEEE; +} + +A { + text-decoration: none; +/* background: #FFFFFF; */ + color: #b00; +} + +A:hover { + text-decoration: underline; + /* background: #FFFFFF; */ + color: #003300 ; +} + +A.nonexistent { + background: #EEE; + color: #CC6600; +} + + + + +HR { + height:1px; + width: 75%; + /* background:#eeaa00; */ + background:#eee; + color:#000; +} + +P.small { + font-size: xx-small; + background:#fff; + text-align: right; + /*border: dotted 1px;*/ + padding: 5px; +} + +UL { + list-style-type: circle; +} + +#Content>p {margin:0px;} +#Content>p+p {text-indent:30px;} + +#Content { + margin:0px 50px 50px 160px; + padding:10px; + } +div.document>p {margin:0px;} +div.document>p+p {text-indent:30px;} + +div.document { + margin:0px 50px 50px 160px; + padding:10px; + } + +#Menu { + position:absolute; + top:120px; + left:10px; + width:150px; + padding:10px; + line-height:17px; +/* Again, the ugly brilliant hack. */ + voice-family: "\"}\""; + voice-family:inherit; + width:140px; + } +/* Again, "be nice to Opera 5". */ +body>#Menu {width:140px;} + +div."contents topic" { + position:absolute; + top:120px; + left:10px; + width:150px; + padding:10px; + line-height:17px; +/* Again, the ugly brilliant hack. */ + voice-family: "\"}\""; + voice-family:inherit; + width:140px; + } +/* Again, "be nice to Opera 5". */ +body>#"contents topic" {width:140px;} + + +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:date: $Date: 2004-04-23 16:25:52 $ +:version: $Revision: 1.1.1.1 $ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. +*/ + +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + +a.toc-backref { + text-decoration: none ; + color: black } + +dd { + margin-bottom: 0.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.attention, div.caution, div.danger, div.error, div.hint, +div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.hint p.admonition-title, div.important p.admonition-title, +div.note p.admonition-title, div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.title { + text-align: center } + +h2.subtitle { + text-align: center } + +hr { + width: 75% } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.citation { + border-left: solid thin gray ; + padding-left: 0.5ex } + +table.docinfo { + margin: 2em 4em } + +table.footnote { + border-left: solid thin black ; + padding-left: 0.5ex } + +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap } + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + font-size: 100% } + +tt { + background-color: #eeeeee } +tt.literal { + border: solid 1px; +} +ul.auto-toc { + list-style-type: none } diff --git a/doc/memento.png b/doc/memento.png Binary files differnew file mode 100644 index 0000000..4e38a42 --- /dev/null +++ b/doc/memento.png diff --git a/doc/moresliders.pd b/doc/moresliders.pd new file mode 100644 index 0000000..4eae09c --- /dev/null +++ b/doc/moresliders.pd @@ -0,0 +1,13 @@ +#N canvas 186 212 371 285 10; +#X obj 35 25 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 3800 1; +#X obj 62 108 commun /volume \$0; +#X obj 63 142 originator /mypatch \$0; +#X obj 21 174 careGUI; +#X obj 108 64 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 140 35 commun /pan \$0; +#X connect 0 0 1 0; +#X connect 1 0 0 0; +#X connect 4 0 5 0; +#X connect 5 0 4 0; diff --git a/doc/moresliders.png b/doc/moresliders.png Binary files differnew file mode 100644 index 0000000..f824b21 --- /dev/null +++ b/doc/moresliders.png diff --git a/doc/osccontrol.pd b/doc/osccontrol.pd new file mode 100644 index 0000000..fc25ee7 --- /dev/null +++ b/doc/osccontrol.pd @@ -0,0 +1,27 @@ +#N canvas 100 217 609 319 10; +#X obj 35 25 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 8000 1; +#X obj 62 108 commun /volume \$0; +#X obj 220 145 originator /mypatch \$0; +#X obj 21 174 careGUI; +#X obj 108 64 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 6400 1; +#X obj 140 35 commun /pan \$0; +#X floatatom 220 98 5 0 0 1 substate_selector - -; +#X msg 220 121 setsub \$1; +#X msg 411 59 /mypatch/volume \$1; +#X floatatom 411 30 5 0 0 2 set_volume_by_OSC_message - -; +#X floatatom 413 105 5 0 0 2 set_pan_by_OSC_message - -; +#X msg 413 134 /mypatch/pan \$1; +#X obj 369 181 print OSC; +#X connect 0 0 1 0; +#X connect 1 0 0 0; +#X connect 2 2 12 0; +#X connect 4 0 5 0; +#X connect 5 0 4 0; +#X connect 6 0 7 0; +#X connect 7 0 2 0; +#X connect 8 0 2 1; +#X connect 9 0 8 0; +#X connect 10 0 11 0; +#X connect 11 0 2 1; diff --git a/doc/osccontrol.png b/doc/osccontrol.png Binary files differnew file mode 100644 index 0000000..bd68a48 --- /dev/null +++ b/doc/osccontrol.png diff --git a/doc/rradicalpd.html b/doc/rradicalpd.html new file mode 100644 index 0000000..04d6a42 --- /dev/null +++ b/doc/rradicalpd.html @@ -0,0 +1,335 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" /> +<title>RRADical Pd</title> +<meta name="author" content="Frank Barknecht <fbar@footils.org>" /> +<link rel="stylesheet" href="default.css" type="text/css" /> +</head> +<body> +<div class="document" id="rradical-pd"> +<h1 class="title">RRADical Pd</h1> +<table class="docinfo" frame="void" rules="none"> +<col class="docinfo-name" /> +<col class="docinfo-content" /> +<tbody valign="top"> +<tr><th class="docinfo-name">Author:</th> +<td>Frank Barknecht <fbar@footils.org></td></tr> +</tbody> +</table> +<div class="abstract topic"> +<p class="topic-title">Abstract</p> +<p>The goal of RRADical Pd is to create a collection of patches, that make +Pd easier and faster to use for people who are more used to commercial +software like Reason(tm) or Reaktor(tm). RRAD as an acronym stands for +"Reusable and Rapid Audio Development" or "Reusable and Rapid +Application Development", if it includes non-audio patches, with Pd. It +is spelled RRAD, but pronounced Rradical. ;)</p> +</div> +<div class="section" id="what-it-takes-to-be-a-rradical"> +<h1><a name="what-it-takes-to-be-a-rradical">What it takes to be a RRADical</a></h1> +<p>RRAD as an acronym stands for "Reusable and Rapid Audio Development" or +"Reusable and Rapid Application Development", if it includes non-audio +patches, with Pd. It is spelled RRAD, but pronounced Rradical. ;)</p> +<p>The goal of RRADical Pd is to create a collection of patches, that make Pd +easier and faster to use for people who are more used to software like Reason(tm) +or Reaktor(tm). For that I would like to create patches, that solve real-world +problems on a higher level of abstraction than the standard Pd objects do. +Where suitable these high level abstractions should have a GUIs +built in.</p> +<p>So for example instead of a basic <tt class="literal"><span class="pre">lop~</span></tt> low pass filter something more +complete like a recreation of the Sherman filter bank could be included in +that collection. My older sseq and angriff patches followed this idea in +general, but there are much more patches needed. Like this:</p> +<ul class="simple"> +<li>a sample player (adapt Gyre?)</li> +<li>Various OSC/LFO with preset waveforms</li> +<li>drum machine</li> +<li>guitar simulator</li> +<li>grain sample player</li> +<li>more sequencers</li> +<li>basically a lot of things like these things in Reason</li> +</ul> +<p>Not that I want to make Pd be Reason, no way. But pre-fabricated high-level +abstractions may not only make Pd easier to use for beginners, they also +can spare lot of tedious, repeating patching work.</p> +</div> +<div class="section" id="problems-and-solutions"> +<h1><a name="problems-and-solutions">Problems and Solutions</a></h1> +<p>To building above system several problems are to be solved. Two key areas +already targetted are:</p> +<dl> +<dt><strong>Persistence</strong></dt> +<dd>How to save the current state of a patch? How to save more than one +state (state sequencing)?</dd> +<dt><strong>Communication</strong></dt> +<dd>The various modules are building blocks for a larger application. How +should they talk to each other. (In Reason this is done by patching the +back or modules with horrible looking cables. We must do better.)</dd> +</dl> +<p>It turned out, that both tasks are possible to solve in a consistent way +using a unique abstraction. But first lets look a bit deeper at the +problems at hand.</p> +<div class="section" id="persistence"> +<h2><a name="persistence">Persistence</a></h2> +<p>Pd offers no direct way to store the current state of a patch. Here's what +Pd author Miller S. Puckette writes about this in the Pd manual in section +"2.6.2. persistence of data":</p> +<blockquote> +Among the design principles of Pd is that patches should be printable, +in the sense that the appearance of a patch should fully determine its +functionality. For this reason, if messages received by an object +change its action, since the changes aren't reflected in the object's +appearance, they are not saved as part of the file which specifies the +patch and will be forgotten when the patch is reloaded.</blockquote> +<p>(I'll show an example of a float object changing "state" by a message in +its right inlet here.)</p> +<p>Still, in a musician's practice some kind of persistence turns out to be an +important feature, that many Pd beginners do miss. So there are several +approaches to add it. Max/MSP has the <tt class="literal"><span class="pre">preset</span></tt>-object, Pd has the +<tt class="literal"><span class="pre">state</span></tt>-object which saves the current state of (some) GUI objects inside +a patch. Both also support changing between several different states.</p> +<p>Both have at least two problems: They save only the state of GUI objects, +which might not be all that a user wants to save. And they don't handle +abstractions very well, which are crucial when creating modularized +patches.</p> +<p>Another approach is to (ab)use some of the Pd objects that can persist +itself to a file, especially <tt class="literal"><span class="pre">textfile</span></tt>, <tt class="literal"><span class="pre">qlist</span></tt> and <tt class="literal"><span class="pre">table</span></tt>, which +works better, but isn't standardized.</p> +<p>A rather new candidate for state saving is Thomas Grill's <tt class="literal"><span class="pre">pool</span></tt> +external. Basically it offers something, that is standard in many +programming languages: a data structure that stores key-value-pairs. This +also is known as hash, dictonary or map. With <tt class="literal"><span class="pre">pool</span></tt> those pairs also can +be stored in hierarchies and they can be saved to or loaded from disk. The +last but maybe most important feature for us is, that several pools can be +shared by giving them the same name. A <tt class="literal"><span class="pre">pool</span> <span class="pre">MYPOOL</span></tt> in one patch will +contain the same data as a <tt class="literal"><span class="pre">pool</span> <span class="pre">MYPOOL</span></tt> in another patch. Changes to one +pool will change the data in the other as well.</p> +<p>A <tt class="literal"><span class="pre">pool</span></tt> object is central to the persistence in RRADical patches, but it +is hidden behind an abstracted "API", if one could name it that. I'll +come back to haw this is done late.</p> +</div> +<div class="section" id="communication"> +<h2><a name="communication">Communication</a></h2> +<p>Besides persistance it also is important to create a common path through +which the RRADical modules will talk to each other. Generally the modules +will have to use, what Pd offers them, and that is either a direct +connection through patch cords or the indirect use of the send/receive +mechanism in Pd. Patch cords are fine, but tend to clutter the interface. +Sends and receives on the other hand will have to make sure, that no name +clashes occur. A name clash is, when one target receives messages not +intended for it. A patch author has to remember all used send-names, but +this gets harder, if he uses prefabricated modules, which might use their +own senders.</p> +<p>So it is crucial, that senders in RRADical abstractions use local senders +only with as few exceptions as possible. This is achieved by prepending the +RRADical senders with the string "$0-". So you'd not use <tt class="literal"><span class="pre">send</span> <span class="pre">volume</span></tt>, +but instead use <tt class="literal"><span class="pre">send</span> <span class="pre">$0-volume</span></tt>. $0 makes those sends local inside their +own patch borders. This might be a bit difficult to understand to the +casual Pd user, but is a pretty standard idiom in the Pd world.</p> +<p>Still we will want to control a lot of parameters and do so not only +through the GUI Pd offers, but probably also through other ways, for +example through Midi controllers, through some kind of score on disk, +through satellite navigation receivers or whatever.</p> +<p>This creates a fundamental conflict:</p> +<dl> +<dt><strong>We want borders</strong> </dt> +<dd>We want to separate our abstraction so they don't conflict with each +other.</dd> +<dt><strong>We want border crossings</strong></dt> +<dd>We want to have a way to reach their many internals and control them +from the outside.</dd> +</dl> +<p>The RRADical approach adheres to this in that it enforces a strict border +but drills a single hole in it: the <strong>OSC inlet</strong>. This idea is the result +of a discussion on the Pd mailing list and goes back to suggestions by +<a class="reference" href="http://www.audionerd.com">Eric Skogen</a> and <a class="reference" href="http://www.ekran.org/ben/">Ben Bogart</a>. Every RRADical patch has (to have) a +rightmost inlet that accepts messages formatted according to the OSC +protocol. OSC stands for <a class="reference" href="http://www.cnmat.berkeley.edu/OpenSoundControl/">Open Sound Control</a> and is a network transparent +system to control audio applications remotely developed at CNMAT in Berkley.</p> +<p>The nice thing about OSC is that it can control many parameters over a +single communication path. This is so, because OSC uses a URL-like scheme +to address parameters. An example would be this message:</p> +<pre class="literal-block"> +/synth/fm/volume 85 +</pre> +<p>It sends the message "85" to the "volume" control of a "fm" module below a +"synth" module. OSC allows many parameters constructs like:</p> +<pre class="literal-block"> +/synth/fm/basenote 52 +/synth/virtualanalog/basenote 40 +/synth/*/playchords m7b5 M6 7b9 +</pre> +<p>This might set the base note of two synths, <cite>fm</cite> and <cite>virtualanalog</cite> and +send a chord progression to be played by both -- indicated by the wildcard +<cite>*</cite> -- afterwards.</p> +<p>The OSC-inlet of every RRADical patch is intended as the border crossing: +Everything the author of a certain patch intends to be controlled from the +outside can be controlled by OSC messages to the rightmost inlet.</p> +</div> +</div> +<div class="section" id="trying-to-remember-it-all-memento"> +<h1><a name="trying-to-remember-it-all-memento">Trying to remember it all: Memento</a></h1> +<p>To realize the functionality requirements developed so far I resorted to a +so called <cite>Memento</cite>. <cite>"Memento"</cite> is a very cool movie by director +Christopher Nolan where - quoting IMDB:</p> +<blockquote> +A man, suffering from short-term memory loss, uses notes and tattoos to +hunt down his wife's killer.</blockquote> +<p>If you haven't already done so: Watch this movie! It's much better than +Matrix 2 and 3 and also stars Carrie-Anne "Trinity" Moss.</p> +<p>Here's a scene from "Memento":</p> +<p><img alt="memento.png" src="memento.png" /></p> +<p>We see the film's main character Leonard who has a similar problem as Pd: he +cannot remember things. To deal with his persistence problem, his inability +to save data to his internal harddisk he resorts to taking a lot of photos. +These pictures act as what is called a Memento: a recording of the current +state of things.</p> +<p>In software development Mementos are quite common as well. The computer +science literature describes them in great detail. To make the best use of +a Memento science recommends an approach where certain tasks are in the +responsibility of certain independent players.</p> +<p>The Memento itself, as we have seen, is the photo, i.e. some kind of state +record. A module called the "Originator" is responsible for creating this +state and managing changes in it. In the movie, Leonard is the Originator, +he is the one taking photos of the world he is soon to forget.</p> +<p>The actual persistence, that could be the saving of a state to harddisk, +but could just as well be an upload to a webserver or a CVS check-in, is +done by someone called the "Caretaker" in the literature. A Caretaker could +be a safe, where Leonard puts his photos, or could be a person, to whom +Leonard gives his photos. In the movie Leonard also makes "hard saves" by +tattooing himself with notes he took. In that case, he is not only the +Originator of the notes, but also the Caretaker in one single person. The +Caretaker only has to take care, that those photos, the Mementos, are in a +safe place and noone fiddles around with them. Btw: In the movie some +interesting problems with Caretakers, who don't always act responsible, +occur.</p> +<div class="section" id="memento-in-pd"> +<h2><a name="memento-in-pd">Memento in Pd</a></h2> +<p>I developed a set of abstractions, of patches for Pd, that follow this +design pattern. Memento for Pd includes a <tt class="literal"><span class="pre">caretaker</span></tt> and an +<tt class="literal"><span class="pre">originator</span></tt> abstraction, plus a third one called <tt class="literal"><span class="pre">commun</span></tt> which is +responsible for the <strong>internal</strong> communication. <tt class="literal"><span class="pre">commun</span></tt> basically is +just a thin extension of <tt class="literal"><span class="pre">originator</span></tt> and should be considered part of +it. There is another patch, the <tt class="literal"><span class="pre">careGUI</span></tt> which I personally use instead +of the <tt class="literal"><span class="pre">caretaker</span></tt> directly, because it has a simple GUI included.</p> +<p>Here's how it looks:</p> +<p><img alt="caregui.png" src="caregui.png" /></p> +<p>The <tt class="literal"><span class="pre">careGUI</span></tt> is very simple: select a FILE-name to save to, then +clicking SAVE you can save the current state, with RESTORE you can restore +a state previously saved. After restore, the outlet of <tt class="literal"><span class="pre">careGUI</span></tt> sends a +<tt class="literal"><span class="pre">bang</span></tt> message to be used as you like.</p> +<p>Internally <tt class="literal"><span class="pre">caretaker</span></tt> has a named <tt class="literal"><span class="pre">pool</span></tt> object using the global pool +called "RRADICAL". The same <tt class="literal"><span class="pre">pool</span> <span class="pre">RRADICAL</span></tt> also is used inside the +<tt class="literal"><span class="pre">originator</span></tt> object. This abstraction handles all access to this pool. A +user should not read or write the contents of <tt class="literal"><span class="pre">pool</span> <span class="pre">RRADICAL</span></tt> directly. +The <tt class="literal"><span class="pre">originator</span></tt> patch also handles the border crossing through OSC +messages by it's rightmost inlet. The patch accepts two mandatory +arguments: The first on is the name under which this patch is to be stored +inside the <tt class="literal"><span class="pre">pool</span></tt> data. Each <tt class="literal"><span class="pre">originator</span> <span class="pre">SomeName</span> <span class="pre">secondarg</span></tt> stores +it's data in a virtual subdirectory inside the RRADICAL-pool called like +its first argument - SomeName in the example. If the SomeName starts with a +slash like "/patch" , you can also accesse it via OSC through the rightmost inlet of +<tt class="literal"><span class="pre">originator</span></tt> under the tree "/patch"</p> +<p>The second argument practically always will be $0. It is used to talk to +those <tt class="literal"><span class="pre">commun</span></tt> objects which share the same second argument. As $0 is a +value local and unique to a patch (or to an abstraction to be correct) each +<tt class="literal"><span class="pre">originator</span></tt> then only can talk to <tt class="literal"><span class="pre">commun</span></tt>s inside the same patch and +will not disturb other <tt class="literal"><span class="pre">commun</span></tt> objects in other abstractions.</p> +<p>The <tt class="literal"><span class="pre">commun</span></tt> objects finally are where the contents of a state are read +and set. They, too, accept two arguments, the second of which was +discussed before and will most of the time just be $0. The first argument +will be the key under which some value will be saved. You should use a slash +as first character here as well to allow OSC control. So an example for a +usage would be <tt class="literal"><span class="pre">commun</span> <span class="pre">/vol</span> <span class="pre">$0</span></tt>.</p> +<p><tt class="literal"><span class="pre">commun</span></tt> has one inlet and one outlet. What comes in through the inlet is +send to <tt class="literal"><span class="pre">originator</span></tt> who stores it inside its Memento under the key, that +is specified by the <tt class="literal"><span class="pre">commun</span></tt>'s first arg. Actually <tt class="literal"><span class="pre">originator</span></tt>. The +outlet of a <tt class="literal"><span class="pre">commun</span></tt> will spit out the current value stored under its key +inside the Memento, when <tt class="literal"><span class="pre">originator</span></tt> tells it to do so. So <tt class="literal"><span class="pre">commun</span></tt>s +are intended to be cross-connected to some thing that can change. And +example would be a slider which can be connected as seen in the next +picture:</p> +<p><img alt="communslider.png" src="communslider.png" /></p> +<p>In this patch, every change to the slider will be reflected inside the +Memento. The little print button in <tt class="literal"><span class="pre">careGUI</span></tt> can be used to print the +contents to the console from which Pd was started. Setting the slider will +result in something like this:</p> +<pre class="literal-block"> +/mypatch 0 , /volume , 38 +</pre> +<p>Here a comma separates key and value pairs. "mypatch" is the toplevel +directory. This contains a 0, which is the default subdirectory, after that +comes the key "/volume", whose value is 38. Let's add another slider for +pan-values:</p> +<p><img alt="moresliders.png" src="moresliders.png" /></p> +<p>Moving the /pan slider will let careGUI print out:</p> +<pre class="literal-block"> +/mypatch 0 , /volume , 38 +/mypatch 0 , /pan , 92 +</pre> +<p>The <tt class="literal"><span class="pre">originator</span></tt> can save several substates or presets by sending a +<tt class="literal"><span class="pre">substate</span> <span class="pre">#number</span></tt> message to its first inlet. Let's do just this and +move the sliders again as seen in the next picture:</p> +<p><img alt="substates.png" src="substates.png" /></p> +<p>Now careGUI prints:</p> +<pre class="literal-block"> +/mypatch 0 , /volume , 38 +/mypatch 0 , /pan , 92 +/mypatch 1 , /volume , 116 +/mypatch 1 , /pan , 27 +</pre> +<p>You see, the substate 0 is unaffected, the new state can have different +values. Exchanging the <tt class="literal"><span class="pre">substate</span></tt> message with a <tt class="literal"><span class="pre">setsub</span></tt> message will +autoload the selected state and "set" the sliders to the stored values +immediatly.</p> +</div> +<div class="section" id="osc-in-memento"> +<h2><a name="osc-in-memento">OSC in Memento</a></h2> +<p>The whole system now already is prepared to be used over OSC. You probably +already guess, how the message looks like. Any takers? Thank you, you're +right, the messages are built as <tt class="literal"><span class="pre">/mypatch/volume</span> <span class="pre">#number</span></tt> and +<tt class="literal"><span class="pre">/mypatch/pan</span> <span class="pre">#number</span></tt> as shown in the next stage:</p> +<p><img alt="osccontrol.png" src="osccontrol.png" /></p> +<p>Sometimes it is useful to also get OSC messages out of a patch, for example +to control other OSC software through Pd. For this the <strong>OSC-outlet</strong> of +<tt class="literal"><span class="pre">originator</span></tt> can be used, which is the rightmost outlet of the +abstraction. It will print out every change to the current state. +Connecting a <tt class="literal"><span class="pre">print</span> <span class="pre">OSC</span></tt> debug object to it, we get to see what's coming +out of the OSC-outlet when we move a slider:</p> +<pre class="literal-block"> +OSC: /mypatch/pan 92 +OSC: /mypatch/pan 91 +OSC: /mypatch/pan 90 +OSC: /mypatch/pan 89 +</pre> +</div> +</div> +<div class="section" id="putting-it-all-to-rradical-use"> +<h1><a name="putting-it-all-to-rradical-use">Putting it all to RRADical use</a></h1> +<p>Now that the foundation for a general preset and communication system are +set, it is possible to build real patches with it that have two main +characteristics:</p> +<dl> +<dt><strong>Rapidity</strong></dt> +<dd>Ready-to-use highlevel abstraction can save a lot of time when building +larger patches. Clear communication paths will let you think faster and +more about the really important things.</dd> +<dt><strong>Reusability</strong></dt> +<dd>Don't reinvent the wheel all the time. Reuse patches like instruments +for more than one piece by just exchanging the Caretaker-file used.</dd> +</dl> +<p>I already developed a growing number of patches that follow the RRADical +paradigm, among these are a complex pattern sequencer, some synths and +effects and more. The RRADical collection comes with a template file, +called <tt class="literal"><span class="pre">rrad.tpl</span></tt> that makes deploying new RRADical patches easier and +lets developers concentrate on the algorighm instead of bookeeping. Some +utils (footils?) help with creating the sometimes needed many +<tt class="literal"><span class="pre">commun</span></tt>-objects. Several usecases show example applications of the +provided abstractions.</p> +</div> +</div> +</body> +</html> diff --git a/doc/rradicalpd.pdf b/doc/rradicalpd.pdf Binary files differnew file mode 100644 index 0000000..9820474 --- /dev/null +++ b/doc/rradicalpd.pdf diff --git a/doc/rradicalpd.png b/doc/rradicalpd.png Binary files differnew file mode 100644 index 0000000..bc752a9 --- /dev/null +++ b/doc/rradicalpd.png diff --git a/doc/rradicalpd.rst b/doc/rradicalpd.rst new file mode 100644 index 0000000..9d77090 --- /dev/null +++ b/doc/rradicalpd.rst @@ -0,0 +1,366 @@ +RRADical Pd +============ + + +:Authors: + Frank Barknecht <fbar@footils.org> +:Abstract: + The goal of RRADical Pd is to create a collection of patches, that make + Pd easier and faster to use for people who are more used to commercial + software like Reason(tm) or Reaktor(tm). RRAD as an acronym stands for + "Reusable and Rapid Audio Development" or "Reusable and Rapid + Application Development", if it includes non-audio patches, with Pd. It + is spelled RRAD, but pronounced Rradical. ;) + +What it takes to be a RRADical +------------------------------ + +RRAD as an acronym stands for "Reusable and Rapid Audio Development" or +"Reusable and Rapid Application Development", if it includes non-audio +patches, with Pd. It is spelled RRAD, but pronounced Rradical. ;) + +The goal of RRADical Pd is to create a collection of patches, that make Pd +easier and faster to use for people who are more used to software like Reason(tm) +or Reaktor(tm). For that I would like to create patches, that solve real-world +problems on a higher level of abstraction than the standard Pd objects do. +Where suitable these high level abstractions should have a GUIs +built in. + +So for example instead of a basic ``lop~`` low pass filter something more +complete like a recreation of the Sherman filter bank could be included in +that collection. My older sseq and angriff patches followed this idea in +general, but there are much more patches needed. Like this: + +* a sample player (adapt Gyre?) +* Various OSC/LFO with preset waveforms +* drum machine +* guitar simulator +* grain sample player +* more sequencers +* basically a lot of things like these things in Reason + +Not that I want to make Pd be Reason, no way. But pre-fabricated high-level +abstractions may not only make Pd easier to use for beginners, they also +can spare lot of tedious, repeating patching work. + +Problems and Solutions +---------------------- + +To building above system several problems are to be solved. Two key areas +already targetted are: + +**Persistence** + How to save the current state of a patch? How to save more than one + state (state sequencing)? + +**Communication** + The various modules are building blocks for a larger application. How + should they talk to each other. (In Reason this is done by patching the + back or modules with horrible looking cables. We must do better.) + +It turned out, that both tasks are possible to solve in a consistent way +using a unique abstraction. But first lets look a bit deeper at the +problems at hand. + +Persistence +............ + +Pd offers no direct way to store the current state of a patch. Here's what +Pd author Miller S. Puckette writes about this in the Pd manual in section +"2.6.2. persistence of data": + + Among the design principles of Pd is that patches should be printable, + in the sense that the appearance of a patch should fully determine its + functionality. For this reason, if messages received by an object + change its action, since the changes aren't reflected in the object's + appearance, they are not saved as part of the file which specifies the + patch and will be forgotten when the patch is reloaded. + +(I'll show an example of a float object changing "state" by a message in +its right inlet here.) + +Still, in a musician's practice some kind of persistence turns out to be an +important feature, that many Pd beginners do miss. So there are several +approaches to add it. Max/MSP has the ``preset``-object, Pd has the +``state``-object which saves the current state of (some) GUI objects inside +a patch. Both also support changing between several different states. + +Both have at least two problems: They save only the state of GUI objects, +which might not be all that a user wants to save. And they don't handle +abstractions very well, which are crucial when creating modularized +patches. + +Another approach is to (ab)use some of the Pd objects that can persist +itself to a file, especially ``textfile``, ``qlist`` and ``table``, which +works better, but isn't standardized. + +A rather new candidate for state saving is Thomas Grill's ``pool`` +external. Basically it offers something, that is standard in many +programming languages: a data structure that stores key-value-pairs. This +also is known as hash, dictonary or map. With ``pool`` those pairs also can +be stored in hierarchies and they can be saved to or loaded from disk. The +last but maybe most important feature for us is, that several pools can be +shared by giving them the same name. A ``pool MYPOOL`` in one patch will +contain the same data as a ``pool MYPOOL`` in another patch. Changes to one +pool will change the data in the other as well. + +A ``pool`` object is central to the persistence in RRADical patches, but it +is hidden behind an abstracted "API", if one could name it that. I'll +come back to haw this is done late. + +Communication +............. + +Besides persistance it also is important to create a common path through +which the RRADical modules will talk to each other. Generally the modules +will have to use, what Pd offers them, and that is either a direct +connection through patch cords or the indirect use of the send/receive +mechanism in Pd. Patch cords are fine, but tend to clutter the interface. +Sends and receives on the other hand will have to make sure, that no name +clashes occur. A name clash is, when one target receives messages not +intended for it. A patch author has to remember all used send-names, but +this gets harder, if he uses prefabricated modules, which might use their +own senders. + +So it is crucial, that senders in RRADical abstractions use local senders +only with as few exceptions as possible. This is achieved by prepending the +RRADical senders with the string "$0-". So you'd not use ``send volume``, +but instead use ``send $0-volume``. $0 makes those sends local inside their +own patch borders. This might be a bit difficult to understand to the +casual Pd user, but is a pretty standard idiom in the Pd world. + +Still we will want to control a lot of parameters and do so not only +through the GUI Pd offers, but probably also through other ways, for +example through Midi controllers, through some kind of score on disk, +through satellite navigation receivers or whatever. + +This creates a fundamental conflict: + +**We want borders** + We want to separate our abstraction so they don't conflict with each + other. +**We want border crossings** + We want to have a way to reach their many internals and control them + from the outside. + +The RRADical approach adheres to this in that it enforces a strict border +but drills a single hole in it: the **OSC inlet**. This idea is the result +of a discussion on the Pd mailing list and goes back to suggestions by +`Eric Skogen`_ and `Ben Bogart`_. Every RRADical patch has (to have) a +rightmost inlet that accepts messages formatted according to the OSC +protocol. OSC stands for `Open Sound Control`_ and is a network transparent +system to control audio applications remotely developed at CNMAT in Berkley. + +.. _`Eric Skogen`: http://www.audionerd.com +.. _`Ben Bogart`: http://www.ekran.org/ben/ +.. _`Open Sound Control`: http://www.cnmat.berkeley.edu/OpenSoundControl/ + +The nice thing about OSC is that it can control many parameters over a +single communication path. This is so, because OSC uses a URL-like scheme +to address parameters. An example would be this message:: + + /synth/fm/volume 85 + +It sends the message "85" to the "volume" control of a "fm" module below a +"synth" module. OSC allows many parameters constructs like:: + + /synth/fm/basenote 52 + /synth/virtualanalog/basenote 40 + /synth/*/playchords m7b5 M6 7b9 + +This might set the base note of two synths, `fm` and `virtualanalog` and +send a chord progression to be played by both -- indicated by the wildcard +`*` -- afterwards. + +The OSC-inlet of every RRADical patch is intended as the border crossing: +Everything the author of a certain patch intends to be controlled from the +outside can be controlled by OSC messages to the rightmost inlet. + + +Trying to remember it all: Memento +------------------------------------- + +To realize the functionality requirements developed so far I resorted to a +so called `Memento`. `"Memento"` is a very cool movie by director +Christopher Nolan where - quoting IMDB: + + A man, suffering from short-term memory loss, uses notes and tattoos to + hunt down his wife's killer. + +If you haven't already done so: Watch this movie! It's much better than +Matrix 2 and 3 and also stars Carrie-Anne "Trinity" Moss. + +Here's a scene from "Memento": + +.. image:: memento.png + +We see the film's main character Leonard who has a similar problem as Pd: he +cannot remember things. To deal with his persistence problem, his inability +to save data to his internal harddisk he resorts to taking a lot of photos. +These pictures act as what is called a Memento: a recording of the current +state of things. + +In software development Mementos are quite common as well. The computer +science literature describes them in great detail. To make the best use of +a Memento science recommends an approach where certain tasks are in the +responsibility of certain independent players. + +The Memento itself, as we have seen, is the photo, i.e. some kind of state +record. A module called the "Originator" is responsible for creating this +state and managing changes in it. In the movie, Leonard is the Originator, +he is the one taking photos of the world he is soon to forget. + +The actual persistence, that could be the saving of a state to harddisk, +but could just as well be an upload to a webserver or a CVS check-in, is +done by someone called the "Caretaker" in the literature. A Caretaker could +be a safe, where Leonard puts his photos, or could be a person, to whom +Leonard gives his photos. In the movie Leonard also makes "hard saves" by +tattooing himself with notes he took. In that case, he is not only the +Originator of the notes, but also the Caretaker in one single person. The +Caretaker only has to take care, that those photos, the Mementos, are in a +safe place and noone fiddles around with them. Btw: In the movie some +interesting problems with Caretakers, who don't always act responsible, +occur. + +Memento in Pd +............. + +I developed a set of abstractions, of patches for Pd, that follow this +design pattern. Memento for Pd includes a ``caretaker`` and an +``originator`` abstraction, plus a third one called ``commun`` which is +responsible for the **internal** communication. ``commun`` basically is +just a thin extension of ``originator`` and should be considered part of +it. There is another patch, the ``careGUI`` which I personally use instead +of the ``caretaker`` directly, because it has a simple GUI included. + +Here's how it looks: + +.. image:: caregui.png + +The ``careGUI`` is very simple: select a FILE-name to save to, then +clicking SAVE you can save the current state, with RESTORE you can restore +a state previously saved. After restore, the outlet of ``careGUI`` sends a +``bang`` message to be used as you like. + +Internally ``caretaker`` has a named ``pool`` object using the global pool +called "RRADICAL". The same ``pool RRADICAL`` also is used inside the +``originator`` object. This abstraction handles all access to this pool. A +user should not read or write the contents of ``pool RRADICAL`` directly. +The ``originator`` patch also handles the border crossing through OSC +messages by it's rightmost inlet. The patch accepts two mandatory +arguments: The first on is the name under which this patch is to be stored +inside the ``pool`` data. Each ``originator SomeName secondarg`` stores +it's data in a virtual subdirectory inside the RRADICAL-pool called like +its first argument - SomeName in the example. If the SomeName starts with a +slash like "/patch" , you can also accesse it via OSC through the rightmost inlet of +``originator`` under the tree "/patch" + +The second argument practically always will be $0. It is used to talk to +those ``commun`` objects which share the same second argument. As $0 is a +value local and unique to a patch (or to an abstraction to be correct) each +``originator`` then only can talk to ``commun``\s inside the same patch and +will not disturb other ``commun`` objects in other abstractions. + +The ``commun`` objects finally are where the contents of a state are read +and set. They, too, accept two arguments, the second of which was +discussed before and will most of the time just be $0. The first argument +will be the key under which some value will be saved. You should use a slash +as first character here as well to allow OSC control. So an example for a +usage would be ``commun /vol $0``. + +``commun`` has one inlet and one outlet. What comes in through the inlet is +send to ``originator`` who stores it inside its Memento under the key, that +is specified by the ``commun``'s first arg. Actually ``originator``. The +outlet of a ``commun`` will spit out the current value stored under its key +inside the Memento, when ``originator`` tells it to do so. So ``commun``\s +are intended to be cross-connected to some thing that can change. And +example would be a slider which can be connected as seen in the next +picture: + +.. image:: communslider.png + +In this patch, every change to the slider will be reflected inside the +Memento. The little print button in ``careGUI`` can be used to print the +contents to the console from which Pd was started. Setting the slider will +result in something like this:: + + /mypatch 0 , /volume , 38 + +Here a comma separates key and value pairs. "mypatch" is the toplevel +directory. This contains a 0, which is the default subdirectory, after that +comes the key "/volume", whose value is 38. Let's add another slider for +pan-values: + +.. image:: moresliders.png + +Moving the /pan slider will let careGUI print out:: + + /mypatch 0 , /volume , 38 + /mypatch 0 , /pan , 92 + +The ``originator`` can save several substates or presets by sending a +``substate #number`` message to its first inlet. Let's do just this and +move the sliders again as seen in the next picture: + +.. image:: substates.png + +Now careGUI prints:: + + /mypatch 0 , /volume , 38 + /mypatch 0 , /pan , 92 + /mypatch 1 , /volume , 116 + /mypatch 1 , /pan , 27 + +You see, the substate 0 is unaffected, the new state can have different +values. Exchanging the ``substate`` message with a ``setsub`` message will +autoload the selected state and "set" the sliders to the stored values +immediatly. + +OSC in Memento +............... + +The whole system now already is prepared to be used over OSC. You probably +already guess, how the message looks like. Any takers? Thank you, you're +right, the messages are built as ``/mypatch/volume #number`` and +``/mypatch/pan #number`` as shown in the next stage: + +.. image:: osccontrol.png + +Sometimes it is useful to also get OSC messages out of a patch, for example +to control other OSC software through Pd. For this the **OSC-outlet** of +``originator`` can be used, which is the rightmost outlet of the +abstraction. It will print out every change to the current state. +Connecting a ``print OSC`` debug object to it, we get to see what's coming +out of the OSC-outlet when we move a slider:: + + OSC: /mypatch/pan 92 + OSC: /mypatch/pan 91 + OSC: /mypatch/pan 90 + OSC: /mypatch/pan 89 + +Putting it all to RRADical use +--------------------------------- + +Now that the foundation for a general preset and communication system are +set, it is possible to build real patches with it that have two main +characteristics: + +**Rapidity** + Ready-to-use highlevel abstraction can save a lot of time when building + larger patches. Clear communication paths will let you think faster and + more about the really important things. + +**Reusability** + Don't reinvent the wheel all the time. Reuse patches like instruments + for more than one piece by just exchanging the Caretaker-file used. + +I already developed a growing number of patches that follow the RRADical +paradigm, among these are a complex pattern sequencer, some synths and +effects and more. The RRADical collection comes with a template file, +called ``rrad.tpl`` that makes deploying new RRADical patches easier and +lets developers concentrate on the algorighm instead of bookeeping. Some +utils (footils?) help with creating the sometimes needed many +``commun``-objects. Several usecases show example applications of the +provided abstractions. + + diff --git a/doc/rradicalpd.tex b/doc/rradicalpd.tex new file mode 100644 index 0000000..157aace --- /dev/null +++ b/doc/rradicalpd.tex @@ -0,0 +1,511 @@ +\documentclass[10pt,english]{scrartcl} +\usepackage{babel} +\usepackage{shortvrb} +\usepackage[latin1]{inputenc} +\usepackage{tabularx} +\usepackage{longtable} +\setlength{\extrarowheight}{2pt} +\usepackage{amsmath} +\usepackage{graphicx} +\usepackage{color} +\usepackage{multirow} +\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref} +\usepackage[a4paper,margin=2cm,nohead]{geometry} +%% generator Docutils: http://docutils.sourceforge.net/ +\newlength{\admonitionwidth} +\setlength{\admonitionwidth}{0.9\textwidth} +\newlength{\docinfowidth} +\setlength{\docinfowidth}{0.9\textwidth} +\newcommand{\optionlistlabel}[1]{\bf #1 \hfill} +\newenvironment{optionlist}[1] +{\begin{list}{} + {\setlength{\labelwidth}{#1} + \setlength{\rightmargin}{1cm} + \setlength{\leftmargin}{\rightmargin} + \addtolength{\leftmargin}{\labelwidth} + \addtolength{\leftmargin}{\labelsep} + \renewcommand{\makelabel}{\optionlistlabel}} +}{\end{list}} +% begin: floats for footnotes tweaking. +\setlength{\floatsep}{0.5em} +\setlength{\textfloatsep}{\fill} +\addtolength{\textfloatsep}{3em} +\renewcommand{\textfraction}{0.5} +\renewcommand{\topfraction}{0.5} +\renewcommand{\bottomfraction}{0.5} +\setcounter{totalnumber}{50} +\setcounter{topnumber}{50} +\setcounter{bottomnumber}{50} +% end floats for footnotes +% some commands, that could be overwritten in the style file. +\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}} +% end of "some commands" +\title{RRADical Pd} +\author{} +\date{} +\hypersetup{ +pdftitle={RRADical Pd}, +pdfauthor={Frank Barknecht {$<$}fbar@footils.org{$>$}} +} +\raggedbottom +\begin{document} +\maketitle + +%___________________________________________________________________________ +\begin{center} +\begin{tabularx}{\docinfowidth}{lX} +\textbf{Author}: & + Frank Barknecht {$<$}fbar@footils.org{$>$} \\ +\end{tabularx} +\end{center} +\subsection*{~\hfill Abstract\hfill ~} + +The goal of RRADical Pd is to create a collection of patches, that make +Pd easier and faster to use for people who are more used to commercial +software like Reason(tm) or Reaktor(tm). RRAD as an acronym stands for +``Reusable and Rapid Audio Development'' or ``Reusable and Rapid +Application Development'', if it includes non-audio patches, with Pd. It +is spelled RRAD, but pronounced Rradical. ;) + + + +%___________________________________________________________________________ + +\hypertarget{what-it-takes-to-be-a-rradical}{} +\section*{What it takes to be a RRADical} +\pdfbookmark[0]{What it takes to be a RRADical}{what-it-takes-to-be-a-rradical} + +RRAD as an acronym stands for ``Reusable and Rapid Audio Development'' or +``Reusable and Rapid Application Development'', if it includes non-audio +patches, with Pd. It is spelled RRAD, but pronounced Rradical. ;) + +The goal of RRADical Pd is to create a collection of patches, that make Pd +easier and faster to use for people who are more used to software like Reason(tm) +or Reaktor(tm). For that I would like to create patches, that solve real-world +problems on a higher level of abstraction than the standard Pd objects do. +Where suitable these high level abstractions should have a GUIs +built in. + +So for example instead of a basic \texttt{lop{\~{ }}} low pass filter something more +complete like a recreation of the Sherman filter bank could be included in +that collection. My older sseq and angriff patches followed this idea in +general, but there are much more patches needed. Like this: +\begin{itemize} +\item +a sample player (adapt Gyre?) + +\item +Various OSC/LFO with preset waveforms + +\item +drum machine + +\item +guitar simulator + +\item +grain sample player + +\item +more sequencers + +\item +basically a lot of things like these things in Reason + +\end{itemize} + +Not that I want to make Pd be Reason, no way. But pre-fabricated high-level +abstractions may not only make Pd easier to use for beginners, they also +can spare lot of tedious, repeating patching work. + + +%___________________________________________________________________________ + +\hypertarget{problems-and-solutions}{} +\section*{Problems and Solutions} +\pdfbookmark[0]{Problems and Solutions}{problems-and-solutions} + +To building above system several problems are to be solved. Two key areas +already targetted are: +\begin{description} +%[visit_definition_list_item] +\item[\textbf{Persistence}] +%[visit_definition] + +How to save the current state of a patch? How to save more than one +state (state sequencing)? + +%[depart_definition] +%[depart_definition_list_item] +%[visit_definition_list_item] +\item[\textbf{Communication}] +%[visit_definition] + +The various modules are building blocks for a larger application. How +should they talk to each other. (In Reason this is done by patching the +back or modules with horrible looking cables. We must do better.) + +%[depart_definition] +%[depart_definition_list_item] +\end{description} + +It turned out, that both tasks are possible to solve in a consistent way +using a unique abstraction. But first lets look a bit deeper at the +problems at hand. + + +%___________________________________________________________________________ + +\hypertarget{persistence}{} +\subsection*{Persistence} +\pdfbookmark[1]{Persistence}{persistence} + +Pd offers no direct way to store the current state of a patch. Here's what +Pd author Miller S. Puckette writes about this in the Pd manual in section +``2.6.2. persistence of data'': +\begin{quote} + +Among the design principles of Pd is that patches should be printable, +in the sense that the appearance of a patch should fully determine its +functionality. For this reason, if messages received by an object +change its action, since the changes aren't reflected in the object's +appearance, they are not saved as part of the file which specifies the +patch and will be forgotten when the patch is reloaded. +\end{quote} + +(I'll show an example of a float object changing ``state'' by a message in +its right inlet here.) + +Still, in a musician's practice some kind of persistence turns out to be an +important feature, that many Pd beginners do miss. So there are several +approaches to add it. Max/MSP has the \texttt{preset}-object, Pd has the +\texttt{state}-object which saves the current state of (some) GUI objects inside +a patch. Both also support changing between several different states. + +Both have at least two problems: They save only the state of GUI objects, +which might not be all that a user wants to save. And they don't handle +abstractions very well, which are crucial when creating modularized +patches. + +Another approach is to (ab)use some of the Pd objects that can persist +itself to a file, especially \texttt{textfile}, \texttt{qlist} and \texttt{table}, which +works better, but isn't standardized. + +A rather new candidate for state saving is Thomas Grill's \texttt{pool} +external. Basically it offers something, that is standard in many +programming languages: a data structure that stores key-value-pairs. This +also is known as hash, dictonary or map. With \texttt{pool} those pairs also can +be stored in hierarchies and they can be saved to or loaded from disk. The +last but maybe most important feature for us is, that several pools can be +shared by giving them the same name. A \texttt{pool MYPOOL} in one patch will +contain the same data as a \texttt{pool MYPOOL} in another patch. Changes to one +pool will change the data in the other as well. + +A \texttt{pool} object is central to the persistence in RRADical patches, but it +is hidden behind an abstracted ``API'', if one could name it that. I'll +come back to haw this is done late. + + +%___________________________________________________________________________ + +\hypertarget{communication}{} +\subsection*{Communication} +\pdfbookmark[1]{Communication}{communication} + +Besides persistance it also is important to create a common path through +which the RRADical modules will talk to each other. Generally the modules +will have to use, what Pd offers them, and that is either a direct +connection through patch cords or the indirect use of the send/receive +mechanism in Pd. Patch cords are fine, but tend to clutter the interface. +Sends and receives on the other hand will have to make sure, that no name +clashes occur. A name clash is, when one target receives messages not +intended for it. A patch author has to remember all used send-names, but +this gets harder, if he uses prefabricated modules, which might use their +own senders. + +So it is crucial, that senders in RRADical abstractions use local senders +only with as few exceptions as possible. This is achieved by prepending the +RRADical senders with the string ``{\$}0-''. So you'd not use \texttt{send volume}, +but instead use \texttt{send {\$}0-volume}. {\$}0 makes those sends local inside their +own patch borders. This might be a bit difficult to understand to the +casual Pd user, but is a pretty standard idiom in the Pd world. + +Still we will want to control a lot of parameters and do so not only +through the GUI Pd offers, but probably also through other ways, for +example through Midi controllers, through some kind of score on disk, +through satellite navigation receivers or whatever. + +This creates a fundamental conflict: +\begin{description} +%[visit_definition_list_item] +\item[\textbf{We want borders} ] +%[visit_definition] + +We want to separate our abstraction so they don't conflict with each +other. + +%[depart_definition] +%[depart_definition_list_item] +%[visit_definition_list_item] +\item[\textbf{We want border crossings}] +%[visit_definition] + +We want to have a way to reach their many internals and control them +from the outside. + +%[depart_definition] +%[depart_definition_list_item] +\end{description} + +The RRADical approach adheres to this in that it enforces a strict border +but drills a single hole in it: the \textbf{OSC inlet}. This idea is the result +of a discussion on the Pd mailing list and goes back to suggestions by +\href{http://www.audionerd.com}{Eric Skogen} and \href{http://www.ekran.org/ben/}{Ben Bogart}. Every RRADical patch has (to have) a +rightmost inlet that accepts messages formatted according to the OSC +protocol. OSC stands for \href{http://www.cnmat.berkeley.edu/OpenSoundControl/}{Open Sound Control} and is a network transparent +system to control audio applications remotely developed at CNMAT in Berkley. + +The nice thing about OSC is that it can control many parameters over a +single communication path. This is so, because OSC uses a URL-like scheme +to address parameters. An example would be this message: +\begin{ttfamily}\begin{flushleft} +\mbox{/synth/fm/volume~85} +\end{flushleft}\end{ttfamily} + +It sends the message ``85'' to the ``volume'' control of a ``fm'' module below a +``synth'' module. OSC allows many parameters constructs like: +\begin{ttfamily}\begin{flushleft} +\mbox{/synth/fm/basenote~~~~~~~~~~~~~~52}\\ +\mbox{/synth/virtualanalog/basenote~~~40}\\ +\mbox{/synth/*/playchords~~~~~~~~~~~~~m7b5~M6~7b9} +\end{flushleft}\end{ttfamily} + +This might set the base note of two synths, fm and virtualanalog and +send a chord progression to be played by both -- indicated by the wildcard +* -- afterwards. + +The OSC-inlet of every RRADical patch is intended as the border crossing: +Everything the author of a certain patch intends to be controlled from the +outside can be controlled by OSC messages to the rightmost inlet. + + +%___________________________________________________________________________ + +\hypertarget{trying-to-remember-it-all-memento}{} +\section*{Trying to remember it all: Memento} +\pdfbookmark[0]{Trying to remember it all: Memento}{trying-to-remember-it-all-memento} + +To realize the functionality requirements developed so far I resorted to a +so called Memento. ``Memento'' is a very cool movie by director +Christopher Nolan where - quoting IMDB: +\begin{quote} + +A man, suffering from short-term memory loss, uses notes and tattoos to +hunt down his wife's killer. +\end{quote} + +If you haven't already done so: Watch this movie! It's much better than +Matrix 2 and 3 and also stars Carrie-Anne ``Trinity'' Moss. + +Here's a scene from ``Memento'': + +\includegraphics{memento.png} + +We see the film's main character Leonard who has a similar problem as Pd: he +cannot remember things. To deal with his persistence problem, his inability +to save data to his internal harddisk he resorts to taking a lot of photos. +These pictures act as what is called a Memento: a recording of the current +state of things. + +In software development Mementos are quite common as well. The computer +science literature describes them in great detail. To make the best use of +a Memento science recommends an approach where certain tasks are in the +responsibility of certain independent players. + +The Memento itself, as we have seen, is the photo, i.e. some kind of state +record. A module called the ``Originator'' is responsible for creating this +state and managing changes in it. In the movie, Leonard is the Originator, +he is the one taking photos of the world he is soon to forget. + +The actual persistence, that could be the saving of a state to harddisk, +but could just as well be an upload to a webserver or a CVS check-in, is +done by someone called the ``Caretaker'' in the literature. A Caretaker could +be a safe, where Leonard puts his photos, or could be a person, to whom +Leonard gives his photos. In the movie Leonard also makes ``hard saves'' by +tattooing himself with notes he took. In that case, he is not only the +Originator of the notes, but also the Caretaker in one single person. The +Caretaker only has to take care, that those photos, the Mementos, are in a +safe place and noone fiddles around with them. Btw: In the movie some +interesting problems with Caretakers, who don't always act responsible, +occur. + + +%___________________________________________________________________________ + +\hypertarget{memento-in-pd}{} +\subsection*{Memento in Pd} +\pdfbookmark[1]{Memento in Pd}{memento-in-pd} + +I developed a set of abstractions, of patches for Pd, that follow this +design pattern. Memento for Pd includes a \texttt{caretaker} and an +\texttt{originator} abstraction, plus a third one called \texttt{commun} which is +responsible for the \textbf{internal} communication. \texttt{commun} basically is +just a thin extension of \texttt{originator} and should be considered part of +it. There is another patch, the \texttt{careGUI} which I personally use instead +of the \texttt{caretaker} directly, because it has a simple GUI included. + +Here's how it looks: + +\includegraphics{caregui.png} + +The \texttt{careGUI} is very simple: select a FILE-name to save to, then +clicking SAVE you can save the current state, with RESTORE you can restore +a state previously saved. After restore, the outlet of \texttt{careGUI} sends a +\texttt{bang} message to be used as you like. + +Internally \texttt{caretaker} has a named \texttt{pool} object using the global pool +called ``RRADICAL''. The same \texttt{pool RRADICAL} also is used inside the +\texttt{originator} object. This abstraction handles all access to this pool. A +user should not read or write the contents of \texttt{pool RRADICAL} directly. +The \texttt{originator} patch also handles the border crossing through OSC +messages by it's rightmost inlet. The patch accepts two mandatory +arguments: The first on is the name under which this patch is to be stored +inside the \texttt{pool} data. Each \texttt{originator SomeName secondarg} stores +it's data in a virtual subdirectory inside the RRADICAL-pool called like +its first argument - SomeName in the example. If the SomeName starts with a +slash like ``/patch'' , you can also accesse it via OSC through the rightmost inlet of +\texttt{originator} under the tree ``/patch'' + +The second argument practically always will be {\$}0. It is used to talk to +those \texttt{commun} objects which share the same second argument. As {\$}0 is a +value local and unique to a patch (or to an abstraction to be correct) each +\texttt{originator} then only can talk to \texttt{commun}s inside the same patch and +will not disturb other \texttt{commun} objects in other abstractions. + +The \texttt{commun} objects finally are where the contents of a state are read +and set. They, too, accept two arguments, the second of which was +discussed before and will most of the time just be {\$}0. The first argument +will be the key under which some value will be saved. You should use a slash +as first character here as well to allow OSC control. So an example for a +usage would be \texttt{commun /vol {\$}0}. + +\texttt{commun} has one inlet and one outlet. What comes in through the inlet is +send to \texttt{originator} who stores it inside its Memento under the key, that +is specified by the \texttt{commun}'s first arg. Actually \texttt{originator}. The +outlet of a \texttt{commun} will spit out the current value stored under its key +inside the Memento, when \texttt{originator} tells it to do so. So \texttt{commun}s +are intended to be cross-connected to some thing that can change. And +example would be a slider which can be connected as seen in the next +picture: + +\includegraphics{communslider.png} + +In this patch, every change to the slider will be reflected inside the +Memento. The little print button in \texttt{careGUI} can be used to print the +contents to the console from which Pd was started. Setting the slider will +result in something like this: +\begin{ttfamily}\begin{flushleft} +\mbox{/mypatch~0~,~/volume~,~38} +\end{flushleft}\end{ttfamily} + +Here a comma separates key and value pairs. ``mypatch'' is the toplevel +directory. This contains a 0, which is the default subdirectory, after that +comes the key ``/volume'', whose value is 38. Let's add another slider for +pan-values: + +\includegraphics{moresliders.png} + +Moving the /pan slider will let careGUI print out: +\begin{ttfamily}\begin{flushleft} +\mbox{/mypatch~0~,~/volume~,~38}\\ +\mbox{/mypatch~0~,~/pan~,~92} +\end{flushleft}\end{ttfamily} + +The \texttt{originator} can save several substates or presets by sending a +\texttt{substate {\#}number} message to its first inlet. Let's do just this and +move the sliders again as seen in the next picture: + +\includegraphics{substates.png} + +Now careGUI prints: +\begin{ttfamily}\begin{flushleft} +\mbox{/mypatch~0~,~/volume~,~38}\\ +\mbox{/mypatch~0~,~/pan~,~92}\\ +\mbox{/mypatch~1~,~/volume~,~116}\\ +\mbox{/mypatch~1~,~/pan~,~27} +\end{flushleft}\end{ttfamily} + +You see, the substate 0 is unaffected, the new state can have different +values. Exchanging the \texttt{substate} message with a \texttt{setsub} message will +autoload the selected state and ``set'' the sliders to the stored values +immediatly. + + +%___________________________________________________________________________ + +\hypertarget{osc-in-memento}{} +\subsection*{OSC in Memento} +\pdfbookmark[1]{OSC in Memento}{osc-in-memento} + +The whole system now already is prepared to be used over OSC. You probably +already guess, how the message looks like. Any takers? Thank you, you're +right, the messages are built as \texttt{/mypatch/volume {\#}number} and +\texttt{/mypatch/pan {\#}number} as shown in the next stage: + +\includegraphics{osccontrol.png} + +Sometimes it is useful to also get OSC messages out of a patch, for example +to control other OSC software through Pd. For this the \textbf{OSC-outlet} of +\texttt{originator} can be used, which is the rightmost outlet of the +abstraction. It will print out every change to the current state. +Connecting a \texttt{print OSC} debug object to it, we get to see what's coming +out of the OSC-outlet when we move a slider: +\begin{ttfamily}\begin{flushleft} +\mbox{OSC:~/mypatch/pan~92}\\ +\mbox{OSC:~/mypatch/pan~91}\\ +\mbox{OSC:~/mypatch/pan~90}\\ +\mbox{OSC:~/mypatch/pan~89} +\end{flushleft}\end{ttfamily} + + +%___________________________________________________________________________ + +\hypertarget{putting-it-all-to-rradical-use}{} +\section*{Putting it all to RRADical use} +\pdfbookmark[0]{Putting it all to RRADical use}{putting-it-all-to-rradical-use} + +Now that the foundation for a general preset and communication system are +set, it is possible to build real patches with it that have two main +characteristics: +\begin{description} +%[visit_definition_list_item] +\item[\textbf{Rapidity}] +%[visit_definition] + +Ready-to-use highlevel abstraction can save a lot of time when building +larger patches. Clear communication paths will let you think faster and +more about the really important things. + +%[depart_definition] +%[depart_definition_list_item] +%[visit_definition_list_item] +\item[\textbf{Reusability}] +%[visit_definition] + +Don't reinvent the wheel all the time. Reuse patches like instruments +for more than one piece by just exchanging the Caretaker-file used. + +%[depart_definition] +%[depart_definition_list_item] +\end{description} + +I already developed a growing number of patches that follow the RRADical +paradigm, among these are a complex pattern sequencer, some synths and +effects and more. The RRADical collection comes with a template file, +called \texttt{rrad.tpl} that makes deploying new RRADical patches easier and +lets developers concentrate on the algorighm instead of bookeeping. Some +utils (footils?) help with creating the sometimes needed many +\texttt{commun}-objects. Several usecases show example applications of the +provided abstractions. + +\end{document} diff --git a/doc/substates.pd b/doc/substates.pd new file mode 100644 index 0000000..f194967 --- /dev/null +++ b/doc/substates.pd @@ -0,0 +1,17 @@ +#N canvas 186 212 462 290 10; +#X obj 35 25 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 3800 1; +#X obj 62 108 commun /volume \$0; +#X obj 220 145 originator /mypatch \$0; +#X obj 21 174 careGUI; +#X obj 108 64 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 9200 1; +#X obj 140 35 commun /pan \$0; +#X floatatom 220 98 5 0 0 1 substate_selector - -; +#X msg 220 121 substate \$1; +#X connect 0 0 1 0; +#X connect 1 0 0 0; +#X connect 4 0 5 0; +#X connect 5 0 4 0; +#X connect 6 0 7 0; +#X connect 7 0 2 0; diff --git a/doc/substates.png b/doc/substates.png Binary files differnew file mode 100644 index 0000000..0667fab --- /dev/null +++ b/doc/substates.png |