aboutsummaryrefslogtreecommitdiff
path: root/doc/tutorials/externals-howto/HOWTO-externals-en.tex
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2014-03-25 11:42:00 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2014-03-25 11:42:00 +0000
commitab047cfb36d6dc94db2eaf669da566029ce049b7 (patch)
treef5ad3f5dc185df3362e1f5937e3aa524d2065438 /doc/tutorials/externals-howto/HOWTO-externals-en.tex
parent6f885df5d63d2f2dcbabdfe6f03cdd6bb08490ec (diff)
renamed HOWTO to 'pd-externals-HOWTO'
no longer language-specific names... svn path=/trunk/; revision=17291
Diffstat (limited to 'doc/tutorials/externals-howto/HOWTO-externals-en.tex')
-rw-r--r--doc/tutorials/externals-howto/HOWTO-externals-en.tex1827
1 files changed, 0 insertions, 1827 deletions
diff --git a/doc/tutorials/externals-howto/HOWTO-externals-en.tex b/doc/tutorials/externals-howto/HOWTO-externals-en.tex
deleted file mode 100644
index ab5f3688..00000000
--- a/doc/tutorials/externals-howto/HOWTO-externals-en.tex
+++ /dev/null
@@ -1,1827 +0,0 @@
-% format latexg -*- latex -*-
-
-\documentclass[12pt, a4paper,english,titlepage]{article}
-
-%% HOWTO write an external for Pd
-%% Copyright (c) 2001-2014 by IOhannes m zmölnig
-%%
-%% Permission is granted to copy, distribute and/or modify this document
-%% under the terms of the GNU Free Documentation License, Version 1.2
-%% or any later version published by the Free Software Foundation;
-%% with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
-%% Texts. A copy of the license is included in the LICENSE.txt file.
-
-\usepackage[utf8]{inputenc}
-
-\usepackage[T1]{fontenc}
-\usepackage[english]{babel}
-
-% add hypertext support (fine for latex2html)
-\usepackage{html}
-\usepackage{hyperref}
-
-% add landscape support (for rotating text through 90deg)
-\usepackage{lscape}
-
-\makeatletter
-\@ifpackageloaded{tex4ht}
- {\let\iftexforht\@firstoftwo}
- {\let\iftexforht\@secondoftwo}
-\makeatother
-
-\iftexforht{\newcommand\pdtilde{\textasciitilde}}{\newcommand\pdtilde{$\sim$}}
-
-\title{
-HOWTO \\
-write an External \\
-for {\em Pure Data}
-}
-
-\author{
-IOhannes m zmölnig \\
-\\
-\href{http://iem.at/}{institute of electronic music and acoustics}
-}
-
-%\date{}
-
-\begin{document}
-\maketitle
-
-\begin{abstract}
-Pd is a graphical real-time computer-music system that follows the tradition of
-IRCAMs {\em ISPW-max}.
-
-Although plenty of functions are built into Pd,
-it is sometimes a pain or simply impossible to create a patch with a certain
-functionality out of the given primitives and combinations of these.
-
-Therefore, Pd can be extended with self made primitives (``objects'')
-that are written in complex programming-languages, like {\tt C/C++}.
-
-This document aims to explain how to write such primitives in {\tt C},
-the popular language that was used to realize Pd.
-
-\iftexforht{You can download this HOWTO as \href{pd-externals-HOWTO.pdf}{pdf (English)}.}{}
-
-\end{abstract}
-
-
-\vfill
-\newpage
-
-\tableofcontents
-
-\vfill
-\newpage
-
-\section{definitions and prerequisites}
-Pd refers to the graphical real-time computer-music environment {\em Pure Data}
-by Miller~S.~Puckette.
-
-To fully understand this document, it is necessary to
-be acquainted with Pd and to
-have a general understanding of programming techniques especially in {\tt C}.
-
-To write externals yourself, a {\tt C}-compiler that supports the
-{\tt ANSI-C}-Standard, like the {\em Gnu C-compiler} (gcc) on linux-systems or
-{\em Visual-C++} on windos-plattforms, will be necessary.
-
-\subsection{classes, instances, objects}
-Pd is written in the programming-language {\tt C}.
-Due to its graphical nature, Pd is a {\em object-oriented} system.
-Unfortunately {\tt C} does not support very well the use of classes.
-Thus the resulting source-code is not as elegant as {\tt C++}-code would be, for instance.
-
-In this document, the expression {\em class} refers to the realisation of a concept
-combining data and manipulators on this data.
-
-Concrete {\em instances of a class} are called {\em objects}.
-
-\subsection{internals, externals und libraries}
-
-To avoid confusion of ideas, the expressions {\em internal}, {\em external} and
-{\em library} should be explained here.
-
-\paragraph{Internal}
-An {\em internal} is a class that is built into Pd.
-Plenty of primitives, such as ``+'', ``pack'' or ``sig\pdtilde'' are {\em internals}.
-
-\paragraph{External}
-An {\em external} is a class that is not built into Pd but is loaded at runtime.
-Once loaded into Pd's memory, {\em externals} cannot be distinguished from
-{\em internals} any more.
-
-\paragraph{Library}
-A {\em library} is a collection of {\em externals} that are compiled into a
-single binary-file.
-
-{\em Library}-files have to follow a system dependent naming convention:
-
-\begin{tabular}{c||c|c|c}
-library & linux&irix&Win32 \\
-\hline
-{\tt my\_lib}&{\tt my\_lib.pd\_linux}&{\tt my\_lib.pd\_irix}&
-{\tt my\_lib.dll}\\
-\end{tabular}
-
-The simplest form of a {\em library} includes exactly one {\em external}
-bearing the same name as the {\em library}.
-
-Unlike {\em externals}, {\em libraries} can be imported by Pd with special operations.
-After a {\em library} has been imported,
-all included {\em externals} have been loaded into memory and are available as objects.
-
-Pd supports two modes to import {\em libraries}:
-
-\begin{itemize}
-\item via the command line-option ``{\tt -lib my\_lib}''
-\item by creating an object ``{\tt my\_lib}''
-\end{itemize}
-
-The first method loads a {\em library} when Pd is started.
-This method is preferably used for {\em libraries} that contain several {\em externals}.
-
-The other method should be used for {\em libraries} that contain exactly
-one {\em external} bearing the same name.
-Pd checks first, whether a class named ``my\_lib'' is already loaded.
-If this is not the case\footnote{
-If a class ``my\_lib'' is already existent, an object ``my\_lib'' will be instantiated
-and the procedure is done.
-Thus, no {\em library} has been loaded.
-Therefore no {\em library} that is named like an already used class-name like, say, ``abs'',
-can be loaded.}, all paths are searched for a file called
-``{\tt my\_lib.pd\_linux}''\footnote{or another system-dependent filename-extensions (s.a.)}.
-If such file is found, all included {\em externals} are loaded into memory by calling a
-routine \verb+my_lib_setup()+.
-After loading, a class ``my\_lib'' is (again) looked for as a (newly loaded) {\em external}.
-If so, an instance of this class is created, else the instantiation fails and an error is
-printed.
-Anyhow, all {\em external}-classes declared in the {\em library} are loaded by now.
-
-
-\section{my first external: {\tt helloworld}}
-Usually the first attempt learning a programming-language is a ``hello world''-application.
-
-In our case, an object class should be created, that prints the line ``hello world!!'' to
-the standard error every time it is triggered with a ``bang''-message.
-
-
-
-\subsection{the interface to Pd}
-To write a Pd-external a well-defined interface is needed.
-This is provided in the header-file ``m\_pd.h''.
-
-\begin{verbatim}
-#include "m_pd.h"
-\end{verbatim}
-
-\subsection{a class and its data space}
-First a new class has to be prepared and the data space for this class has to be defined.
-
-\begin{verbatim}
-static t_class *helloworld_class;
-
-typedef struct _helloworld {
- t_object x_obj;
-} t_helloworld;
-\end{verbatim}
-
-\verb+hello_worldclass+ is going to be a pointer to the new class.
-
-The structure \verb+t_helloworld+ (of the type \verb+_helloworld+) is
-the data space of the class.
-
-An absolutely necessary element of the data space is a variable of the type
-\verb+t_object+, which is used to store internal object-properties like
-the graphical presentation of the object or data about inlets and outlets.
-
-\verb+t_object+ has to be the first entry in the structure !
-
-Because a simple ``hello world''-application needs no variables,
-the structure is empty apart from the \verb+t_object+.
-
-
-\subsection{method space}
-Apart from the data space, a class needs a set of manipulators (methods) to
-manipulate the data with.
-
-If a message is sent to an instance of our class, a method is called.
-These methods are the interfaces to the message system of Pd.
-On principal they have no return argument and are therefore of the
-type \verb+void+.
-
-\begin{verbatim}
-void helloworld_bang(t_helloworld *x)
-{
- post("Hello world !!");
-}
-\end{verbatim}
-
-
-This method has an argument of the type \verb+t_helloworld+,
-which would enable us to manipulate the data space.
-
-Since we only want to output ``Hello world!''
-(and, by the way, our data space is quite sparse),
-we renounce a manipulation.
-
-The command \verb+post(char *c,...)+ sends a string to the standard error.
-A carriage return is added automatically.
-Apart from this, the \verb+post+-command works like the {\tt C}-command \verb+printf()+.
-
-\subsection{generation of a new class}
-To generate a new class, information of the data space and the method space of this class,
-have to be passed to Pd when a library is loaded.
-
-On loading a new library ``my\_lib'',
-Pd tries to call a function ``my\_lib\_setup()''.
-This function (or functions called by it)
-declares the new classes and their properties.
-It is only called once, when the library is loaded.
-If the function-call fails (e.g., because no function of the specified name is present)
-no external of the library will be loaded.
-
-\begin{verbatim}
-void helloworld_setup(void)
-{
- helloworld_class = class_new(gensym("helloworld"),
- (t_newmethod)helloworld_new,
- 0, sizeof(t_helloworld),
- CLASS_DEFAULT, 0);
-
- class_addbang(helloworld_class, helloworld_bang);
-}
-\end{verbatim}
-
-\paragraph{class\_new}
-
-The function \verb+class_new+ creates a new class and returns a pointer to this prototype.
-
-The first argument is the symbolic name of the class.
-
-The next two arguments define the constructor and destructor of the class.
-
-Whenever a class object is created in a Pd-patch,
-the class-constructor \verb+(t_newmethod)helloworld_new+ instantiates the object
-and initialises the data space.
-
-Whenever an object is destroyed
-(either by closing the containing patch or by deleting the object from the patch)
-the destructor frees the dynamically reserved memory.
-The allocated memory for the static data space is automatically reserved and freed.
-
-Therefore we do not have to provide a destructor in this example, the argument
-is set to ``0''.
-
-To enable Pd to reserve and free enough memory for the static data space,
-the size of the data structure has to be passed as the fourth argument.
-
-The fifth argument has influence on the graphical representation of the class objects.
-The default-value is \verb+CLASS_DEFAULT+ or simply ``0''.
-
-The remaining arguments define the arguments of an object and its type.
-
-Up to six numeric and symbolic object-arguments can be defined via
-\verb+A_DEFFLOAT+ and \verb+A_DEFSYMBOL+.
-If more arguments are to be passed to the object
-or if the order of atom types should by more flexible,
-\verb+A_GIMME+ can be used for passing an arbitrary list of atoms.
-
-The list of object-arguments is terminated by ``0''.
-In this example we have no object-arguments at all for the class.
-
-\paragraph{class\_addbang}
-We still have to add a method space to the class.
-
-\verb+class_addbang+ adds a method for a ``bang''-message to the class that is
-defined in the first argument.
-The added method is defined in the second argument.
-
-
-\subsection{constructor: instantiation of an object}
-Each time, an object is created in a Pd-patch, the
-constructor that is defined with the \verb+class_new+-command,
-generates a new instance of the class.
-
-The constructor has to be of type \verb+void *+.
-
-\begin{verbatim}
-void *helloworld_new(void)
-{
- t_helloworld *x = (t_helloworld *)pd_new(helloworld_class);
-
- return (void *)x;
-}
-\end{verbatim}
-
-
-The arguments of the constructor-method depend on the object-arguments
-defined with \verb+class_new+.
-
-\begin{tabular}{l|l}
-\verb+class_new+-argument&constructor-argument\\
-\hline
-\verb+A_DEFFLOAT+&\verb+t_floatarg f+ \\
-\verb+A_DEFSYMBOL+&\verb+t_symbol *s+ \\
-\verb+A_GIMME+&\verb+t_symbol *s, int argc, t_atom *argv+
-\end{tabular}
-
-Because there are no object-arguments for our ``hello world''-class,
-the constructor has anon too.
-
-The function \verb+pd_new+ reserves memory for the data space,
-initialises the variables that are internal to the object and
-returns a pointer to the data space.
-
-The type-cast to the data space is necessary.
-
-Normally, the constructor would initialise the object-variables.
-However, since we have none, this is not necessary.
-
-
-The constructor has to return a pointer to the instantiated data space.
-
-\subsection{the code: \tt helloworld}
-
-\begin{verbatim}
-#include "m_pd.h"
-
-static t_class *helloworld_class;
-
-typedef struct _helloworld {
- t_object x_obj;
-} t_helloworld;
-
-void helloworld_bang(t_helloworld *x)
-{
- post("Hello world !!");
-}
-
-void *helloworld_new(void)
-{
- t_helloworld *x = (t_helloworld *)pd_new(helloworld_class);
-
- return (void *)x;
-}
-
-void helloworld_setup(void) {
- helloworld_class = class_new(gensym("helloworld"),
- (t_newmethod)helloworld_new,
- 0, sizeof(t_helloworld),
- CLASS_DEFAULT, 0);
- class_addbang(helloworld_class, helloworld_bang);
-}
-\end{verbatim}
-
-
-\section{a simple external: {\tt counter}}
-
-Now we want to realize a simple counter as an external.
-A ``bang''-trigger outputs the counter-value on the outlet and
-afterwards increases the counter-value by 1.
-
-This class is similar to the previous one,
-but the data space is extended by a variable ``counter'' and the
-result is written as a message to an outlet instead of
-a string to the standard error.
-
-\subsection{object-variables}
-Of course, a counter needs a state-variable to store the actual counter-value.
-
-State-variables that belong to class instances belong to the data space.
-
-\begin{verbatim}
-typedef struct _counter {
- t_object x_obj;
- t_int i_count;
-} t_counter;
-\end{verbatim}
-
-The integer variable \verb+i_count+ stores the counter-value.
-
-\subsection{object-arguments}
-It is quite useful for a counter, if a initial value can be defined by the user.
-Therefore this initial value should be passed to the object at creation-time.
-
-\begin{verbatim}
-void counter_setup(void) {
- counter_class = class_new(gensym("counter"),
- (t_newmethod)counter_new,
- 0, sizeof(t_counter),
- CLASS_DEFAULT,
- A_DEFFLOAT, 0);
-
- class_addbang(counter_class, counter_bang);
-}
-\end{verbatim}
-
-So we have an additional argument in the function \verb+class_new+:
-\verb+A_DEFFLOAT+ tells Pd, that the object needs one argument of the
-type \verb+t_floatarg+.
-If no argument is passed, this will default to ``0''.
-
-\subsection{constructor}
-The constructor has some new tasks.
-On the one hand, a variable value has to be initialised,
-on the other hand, an outlet for the object has to be created.
-
-\begin{verbatim}
-void *counter_new(t_floatarg f)
-{
- t_counter *x = (t_counter *)pd_new(counter_class);
-
- x->i_count=f;
- outlet_new(&x->x_obj, &s_float);
-
- return (void *)x;
-}
-\end{verbatim}
-
-The constructor-method has one argument of type \verb+t_floatarg+ as declared
-in the setup-routine by \verb+class_new+.
-This argument is used to initialise the counter.
-
-A new outlet is created with the function \verb+outlet_new+.
-The first argument is a pointer to the interna of the object
-the new outlet is created for.
-
-The second argument is a symbolic description of the outlet-type.
-Since out counter should output numeric values it is of type ``float''.
-
-\verb+outlet_new+ returns a pointer to the new outlet and saves this very pointer
-in the \verb+t_object+-variable \verb+x_obj.ob_outlet+.
-If only one outlet is used, the pointer need not additionally be stored in the data space.
-If more than one outlets are used, the pointers have to be stored in the data space,
-because the \verb+t_object+-variable can only hold one outlet pointer.
-
-\subsection{the counter method}
-When triggered, the counter value should be sent to the outlet
-and afterwards be incremented by 1.
-
-\begin{verbatim}
-void counter_bang(t_counter *x)
-{
- t_float f=x->i_count;
- x->i_count++;
- outlet_float(x->x_obj.ob_outlet, f);
-}
-\end{verbatim}
-
-The function \verb+outlet_float+ sends a floating-point-value (second argument) to the outlet
-that is specified by the first argument.
-
-We first store the counter in a floating point-buffer.
-Afterwards the counter is incremented and not before that the buffer variable is sent
-to the outlet.
-
-What appears to be unnecessary on the first glance, makes sense after further
-inspection:
-The buffer variable has been realized as \verb+t_float+,
-since \verb+outlet_float+ expects a floating point-value and a typecast is
-inevitable.
-
-If the counter value was sent to the outlet before being incremented,
-this could result in an unwanted (though well defined) behaviour:
-If the counter-outlet directly triggered its own inlet,
-the counter-method would be called although the counter value was not yet incremented.
-Normally this is not what we want.
-
-The same (correct) result could of course be obtained with a single line,
-but this would obscure the {\em reentrant}-problem.
-
-\subsection{the code: \tt counter}
-
-\begin{verbatim}
-#include "m_pd.h"
-
-static t_class *counter_class;
-
-typedef struct _counter {
- t_object x_obj;
- t_int i_count;
-} t_counter;
-
-void counter_bang(t_counter *x)
-{
- t_float f=x->i_count;
- x->i_count++;
- outlet_float(x->x_obj.ob_outlet, f);
-}
-
-void *counter_new(t_floatarg f)
-{
- t_counter *x = (t_counter *)pd_new(counter_class);
-
- x->i_count=f;
- outlet_new(&x->x_obj, &s_float);
-
- return (void *)x;
-}
-
-void counter_setup(void) {
- counter_class = class_new(gensym("counter"),
- (t_newmethod)counter_new,
- 0, sizeof(t_counter),
- CLASS_DEFAULT,
- A_DEFFLOAT, 0);
-
- class_addbang(counter_class, counter_bang);
-}
-\end{verbatim}
-
-
-\section{a complex external: \tt counter}
-
-The simple counter of the previous chapter can easily be extended to more complexity.
-It might be quite useful to be able to reset the counter to an initial value,
-to set upper and lower boundaries and to control the step-width.
-Each overrun should send a ``bang''-Message to a second outlet and reset the counter to
-the initial value.
-
-\subsection{extended data space}
-
-\begin{verbatim}
-typedef struct _counter {
- t_object x_obj;
- t_int i_count;
- t_float step;
- t_int i_down, i_up;
- t_outlet *f_out, *b_out;
-} t_counter;
-\end{verbatim}
-
-The data space has been extended to hold variables for step width and
-upper and lower boundaries.
-Furthermore pointers for two outlets have been added.
-
-\subsection{extension of the class}
-The new class objects should have methods for different messages,
-like ``set'' and ``reset''.
-Therefore the method space has to be extended too.
-
-\begin{verbatim}
- counter_class = class_new(gensym("counter"),
- (t_newmethod)counter_new,
- 0, sizeof(t_counter),
- CLASS_DEFAULT,
- A_GIMME, 0);
-\end{verbatim}
-
-The class generator \verb+class_new+ has been extended by the argument \verb+A_GIMME+.
-This enables a dynamic number of arguments to be passed at the instantiation of the object.
-
-\begin{verbatim}
- class_addmethod(counter_class,
- (t_method)counter_reset,
- gensym("reset"), 0);
-\end{verbatim}
-
-\verb+class_addmethod+ adds a method for an arbitrary selector to an class.
-
-The first argument is the class the method (second argument) will be added to.
-
-The third argument is the symbolic selector that should be associated with the method.
-
-The remaining ``0''-terminated arguments describe the list of atoms that
-follows the selector.
-
-\begin{verbatim}
- class_addmethod(counter_class,
- (t_method)counter_set, gensym("set"),
- A_DEFFLOAT, 0);
- class_addmethod(counter_class,
- (t_method)counter_bound, gensym("bound"),
- A_DEFFLOAT, A_DEFFLOAT, 0);
-\end{verbatim}
-
-A method for ``set'' followed by a numerical value is added,
-as well as a method for the selector ``bound'' followed by two numerical values.
-
-\begin{verbatim}
- class_sethelpsymbol(counter_class, gensym("help-counter"));
-\end{verbatim}
-
-If a Pd-object is right-clicked, a help-patch describing the object-class can be opened.
-By default, this patch is located in the directory ``{\em doc/5.reference/}'' and
-is named like the symbolic class name.
-
-An alternative help-patch can be defined with the
-\verb+class_sethelpsymbol+-command.
-
-\subsection{construction of in- and outlets}
-
-When creating the object, several arguments should be passed by the user.
-
-\begin{verbatim}
-void *counter_new(t_symbol *s, int argc, t_atom *argv)
-\end{verbatim}
-Because of the declaration of arguments in the \verb+class_new+-function
-with \verb+A_GIMME+,
-the constructor has following arguments:
-
-\begin{tabular}{c|l}
-\verb+t_symbol *s+ & the symbolic name,\\
-& that was used for object creation \\
-\verb+int argc+ & the number of arguments passed to the object\\
-\verb+t_atom *argv+ & a pointer to a list of {\tt argc} atoms
-\end{tabular}
-
-\begin{verbatim}
- t_float f1=0, f2=0;
-
- x->step=1;
- switch(argc){
- default:
- case 3:
- x->step=atom_getfloat(argv+2);
- case 2:
- f2=atom_getfloat(argv+1);
- case 1:
- f1=atom_getfloat(argv);
- break;
- case 0:
- break;
- }
- if (argc<2)f2=f1;
- x->i_down = (f1<f2)?f1:f2;
- x->i_up = (f1>f2)?f1:f2;
-
- x->i_count=x->i_down;
-\end{verbatim}
-
-If three arguments are passed, these should be the {\em lower boundary},
-the {\em upper boundary} and the {\em step width}.
-
-If only two arguments are passed, the step-width defaults to ``1''.
-If only one argument is passed, this should be the {\em initial value} of the counter with
-step-width of ``1''.
-
-\begin{verbatim}
- inlet_new(&x->x_obj, &x->x_obj.ob_pd,
- gensym("list"), gensym("bound"));
-\end{verbatim}
-
-The function \verb+inlet_new+ creates a new ``active'' inlet.
-``Active'' means, that a class-method is called each time
-a message is sent to an ``active'' inlet.
-
-Due to the software-architecture, the first inlet is always ``active''.
-
-The first two arguments of the \verb+inlet_new+-function are
-pointers to the interna of the object and to the graphical presentation of the object.
-
-The symbolic selector that is specified by the third argument is to be
-substituted by another symbolic selector (fourth argument) for this inlet.
-
-Because of this substitution of selectors,
-a message on a certain right inlet can be treated as a message with
-a certain selector on the leftmost inlet.
-
-This means:
-\begin{itemize}
-\item The substituting selector has to be declared by \verb+class_addmethod+
-in the setup-routine.
-\item It is possible to simulate a certain right inlet, by sending a message with
-this inlet's selector to the leftmost inlet.
-\item It is not possible to add methods for more than one selector to a right inlet.
-Particularly it is not possible to add a universal method for arbitrary selectors to
-a right inlet.
-\end{itemize}
-
-\begin{verbatim}
- floatinlet_new(&x->x_obj, &x->step);
-\end{verbatim}
-\verb+floatinlet_new+ generates a new ``passive'' inlet for numerical values.
-``Passive'' inlets allow parts of the data space-memory to be written directly
-from outside.
-Therefore it is not possible to check for illegal inputs.
-
-The first argument is a pointer to the internal infrastructure of the object.
-The second argument is the address in the data space-memory,
-where other objects can write too.
-
-``Passive'' inlets can be created for pointers, symbolic or
-numerical (floating point\footnote{
-That's why the {\tt step}-width of the class\/data space is realized as {\tt t\_float}.})
-values.
-
-
-\begin{verbatim}
- x->f_out = outlet_new(&x->x_obj, &s_float);
- x->b_out = outlet_new(&x->x_obj, &s_bang);
-\end{verbatim}
-
-The pointers returned by \verb+outlet_new+ have to be saved in the class\/data space
-to be used later by the outlet-routines.
-
-The order of the generation of inlets and outlets is important,
-since it corresponds to the order of inlets and outlets in the
-graphical representation of the object.
-
-\subsection{extended method space}
-
-The method for the ``bang''-message has to full fill the more complex tasks.
-
-\begin{verbatim}
-void counter_bang(t_counter *x)
-{
- t_float f=x->i_count;
- t_int step = x->step;
- x->i_count+=step;
- if (x->i_down-x->i_up) {
- if ((step>0) && (x->i_count > x->i_up)) {
- x->i_count = x->i_down;
- outlet_bang(x->b_out);
- } else if (x->i_count < x->i_down) {
- x->i_count = x->i_up;
- outlet_bang(x->b_out);
- }
- }
- outlet_float(x->f_out, f);
-}
-\end{verbatim}
-
-Each outlet is identified by the \verb+outlet_...+-functions via the
-pointer to this outlets.
-
-The remaining methods still have to be implemented:
-
-\begin{verbatim}
-void counter_reset(t_counter *x)
-{
- x->i_count = x->i_down;
-}
-
-void counter_set(t_counter *x, t_floatarg f)
-{
- x->i_count = f;
-}
-
-void counter_bound(t_counter *x, t_floatarg f1, t_floatarg f2)
-{
- x->i_down = (f1<f2)?f1:f2;
- x->i_up = (f1>f2)?f1:f2;
-}
-\end{verbatim}
-
-\subsection{the code: \tt counter}
-
-\begin{verbatim}
-#include "m_pd.h"
-
-static t_class *counter_class;
-
-typedef struct _counter {
- t_object x_obj;
- t_int i_count;
- t_float step;
- t_int i_down, i_up;
- t_outlet *f_out, *b_out;
-} t_counter;
-
-void counter_bang(t_counter *x)
-{
- t_float f=x->i_count;
- t_int step = x->step;
- x->i_count+=step;
-
- if (x->i_down-x->i_up) {
- if ((step>0) && (x->i_count > x->i_up)) {
- x->i_count = x->i_down;
- outlet_bang(x->b_out);
- } else if (x->i_count < x->i_down) {
- x->i_count = x->i_up;
- outlet_bang(x->b_out);
- }
- }
-
- outlet_float(x->f_out, f);
-}
-
-void counter_reset(t_counter *x)
-{
- x->i_count = x->i_down;
-}
-
-void counter_set(t_counter *x, t_floatarg f)
-{
- x->i_count = f;
-}
-
-void counter_bound(t_counter *x, t_floatarg f1, t_floatarg f2)
-{
- x->i_down = (f1<f2)?f1:f2;
- x->i_up = (f1>f2)?f1:f2;
-}
-
-void *counter_new(t_symbol *s, int argc, t_atom *argv)
-{
- t_counter *x = (t_counter *)pd_new(counter_class);
- t_float f1=0, f2=0;
-
- x->step=1;
- switch(argc){
- default:
- case 3:
- x->step=atom_getfloat(argv+2);
- case 2:
- f2=atom_getfloat(argv+1);
- case 1:
- f1=atom_getfloat(argv);
- break;
- case 0:
- break;
- }
- if (argc<2)f2=f1;
-
- x->i_down = (f1<f2)?f1:f2;
- x->i_up = (f1>f2)?f1:f2;
-
- x->i_count=x->i_down;
-
- inlet_new(&x->x_obj, &x->x_obj.ob_pd,
- gensym("list"), gensym("bound"));
- floatinlet_new(&x->x_obj, &x->step);
-
- x->f_out = outlet_new(&x->x_obj, &s_float);
- x->b_out = outlet_new(&x->x_obj, &s_bang);
-
- return (void *)x;
-}
-
-void counter_setup(void) {
- counter_class = class_new(gensym("counter"),
- (t_newmethod)counter_new,
- 0, sizeof(t_counter),
- CLASS_DEFAULT,
- A_GIMME, 0);
-
- class_addbang (counter_class, counter_bang);
- class_addmethod(counter_class,
- (t_method)counter_reset, gensym("reset"), 0);
- class_addmethod(counter_class,
- (t_method)counter_set, gensym("set"),
- A_DEFFLOAT, 0);
- class_addmethod(counter_class,
- (t_method)counter_bound, gensym("bound"),
- A_DEFFLOAT, A_DEFFLOAT, 0);
-
- class_sethelpsymbol(counter_class, gensym("help-counter"));
-}
-\end{verbatim}
-
-
-\section{a signal-external: {\tt pan\pdtilde}}
-Signal classes are normal Pd-classes, that offer additional methods for signals.
-
-
-All methods and concepts that can be realized with normal object classes can
-therefore be realized with signal classes too.
-
-Per agreement, the symbolic names of signal classes end with a tilde \pdtilde.
-
-The class ``pan\pdtilde'' shall demonstrate, how signal classes are written.
-
-A signal on the left inlet is mixed with a signal on the second inlet.
-The mixing-factor between 0 and 1 is defined via a \verb+t_float+-message
-on a third inlet.
-
-\subsection{variables of a signal class}
-Since a signal-class is only an extended normal class,
-there are no principal differences between the data spaces.
-
-\begin{verbatim}
-typedef struct _pan_tilde {
- t_object x_obj;
-
- t_sample f_pan;
- t_float f;
-
- t_inlet *x_in2;
- t_inlet *x_in3;
-
- t_outlet*x_out;
-
-} t_pan_tilde;
-\end{verbatim}
-
-Only one variable \verb+f_pan+ for the {\em mixing-factor} of the panning-function is needed.
-
-The other variable \verb+f+ is needed whenever a signal-inlet is needed too.
-If no signal but only a float-message is present at a signal-inlet, this
-variable is used to automatically convert the float to signal.
-
-Finally, we have the members \verb+x_in2+, \verb+x_in3+ and \verb+x_out+,
-which are needed to store handles to the various extra inlets (resp. outlets) of the object.
-
-\subsection{signal-classes}
-
-\begin{verbatim}
-void pan_tilde_setup(void) {
- pan_tilde_class = class_new(gensym("pan~"),
- (t_newmethod)pan_tilde_new,
- (t_method)pan_tilde_free,
- sizeof(t_pan_tilde),
- CLASS_DEFAULT,
- A_DEFFLOAT, 0);
-
- class_addmethod(pan_tilde_class,
- (t_method)pan_tilde_dsp, gensym("dsp"), 0);
- CLASS_MAINSIGNALIN(pan_tilde_class, t_pan_tilde, f);
-}
-\end{verbatim}
-
-Something has changed with the \verb+class_new+ function:
-the third argument specifies a ``free-method'' (aka {\em destructor}), which is called whenever an instance of the object
-is to be deleted (just like the ``new-method'' is called whenever an instance is to be created).
-In the prior examples this was set to \verb+0+ (meaning: we don't care),
-but in this example we have to clean up some ressources when we don't need them any more.
-
-More interestingly, a method for signal-processing has to be provided by each signal class.
-
-Whenever Pd's audio engine is started, a message with the selector ``dsp''
-is sent to each object.
-Each class that has a method for the ``dsp''-message is recognised as signal class.
-
-Signal classes that want to provide signal-inlets have to
-declare this via the \verb+CLASS_MAINSIGNALIN+-macro.
-This enables signals at the first (default) inlet.
-If more than one signal-inlet is needed, they have to be created explicitly
-in the constructor-method.
-
-Inlets that are declared as signal-inlets cannot provide
-methods for \verb+t_float+-messages any longer.
-
-The first argument of the macro is a pointer to the signal class.
-The second argument is the type of the class's data space.
-
-The last argument is a dummy-variable out of the data space that is needed
-to replace non-existing signal at the signal-inlet(s) with \verb+t_float+-messages.
-
-\subsection{construction of signal-inlets and -outlets}
-
-\begin{verbatim}
-void *pan_tilde_new(t_floatarg f)
-{
- t_pan_tilde *x = (t_pan_tilde *)pd_new(pan_tilde_class);
-
- x->f_pan = f;
-
- x->x_in2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
- x->x_in3 = floatinlet_new (&x->x_obj, &x->f_pan);
-
- x->x_out = outlet_new(&x->x_obj, &s_signal);
-
- return (void *)x;
-}
-\end{verbatim}
-
-Additional signal-inlets are added like other inlets with the routine \verb+inlet_new+.
-The last two arguments are references to the symbolic selector ``signal''
-in the lookup-table.
-
-Signal-outlets are also created like normal (message-)outlets,
-by setting the outlet-selector to ``signal''.
-
-The newly created inlets/outlets are ``user-allocated'' data.
-Pd will keep track of all the ressources it automatically creates (like the default inlet),
-and will eventually free these ressources once they are no longer needed.
-However, if we request an ``extra'' ressource (like the additional inlets/outlets in this example;
-or - more commonly - memory that is allocated via \verb+malloc+ or similar),
-we have to make sure ourselves, that these ressources are freed when no longer needed.
-If we fail to do so, we will invariably create a dreaded {\em memory leak}.
-
-Therefore, we store the ``handles'' to the newly created inlets/outlets as returned by the \verb+..._new+ routines
-for later use.
-
-
-\subsection{DSP-methods}
-Whenever Pd's audio engine is turned on,
-all signal-objects declare their perform-routines that are to be added to the DSP-tree.
-
-The ``dsp''-method has two arguments, the pointer to the class-data space, and
-a pointer to an array of signals.
-
-The signals are arranged in the array in such way,
-that they are ordered in a clockwise way in the graphical representation of the
-object.\footnote{
-If both left and right in- and out-signals exist, this means:
-First is the leftmost in-signal followed by the right in-signals;
-after the right out-signals, finally there comes the leftmost out-signal.}
-
-\begin{verbatim}
-void pan_tilde_dsp(t_pan_tilde *x, t_signal **sp)
-{
- dsp_add(pan_tilde_perform, 5, x,
- sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
-}
-\end{verbatim}
-
-\verb+dsp_add+ adds a {\em perform}-routine (as declared in the first argument)
-to the DSP-tree.
-
-The second argument is the number of the following pointers to diverse variables.
-Which pointers to which variables are passed is not limited.
-
-Here, sp[0] is the first in-signal, sp[1] represents the second in-signal and
-sp[3] points to the out-signal.
-
-The structure \verb+t_signal+ contains a pointer to the
-its signal-vector \verb+().s_vec+ (an array of samples of type \verb+t_sample+),
-and the length of this signal-vector \verb+().s_n+.
-
-Since all signal vectors of a patch (not including it's sub-patches) are of the same length,
-it is sufficient to get the length of one of these vectors.
-
-\subsection{perform-routine}
-The perform-routine is the DSP-heart of each signal class.
-
-A pointer to an integer-array is passed to it.
-This array contains the pointers, that were passed via \verb+dsp_add+,
-which must be casted back to their real type.
-
-The perform-routine has to return a pointer to integer,
-that points to the address behind the stored pointers of the routine.
-This means, that the return argument equals the
-argument of the perform-routine plus
-the number of pointer variables (as declared as the second argument
-of \verb+dsp_add+) plus one.
-
-\begin{verbatim}
-t_int *pan_tilde_perform(t_int *w)
-{
- t_pan_tilde *x = (t_pan_tilde *)(w[1]);
- t_sample *in1 = (t_sample *)(w[2]);
- t_sample *in2 = (t_sample *)(w[3]);
- t_sample *out = (t_sample *)(w[4]);
- int n = (int)(w[5]);
-
- t_sample f_pan = (x->f_pan<0)?0.0:(x->f_pan>1)?1.0:x->f_pan;
-
- while (n--) *out++ = (*in1++)*(1-f_pan)+(*in2++)*f_pan;
-
- return (w+6);
-}
-\end{verbatim}
-
-Each sample of the signal vectors is read and manipulated in the \verb+while+-loop.
-
-
-Optimisation of the DSP-tree tries to avoid unnecessary copy-operations.
-Therefore it is possible, that in- and out-signal are located
-at the same address in the memory.
-In this case, the programmer has to be careful not to write into the out-signal
-before having read the in-signal to avoid overwriting data that is not yet saved.
-
-\subsection{destructor}
-
-\begin{verbatim}
-void pan_tilde_free(t_pan_tilde *x)
-{
- inlet_free(x->x_in2);
- inlet_free(x->x_in3);
- outlet_free(x->x_out);
-}
-\end{verbatim}
-
-The object has some dynamically allocated ressources,
-namely the additional inlets and outlets we created in the constructor.
-
-Since Pd doesn't track dynamically allocated ressources for us,
-we have to free them manually in the ``free-method'' (aka: destructor).
-We do so by calling \verb+inlet_free+ (resp. \verb+outlet_free+) on the handles to
-our additional iolets.
-
-Note that we do not need to free the default first outlet.
-As it is created automatically by Pd, it is also freed automatically.
-
-\subsection{the code: \tt pan\pdtilde}
-
-\begin{verbatim}
-#include "m_pd.h"
-
-static t_class *pan_tilde_class;
-
-typedef struct _pan_tilde {
- t_object x_obj;
- t_sample f_pan;
- t_sample f;
-
- t_inlet *x_in2;
- t_inlet *x_in3;
- t_outlet*x_out;
-} t_pan_tilde;
-
-t_int *pan_tilde_perform(t_int *w)
-{
- t_pan_tilde *x = (t_pan_tilde *)(w[1]);
- t_sample *in1 = (t_sample *)(w[2]);
- t_sample *in2 = (t_sample *)(w[3]);
- t_sample *out = (t_sample *)(w[4]);
- int n = (int)(w[5]);
- t_sample f_pan = (x->f_pan<0)?0.0:(x->f_pan>1)?1.0:x->f_pan;
-
- while (n--) *out++ = (*in1++)*(1-f_pan)+(*in2++)*f_pan;
-
- return (w+6);
-}
-
-void pan_tilde_dsp(t_pan_tilde *x, t_signal **sp)
-{
- dsp_add(pan_tilde_perform, 5, x,
- sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
-}
-
-void pan_tilde_free(t_pan_tilde *x)
-{
- inlet_free(x->x_in2);
- inlet_free(x->x_in3);
- outlet_free(x->x_out);
-}
-
-void *pan_tilde_new(t_floatarg f)
-{
- t_pan_tilde *x = (t_pan_tilde *)pd_new(pan_tilde_class);
-
- x->f_pan = f;
-
- x->x_in2=inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
- x->x_in3=floatinlet_new (&x->x_obj, &x->f_pan);
- x->x_out=outlet_new(&x->x_obj, &s_signal);
-
- return (void *)x;
-}
-
-void pan_tilde_setup(void) {
- pan_tilde_class = class_new(gensym("pan~"),
- (t_newmethod)pan_tilde_new,
- 0, sizeof(t_pan_tilde),
- CLASS_DEFAULT,
- A_DEFFLOAT, 0);
-
- class_addmethod(pan_tilde_class,
- (t_method)pan_tilde_dsp, gensym("dsp"), 0);
- CLASS_MAINSIGNALIN(pan_tilde_class, t_pan_tilde, f);
-}
-\end{verbatim}
-
-\vfill
-\newpage
-\begin{appendix}
-
-\section{Pd's message-system}
-Non-audio-data are distributed via a message-system.
-Each message consists of a ``selector'' and a list of atoms.
-
-\subsection{atoms}
-
-There are three kinds of atoms:
-\begin{itemize}
-\item {\em A\_FLOAT}: a numerical value (floating point)
-\item {\em A\_SYMBOL}: a symbolic value (string)
-\item {\em A\_POINTER}: a pointer
-\end{itemize}
-
-Numerical values are always floating point-values (\verb+t_float+),
-even if they could be displayed as integer values.
-
-Each symbol is stored in a lookup-table for reasons of performance.
-The command \verb+gensym+ looks up a string in the lookup-table and
-returns the address of the symbol.
-If the string is not yet to be found in the table,
-a new symbol is added.
-
-Atoms of type {\em A\_POINTER} are not very important (for simple externals).
-
-The type of an atom \verb+a+ is stored in the structure-element \verb+a.a_type+.
-
-\subsection{selectors}
-The selector is a symbol that defines the type of a message.
-There are five predefined selectors:
-\begin{itemize}
-\item ``{\tt bang}'' labels a trigger event.
-A ``bang''-message consists only of the selector and contains no lists of atoms.
-\item ``{\tt float}'' labels a numerical value.
-The list of a ``float''-Message contains one single atom of type {\em A\_FLOAT}
-\item ``{\tt symbol}'' labels a symbolic value.
-The list of a ``symbol''-Message contains one single atom of type {\em A\_SYMBOL}
-\item ``{\tt pointer}'' labels a pointer value.
-The list of a ``pointer''-Message contains one single atom of type {\em A\_POINTER}
-\item ``{\tt list}'' labels a list of one or more atoms of arbitrary type.
-\end{itemize}
-
-Since the symbols for these selectors are used quite often,
-their address in the lookup-table can be queried directly,
-without having to use \verb+gensym+:
-
-\begin{tabular}{l||l|l}
-selector&lookup-routine&lookup-address\\
-\hline
-\tt bang &\verb+gensym("bang")+ & \verb+&s_bang+ \\
-\tt float &\verb+gensym("float")+ & \verb+&s_float+ \\
-\tt symbol &\verb+gensym("symbol")+ & \verb+&s_symbol+ \\
-\tt pointer &\verb+gensym("pointer")+ & \verb+&s_pointer+ \\
-\tt list &\verb+gensym("list")+ & \verb+&s_list+ \\
---- (signal) &\verb+gensym("signal")+&\verb+&s_symbol+
-\end{tabular}
-
-Other selectors can be used as well.
-The receiving class has to provide a method for a specifique selector
-or for ``anything'', which is any arbitrary selector.
-
-Messages that have no explicit selector and start with a numerical value,
-are recognised automatically either as ``float''-message (only one atom) or as
-``list''-message (several atoms).
-
-For example, messages ``\verb+12.429+'' and ``\verb+float 12.429+'' are identical.
-Likewise, the messages ``\verb+list 1 for you+'' is identical to ``\verb+1 for you+''.
-
-\section{Pd-types}
-Since Pd is used on several platforms,
-many ordinary types of variables, like \verb|int|, are re-defined.
-To write portable code, it is reasonable to use types provided by Pd.
-
-Apart from this there are many predefined types,
-that should make the life of the programmer simpler.
-
-Generally, Pd-types start with \verb|t_|.
-
-\begin{tabular}{c|l}
-Pd-type & description \\
-\hline\hline
-\verb+t_atom+& atom \\
-\verb+t_float+ & floating point value\\
-\verb+t_symbol+ & symbol \\
-\verb+t_gpointer+ & pointer (to graphical objects) \\
-\hline
-\verb+t_int+ & integer value \\
-\verb+t_signal+ & structure of a signal \\
-\verb+t_sample+ & audio signal-value (floating point)\\
-\verb+t_outlet+ & outlet of an object \\
-\verb+t_inlet+ & inlet of an object \\
-\verb+t_object+ & object-interna \\
-\hline
-\verb+t_class+ & a Pd-class \\
-\verb+t_method+ & class-method \\
-\verb+t_newmethod+ & pointer to a constructor (new-routine) \\
-\end{tabular}
-
-
-\section{important functions in ``m\_pd.h''}
-
-\subsection{functions: atoms}
-
-\subsubsection{SETFLOAT}
-\begin{verbatim}
-SETFLOAT(atom, f)
-\end{verbatim}
-This macro sets the type of \verb+atom+ to \verb+A_FLOAT+
-and stores the numerical value \verb+f+ in this atom.
-
-\subsubsection{SETSYMBOL}
-\begin{verbatim}
-SETSYMBOL(atom, s)
-\end{verbatim}
-This macro sets the type of \verb+atom+ to \verb+A_SYMBOL+
-and stores the symbolic pointer \verb+s+ in this atom.
-
-\subsubsection{SETPOINTER}
-\begin{verbatim}
-SETPOINTER(atom, pt)
-\end{verbatim}
-This macro sets the type of \verb+atom+ to \verb+A_POINTER+
-and stores the pointer \verb+pt+ in this atom.
-
-\subsubsection{atom\_getfloat}
-\begin{verbatim}
-t_float atom_getfloat(t_atom *a);
-\end{verbatim}
-If the type of the atom \verb+a+ is \verb+A_FLOAT+,
-the numerical value of this atom else ``0.0'' is returned.
-
-\subsubsection{atom\_getfloatarg}
-\begin{verbatim}
-t_float atom_getfloatarg(int which, int argc, t_atom *argv)
-\end{verbatim}
-If the type of the atom -- that is found at in the atom-list
-\verb+argv+ with the length \verb+argc+ at the place \verb+which+ --
-is \verb+A_FLOAT+, the numerical value of this atom else ``0.0'' is returned.
-
-\subsubsection{atom\_getint}
-\begin{verbatim}
-t_int atom_getint(t_atom *a);
-\end{verbatim}
-If the type of the atom \verb+a+ is \verb+A_FLOAT+,
-its numerical value is returned as integer else ``0'' is returned.
-
-\subsubsection{atom\_getsymbol}
-\begin{verbatim}
-t_symbol atom_getsymbol(t_atom *a);
-\end{verbatim}
-If the type of the atom \verb+a+ is \verb+A_SYMBOL+,
-a pointer to this symbol is returned, else a null-pointer ``0'' is returned.
-
-\subsubsection{atom\_gensym}
-\begin{verbatim}
-t_symbol *atom_gensym(t_atom *a);
-\end{verbatim}
-If the type of the atom \verb+a+ is \verb+A_SYMBOL+,
-a pointer to this symbol is returned.
-
-Atoms of a different type, are ``reasonably'' converted into a string.
-This string is -- on demand -- inserted into the symbol-table.
-A pointer to this symbol is returned.
-
-\subsubsection{atom\_string}
-\begin{verbatim}
-void atom_string(t_atom *a, char *buf, unsigned int bufsize);
-\end{verbatim}
-Converts an atom \verb+a+ into a {\tt C}-string \verb+buf+.
-The memory to this char-Buffer has to be reserved manually and
-its length has to be declared in \verb+bufsize+.
-
-\subsubsection{gensym}
-\begin{verbatim}
-t_symbol *gensym(char *s);
-\end{verbatim}
-Checks, whether the C-string \verb+*s+ has already been inserted into the symbol-table.
-If no entry exists, it is created.
-A pointer to the symbol is returned.
-
-\subsection{functions: classes}
-\subsubsection{class\_new}
-\begin{verbatim}
-t_class *class_new(t_symbol *name,
- t_newmethod newmethod, t_method freemethod,
- size_t size, int flags,
- t_atomtype arg1, ...);
-\end{verbatim}
-Generates a class with the symbolic name \verb+name+.
-\verb+newmethod+ is the constructor that creates an instance of the class and
-returns a pointer to this instance.
-
-If memory is reserved dynamically, this memory has to be freed by the
-destructor-method \verb+freemethod+ (without any return argument),
-when the object is destroyed.
-
-\verb+size+ is the static size of the class-data space,
-that is returned by \verb+sizeof(t_mydata)+.
-
-\verb+flags+ define the presentation of the graphical object.
-A (more or less arbitrary) combination of following objects is possible:
-
-\begin{tabular}{l|l}
-flag&description\\
-\hline
-\verb+CLASS_DEFAULT+ & a normal object with one inlet \\
-\verb+CLASS_PD+ & \em object (without graphical presentation) \\
-\verb+CLASS_GOBJ+ & \em pure graphical object (like arrays, graphs,...)\\
-\verb+CLASS_PATCHABLE+ & \em a normal object (with one inlet) \\
-\verb+CLASS_NOINLET+ & the default inlet is suppressed \\
-\end{tabular}
-
-Flags the description of which is printed in {\em italic}
-are of small importance for writing externals.
-
-The remaining arguments \verb+arg1,...+ define the
-types of object-arguments passed at the creation of a class-object.
-A maximum of six type checked arguments can be passed to an object.
-The list of argument-types are terminated by ``0''.
-
-Possible types of arguments are:
-
-\begin{tabular}{l|l}
-\verb+A_DEFFLOAT+ & a numerical value \\
-\verb+A_DEFSYMBOL+ & a symbolical value \\
-\verb+A_GIMME+ & a list of atoms of arbitrary length and types \\
-\end{tabular}
-
-If more than six arguments are to be passed,
-\verb+A_GIMME+ has to be used and a manual type-check has to be made.
-
-\subsubsection{class\_addmethod}
-\begin{verbatim}
-void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
- t_atomtype arg1, ...);
-\end{verbatim}
-Adds a method \verb+fn+ for a selector \verb+sel+ to a class \verb+c+.
-
-The remaining arguments \verb+arg1,...+ define the
-types of the list of atoms that follow the selector.
-A maximum of six type-checked arguments can be passed.
-If more than six arguments are to be passed,
-\verb+A_GIMME+ has to be used and a manual type-check has to be made.
-
-The list of arguments is terminated by ``0''.
-
-
-Possible types of arguments are:
-
-\begin{tabular}{l|l}
-\verb+A_DEFFLOAT+ & a numerical value \\
-\verb+A_DEFSYMBOL+ & a symbolical value \\
-\verb+A_POINTER+ & a pointer \\
-\verb+A_GIMME+ & a list of atoms of arbitrary length and types \\
-\end{tabular}
-
-\subsubsection{class\_addbang}
-\begin{verbatim}
-void class_addbang(t_class *c, t_method fn);
-\end{verbatim}
-Adds a method \verb+fn+ for ``bang''-messages to the class \verb+c+.
-
-The argument of the ``bang''-method is a pointer to the class-data space:
-
-\verb+void my_bang_method(t_mydata *x);+
-
-\subsubsection{class\_addfloat}
-\begin{verbatim}
-void class_addfloat(t_class *c, t_method fn);
-\end{verbatim}
-Adds a method \verb+fn+ for ``float''-messages to the class \verb+c+.
-
-The arguments of the ``float''-method is a pointer to the class-data space and
-a floating point-argument:
-
-\verb+void my_float_method(t_mydata *x, t_floatarg f);+
-
-\subsubsection{class\_addsymbol}
-\begin{verbatim}
-void class_addsymbol(t_class *c, t_method fn);
-\end{verbatim}
-Adds a method \verb+fn+ for ``symbol''-messages to the class \verb+c+.
-
-The arguments of the ``symbol''-method is a pointer to the class-data space and
-a pointer to the passed symbol:
-
-\verb+void my_symbol_method(t_mydata *x, t_symbol *s);+
-
-\subsubsection{class\_addpointer}
-\begin{verbatim}
-void class_addpointer(t_class *c, t_method fn);
-\end{verbatim}
-Adds a method \verb+fn+ for ``pointer''-messages to the class \verb+c+.
-
-The arguments of the ``pointer''-method is a pointer to the class-data space and
-a pointer to a pointer:
-
-\verb+void my_pointer_method(t_mydata *x, t_gpointer *pt);+
-
-\subsubsection{class\_addlist}
-\begin{verbatim}
-void class_addlist(t_class *c, t_method fn);
-\end{verbatim}
-Adds a method \verb+fn+ for ``list''-messages to the class \verb+c+.
-
-The arguments of the ``list''-method are -- apart from a pointer to the class-data space --
-a pointer to the selector-symbol (always \verb+&s_list+),
-the number of atoms and a pointer to the list of atoms:
-
-\verb+void my_list_method(t_mydata *x,+
-
-\verb+ t_symbol *s, int argc, t_atom *argv);+
-
-\subsubsection{class\_addanything}
-\begin{verbatim}
-void class_addanything(t_class *c, t_method fn);
-\end{verbatim}
-Adds a method \verb+fn+ for an arbitrary message to the class \verb+c+.
-
-The arguments of the anything-method are -- apart from a pointer to the class-data space --
-a pointer to the selector-symbol,
-the number of atoms and a pointer to the list of atoms:
-
-\verb+void my_any_method(t_mydata *x,+
-
-\verb+ t_symbol *s, int argc, t_atom *argv);+
-
-\subsubsection{class\_addcreator}
-\begin{verbatim}
- void class_addcreator(t_newmethod newmethod, t_symbol *s,
- t_atomtype type1, ...);
-\end{verbatim}
-Adds a creator-symbol \verb+s+, alternative to the symbolic class name,
-to the constructor \verb+newmethod+.
-Thus, objects can be created either by their ``real'' class name or
-an alias-name (p.e. an abbreviation, like the internal ``float'' resp. ``f'').
-
-The ``0''-terminated list of types corresponds to that of \verb+class_new+.
-
-\subsubsection{class\_sethelpsymbol}
-\begin{verbatim}
-void class_sethelpsymbol(t_class *c, t_symbol *s);
-\end{verbatim}
-
-If a Pd-object is right-clicked, a help-patch for the corresponding object class
-can be opened.
-By default this is a patch with the symbolic class name in the
-directory ``{\em doc/5.reference/}''.
-
-The name of the help-patch for the class that is pointed to by \verb+c+
-is changed to the symbol \verb+s+.
-
-Therefore, several similar classes can share a single help-patch.
-
-Path-information is relative to the default help path {\em doc/5.reference/}.
-
-\subsubsection{pd\_new}
-\begin{verbatim}
-t_pd *pd_new(t_class *cls);
-\end{verbatim}
-Generates a new instance of the class \verb+cls+ and
-returns a pointer to this instance.
-
-\subsection{functions: inlets and outlets}
-All routines for inlets and outlets need a reference to the object-interna of
-the class-instance.
-When instantiating a new object,
-the necessary data space-variable of the \verb+t_object+-type is initialised.
-This variable has to be passed as the \verb+owner+-object to the
-various inlet- and outlet-routines.
-
-\subsubsection{inlet\_new}
-\begin{verbatim}
-t_inlet *inlet_new(t_object *owner, t_pd *dest,
- t_symbol *s1, t_symbol *s2);
-\end{verbatim}
-Generates an additional ``active'' inlet for the object
-that is pointed at by \verb+owner+.
-Generally, \verb+dest+ points at ``\verb+owner.ob_pd+''.
-
-The selector \verb+s1+ at the new inlet is substituted by the selector \verb+s2+.
-
-If a message with selector \verb+s1+ appears at the new inlet,
-the class-method for the selector \verb+s2+ is called.
-
-This means
-\begin{itemize}
-\item The substituting selector has to be declared by \verb+class_addmethod+
-in the setup-routine.
-\item It is possible to simulate a certain right inlet, by sending a message with
-this inlet's selector to the leftmost inlet.
-
-Using an empty symbol (\verb+gensym("")+) as selector
-makes it impossible to address a right inlet via the leftmost one.
-
-\item It is not possible to add methods for more than one selector to a right inlet.
-Particularly it is not possible to add a universal method for arbitrary selectors to
-a right inlet.
-\end{itemize}
-
-\subsubsection{floatinlet\_new}
-\begin{verbatim}
-t_inlet *floatinlet_new(t_object *owner, t_float *fp);
-\end{verbatim}
-Generates a new ``passive'' inlet for the object that is pointed at by \verb+owner+.
-This inlet enables numerical values to be written directly into the
-memory \verb+fp+, without calling a dedicated method.
-
-\subsubsection{symbolinlet\_new}
-\begin{verbatim}
-t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp);
-\end{verbatim}
-Generates a new ``passive'' inlet for the object that is pointed at by \verb+owner+.
-This inlet enables symbolic values to be written directly into the
-memory \verb+*sp+, without calling a dedicated method.
-
-
-\subsubsection{pointerinlet\_new}
-\begin{verbatim}
-t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp);
-\end{verbatim}
-Generates a new ``passive'' inlet for the object that is pointed at by \verb+owner+.
-This inlet enables pointer to be written directly into the
-memory \verb+gp+, without calling a dedicated method.
-
-\subsubsection{outlet\_new}
-\begin{verbatim}
-t_outlet *outlet_new(t_object *owner, t_symbol *s);
-\end{verbatim}
-Generates a new outlet for the object that is pointed at by \verb+owner+.
-The Symbol \verb+s+ indicates the type of the outlet.
-
-\begin{tabular}{c|l||l}
-symbol & symbol-address & outlet-type \\
-\hline\hline
-``bang'' & \verb+&s_bang+ & message (bang)\\
-``float'' & \verb+&s_float+ & message (float)\\
-``symbol'' & \verb+&s_symbol+ & message (symbol) \\
-``pointer'' & \verb+&s_gpointer+ & message (pointer)\\
-``list'' & \verb+&s_list+ & message (list) \\
---- & 0 & message \\
-\hline
-``signal'' & \verb+&s_signal+ & signal \\
-\end{tabular}
-
-There are no real differences between outlets of the various message-types.
-At any rate, it makes code more easily readable,
-if the use of outlet is shown at creation-time.
-For outlets for any messages a null-pointer is used.
-Signal-outlet must be declared with \verb+&s_signal+.
-
-Variables if the type \verb+t_object+ provide pointer to one outlet.
-Whenever a new outlet is generated, its address is stored in the
-object variable \verb+(*owner).ob_outlet+.
-
-If more than one message-outlet is needed,
-the outlet-pointers that are returned by \verb+outlet_new+
-have to be stored manually in the data space
-to address the given outlets.
-
-\subsubsection{outlet\_bang}
-\begin{verbatim}
-void outlet_bang(t_outlet *x);
-\end{verbatim}
-Outputs a ``bang''-message at the outlet specified by \verb+x+.
-
-\subsubsection{outlet\_float}
-\begin{verbatim}
-void outlet_float(t_outlet *x, t_float f);
-\end{verbatim}
-Outputs a ``float''-message with the numeric value \verb+f+
-at the outlet specified by \verb+x+.
-
-\subsubsection{outlet\_symbol}
-\begin{verbatim}
-void outlet_symbol(t_outlet *x, t_symbol *s);
-\end{verbatim}
-Outputs a ``symbol''-message with the symbolic value \verb+s+
-at the outlet specified by \verb+x+.
-
-\subsubsection{outlet\_pointer}
-\begin{verbatim}
-void outlet_pointer(t_outlet *x, t_gpointer *gp);
-\end{verbatim}
-Outputs a ``pointer''-message with the pointer \verb+gp+
-at the outlet specified by \verb+x+.
-
-\subsubsection{outlet\_list}
-\begin{verbatim}
-void outlet_list(t_outlet *x,
- t_symbol *s, int argc, t_atom *argv);
-\end{verbatim}
-Outputs a ``list''-message at the outlet specified by \verb+x+.
-The list contains \verb+argc+ atoms.
-\verb+argv+ points to the first element of the atom-list.
-
-Independent of the symbol \verb+s+, the selector ``list'' will precede
-the list.
-
-To make the code more readable,
-\verb+s+ should point to the symbol list
-(either via \verb+gensym("list")+ or via \verb+&s_list+)
-
-\subsubsection{outlet\_anything}
-\begin{verbatim}
-void outlet_anything(t_outlet *x,
- t_symbol *s, int argc, t_atom *argv);
-\end{verbatim}
-Outputs a message at the outlet specified by \verb+x+.
-
-The message-selector is specified with \verb+s+.
-It is followed by \verb+argc+ atoms.
-\verb+argv+ points to the first element of the atom-list.
-
-\subsection{functions: DSP}
-If a class should provide methods for digital signal-processing,
-a method for the selector ``dsp'' (followed by no atoms)
-has to be added to this class
-
-Whenever Pd's audio engine is started,
-all objects that provide a ``dsp''-method are identified as instances of signal classes.
-
-\paragraph{DSP-method}
-
-\begin{verbatim}
-void my_dsp_method(t_mydata *x, t_signal **sp)
-\end{verbatim}
-
-In the ``dsp''-method a class method for signal-processing
-is added to the DSP-tree by the function \verb+dsp_add+.
-
-Apart from the data space \verb+x+ of the object,
-an array of signals is passed.
-The signals in the array are arranged in such a way,
-that they can be read in the graphical representation of the object
-clockwisely.
-
-In case there are both two in- and out-signals, this means:
-
-\begin{tabular}{c|r}
-pointer & to signal \\
-\hline\hline
-sp[0] & left in-signal \\
-sp[1] & right in-signal \\
-sp[2] & right out-signal \\
-sp[3] & left out-signal \\
-\end{tabular}
-
-The signal structure contains apart from other things:
-
-\begin{tabular}{c|l}
-structure-element & description \\
-\hline
-\verb+s_n+ & length of the signal vector \\
-\verb+s_vec+ & pointer to the signal vector \\
-\end{tabular}
-
-The signal vector is an array of samples of type \verb+t_sample+.
-
-\paragraph{perform-routine}
-\begin{verbatim}
-t_int *my_perform_routine(t_int *w)
-\end{verbatim}
-
-
-A pointer \verb+w+ to an array (of integer) is passed to
-the perform-routine that is inserted into the DSP-tree by \verb+class_add+.
-
-In this array the pointers that are passed via \verb+dsp_add+ are stored.
-These pointers have to be casted back to their original type.
-
-The first pointer is stored at \verb+w[1]+ !!!
-
-The perform-routine has to return a pointer to integer,
-that points directly behind the memory, where the object's pointers are stored.
-This means, that the return-argument equals the routine's argument \verb+w+
-plus the number of used pointers
-(as defined in the second argument of \verb+dsp_add+) plus one.
-
-\subsubsection{CLASS\_MAINSIGNALIN}
-\begin{verbatim}
-CLASS_MAINSIGNALIN(<class_name>, <class_data>, <f>);
-\end{verbatim}
-The macro \verb+CLASS_MAINSIGNALIN+ declares,
-that the class will use signal-inlets.
-
-The first macro-argument is a pointer to the signal-class.
-The second argument is the type of the class-data space.
-The third argument is a (dummy-)floating point-variable of the data space,
-that is needed to automatically convert ``float''-messages into signals
-if no signal is present at the signal-inlet.
-
-No ``float''-methods can be used for signal-inlets, that are created this way.
-
-\subsubsection{dsp\_add}
-\begin{verbatim}
-void dsp_add(t_perfroutine f, int n, ...);
-\end{verbatim}
-Adds the perform-routine \verb+f+ to the DSP-tree.
-The perform-routine is called at each DSP-cycle.
-
-The second argument\verb+n+ defines the number of following pointer-arguments
-
-Which pointers to which data are passes is not limited.
-Generally, pointers to the data space of the object and to the
-signal-vectors are reasonable.
-The length of the signal-vectors should also be passed to manipulate signals effectively.
-
-\subsubsection{sys\_getsr}
-\begin{verbatim}
-float sys_getsr(void);
-\end{verbatim}
-Returns the sampler ate of the system.
-
-\subsection{functions: memory}
-\subsubsection{getbytes}
-\begin{verbatim}
-void *getbytes(size_t nbytes);
-\end{verbatim}
-Reserves \verb+nbytes+ bytes and returns a pointer to the allocated memory.
-
-\subsubsection{copybytes}
-\begin{verbatim}
-void *copybytes(void *src, size_t nbytes);
-\end{verbatim}
-Copies \verb+nbytes+ bytes from \verb+*src+ into a newly allocated memory.
-The address of this memory is returned.
-
-\subsubsection{freebytes}
-\begin{verbatim}
-void freebytes(void *x, size_t nbytes);
-\end{verbatim}
-Frees \verb+nbytes+ bytes at address \verb+*x+.
-
-\subsection{functions: output}
-\subsubsection{post}
-\begin{verbatim}
-void post(char *fmt, ...);
-\end{verbatim}
-
-Writes a {\tt C}-string to the standard error (shell).
-
-\subsubsection{error}
-\begin{verbatim}
-void error(char *fmt, ...);
-\end{verbatim}
-
-Writes a {\tt C}-string as an error-message to the standard error (shell).
-
-The object that has output the error-message is marked and
-can be identified via the Pd-menu {\em Find->Find last error}.
-
-\end{appendix}
-
-\end{document}
-