├── .gitignore ├── LICENSE.txt ├── README.rst ├── example1 ├── Makefile └── helloworld.c ├── example2 ├── Makefile └── counter.c ├── example3 ├── Makefile └── counter.c ├── example4 ├── Makefile └── xfade~.c ├── legacy ├── HOWTO-externals-de.tex ├── Makefile └── pd-externals-HOWTO.tex └── pd-lib-builder ├── CHANGELOG.txt ├── Makefile.pdlibbuilder ├── README.md └── tips-tricks.md /.gitignore: -------------------------------------------------------------------------------- 1 | # object files 2 | *.o 3 | 4 | # macOS 5 | *.pd_darwin 6 | 7 | # GNU/Linux 8 | *.pd_linux 9 | 10 | # Windows 11 | *.lib 12 | *.dll 13 | 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pure-data/externals-howto/06958d03525e75f81c90e9b006fbbfbfe6f9d7d4/LICENSE.txt -------------------------------------------------------------------------------- /example1/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to build class 'helloworld' for Pure Data. 2 | # Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build 3 | # settings and rules. 4 | 5 | # library name 6 | lib.name = externals.howto.example1 7 | 8 | # input source file (class name == source file basename) 9 | class.sources = helloworld.c 10 | 11 | # all extra files to be included in binary distribution of the library 12 | datafiles = 13 | 14 | # include Makefile.pdlibbuilder from submodule directory 'pd-lib-builder' 15 | PDLIBBUILDER_DIR=../pd-lib-builder/ 16 | include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder 17 | -------------------------------------------------------------------------------- /example1/helloworld.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pure-data/externals-howto/06958d03525e75f81c90e9b006fbbfbfe6f9d7d4/example1/helloworld.c -------------------------------------------------------------------------------- /example2/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to build class 'counter' for Pure Data. 2 | # Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build 3 | # settings and rules. 4 | 5 | # library name 6 | lib.name = externals.howto.example2 7 | 8 | # input source file (class name == source file basename) 9 | class.sources = counter.c 10 | 11 | # all extra files to be included in binary distribution of the library 12 | datafiles = 13 | 14 | # include Makefile.pdlibbuilder from submodule directory 'pd-lib-builder' 15 | PDLIBBUILDER_DIR=../pd-lib-builder/ 16 | include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder 17 | -------------------------------------------------------------------------------- /example2/counter.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pure-data/externals-howto/06958d03525e75f81c90e9b006fbbfbfe6f9d7d4/example2/counter.c -------------------------------------------------------------------------------- /example3/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to build class 'counter' for Pure Data. 2 | # Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build 3 | # settings and rules. 4 | 5 | # library name 6 | lib.name = externals.howto.example3 7 | 8 | # input source file (class name == source file basename) 9 | class.sources = counter.c 10 | 11 | # all extra files to be included in binary distribution of the library 12 | datafiles = 13 | 14 | # include Makefile.pdlibbuilder from submodule directory 'pd-lib-builder' 15 | PDLIBBUILDER_DIR=../pd-lib-builder/ 16 | include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder 17 | -------------------------------------------------------------------------------- /example3/counter.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pure-data/externals-howto/06958d03525e75f81c90e9b006fbbfbfe6f9d7d4/example3/counter.c -------------------------------------------------------------------------------- /example4/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to build class 'xfade~' for Pure Data. 2 | # Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build 3 | # settings and rules. 4 | 5 | # library name 6 | lib.name = externals.howto.example4 7 | 8 | # input source file (class name == source file basename) 9 | class.sources = xfade~.c 10 | 11 | # all extra files to be included in binary distribution of the library 12 | datafiles = 13 | 14 | # include Makefile.pdlibbuilder from submodule directory 'pd-lib-builder' 15 | PDLIBBUILDER_DIR=../pd-lib-builder/ 16 | include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder 17 | -------------------------------------------------------------------------------- /example4/xfade~.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pure-data/externals-howto/06958d03525e75f81c90e9b006fbbfbfe6f9d7d4/example4/xfade~.c -------------------------------------------------------------------------------- /legacy/HOWTO-externals-de.tex: -------------------------------------------------------------------------------- 1 | % format latexg -*- latex -*- 2 | 3 | \documentclass[12pt, a4paper,austrian, titlepage]{article} 4 | 5 | %% HOWTO write an external for Pd 6 | %% Copyright (c) 2001-2014 by IOhannes m zmölnig 7 | %% 8 | %% Permission is granted to copy, distribute and/or modify this document 9 | %% under the terms of the GNU Free Documentation License, Version 1.2 10 | %% or any later version published by the Free Software Foundation; 11 | %% with no Invariant Sections, no Front-Cover Texts, and no Back-Cover 12 | %% Texts. A copy of the license is included in the LICENSE.txt file. 13 | 14 | %sprache 15 | \usepackage[utf8]{inputenc} 16 | 17 | \usepackage[T1]{fontenc} 18 | \usepackage[austrian]{babel} 19 | 20 | % add hypertext support (fine for latex2html) 21 | \usepackage{html} 22 | 23 | % add landscape support (for rotating text through 90deg) 24 | \usepackage{lscape} 25 | 26 | 27 | %\begin{latexonly} 28 | % pdf kompatibilität 29 | \newif\ifpdf 30 | \ifx\pdfoutput\undefined 31 | \pdffalse % we are not running PDFLatex 32 | \else 33 | \pdfoutput=1 % yes, we are running PDFLatex 34 | \pdftrue 35 | \fi 36 | 37 | \latexhtml{ 38 | \ifpdf 39 | \usepackage[pdftex]{graphicx} 40 | \pdfcompresslevel=9 41 | \else 42 | \usepackage{graphicx} 43 | \fi 44 | }{ 45 | \usepackage{graphicx} 46 | } 47 | 48 | 49 | \title{ 50 | HOWTO \\ 51 | write an External \\ 52 | for {\em Pure data} 53 | } 54 | 55 | \author{ 56 | IOhannes m zmölnig \\ 57 | \\ 58 | {\em 59 | \latexhtml{institut für elektronische musik und akustik} 60 | {\htmladdnormalink{institut für elektronische musik und akustik}{http://iem.at}} 61 | } 62 | } 63 | 64 | \date{} 65 | 66 | \begin {document} 67 | \maketitle 68 | 69 | \hyphenation{Echt-zeit} 70 | \hyphenation{Computer-musik-program-men} 71 | \hyphenation{Echt-zeit-Computer-musik-pro-gramm} 72 | 73 | \begin{abstract} 74 | Pd ist ein graphisches Computermusiksystem in der Tradition von IRCAMs {\em ISPW-max}. 75 | 76 | Obwohl eine Fülle von Funktionen von Pd selbst zur Verfügung gestellt 77 | werden, stößt man doch manchmal an die Grenzen dessen, 78 | das mit diesen Primitiven und ihren Kombinationen möglich ist. 79 | 80 | Deswegen bietet Pd die Möglichkeit, eigene Primitive (``objects'', Objekte) in komplexen 81 | Programmiersprachen wie {\tt C/C++} zu erstellen. 82 | 83 | In diesem Dokument soll beschrieben werden, wie man solche Primitive mit Hilfe der 84 | Sprache {\tt C}, in der auch Pd selbst realisiert wurde, schreibt. 85 | \end{abstract} 86 | 87 | 88 | \vfill 89 | \newpage 90 | 91 | \tableofcontents 92 | 93 | \vfill 94 | \newpage 95 | 96 | \section{Voraussetzungen und Begriffsbestimmungen} 97 | 98 | Pd bezieht sich auf das graphische Echtzeit-Computermusikprogramm von 99 | Miller~S.~Puckette. 100 | {\em Pure data}. 101 | 102 | Zum Verständnis dieses Dokumentes wird der Umgang mit Pd sowie 103 | Verständnis von Programmiertechniken, insbesondere {\tt C} vorausgesetzt. 104 | 105 | Zum Schreiben von eigenen Primitiven wird weiters ein {\tt C}-Compiler, 106 | der dem {\tt ANSI-C}-Standard genügt, notwendig sein. 107 | Solche Compiler sind beispielsweise der {\em Gnu C-Compiler} (gcc) auf linux-Systemen oder 108 | {\em Visual-C++} auf Windows-Systemen. 109 | 110 | \subsection{Klassen, Instanzen und Objekte} 111 | Pd ist in der Programmiersprache {\tt C} geschrieben. 112 | Allerdings ist Pd auf Grund seiner graphischen Natur ein {\em objektorientiertes} System. 113 | Da {\tt C} die Verwendung von Klassen nicht sehr gut unterstützt, ist der resultierende 114 | Quellcode nicht so elegant wie er zum Beispiel unter {\tt C++} wäre. 115 | 116 | Der Ausdruck {\em Klasse} bezieht sich in diesem Dokument auf die Realisierung eines 117 | Konzeptes, bei dem Daten und Manipulatoren eine Einheit bilden. 118 | 119 | Konkrete {\em Instanzen einer Klasse} sind {\em Objekte}. 120 | 121 | \subsection{Internals, Externals und Libraries} 122 | Um Begriffsverwirrungen von vorneherein auszuschließen, seien hier kurz die Ausdrücke 123 | {\em Internal}, {\em External} und {\em Library} erklärt. 124 | 125 | \paragraph{Internal} 126 | Ein {\em Internal} ist eine Klasse, die in Pd eingebaut ist. 127 | Viele Primitive wie ``+'', ``pack'' oder ``sig\~\/`` sind {\em Internals} 128 | 129 | \paragraph{External} 130 | Ein {\em External} ist eine Klasse, die nicht in Pd eingebaut ist und erst zur Laufzeit 131 | nachgeladen wird. 132 | Sind sie einmal im Speicher von Pd, so sind {\em Externals} nicht mehr von {\em Internals} zu 133 | unterscheiden. 134 | 135 | \paragraph{Library} 136 | Eine {\em Library} bezeichnet eine Sammlung von {\em Externals}, 137 | die gemeinsam in eine Binärdatei kompiliert werden. 138 | 139 | {\em Library}-Dateien müssen eine betriebssystemabhängige Namenskonvention einhalten: 140 | 141 | \begin{tabular}{c||c|c|c} 142 | Bibliothek&linux&irix&Win32 \\ 143 | \hline 144 | {\tt my\_lib}&{\tt my\_lib.pd\_linux}&{\tt my\_lib.pd\_irix}& 145 | {\tt my\_lib.dll}\\ 146 | \end{tabular} 147 | 148 | Die einfachste Form einer {\em Library} beinhaltet genau ein {\em External}, 149 | das den selben Name trägt, wie auch die {\em Library} 150 | 151 | Im Gegensatz zu Externals können {\em Libraries} mit bestimmten Befehlen 152 | von Pd importiert werden. 153 | Ist eine {\em Library} importiert worden, 154 | so sind alle {\em Externals}, die sie beinhaltet, 155 | in den Speicher geladen und stehen als Objekte zur Verfügung. 156 | 157 | Pd stellt zwei Methoden zur Verfügung, um {\em Libraries} zu laden: 158 | \begin{itemize} 159 | \item mit der commandline-Option ``{\tt -lib my\_lib}'' 160 | \item durch Kreieren eines Objektes ``{\tt my\_lib}'' 161 | \end{itemize} 162 | 163 | Die erste Methode lädt die {\em Library} sofort beim Starten von Pd. 164 | Dies ist die zu bevorzugende Methode für {\em Libraries}, 165 | die mehrere {\em Externals} beinhalten. 166 | 167 | Die zweite Methode ist für {\em Libraries} zu bevorzugen, die genau 168 | ein {\em External} mit dem selben Namen beinhalten. 169 | Bei der zweiten Methode wird zuerst geprüft, ob eine Klasse namens ``my\_lib'' bereits 170 | in den Speicher geladen ist. 171 | Ist dies nicht der Fall\footnote 172 | {Ist eine solche Klasse bereits im Speicher, wird ein 173 | Objekt namens ``my\_lib'' instanziiert und der Vorgang bricht ab. 174 | Es wird also keine neue {\em Library} geladen. 175 | Man kann daher keine {\em Libraries} mit bereits verwendeten Klassennamen, 176 | wie zum Beispiel ``abs'', laden.} 177 | so werden alle Pfade untersucht, 178 | ob darin eine Datei namens ``{\tt my\_lib.pd\_linux}''\footnote{ 179 | oder einer anderen betriebssystemabhängigen Dateinamenerweiterung (s.o.)} 180 | existiert. 181 | Wird eine solche Datei gefunden, so werden alle in ihr enthaltenen {\em Externals} 182 | in den Speicher geladen. 183 | Danach wird nachgesehen, ob nun eine Klasse namens ``my\_lib'' 184 | als (neu geladenes) {\em External} im Speicher existiert. 185 | Ist dies der Fall, so wird eine Instanz dieser Klasse geschaffen. 186 | Ansonsten wird eine Fehlermeldung ausgegeben, die Instanziierung ist gescheitert. 187 | 188 | 189 | \section{mein erstes External: {\tt helloworld}} 190 | Wie das beim Erlernen von Programmiersprachen so üblich ist, 191 | beginnen wir mit ``Hello world''. 192 | 193 | Ein Objekt soll geschaffen werden, dass jedesmal, wenn es 194 | mit ``bang'' getriggert wird, die Zeile ``Hello world!!'' auf 195 | die Standardausgabe schreibt. 196 | 197 | \subsection{die Schnittstelle zu Pd} 198 | Um ein Pd-External zu schreiben, braucht man eine wohldefinierte Schnittstelle. 199 | Diese wird in der Datei ``m\_pd.h'' zur Verfügung gestellt. 200 | 201 | \begin{verbatim} 202 | #include "m_pd.h" 203 | \end{verbatim} 204 | 205 | 206 | \subsection{eine Klasse und ihr Datenraum} 207 | Als nächstes muß eine neue Klasse vorbereitet und der 208 | Datenraum für diese Klasse definiert werden. 209 | 210 | \begin{verbatim} 211 | static t_class *helloworld_class; 212 | 213 | typedef struct _helloworld { 214 | t_object x_obj; 215 | } t_helloworld; 216 | \end{verbatim} 217 | 218 | \verb+hello_worldclass+ wird der Zeiger auf die neue Klasse. 219 | 220 | Die Struktur \verb+t_helloworld+ (vom Typ \verb+_helloworld+) 221 | stellt den Datenraum der Klasse dar. 222 | Ein unverzichtbares Element ist dabei eine Variable des Type \verb+t_object+. 223 | In ihr werden interne Objekteigenschaften abgelegt, wie zum Beispiel 224 | die Größe der Objekt-Box bei der graphischen Darstellung, aber auch 225 | Daten über Inlets und Outlets. 226 | \verb+t_object+ muss der erste Eintrag in die Struktur sein ! 227 | 228 | Da bei einer einfachen ``Hello world''-Anwendung keine Variablen gebraucht werden, 229 | ist die Struktur ansonsten leer. 230 | 231 | \subsection{Methodenraum} 232 | Zu einer Klasse gehören neben einem Datenraum auch ein Satz von 233 | Manipulatoren (Methoden) mit denen diese Daten manipuliert werden können. 234 | 235 | Wird eine Message an eine Instanz unserer Klasse geschickt, 236 | so wird eine Methoden aufgerufen. 237 | Diese Mehtoden, die die Schnittstelle zum Messagesystem von Pd bilden, 238 | haben grundsätzlich kein Rückgabeargument, sind also vom Typ \verb+void+. 239 | 240 | \begin{verbatim} 241 | void helloworld_bang(t_helloworld *x) 242 | { 243 | post("Hello world !!"); 244 | } 245 | \end{verbatim} 246 | 247 | Diese Methode hat ein Übergabeargument vom Typ \verb+t_helloworld+, 248 | sodass wir also unseren Datenraum manipulieren könnten. 249 | 250 | Da wir nur ``Hello world!'' ausgeben wollen (und ausserdem unser Datenraum 251 | recht spärlich ist), verzichten wir auf eine Manipulation. 252 | 253 | Mit dem Befehl \verb+post(char *c,...)+ wird eine Meldung an die Standardausgabe 254 | geschickt. 255 | Ein Zeilenumbruch wird automatisch angehängt. 256 | Ansonsten funktioniert \verb+post()+ gleich wie der {\tt C}-Befehl \verb+printf()+. 257 | 258 | \subsection{Generierung einer neuen Klasse} 259 | Um eine neue Klasse zu generieren, müssen Angaben über 260 | den Datenraum und den Methodenraum dieser Klasse 261 | beim Laden einer Library an Pd übergeben werden. 262 | 263 | Wird eine neue Library ``my\_lib'' geladen, 264 | so versucht Pd eine Funktion ``my\_lib\_setup()'' aufzurufen. 265 | Diese Funktion (oder von ihr aufgerufene Funktionen) teilt Pd mit, 266 | welche Eigenschaften die neuen Klassen haben. 267 | Sie wird nur einmal, beim Laden der Library aufgerufen. 268 | 269 | \begin{verbatim} 270 | void helloworld_setup(void) 271 | { 272 | helloworld_class = class_new(gensym("helloworld"), 273 | (t_newmethod)helloworld_new, 274 | 0, sizeof(t_helloworld), 275 | CLASS_DEFAULT, 0); 276 | 277 | class_addbang(helloworld_class, helloworld_bang); 278 | } 279 | \end{verbatim} 280 | 281 | \paragraph{class\_new} 282 | 283 | Der Befehl \verb+class_new+ kreiert eine neue Klasse und gibt einen Zeiger auf diesen 284 | Prototyp zurück. 285 | 286 | Das erste Argument ist der symbolische Name der Klasse. 287 | 288 | Die nächsten beiden Argumente definieren Konstruktor und Destruktor der Klasse. 289 | Wenn in einen Pd-Patch ein Objekt kreiert wird, 290 | instanziiert der Konstruktor \verb+(t_newmethod)helloworld_new+ diesses Objekt 291 | und initialisiert den Datenraum. 292 | Wird ein Pd-Patch geschlossen oder ein Objekt daraus entfernt, 293 | so gibt der Destruktor, wenn notwendig, dynamisch reservierten Speicher wieder frei. 294 | Der Speicherplatz für den Datenraum selbst wird von Pd automatisch freigegeben. 295 | Deshalb kann in diesem Beispiel auf einen Destruktor verzichtet werden, 296 | folglich wird dieses Argument auf ``0'' gesetzt. 297 | 298 | Damit Pd genug Speicher für den Datenraum allozieren und wieder freigeben kann, 299 | wird die Größe dieser Datenstruktur als viertes Argument übergeben. 300 | 301 | Das fünfte Argument bestimmt, wie Klasseninstanzen graphisch dargestellt werden und 302 | ob sie mit anderen Objekten verknüpfbar sind. 303 | Der Standardwert \verb+CLASS_DEFAULT+ (oder einfacher: ``0'') bezieht sich auf 304 | ein Objekt mit mindestens einem Inlet. 305 | Würde man keinen Eingang wollen (wie zum Beispiel beim Internal ``receive''), 306 | so kann man diesen Wert auf \verb+CLASS_NOINLET+ setzen. 307 | 308 | Die restlichen Argumente definieren die Übergabeargumente eines Objektes und deren Typ. 309 | 310 | Bis zu sechs numerische und symbolische Objektargumente können in beliebiger Reihenfolge 311 | mit \verb+A_DEFFLOAT+ und \verb+A_DEFSYMBOL+ angegeben werden. 312 | Sollen mehr Argumente übergeben werden oder die Atomtyp-Reihenfolge flexibler sein, 313 | so bietet \verb+A_GIMME+ die Übergabe einer beliebigen Liste von Atomen. 314 | 315 | Die Objektargumentliste wird mit ``0'' terminiert. 316 | In unserem Beispiel sind also keine Übergabeargumente für die Klasse vorgesehen. 317 | 318 | \paragraph{class\_addbang} 319 | Jetzt muss zur Klasse noch ein Methodenraum hinzugefügt werden. 320 | 321 | Mit \verb+class_addbang+ wird der durch das erste Argument definierten Klasse 322 | eine Methode für eine ``bang''-Message hinzuzugefügt. 323 | Diese Methode ist das zweite Argument. 324 | 325 | 326 | 327 | \subsection{Konstruktor: Instanziierung eines Objektes} 328 | Jedesmal, wenn in einem Pd-Patch ein Objekt einer Klasse kreiert wird, 329 | schafft der mit \verb+class_new+ angegebene Konstruktor eine neue Instanz der Klasse. 330 | 331 | Der Konstruktor ist immer vom Typ \verb+void *+ 332 | 333 | \begin{verbatim} 334 | void *helloworld_new(void) 335 | { 336 | t_helloworld *x = (t_helloworld *)pd_new(helloworld_class); 337 | 338 | return (void *)x; 339 | } 340 | \end{verbatim} 341 | 342 | Die Übergabeargumente der Konstruktorfunktion hängen von den mit 343 | \verb+class_new+ angegebenen Objektargumenten ab. 344 | 345 | \begin{tabular}{l|l} 346 | \verb+class_new+-Argument&Konstruktorargument\\ 347 | \hline 348 | \verb+A_DEFFLOAT+&\verb+t_floatarg f+ \\ 349 | \verb+A_DEFSYMBOL+&\verb+t_symbol *s+ \\ 350 | \verb+A_GIMME+&\verb+t_symbol *s, int argc, t_atom *argv+ 351 | \end{tabular} 352 | 353 | Da in diesem Beispiel keine Objektargumente existieren, hat auch 354 | der Konstruktor keine. 355 | 356 | Die Funktion \verb+pd_new+ reserviert Speicher für den Datenraum, initialisiert 357 | die objektinternen Variablen und gibt einen Zeiger auf den Datenraum zurück. 358 | 359 | Der Typ-Cast auf den Datenraum ist notwendig. 360 | 361 | Normalerweise würden im Konstruktor auch die Objektvariablen initialisiert werden. 362 | In diesem Beispiel ist dies aber nicht notwendig. 363 | 364 | Der Konstruktor muss einen Zeiger auf den instanziierten Datenraum zurückgeben. 365 | 366 | \subsection{der Code: \tt helloworld} 367 | 368 | \begin{verbatim} 369 | #include "m_pd.h" 370 | 371 | static t_class *helloworld_class; 372 | 373 | typedef struct _helloworld { 374 | t_object x_obj; 375 | } t_helloworld; 376 | 377 | void helloworld_bang(t_helloworld *x) 378 | { 379 | post("Hello world !!"); 380 | } 381 | 382 | void *helloworld_new(void) 383 | { 384 | t_helloworld *x = (t_helloworld *)pd_new(helloworld_class); 385 | 386 | return (void *)x; 387 | } 388 | 389 | void helloworld_setup(void) { 390 | helloworld_class = class_new(gensym("helloworld"), 391 | (t_newmethod)helloworld_new, 392 | 0, sizeof(t_helloworld), 393 | CLASS_DEFAULT, 0); 394 | class_addbang(helloworld_class, helloworld_bang); 395 | } 396 | \end{verbatim} 397 | 398 | 399 | \section{ein komplexes External: {\tt counter}} 400 | 401 | Als nächstes soll ein einfacher Zähler als External geschrieben werden. 402 | Ein ``bang''-Trigger soll den aktuellen Zählerstand am Outlet ausgeben 403 | und anschließend um 1 erhöhen. 404 | 405 | Diese Klasse unterscheidet sich nicht sonderlich von der vorherigen, 406 | ausser dass nun eine interne Variable ``Zählerstand'' benötigt 407 | wird und das Ergebnis nicht mehr auf die Standardausgabe geschrieben sondern 408 | als Message zu einem Outlet geschickt wird. 409 | 410 | \subsection{Variablen eines Objektes} 411 | Ein Zähler braucht natürlich eine Zustandsvariable, 412 | in der der aktueller Zählerstand gespeichert ist. 413 | 414 | Solche zum Objekt gehörigen Zustandsvariablen werden im Datenraum abgelegt. 415 | 416 | \begin{verbatim} 417 | typedef struct _counter { 418 | t_object x_obj; 419 | t_int i_count; 420 | } t_counter; 421 | \end{verbatim} 422 | 423 | Die Ganzzahlvariable \verb+i_count+ beschreibt den Zählerstand. 424 | Natürlich könnte man sie auch als Gleitkommawert realisieren, 425 | doch traditionell werden Zähler ganzzahlig ausgeführt. 426 | 427 | \subsection{Übergabeargumente} 428 | Für einen Zähler ist es durchaus sinnvoll, wenn man den Startwert festlegen kann. 429 | Hier soll der Startwert dem Objekt bei der Kreation übergeben werden. 430 | 431 | \begin{verbatim} 432 | void counter_setup(void) { 433 | counter_class = class_new(gensym("counter"), 434 | (t_newmethod)counter_new, 435 | 0, sizeof(t_counter), 436 | CLASS_DEFAULT, 437 | A_DEFFLOAT, 0); 438 | 439 | class_addbang(counter_class, counter_bang); 440 | } 441 | \end{verbatim} 442 | 443 | Es ist also ein Argument zur Funktion \verb+class_new+ hinzugekommen: 444 | 445 | \verb+A_DEFFLOAT+ teilt mit, dass das Objekt ein Übergabeargument 446 | vom Typ \verb+t_floatarg+ hat. 447 | 448 | 449 | 450 | \subsection{Konstruktor} 451 | Dem Konstruktor kommen nun mehrere neue Aufgaben zu. 452 | Zum ersten muss eine Variable initialisiert werden, 453 | zum anderen muss auch ein Outlet für das Objekt geschaffen werden. 454 | \begin{verbatim} 455 | void *counter_new(t_floatarg f) 456 | { 457 | t_counter *x = (t_counter *)pd_new(counter_class); 458 | 459 | x->i_count=f; 460 | outlet_new(&x->x_obj, &s_float); 461 | 462 | return (void *)x; 463 | } 464 | \end{verbatim} 465 | 466 | Die Konstruktorfunktion hat jetzt ein Argument fom Typ \verb+t_floatarg+, wie es in 467 | der Setup-Routine \verb+class_new+ deklariert worden ist. 468 | Dieses Argument initialisiert den Zähler. 469 | 470 | Einer neuer Outlet wird mit der Funktion \verb+outlet_new+ geschaffen. 471 | Das erste Argument ist ein Zeiger auf die Objektinterna, 472 | in denen der neue Ausgang geschaffen wird. 473 | 474 | Das zweite Argument ist eine symbolische Typbeschreibung des Ausgangs. 475 | Da der Zähler numerische Werte ausgeben soll, ist er vom Typ ``float''. 476 | Sollte der Ausgang für Messages mit verschiedenen Selectoren verwendet werden, 477 | so ist dieser Wert ``0''. 478 | 479 | \verb+outlet_new+ gibt einen Zeiger auf den neuen Outlet zurück und speichert diesen 480 | Zeiger in der \verb+t_object+-Variablen \verb+x_obj.ob_outlet+. 481 | Wird nur ein Outlet verwendet, muss daher der Zeiger nicht extra im Datenraum gespeichert 482 | werden. 483 | Werden mehrere Outlets verwendet, so müssen diese Zeiger im Datenraum gespeichert werden. 484 | 485 | \subsection{die Zählermethode} 486 | Bei einem Triggerevent soll der alte Zählerstand ausgegeben und um eins inkrementiert werden. 487 | 488 | \begin{verbatim} 489 | void counter_bang(t_counter *x) 490 | { 491 | t_float f=x->i_count; 492 | x->i_count++; 493 | outlet_float(x->x_obj.ob_outlet, f); 494 | } 495 | \end{verbatim} 496 | 497 | Die Funktion \verb+outlet_float+ gibt an dem Outlet, auf den das erste Argument verweist, 498 | eine Gleitkommazahl (zweites Argument) aus. 499 | 500 | Hier wird zuerst der Zählerstand in eine Gleitkomma-Buffervariable gespeichert. 501 | Danach wird er inkrementiert und dann wird erst die Buffervariable ausgegeben. 502 | 503 | Was auf den ersten Blick unnötig erscheint, macht bei näherer Betrachtung Sinn: 504 | Die Buffervariable wurde gleich als \verb+t_float+ realisiert, 505 | da sich \verb+outlet_float+ sowieso einen Gleitkommawert erwartet 506 | und ein Cast unvermeidlich ist. 507 | 508 | Würde der Zählerstand zuerst an den Outlet geschickt werden und 509 | danach erst inkrementiert werden, würde dies unter Umständen zu einem etwas seltsamen 510 | Verhalten führen. 511 | Wenn nämlich der Zählerausgang wieder an den Inlet zurückgeführt würde, der 512 | Zähler sich also selbst triggerte, so würde die Zählermethode erneut 513 | aufgerufen, ohne dass der Zählerstand inkrementiert worden wäre. 514 | Dies ist im Allgemeinen aber unerwünscht. 515 | 516 | Man kann übrigens das gleiche Ergebnis wie hier mit nur einer einzigen Zeile erreichen, 517 | doch sieht man das {\em Reentrant}-Problem dann nicht sehr gut. 518 | 519 | \subsection{der Code: \tt counter} 520 | 521 | \begin{verbatim} 522 | #include "m_pd.h" 523 | 524 | static t_class *counter_class; 525 | 526 | typedef struct _counter { 527 | t_object x_obj; 528 | t_int i_count; 529 | } t_counter; 530 | 531 | void counter_bang(t_counter *x) 532 | { 533 | t_float f=x->i_count; 534 | x->i_count++; 535 | outlet_float(x->x_obj.ob_outlet, f); 536 | } 537 | 538 | void *counter_new(t_floatarg f) 539 | { 540 | t_counter *x = (t_counter *)pd_new(counter_class); 541 | 542 | x->i_count=f; 543 | outlet_new(&x->x_obj, &s_float); 544 | 545 | return (void *)x; 546 | } 547 | 548 | void counter_setup(void) { 549 | counter_class = class_new(gensym("counter"), 550 | (t_newmethod)counter_new, 551 | 0, sizeof(t_counter), 552 | CLASS_DEFAULT, 553 | A_DEFFLOAT, 0); 554 | 555 | class_addbang(counter_class, counter_bang); 556 | } 557 | \end{verbatim} 558 | 559 | 560 | \section{ein komplexeres External: \tt counter} 561 | 562 | Man kann natürlich auch einen einfache Zähler ein bißchen komplexer gestalten. 563 | Es wäre zum Beispiel sinnvoll, 564 | wenn der Zählerstand auf einen Startwert zurückgesetzt werden könnte, 565 | wenn man Start- und Endwert bestimmen könnte und auch die Schrittweite variabel wäre. 566 | 567 | Bei jedem Zählerüberlauf soll ein zweiter Outlet eine ``bang''-Message schicken und der 568 | Zähler auf den Startwert zurückgesetzt werden. 569 | 570 | \subsection{erweiterter Datenraum} 571 | 572 | \begin{verbatim} 573 | typedef struct _counter { 574 | t_object x_obj; 575 | t_int i_count; 576 | t_float step; 577 | t_int i_down, i_up; 578 | t_outlet *f_out, *b_out; 579 | } t_counter; 580 | \end{verbatim} 581 | 582 | Der Datenraum wurde also erweitert um Variablen für Schrittweite und Start- bzw. Stopwert. 583 | Weiters werden Zeiger auf zwei Outlets zur Verfügung gestellt. 584 | 585 | \subsection{Erweiterung der Klasse} 586 | Da nun die Klassenobjekte verschiedene Messages, wie ``set'' und ``reset'', 587 | verstehen können sollen, mussen der Methodenraum entsprechend erweitert werden. 588 | 589 | \begin{verbatim} 590 | counter_class = class_new(gensym("counter"), 591 | (t_newmethod)counter_new, 592 | 0, sizeof(t_counter), 593 | CLASS_DEFAULT, 594 | A_GIMME, 0); 595 | \end{verbatim} 596 | 597 | Der Klassengenerator \verb+class_new+ ist um das Objektübergabeargument 598 | \verb+A_GIMME+ erweitert. 599 | Damit kann eine dynamische Anzahl von Argumenten bei der Objektinstanziierung 600 | verwaltet werden. 601 | 602 | \begin{verbatim} 603 | class_addmethod(counter_class, 604 | (t_method)counter_reset, 605 | gensym("reset"), 0); 606 | \end{verbatim} 607 | 608 | \verb+class_addmethod+ fügt einer Klasse eine Methode mit für einen 609 | beliebigen Selector hinzu. 610 | 611 | Das erste Argument ist die Klasse, 612 | zu der die Methode (zweites Argument) hinzugefügt wird. 613 | 614 | Das dritte Argument ist der symbolische Selector, 615 | der mit der Methode assoziiert wird. 616 | 617 | Die restlichen ``0''-terminierten Argumente 618 | beschreiben die Atomliste, die dem Selector folgt. 619 | 620 | \begin{verbatim} 621 | class_addmethod(counter_class, 622 | (t_method)counter_set, gensym("set"), 623 | A_DEFFLOAT, 0); 624 | class_addmethod(counter_class, 625 | (t_method)counter_bound, gensym("bound"), 626 | A_DEFFLOAT, A_DEFFLOAT, 0); 627 | \end{verbatim} 628 | 629 | Eine Methode für den Selector ``set'', gefolgt von einem numerischen Wert, 630 | wird hinzugefügt. 631 | 632 | Für den Selector ``bound'', gefolgt von zwei numerischen Werten, 633 | wird ebenfalls eine Methode zur Klasse hinzugefügt. 634 | 635 | \begin{verbatim} 636 | class_sethelpsymbol(counter_class, gensym("help-counter")); 637 | \end{verbatim} 638 | 639 | Clickt man mit der rechten Maustaste auf ein Pd-Objekt, 640 | so kann man sich einen Hilfe-Patch für die zugehörige Objektklasse anzeigen lasse. 641 | Standardmäßig wird ist dies ein Patch mit dem symbolischen Klassennamen 642 | im Verzeichnis ``{\em doc/5.reference/}'' gesucht. 643 | Mit dem Befehl \verb+class_sethelpsymbol+ kann ein alternativer Patch angegeben werden. 644 | 645 | \subsection{Konstruktion von In- und Outlets} 646 | 647 | Bei der Objektkreation sollten dem Objekt verschiedene Argumente übergeben 648 | werden. 649 | 650 | \begin{verbatim} 651 | void *counter_new(t_symbol *s, int argc, t_atom *argv) 652 | \end{verbatim} 653 | Durch die Argumentendeklaration in der \verb+class_new+-Funktion 654 | mit \verb+A_GIMME+, werden dem Konstruktor folgende Argumente 655 | übergeben: 656 | 657 | \begin{tabular}{c|l} 658 | \verb+t_symbol *s+ & der symbolische Namen,\\ 659 | & mit dem das Objekt kreiert wurde \\ 660 | \verb+int argc+ & die Anzahl, der dem Objekt übergebenen Argumente\\ 661 | \verb+t_atom *argv+ & ein Zeiger auf eine Liste von {\tt argc} Atomen 662 | \end{tabular} 663 | 664 | \begin{verbatim} 665 | t_float f1=0, f2=0; 666 | 667 | x->step=1; 668 | switch(argc){ 669 | default: 670 | case 3: 671 | x->step=atom_getfloat(argv+2); 672 | case 2: 673 | f2=atom_getfloat(argv+1); 674 | case 1: 675 | f1=atom_getfloat(argv); 676 | break; 677 | case 0: 678 | break; 679 | } 680 | if (argc<2)f2=f1; 681 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 683 | 684 | x->i_count=x->i_down; 685 | \end{verbatim} 686 | 687 | Werden drei Argumente übergeben, so sollten dies {\em untere Zählergrenze}, 688 | {\em obere Zählergrenze} und {\em Schrittgröße} sein. 689 | Werden nur zwei Argumente übergeben, 690 | so wird die Schrittgröße standardmäßig auf ``1'' gesetzt. 691 | Bei nur einem Argument, sei dies der {\em Startwert} des Zählers, 692 | die {\em Schrittgröße} sei ``1''. 693 | 694 | \begin{verbatim} 695 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, 696 | gensym("list"), gensym("bound")); 697 | \end{verbatim} 698 | Die Funktion \verb+inlet_new+ erzeugt einen neuen ``aktiven'' Inlet. 699 | ``Aktiv'' heißt, dass eine Klassenmethode ausgeführt wird, 700 | wenn eine Message in den einen ``aktiven'' Inlet geschickt wird. 701 | 702 | Von der Software-Architektur her ist der erste Inlet immer ``aktiv''. 703 | 704 | Die ersten beiden Argumente der \verb+inlet_new+-Funktion 705 | sind Zeiger auf die Objektinterna und die graphische Darstellung des Objektes. 706 | 707 | Der symbolische Selector, der durch das dritte Argument spezifiziert wird, 708 | wird für diesen Inlet durch einen anderen symbolischen Selector (viertes Argument) 709 | substituiert. 710 | 711 | Durch die Substitution von Selectoren kann eine Message 712 | an einem bestimmten rechten Eingang wie eine Message mit einem bestimmten Selector 713 | am linken Eingang betrachtet werden. 714 | 715 | Dies bedeutet 716 | \begin{itemize} 717 | \item Der substituierende Selector muss mit \verb+class_addmethod+ angegeben werden. 718 | \item Man kann einen bestimmten rechten Eingang simulieren, 719 | indem man dem ersten Eingang eine Message mit dem Selector dieses Eingangs schickt. 720 | \item Es ist nicht möglich, einem rechten Eingang Methoden für mehr als einen Selector 721 | zuzuweisen. Insbesondere ist es nicht möglich, ihm eine allgemeine Methode 722 | für einen beliebigen Selector zuzuweisen. 723 | \end{itemize} 724 | 725 | \begin{verbatim} 726 | floatinlet_new(&x->x_obj, &x->step); 727 | \end{verbatim} 728 | \verb+floatinlet_new+ generiert einen ``passiven'' Inlet für numerische Werte. 729 | ``Passive'' Eingänge erlauben, dass ein Speicherplatz bestimmten Typs im 730 | Variablenraum des Objektes von außen direkt beschrieben werden kann. 731 | Dadurch ist zum Beispiel eine Abfrage nach illegalen Eingaben nicht möglich. 732 | Das erste Argument ist dabei ein Zeiger auf die interne Objektinfrastruktur. 733 | Das zweite Argument ist ein Zeiger auf den Speicherplatz, auf den geschrieben wird. 734 | 735 | Es können ``passive'' Eingänge für numerische (Gleitkomma\footnote{ 736 | Deswegen ist der {\tt step}-Wert des Klassendatenraums als {\tt t\_float} realisiert.}) 737 | -Werte, symbolische Werte und Pointer geschaffen werden. 738 | 739 | \begin{verbatim} 740 | x->f_out = outlet_new(&x->x_obj, &s_float); 741 | x->b_out = outlet_new(&x->x_obj, &s_bang); 742 | \end{verbatim} 743 | 744 | Die von \verb+outlet_new+ zurückgegebenen Zeiger auf die geschaffenen Outlets, 745 | müssen im Klassendatenraum gespeichert werden, 746 | damit sie später von den Ausgaberoutinen angesprochen werden. 747 | 748 | Die Reihenfolge der Generierung von In- und Outlets ist wichtig, 749 | da sie der Reihenfolge der Ein- und Ausgänge der graphischen Repräsentation 750 | des Objektes entsprechen. 751 | 752 | \subsection{erweiterter Methodenraum} 753 | 754 | Der Methode für die ``bang''-Message muss natürlich der komplexeren Zählerstruktur 755 | genüge tun. 756 | 757 | 758 | \begin{verbatim} 759 | void counter_bang(t_counter *x) 760 | { 761 | t_float f=x->i_count; 762 | t_int step = x->step; 763 | x->i_count+=step; 764 | if (x->i_down-x->i_up) { 765 | if ((step>0) && (x->i_count > x->i_up)) { 766 | x->i_count = x->i_down; 767 | outlet_bang(x->b_out); 768 | } else if (x->i_count < x->i_down) { 769 | x->i_count = x->i_up; 770 | outlet_bang(x->b_out); 771 | } 772 | } 773 | outlet_float(x->f_out, f); 774 | } 775 | \end{verbatim} 776 | 777 | Die einzelnen Outlets werden von den \verb+outlet_...+-Funktionen über 778 | die Zeiger auf diese Ausgänge identifiziert. 779 | 780 | Die übrigen Methoden müssen noch implementiert werden: 781 | 782 | \begin{verbatim} 783 | void counter_reset(t_counter *x) 784 | { 785 | x->i_count = x->i_down; 786 | } 787 | 788 | void counter_set(t_counter *x, t_floatarg f) 789 | { 790 | x->i_count = f; 791 | } 792 | 793 | void counter_bound(t_counter *x, t_floatarg f1, t_floatarg f2) 794 | { 795 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 797 | } 798 | \end{verbatim} 799 | 800 | \subsection{der Code: \tt counter} 801 | 802 | \begin{verbatim} 803 | #include "m_pd.h" 804 | 805 | static t_class *counter_class; 806 | 807 | typedef struct _counter { 808 | t_object x_obj; 809 | t_int i_count; 810 | t_float step; 811 | t_int i_down, i_up; 812 | t_outlet *f_out, *b_out; 813 | } t_counter; 814 | 815 | void counter_bang(t_counter *x) 816 | { 817 | t_float f=x->i_count; 818 | t_int step = x->step; 819 | x->i_count+=step; 820 | 821 | if (x->i_down-x->i_up) { 822 | if ((step>0) && (x->i_count > x->i_up)) { 823 | x->i_count = x->i_down; 824 | outlet_bang(x->b_out); 825 | } else if (x->i_count < x->i_down) { 826 | x->i_count = x->i_up; 827 | outlet_bang(x->b_out); 828 | } 829 | } 830 | 831 | outlet_float(x->f_out, f); 832 | } 833 | 834 | void counter_reset(t_counter *x) 835 | { 836 | x->i_count = x->i_down; 837 | } 838 | 839 | void counter_set(t_counter *x, t_floatarg f) 840 | { 841 | x->i_count = f; 842 | } 843 | 844 | void counter_bound(t_counter *x, t_floatarg f1, t_floatarg f2) 845 | { 846 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 848 | } 849 | 850 | void *counter_new(t_symbol *s, int argc, t_atom *argv) 851 | { 852 | t_counter *x = (t_counter *)pd_new(counter_class); 853 | t_float f1=0, f2=0; 854 | 855 | x->step=1; 856 | switch(argc){ 857 | default: 858 | case 3: 859 | x->step=atom_getfloat(argv+2); 860 | case 2: 861 | f2=atom_getfloat(argv+1); 862 | case 1: 863 | f1=atom_getfloat(argv); 864 | break; 865 | case 0: 866 | break; 867 | } 868 | if (argc<2)f2=f1; 869 | 870 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 872 | 873 | x->i_count=x->i_down; 874 | 875 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, 876 | gensym("list"), gensym("bound")); 877 | floatinlet_new(&x->x_obj, &x->step); 878 | 879 | x->f_out = outlet_new(&x->x_obj, &s_float); 880 | x->b_out = outlet_new(&x->x_obj, &s_bang); 881 | 882 | return (void *)x; 883 | } 884 | 885 | void counter_setup(void) { 886 | counter_class = class_new(gensym("counter"), 887 | (t_newmethod)counter_new, 888 | 0, sizeof(t_counter), 889 | CLASS_DEFAULT, 890 | A_GIMME, 0); 891 | 892 | class_addbang (counter_class, counter_bang); 893 | class_addmethod(counter_class, 894 | (t_method)counter_reset, gensym("reset"), 0); 895 | class_addmethod(counter_class, 896 | (t_method)counter_set, gensym("set"), 897 | A_DEFFLOAT, 0); 898 | class_addmethod(counter_class, 899 | (t_method)counter_bound, gensym("bound"), 900 | A_DEFFLOAT, A_DEFFLOAT, 0); 901 | 902 | class_sethelpsymbol(counter_class, gensym("help-counter")); 903 | } 904 | \end{verbatim} 905 | 906 | 907 | \section{ein Signal-External: {\tt pan\~\/}} 908 | Signalklassen sind normale Klassen, die zusätzlich Methoden 909 | für Signale bereitstellen. 910 | 911 | Alle Methoden und Konzepte die mit normalen Objektklassen realisierbar sind, 912 | sind also auch mit Signalklassen zuverwirklichen. 913 | 914 | Per Konvention enden die symbolischen Namen mit einer Tilde \~\/. 915 | 916 | Anhand einer Klasse ``pan\~\/`` soll demonstriert werden wie Signalklassen geschrieben 917 | werden können. 918 | 919 | Ein Signal am linken Inlet wird mit einem Signal am zweiten Inlet gemischt. 920 | Der Mischungsgrad wird als \verb+t_float+-Message an einen dritten Eingang festgelegt. 921 | 922 | \subsection{Variablen einer Signalklasse} 923 | Da eine Signalklasse nur eine erweiterte normale Klasse ist, 924 | gibt es keine prinzipielle Unterschiede zwischen den Datenräumen. 925 | 926 | \begin{verbatim} 927 | typedef struct _pan_tilde { 928 | t_object x_obj; 929 | 930 | t_sample f_pan; 931 | t_float f; 932 | } t_pan_tilde; 933 | \end{verbatim} 934 | 935 | Es wird nur eine Variable für den {\em Mischfaktor} der Panningfunktion benötigt. 936 | 937 | Die Variable \verb+f+ wird gebraucht, falls kein Signal am Signalinlet liegt. 938 | Wird dann an diesen Signalinlet ein numerischer Wert als Message geschickt, 939 | so ersetzt dieser das Signal und wird in der Variable \verb+f+ gespeichert. 940 | 941 | \subsection{Signalklassen} 942 | 943 | \begin{verbatim} 944 | void pan_tilde_setup(void) { 945 | pan_tilde_class = class_new(gensym("pan~"), 946 | (t_newmethod)pan_tilde_new, 947 | 0, sizeof(t_pan_tilde), 948 | CLASS_DEFAULT, 949 | A_DEFFLOAT, 0); 950 | 951 | class_addmethod(pan_tilde_class, 952 | (t_method)pan_tilde_dsp, gensym("dsp"), 0); 953 | CLASS_MAINSIGNALIN(pan_tilde_class, t_pan_tilde, f); 954 | } 955 | \end{verbatim} 956 | 957 | Jeder Signalklasse muss eine Methode für die Signalverarbeitung zugeordnet werden. 958 | Wenn die Audioengine von Pd gestartet wird, wird allen Objekten eine 959 | Message mit dem Selector ``\verb+dsp+'' geschickt. 960 | Alle Klassen, die eine Methode für die ``dsp''-Message haben, sind Signalklassen. 961 | 962 | Signalklassen, die Signal-Inlets zur Verfügung stellen wollen, 963 | müssen dies mit dem \verb+CLASS_MAINSIGNALIN+-Makro anmelden. 964 | Dadurch ist der erste Inlet als Signalinlet deklariert. 965 | \verb+t_float+-Messages können nicht mehr an einen solchen Eingang 966 | gesendet werden. 967 | 968 | Das erste Argument des Makros ist ein Zeiger auf die Signalklasse. 969 | Das zweite Argument ist der Typ des Datenraums der Klasse. 970 | Das dritte Argument ist eine Dummy-Variable aus dem Datenraum, die gebraucht wird, 971 | um bei nicht vorhandenen Signalen am Signalinlet diese durch \verb+t_float+-Messages 972 | einfach ersetzen zu können. 973 | 974 | \subsection{Konstruktion von Signal-In- und Outlets} 975 | 976 | \begin{verbatim} 977 | void *pan_tilde_new(t_floatarg f) 978 | { 979 | t_pan_tilde *x = (t_pan_tilde *)pd_new(pan_tilde_class); 980 | 981 | x->f_pan = f; 982 | 983 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); 984 | floatinlet_new (&x->x_obj, &x->f_pan); 985 | 986 | outlet_new(&x->x_obj, &s_signal); 987 | 988 | return (void *)x; 989 | } 990 | \end{verbatim} 991 | 992 | Zusätzliche Signal-Eingänge werden normal mit der Routine \verb+inlet_new+ 993 | hinzugefügt. 994 | Die letzen beiden Argumente sind dann jeweils ein Verweis auf den symbolischen Selector 995 | ``signal'' in der lookup-Tabelle. 996 | 997 | Signal-Outlets werden ebenfalls wie Message-Outlets generiert, deren Outlet mit dem 998 | Selector ``signal'' versehen ist. 999 | 1000 | 1001 | \subsection{DSP-Methode} 1002 | Wenn die Audio-Engine von Pd eingeschalten wird, 1003 | so teilen ihr alle Signal-Objekte mit, 1004 | welche Methode von ihrer Klasse zur digitalen Signalverarbeitung herangezogen werden soll. 1005 | 1006 | Die ``DSP''-Methode hat als Argumente einen Zeiger auf den Klassendatenraum und 1007 | einen Zeiger auf ein Array von Signalen. 1008 | 1009 | Die Signale im Array sind so angeordnet, dass sie am graphischen Objekt 1010 | im Uhrzeigersinn gelesen werden.\footnote{ 1011 | Sofern linke und rechte Ein- und Ausgangssignale vorhanden sind, gilt also: 1012 | Zuerst kommt das linke Eingangssignal, danach die rechten Eingangssignale; 1013 | nach den rechten Ausgangssignalen kommt das linke Ausgangssignal. 1014 | } 1015 | 1016 | \begin{verbatim} 1017 | void pan_tilde_dsp(t_pan_tilde *x, t_signal **sp) 1018 | { 1019 | dsp_add(pan_tilde_perform, 5, x, 1020 | sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); 1021 | } 1022 | \end{verbatim} 1023 | 1024 | \verb+dsp_add+ fügt eine ``Perform''-Routine (erstes Argument) zum DSP-Baum hinzu. 1025 | Das zweite Argument ist die Anzahl der nachfolgenden Zeiger auf diverse Variablen. 1026 | Welche Zeiger auf welche Variablen übergeben werden, unterliegt keiner Beschränkung. 1027 | 1028 | sp[0] bezeichnet hier das erste Eingangssignal, sp[1] das zweite Eingangssignal, 1029 | sp[3] das Ausgangssignal. 1030 | 1031 | Die Struktur \verb+t_signal+ enthält einen Zeiger auf den 1032 | zugehörigen Signalvektor \verb+.s_vec+ (ein Array von Samples \verb+t_sample+), 1033 | sowie die Länge dieses Signalvektors \verb+.s_n+. 1034 | Da innerhalb eines Patches alle Signalvektoren die gleiche Länge haben, 1035 | genügt es, die Länge eines dieser Vektoren abzufragen. 1036 | 1037 | \subsection{perform-Routine} 1038 | Die perform-Routine ist das eigentliche DSP-Herzstück einer Signalklasse. 1039 | 1040 | Ihr wird ein Zeiger auf ein Integer-Array übergeben. 1041 | In diesem Array sind die Zeiger gespeichert, die mit \verb+dsp_add+ übergeben wurden. 1042 | Sie müssen auf ihren ursprünglichen Typ zurückgecastet werden. 1043 | 1044 | Die perform-Routine muß einen Zeiger auf Integer zurückgeben, der hinter den 1045 | Speicherplatz zeigt, in dem die eigenen Zeiger gespeichert sind. 1046 | Dies bedeutet, dass das Rückgabeargument gleich dem Übergabeargument plus der 1047 | Anzahl der eigenen Zeigervariablen (wie sie als zweites Argument in 1048 | \verb+dsp_add+ angegeben wurde) plus eins. 1049 | 1050 | \begin{verbatim} 1051 | t_int *pan_tilde_perform(t_int *w) 1052 | { 1053 | t_pan_tilde *x = (t_pan_tilde *)(w[1]); 1054 | t_sample *in1 = (t_sample *)(w[2]); 1055 | t_sample *in2 = (t_sample *)(w[3]); 1056 | t_sample *out = (t_sample *)(w[4]); 1057 | int n = (int)(w[5]); 1058 | 1059 | t_sample f_pan = (x->f_pan<0)?0.0:(x->f_pan>1)?1.0:x->f_pan; 1060 | 1061 | while (n--) *out++ = (*in1++)*(1-f_pan)+(*in2++)*f_pan; 1062 | 1063 | return (w+6); 1064 | } 1065 | \end{verbatim} 1066 | 1067 | In der \verb+while+-Schleife wird jedes Sample der Signalvektoren einzeln 1068 | abgearbeitet. 1069 | 1070 | Eine Optimierungsroutine bei der Erstellung des DSP-Baumes wird darauf geachtet, 1071 | keine unnötigen Kopieroperationen durchzuführen. 1072 | Es kann daher geschehen, dass ein Eingangs- und ein Ausgangssignal an der 1073 | gleichen Stelle im Speicher stehen. 1074 | Es ist daher in solchem Falle darauf zu achten, 1075 | dass nicht in das Ausgangssignal geschrieben wird, 1076 | bevor dort das Eingangssignal ausgelesen wurde. 1077 | 1078 | \subsection{der Code: \tt pan\~\/} 1079 | 1080 | \begin{verbatim} 1081 | #include "m_pd.h" 1082 | 1083 | static t_class *pan_tilde_class; 1084 | 1085 | typedef struct _pan_tilde { 1086 | t_object x_obj; 1087 | t_sample f_pan; 1088 | t_sample f; 1089 | } t_pan_tilde; 1090 | 1091 | t_int *pan_tilde_perform(t_int *w) 1092 | { 1093 | t_pan_tilde *x = (t_pan_tilde *)(w[1]); 1094 | t_sample *in1 = (t_sample *)(w[2]); 1095 | t_sample *in2 = (t_sample *)(w[3]); 1096 | t_sample *out = (t_sample *)(w[4]); 1097 | int n = (int)(w[5]); 1098 | t_sample f_pan = (x->f_pan<0)?0.0:(x->f_pan>1)?1.0:x->f_pan; 1099 | 1100 | while (n--) *out++ = (*in1++)*(1-f_pan)+(*in2++)*f_pan; 1101 | 1102 | return (w+6); 1103 | } 1104 | 1105 | void pan_tilde_dsp(t_pan_tilde *x, t_signal **sp) 1106 | { 1107 | dsp_add(pan_tilde_perform, 5, x, 1108 | sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); 1109 | } 1110 | 1111 | void *pan_tilde_new(t_floatarg f) 1112 | { 1113 | t_pan_tilde *x = (t_pan_tilde *)pd_new(pan_tilde_class); 1114 | 1115 | x->f_pan = f; 1116 | 1117 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); 1118 | floatinlet_new (&x->x_obj, &x->f_pan); 1119 | outlet_new(&x->x_obj, &s_signal); 1120 | 1121 | return (void *)x; 1122 | } 1123 | 1124 | void pan_tilde_setup(void) { 1125 | pan_tilde_class = class_new(gensym("pan~"), 1126 | (t_newmethod)pan_tilde_new, 1127 | 0, sizeof(t_pan_tilde), 1128 | CLASS_DEFAULT, 1129 | A_DEFFLOAT, 0); 1130 | 1131 | class_addmethod(pan_tilde_class, 1132 | (t_method)pan_tilde_dsp, gensym("dsp"), 0); 1133 | CLASS_MAINSIGNALIN(pan_tilde_class, t_pan_tilde, f); 1134 | } 1135 | \end{verbatim} 1136 | 1137 | 1138 | 1139 | 1140 | \vfill 1141 | \newpage 1142 | \begin{appendix} 1143 | 1144 | \section{das Message-System von \em pd} 1145 | Nicht-Audio-Daten werden über ein Message-System verteilt. 1146 | Jede Message besteht aus einem ``Selector'' und einer Liste von Atomen. 1147 | 1148 | \subsection{Atome} 1149 | 1150 | Es gibt drei Arten von Atomen: 1151 | \begin{itemize} 1152 | \item {\em A\_FLOAT}: ein numerischer Wert (Gleitkommazahl) 1153 | \item {\em A\_SYMBOL}: ein symbolischer Wert (String) 1154 | \item {\em A\_POINTER}: ein Zeiger 1155 | \end{itemize} 1156 | 1157 | Numerische Werte werden immer als Floating-Point-Werte (\verb+double+) dargestellt, 1158 | auch wenn es sich um Ganzzahlwerte handelt. 1159 | 1160 | Jedes Symbol wird aus Performancegründen in einer lookup-Tabelle abgelegt. 1161 | Der Befehl \verb+gensym+ speichert, wenn nötig, 1162 | einen String in dieser Symboltabelle und gibt seine Addresse in der Tabelle zurück. 1163 | 1164 | Atome vom Typ {\em A\_POINTER} haben in der Praxis 1165 | (für einfache Externals) eher untergeordnete Bedeutung. 1166 | 1167 | Der Typ eines Atoms \verb+a+ wird im Strukturelement \verb+a.a_type+ gespeichert. 1168 | 1169 | \subsection{Selectoren} 1170 | 1171 | Der Selector ist ein Symbol und bestimmt, welchen Typ eine Message hat. 1172 | Es gibt fünf vordefinierte Selectoren: 1173 | \begin{itemize} 1174 | \item ``{\tt bang}'' bezeichnet ein Triggerevent. 1175 | Die Message besteht nur aus dem Selector und enthält keine Liste von Atomen. 1176 | \item ``{\tt float}'' bezeichnet einen numerischen Wert. Die Liste enthält nur ein Atom. 1177 | \item ``{\tt symbol}'' bezeichnet einen symbolischen Wert. Die Liste enthält nur ein Atom. 1178 | \item ``{\tt pointer}'' bezeichnet einen Zeiger. Die Liste enthält nur ein Atom. 1179 | \item ``{\tt list}'' bezeichnet eine Liste von mehreren Atomen. 1180 | \end{itemize} 1181 | 1182 | Da die Symbole für diese Selectoren relativ häufig verwendet werden, 1183 | kann man deren Symboltabellen-Adresse auch direkt, 1184 | ohne den Umweg über \verb+gensym+ abfragen: 1185 | 1186 | \begin{tabular}{l||l|l} 1187 | Selector&lookup-Routine&lookup-Addresse\\ 1188 | \hline 1189 | \tt bang &\verb+gensym("bang")+ & \verb+&s_bang+ \\ 1190 | \tt float &\verb+gensym("float")+ & \verb+&s_float+ \\ 1191 | \tt symbol &\verb+gensym("symbol")+ & \verb+&s_symbol+ \\ 1192 | \tt pointer &\verb+gensym("pointer")+ & \verb+&s_pointer+ \\ 1193 | \tt list &\verb+gensym("list")+ & \verb+&s_list+ \\ 1194 | --- (Signal) &\verb+gensym("signal")+&\verb+&s_symbol+ 1195 | \end{tabular} 1196 | 1197 | Es können auch andere Selectoren verwendet werden, 1198 | doch muss dann die Empfängerklasse entweder selbst eine Methode 1199 | für diesen Selector zur verfügung stellen, 1200 | oder eine Methode für ``anything'', also jeden beliebigen Selector, anbieten. 1201 | 1202 | Messages die ohne Selector sofort mit einem Zahlenwert beginnen, werden automatisch 1203 | entweder als numerischer Wert (nur ein Atom) oder als Liste (mehrere Atome) erkannt. 1204 | 1205 | Zum Beispiel sind also die Messages ``\verb+12.429+'' und ``\verb+float 12.429+'' ident. 1206 | Ebenfalls ident sind auch die Listen-Messages 1207 | ``\verb+list 1 kleines Haus+'' und ``\verb+1 kleines Haus+''. 1208 | 1209 | \section{Pd-Typen} 1210 | Da Pd auf mehreren Plattformen benutzt wird, 1211 | werden viele gewöhnliche Variablentypen, wie \verb|int|, neu definiert. 1212 | Um portablen Code zu schreiben ist es daher angebracht, die von Pd bereitgestellten 1213 | Typen zu verwenden. 1214 | 1215 | Weiters gibt es viele vordefinierte Typen, 1216 | die das Leben des Programmierers vereinfachen sollten. 1217 | Pd-Typen beginnen im Allgemeinen mit \verb|t_|. 1218 | 1219 | \begin{tabular}{c|l} 1220 | Pd-Type & Beschreibung \\ 1221 | \hline\hline 1222 | \verb+t_atom+& Atom \\ 1223 | \verb+t_float+ & Gleitkomma-Zahl \\ 1224 | \verb+t_symbol+ & Symbol \\ 1225 | \verb+t_gpointer+ & Zeiger (auf graphische Objekte) \\ 1226 | \hline 1227 | \verb+t_int+ & Ganzzahl \\ 1228 | \verb+t_signal+ & Struktur auf ein Signal \\ 1229 | \verb+t_sample+ & Audio-Signalwert (Gleitkomma)\\ 1230 | \verb+t_outlet+ & Outlet eines Objekts \\ 1231 | \verb+t_inlet+ & Inlet eines Objekts \\ 1232 | \verb+t_object+ & Objekt-Interna \\ 1233 | \hline 1234 | \verb+t_class+ & eine Pd-Klasse \\ 1235 | \verb+t_method+ & Zeiger auf Klassenmethode \\ 1236 | \verb+t_newmethod+ & Zeiger auf Klasseninstanziierungsmethode (new-Routine) \\ 1237 | \end{tabular} 1238 | 1239 | 1240 | \section{Wichtige Funktionen aus ``m\_pd.h''} 1241 | \subsection{Funktionen: Atome} 1242 | 1243 | \subsubsection{SETFLOAT} 1244 | \begin{verbatim} 1245 | SETFLOAT(atom, f) 1246 | \end{verbatim} 1247 | Dieses Makro setzt den Typ von \verb+atom+ auf \verb+A_FLOAT+ 1248 | und setzt den numerischen Wert dieses Atoms auf \verb+f+. 1249 | 1250 | \subsubsection{SETSYMBOL} 1251 | \begin{verbatim} 1252 | SETSYMBOL(atom, s) 1253 | \end{verbatim} 1254 | Dieses Makro setzt den Typ von \verb+atom+ auf \verb+A_SYMBOL+ 1255 | und setzt den symbolischen Wert dieses Atoms auf \verb+s+. 1256 | 1257 | \subsubsection{SETPOINTER} 1258 | \begin{verbatim} 1259 | SETPOINTER(atom, pt) 1260 | \end{verbatim} 1261 | Dieses Makro setzt den Typ von \verb+atom+ auf \verb+A_POINTER+ 1262 | und setzt den Zeiger-Wert dieses Atoms auf \verb+pt+. 1263 | 1264 | \subsubsection{atom\_getfloat} 1265 | \begin{verbatim} 1266 | t_float atom_getfloat(t_atom *a); 1267 | \end{verbatim} 1268 | Wenn der Typ des Atoms \verb+a+ \verb+A_FLOAT+ ist, wird dessen numerischer Wert, 1269 | ansonsten ``0.0'' zurückgegeben. 1270 | 1271 | \subsubsection{atom\_getfloatarg} 1272 | \begin{verbatim} 1273 | t_float atom_getfloatarg(int which, int argc, t_atom *argv) 1274 | \end{verbatim} 1275 | Wenn das Atom, 1276 | das in der Atomliste \verb+argv+ mit der Länge \verb+argc+ an der Stelle \verb+which+ 1277 | zu finden ist, 1278 | vom Typ \verb+A_FLOAT+ ist, wird dessen numerischer Wert, 1279 | ansonsten ``0.0'' zurückgegeben. 1280 | 1281 | \subsubsection{atom\_getint} 1282 | \begin{verbatim} 1283 | t_int atom_getint(t_atom *a); 1284 | \end{verbatim} 1285 | Wenn der Typ des Atoms \verb+a+ \verb+A_FLOAT+ ist, wird dessen numerischer 1286 | Wert als Ganzzahlwert, ansonsten ``0'' zurückgegeben. 1287 | 1288 | \subsubsection{atom\_getsymbol} 1289 | \begin{verbatim} 1290 | t_symbol atom_getsymbol(t_atom *a); 1291 | \end{verbatim} 1292 | Wenn der Typ des Atoms \verb+a+ \verb+A_SYMBOL+ ist, wird ein Zeiger 1293 | auf dessen Symbol ansonsten auf das Symbol ``float'' zurückgegeben. 1294 | 1295 | \subsubsection{atom\_gensym} 1296 | \begin{verbatim} 1297 | t_symbol *atom_gensym(t_atom *a); 1298 | \end{verbatim} 1299 | Wenn der Typ des Atoms \verb+a+ \verb+A_SYMBOL+ ist, wird ein Zeiger 1300 | auf dessen Symbol zurückgegeben. 1301 | 1302 | Atome anderen Typs werden zuerst ``sinnvoll'' in Strings umgewandelt. 1303 | Diese Strings werden, falls nötig, in die Symbol-Tabelle eingetragen. 1304 | Die Zeiger auf das Symbol wird zurückgegeben. 1305 | 1306 | 1307 | \subsubsection{atom\_string} 1308 | \begin{verbatim} 1309 | void atom_string(t_atom *a, char *buf, unsigned int bufsize); 1310 | \end{verbatim} 1311 | Konvertiert ein Atom \verb+a+ in einen {\tt C}-String \verb+buf+. 1312 | Der char-Buffer muss selbst reserviert und seine Länge in \verb+bufsize+ angegeben werden. 1313 | 1314 | \subsubsection{gensym} 1315 | \begin{verbatim} 1316 | t_symbol *gensym(char *s); 1317 | \end{verbatim} 1318 | Prüft, ob für den C-String \verb+*s+ bereits ein Eintrag in der Symbol-lookup-Tabelle 1319 | vorhanden ist. 1320 | Ist noch kein Eintrag vorhanden, so wird einer angelegt. 1321 | Ein Zeiger auf das Symbol in der Tabelle wird zurückgegeben. 1322 | 1323 | 1324 | \subsection{Funktionen: Klassen} 1325 | \subsubsection{class\_new} 1326 | \begin{verbatim} 1327 | t_class *class_new(t_symbol *name, 1328 | t_newmethod newmethod, t_method freemethod, 1329 | size_t size, int flags, 1330 | t_atomtype arg1, ...); 1331 | \end{verbatim} 1332 | Generiert eine neue Klasse mit dem symbolischen Namen \verb+name+. 1333 | 1334 | \verb+newmethod+ ist eine Konstruktorfunktion, 1335 | die eine Instanz der Klasse konstruiert und einen Zeiger auf diese Instanz zurückgibt. 1336 | 1337 | Wird manuell dynamischer Speicher reserviert, 1338 | so muss dieser bei Zerstörung eines Objektes 1339 | mit der Destruktormethode \verb+freemethod+ (kein Rückgabeargument) 1340 | wieder freigegeben werden. 1341 | 1342 | \verb+size+ ist statische die Größe des Klassendatenraumes, 1343 | die mit der Funktion \verb+sizeof(t_mydata)+ berechnet werden kann. 1344 | 1345 | \verb+flags+ bestimmen das Aussehen des graphischen Objektes. 1346 | Eine beliebige Kombination folgender Flags ist möglich: 1347 | 1348 | \begin{tabular}{l|l} 1349 | Flag&Bedeutung\\ 1350 | \hline 1351 | \verb+CLASS_DEFAULT+ &Ein normales Objekt mit einem Inlet \\ 1352 | \verb+CLASS_PD+ & \em Objekte ohne Graphikdarstellung\\ 1353 | \verb+CLASS_GOBJ+ & \em reine Graphikobjekte (wie Arrays, Graphen,...)\\ 1354 | \verb+CLASS_PATCHABLE+ & \em normales Objekt (mit einem Inlet) \\ 1355 | \verb+CLASS_NOINLET+ & Der standardmäßige Inlet wird unterdrückt \\ 1356 | \end{tabular} 1357 | 1358 | Flags, deren Bedeutung {\em kursiv} gedruckt ist, 1359 | haben geringe Bedeutung beim Schreiben von Externals. 1360 | 1361 | Die restlichen Argumente \verb+arg1,...+ definieren 1362 | die Typen die Übergabeargumente bei der Objektkreation. 1363 | Höchstens sechs typgeprüfte Argumente können einem Objekt übergeben werden. 1364 | Die Argumententypeliste wird ``0'' terminiert. 1365 | 1366 | Mögliche Argumententypen sind: 1367 | 1368 | \begin{tabular}{l|l} 1369 | \verb+A_DEFFLOAT+ & ein numerischer Wert \\ 1370 | \verb+A_DEFSYMBOL+ & ein symbolischer Wert \\ 1371 | \verb+A_GIMME+ & eine Atomliste beliebiger Länge und Typen \\ 1372 | \end{tabular} 1373 | 1374 | Sollten mehr als sechs Argumente übergeben werden, muss man 1375 | \verb+A_GIMME+ verwenden und eine händische Typprüfung durchführen. 1376 | 1377 | \subsubsection{class\_addmethod} 1378 | \begin{verbatim} 1379 | void class_addmethod(t_class *c, t_method fn, t_symbol *sel, 1380 | t_atomtype arg1, ...); 1381 | \end{verbatim} 1382 | Fügt der Klasse, auf die \verb+c+ zeigt, die Methode \verb+fn+ für 1383 | eine Message mit dem Selector \verb+sel+ hinzu. 1384 | 1385 | Die restlichen Argumente \verb+arg1,...+ definieren 1386 | die Typen der Atomliste die dem Selector folgt. 1387 | Höchstens sechs typgeprüfte Argumente angegeben werden. 1388 | Sollten mehr als sechs Argumente übergeben werden, muss man 1389 | \verb+A_GIMME+ verwenden und eine händische Typprüfung durchführen. 1390 | 1391 | Die Argumententypeliste wird ``0'' terminiert. 1392 | 1393 | Mögliche Argumententypen sind: 1394 | 1395 | \begin{tabular}{l|l} 1396 | \verb+A_DEFFLOAT+ & ein numerischer Wert \\ 1397 | \verb+A_DEFSYMBOL+ & ein symbolischer Wert \\ 1398 | \verb+A_POINTER+ & eine Zeiger \\ 1399 | \verb+A_GIMME+ & eine Atomliste beliebiger Länge und Typen \\ 1400 | \end{tabular} 1401 | 1402 | \subsubsection{class\_addbang} 1403 | \begin{verbatim} 1404 | void class_addbang(t_class *c, t_method fn); 1405 | \end{verbatim} 1406 | Fügt der Klasse, auf die \verb+c+ zeigt, die Methode \verb+fn+ 1407 | für eine ``bang''-Message hinzu. 1408 | Die ``bang''-Methode hat als Übergabeargument einen Zeiger auf den Klassendatenraum: 1409 | 1410 | \verb+void my_bang_method(t_mydata *x);+ 1411 | 1412 | \subsubsection{class\_addfloat} 1413 | \begin{verbatim} 1414 | void class_addfloat(t_class *c, t_method fn); 1415 | \end{verbatim} 1416 | Fügt der Klasse, auf die \verb+c+ zeigt, die Methode \verb+fn+ 1417 | für eine ``float''-Message hinzu. 1418 | Die ``float''-Methode hat als Übergabeargument einen Zeiger auf den Klassendatenraum und 1419 | ein Gleitkommaargument: 1420 | 1421 | \verb+void my_float_method(t_mydata *x, t_floatarg f);+ 1422 | 1423 | \subsubsection{class\_addsymbol} 1424 | \begin{verbatim} 1425 | void class_addsymbol(t_class *c, t_method fn); 1426 | \end{verbatim} 1427 | Fügt der Klasse, auf die \verb+c+ zeigt, die Methode \verb+fn+ 1428 | für eine ``symbol''-Message hinzu. 1429 | Die ``symbol''-Methode hat als Übergabeargument einen Zeiger auf den Klassendatenraum und 1430 | einen Zeiger auf das übergebene Symbol: 1431 | 1432 | \verb+void my_symbol_method(t_mydata *x, t_symbol *s);+ 1433 | 1434 | \subsubsection{class\_addpointer} 1435 | \begin{verbatim} 1436 | void class_addpointer(t_class *c, t_method fn); 1437 | \end{verbatim} 1438 | Fügt der Klasse, auf die \verb+c+ zeigt, die Methode \verb+fn+ 1439 | für eine ``pointer''-Message hinzu. 1440 | Die ``pointer''-Methode hat als Übergabeargument einen Zeiger 1441 | auf den Klassendatenraum und einen Zeiger auf einen Pointer: 1442 | 1443 | \verb+void my_pointer_method(t_mydata *x, t_gpointer *pt);+ 1444 | 1445 | \subsubsection{class\_addlist} 1446 | \begin{verbatim} 1447 | void class_addlist(t_class *c, t_method fn); 1448 | \end{verbatim} 1449 | Fügt der Klasse, auf die \verb+c+ zeigt, die Methode \verb+fn+ 1450 | für eine ``list''-Message hinzu. 1451 | Die ``list''-Methode hat als Übergabeargument neben einem Zeiger 1452 | auf den Klassendatenraum einen Zeiger auf das Selectorsymbol 1453 | (immer \verb+&s_list+), 1454 | die Anzahl der Atome in der Liste sowie einen Zeiger auf die Atomliste: 1455 | 1456 | \verb+void my_list_method(t_mydata *x,+ 1457 | 1458 | \verb+ t_symbol *s, int argc, t_atom *argv);+ 1459 | 1460 | 1461 | %\begin{verbatim} 1462 | %void my_list_method(t_mydata *x, 1463 | % t_symbol *s, int argc, t_atom *argv); 1464 | %\end{verbatim} 1465 | 1466 | 1467 | 1468 | \subsubsection{class\_addanything} 1469 | \begin{verbatim} 1470 | void class_addanything(t_class *c, t_method fn); 1471 | \end{verbatim} 1472 | Fügt der Klasse, auf die \verb+c+ zeigt, die Methode \verb+fn+ 1473 | für eine beliebige Message hinzu. 1474 | Die anything-Methode hat als Übergabeargument neben einem Zeiger 1475 | auf den Klassendatenraum einen Zeiger auf das Selectorsymbol, 1476 | die Anzahl der Atome in der Liste sowie einen Zeiger auf die Atomliste: 1477 | 1478 | 1479 | \verb+void my_any_method(t_mydata *x,+ 1480 | 1481 | \verb+ t_symbol *s, int argc, t_atom *argv);+ 1482 | 1483 | 1484 | %\begin{verbatim} 1485 | %void my_any_method(t_mydata *x, 1486 | % t_symbol *s, int argc, t_atom *argv); 1487 | %\end{verbatim} 1488 | 1489 | \subsubsection{class\_addcreator} 1490 | \begin{verbatim} 1491 | void class_addcreator(t_newmethod newmethod, t_symbol *s, 1492 | t_atomtype type1, ...); 1493 | \end{verbatim} 1494 | Fügt zu einem Konstruktor \verb+newmethod+ ein zum Klassennamen alternatives 1495 | Kreatorsymbol \verb+s+ hinzu. 1496 | Dadurch können Objekte mit dem richtigen Klassennamen und einem Aliasnamen 1497 | (zum Beispiel eine Abkürzung, wie das Internal ``float'' bzw. ``f'') kreiert werden. 1498 | 1499 | Die ``0''-terminierte Typenliste entspricht der von \verb+class_new+. 1500 | 1501 | \subsubsection{class\_sethelpsymbol} 1502 | \begin{verbatim} 1503 | void class_sethelpsymbol(t_class *c, t_symbol *s); 1504 | \end{verbatim} 1505 | 1506 | Clickt man mit der rechten Maustaste auf ein Pd-Objekt, 1507 | so kann man sich einen Hilfe-Patch für die zugehörige Objektklasse anzeigen lasse. 1508 | Standardmäßig wird ist dies ein Patch mit dem symbolischen Klassennamen 1509 | im Verzeichnis ``{\em doc/5.reference/}'' gesucht. 1510 | 1511 | Für die Klasse, auf die \verb+c+ zeigt, wird der Name des Hilfepatches auf den 1512 | symbolischen Wert \verb+s+ geändert. 1513 | 1514 | Dadurch können sich mehrere verwandte Klassen einen Hilfepatch teilen. 1515 | 1516 | Pfadangaben erfolgen relativ zum Standardhilfepfad {\em doc/5.reference/}. 1517 | 1518 | \subsubsection{pd\_new} 1519 | \begin{verbatim} 1520 | t_pd *pd_new(t_class *cls); 1521 | \end{verbatim} 1522 | Generiert eine neue Instanz der Klasse \verb+cls+ und gibt einen Zeiger auf diese 1523 | Instanz zurück. 1524 | 1525 | \subsection{Funktionen: In- und Outlets} 1526 | Alle Inlet- und Outletroutinen benötigen eine Referenz auf die Objektinterna 1527 | der Klasseninstanz. 1528 | Die notwendige Variable vom Typ \verb+t_object+ im Datenraum wird bei der 1529 | Objektinstanziierung initialisiert. 1530 | Diese Variable muß als \verb+owner+-Objekt den Inlet- und Outletroutinen übergeben werden. 1531 | 1532 | \subsubsection{inlet\_new} 1533 | \begin{verbatim} 1534 | t_inlet *inlet_new(t_object *owner, t_pd *dest, 1535 | t_symbol *s1, t_symbol *s2); 1536 | \end{verbatim} 1537 | Generiert einen zusätzlichen ``aktiven'' Inlet des Objektes, auf das \verb+owner+ zeigt. 1538 | \verb+dest+ zeigt im Allgemeinen auf ``\verb+owner.ob_pd+''. 1539 | 1540 | Der Selector \verb+s1+ am neuen Inlet, wird durch den Selector \verb+s2+ substituiert. 1541 | 1542 | Tritt also eine Message mit dem Selector \verb+s1+ am neuen Inlet auf, 1543 | wird die Klassenmethode für den Selector \verb+s2+ ausgeführt. 1544 | 1545 | Dies bedeutet 1546 | \begin{itemize} 1547 | \item Der substituierende Selector muss mit \verb+class_addmethod+ angegeben werden. 1548 | \item Man kann einen bestimmten rechten Eingang simulieren, 1549 | indem man dem ersten Eingang eine Message mit dem Selector dieses Eingangs schickt. 1550 | 1551 | Verwendet man ein leeres Symbol (\verb+gensym("")+) als Selector, 1552 | so erreicht man, dass der rechte Eingang nicht über den ersten angesprochen werden kann. 1553 | \item Es ist nicht möglich, einem rechten Eingang Methoden für mehr als einen Selector 1554 | zuzuweisen. Insbesondere ist es nicht möglich, ihm eine allgemeine Methode 1555 | für einen beliebigen Selector zuzuweisen. 1556 | \end{itemize} 1557 | 1558 | \subsubsection{floatinlet\_new} 1559 | \begin{verbatim} 1560 | t_inlet *floatinlet_new(t_object *owner, t_float *fp); 1561 | \end{verbatim} 1562 | Schafft einen neuen ``passiven'' Eingang für das Objekt, auf das \verb+owner+ zeigt, 1563 | der es erlaubt, einen numerischen Wert von außen direkt auf einen 1564 | Speicherplatz \verb+fp+ zu schreiben, ohne eine eigene Methode aufzurufen. 1565 | 1566 | \subsubsection{symbolinlet\_new} 1567 | \begin{verbatim} 1568 | t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp); 1569 | \end{verbatim} 1570 | Schafft einen neuen ``passiven'' Eingang für das Objekt, auf das \verb+owner+ zeigt, 1571 | der es erlaubt, einen symbolischen Wert von außen direkt auf einen 1572 | Speicherplatz \verb+sp+ zu schreiben, ohne eine eigene Methode aufzurufen. 1573 | 1574 | \subsubsection{pointerinlet\_new} 1575 | \begin{verbatim} 1576 | t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp); 1577 | \end{verbatim} 1578 | Schafft einen neuen ``passiven'' Eingang für das Objekt, auf das \verb+owner+ zeigt, 1579 | der es erlaubt, einen Zeigerwert von außen direkt auf einen 1580 | Speicherplatz \verb+gp+ zu schreiben, ohne eine eigene Methode aufzurufen. 1581 | 1582 | \subsubsection{outlet\_new} 1583 | \begin{verbatim} 1584 | t_outlet *outlet_new(t_object *owner, t_symbol *s); 1585 | \end{verbatim} 1586 | Generiert einen neuen Ausgang für das Objekt, auf das \verb+owner+ zeigt. 1587 | Das Symbol, auf das \verb+s+ zeigt, zeigt den Typ des Ausgangs an. 1588 | 1589 | \begin{tabular}{c|l||l} 1590 | Symbolwert & Symboladresse & Outlet-Typus \\ 1591 | \hline\hline 1592 | ``bang'' & \verb+&s_bang+ & Message (Bang)\\ 1593 | ``float'' & \verb+&s_float+ & Message (Float)\\ 1594 | ``symbol'' & \verb+&s_symbol+ & Message (Symbol) \\ 1595 | ``pointer'' & \verb+&s_gpointer+ & Message (List)\\ 1596 | ``list'' & \verb+&s_list+ & Message \\ 1597 | --- & 0 & Message \\ 1598 | \hline 1599 | ``signal'' & \verb+&s_signal+ & Signal \\ 1600 | \end{tabular} 1601 | 1602 | Zwischen den verschiedenen Message-Outlet-Typen gibt es keinen Unterschied. 1603 | Allerdings macht es den Code leichter lesbar, 1604 | wenn schon bei der Outlet-Generierung angezeigt wird, wozu der Ausgang verwendet wird. 1605 | Für allgemeine Message-Outlets verwendet man einen ``0''-Pointer. 1606 | 1607 | Variablen vom Typ \verb+t_object+ stellen einen Zeiger auf einen Outlet zur Verfügung. 1608 | Bei der Generierung eines neuen Outlets, 1609 | wird seine Addresse in der Objektvariablen \verb+(*owner).ob_outlet+ gespeichert. 1610 | 1611 | Werden mehrere Message-Ausgänge benötigt, müssen die Outletzeiger, 1612 | die von \verb+outlet_new+ zurückgegeben werden, manuell im Datenraum gespeichert werden, 1613 | um die jeweiligen Ausgänge ansprechen zu können. 1614 | 1615 | \subsubsection{outlet\_bang} 1616 | \begin{verbatim} 1617 | void outlet_bang(t_outlet *x); 1618 | \end{verbatim} 1619 | Gibt am Outlet, auf den \verb+x+ zeigt, eine ``bang''-Message aus. 1620 | 1621 | \subsubsection{outlet\_float} 1622 | \begin{verbatim} 1623 | void outlet_float(t_outlet *x, t_float f); 1624 | \end{verbatim} 1625 | Gibt am Outlet, auf den \verb+x+ zeigt, eine ``float''-Message mit dem 1626 | numerischen Wert \verb+f+ aus. 1627 | 1628 | \subsubsection{outlet\_symbol} 1629 | \begin{verbatim} 1630 | void outlet_symbol(t_outlet *x, t_symbol *s); 1631 | \end{verbatim} 1632 | Gibt am Outlet, auf den \verb+x+ zeigt, eine ``symbol''-Message mit dem 1633 | symbolischen Wert von \verb+s+ aus. 1634 | 1635 | \subsubsection{outlet\_pointer} 1636 | \begin{verbatim} 1637 | void outlet_pointer(t_outlet *x, t_gpointer *gp); 1638 | \end{verbatim} 1639 | Gibt am Outlet, auf den \verb+x+ zeigt, eine ``pointer''-Message mit dem 1640 | Zeiger \verb+gp+ aus. 1641 | 1642 | \subsubsection{outlet\_list} 1643 | \begin{verbatim} 1644 | void outlet_list(t_outlet *x, 1645 | t_symbol *s, int argc, t_atom *argv); 1646 | \end{verbatim} 1647 | Gibt am Outlet, auf den \verb+x+ zeigt, eine ``list''-Message mit 1648 | \verb+argc+ Atomen aus. 1649 | \verb+argv+ zeigt auf das erste Atom der Liste. 1650 | 1651 | Unabhängig davon, auf welches Symbol \verb+s+ zeigt, wird der Selector 1652 | ``list'' der Liste vorangestellt. 1653 | 1654 | Aus Lesbarkeitsgründen sollte man aber trotzdem einen Zeiger auf das 1655 | Symbol ``list'' (\verb+gensym("list")+ oder \verb+&s_list+) angeben. 1656 | 1657 | \subsubsection{outlet\_anything} 1658 | \begin{verbatim} 1659 | void outlet_anything(t_outlet *x, 1660 | t_symbol *s, int argc, t_atom *argv); 1661 | \end{verbatim} 1662 | Gibt am Outlet, auf den \verb+x+ zeigt, eine Message mit 1663 | dem Selector, auf den \verb+s+ zeigt, aus. 1664 | Dem Selector folgen \verb+argc+ Atome. 1665 | \verb+argv+ zeigt auf das erste Atom dieser Liste. 1666 | 1667 | 1668 | \subsection{Funktionen: DSP} 1669 | Soll eine Klasse Methoden zur digitalen Signalsverarbeitung zur Verfügung stellen, 1670 | so muss ihr eine Methode für den Selector ``dsp'' hinzugefügt werden. 1671 | 1672 | Wird die Audio-Engine gestartet, so werden alle Objekte, die eine ``dsp''-Methode 1673 | zur Verfügung stellen, als Instanzen von Signalklassen identifiziert. 1674 | 1675 | \paragraph{DSP-Methode} 1676 | 1677 | \begin{verbatim} 1678 | void my_dsp_method(t_mydata *x, t_signal **sp) 1679 | \end{verbatim} 1680 | 1681 | In der ``dsp''-Methode wird mit der Funktion \verb+dsp_add+ die 1682 | Klassenroutine für Signalverarbeitung in den DSP-Baum eingebunden. 1683 | 1684 | Neben dem eigenen Datenraum \verb+x+, wird auch ein Array von Signalen übergeben. 1685 | Die Signale im Array sind so angeordnet, dass sie am graphischen Objekt 1686 | im Uhrzeigersinn gelesen werden. 1687 | 1688 | Sofern je zwei Ein- und Ausgangssignale vorhanden sind, gilt also: 1689 | 1690 | \begin{tabular}{c|r} 1691 | Zeiger & auf Signal \\ 1692 | \hline\hline 1693 | sp[0] & linkes Eingangssignal \\ 1694 | sp[1] & rechtes Eingangssignal \\ 1695 | sp[2] & rechtes Ausgangssignal \\ 1696 | sp[3] & linkes Ausgangssignal \\ 1697 | \end{tabular} 1698 | 1699 | Die Signalstruktur enthält unter anderem: 1700 | 1701 | \begin{tabular}{c|l} 1702 | Strukturelement & Bedeutung \\ 1703 | \hline 1704 | \verb+s_n+ & Länge des Signalvektors \\ 1705 | \verb+s_vec+ & Zeiger auf den Signalvektor \\ 1706 | \end{tabular} 1707 | 1708 | Der Signalvektor ist ein Array auf Samples vom Typ \verb+t_sample+. 1709 | 1710 | \paragraph{Perform-Routine} 1711 | \begin{verbatim} 1712 | t_int *my_perform_routine(t_int *w) 1713 | \end{verbatim} 1714 | 1715 | Der Perform-Routine die mit \verb+class_add+ in den DSP-Baum eingefügt wurde, 1716 | wird ein Zeiger \verb+w+ auf ein (Integer-)Array übergeben. 1717 | In diesem Array sind die Zeiger gespeichert, die mit \verb+dsp_add+ übergeben wurden. 1718 | Sie müssen auf ihren ursprünglichen Typ zurückgecastet werden. 1719 | Der erste Zeiger ist an der Stelle \verb+w[1]+ gespeichert !!! 1720 | 1721 | Die perform-Routine muß einen Zeiger auf Integer zurückgeben, der hinter den 1722 | Speicherplatz zeigt, in dem die eigenen Zeiger gespeichert sind. 1723 | Dies bedeutet, dass das Rückgabeargument gleich dem Übergabeargument plus der 1724 | Anzahl der eigenen Zeigervariablen (wie sie als zweites Argument in 1725 | \verb+dsp_add+ angegeben wurde) plus eins. 1726 | 1727 | 1728 | 1729 | 1730 | \subsubsection{CLASS\_MAINSIGNALIN} 1731 | \begin{verbatim} 1732 | CLASS_MAINSIGNALIN(, , ); 1733 | \end{verbatim} 1734 | Das Makro \verb+CLASS_MAINSIGNALIN+ meldet an, dass die Klasse 1735 | Signal-Inlets brauchts. 1736 | 1737 | Das erste Argument des Makros ist ein Zeiger auf die Signalklasse. 1738 | Das zweite Argument ist der Typ des Datenraums der Klasse. 1739 | Das dritte Argument ist eine (Dummy-)Gleitkomma-Variable aus dem Datenraum, 1740 | die gebraucht wird, um bei nicht vorhandenen Signalen am Signalinlet, 1741 | ``float''-Messages wie Signale behandeln zu können. 1742 | 1743 | An so kreierten Signaleingängen können daher keine zusätzlichen ``float''-Messages 1744 | geschickt werden. 1745 | 1746 | \subsubsection{dsp\_add} 1747 | \begin{verbatim} 1748 | void dsp_add(t_perfroutine f, int n, ...); 1749 | \end{verbatim} 1750 | Fügt dem DSP-Baum eine Perform-Routine \verb+f+ hinzu, 1751 | die jeden DSP-Zyklus neu aufgerufen wird. 1752 | 1753 | Das zweite Argument \verb+n+ legt die Anzahl der nachfolgenden Zeigerargumente fest. 1754 | 1755 | Welche Zeiger auf welche Variablen übergeben werden, unterliegt keiner Beschränkung. 1756 | Sinnvoll sind im Allgemeinen Zeiger auf den Datenraum und auf die Signalvektoren. 1757 | Auch die Länge der Signalvektoren sollte übergeben werden, 1758 | um effektiv Signale manipulieren zu können. 1759 | 1760 | \subsubsection{sys\_getsr} 1761 | \begin{verbatim} 1762 | float sys_getsr(void); 1763 | \end{verbatim} 1764 | Gibt die Abtastrate des Systems zurück. 1765 | 1766 | \subsection{Funktion: Memory} 1767 | \subsubsection{getbytes} 1768 | \begin{verbatim} 1769 | void *getbytes(size_t nbytes); 1770 | \end{verbatim} 1771 | Reserviert \verb+nbytes+ Bytes und gibt einen Zeiger auf den reservierten Speicher zurück. 1772 | 1773 | \subsubsection{copybytes} 1774 | \begin{verbatim} 1775 | void *copybytes(void *src, size_t nbytes); 1776 | \end{verbatim} 1777 | Kopiert \verb+nbytes+ Bytes von \verb+*src+ in einen neu alloziierten Speicher. 1778 | Die Addresse dieses Speichers wird zurückgegeben. 1779 | 1780 | \subsubsection{freebytes} 1781 | \begin{verbatim} 1782 | void freebytes(void *x, size_t nbytes); 1783 | \end{verbatim} 1784 | Gibt \verb+nbytes+ Bytes an der Addresse \verb+*x+ frei. 1785 | 1786 | \subsection{Funktionen: Ausgabe} 1787 | \subsubsection{post} 1788 | \begin{verbatim} 1789 | void post(char *fmt, ...); 1790 | \end{verbatim} 1791 | 1792 | Schreibt einen {\tt C}-String auf den Standarderror (Shell). 1793 | 1794 | \subsubsection{error} 1795 | \begin{verbatim} 1796 | void error(char *fmt, ...); 1797 | \end{verbatim} 1798 | 1799 | Schreibt einen {\tt C}-String als Fehlermeldung auf den Standarderror (Shell). 1800 | Das Objekt, das die Fehlermeldung ausgegeben hat, wird markiert und 1801 | ist über das Pd-Menü {\em Find->Find last error} identifizierbar. 1802 | 1803 | \end{appendix} 1804 | 1805 | \end{document} 1806 | 1807 | -------------------------------------------------------------------------------- /legacy/Makefile: -------------------------------------------------------------------------------- 1 | HOWTO=pd-externals-HOWTO 2 | 3 | HOWTO_EXAMPLES=example1 example2 example3 example4 4 | 5 | HTMLDIR=HOWTO 6 | 7 | LATEX=latex 8 | DVIPS=dvips 9 | PDFLATEX=pdflatex 10 | HTLATEX=htlatex 11 | HTLATEX_OPTIONS2=html,2,next,fn-in 12 | HTLATEX_OPTIONS3= 13 | ## htlatex HOWTO-externals-en "html,2,next" "" -dHOWTO/ 14 | 15 | default: pdf 16 | 17 | TARGETS: default \ 18 | ps pdf html \ 19 | clean cleaner distclean \ 20 | examples $(HOWTO_EXAMPLES) 21 | 22 | .PHONY: $(TARGETS) 23 | 24 | ps: $(HOWTO).ps 25 | pdf: $(HOWTO).pdf 26 | 27 | html: $(HOWTO).tex $(HOWTO).pdf 28 | mkdir -p $(HTMLDIR) 29 | $(HTLATEX) $< "$(HTLATEX_OPTIONS2)" "$(HTLATEX_OPTIONS3)" "-d$(HTMLDIR)/" 30 | cp $(HOWTO).pdf "$(HTMLDIR)/" 31 | 32 | clean: 33 | -rm -f *.aux *.log *.toc *.out *.dvi 34 | -rm -f *.idv *.lg *.tmp *.xref *.4ct *.4tc 35 | -rm -f *.css *.html 36 | -rm -f *~ 37 | 38 | cleaner: clean 39 | -rm -f *.ps *.pdf 40 | -rm -rf $(HTMLDIR_EN) $(HTMLDIR_DE) 41 | 42 | distclean: cleaner 43 | @for d in ${HOWTO_EXAMPLES}; do ${MAKE} -C $$d clean; done 44 | 45 | %.dvi: $.tex 46 | $(LATEX) $< 47 | $(LATEX) $< 48 | 49 | %.ps: %.dvi 50 | $(DVIPS) $< 51 | 52 | %.pdf: %.tex 53 | $(PDFLATEX) $< 54 | $(PDFLATEX) $< 55 | 56 | examples: $(HOWTO_EXAMPLES) 57 | echo made examples 58 | 59 | $(HOWTO_EXAMPLES): 60 | $(MAKE) -C $@ 61 | -------------------------------------------------------------------------------- /legacy/pd-externals-HOWTO.tex: -------------------------------------------------------------------------------- 1 | % format latexg -*- latex -*- 2 | 3 | \documentclass[12pt, a4paper,english,titlepage]{article} 4 | 5 | %% HOWTO write an external for Pd 6 | %% Copyright (c) 2001-2014 by IOhannes m zmölnig 7 | %% 8 | %% Permission is granted to copy, distribute and/or modify this document 9 | %% under the terms of the GNU Free Documentation License, Version 1.2 10 | %% or any later version published by the Free Software Foundation; 11 | %% with no Invariant Sections, no Front-Cover Texts, and no Back-Cover 12 | %% Texts. A copy of the license is included in the LICENSE.txt file. 13 | 14 | \usepackage[utf8]{inputenc} 15 | 16 | \usepackage[T1]{fontenc} 17 | \usepackage[english]{babel} 18 | 19 | % add hypertext support (fine for latex2html) 20 | \usepackage{html} 21 | \usepackage{hyperref} 22 | 23 | % add landscape support (for rotating text through 90deg) 24 | \usepackage{lscape} 25 | 26 | \makeatletter 27 | \@ifpackageloaded{tex4ht} 28 | {\let\iftexforht\@firstoftwo} 29 | {\let\iftexforht\@secondoftwo} 30 | \makeatother 31 | 32 | \iftexforht{\newcommand\pdtilde{\textasciitilde}}{\newcommand\pdtilde{$\sim$}} 33 | 34 | \title{ 35 | HOWTO \\ 36 | write an External \\ 37 | for {\em Pure Data} 38 | } 39 | 40 | \author{ 41 | IOhannes m zmölnig \\ 42 | \\ 43 | \href{http://iem.at/}{institute of electronic music and acoustics} 44 | } 45 | 46 | %\date{} 47 | 48 | \begin{document} 49 | \maketitle 50 | 51 | \begin{abstract} 52 | Pd is a graphical real-time computer-music system that follows the tradition of 53 | IRCAMs {\em ISPW-max}. 54 | 55 | Although plenty of functions are built into Pd, 56 | it is sometimes a pain or simply impossible to create a patch with a certain 57 | functionality out of the given primitives and combinations of these. 58 | 59 | Therefore, Pd can be extended with self made primitives (``objects'') 60 | that are written in complex programming-languages, like {\tt C/C++}. 61 | 62 | This document aims to explain how to write such primitives in {\tt C}, 63 | the popular language that was used to realize Pd. 64 | 65 | \iftexforht{You can download this HOWTO as \href{pd-externals-HOWTO.pdf}{pdf (English)}.}{} 66 | 67 | \end{abstract} 68 | 69 | 70 | \vfill 71 | \newpage 72 | 73 | \tableofcontents 74 | 75 | \vfill 76 | \newpage 77 | 78 | \section{definitions and prerequisites} 79 | Pd refers to the graphical real-time computer-music environment {\em Pure Data} 80 | by Miller~S.~Puckette. 81 | 82 | To fully understand this document, it is necessary to 83 | be acquainted with Pd and to 84 | have a general understanding of programming techniques especially in {\tt C}. 85 | 86 | To write externals yourself, a {\tt C}-compiler that supports the 87 | {\tt ANSI-C}-Standard, like the {\em Gnu C-compiler} (gcc) on linux-systems or 88 | {\em Visual-C++} on windos-plattforms, will be necessary. 89 | 90 | \subsection{classes, instances, objects} 91 | Pd is written in the programming-language {\tt C}. 92 | Due to its graphical nature, Pd is a {\em object-oriented} system. 93 | Unfortunately {\tt C} does not support very well the use of classes. 94 | Thus the resulting source-code is not as elegant as {\tt C++}-code would be, for instance. 95 | 96 | In this document, the expression {\em class} refers to the realisation of a concept 97 | combining data and manipulators on this data. 98 | 99 | Concrete {\em instances of a class} are called {\em objects}. 100 | 101 | \subsection{internals, externals und libraries} 102 | 103 | To avoid confusion of ideas, the expressions {\em internal}, {\em external} and 104 | {\em library} should be explained here. 105 | 106 | \paragraph{Internal} 107 | An {\em internal} is a class that is built into Pd. 108 | Plenty of primitives, such as ``+'', ``pack'' or ``sig\pdtilde'' are {\em internals}. 109 | 110 | \paragraph{External} 111 | An {\em external} is a class that is not built into Pd but is loaded at runtime. 112 | Once loaded into Pd's memory, {\em externals} cannot be distinguished from 113 | {\em internals} any more. 114 | 115 | \paragraph{Library} 116 | A {\em library} is a collection of {\em externals} that are compiled into a 117 | single binary-file. 118 | 119 | {\em Library}-files have to follow a system dependent naming convention: 120 | 121 | \begin{tabular}{c||c|c|c} 122 | library & linux&irix&Win32 \\ 123 | \hline 124 | {\tt my\_lib}&{\tt my\_lib.pd\_linux}&{\tt my\_lib.pd\_irix}& 125 | {\tt my\_lib.dll}\\ 126 | \end{tabular} 127 | 128 | The simplest form of a {\em library} includes exactly one {\em external} 129 | bearing the same name as the {\em library}. 130 | 131 | Unlike {\em externals}, {\em libraries} can be imported by Pd with special operations. 132 | After a {\em library} has been imported, 133 | all included {\em externals} have been loaded into memory and are available as objects. 134 | 135 | Pd supports two modes to import {\em libraries}: 136 | 137 | \begin{itemize} 138 | \item via the command line-option ``{\tt -lib my\_lib}'' 139 | \item by creating an object ``{\tt my\_lib}'' 140 | \end{itemize} 141 | 142 | The first method loads a {\em library} when Pd is started. 143 | This method is preferably used for {\em libraries} that contain several {\em externals}. 144 | 145 | The other method should be used for {\em libraries} that contain exactly 146 | one {\em external} bearing the same name. 147 | Pd checks first, whether a class named ``my\_lib'' is already loaded. 148 | If this is not the case\footnote{ 149 | If a class ``my\_lib'' is already existent, an object ``my\_lib'' will be instantiated 150 | and the procedure is done. 151 | Thus, no {\em library} has been loaded. 152 | Therefore no {\em library} that is named like an already used class-name like, say, ``abs'', 153 | can be loaded.}, all paths are searched for a file called 154 | ``{\tt my\_lib.pd\_linux}''\footnote{or another system-dependent filename-extensions (s.a.)}. 155 | If such file is found, all included {\em externals} are loaded into memory by calling a 156 | routine \verb+my_lib_setup()+. 157 | After loading, a class ``my\_lib'' is (again) looked for as a (newly loaded) {\em external}. 158 | If so, an instance of this class is created, else the instantiation fails and an error is 159 | printed. 160 | Anyhow, all {\em external}-classes declared in the {\em library} are loaded by now. 161 | 162 | 163 | \section{my first external: {\tt helloworld}} 164 | Usually the first attempt learning a programming-language is a ``hello world''-application. 165 | 166 | In our case, an object class should be created, that prints the line ``hello world!!'' to 167 | the standard error every time it is triggered with a ``bang''-message. 168 | 169 | 170 | 171 | \subsection{the interface to Pd} 172 | To write a Pd-external a well-defined interface is needed. 173 | This is provided in the header-file ``m\_pd.h''. 174 | 175 | \begin{verbatim} 176 | #include "m_pd.h" 177 | \end{verbatim} 178 | 179 | \subsection{a class and its data space} 180 | First a new class has to be prepared and the data space for this class has to be defined. 181 | 182 | \begin{verbatim} 183 | static t_class *helloworld_class; 184 | 185 | typedef struct _helloworld { 186 | t_object x_obj; 187 | } t_helloworld; 188 | \end{verbatim} 189 | 190 | \verb+hello_worldclass+ is going to be a pointer to the new class. 191 | 192 | The structure \verb+t_helloworld+ (of the type \verb+_helloworld+) is 193 | the data space of the class. 194 | 195 | An absolutely necessary element of the data space is a variable of the type 196 | \verb+t_object+, which is used to store internal object-properties like 197 | the graphical presentation of the object or data about inlets and outlets. 198 | 199 | \verb+t_object+ has to be the first entry in the structure ! 200 | 201 | Because a simple ``hello world''-application needs no variables, 202 | the structure is empty apart from the \verb+t_object+. 203 | 204 | 205 | \subsection{method space} 206 | Apart from the data space, a class needs a set of manipulators (methods) to 207 | manipulate the data with. 208 | 209 | If a message is sent to an instance of our class, a method is called. 210 | These methods are the interfaces to the message system of Pd. 211 | On principal they have no return argument and are therefore of the 212 | type \verb+void+. 213 | 214 | \begin{verbatim} 215 | void helloworld_bang(t_helloworld *x) 216 | { 217 | post("Hello world !!"); 218 | } 219 | \end{verbatim} 220 | 221 | 222 | This method has an argument of the type \verb+t_helloworld+, 223 | which would enable us to manipulate the data space. 224 | 225 | Since we only want to output ``Hello world!'' 226 | (and, by the way, our data space is quite sparse), 227 | we renounce a manipulation. 228 | 229 | The command \verb+post(char *c,...)+ sends a string to the standard error. 230 | A carriage return is added automatically. 231 | Apart from this, the \verb+post+-command works like the {\tt C}-command \verb+printf()+. 232 | 233 | \subsection{generation of a new class} 234 | To generate a new class, information of the data space and the method space of this class, 235 | have to be passed to Pd when a library is loaded. 236 | 237 | On loading a new library ``my\_lib'', 238 | Pd tries to call a function ``my\_lib\_setup()''. 239 | This function (or functions called by it) 240 | declares the new classes and their properties. 241 | It is only called once, when the library is loaded. 242 | If the function-call fails (e.g., because no function of the specified name is present) 243 | no external of the library will be loaded. 244 | 245 | \begin{verbatim} 246 | void helloworld_setup(void) 247 | { 248 | helloworld_class = class_new(gensym("helloworld"), 249 | (t_newmethod)helloworld_new, 250 | 0, sizeof(t_helloworld), 251 | CLASS_DEFAULT, 0); 252 | 253 | class_addbang(helloworld_class, helloworld_bang); 254 | } 255 | \end{verbatim} 256 | 257 | \paragraph{class\_new} 258 | 259 | The function \verb+class_new+ creates a new class and returns a pointer to this prototype. 260 | 261 | The first argument is the symbolic name of the class. 262 | 263 | The next two arguments define the constructor and destructor of the class. 264 | 265 | Whenever a class object is created in a Pd-patch, 266 | the class-constructor \verb+(t_newmethod)helloworld_new+ instantiates the object 267 | and initialises the data space. 268 | 269 | Whenever an object is destroyed 270 | (either by closing the containing patch or by deleting the object from the patch) 271 | the destructor frees the dynamically reserved memory. 272 | The allocated memory for the static data space is automatically reserved and freed. 273 | 274 | Therefore we do not have to provide a destructor in this example, the argument 275 | is set to ``0''. 276 | 277 | To enable Pd to reserve and free enough memory for the static data space, 278 | the size of the data structure has to be passed as the fourth argument. 279 | 280 | The fifth argument has influence on the graphical representation of the class objects. 281 | The default-value is \verb+CLASS_DEFAULT+ or simply ``0''. 282 | 283 | The remaining arguments define the arguments of an object and its type. 284 | 285 | Up to six numeric and symbolic object-arguments can be defined via 286 | \verb+A_DEFFLOAT+ and \verb+A_DEFSYMBOL+. 287 | If more arguments are to be passed to the object 288 | or if the order of atom types should by more flexible, 289 | \verb+A_GIMME+ can be used for passing an arbitrary list of atoms. 290 | 291 | The list of object-arguments is terminated by ``0''. 292 | In this example we have no object-arguments at all for the class. 293 | 294 | \paragraph{class\_addbang} 295 | We still have to add a method space to the class. 296 | 297 | \verb+class_addbang+ adds a method for a ``bang''-message to the class that is 298 | defined in the first argument. 299 | The added method is defined in the second argument. 300 | 301 | 302 | \subsection{constructor: instantiation of an object} 303 | Each time, an object is created in a Pd-patch, the 304 | constructor that is defined with the \verb+class_new+-command, 305 | generates a new instance of the class. 306 | 307 | The constructor has to be of type \verb+void *+. 308 | 309 | \begin{verbatim} 310 | void *helloworld_new(void) 311 | { 312 | t_helloworld *x = (t_helloworld *)pd_new(helloworld_class); 313 | 314 | return (void *)x; 315 | } 316 | \end{verbatim} 317 | 318 | 319 | The arguments of the constructor-method depend on the object-arguments 320 | defined with \verb+class_new+. 321 | 322 | \begin{tabular}{l|l} 323 | \verb+class_new+-argument&constructor-argument\\ 324 | \hline 325 | \verb+A_DEFFLOAT+&\verb+t_floatarg f+ \\ 326 | \verb+A_DEFSYMBOL+&\verb+t_symbol *s+ \\ 327 | \verb+A_GIMME+&\verb+t_symbol *s, int argc, t_atom *argv+ 328 | \end{tabular} 329 | 330 | Because there are no object-arguments for our ``hello world''-class, 331 | the constructor has anon too. 332 | 333 | The function \verb+pd_new+ reserves memory for the data space, 334 | initialises the variables that are internal to the object and 335 | returns a pointer to the data space. 336 | 337 | The type-cast to the data space is necessary. 338 | 339 | Normally, the constructor would initialise the object-variables. 340 | However, since we have none, this is not necessary. 341 | 342 | 343 | The constructor has to return a pointer to the instantiated data space. 344 | 345 | \subsection{the code: \tt helloworld} 346 | 347 | \begin{verbatim} 348 | #include "m_pd.h" 349 | 350 | static t_class *helloworld_class; 351 | 352 | typedef struct _helloworld { 353 | t_object x_obj; 354 | } t_helloworld; 355 | 356 | void helloworld_bang(t_helloworld *x) 357 | { 358 | post("Hello world !!"); 359 | } 360 | 361 | void *helloworld_new(void) 362 | { 363 | t_helloworld *x = (t_helloworld *)pd_new(helloworld_class); 364 | 365 | return (void *)x; 366 | } 367 | 368 | void helloworld_setup(void) { 369 | helloworld_class = class_new(gensym("helloworld"), 370 | (t_newmethod)helloworld_new, 371 | 0, sizeof(t_helloworld), 372 | CLASS_DEFAULT, 0); 373 | class_addbang(helloworld_class, helloworld_bang); 374 | } 375 | \end{verbatim} 376 | 377 | 378 | \section{a simple external: {\tt counter}} 379 | 380 | Now we want to realize a simple counter as an external. 381 | A ``bang''-trigger outputs the counter-value on the outlet and 382 | afterwards increases the counter-value by 1. 383 | 384 | This class is similar to the previous one, 385 | but the data space is extended by a variable ``counter'' and the 386 | result is written as a message to an outlet instead of 387 | a string to the standard error. 388 | 389 | \subsection{object-variables} 390 | Of course, a counter needs a state-variable to store the actual counter-value. 391 | 392 | State-variables that belong to class instances belong to the data space. 393 | 394 | \begin{verbatim} 395 | typedef struct _counter { 396 | t_object x_obj; 397 | int i_count; 398 | } t_counter; 399 | \end{verbatim} 400 | 401 | The integer variable \verb+i_count+ stores the counter-value. 402 | 403 | \subsection{object-arguments} 404 | It is quite useful for a counter, if a initial value can be defined by the user. 405 | Therefore this initial value should be passed to the object at creation-time. 406 | 407 | \begin{verbatim} 408 | void counter_setup(void) { 409 | counter_class = class_new(gensym("counter"), 410 | (t_newmethod)counter_new, 411 | 0, sizeof(t_counter), 412 | CLASS_DEFAULT, 413 | A_DEFFLOAT, 0); 414 | 415 | class_addbang(counter_class, counter_bang); 416 | } 417 | \end{verbatim} 418 | 419 | So we have an additional argument in the function \verb+class_new+: 420 | \verb+A_DEFFLOAT+ tells Pd, that the object needs one argument of the 421 | type \verb+t_floatarg+. 422 | If no argument is passed, this will default to ``0''. 423 | 424 | \subsection{constructor} 425 | The constructor has some new tasks. 426 | On the one hand, a variable value has to be initialised, 427 | on the other hand, an outlet for the object has to be created. 428 | 429 | \begin{verbatim} 430 | void *counter_new(t_floatarg f) 431 | { 432 | t_counter *x = (t_counter *)pd_new(counter_class); 433 | 434 | x->i_count=f; 435 | outlet_new(&x->x_obj, &s_float); 436 | 437 | return (void *)x; 438 | } 439 | \end{verbatim} 440 | 441 | The constructor-method has one argument of type \verb+t_floatarg+ as declared 442 | in the setup-routine by \verb+class_new+. 443 | This argument is used to initialise the counter. 444 | 445 | A new outlet is created with the function \verb+outlet_new+. 446 | The first argument is a pointer to the interna of the object 447 | the new outlet is created for. 448 | 449 | The second argument is a symbolic description of the outlet-type. 450 | Since out counter should output numeric values it is of type ``float''. 451 | 452 | \verb+outlet_new+ returns a pointer to the new outlet and saves this very pointer 453 | in the \verb+t_object+-variable \verb+x_obj.ob_outlet+. 454 | If only one outlet is used, the pointer need not additionally be stored in the data space. 455 | If more than one outlets are used, the pointers have to be stored in the data space, 456 | because the \verb+t_object+-variable can only hold one outlet pointer. 457 | 458 | \subsection{the counter method} 459 | When triggered, the counter value should be sent to the outlet 460 | and afterwards be incremented by 1. 461 | 462 | \begin{verbatim} 463 | void counter_bang(t_counter *x) 464 | { 465 | t_float f=x->i_count; 466 | x->i_count++; 467 | outlet_float(x->x_obj.ob_outlet, f); 468 | } 469 | \end{verbatim} 470 | 471 | The function \verb+outlet_float+ sends a floating-point-value (second argument) to the outlet 472 | that is specified by the first argument. 473 | 474 | We first store the counter in a floating point-buffer. 475 | Afterwards the counter is incremented and not before that the buffer variable is sent 476 | to the outlet. 477 | 478 | What appears to be unnecessary on the first glance, makes sense after further 479 | inspection: 480 | The buffer variable has been realized as \verb+t_float+, 481 | since \verb+outlet_float+ expects a floating point-value and a typecast is 482 | inevitable. 483 | 484 | If the counter value was sent to the outlet before being incremented, 485 | this could result in an unwanted (though well defined) behaviour: 486 | If the counter-outlet directly triggered its own inlet, 487 | the counter-method would be called although the counter value was not yet incremented. 488 | Normally this is not what we want. 489 | 490 | The same (correct) result could of course be obtained with a single line, 491 | but this would obscure the {\em reentrant}-problem. 492 | 493 | \subsection{the code: \tt counter} 494 | 495 | \begin{verbatim} 496 | #include "m_pd.h" 497 | 498 | static t_class *counter_class; 499 | 500 | typedef struct _counter { 501 | t_object x_obj; 502 | int i_count; 503 | } t_counter; 504 | 505 | void counter_bang(t_counter *x) 506 | { 507 | t_float f=x->i_count; 508 | x->i_count++; 509 | outlet_float(x->x_obj.ob_outlet, f); 510 | } 511 | 512 | void *counter_new(t_floatarg f) 513 | { 514 | t_counter *x = (t_counter *)pd_new(counter_class); 515 | 516 | x->i_count=f; 517 | outlet_new(&x->x_obj, &s_float); 518 | 519 | return (void *)x; 520 | } 521 | 522 | void counter_setup(void) { 523 | counter_class = class_new(gensym("counter"), 524 | (t_newmethod)counter_new, 525 | 0, sizeof(t_counter), 526 | CLASS_DEFAULT, 527 | A_DEFFLOAT, 0); 528 | 529 | class_addbang(counter_class, counter_bang); 530 | } 531 | \end{verbatim} 532 | 533 | 534 | \section{a complex external: \tt counter} 535 | 536 | The simple counter of the previous chapter can easily be extended to more complexity. 537 | It might be quite useful to be able to reset the counter to an initial value, 538 | to set upper and lower boundaries and to control the step-width. 539 | Each overrun should send a ``bang''-Message to a second outlet and reset the counter to 540 | the initial value. 541 | 542 | \subsection{extended data space} 543 | 544 | \begin{verbatim} 545 | typedef struct _counter { 546 | t_object x_obj; 547 | int i_count; 548 | t_float step; 549 | int i_down, i_up; 550 | t_outlet *f_out, *b_out; 551 | } t_counter; 552 | \end{verbatim} 553 | 554 | The data space has been extended to hold variables for step width and 555 | upper and lower boundaries. 556 | Furthermore pointers for two outlets have been added. 557 | 558 | \subsection{extension of the class} 559 | The new class objects should have methods for different messages, 560 | like ``set'' and ``reset''. 561 | Therefore the method space has to be extended too. 562 | 563 | \begin{verbatim} 564 | counter_class = class_new(gensym("counter"), 565 | (t_newmethod)counter_new, 566 | 0, sizeof(t_counter), 567 | CLASS_DEFAULT, 568 | A_GIMME, 0); 569 | \end{verbatim} 570 | 571 | The class generator \verb+class_new+ has been extended by the argument \verb+A_GIMME+. 572 | This enables a dynamic number of arguments to be passed at the instantiation of the object. 573 | 574 | \begin{verbatim} 575 | class_addmethod(counter_class, 576 | (t_method)counter_reset, 577 | gensym("reset"), 0); 578 | \end{verbatim} 579 | 580 | \verb+class_addmethod+ adds a method for an arbitrary selector to an class. 581 | 582 | The first argument is the class the method (second argument) will be added to. 583 | 584 | The third argument is the symbolic selector that should be associated with the method. 585 | 586 | The remaining ``0''-terminated arguments describe the list of atoms that 587 | follows the selector. 588 | 589 | \begin{verbatim} 590 | class_addmethod(counter_class, 591 | (t_method)counter_set, gensym("set"), 592 | A_DEFFLOAT, 0); 593 | class_addmethod(counter_class, 594 | (t_method)counter_bound, gensym("bound"), 595 | A_DEFFLOAT, A_DEFFLOAT, 0); 596 | \end{verbatim} 597 | 598 | A method for ``set'' followed by a numerical value is added, 599 | as well as a method for the selector ``bound'' followed by two numerical values. 600 | 601 | \begin{verbatim} 602 | class_sethelpsymbol(counter_class, gensym("help-counter")); 603 | \end{verbatim} 604 | 605 | If a Pd-object is right-clicked, a help-patch describing the object-class can be opened. 606 | By default, this patch is located in the directory ``{\em doc/5.reference/}'' and 607 | is named like the symbolic class name. 608 | 609 | An alternative help-patch can be defined with the 610 | \verb+class_sethelpsymbol+-command. 611 | 612 | \subsection{construction of in- and outlets} 613 | 614 | When creating the object, several arguments should be passed by the user. 615 | 616 | \begin{verbatim} 617 | void *counter_new(t_symbol *s, int argc, t_atom *argv) 618 | \end{verbatim} 619 | Because of the declaration of arguments in the \verb+class_new+-function 620 | with \verb+A_GIMME+, 621 | the constructor has following arguments: 622 | 623 | \begin{tabular}{c|l} 624 | \verb+t_symbol *s+ & the symbolic name,\\ 625 | & that was used for object creation \\ 626 | \verb+int argc+ & the number of arguments passed to the object\\ 627 | \verb+t_atom *argv+ & a pointer to a list of {\tt argc} atoms 628 | \end{tabular} 629 | 630 | \begin{verbatim} 631 | t_float f1=0, f2=0; 632 | 633 | x->step=1; 634 | switch(argc){ 635 | default: 636 | case 3: 637 | x->step=atom_getfloat(argv+2); 638 | case 2: 639 | f2=atom_getfloat(argv+1); 640 | case 1: 641 | f1=atom_getfloat(argv); 642 | break; 643 | case 0: 644 | break; 645 | } 646 | if (argc<2)f2=f1; 647 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 649 | 650 | x->i_count=x->i_down; 651 | \end{verbatim} 652 | 653 | If three arguments are passed, these should be the {\em lower boundary}, 654 | the {\em upper boundary} and the {\em step width}. 655 | 656 | If only two arguments are passed, the step-width defaults to ``1''. 657 | If only one argument is passed, this should be the {\em initial value} of the counter with 658 | step-width of ``1''. 659 | 660 | \begin{verbatim} 661 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, 662 | gensym("list"), gensym("bound")); 663 | \end{verbatim} 664 | 665 | The function \verb+inlet_new+ creates a new ``active'' inlet. 666 | ``Active'' means, that a class-method is called each time 667 | a message is sent to an ``active'' inlet. 668 | 669 | Due to the software-architecture, the first inlet is always ``active''. 670 | 671 | The first two arguments of the \verb+inlet_new+-function are 672 | pointers to the interna of the object and to the graphical presentation of the object. 673 | 674 | The symbolic selector that is specified by the third argument is to be 675 | substituted by another symbolic selector (fourth argument) for this inlet. 676 | 677 | Because of this substitution of selectors, 678 | a message on a certain right inlet can be treated as a message with 679 | a certain selector on the leftmost inlet. 680 | 681 | This means: 682 | \begin{itemize} 683 | \item The substituting selector has to be declared by \verb+class_addmethod+ 684 | in the setup-routine. 685 | \item It is possible to simulate a certain right inlet, by sending a message with 686 | this inlet's selector to the leftmost inlet. 687 | \item It is not possible to add methods for more than one selector to a right inlet. 688 | Particularly it is not possible to add a universal method for arbitrary selectors to 689 | a right inlet. 690 | \end{itemize} 691 | 692 | \begin{verbatim} 693 | floatinlet_new(&x->x_obj, &x->step); 694 | \end{verbatim} 695 | \verb+floatinlet_new+ generates a new ``passive'' inlet for numerical values. 696 | ``Passive'' inlets allow parts of the data space-memory to be written directly 697 | from outside. 698 | Therefore it is not possible to check for illegal inputs. 699 | 700 | The first argument is a pointer to the internal infrastructure of the object. 701 | The second argument is the address in the data space-memory, 702 | where other objects can write too. 703 | 704 | ``Passive'' inlets can be created for pointers, symbolic or 705 | numerical (floating point\footnote{ 706 | That's why the {\tt step}-width of the class\/data space is realized as {\tt t\_float}.}) 707 | values. 708 | 709 | 710 | \begin{verbatim} 711 | x->f_out = outlet_new(&x->x_obj, &s_float); 712 | x->b_out = outlet_new(&x->x_obj, &s_bang); 713 | \end{verbatim} 714 | 715 | The pointers returned by \verb+outlet_new+ have to be saved in the class\/data space 716 | to be used later by the outlet-routines. 717 | 718 | The order of the generation of inlets and outlets is important, 719 | since it corresponds to the order of inlets and outlets in the 720 | graphical representation of the object. 721 | 722 | \subsection{extended method space} 723 | 724 | The method for the ``bang''-message has to full fill the more complex tasks. 725 | 726 | \begin{verbatim} 727 | void counter_bang(t_counter *x) 728 | { 729 | t_float f=x->i_count; 730 | int step = x->step; 731 | x->i_count+=step; 732 | if (x->i_down-x->i_up) { 733 | if ((step>0) && (x->i_count > x->i_up)) { 734 | x->i_count = x->i_down; 735 | outlet_bang(x->b_out); 736 | } else if (x->i_count < x->i_down) { 737 | x->i_count = x->i_up; 738 | outlet_bang(x->b_out); 739 | } 740 | } 741 | outlet_float(x->f_out, f); 742 | } 743 | \end{verbatim} 744 | 745 | Each outlet is identified by the \verb+outlet_...+-functions via the 746 | pointer to this outlets. 747 | 748 | The remaining methods still have to be implemented: 749 | 750 | \begin{verbatim} 751 | void counter_reset(t_counter *x) 752 | { 753 | x->i_count = x->i_down; 754 | } 755 | 756 | void counter_set(t_counter *x, t_floatarg f) 757 | { 758 | x->i_count = f; 759 | } 760 | 761 | void counter_bound(t_counter *x, t_floatarg f1, t_floatarg f2) 762 | { 763 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 765 | } 766 | \end{verbatim} 767 | 768 | \subsection{the code: \tt counter} 769 | 770 | \begin{verbatim} 771 | #include "m_pd.h" 772 | 773 | static t_class *counter_class; 774 | 775 | typedef struct _counter { 776 | t_object x_obj; 777 | int i_count; 778 | t_float step; 779 | int i_down, i_up; 780 | t_outlet *f_out, *b_out; 781 | } t_counter; 782 | 783 | void counter_bang(t_counter *x) 784 | { 785 | t_float f=x->i_count; 786 | int step = x->step; 787 | x->i_count+=step; 788 | 789 | if (x->i_down-x->i_up) { 790 | if ((step>0) && (x->i_count > x->i_up)) { 791 | x->i_count = x->i_down; 792 | outlet_bang(x->b_out); 793 | } else if (x->i_count < x->i_down) { 794 | x->i_count = x->i_up; 795 | outlet_bang(x->b_out); 796 | } 797 | } 798 | 799 | outlet_float(x->f_out, f); 800 | } 801 | 802 | void counter_reset(t_counter *x) 803 | { 804 | x->i_count = x->i_down; 805 | } 806 | 807 | void counter_set(t_counter *x, t_floatarg f) 808 | { 809 | x->i_count = f; 810 | } 811 | 812 | void counter_bound(t_counter *x, t_floatarg f1, t_floatarg f2) 813 | { 814 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 816 | } 817 | 818 | void *counter_new(t_symbol *s, int argc, t_atom *argv) 819 | { 820 | t_counter *x = (t_counter *)pd_new(counter_class); 821 | t_float f1=0, f2=0; 822 | 823 | x->step=1; 824 | switch(argc){ 825 | default: 826 | case 3: 827 | x->step=atom_getfloat(argv+2); 828 | case 2: 829 | f2=atom_getfloat(argv+1); 830 | case 1: 831 | f1=atom_getfloat(argv); 832 | break; 833 | case 0: 834 | break; 835 | } 836 | if (argc<2)f2=f1; 837 | 838 | x->i_down = (f1i_up = (f1>f2)?f1:f2; 840 | 841 | x->i_count=x->i_down; 842 | 843 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, 844 | gensym("list"), gensym("bound")); 845 | floatinlet_new(&x->x_obj, &x->step); 846 | 847 | x->f_out = outlet_new(&x->x_obj, &s_float); 848 | x->b_out = outlet_new(&x->x_obj, &s_bang); 849 | 850 | return (void *)x; 851 | } 852 | 853 | void counter_setup(void) { 854 | counter_class = class_new(gensym("counter"), 855 | (t_newmethod)counter_new, 856 | 0, sizeof(t_counter), 857 | CLASS_DEFAULT, 858 | A_GIMME, 0); 859 | 860 | class_addbang (counter_class, counter_bang); 861 | class_addmethod(counter_class, 862 | (t_method)counter_reset, gensym("reset"), 0); 863 | class_addmethod(counter_class, 864 | (t_method)counter_set, gensym("set"), 865 | A_DEFFLOAT, 0); 866 | class_addmethod(counter_class, 867 | (t_method)counter_bound, gensym("bound"), 868 | A_DEFFLOAT, A_DEFFLOAT, 0); 869 | 870 | class_sethelpsymbol(counter_class, gensym("help-counter")); 871 | } 872 | \end{verbatim} 873 | 874 | 875 | \section{a signal-external: {\tt pan\pdtilde}} 876 | Signal classes are normal Pd-classes, that offer additional methods for signals. 877 | 878 | 879 | All methods and concepts that can be realized with normal object classes can 880 | therefore be realized with signal classes too. 881 | 882 | Per agreement, the symbolic names of signal classes end with a tilde \pdtilde. 883 | 884 | The class ``pan\pdtilde'' shall demonstrate, how signal classes are written. 885 | 886 | A signal on the left inlet is mixed with a signal on the second inlet. 887 | The mixing-factor between 0 and 1 is defined via a \verb+t_float+-message 888 | on a third inlet. 889 | 890 | \subsection{variables of a signal class} 891 | Since a signal-class is only an extended normal class, 892 | there are no principal differences between the data spaces. 893 | 894 | \begin{verbatim} 895 | typedef struct _pan_tilde { 896 | t_object x_obj; 897 | 898 | t_sample f_pan; 899 | t_float f; 900 | 901 | t_inlet *x_in2; 902 | t_inlet *x_in3; 903 | 904 | t_outlet*x_out; 905 | 906 | } t_pan_tilde; 907 | \end{verbatim} 908 | 909 | Only one variable \verb+f_pan+ for the {\em mixing-factor} of the panning-function is needed. 910 | 911 | The other variable \verb+f+ is needed whenever a signal-inlet is needed too. 912 | If no signal but only a float-message is present at a signal-inlet, this 913 | variable is used to automatically convert the float to signal. 914 | 915 | Finally, we have the members \verb+x_in2+, \verb+x_in3+ and \verb+x_out+, 916 | which are needed to store handles to the various extra inlets (resp. outlets) of the object. 917 | 918 | \subsection{signal-classes} 919 | 920 | \begin{verbatim} 921 | void pan_tilde_setup(void) { 922 | pan_tilde_class = class_new(gensym("pan~"), 923 | (t_newmethod)pan_tilde_new, 924 | (t_method)pan_tilde_free, 925 | sizeof(t_pan_tilde), 926 | CLASS_DEFAULT, 927 | A_DEFFLOAT, 0); 928 | 929 | class_addmethod(pan_tilde_class, 930 | (t_method)pan_tilde_dsp, gensym("dsp"), 0); 931 | CLASS_MAINSIGNALIN(pan_tilde_class, t_pan_tilde, f); 932 | } 933 | \end{verbatim} 934 | 935 | Something has changed with the \verb+class_new+ function: 936 | the third argument specifies a ``free-method'' (aka {\em destructor}), which is called whenever an instance of the object 937 | is to be deleted (just like the ``new-method'' is called whenever an instance is to be created). 938 | In the prior examples this was set to \verb+0+ (meaning: we don't care), 939 | but in this example we have to clean up some ressources when we don't need them any more. 940 | 941 | More interestingly, a method for signal-processing has to be provided by each signal class. 942 | 943 | Whenever Pd's audio engine is started, a message with the selector ``dsp'' 944 | is sent to each object. 945 | Each class that has a method for the ``dsp''-message is recognised as signal class. 946 | 947 | Signal classes that want to provide signal-inlets have to 948 | declare this via the \verb+CLASS_MAINSIGNALIN+-macro. 949 | This enables signals at the first (default) inlet. 950 | If more than one signal-inlet is needed, they have to be created explicitly 951 | in the constructor-method. 952 | 953 | Inlets that are declared as signal-inlets cannot provide 954 | methods for \verb+t_float+-messages any longer. 955 | 956 | The first argument of the macro is a pointer to the signal class. 957 | The second argument is the type of the class's data space. 958 | 959 | The last argument is a dummy-variable out of the data space that is needed 960 | to replace non-existing signal at the signal-inlet(s) with \verb+t_float+-messages. 961 | 962 | \subsection{construction of signal-inlets and -outlets} 963 | 964 | \begin{verbatim} 965 | void *pan_tilde_new(t_floatarg f) 966 | { 967 | t_pan_tilde *x = (t_pan_tilde *)pd_new(pan_tilde_class); 968 | 969 | x->f_pan = f; 970 | 971 | x->x_in2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); 972 | x->x_in3 = floatinlet_new (&x->x_obj, &x->f_pan); 973 | 974 | x->x_out = outlet_new(&x->x_obj, &s_signal); 975 | 976 | return (void *)x; 977 | } 978 | \end{verbatim} 979 | 980 | Additional signal-inlets are added like other inlets with the routine \verb+inlet_new+. 981 | The last two arguments are references to the symbolic selector ``signal'' 982 | in the lookup-table. 983 | 984 | Signal-outlets are also created like normal (message-)outlets, 985 | by setting the outlet-selector to ``signal''. 986 | 987 | The newly created inlets/outlets are ``user-allocated'' data. 988 | Pd will keep track of all the ressources it automatically creates (like the default inlet), 989 | and will eventually free these ressources once they are no longer needed. 990 | However, if we request an ``extra'' ressource (like the additional inlets/outlets in this example; 991 | or - more commonly - memory that is allocated via \verb+malloc+ or similar), 992 | we have to make sure ourselves, that these ressources are freed when no longer needed. 993 | If we fail to do so, we will invariably create a dreaded {\em memory leak}. 994 | 995 | Therefore, we store the ``handles'' to the newly created inlets/outlets as returned by the \verb+..._new+ routines 996 | for later use. 997 | 998 | 999 | \subsection{DSP-methods} 1000 | Whenever Pd's audio engine is turned on, 1001 | all signal-objects declare their perform-routines that are to be added to the DSP-tree. 1002 | 1003 | The ``dsp''-method has two arguments, the pointer to the class-data space, and 1004 | a pointer to an array of signals. 1005 | 1006 | The signals are arranged in the array in such way, 1007 | that they are ordered in a clockwise way in the graphical representation of the 1008 | object.\footnote{ 1009 | If both left and right in- and out-signals exist, this means: 1010 | First is the leftmost in-signal followed by the right in-signals; 1011 | after the right out-signals, finally there comes the leftmost out-signal.} 1012 | 1013 | \begin{verbatim} 1014 | void pan_tilde_dsp(t_pan_tilde *x, t_signal **sp) 1015 | { 1016 | dsp_add(pan_tilde_perform, 5, x, 1017 | sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); 1018 | } 1019 | \end{verbatim} 1020 | 1021 | \verb+dsp_add+ adds a {\em perform}-routine (as declared in the first argument) 1022 | to the DSP-tree. 1023 | 1024 | The second argument is the number of the following pointers to diverse variables. 1025 | Which pointers to which variables are passed is not limited. 1026 | 1027 | Here, sp[0] is the first in-signal, sp[1] represents the second in-signal and 1028 | sp[3] points to the out-signal. 1029 | 1030 | The structure \verb+t_signal+ contains a pointer to the 1031 | its signal-vector \verb+().s_vec+ (an array of samples of type \verb+t_sample+), 1032 | and the length of this signal-vector \verb+().s_n+. 1033 | 1034 | Since all signal vectors of a patch (not including it's sub-patches) are of the same length, 1035 | it is sufficient to get the length of one of these vectors. 1036 | 1037 | \subsection{perform-routine} 1038 | The perform-routine is the DSP-heart of each signal class. 1039 | 1040 | A pointer to an integer-array is passed to it. 1041 | This array contains the pointers, that were passed via \verb+dsp_add+, 1042 | which must be casted back to their real type. 1043 | 1044 | The perform-routine has to return a pointer to integer, 1045 | that points to the address behind the stored pointers of the routine. 1046 | This means, that the return argument equals the 1047 | argument of the perform-routine plus 1048 | the number of pointer variables (as declared as the second argument 1049 | of \verb+dsp_add+) plus one. 1050 | 1051 | \begin{verbatim} 1052 | t_int *pan_tilde_perform(t_int *w) 1053 | { 1054 | t_pan_tilde *x = (t_pan_tilde *)(w[1]); 1055 | t_sample *in1 = (t_sample *)(w[2]); 1056 | t_sample *in2 = (t_sample *)(w[3]); 1057 | t_sample *out = (t_sample *)(w[4]); 1058 | int n = (int)(w[5]); 1059 | 1060 | t_sample f_pan = (x->f_pan<0)?0.0:(x->f_pan>1)?1.0:x->f_pan; 1061 | 1062 | while (n--) *out++ = (*in1++)*(1-f_pan)+(*in2++)*f_pan; 1063 | 1064 | return (w+6); 1065 | } 1066 | \end{verbatim} 1067 | 1068 | Each sample of the signal vectors is read and manipulated in the \verb+while+-loop. 1069 | 1070 | 1071 | Optimisation of the DSP-tree tries to avoid unnecessary copy-operations. 1072 | Therefore it is possible, that in- and out-signal are located 1073 | at the same address in the memory. 1074 | In this case, the programmer has to be careful not to write into the out-signal 1075 | before having read the in-signal to avoid overwriting data that is not yet saved. 1076 | 1077 | \subsection{destructor} 1078 | 1079 | \begin{verbatim} 1080 | void pan_tilde_free(t_pan_tilde *x) 1081 | { 1082 | inlet_free(x->x_in2); 1083 | inlet_free(x->x_in3); 1084 | outlet_free(x->x_out); 1085 | } 1086 | \end{verbatim} 1087 | 1088 | The object has some dynamically allocated ressources, 1089 | namely the additional inlets and outlets we created in the constructor. 1090 | 1091 | Since Pd doesn't track dynamically allocated ressources for us, 1092 | we have to free them manually in the ``free-method'' (aka: destructor). 1093 | We do so by calling \verb+inlet_free+ (resp. \verb+outlet_free+) on the handles to 1094 | our additional iolets. 1095 | 1096 | Note that we do not need to free the default first outlet. 1097 | As it is created automatically by Pd, it is also freed automatically. 1098 | 1099 | \subsection{the code: \tt pan\pdtilde} 1100 | 1101 | \begin{verbatim} 1102 | #include "m_pd.h" 1103 | 1104 | static t_class *pan_tilde_class; 1105 | 1106 | typedef struct _pan_tilde { 1107 | t_object x_obj; 1108 | t_sample f_pan; 1109 | t_sample f; 1110 | 1111 | t_inlet *x_in2; 1112 | t_inlet *x_in3; 1113 | t_outlet*x_out; 1114 | } t_pan_tilde; 1115 | 1116 | t_int *pan_tilde_perform(t_int *w) 1117 | { 1118 | t_pan_tilde *x = (t_pan_tilde *)(w[1]); 1119 | t_sample *in1 = (t_sample *)(w[2]); 1120 | t_sample *in2 = (t_sample *)(w[3]); 1121 | t_sample *out = (t_sample *)(w[4]); 1122 | int n = (int)(w[5]); 1123 | t_sample f_pan = (x->f_pan<0)?0.0:(x->f_pan>1)?1.0:x->f_pan; 1124 | 1125 | while (n--) *out++ = (*in1++)*(1-f_pan)+(*in2++)*f_pan; 1126 | 1127 | return (w+6); 1128 | } 1129 | 1130 | void pan_tilde_dsp(t_pan_tilde *x, t_signal **sp) 1131 | { 1132 | dsp_add(pan_tilde_perform, 5, x, 1133 | sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); 1134 | } 1135 | 1136 | void pan_tilde_free(t_pan_tilde *x) 1137 | { 1138 | inlet_free(x->x_in2); 1139 | inlet_free(x->x_in3); 1140 | outlet_free(x->x_out); 1141 | } 1142 | 1143 | void *pan_tilde_new(t_floatarg f) 1144 | { 1145 | t_pan_tilde *x = (t_pan_tilde *)pd_new(pan_tilde_class); 1146 | 1147 | x->f_pan = f; 1148 | 1149 | x->x_in2=inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); 1150 | x->x_in3=floatinlet_new (&x->x_obj, &x->f_pan); 1151 | x->x_out=outlet_new(&x->x_obj, &s_signal); 1152 | 1153 | return (void *)x; 1154 | } 1155 | 1156 | void pan_tilde_setup(void) { 1157 | pan_tilde_class = class_new(gensym("pan~"), 1158 | (t_newmethod)pan_tilde_new, 1159 | 0, sizeof(t_pan_tilde), 1160 | CLASS_DEFAULT, 1161 | A_DEFFLOAT, 0); 1162 | 1163 | class_addmethod(pan_tilde_class, 1164 | (t_method)pan_tilde_dsp, gensym("dsp"), 0); 1165 | CLASS_MAINSIGNALIN(pan_tilde_class, t_pan_tilde, f); 1166 | } 1167 | \end{verbatim} 1168 | 1169 | \vfill 1170 | \newpage 1171 | \begin{appendix} 1172 | 1173 | \section{Pd's message-system} 1174 | Non-audio-data are distributed via a message-system. 1175 | Each message consists of a ``selector'' and a list of atoms. 1176 | 1177 | \subsection{atoms} 1178 | 1179 | There are three kinds of atoms: 1180 | \begin{itemize} 1181 | \item {\em A\_FLOAT}: a numerical value (floating point) 1182 | \item {\em A\_SYMBOL}: a symbolic value (string) 1183 | \item {\em A\_POINTER}: a pointer 1184 | \end{itemize} 1185 | 1186 | Numerical values are always floating point-values (\verb+t_float+), 1187 | even if they could be displayed as integer values. 1188 | 1189 | Each symbol is stored in a lookup-table for reasons of performance. 1190 | The command \verb+gensym+ looks up a string in the lookup-table and 1191 | returns the address of the symbol. 1192 | If the string is not yet to be found in the table, 1193 | a new symbol is added. 1194 | 1195 | Atoms of type {\em A\_POINTER} are not very important (for simple externals). 1196 | 1197 | The type of an atom \verb+a+ is stored in the structure-element \verb+a.a_type+. 1198 | 1199 | \subsection{selectors} 1200 | The selector is a symbol that defines the type of a message. 1201 | There are five predefined selectors: 1202 | \begin{itemize} 1203 | \item ``{\tt bang}'' labels a trigger event. 1204 | A ``bang''-message consists only of the selector and contains no lists of atoms. 1205 | \item ``{\tt float}'' labels a numerical value. 1206 | The list of a ``float''-Message contains one single atom of type {\em A\_FLOAT} 1207 | \item ``{\tt symbol}'' labels a symbolic value. 1208 | The list of a ``symbol''-Message contains one single atom of type {\em A\_SYMBOL} 1209 | \item ``{\tt pointer}'' labels a pointer value. 1210 | The list of a ``pointer''-Message contains one single atom of type {\em A\_POINTER} 1211 | \item ``{\tt list}'' labels a list of one or more atoms of arbitrary type. 1212 | \end{itemize} 1213 | 1214 | Since the symbols for these selectors are used quite often, 1215 | their address in the lookup-table can be queried directly, 1216 | without having to use \verb+gensym+: 1217 | 1218 | \begin{tabular}{l||l|l} 1219 | selector&lookup-routine&lookup-address\\ 1220 | \hline 1221 | \tt bang &\verb+gensym("bang")+ & \verb+&s_bang+ \\ 1222 | \tt float &\verb+gensym("float")+ & \verb+&s_float+ \\ 1223 | \tt symbol &\verb+gensym("symbol")+ & \verb+&s_symbol+ \\ 1224 | \tt pointer &\verb+gensym("pointer")+ & \verb+&s_pointer+ \\ 1225 | \tt list &\verb+gensym("list")+ & \verb+&s_list+ \\ 1226 | --- (signal) &\verb+gensym("signal")+&\verb+&s_symbol+ 1227 | \end{tabular} 1228 | 1229 | Other selectors can be used as well. 1230 | The receiving class has to provide a method for a specifique selector 1231 | or for ``anything'', which is any arbitrary selector. 1232 | 1233 | Messages that have no explicit selector and start with a numerical value, 1234 | are recognised automatically either as ``float''-message (only one atom) or as 1235 | ``list''-message (several atoms). 1236 | 1237 | For example, messages ``\verb+12.429+'' and ``\verb+float 12.429+'' are identical. 1238 | Likewise, the messages ``\verb+list 1 for you+'' is identical to ``\verb+1 for you+''. 1239 | 1240 | \section{Pd-types} 1241 | Since Pd is used on several platforms, 1242 | many ordinary types of variables, like \verb|int|, are re-defined. 1243 | To write portable code, it is reasonable to use types provided by Pd. 1244 | 1245 | Apart from this there are many predefined types, 1246 | that should make the life of the programmer simpler. 1247 | 1248 | Generally, Pd-types start with \verb|t_|. 1249 | 1250 | \begin{tabular}{c|l} 1251 | Pd-type & description \\ 1252 | \hline\hline 1253 | \verb+t_atom+& atom \\ 1254 | \verb+t_float+ & floating point value\\ 1255 | \verb+t_symbol+ & symbol \\ 1256 | \verb+t_gpointer+ & pointer (to graphical objects) \\ 1257 | \hline 1258 | \verb+t_int+ & pointer-sized integer value (only used for perform routines) \\ 1259 | \verb+t_signal+ & structure of a signal \\ 1260 | \verb+t_sample+ & audio signal-value (floating point)\\ 1261 | \verb+t_outlet+ & outlet of an object \\ 1262 | \verb+t_inlet+ & inlet of an object \\ 1263 | \verb+t_object+ & object-interna \\ 1264 | \hline 1265 | \verb+t_class+ & a Pd-class \\ 1266 | \verb+t_method+ & class-method \\ 1267 | \verb+t_newmethod+ & pointer to a constructor (new-routine) \\ 1268 | \end{tabular} 1269 | 1270 | 1271 | \section{important functions in ``m\_pd.h''} 1272 | 1273 | \subsection{functions: atoms} 1274 | 1275 | \subsubsection{SETFLOAT} 1276 | \begin{verbatim} 1277 | SETFLOAT(atom, f) 1278 | \end{verbatim} 1279 | This macro sets the type of \verb+atom+ to \verb+A_FLOAT+ 1280 | and stores the numerical value \verb+f+ in this atom. 1281 | 1282 | \subsubsection{SETSYMBOL} 1283 | \begin{verbatim} 1284 | SETSYMBOL(atom, s) 1285 | \end{verbatim} 1286 | This macro sets the type of \verb+atom+ to \verb+A_SYMBOL+ 1287 | and stores the symbolic pointer \verb+s+ in this atom. 1288 | 1289 | \subsubsection{SETPOINTER} 1290 | \begin{verbatim} 1291 | SETPOINTER(atom, pt) 1292 | \end{verbatim} 1293 | This macro sets the type of \verb+atom+ to \verb+A_POINTER+ 1294 | and stores the pointer \verb+pt+ in this atom. 1295 | 1296 | \subsubsection{atom\_getfloat} 1297 | \begin{verbatim} 1298 | t_float atom_getfloat(t_atom *a); 1299 | \end{verbatim} 1300 | If the type of the atom \verb+a+ is \verb+A_FLOAT+, 1301 | the numerical value of this atom else ``0.0'' is returned. 1302 | 1303 | \subsubsection{atom\_getfloatarg} 1304 | \begin{verbatim} 1305 | t_float atom_getfloatarg(int which, int argc, t_atom *argv) 1306 | \end{verbatim} 1307 | If the type of the atom -- that is found at in the atom-list 1308 | \verb+argv+ with the length \verb+argc+ at the place \verb+which+ -- 1309 | is \verb+A_FLOAT+, the numerical value of this atom else ``0.0'' is returned. 1310 | 1311 | \subsubsection{atom\_getint} 1312 | \begin{verbatim} 1313 | t_int atom_getint(t_atom *a); 1314 | \end{verbatim} 1315 | If the type of the atom \verb+a+ is \verb+A_FLOAT+, 1316 | its numerical value is returned as integer else ``0'' is returned. 1317 | 1318 | \subsubsection{atom\_getsymbol} 1319 | \begin{verbatim} 1320 | t_symbol atom_getsymbol(t_atom *a); 1321 | \end{verbatim} 1322 | If the type of the atom \verb+a+ is \verb+A_SYMBOL+, 1323 | a pointer to this symbol is returned, else a null-pointer ``0'' is returned. 1324 | 1325 | \subsubsection{atom\_gensym} 1326 | \begin{verbatim} 1327 | t_symbol *atom_gensym(t_atom *a); 1328 | \end{verbatim} 1329 | If the type of the atom \verb+a+ is \verb+A_SYMBOL+, 1330 | a pointer to this symbol is returned. 1331 | 1332 | Atoms of a different type, are ``reasonably'' converted into a string. 1333 | This string is -- on demand -- inserted into the symbol-table. 1334 | A pointer to this symbol is returned. 1335 | 1336 | \subsubsection{atom\_string} 1337 | \begin{verbatim} 1338 | void atom_string(t_atom *a, char *buf, unsigned int bufsize); 1339 | \end{verbatim} 1340 | Converts an atom \verb+a+ into a {\tt C}-string \verb+buf+. 1341 | The memory to this char-Buffer has to be reserved manually and 1342 | its length has to be declared in \verb+bufsize+. 1343 | 1344 | \subsubsection{gensym} 1345 | \begin{verbatim} 1346 | t_symbol *gensym(char *s); 1347 | \end{verbatim} 1348 | Checks, whether the C-string \verb+*s+ has already been inserted into the symbol-table. 1349 | If no entry exists, it is created. 1350 | A pointer to the symbol is returned. 1351 | 1352 | \subsection{functions: classes} 1353 | \subsubsection{class\_new} 1354 | \begin{verbatim} 1355 | t_class *class_new(t_symbol *name, 1356 | t_newmethod newmethod, t_method freemethod, 1357 | size_t size, int flags, 1358 | t_atomtype arg1, ...); 1359 | \end{verbatim} 1360 | Generates a class with the symbolic name \verb+name+. 1361 | \verb+newmethod+ is the constructor that creates an instance of the class and 1362 | returns a pointer to this instance. 1363 | 1364 | If memory is reserved dynamically, this memory has to be freed by the 1365 | destructor-method \verb+freemethod+ (without any return argument), 1366 | when the object is destroyed. 1367 | 1368 | \verb+size+ is the static size of the class-data space, 1369 | that is returned by \verb+sizeof(t_mydata)+. 1370 | 1371 | \verb+flags+ define the presentation of the graphical object. 1372 | A (more or less arbitrary) combination of following objects is possible: 1373 | 1374 | \begin{tabular}{l|l} 1375 | flag&description\\ 1376 | \hline 1377 | \verb+CLASS_DEFAULT+ & a normal object with one inlet \\ 1378 | \verb+CLASS_PD+ & \em object (without graphical presentation) \\ 1379 | \verb+CLASS_GOBJ+ & \em pure graphical object (like arrays, graphs,...)\\ 1380 | \verb+CLASS_PATCHABLE+ & \em a normal object (with one inlet) \\ 1381 | \verb+CLASS_NOINLET+ & the default inlet is suppressed \\ 1382 | \end{tabular} 1383 | 1384 | Flags the description of which is printed in {\em italic} 1385 | are of small importance for writing externals. 1386 | 1387 | The remaining arguments \verb+arg1,...+ define the 1388 | types of object-arguments passed at the creation of a class-object. 1389 | A maximum of six type checked arguments can be passed to an object. 1390 | The list of argument-types are terminated by ``0''. 1391 | 1392 | Possible types of arguments are: 1393 | 1394 | \begin{tabular}{l|l} 1395 | \verb+A_DEFFLOAT+ & a numerical value \\ 1396 | \verb+A_DEFSYMBOL+ & a symbolical value \\ 1397 | \verb+A_GIMME+ & a list of atoms of arbitrary length and types \\ 1398 | \end{tabular} 1399 | 1400 | If more than six arguments are to be passed, 1401 | \verb+A_GIMME+ has to be used and a manual type-check has to be made. 1402 | 1403 | \subsubsection{class\_addmethod} 1404 | \begin{verbatim} 1405 | void class_addmethod(t_class *c, t_method fn, t_symbol *sel, 1406 | t_atomtype arg1, ...); 1407 | \end{verbatim} 1408 | Adds a method \verb+fn+ for a selector \verb+sel+ to a class \verb+c+. 1409 | 1410 | The remaining arguments \verb+arg1,...+ define the 1411 | types of the list of atoms that follow the selector. 1412 | A maximum of six type-checked arguments can be passed. 1413 | If more than six arguments are to be passed, 1414 | \verb+A_GIMME+ has to be used and a manual type-check has to be made. 1415 | 1416 | The list of arguments is terminated by ``0''. 1417 | 1418 | 1419 | Possible types of arguments are: 1420 | 1421 | \begin{tabular}{l|l} 1422 | \verb+A_DEFFLOAT+ & a numerical value \\ 1423 | \verb+A_DEFSYMBOL+ & a symbolical value \\ 1424 | \verb+A_POINTER+ & a pointer \\ 1425 | \verb+A_GIMME+ & a list of atoms of arbitrary length and types \\ 1426 | \end{tabular} 1427 | 1428 | \subsubsection{class\_addbang} 1429 | \begin{verbatim} 1430 | void class_addbang(t_class *c, t_method fn); 1431 | \end{verbatim} 1432 | Adds a method \verb+fn+ for ``bang''-messages to the class \verb+c+. 1433 | 1434 | The argument of the ``bang''-method is a pointer to the class-data space: 1435 | 1436 | \verb+void my_bang_method(t_mydata *x);+ 1437 | 1438 | \subsubsection{class\_addfloat} 1439 | \begin{verbatim} 1440 | void class_addfloat(t_class *c, t_method fn); 1441 | \end{verbatim} 1442 | Adds a method \verb+fn+ for ``float''-messages to the class \verb+c+. 1443 | 1444 | The arguments of the ``float''-method is a pointer to the class-data space and 1445 | a floating point-argument: 1446 | 1447 | \verb+void my_float_method(t_mydata *x, t_floatarg f);+ 1448 | 1449 | \subsubsection{class\_addsymbol} 1450 | \begin{verbatim} 1451 | void class_addsymbol(t_class *c, t_method fn); 1452 | \end{verbatim} 1453 | Adds a method \verb+fn+ for ``symbol''-messages to the class \verb+c+. 1454 | 1455 | The arguments of the ``symbol''-method is a pointer to the class-data space and 1456 | a pointer to the passed symbol: 1457 | 1458 | \verb+void my_symbol_method(t_mydata *x, t_symbol *s);+ 1459 | 1460 | \subsubsection{class\_addpointer} 1461 | \begin{verbatim} 1462 | void class_addpointer(t_class *c, t_method fn); 1463 | \end{verbatim} 1464 | Adds a method \verb+fn+ for ``pointer''-messages to the class \verb+c+. 1465 | 1466 | The arguments of the ``pointer''-method is a pointer to the class-data space and 1467 | a pointer to a pointer: 1468 | 1469 | \verb+void my_pointer_method(t_mydata *x, t_gpointer *pt);+ 1470 | 1471 | \subsubsection{class\_addlist} 1472 | \begin{verbatim} 1473 | void class_addlist(t_class *c, t_method fn); 1474 | \end{verbatim} 1475 | Adds a method \verb+fn+ for ``list''-messages to the class \verb+c+. 1476 | 1477 | The arguments of the ``list''-method are -- apart from a pointer to the class-data space -- 1478 | a pointer to the selector-symbol (always \verb+&s_list+), 1479 | the number of atoms and a pointer to the list of atoms: 1480 | 1481 | \verb+void my_list_method(t_mydata *x,+ 1482 | 1483 | \verb+ t_symbol *s, int argc, t_atom *argv);+ 1484 | 1485 | \subsubsection{class\_addanything} 1486 | \begin{verbatim} 1487 | void class_addanything(t_class *c, t_method fn); 1488 | \end{verbatim} 1489 | Adds a method \verb+fn+ for an arbitrary message to the class \verb+c+. 1490 | 1491 | The arguments of the anything-method are -- apart from a pointer to the class-data space -- 1492 | a pointer to the selector-symbol, 1493 | the number of atoms and a pointer to the list of atoms: 1494 | 1495 | \verb+void my_any_method(t_mydata *x,+ 1496 | 1497 | \verb+ t_symbol *s, int argc, t_atom *argv);+ 1498 | 1499 | \subsubsection{class\_addcreator} 1500 | \begin{verbatim} 1501 | void class_addcreator(t_newmethod newmethod, t_symbol *s, 1502 | t_atomtype type1, ...); 1503 | \end{verbatim} 1504 | Adds a creator-symbol \verb+s+, alternative to the symbolic class name, 1505 | to the constructor \verb+newmethod+. 1506 | Thus, objects can be created either by their ``real'' class name or 1507 | an alias-name (p.e. an abbreviation, like the internal ``float'' resp. ``f''). 1508 | 1509 | The ``0''-terminated list of types corresponds to that of \verb+class_new+. 1510 | 1511 | \subsubsection{class\_sethelpsymbol} 1512 | \begin{verbatim} 1513 | void class_sethelpsymbol(t_class *c, t_symbol *s); 1514 | \end{verbatim} 1515 | 1516 | If a Pd-object is right-clicked, a help-patch for the corresponding object class 1517 | can be opened. 1518 | By default this is a patch with the symbolic class name in the 1519 | directory ``{\em doc/5.reference/}''. 1520 | 1521 | The name of the help-patch for the class that is pointed to by \verb+c+ 1522 | is changed to the symbol \verb+s+. 1523 | 1524 | Therefore, several similar classes can share a single help-patch. 1525 | 1526 | Path-information is relative to the default help path {\em doc/5.reference/}. 1527 | 1528 | \subsubsection{pd\_new} 1529 | \begin{verbatim} 1530 | t_pd *pd_new(t_class *cls); 1531 | \end{verbatim} 1532 | Generates a new instance of the class \verb+cls+ and 1533 | returns a pointer to this instance. 1534 | 1535 | \subsection{functions: inlets and outlets} 1536 | All routines for inlets and outlets need a reference to the object-interna of 1537 | the class-instance. 1538 | When instantiating a new object, 1539 | the necessary data space-variable of the \verb+t_object+-type is initialised. 1540 | This variable has to be passed as the \verb+owner+-object to the 1541 | various inlet- and outlet-routines. 1542 | 1543 | \subsubsection{inlet\_new} 1544 | \begin{verbatim} 1545 | t_inlet *inlet_new(t_object *owner, t_pd *dest, 1546 | t_symbol *s1, t_symbol *s2); 1547 | \end{verbatim} 1548 | Generates an additional ``active'' inlet for the object 1549 | that is pointed at by \verb+owner+. 1550 | Generally, \verb+dest+ points at ``\verb+owner.ob_pd+''. 1551 | 1552 | The selector \verb+s1+ at the new inlet is substituted by the selector \verb+s2+. 1553 | 1554 | If a message with selector \verb+s1+ appears at the new inlet, 1555 | the class-method for the selector \verb+s2+ is called. 1556 | 1557 | This means 1558 | \begin{itemize} 1559 | \item The substituting selector has to be declared by \verb+class_addmethod+ 1560 | in the setup-routine. 1561 | \item It is possible to simulate a certain right inlet, by sending a message with 1562 | this inlet's selector to the leftmost inlet. 1563 | 1564 | Using an empty symbol (\verb+gensym("")+) as selector 1565 | makes it impossible to address a right inlet via the leftmost one. 1566 | 1567 | \item It is not possible to add methods for more than one selector to a right inlet. 1568 | Particularly it is not possible to add a universal method for arbitrary selectors to 1569 | a right inlet. 1570 | \end{itemize} 1571 | 1572 | \subsubsection{floatinlet\_new} 1573 | \begin{verbatim} 1574 | t_inlet *floatinlet_new(t_object *owner, t_float *fp); 1575 | \end{verbatim} 1576 | Generates a new ``passive'' inlet for the object that is pointed at by \verb+owner+. 1577 | This inlet enables numerical values to be written directly into the 1578 | memory \verb+fp+, without calling a dedicated method. 1579 | 1580 | \subsubsection{symbolinlet\_new} 1581 | \begin{verbatim} 1582 | t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp); 1583 | \end{verbatim} 1584 | Generates a new ``passive'' inlet for the object that is pointed at by \verb+owner+. 1585 | This inlet enables symbolic values to be written directly into the 1586 | memory \verb+*sp+, without calling a dedicated method. 1587 | 1588 | 1589 | \subsubsection{pointerinlet\_new} 1590 | \begin{verbatim} 1591 | t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp); 1592 | \end{verbatim} 1593 | Generates a new ``passive'' inlet for the object that is pointed at by \verb+owner+. 1594 | This inlet enables pointer to be written directly into the 1595 | memory \verb+gp+, without calling a dedicated method. 1596 | 1597 | \subsubsection{outlet\_new} 1598 | \begin{verbatim} 1599 | t_outlet *outlet_new(t_object *owner, t_symbol *s); 1600 | \end{verbatim} 1601 | Generates a new outlet for the object that is pointed at by \verb+owner+. 1602 | The Symbol \verb+s+ indicates the type of the outlet. 1603 | 1604 | \begin{tabular}{c|l||l} 1605 | symbol & symbol-address & outlet-type \\ 1606 | \hline\hline 1607 | ``bang'' & \verb+&s_bang+ & message (bang)\\ 1608 | ``float'' & \verb+&s_float+ & message (float)\\ 1609 | ``symbol'' & \verb+&s_symbol+ & message (symbol) \\ 1610 | ``pointer'' & \verb+&s_gpointer+ & message (pointer)\\ 1611 | ``list'' & \verb+&s_list+ & message (list) \\ 1612 | --- & 0 & message \\ 1613 | \hline 1614 | ``signal'' & \verb+&s_signal+ & signal \\ 1615 | \end{tabular} 1616 | 1617 | There are no real differences between outlets of the various message-types. 1618 | At any rate, it makes code more easily readable, 1619 | if the use of outlet is shown at creation-time. 1620 | For outlets for any messages a null-pointer is used. 1621 | Signal-outlet must be declared with \verb+&s_signal+. 1622 | 1623 | Variables if the type \verb+t_object+ provide pointer to one outlet. 1624 | Whenever a new outlet is generated, its address is stored in the 1625 | object variable \verb+(*owner).ob_outlet+. 1626 | 1627 | If more than one message-outlet is needed, 1628 | the outlet-pointers that are returned by \verb+outlet_new+ 1629 | have to be stored manually in the data space 1630 | to address the given outlets. 1631 | 1632 | \subsubsection{outlet\_bang} 1633 | \begin{verbatim} 1634 | void outlet_bang(t_outlet *x); 1635 | \end{verbatim} 1636 | Outputs a ``bang''-message at the outlet specified by \verb+x+. 1637 | 1638 | \subsubsection{outlet\_float} 1639 | \begin{verbatim} 1640 | void outlet_float(t_outlet *x, t_float f); 1641 | \end{verbatim} 1642 | Outputs a ``float''-message with the numeric value \verb+f+ 1643 | at the outlet specified by \verb+x+. 1644 | 1645 | \subsubsection{outlet\_symbol} 1646 | \begin{verbatim} 1647 | void outlet_symbol(t_outlet *x, t_symbol *s); 1648 | \end{verbatim} 1649 | Outputs a ``symbol''-message with the symbolic value \verb+s+ 1650 | at the outlet specified by \verb+x+. 1651 | 1652 | \subsubsection{outlet\_pointer} 1653 | \begin{verbatim} 1654 | void outlet_pointer(t_outlet *x, t_gpointer *gp); 1655 | \end{verbatim} 1656 | Outputs a ``pointer''-message with the pointer \verb+gp+ 1657 | at the outlet specified by \verb+x+. 1658 | 1659 | \subsubsection{outlet\_list} 1660 | \begin{verbatim} 1661 | void outlet_list(t_outlet *x, 1662 | t_symbol *s, int argc, t_atom *argv); 1663 | \end{verbatim} 1664 | Outputs a ``list''-message at the outlet specified by \verb+x+. 1665 | The list contains \verb+argc+ atoms. 1666 | \verb+argv+ points to the first element of the atom-list. 1667 | 1668 | Independent of the symbol \verb+s+, the selector ``list'' will precede 1669 | the list. 1670 | 1671 | To make the code more readable, 1672 | \verb+s+ should point to the symbol list 1673 | (either via \verb+gensym("list")+ or via \verb+&s_list+) 1674 | 1675 | \subsubsection{outlet\_anything} 1676 | \begin{verbatim} 1677 | void outlet_anything(t_outlet *x, 1678 | t_symbol *s, int argc, t_atom *argv); 1679 | \end{verbatim} 1680 | Outputs a message at the outlet specified by \verb+x+. 1681 | 1682 | The message-selector is specified with \verb+s+. 1683 | It is followed by \verb+argc+ atoms. 1684 | \verb+argv+ points to the first element of the atom-list. 1685 | 1686 | \subsection{functions: DSP} 1687 | If a class should provide methods for digital signal-processing, 1688 | a method for the selector ``dsp'' (followed by no atoms) 1689 | has to be added to this class 1690 | 1691 | Whenever Pd's audio engine is started, 1692 | all objects that provide a ``dsp''-method are identified as instances of signal classes. 1693 | 1694 | \paragraph{DSP-method} 1695 | 1696 | \begin{verbatim} 1697 | void my_dsp_method(t_mydata *x, t_signal **sp) 1698 | \end{verbatim} 1699 | 1700 | In the ``dsp''-method a class method for signal-processing 1701 | is added to the DSP-tree by the function \verb+dsp_add+. 1702 | 1703 | Apart from the data space \verb+x+ of the object, 1704 | an array of signals is passed. 1705 | The signals in the array are arranged in such a way, 1706 | that they can be read in the graphical representation of the object 1707 | clockwisely. 1708 | 1709 | In case there are both two in- and out-signals, this means: 1710 | 1711 | \begin{tabular}{c|r} 1712 | pointer & to signal \\ 1713 | \hline\hline 1714 | sp[0] & left in-signal \\ 1715 | sp[1] & right in-signal \\ 1716 | sp[2] & right out-signal \\ 1717 | sp[3] & left out-signal \\ 1718 | \end{tabular} 1719 | 1720 | The signal structure contains apart from other things: 1721 | 1722 | \begin{tabular}{c|l} 1723 | structure-element & description \\ 1724 | \hline 1725 | \verb+s_n+ & length of the signal vector \\ 1726 | \verb+s_vec+ & pointer to the signal vector \\ 1727 | \end{tabular} 1728 | 1729 | The signal vector is an array of samples of type \verb+t_sample+. 1730 | 1731 | \paragraph{perform-routine} 1732 | \begin{verbatim} 1733 | t_int *my_perform_routine(t_int *w) 1734 | \end{verbatim} 1735 | 1736 | 1737 | A pointer \verb+w+ to an array (of integer) is passed to 1738 | the perform-routine that is inserted into the DSP-tree by \verb+class_add+. 1739 | 1740 | In this array the pointers that are passed via \verb+dsp_add+ are stored. 1741 | These pointers have to be casted back to their original type. 1742 | 1743 | The first pointer is stored at \verb+w[1]+ !!! 1744 | 1745 | The perform-routine has to return a pointer to integer, 1746 | that points directly behind the memory, where the object's pointers are stored. 1747 | This means, that the return-argument equals the routine's argument \verb+w+ 1748 | plus the number of used pointers 1749 | (as defined in the second argument of \verb+dsp_add+) plus one. 1750 | 1751 | \subsubsection{CLASS\_MAINSIGNALIN} 1752 | \begin{verbatim} 1753 | CLASS_MAINSIGNALIN(, , ); 1754 | \end{verbatim} 1755 | The macro \verb+CLASS_MAINSIGNALIN+ declares, 1756 | that the class will use signal-inlets. 1757 | 1758 | The first macro-argument is a pointer to the signal-class. 1759 | The second argument is the type of the class-data space. 1760 | The third argument is a (dummy-)floating point-variable of the data space, 1761 | that is needed to automatically convert ``float''-messages into signals 1762 | if no signal is present at the signal-inlet. 1763 | 1764 | No ``float''-methods can be used for signal-inlets, that are created this way. 1765 | 1766 | \subsubsection{dsp\_add} 1767 | \begin{verbatim} 1768 | void dsp_add(t_perfroutine f, int n, ...); 1769 | \end{verbatim} 1770 | Adds the perform-routine \verb+f+ to the DSP-tree. 1771 | The perform-routine is called at each DSP-cycle. 1772 | 1773 | The second argument\verb+n+ defines the number of following pointer-arguments 1774 | 1775 | Which pointers to which data are passes is not limited. 1776 | Generally, pointers to the data space of the object and to the 1777 | signal-vectors are reasonable. 1778 | The length of the signal-vectors should also be passed to manipulate signals effectively. 1779 | 1780 | \subsubsection{sys\_getsr} 1781 | \begin{verbatim} 1782 | float sys_getsr(void); 1783 | \end{verbatim} 1784 | Returns the sampler ate of the system. 1785 | 1786 | \subsection{functions: memory} 1787 | \subsubsection{getbytes} 1788 | \begin{verbatim} 1789 | void *getbytes(size_t nbytes); 1790 | \end{verbatim} 1791 | Reserves \verb+nbytes+ bytes and returns a pointer to the allocated memory. 1792 | 1793 | \subsubsection{copybytes} 1794 | \begin{verbatim} 1795 | void *copybytes(void *src, size_t nbytes); 1796 | \end{verbatim} 1797 | Copies \verb+nbytes+ bytes from \verb+*src+ into a newly allocated memory. 1798 | The address of this memory is returned. 1799 | 1800 | \subsubsection{freebytes} 1801 | \begin{verbatim} 1802 | void freebytes(void *x, size_t nbytes); 1803 | \end{verbatim} 1804 | Frees \verb+nbytes+ bytes at address \verb+*x+. 1805 | 1806 | \subsection{functions: output} 1807 | \subsubsection{post} 1808 | \begin{verbatim} 1809 | void post(char *fmt, ...); 1810 | \end{verbatim} 1811 | 1812 | Writes a {\tt C}-string to the standard error (shell). 1813 | 1814 | \subsubsection{error} 1815 | \begin{verbatim} 1816 | void error(char *fmt, ...); 1817 | \end{verbatim} 1818 | 1819 | Writes a {\tt C}-string as an error-message to the standard error (shell). 1820 | 1821 | The object that has output the error-message is marked and 1822 | can be identified via the Pd-menu {\em Find->Find last error}. 1823 | 1824 | \end{appendix} 1825 | 1826 | \end{document} 1827 | 1828 | -------------------------------------------------------------------------------- /pd-lib-builder/CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | Changelog for Makefile.pdlibbuilder. 2 | 3 | v0.6.0, dated 2019-12-21 4 | - detect target platform (OS and architecture) rather than build platform (#55) 5 | - introduce optional user variable 'PLATFORM' for cross compilation 6 | - no longer build OSX/MacOS fat binaries by default (#21, #50) 7 | - do build fat binaries when 'extension=d_fat' is specified for OSX/MacOS 8 | - fix bug where minimum OSX/MacOS version wasn't defined, and set it to 10.6 9 | 10 | v0.5.1, dated 2018-03-15 11 | Fixes and improvements for Windows builds: 12 | - properly evaluate variables 'PDDIR' and 'PDBINDIR' to find pd.dll 13 | - define default path of 32 bit Pd on 64 bit Windows 14 | - link C++ externals with standard C libs on Windows, they don't load otherwise 15 | - strip installed Windows binaries by default 16 | (issues #34, #39, #41, #42 respectively) 17 | Warning for all platforms: variable 'PD_PATH' is no longer supported, use the 18 | equivalent 'PDDIR'. 19 | 20 | v0.5.0, dated 2018-01-23 21 | Implement target architecture detection for Windows builds, 22 | and set appropriate options for 32 and 64 bit (used to be for 32 bit only). 23 | (feature, issue #37 #38, merge commit 215bf3e) 24 | 25 | v0.4.4, dated 2016-11-22 26 | Use variable 'system' when evaluating 'for{Linux,Darwin,Windows}' 27 | (bugfix, issue #31, commit 2c14110) 28 | 29 | v0.4.3, dated 2016-11-02 30 | Replace flags '-fpic' by 'fPIC'. 31 | (bugfix, issue #29, commit 426b38b) 32 | 33 | v0.4.2, dated 2016-10-30 34 | Fix issue where incorrect message about m_pd.h is given. 35 | (bugfix, commit 2e13d8f) 36 | 37 | v0.4.1, dated 2016-10-27 38 | Respect cflag for minimum OSX version when defined by lib makefile. 39 | (bugfix, pull request #22, commit 48c4127) 40 | 41 | v0.4.0, dated 2016-10-14 42 | Introduced path variables PDDIR, PDINCLUDEDIR, PDBINDIR, PDLIBDIR which can 43 | also be defined in environment. 44 | (feature, issue #27, commit b0dab72) 45 | 46 | v0.3.1, dated 2016-10-13 47 | Fix bug where pd.dll wouldn't be found. 48 | (bugfix, commit a0c87be) 49 | 50 | v0.3.0, dated 2016-10-09 51 | Variable 'PD_PATH' introduced for pd-extended / pd-l2ork compatibility. 52 | (feature, issue #26, commit 41e9743) 53 | 54 | v0.2.8, dated 2016-10-09 55 | Allow installed files to contain weird characters (notably '$'). 56 | (bugfix, pull request #20, commit 5b920b1) 57 | 58 | v0.2.7, dated 2016-10-04 59 | Remove all default pd search paths except vanilla's. 60 | (discussion, issue #25, commit a6a89dc) 61 | 62 | v0.2.6, dated 2016-09-20 63 | Redefined dependency checking so it won't stall rebuilds on OSX. 64 | (bugfix, issue #16, commit 9fd1795) 65 | 66 | v0.2.5, dated 2016-06-26 67 | Fixed dependency checking for object files in other directories. 68 | (bugfix, commit f06e550) 69 | 70 | v0.2.4, dated 2016-06-25 71 | Fixed regression bug that disabled all dependency checking. 72 | (bugfix, commit 1d7bb5e) 73 | 74 | v0.2.3, dated 2016-03-29 75 | Disabled dependency checking for OSX <= 10.5 because it stalled rebuilds. 76 | (bugfix, issue #16, commit eb614fd) 77 | 78 | v0.2.2, dated 2016-03-28 79 | Removed target 'pre' because it forced rebuild of everything in 'all'. 80 | (bugfix, issue #17, commit c989c8e) 81 | 82 | v0.2.1, dated 2015-12-27 83 | Implement / respect 'CPPFLAGS','CFLAGS'and 'LDFLAGS'. 84 | (bugfix, issue #5, commit 98f3582) 85 | 86 | v0.2.0, dated 2015-12-19 87 | Added per-platform multiline defines 'forLinux', 'forDarwin', 'forWindows'. 88 | (feature, pull request #9, commit 3946ea5) 89 | 90 | v0.1.0, dated 2015-12-08 91 | Added targets 'pre' and 'post' to automatically run before and after 'all'. 92 | (feature, pull request #4, commit a5678ac) 93 | 94 | v0.0.2, dated 2015-12-06 95 | Improved methods for searching pd paths. 96 | (bugfix, commit ed37e6b) 97 | 98 | v0.0.1, dated 2015-10-31 99 | Fixed expansion of variable 'lib.version'. 100 | (bugfix, issue #1, commit 974b617) 101 | 102 | v0.0.0, dated 2015-06-24 103 | Initial version. 104 | (commit 16517a2) 105 | -------------------------------------------------------------------------------- /pd-lib-builder/Makefile.pdlibbuilder: -------------------------------------------------------------------------------- 1 | # Makefile.pdlibbuilder dated 2019-12-21 2 | version = 0.6.0 3 | 4 | # Helper makefile for Pure Data external libraries. 5 | # Written by Katja Vetter March-June 2015 for the public domain. No warranties. 6 | # Inspired by Hans Christoph Steiner's Makefile Template and Stephan Beal's 7 | # ShakeNMake. 8 | # 9 | # Grab the newest version of Makefile.pdlibbuilder from 10 | # https://github.com/pure-data/pd-lib-builder/ 11 | # 12 | # GNU make version >= 3.81 required. 13 | # 14 | # 15 | #=== characteristics =========================================================== 16 | # 17 | # 18 | # - defines build settings based on autodetected OS and architecture 19 | # - defines rules to build Pd class- or lib executables from C or C++ sources 20 | # - defines rules for libdir installation 21 | # - defines convenience targets for developer and user 22 | # - evaluates implicit dependencies for non-clean builds 23 | # 24 | # 25 | #=== basic usage =============================================================== 26 | # 27 | # 28 | # In your Makefile, define your Pd lib name and class files, and include 29 | # Makefile.pdlibbuilder at the end of the Makefile. Like so: 30 | # 31 | # ________________________________________________________________________ 32 | # 33 | # # Makefile for mylib 34 | # 35 | # lib.name = mylib 36 | # 37 | # class.sources = myclass1.c myclass2.c 38 | # 39 | # datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt 40 | # 41 | # include Makefile.pdlibbuilder 42 | # ________________________________________________________________________ 43 | # 44 | # 45 | # For files in class.sources it is assumed that class basename == source file 46 | # basename. The default target builds all classes as individual executables 47 | # with Pd's default extension for the platform. For anything more than the 48 | # most basic usage, continue reading. 49 | # 50 | # 51 | #=== list of Makefile.pdlibbuilder API variables =============================== 52 | # 53 | # 54 | # Variables available for definition in your library Makefile: 55 | # 56 | # - lib.name 57 | # - lib.setup.sources 58 | # - class.sources 59 | # - common.sources 60 | # - shared.sources 61 | # - .class.sources 62 | # - .class.ldflags 63 | # - .class.ldlibs 64 | # - cflags 65 | # - ldflags 66 | # - ldlibs 67 | # - datafiles 68 | # - datadirs 69 | # - makefiles 70 | # - makefiledirs 71 | # - externalsdir 72 | # 73 | # Optional multiline defines evaluated per operating system: 74 | # 75 | # - forLinux 76 | # - forDarwin 77 | # - forWindows 78 | # 79 | # Variables available for your makefile or make command line: 80 | # 81 | # - make-lib-executable 82 | # - suppress-wunused 83 | # 84 | # Path variables for make command line or environment: 85 | # 86 | # - PDDIR 87 | # - PDINCLUDEDIR 88 | # - PDBINDIR 89 | # - PDLIBDIR 90 | # 91 | # Standard make variables for make command line or environment: 92 | # 93 | # - CPPFLAGS 94 | # - CFLAGS 95 | # - LDFLAGS 96 | # - CC 97 | # - CXX 98 | # - INSTALL 99 | # - STRIP 100 | # - DESTDIR 101 | # 102 | # Optional user variables for make command line or environment: 103 | # 104 | # - PLATFORM 105 | # 106 | # Deprecated path variables: 107 | # 108 | # - pdincludepath 109 | # - pdbinpath 110 | # - objectsdir 111 | # 112 | # 113 | #=== descriptions of Makefile.pdlibbuilder API variables ======================= 114 | # 115 | # 116 | # lib.name: 117 | # Name of the library directory as it will be installed / distributed. Also the 118 | # name of the lib executable in the case where all classes are linked into 119 | # a single binary. 120 | # 121 | # lib.setup.sources: 122 | # Source file(s) (C or C++) which must be compiled only when linking all classes 123 | # into a single lib binary. 124 | # 125 | # class.sources: 126 | # All sources files (C or C++) for which the condition holds that 127 | # class name == source file basename. 128 | # 129 | # .class.sources: 130 | # Source file(s) (C or C++) specific to class . Use this for 131 | # multiple-source classes or when class name != source file basename. 132 | # 133 | # common.sources: 134 | # Source file(s) which must be statically linked to each class in the library. 135 | # 136 | # shared.sources: 137 | # Source file(s) (C or C++) to build a shared dynamic link lib, to be linked 138 | # with all class executables. 139 | # 140 | # cflags, ldflags, ldlibs: 141 | # Define cflags (preprocessor&compiler), ldflags (linker) and ldlibs (dynamic 142 | # link libs) for the whole library. These flags are added to platform-specific 143 | # flags defined by Makefile.pdlibbuilder. 144 | # 145 | # .class.ldflags and .class.ldlibs: 146 | # Define ldflags resp. ldlibs specific to class . These flags are 147 | # added to platform-specific flags defined by Makefile.pdlibbuilder, and flags 148 | # defined in your Makefile for the whole library. Note: cflags can not be 149 | # defined per class in the current implementation. 150 | # 151 | # datafiles and datadirs: 152 | # All extra files you want to include in binary distributions of the 153 | # library: abstractions and help patches, example patches, meta patch, readme 154 | # and license texts, manuals, sound files, etcetera. Use 'datafiles' for all 155 | # files that should go into your lib rootdir and 'datadirs' for complete 156 | # directories you want to copy from source to distribution. 157 | # 158 | # forLinux, forDarwin, forWindows: 159 | # Shorthand for 'variable definitions for Linux only' etc. Use like: 160 | # define forLinux 161 | # cflags += -DLINUX 162 | # class.sources += linuxthing.c 163 | # endef 164 | # 165 | # makefiles and makefiledirs: 166 | # Extra makefiles or directories with makefiles that should be made in sub-make 167 | # processes. 168 | # 169 | # make-lib-executable: 170 | # When this variable is defined 'yes' in your makefile or as command argument, 171 | # Makefile.pdlibbuilder will try to build all classes into a single library 172 | # executable (but it will force exit if lib.setup.sources is undefined). 173 | # If your makefile defines 'make-lib-executable=yes' as the library default, 174 | # this can still be overridden with 'make-lib-executable=no' as command argument 175 | # to build individual class executables (the Makefile.pdlibbuilder default.) 176 | # 177 | # suppress-wunused: 178 | # When this variable is defined ('yes' or any other value), -Wunused-variable, 179 | # -Wunused-parameter, -Wunused-value and -Wunused-function are suppressed, 180 | # but the other warnings from -Wall are retained. 181 | # 182 | # PDDIR: 183 | # Root directory of 'portable' pd package. When defined, PDINCLUDEDIR and 184 | # PDBINDIR will be evaluated as $(PDDIR)/src and $(PDDIR)/bin. 185 | # 186 | # PDINCLUDEDIR: 187 | # Directory where Pd API m_pd.h should be found, and other Pd header files. 188 | # Overrides the default search path. 189 | # 190 | # PDBINDIR: 191 | # Directory where pd.dll should be found for linking (Windows only). Overrides 192 | # the default search path. 193 | # 194 | # PDLIBDIR: 195 | # Root directory for installation of Pd library directories. Overrides the 196 | # default install location. 197 | # 198 | # DESTDIR: 199 | # Prepended path component for staged install. 200 | # 201 | # PLATFORM: 202 | # Target platform for cross compilation in the form of GNU triplet: 203 | # cpu-vendor-os. Example: x86_64-w64-mingw32. This specifies the tool chain that 204 | # pdlibbuilder will use, if installed and locatable. System and architecture 205 | # will then be autodefined accordingly. In most cases no other variables need to 206 | # be overridden. 207 | # 208 | # CPPFLAGS: 209 | # Preprocessor flags which are not strictly required for building. 210 | # 211 | # CFLAGS: 212 | # Compiler flags which are not strictly required for building. Compiler flags 213 | # defined by Makefile.pdlibbuilder for warning, optimization and architecture 214 | # specification are overriden by CFLAGS. 215 | # 216 | # LDFLAGS: 217 | # Linker flags which are not strictly required for building. Linker flags 218 | # defined by Makefile.pdlibbuilder for architecture specification are overriden 219 | # by LDFLAGS. 220 | # 221 | # CC and CXX: 222 | # C and C++ compiler programs as defined in your build environment. 223 | # 224 | # INSTALL 225 | # Definition of install program. 226 | # 227 | # STRIP 228 | # Name of strip program. Default 'strip' can be overridden in cross compilation 229 | # environments. 230 | # 231 | # objectsdir: 232 | # Root directory for installation of Pd library directories, like PDLIBDIR but 233 | # not overridable by environment. Supported for compatibility with pd-extended 234 | # central makefile, but deprecated otherwise. 235 | # 236 | # pdincludepath, pdbinpath: 237 | # As PDINCLUDEDIR and PDBINDIR but not overridable by environment. Deprecated 238 | # as user variables. 239 | # 240 | # 241 | #=== paths ===================================================================== 242 | # 243 | # 244 | # Source files in directories other than current working directory must be 245 | # prefixed with their relative path. Do not rely on VPATH or vpath. 246 | # Object (.o) files are built in the directory of their source files. 247 | # Executables are built in current working directory. 248 | # 249 | # Default search path for m_pd.h and other API header files is platform 250 | # dependent, and overridable by PDINCLUDEDIR: 251 | # 252 | # Linux: /usr/include/pd 253 | # 254 | # OSX: /Applications/Pd*.app/Contents/Resources/src 255 | # 256 | # Windows: %PROGRAMFILES%/Pd/src 257 | # %PROGRAMFILES(X86)%/Pd/src (32 bit builds on 64 bit Windows) 258 | # 259 | # Default search path for binary pd.dll (Windows), overridable by PDBINDIR 260 | # 261 | # %PROGRAMFILES%/Pd/bin 262 | # %PROGRAMFILES(X86)%/Pd/bin (32 bit builds on 64 bit Windows) 263 | # 264 | # Default location to install pd libraries is platform dependent, and 265 | # overridable by PDLIBDIR: 266 | # 267 | # Linux: /usr/local/lib/pd-externals 268 | # OSX: ~/Library/Pd 269 | # Windows: %APPDATA%/Pd 270 | # 271 | # https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files 272 | # The rationale for not installing to ~/pd-externals by default on Linux 273 | # is that some people share the home dir between 32 and 64 bit installations. 274 | # 275 | # 276 | #=== targets =================================================================== 277 | # 278 | # 279 | # all: build $(executables) plus optional post target 280 | # post: target to build after $(executables) 281 | # alldebug: build all with -g option turned on for debug symbols 282 | # : force clean build of an individual class 283 | # .pre: make preprocessor output file in current working directory 284 | # .lst: make asm/source output file in current working directory 285 | # 286 | # install: install executables and data files 287 | # clean: remove build products from source tree 288 | # 289 | # help: print help text 290 | # vars: print makefile variables 291 | # allvars: print all variables 292 | # depend: print generated prerequisites 293 | # dumpmachine: print compiler output of option '-dumpmachine' 294 | # coffee: dummy target 295 | # 296 | # Variable $(executables) expands to class executables plus optional shared lib, 297 | # or alternatively to single lib executable when make-lib-executable=true. 298 | # Targets pre and post can be defined by library makefile. Make sure to include 299 | # Makefile.pdlibbuilder first so default target all will not be redefined. 300 | # 301 | # 302 | #=== Pd-extended libdir concept ================================================ 303 | # 304 | # 305 | # For libdir layout as conceived by Hans-Christoph Steiner, see: 306 | # 307 | # https://puredata.info/docs/developer/Libdir 308 | # 309 | # Files README.txt, LICENSE.txt and -meta.pd are part of the libdir 310 | # convention. Help patches for each class and abstraction are supposed to be 311 | # available. Makefile.pdlibbuilder does not force the presence of these files 312 | # however. It does not automatically include such files in libdir installations. 313 | # Data files you want to include in distributions must be defined explicitly in 314 | # your Makefile. 315 | # 316 | # 317 | #=== Makefile.pdlibbuilder syntax conventions ================================== 318 | # 319 | # 320 | # Makefile.pdlibbuilder variable names are lower case. Default make variables, 321 | # environment variables, and standard user variables (CC, CXX, CFLAGS, DESTDIR) 322 | # are upper case. Use target 'allvars' to print all variables and their values. 323 | # 324 | # 'Fields' in data variables are separated by dots, like in 'foo.class.sources'. 325 | # Words in variables expressing a function or command are separated by dashes, 326 | # like in 'make-lib-executable'. 327 | # 328 | # 329 | #=== useful make options ======================================================= 330 | # 331 | # 332 | # Use 'make -d ' to print debug details of the make process. 333 | # Use 'make -p ' to print make's database. 334 | # 335 | # 336 | #=== TODO ====================================================================== 337 | # 338 | # 339 | # - decide whether to use -static-libgcc or shared dll in MinGW 340 | # - cygwin support 341 | # - android support 342 | # - figure out how to handle '$' in filenames 343 | # - add makefile template targets dpkg-source dist libdir distclean tags? 344 | # 345 | # 346 | #=== end of documentation sections ============================================= 347 | # 348 | # 349 | ################################################################################ 350 | ################################################################################ 351 | ################################################################################ 352 | 353 | 354 | # GNU make version 3.81 (2006) or higher is required because of the following: 355 | # - function 'info' 356 | # - variable '.DEFAULT_GOAL' 357 | 358 | # force exit when make version is < 3.81 359 | ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))), 3.81) 360 | $(error GNU make version 3.81 or higher is required) 361 | endif 362 | 363 | # Relative path to externals root dir in multi-lib source tree like 364 | # pd-extended SVN. Default is parent of current working directory. May be 365 | # defined differently in including makefile. 366 | externalsdir ?= .. 367 | 368 | # variable you can use to check if Makefile.pdlibbuilder is already included 369 | Makefile.pdlibbuilder = true 370 | 371 | 372 | ################################################################################ 373 | ### variables: library name and version ######################################## 374 | ################################################################################ 375 | 376 | 377 | # strip possibles spaces from lib.name, they mess up calculated file names 378 | lib.name := $(strip $(lib.name)) 379 | 380 | # if meta file exists, check library version 381 | metafile := $(wildcard $(lib.name)-meta.pd) 382 | 383 | ifdef metafile 384 | lib.version := $(shell sed -n \ 385 | 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' \ 386 | $(metafile)) 387 | endif 388 | 389 | 390 | ################################################################################ 391 | ### variables: files ########################################################### 392 | ################################################################################ 393 | 394 | 395 | #=== sources =================================================================== 396 | 397 | 398 | # (re)define .class.sources using file names in class.sources 399 | 400 | define add-class-source 401 | $(notdir $(basename $v)).class.sources += $v 402 | endef 403 | 404 | $(foreach v, $(class.sources), $(eval $(add-class-source))) 405 | 406 | # derive class names from .class.sources variables 407 | sourcevariables := $(filter %.class.sources, $(.VARIABLES)) 408 | classes := $(basename $(basename $(sourcevariables))) 409 | 410 | # accumulate all source files specified in makefile 411 | classes.sources := $(sort $(foreach v, $(sourcevariables), $($v))) 412 | all.sources := $(classes.sources) $(lib.setup.sources) \ 413 | $(shared.sources) $(common.sources) 414 | 415 | 416 | #=== object files ============================================================== 417 | 418 | 419 | # construct object filenames from all C and C++ source file names 420 | classes.objects := $(addsuffix .o, $(basename $(classes.sources))) 421 | common.objects := $(addsuffix .o, $(basename $(common.sources))) 422 | shared.objects := $(addsuffix .o, $(basename $(shared.sources))) 423 | lib.setup.objects := $(addsuffix .o, $(basename $(lib.setup.sources))) 424 | all.objects = $(classes.objects) $(common.objects) $(shared.objects) \ 425 | $(lib.setup.objects) 426 | 427 | 428 | #=== executables =============================================================== 429 | 430 | 431 | # use recursive variables here because executable extension is not yet known 432 | 433 | # construct class executable names from class names 434 | classes.executables = $(addsuffix .$(extension), $(classes)) 435 | 436 | # construct shared lib executable name if shared sources are defined 437 | ifdef shared.sources 438 | shared.lib = lib$(lib.name).$(shared.extension) 439 | else 440 | shared.lib = 441 | endif 442 | 443 | 444 | ################################################################################ 445 | ### target platform detection ################################################## 446 | ################################################################################ 447 | 448 | 449 | #=== target platform =========================================================== 450 | 451 | 452 | # PLATFORM: optional user variable to define target platform for cross 453 | # compilation. Redefine build tools accordingly. PLATFORM should match 454 | # the exact target prefix of tools present in $PATH, like x86_64-w64-mingw32, 455 | # x86_64-apple-darwin12 etc. Tool definitions are exported to ensure submakes 456 | # will get the same. 457 | 458 | ifneq ($(PLATFORM),) 459 | ifneq ($(findstring darwin, $(PLATFORM)),) 460 | export CC = $(PLATFORM)-cc 461 | export CXX = $(PLATFORM)-c++ 462 | export CPP = $(PLATFORM)-cc 463 | else 464 | export CC = $(PLATFORM)-gcc 465 | export CXX = $(PLATFORM)-g++ 466 | export CPP = $(PLATFORM)-cpp 467 | endif 468 | STRIP = $(PLATFORM)-strip 469 | endif 470 | 471 | # Let (native or cross-) compiler report target triplet and isolate individual 472 | # words therein to facilitate later processing. 473 | target.triplet := $(subst -, ,$(shell $(CC) -dumpmachine)) 474 | 475 | 476 | #=== operating system ========================================================== 477 | 478 | 479 | # The following systems are defined: Linux, Darwin, Windows. GNU and 480 | # GNU/kFreeBSD are treated as Linux to get the same options. 481 | 482 | ifneq ($(filter linux gnu% kfreebsd, $(target.triplet)),) 483 | system = Linux 484 | endif 485 | 486 | ifneq ($(filter darwin%, $(target.triplet)),) 487 | system = Darwin 488 | endif 489 | 490 | ifneq ($(filter mingw% cygwin%, $(target.triplet)),) 491 | system = Windows 492 | endif 493 | 494 | # evaluate possible system-specific multiline defines from library makefile 495 | $(eval $(for$(system))) 496 | 497 | 498 | # TODO: Cygwin, Android 499 | 500 | 501 | #=== architecture ============================================================== 502 | 503 | 504 | # The following CPU names can be processed by pdlibbuilder: 505 | # i*86 Intel 32 bit 506 | # x86_64 Intel 64 bit 507 | # arm ARM 32 bit 508 | # aarch64 ARM 64 bit 509 | 510 | target.arch := $(firstword $(target.triplet)) 511 | 512 | 513 | ################################################################################ 514 | ### variables per platform ##################################################### 515 | ################################################################################ 516 | 517 | 518 | #=== flags per architecture ==================================================== 519 | 520 | 521 | # Set architecture-dependent cflags, mainly for Linux. For Mac and Windows, 522 | # arch.c.flags are overriden below. To see gcc's default architecture flags: 523 | # $ gcc -Q --help=target 524 | 525 | # ARMv6: Raspberry Pi 1st gen, not detectable from target.arch 526 | ifeq ($(shell uname), armv6l) 527 | arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard 528 | 529 | # ARMv7: Beagle, Udoo, RPi2 etc. 530 | else ifeq ($(target.arch), arm) 531 | arch.c.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard 532 | 533 | # ARMv8 64 bit, not tested yet 534 | else ifeq ($(target.arch), aarch64) 535 | arch.c.flags = -mcpu=cortex-a53 536 | 537 | # Intel 32 bit, build with SSE and SSE2 instructions 538 | else ifneq ($(filter i%86, $(target.arch)),) 539 | arch.c.flags = -march=pentium4 -mfpmath=sse -msse -msse2 540 | 541 | # Intel/AMD 64 bit, build with SSE, SSE2 and SSE3 instructions 542 | else ifeq ($(target.arch), x86_64) 543 | arch.c.flags = -march=core2 -mfpmath=sse -msse -msse2 -msse3 544 | 545 | # if none of the above architectures detected 546 | else 547 | arch.c.flags = 548 | endif 549 | 550 | 551 | #=== flags and paths for Linux ================================================= 552 | 553 | 554 | ifeq ($(system), Linux) 555 | prefix = /usr/local 556 | libdir := $(prefix)/lib 557 | pkglibdir = $(libdir)/pd-externals 558 | pdincludepath := $(wildcard /usr/include/pd) 559 | extension = pd_linux 560 | cpp.flags := -DUNIX 561 | c.flags := -fPIC 562 | c.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags 563 | c.ldlibs := -lc -lm 564 | cxx.flags := -fPIC -fcheck-new 565 | cxx.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags 566 | cxx.ldlibs := -lc -lm -lstdc++ 567 | shared.extension = so 568 | shared.ldflags := -rdynamic -fPIC -shared -Wl,-soname,$(shared.lib) 569 | endif 570 | 571 | 572 | #=== flags and paths for Darwin ================================================ 573 | 574 | 575 | # LLVM-clang doesn't support -fcheck-new, therefore this flag is only used when 576 | # compiling with g++. 577 | 578 | ifeq ($(system), Darwin) 579 | pkglibdir = $(HOME)/Library/Pd 580 | pdincludepath := $(firstword $(wildcard \ 581 | /Applications/Pd*.app/Contents/Resources/src)) 582 | extension = pd_darwin 583 | cpp.flags := -DUNIX -DMACOSX -I /sw/include 584 | c.flags := 585 | c.ldflags := -undefined suppress -flat_namespace -bundle 586 | c.ldlibs := -lc 587 | cxx.ldflags := -undefined suppress -flat_namespace -bundle 588 | cxx.ldlibs := -lc 589 | shared.extension = dylib 590 | shared.ldflags = -dynamiclib -undefined dynamic_lookup \ 591 | -install_name @loader_path/$(shared.lib) \ 592 | -compatibility_version 1 -current_version 1.0 593 | ifneq ($(filter %g++, $(CXX)),) 594 | cxx.flags := -fcheck-new 595 | endif 596 | ifeq ($(extension), d_fat) 597 | arch := i386 x86_64 598 | else 599 | arch := $(target.arch) 600 | endif 601 | ifneq ($(filter -mmacosx-version-min=%, $(cflags)),) 602 | version.flag := $(filter -mmacosx-version-min=%, $(cflags)) 603 | else 604 | version.flag = -mmacosx-version-min=10.6 605 | endif 606 | arch.c.flags := $(addprefix -arch , $(arch)) $(version.flag) 607 | arch.ld.flags := $(arch.c.flags) 608 | endif 609 | 610 | 611 | #=== flags and paths for Windows =============================================== 612 | 613 | 614 | # Standard paths on Windows contain spaces, and GNU make functions treat such 615 | # paths as lists, with unintended effects. Therefore we must use shell function 616 | # ls instead of make's wildcard when probing for a path, and use double quotes 617 | # when specifying a path in a command argument. 618 | 619 | # Default paths in Mingw / Mingw-w64 environments. 'PROGRAMFILES' is standard 620 | # location for builds with native architecture, 'ProgramFiles(x86)' for i686 621 | # builds on x86_64 Windows (detection method by Lucas Cordiviola). Curly braces 622 | # required because of parentheses in variable name. 623 | ifeq ($(system), Windows) 624 | pkglibdir := $(APPDATA)/Pd 625 | ifeq ($(target.arch), i686) 626 | programfiles := ${ProgramFiles(x86)} 627 | else 628 | programfiles := $(PROGRAMFILES) 629 | endif 630 | pdbinpath := $(programfiles)/Pd/bin 631 | pdincludepath := $(programfiles)/Pd/src 632 | endif 633 | 634 | # Store default path to pd.dll in PDBINDIR if the latter is not user-defined. 635 | # For include path this is done in the platform-independent paths section below, 636 | # but for PDBINDIR it is done here so ld flags can be evaluated as immediate 637 | # variables. 638 | ifeq ($(system), Windows) 639 | ifdef PDDIR 640 | PDBINDIR := $(PDDIR)/bin 641 | endif 642 | PDBINDIR ?= $(pdbinpath) 643 | endif 644 | 645 | # TODO: decide whether -mms-bitfields should be specified. 646 | ifeq ($(system), Windows) 647 | cpp.flags := -DMSW -DNT 648 | ifeq ($(target.arch), i686) 649 | arch.c.flags := -march=pentium4 -msse -msse2 -mfpmath=sse 650 | else ifeq ($(target.arch), x86_64) 651 | cpp.flags := -DMSW -DNT -DPD_LONGINTTYPE=__int64 652 | arch.c.flags := -march=core2 -msse -msse2 -msse3 -mfpmath=sse 653 | else 654 | arch.c.flags = 655 | endif 656 | extension = dll 657 | c.flags := 658 | c.ldflags := -static-libgcc -shared \ 659 | -Wl,--enable-auto-import "$(PDBINDIR)/pd.dll" 660 | c.ldlibs := 661 | cxx.flags := -fcheck-new 662 | cxx.ldflags := -static-libgcc -static-libstdc++ -shared \ 663 | -Wl,--enable-auto-import "$(PDBINDIR)/pd.dll" 664 | cxx.ldlibs := 665 | shared.extension = dll 666 | shared.ldflags := -static-libgcc -shared "$(PDBINDIR)/pd.dll" 667 | stripflags = --strip-all 668 | endif 669 | 670 | 671 | #=== paths ===================================================================== 672 | 673 | 674 | # Platform-dependent default paths are specified above, but overridable. 675 | # Path variables in upper case can be defined as make command argument or in the 676 | # environment. Variable 'objectsdir' is supported for compatibility with 677 | # the build system that pd-l2ork has inherited from pd-extended. 678 | 679 | PDINCLUDEDIR ?= $(pdincludepath) 680 | PDLIBDIR ?= $(firstword $(objectsdir) $(pkglibdir)) 681 | 682 | ifdef PDDIR 683 | PDINCLUDEDIR := $(wildcard $(PDDIR)/src) 684 | endif 685 | 686 | # base path where all components of the lib will be installed by default 687 | installpath := $(DESTDIR)$(PDLIBDIR)/$(lib.name) 688 | 689 | # check if include path contains spaces (as is often the case on Windows) 690 | # if so, store the path so we can later do checks with it 691 | pdincludepathwithspaces := $(if $(word 2, $(PDINCLUDEDIR)), $(PDINCLUDEDIR)) 692 | 693 | 694 | #=== accumulated build flags =================================================== 695 | 696 | 697 | # From GNU make docs: 'Users expect to be able to specify CFLAGS freely 698 | # themselves.' So we use CFLAGS to define options which are not strictly 699 | # required for compilation: optimizations, architecture specifications, and 700 | # warnings. CFLAGS can be safely overriden using a make command argument. 701 | # Variables cflags, ldflags and ldlibs may be defined in including makefile. 702 | 703 | optimization.flags = -O3 -ffast-math -funroll-loops -fomit-frame-pointer 704 | warn.flags = -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing 705 | 706 | # suppress -Wunused-variable & Co if you don't want to clutter a build log 707 | ifdef suppress-wunused 708 | warn.flags += $(addprefix -Wno-unused-, function parameter value variable) 709 | endif 710 | 711 | CFLAGS = $(warn.flags) $(optimization.flags) $(arch.c.flags) 712 | 713 | # preprocessor flags 714 | cpp.flags := -DPD -I "$(PDINCLUDEDIR)" $(cpp.flags) $(CPPFLAGS) 715 | 716 | # flags for dependency checking (cflags from makefile may define -I options) 717 | depcheck.flags := $(cpp.flags) $(cflags) 718 | 719 | # architecture specifications for linker are overridable by LDFLAGS 720 | LDFLAGS := $(arch.ld.flags) 721 | 722 | # now add the same ld flags to shared dynamic lib 723 | shared.ldflags := $(shared.ldflags) $(LDFLAGS) 724 | 725 | # accumulated flags for C compiler / linker 726 | c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS) 727 | c.ldflags := $(c.ldflags) $(ldflags) $(LDFLAGS) 728 | c.ldlibs := $(c.ldlibs) $(ldlibs) 729 | 730 | # accumulated flags for C++ compiler / linker 731 | cxx.flags := $(cpp.flags) $(cxx.flags) $(cflags) $(CFLAGS) 732 | cxx.ldflags := $(cxx.ldflags) $(ldflags) $(LDFLAGS) 733 | cxx.ldlibs := $(cxx.ldlibs) $(ldlibs) 734 | 735 | 736 | ################################################################################ 737 | ### variables: tools ########################################################### 738 | ################################################################################ 739 | 740 | 741 | # aliases so we can later define 'compile-$1' and set 'c' or 'cxx' as argument 742 | compile-c := $(CC) 743 | compile-cxx := $(CXX) 744 | 745 | 746 | ################################################################################ 747 | ### checks ##################################################################### 748 | ################################################################################ 749 | 750 | 751 | # At this point most variables are defined. Now do some checks and info's 752 | # before rules begin. 753 | 754 | # print Makefile.pdlibbuilder version before possible termination 755 | $(info ++++ info: using Makefile.pdlibbuilder version $(version)) 756 | 757 | # Terminate if target triplet remained empty, to avoid all sorts of confusing 758 | # scenarios and spurious bugs. 759 | ifeq ($(target.triplet),) 760 | $(error Command "$(CC) -dumpmachine" did not return a target triplet, \ 761 | needed for a build. \ 762 | Is compiler "$(CC)" installed in your PATH? ($(PATH)). \ 763 | Does compiler "$(CC)" support option "-dumpmachine"?) 764 | endif 765 | 766 | # 'forward declaration' of default target, needed to do checks 767 | all: 768 | 769 | # To avoid unpredictable results, make sure the default target is not redefined 770 | # by including makefile. 771 | ifneq ($(.DEFAULT_GOAL), all) 772 | $(error Default target must be 'all'.) 773 | endif 774 | 775 | # find out which target(s) will be made 776 | ifdef MAKECMDGOALS 777 | goals := $(MAKECMDGOALS) 778 | else 779 | goals := all 780 | endif 781 | 782 | # store path to Pd API m_pd.h if it is found 783 | ifdef PDINCLUDEDIR 784 | mpdh := $(shell ls "$(PDINCLUDEDIR)/m_pd.h") 785 | endif 786 | 787 | # store path to pd.dll; if not found, ls will give a useful error 788 | ifeq ($(system), Windows) 789 | pddll := $(shell ls "$(PDBINDIR)/pd.dll") 790 | endif 791 | 792 | # when making target all, check if m_pd.h is found and print info about it 793 | ifeq ($(goals), all) 794 | $(if $(mpdh), \ 795 | $(info ++++ info: using Pd API $(mpdh)), \ 796 | $(warning Where is Pd API m_pd.h? Do 'make help' for info.)) 797 | endif 798 | 799 | # print target info 800 | $(info ++++ info: making target $(goals) $(if $(lib.name),in lib $(lib.name))) 801 | 802 | # when installing, print installpath info 803 | $(if $(filter install install-lib, $(goals)), $(info ++++ info: \ 804 | installpath is '$(installpath)')) 805 | 806 | 807 | #=== define executables ======================================================== 808 | 809 | 810 | # By default we build class executables, and optionally a shared dynamic link 811 | # lib. When make-lib-executable=yes we build all classes into a single lib 812 | # executable, on the condition that variable lib.setup.sources is defined. 813 | 814 | ifeq ($(make-lib-executable),yes) 815 | $(if $(lib.setup.sources), ,\ 816 | $(error Can not build library blob because lib.setup.sources is undefined)) 817 | executables := $(lib.name).$(extension) 818 | else 819 | executables := $(classes.executables) $(shared.lib) 820 | endif 821 | 822 | 823 | ################################################################################ 824 | ### rules: special targets ##################################################### 825 | ################################################################################ 826 | 827 | 828 | # Disable built-in rules. If some target can't be built with the specified 829 | # rules, it should not be built at all. 830 | MAKEFLAGS += --no-builtin-rules 831 | 832 | .PRECIOUS: 833 | .SUFFIXES: 834 | .PHONY: all post build-lib \ 835 | $(classes) $(makefiledirs) $(makefiles) \ 836 | install install-executables install-datafiles install-datadirs \ 837 | force clean vars allvars depend help 838 | 839 | 840 | ################################################################################ 841 | ### rules: build targets ####################################################### 842 | ################################################################################ 843 | 844 | 845 | # Target all forces the build of targets [$(executables) post] in 846 | # deterministic order. Target $(executables) builds class executables plus 847 | # optional shared lib or alternatively a single lib executable when 848 | # make-lib-executable=true. Target post is optionally defined by 849 | # library makefile. 850 | 851 | all: post 852 | post: $(executables) 853 | 854 | all: 855 | $(info ++++info: target all in lib $(lib.name) completed) 856 | 857 | # build all with -g option turned on for debug symbols 858 | alldebug: c.flags += -g 859 | alldebug: cxx.flags += -g 860 | alldebug: all 861 | 862 | 863 | #=== class executable ========================================================== 864 | 865 | 866 | # recipe for linking objects in class executable 867 | # argument $1 = compiler type (c or cxx) 868 | # argument $2 = class basename 869 | define link-class 870 | $(compile-$1) \ 871 | $($1.ldflags) $($2.class.ldflags) \ 872 | -o $2.$(extension) \ 873 | $(addsuffix .o, $(basename $($2.class.sources))) \ 874 | $(addsuffix .o, $(basename $(common.sources))) \ 875 | $($1.ldlibs) $($2.class.ldlibs) $(shared.lib) 876 | endef 877 | 878 | # general rule for linking object files in class executable 879 | %.$(extension): $(shared.lib) 880 | $(info ++++ info: linking objects in $@ for lib $(lib.name)) 881 | $(if $(filter %.cc %.cpp, $($*.class.sources)), \ 882 | $(call link-class,cxx,$*), \ 883 | $(call link-class,c,$*)) 884 | 885 | 886 | #=== library blob ============================================================== 887 | 888 | 889 | # build all classes into single executable 890 | build-lib: $(lib.name).$(extension) 891 | $(info ++++ info: library blob $(lib.name).$(extension) completed) 892 | 893 | # recipe for linking objects in lib executable 894 | # argument $1 = compiler type (c or cxx) 895 | define link-lib 896 | $(compile-$1) \ 897 | $($1.ldflags) $(lib.ldflags) \ 898 | -o $(lib.name).$(extension) $(all.objects) \ 899 | $($1.ldlibs) $(lib.ldlibs) 900 | endef 901 | 902 | # rule for linking objects in lib executable 903 | # declared conditionally to avoid name clashes 904 | ifeq ($(make-lib-executable),yes) 905 | $(lib.name).$(extension): $(all.objects) 906 | $(if $(filter %.cc %.cpp, $(all.sources)), \ 907 | $(call link-lib,cxx), \ 908 | $(call link-lib,c)) 909 | endif 910 | 911 | 912 | #=== shared dynamic lib ======================================================== 913 | 914 | 915 | # recipe for linking objects in shared executable 916 | # argument $1 = compiler type (c or cxx) 917 | define link-shared 918 | $(compile-$1) \ 919 | $(shared.ldflags) \ 920 | -o lib$(lib.name).$(shared.extension) $(shared.objects) \ 921 | $($1.ldlibs) $(shared.ldlibs) 922 | endef 923 | 924 | # rule for linking objects in shared executable 925 | # build recipe is in macro 'link-shared' 926 | lib$(lib.name).$(shared.extension): $(shared.objects) 927 | $(info ++++ info: linking objects in shared lib $@) 928 | $(if $(filter %.cc %.cpp, $(shared.sources)), \ 929 | $(call link-shared,cxx), \ 930 | $(call link-shared,c)) 931 | 932 | 933 | #=== object files ============================================================== 934 | 935 | 936 | # recipe to make .o file from source 937 | # argument $1 is compiler type (c or cxx) 938 | define make-object-file 939 | $(info ++++ info: making $@ in lib $(lib.name)) 940 | $(compile-$1) \ 941 | $($1.flags) \ 942 | -o $@ -c $< 943 | endef 944 | 945 | # Three rules to create .o files. These are double colon 'terminal' rules, 946 | # meaning they are the last in a rules chain. 947 | 948 | %.o:: %.c 949 | $(call make-object-file,c) 950 | 951 | %.o:: %.cc 952 | $(call make-object-file,cxx) 953 | 954 | %.o:: %.cpp 955 | $(call make-object-file,cxx) 956 | 957 | 958 | #=== explicit prerequisites for class executables ============================== 959 | 960 | 961 | # For class executables, prerequisite rules are declared in run time. Target 962 | # 'depend' prints these rules for debugging purposes. 963 | 964 | # declare explicit prerequisites rule like 'class: class.extension' 965 | # argument $v is class basename 966 | define declare-class-target 967 | $v: $v.$(extension) 968 | endef 969 | 970 | # declare explicit prerequisites rule like 'class.extension: object1.o object2.o' 971 | # argument $v is class basename 972 | define declare-class-executable-target 973 | $v.$(extension): $(addsuffix .o, $(basename $($v.class.sources))) \ 974 | $(addsuffix .o, $(basename $(common.sources))) 975 | endef 976 | 977 | # evaluate explicit prerequisite rules for all classes 978 | $(foreach v, $(classes), $(eval $(declare-class-target))) 979 | $(foreach v, $(classes), $(eval $(declare-class-executable-target))) 980 | 981 | 982 | #=== implicit prerequisites for class executables ============================== 983 | 984 | 985 | # Evaluating implicit prerequisites (header files) with help from the 986 | # preprocessor is 'expensive' so this is done conditionally and selectively. 987 | # Note that it is also possible to trigger a build via install targets, in 988 | # which case implicit prerequisites are not checked. 989 | 990 | # When the Pd include path contains spaces it will mess up the implicit 991 | # prerequisites rules. 992 | disable-dependency-tracking := $(strip $(pdincludepathwithspaces)) 993 | 994 | ifndef disable-dependency-tracking 995 | must-build-everything := $(filter all, $(goals)) 996 | must-build-class := $(filter $(classes), $(goals)) 997 | must-build-sources := $(foreach v, $(must-build-class), $($v.class.sources)) 998 | endif 999 | 1000 | # declare implicit prerequisites rule like 'object.o: header1.h header2.h ...' 1001 | # argument $1 is input source file(s) 1002 | # dir is explicitly added because option -MM strips it by default 1003 | define declare-object-target 1004 | $(dir $1)$(filter %.o: %.h, $(shell $(CPP) $(depcheck.flags) -MM $1)) $(MAKEFILE_LIST) 1005 | endef 1006 | 1007 | # evaluate implicit prerequisite rules when rebuilding everything 1008 | ifdef must-build-everything 1009 | $(if $(wildcard $(all.objects)), \ 1010 | $(info ++++ info: evaluating implicit prerequisites in lib $(lib.name).....) \ 1011 | $(foreach v, $(all.sources), $(eval $(call declare-object-target, $v)))) 1012 | endif 1013 | 1014 | # evaluate implicit prerequisite rules when selectively building classes 1015 | ifdef must-build-class 1016 | $(foreach v, $(must-build-sources), \ 1017 | $(eval $(call declare-object-target, $v))) 1018 | $(foreach v, $(shared.sources), \ 1019 | $(eval $(call declare-object-target, $v))) 1020 | endif 1021 | 1022 | 1023 | ################################################################################ 1024 | ### rules: preprocessor and assembly files ##################################### 1025 | ################################################################################ 1026 | 1027 | 1028 | # Preprocessor and assembly output files for bug tracing etc. They are not part 1029 | # of the build processes for executables. By default these files are created in 1030 | # the current working directory. Dependency tracking is not performed, the build 1031 | # is forced instead to make sure it's up to date. 1032 | 1033 | force: 1034 | 1035 | 1036 | #=== preprocessor file ========================================================= 1037 | 1038 | 1039 | # make preprocessor output file with extension .pre 1040 | # argument $1 = compiler type (c or cxx) 1041 | define make-preprocessor-file 1042 | $(info ++++ info: making preprocessor output file $(notdir $*.pre) \ 1043 | in current working directory) 1044 | $(compile-$1) -E $< $(c.flags) $($1.flags) -o $(notdir $*.pre) 1045 | endef 1046 | 1047 | %.pre:: %.c force 1048 | $(call make-preprocessor-file,c) 1049 | 1050 | %.pre:: %.cc force 1051 | $(call make-preprocessor-file,cxx) 1052 | 1053 | %.pre:: %.cpp force 1054 | $(call make-preprocessor-file,cxx) 1055 | 1056 | 1057 | #=== assembly file ============================================================= 1058 | 1059 | 1060 | # make C / assembly interleaved output file with extension .lst 1061 | # argument $1 = compiler type (c or cxx) 1062 | define make-assembly-file 1063 | $(info ++++ info: making assembly output file $(notdir $*.lst) \ 1064 | in current working directory) 1065 | $(compile-$1) \ 1066 | -c -Wa,-a,-ad -fverbose-asm \ 1067 | $($1.flags) \ 1068 | $< > $(notdir $*.lst) 1069 | endef 1070 | 1071 | %.lst:: %.c force 1072 | $(call make-assembly-file,c) 1073 | 1074 | %.lst:: %.cc force 1075 | $(call make-assembly-file,cxx) 1076 | 1077 | %.lst:: %.cpp force 1078 | $(call make-assembly-file,cxx) 1079 | 1080 | 1081 | ################################################################################ 1082 | ### rules: installation targets ################################################ 1083 | ################################################################################ 1084 | 1085 | 1086 | #=== strip ===================================================================== 1087 | 1088 | 1089 | # Stripping of installed binaries will only be done when variable 'stripflags' 1090 | # is defined non-empty. No default definition is provided except for Windows 1091 | # where the unstripped binaries are large, especially in the case of Mingw-w64. 1092 | 1093 | # Note: while stripping all symbols ('-s' or '--strip-all') is possible for 1094 | # Linux and Windows, in the case of OSX only non-global symbols can be stripped 1095 | # (option '-x' or '--discard-all'). 1096 | 1097 | # Make definition of strip command overridable so it can be defined in an 1098 | # environment for cross-compilation. 1099 | STRIP ?= strip 1100 | 1101 | # Commands in 'strip-executables' will be executed conditionally in the rule for 1102 | # target 'install-executables'. 1103 | strip-executables = cd "$(installpath)" && \ 1104 | $(foreach v, $(executables), $(STRIP) $(stripflags) '$v';) 1105 | 1106 | 1107 | #=== install =================================================================== 1108 | 1109 | 1110 | # Install targets depend on successful exit status of target all because nothing 1111 | # must be installed in case of a build error. 1112 | 1113 | # -p = preserve time stamps 1114 | # -m = set permission mode (as in chmod) 1115 | # -d = create all components of specified directories 1116 | INSTALL = install 1117 | INSTALL_PROGRAM := $(INSTALL) -p -m 644 1118 | INSTALL_DATA := $(INSTALL) -p -m 644 1119 | INSTALL_DIR := $(INSTALL) -m 755 -d 1120 | 1121 | # strip spaces from file names 1122 | executables := $(strip $(executables)) 1123 | datafiles := $(strip $(datafiles)) 1124 | datadirs := $(strip $(datadirs)) 1125 | 1126 | # Do not make any install sub-target with empty variable definition because the 1127 | # install program would exit with an error. 1128 | install: $(if $(executables), install-executables) 1129 | install: $(if $(datafiles), install-datafiles) 1130 | install: $(if $(datadirs), install-datadirs) 1131 | 1132 | install-executables: all 1133 | $(INSTALL_DIR) -v "$(installpath)" 1134 | $(foreach v, $(executables), \ 1135 | $(INSTALL_PROGRAM) '$v' "$(installpath)";) 1136 | $(info ++++ info: executables of lib $(lib.name) installed \ 1137 | from $(CURDIR) to $(installpath)) 1138 | $(if $(stripflags), $(strip-executables),) 1139 | 1140 | install-datafiles: all 1141 | $(INSTALL_DIR) -v "$(installpath)" 1142 | $(foreach v, $(datafiles), \ 1143 | $(INSTALL_DATA) '$(v)' "$(installpath)";) 1144 | $(info ++++ info: data files of lib $(lib.name) installed \ 1145 | from $(CURDIR) to $(installpath)) 1146 | 1147 | install-datadirs: all 1148 | $(foreach v, $(datadirs), $(INSTALL_DIR) "$(installpath)/$v";) 1149 | $(foreach v, $(datadirs), \ 1150 | $(INSTALL_DATA) $(wildcard $v/*) "$(installpath)/$v";) 1151 | $(info ++++ info: data directories of lib $(lib.name) installed \ 1152 | from $(CURDIR) to $(installpath)) 1153 | 1154 | 1155 | ################################################################################ 1156 | ### rules: distribution targets ################################################ 1157 | ################################################################################ 1158 | 1159 | 1160 | # TODO 1161 | # These targets are implemented in Makefile Template, but I have to figure out 1162 | # how to do it under the not-so-strict conditions of Makefile.pdlibbuilder. 1163 | 1164 | # make source package 1165 | dist: 1166 | @echo "target dist not yet implemented" 1167 | 1168 | # make Debian source package 1169 | dpkg-source: 1170 | @echo "target dpkg-source not yet implemented" 1171 | 1172 | $(ORIGDIR): 1173 | 1174 | $(DISTDIR): 1175 | 1176 | 1177 | ################################################################################ 1178 | ### rules: clean targets ####################################################### 1179 | ################################################################################ 1180 | 1181 | 1182 | # delete build products from build tree 1183 | clean: 1184 | rm -f $(all.objects) 1185 | rm -f $(classes.executables) $(lib.name).$(extension) $(shared.lib) 1186 | rm -f *.pre *.lst 1187 | 1188 | # remove distribution directories and tarballs from build tree 1189 | distclean: clean 1190 | @echo "target distclean not yet implemented" 1191 | 1192 | 1193 | ################################################################################ 1194 | ### rules: submake targets ##################################################### 1195 | ################################################################################ 1196 | 1197 | 1198 | # Iterate over sub-makefiles or makefiles in other directories. 1199 | 1200 | # When 'continue-make=yes' is set, sub-makes will report 'true' to the parent 1201 | # process regardless of their real exit status. This prevents the parent make 1202 | # from being aborted by a sub-make error. Useful when you want to quickly find 1203 | # out which sub-makes from a large set will succeed. 1204 | ifeq ($(continue-make),yes) 1205 | continue = || true 1206 | endif 1207 | 1208 | # These targets will trigger sub-make processes for entries in 'makefiledirs' 1209 | # and 'makefiles'. 1210 | all alldebug install clean distclean dist dkpg-source: \ 1211 | $(makefiledirs) $(makefiles) 1212 | 1213 | # this expands to identical rules for each entry in 'makefiledirs' 1214 | $(makefiledirs): 1215 | $(MAKE) --directory=$@ $(MAKECMDGOALS) $(continue) 1216 | 1217 | # this expands to identical rules for each entry in 'makefiles' 1218 | $(makefiles): 1219 | $(MAKE) --directory=$(dir $@) --makefile=$(notdir $@) $(MAKECMDGOALS) $(continue) 1220 | 1221 | 1222 | ################################################################################ 1223 | ### rules: convenience targets ################################################# 1224 | ################################################################################ 1225 | 1226 | 1227 | #=== show variables ============================================================ 1228 | 1229 | 1230 | # Several 'function' macro's cause errors when expanded within a rule or without 1231 | # proper arguments. Variables which are set with the define directive are only 1232 | # shown by name for that reason. 1233 | functions = \ 1234 | add-class-source \ 1235 | declare-class-target \ 1236 | declare-class-executable-target \ 1237 | declare-object-target \ 1238 | link-class \ 1239 | link-lib \ 1240 | link-shared \ 1241 | make-object-file \ 1242 | make-preprocessor-file \ 1243 | make-assembly-file 1244 | 1245 | 1246 | # show variables from makefiles 1247 | vars: 1248 | $(info ++++ info: showing makefile variables:) 1249 | $(foreach v,\ 1250 | $(sort $(filter-out $(functions) functions, $(.VARIABLES))),\ 1251 | $(if $(filter file, $(origin $v)),\ 1252 | $(info variable $v = $($v)))) 1253 | $(foreach v, $(functions), $(info 'function' name: $v)) 1254 | @echo 1255 | 1256 | # show all variables 1257 | allvars: 1258 | $(info ++++ info: showing default, automatic and makefile variables:) 1259 | $(foreach v, \ 1260 | $(sort $(filter-out $(functions) functions, $(.VARIABLES))), \ 1261 | $(info variable ($(origin $v)) $v = $($v))) 1262 | $(foreach v, $(functions), $(info 'function' name: $v)) 1263 | @echo 1264 | 1265 | 1266 | #=== show dependencies ========================================================= 1267 | 1268 | 1269 | # show generated prerequisites rules 1270 | depend: 1271 | $(info ++++ info: generated prerequisite rules) 1272 | $(foreach v, $(classes), $(info $(declare-class-target))) 1273 | $(foreach v, $(classes), $(info $(declare-class-executable-target))) 1274 | $(foreach v, $(all.sources), $(info $(call declare-object-target, $v))) 1275 | @echo 1276 | 1277 | 1278 | #=== show help text ============================================================ 1279 | 1280 | 1281 | # brief info about targets and paths 1282 | 1283 | ifdef mpdh 1284 | mpdhinfo := $(mpdh) 1285 | else 1286 | mpdhinfo := m_pd.h was not found. Is Pd installed? 1287 | endif 1288 | 1289 | help: 1290 | @echo 1291 | @echo " Main targets:" 1292 | @echo " all: build executables (default target)" 1293 | @echo " install: install all components of the library" 1294 | @echo " vars: print makefile variables for troubleshooting" 1295 | @echo " allvars: print all variables for troubleshooting" 1296 | @echo " help: print this help text" 1297 | @echo 1298 | @echo " Pd API m_pd.h:" 1299 | @echo " $(mpdhinfo)" 1300 | @echo " You may specify your preferred Pd include directory as argument" 1301 | @echo " to the make command, like 'PDINCLUDEDIR=path/to/pd/src'." 1302 | @echo 1303 | @echo " Path for installation of your libdir(s):" 1304 | @echo " $(PDLIBDIR)" 1305 | @echo " Alternatively you may specify your path for installation as argument" 1306 | @echo " to the make command, like 'PDLIBDIR=path/to/pd-externals'." 1307 | @echo 1308 | @echo " Default paths are listed in the doc sections in Makefile.pdlibbuilder." 1309 | @echo 1310 | 1311 | 1312 | #=== platform test ============================================================= 1313 | 1314 | 1315 | # This target can be used to test if the compiler for specified PLATFORM is 1316 | # correctly defined and available. 1317 | 1318 | dumpmachine: 1319 | @$(CC) -dumpmachine 1320 | 1321 | 1322 | #=== dummy target ============================================================== 1323 | 1324 | 1325 | coffee: 1326 | @echo "Makefile.pdlibbuilder: Can not make coffee. Sorry." 1327 | 1328 | 1329 | ################################################################################ 1330 | ### end of rules sections ###################################################### 1331 | ################################################################################ 1332 | 1333 | 1334 | # for syntax highlighting in vim and github 1335 | # vim: set filetype=make: 1336 | 1337 | -------------------------------------------------------------------------------- /pd-lib-builder/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Makefile.pdlibbuilder ### 4 | 5 | Helper makefile for Pure Data external libraries. Written by Katja Vetter 6 | March-June 2015 for the public domain and since then developed as a Pd 7 | community project. No warranties. Inspired by Hans Christoph Steiner's Makefile 8 | Template and Stephan Beal's ShakeNMake. 9 | 10 | GNU make version >= 3.81 required. 11 | 12 | 13 | ### characteristics ### 14 | 15 | 16 | * defines build settings based on autodetected target platform 17 | * defines rules to build Pd class- or lib executables from C or C++ sources 18 | * defines rules for libdir installation 19 | * defines convenience targets for developer and user 20 | * evaluates implicit dependencies for non-clean builds 21 | 22 | 23 | ### basic usage ### 24 | 25 | 26 | In your Makefile, define your Pd lib name and class files, and include 27 | Makefile.pdlibbuilder at the end of the Makefile. Like so: 28 | 29 | 30 | # Makefile for mylib 31 | 32 | lib.name = mylib 33 | 34 | class.sources = myclass1.c myclass2.c 35 | 36 | datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt 37 | 38 | include Makefile.pdlibbuilder 39 | 40 | 41 | For files in class.sources it is assumed that class name == source file 42 | basename. The default target builds all classes as individual executables 43 | with Pd's default extension for the platform. For anything more than the 44 | most basic usage, read the documentation sections in Makefile.pdlibbuilder. 45 | 46 | 47 | ### paths ### 48 | 49 | 50 | Makefile.pdlibbuilder >= v0.4.0 supports pd path variables which can be 51 | defined not only as make command argument but also in the environment, to 52 | override platform-dependent defaults: 53 | 54 | PDDIR: 55 | Root directory of 'portable' pd package. When defined, PDINCLUDEDIR and 56 | PDBINDIR will be evaluated as $(PDDIR)/src and $(PDDIR)/bin. 57 | 58 | PDINCLUDEDIR: 59 | Directory where Pd API m_pd.h should be found, and other Pd header files. 60 | Overrides the default search path. 61 | 62 | PDBINDIR: 63 | Directory where pd.dll should be found for linking (Windows only). Overrides 64 | the default search path. 65 | 66 | PDLIBDIR: 67 | Root directory for installation of Pd library directories. Overrides the 68 | default install location. 69 | 70 | 71 | ### documentation ### 72 | 73 | 74 | This README.md provides only basic information. A large comment section inside 75 | Makefile.pdlibbuilder lists and explains the available user variables, default 76 | paths, and targets. The internal documentation reflects the exact functionality 77 | of the particular version. For suggestions about project maintenance and 78 | advanced compilation see tips-tricks.md. 79 | 80 | 81 | ### versioning ### 82 | 83 | 84 | The project is versioned in MAJOR.MINOR.BUGFIX format (see http://semver.org), 85 | and maintained at https://github.com/pure-data/pd-lib-builder. Pd lib developers 86 | are invited to regulary check for updates, and to contribute and discuss 87 | improvements here. If you really need to distribute a personalized version with 88 | your library, rename Makefile.pdlibbuilder to avoid confusion. 89 | 90 | 91 | ### examples ### 92 | 93 | The list of projects using pd-lib-builder can be helpful if you are looking for 94 | examples, from the simplest use case to more complex implementations. 95 | 96 | - helloworld: traditional illustration of simplest use case 97 | - pd-windowing: straightforward real world use case of a small library 98 | - pd-nilwind / pd-cyclone: more elaborate source tree 99 | - zexy: migrated from autotools to pd-lib-builder 100 | 101 | 102 | ### projects using pd-lib-builder ### 103 | 104 | non-exhaustive list 105 | 106 | https://github.com/pure-data/helloworld 107 | 108 | https://github.com/electrickery/pd-nilwind 109 | 110 | https://github.com/electrickery/pd-maxlib 111 | 112 | https://github.com/electrickery/pd-sigpack 113 | 114 | https://github.com/electrickery/pd-tof 115 | 116 | https://github.com/electrickery/pd-windowing 117 | 118 | https://github.com/electrickery/pd-smlib 119 | 120 | https://github.com/porres/pd-cyclone 121 | 122 | https://github.com/porres/pd-else 123 | 124 | https://github.com/porres/pd-psycho 125 | 126 | https://git.iem.at/pd/comport 127 | 128 | https://git.iem.at/pd/hexloader 129 | 130 | https://git.iem.at/pd/iemgui 131 | 132 | https://git.iem.at/pd/iemguts 133 | 134 | https://git.iem.at/pd/iemlib 135 | 136 | https://git.iem.at/pd/iemnet 137 | 138 | https://git.iem.at/pd/iem_ambi 139 | 140 | https://git.iem.at/pd/iem_tab 141 | 142 | https://git.iem.at/pd/iem_adaptfilt 143 | 144 | https://git.iem.at/pd/iem_roomsim 145 | 146 | https://git.iem.at/pd/iem_spec2 147 | 148 | https://git.iem.at/pd/mediasettings 149 | 150 | https://git.iem.at/pd/zexy 151 | 152 | https://git.iem.at/pd-gui/punish 153 | 154 | https://github.com/residuum/PuRestJson 155 | 156 | https://github.com/libpd/abl_link 157 | 158 | https://github.com/wbrent/timbreID 159 | 160 | https://github.com/MetaluNet/moonlib 161 | 162 | 163 | -------------------------------------------------------------------------------- /pd-lib-builder/tips-tricks.md: -------------------------------------------------------------------------------- 1 | pd-lib-builder cheatsheet 2 | ========================= 3 | 4 | # Creating special builds 5 | 6 | ## cross-compiling on linux x86_64 for other platforms 7 | 8 | Using pd-lib-builder >=0.6.0 we can define variable `PLATFORM` to specify a 9 | target triplet for cross-compilation. Example to build W32 binaries (assuming 10 | package `mingw-w64` is installed and a W32 package for Pd is unzipped into a 11 | path `${PDWIN32}`: 12 | 13 | make PLATFORM=x86_64-w64-mingw32 PDDIR="${PDWIN32}" 14 | 15 | #### older pd-lib-builder versions 16 | 17 | Using pd-lib-builder < 0.6.0, in the absence of variable `PLATFORM`, you would 18 | instead override variables `system`, `target.arch`, `CC` and / or `CXX`, 19 | `STRIP`. Example: 20 | 21 | make system=Windows target.arch=i686 CC=i686-w64-mingw32-gcc STRIP=i686-w64-mingw32-strip PDDIR="${PDWIN32}" 22 | 23 | #### toolchains 24 | 25 | Cross toolchains for relevant platforms in Debian Buster (install g++ 26 | with dependencies for a given platform to get the whole tool chain): 27 | 28 | - `arm-linux-gnueabihf` 29 | - `aarch64-linux-gnu` 30 | - `i686-linux-gnu` 31 | - `i686-w64-mingw32` and `x86_64-w64-mingw32` (install `mingw-w64`) 32 | 33 | OSX/MacOS cross tool chains are not distributed by Debian. Use project 34 | `osxcross` from Thomas Poechtraeger to create the tools. 35 | 36 | ## building double-precision externals 37 | 38 | At the time of writing (2018-02) there is no official Pd that supports 39 | double-precision numbers yet. 40 | However, if you do get hold of an experimental double-precision Pd, you can 41 | easily build your externals for 64-bit numbers: 42 | 43 | make CPPFLAGS="-DPD_FLOATSIZE=64" 44 | 45 | ## building externals for W64 (64-bit Windows) 46 | 47 | At the time of writing (2018-02) there is no official Pd that supports 48 | W64 yet. 49 | However, if you do get hold of an experimental W64 Pd, you can 50 | easily build your externals for this environment with 51 | 52 | make CPPFLAGS="-DPD_LONGINTTYPE=__int64" CC=x86_64-w64-mingw32-gcc 53 | 54 | 55 | To build a double-precision external for W64, use something like: 56 | 57 | make CPPFLAGS="-DPD_LONGINTTYPE=__int64 -DPD_FLOATSIZE=64" CC=x86_64-w64-mingw32-gcc 58 | 59 | 60 | ## TODO universal binaries on OSX 61 | 62 | 63 | # Project management 64 | 65 | In general it is advised to put the `Makefile.pdlibbuilder` into a separate 66 | subdirectory (e.g. `pd-lib-builder/`). 67 | This makes it much easier to update the `Makefile.pdlibbuilder` later 68 | 69 | You *should* also use a variable to the actual path of the Makefile.pdlibbuilder 70 | (even if you keep it in the root-directory), as this allows easy experimenting 71 | with newer (or older) (or site-specific) versions of the pd-lib-builder 72 | Makefile. 73 | 74 | ~~~make 75 | PDLIBBUILDER_DIR=pd-lib-builder/ 76 | include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder 77 | ~~~ 78 | 79 | ## Keeping pd-lib-builder up-to-date 80 | 81 | ### `git subtree` 82 | 83 | With git-subtrees, you make the pd-lib-builder repository (or any other 84 | repository for that matter) part of your own repository - with full history and 85 | everything - put nicely into a distinct subdirectory. 86 | 87 | Support for *manipulating* subtrees has been added with Git-v1.7.11 (May 2012). 88 | The nice thing however is, that from "outside" the subtree is part of your 89 | repository like any other directory. E.g. older versions of Git can clone your 90 | repository with the full subtree (and all it's history) just fine. 91 | You can also use git-archive to make a complete snapshot of your repository 92 | (including the subtree) - nice, if you e.g. want self-contained downloads of 93 | your project from git hosting platforms (like Github, Gitlab, Bitbucket,...) 94 | 95 | In short, `git subtree` is the better `git submodule`. 96 | 97 | So here's how to do it: 98 | 99 | #### Initial setup/check-out 100 | This will create a `pd-lib-builder/` directory containing the full history of 101 | the pd-lib-builder repository up to its release `v0.5.0` 102 | 103 | ~~~sh 104 | git subtree add --prefix=pd-lib-builder/ https://github.com/pure-data/pd-lib-builder v0.5.0 105 | ~~~ 106 | 107 | This will automatically merge the `pd-lib-builder/` history into your current 108 | branch, so everything is ready to go. 109 | 110 | #### Cloning your repository with the subtree 111 | Nothing special, really. 112 | Just clone your repository as always: 113 | 114 | ~~~sh 115 | git clone https://git.example.org/pd/superbonk~.git 116 | ~~~ 117 | 118 | #### Updating the subtree 119 | Time passes and sooner or later you will find, that there is a shiny new 120 | pd-lib-builder with plenty of bugfixes and new features. 121 | To update your local copy to pd-lib-builder's current `master`, simply run: 122 | 123 | ~~~sh 124 | git subtree pull --prefix pd-lib-builder/ https://github.com/pure-data/pd-lib-builder master 125 | ~~~ 126 | 127 | #### Pulling the updated subtree into existing clones 128 | Again, nothing special. 129 | Just pull as always: 130 | 131 | ~~~sh 132 | git pull 133 | ~~~ 134 | 135 | 136 | #### Further reading 137 | More on the power of `git subtree` can be found online 138 | - https://medium.com/@v/git-subtrees-a-tutorial-6ff568381844 139 | - https://www.atlassian.com/blog/git/alternatives-to-git-submodule-git-subtree 140 | - ... 141 | 142 | ### ~~`git submodule`~~ [DISCOURAGED] 143 | 144 | 145 | #### Initial setup/check-out 146 | To add a new submodule to your repository, just run `git submodule add` and 147 | commit the changes: 148 | 149 | ~~~sh 150 | git submodule add https://github.com/pure-data/pd-lib-builder 151 | git commit .gitmodules pd-lib-builder/ -m "Added pd-lib-builder as git-submodule" 152 | ~~~ 153 | 154 | #### Cloning your repository with the submodule 155 | 156 | When doing a fresh clone of your repository, pass the `--recursive` option to 157 | automatically fetch all submodules: 158 | 159 | ~~~sh 160 | git clone --recursive https://git.example.org/pd/superbonk~.git 161 | ~~~ 162 | 163 | If you've cloned non-recursively, you can initialize and update the submodules 164 | manually: 165 | 166 | ~~~sh 167 | git submodule init 168 | git submodule update 169 | ~~~ 170 | 171 | #### Updating the submodule 172 | Submodules are usually fixed to a given commit in their repository. 173 | To update the `pd-lib-builder` submodule to the current `master` do something 174 | like: 175 | 176 | ~~~sh 177 | cd pd-lib-builder 178 | git checkout master 179 | git pull 180 | cd .. 181 | git status pd-lib-builder 182 | git commit pd-lib-builder -m "Updated pd-lib-builder to current master" 183 | ~~~ 184 | 185 | #### Pulling the updated submodule into existing clones 186 | After you have pushed the submodule updates in your repository, other clones of 187 | the repository can be updated as follows: 188 | 189 | ~~~sh 190 | git pull 191 | ~~~ 192 | 193 | The above will make your repository aware, that the submodule is out-of-sync. 194 | 195 | ~~~sh 196 | $ LANG=C git status pd-lib-builder 197 | On branch master 198 | Your branch is up to date with 'origin/master'. 199 | 200 | Changes not staged for commit: 201 | (use "git add ..." to update what will be committed) 202 | (use "git checkout -- ..." to discard changes in working directory) 203 | 204 | modified: pd-lib-builder (new commits) 205 | $ 206 | ~~~ 207 | 208 | In order to sync the submodule to the correct commit, run the following: 209 | 210 | ~~~sh 211 | git submodule update 212 | ~~~ 213 | 214 | #### Drawbacks 215 | `git submodule` has a number of drawbacks: 216 | - it requires special commands to synchronize the submodules, in addition to 217 | synching your repository. 218 | - you must make sure to use an URL for the submodule that is accessible to your 219 | potential users. e.g. using `git@github.com:pure-data/pd-lib-builder` is bad, 220 | because it requires everybody who wants to checkout your sources to have a 221 | github-account - even if they could checkout *your* repository anonymously. 222 | - submodules will be excluded from `git archive`. This means, that if you use a 223 | mainstream git provider (like Github, GitLab, Bitbucket,...) and make releases 224 | by creating a `git tag`, the automatically generated zipfiles with the sources 225 | will lack the submodule - and your users will not be able to compile your 226 | source code. 227 | 228 | In general, I would suggest to **avoid** `git submodule`, and instead use the 229 | better `git subtree` (above). 230 | 231 | --------------------------------------------------------------------------------