TclPd primer

In a Tcl script a variable can occur in two ways; as "varName" if you want to change it, and as "$varName" if you want to use its value.

Examples:

set varName 42 ;# sets the variable varName to 42

puts $varName ;# prints the value of varName

BTW, "#" characters at the start of the line indicate a comment line. To add comment at the end of a line with code use ";#".

In Tcl, code within []'s is executed before the result is passed on for interpretation with the code outside the []'s.

proc+

The tclPd environment also adds a special type of procedure: proc+. All procedures which relate to inlets need to be of the proc+ type. Other procedures can be the normal proc type.

The header line of proc+ procedures typically look like:

proc+ counting::0_float {self args} {

Here "counting::" is the namespace of the object, but you can see it as the class the procedure belongs to.

The "0_float" indicates this procedure handles floats for inlet 0.

The "{self args}" are the arguments to the procedure. "self" identifies the instance, used by "pd::.." procedures to specify which instance is calling. "args" is an array containing the arguments, the actual values on the inlet. For a float inlet there is only one.

constructor

The constructor usually contains the creation of extra inlets (you get one for free) and outlets, and the definition of object instance variables.

It is the equivalent of the _setup function in c externals.

@variables

Variables are only available within the procedure in which they are defined. To have variables that are valid within all procedures of an object, the tclPd environment adds a new type with a special notation: "@varName". These object instance variables should be set in the constructor procedure, and can be used in the other procedures, the same way as normal variables.

Examples:

set @varName 42 ;# sets the variable varName to 42

puts $@varName ;# prints the value of varName

Inlets and outlets

Adding inlets and outlets is done in the constructor procedure.

Examples:

pd::add_inlet $self float ;# inlet 1

pd::add_outlet $self float ;# outlet 0

The type "float" in this case does not seem to be very important.

Inlet procedures

All ata send to inlets are handled in procedures, always per inlet and usually per type.

Example:

proc+ helloWorld::0_bang {self args} { ....

This is part of the procedure for the helloWorld oblect handling bangs on inlet 0.

proc+ counting::0_float {self args} {
set inlet0Value [pd::arg 0 float]

This are the first lines of the procedure for the counting object handing floats on inlet 0. The first argument is placed into variable inlet0Value.

It is possible to make a procedure for all types with "proc+ counting::0_anything {", but then you have to find out the type yourself.

The number of arguments can be retrieved with the Tcl command "llength $args".

Sending values to outlets is done with pd::outlet, specifying the outlet number and the type.

Examples:

pd::outlet $self 1 float $counter

Here the value of the counter variable is send as float to outlet 1. The $self identifies the calling instance to the pd::outlet procedure. The "float" specifies the selector, the "type" in Pd.

Lists

Lists exist in both Tcl and Pd, but the Pd mechanism of selectors means they need some special handling when they move between Tcl and Pd.

Example:

proc+ ${objectName}::0_list {self args} {
    set key     [pd::arg 0 float]
    set value   [pd::arg 1 float]
    set channel [pd::arg 2 float] 

Reading a Pd list in a Tcl procedure is relative simple, in this case each value is read as a float from the args array.

pd::outlet $self 0 list [pd::add_selectors [list $key $velocity $channel]]

Here a list is created first, and have the selectors added. Then it is send to the outlet as type "list"