%  devnodes.tex from ObjectProDSP 0.2
%  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
%  
%  This file is part of ObjectProDSP, a tool for Digital Signal
%  Processing design, development and implementation. It is free
%  software provided you use and distribute it under the terms of
%  version 2 of the GNU General Public License as published
%  by the Free Software Foundation. You may NOT distribute it or
%  works derived from it or code that it generates under ANY
%  OTHER terms.  In particular NONE of the ObjectProDSP system is
%  licensed for use under the GNU General Public LIBRARY License.
%  Mountain Math Software plans to offer a commercial version of
%  ObjectProDSP for a fee. That version will allow redistribution
%  of generated code under standard commercial terms.
%  
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%  GNU General Public License for more details.
%  
%  You should have received a copy of version 2 of the GNU General
%  Public License along with this program. See file COPYING. If not
%  or if you wish information on commercial versions and licensing
%  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
%  USA, or send us e-mail at: support@mtnmath.com.
%  
%  You may also obtain the GNU General Public License by writing the
%  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
%  USA.  However if you received a copy of this program without the
%  file COPYING or without a copyright notice attached to all text
%  files, libraries and executables please inform Mountain Math Software.
%  
%  ObjectProDSP is a trademark of Mountain Math Software.
%  
\section{Creating nodes with \protect\IntPp{}}
\label{Sec:IntPp}

\IntPp{} translates a single `\DppNm{.usr}' file into two pairs of
\Cpp{} `\DppNm{.h}' and `\DppNm{.C}' files and additional files
for documentation and to support integration with the menu data
base. The complete list of these files and the sections that
describe them are in Table~\PageRef{Tab:IntPpFiles}.

\begin{table}
\begin{center}
\begin{tabular}{|lllr|} \hline
File & Purpose & Section & Page\\ \hline
\DppNm{xxx.h} & Interactive \Cpp{} header \tref{Sec:FilesInteractive} \\
\DppNm{xxx.C} & Interactive \Cpp{} file \tref{Sec:FilesInteractive} \\
\DppNm{target/xxx.h} & Target \Cpp{} header \tref{Sec:FilesTarget} \\
\DppNm{target/xxx.C} & Target \Cpp{} file \tref{Sec:FilesTarget} \\
\DppNm{tex/xxx.tex} & Node library documentation \tref{Sec:FilesTarget} \\
\DppNm{texs/xxx.tex} & Node summary documentation \tref{Sec:FilesDoc} \\
\DppNm{menus/nodes/xxx.nod} &
    Menu data base \tref{Sec:FilesDataBase} \\
\DppNm{xxxI.h} & Data base initialization \tref{Sec:FilesDataBase} \\
\DppNm{xxx.s} & Text for spelling checker \tref{Sec:FilesDataBase} \\
\hline
\end{tabular}
\caption{Files generated by \IntPp{} from a `\protect\DppNm{.usr}' file}
\label{Tab:IntPpFiles}
\end{center}
\end{table}

We will describe the syntax of the input file, discuss the semantics
and explain how to  integrate a node into \Dpp{}.

\subsection{\protect\IntPp{} class definition}

Figure~\PageRef{Fig:blockusr} shows a sample DSP node definition
in \IntPp{}. First are `include' statements. There
are several types of `include' statements that refer to different
points in the multiple files that will be generated. These
are listed in Table~\PageRef{Tab:IncludeOpt}.
\label{Sec:IncludeOpt}

There is then a declaration of the constructor for this class that
includes documentation.
The class name is followed by a parenthesized list of parameter
descriptions.
These descriptions have three elements. First is a line
that gives the parameter type, default value and bounds.
The allowed types are given in Table~\PageRef{Tab:IntPpDataTypes}.
The key words \DppNm{Min} and \DppNm{Max} designate the largest
and smallest values for a given data type.


\input{blockusr.tex}

\begin{table}
\begin{center}
\begin{tabular}{|lcccc|} \hline
Name & File & Interactive & Target & Before standard includes \\ \hline
\DppNm{Cinclude} &  `\verb".C"' & yes & yes & yes \\
\DppNm{Hinclude} &  `\verb".h"' & yes & yes & yes \\
\DppNm{cinclude} &  `\verb".C"' & yes & yes & no  \\
\DppNm{hinclude} &  `\verb".h"' & yes & yes & no  \\
\DppNm{ICinclude} & `\verb".C"' & yes & no  & yes \\
\DppNm{IHinclude} & `\verb".h"' & yes & no  & yes \\
\DppNm{Icinclude} & `\verb".C"' & yes & no  & no  \\
\DppNm{Ihinclude} & `\verb".h"' & yes & no  & no  \\
\DppNm{TCinclude} & `\verb".C"' & no  & yes & yes \\
\DppNm{THinclude} & `\verb".h"' & no  & yes & yes \\
\DppNm{Tcinclude} & `\verb".C"' & no  & yes & no  \\
\DppNm{Thinclude} & `\verb".h"' & no  & yes & no  \\
\hline
\end{tabular}
\caption{\protect\IntPp{} include options}
\index{include options}
\label{Tab:IncludeOpt}
\end{center}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|ll|} \hline
Name & Definition \\ \hline
int16 & 16 bit integers \\
int32 & 32 bit integers \\
MachWord & native machine word of simulator \\
double & double precision floating point \\
string & character string \\
{\it class} & any \IntPp{} object in {\it class} \\ 
\hline
\end{tabular}
\caption{\protect\IntPp{} data types}
\index{include options}
\label{Tab:IntPpDataTypes}
\end{center}
\end{table}

Any \IntPp{} class can be the type of a parameter.
The syntax for this and for type \DppNm{string} is different
from that for numeric values. Only the default and not the bounds
are relevant for these data types. The default for a string
can be 0 to represent a null pointer.


Either or both of two
key words can precede the data type. \DppNm{Changeable}
indicates that the parameter can be modified after the constructor
is called. An entry in the menu for the object instance under
\DppNm{set} to change
the value is generated for each \DppNm{Changeable}
parameter. 
\DppNm{FirstDefault} indicates that this variable and
\label{ExpFirstDef}
all subsequent variables can be assigned default values when
the constructor is typed in. (The menu data base \verb"create default"
option assigns all default parameters without regard to \DppNm{FirstDefault}.)

Following the parameter and bounds check is a \DppNm{MenuLine} this
gives a brief synopsis of the parameter. This synopsis will appear
in the menu data base above the buttons when the cursor is positioned
over the button for this parameter. This line will be used
in the printed documentation to provide a brief description of
the parameter. Next is an optional \verb"Description" that provides
a more complete description of the parameter. This description
will appear in the {\tt \Dpp{} information} window whenever
the mouse button is pressed in a button representing this parameter.
This description will also be used in the printed documentation.

After the parenthesis that closes the parameter list there is
`\verb": public"' followed by a base class constructor.
There must always be a base class to tie this node into the
existing \Dpp{} class structure. Table~\PageRef{Tab:IntPpBaseClasses} gives
the base classes ordinarily used for DSP objects. It is possible to
define base classes with `\DppNm{.usr}' files but all base classes must
ultimately be built on classes predefined within \Dpp{} that do
not have a `\DppNm{.usr}' file. The bottom of this hierarchy is
class \DppNm{UserEntity} which is common to all interactive objects.
There are seemingly redundant base classes in Table~\ref{Tab:IntPpBaseClasses}
ending with suffix `\DppNm{Str}'.\index{suffix Str} These refer
to different methods of defining parameters in the base class.
Those that end it `\DppNm{Str}' should be used. The others are for
backwards compatibility with nodes that have not been updated. 
Currently the \DppNm{BlockPlot} and \DppNm{Plot} classes are redundant
since all plot nodes support blocked and unblocked data. Eventually
some specialized plotting routines may not support blocked data.

Following the base class name are the parameters for the base
class constructor. These are not assigned in position order as they
are in \Cpp{} but are assigned by name. There are defaults for all
options. Only those for which the defaults are incorrect need to
be assigned. The allowed names differ with different base classes,
The base classes are described in Section~\PageRef{Sec:BaseClass}.

Next is a \DppNm{MenuLine} for the node. This is like the \DppNm{MenuLine} for each parameter but
it describes the node.

\subsection{Placing a node in the data base}
\label{Sec:PlaceNode}

The key word \DppNm{MenuLine} may be
followed by the name of a menu (defined in \DppNm{opd.menu}
described in Section~\PageRef{Sec:MenuDataBase}) to connect this
node to the menu data base. If this is not present the
node will be added to menu \DppNm{DspNodesMenu} (or another
standard menu as determined by the optional
{\tt InteractiveEntityList}
\index{InteractiveEntityList}
option described in Table~\PageRef{Sec:ClassDataBase}). This also
controls where the node will be documented in the printed
manuals.

The text of the \DppNm{MenuLine}  is followed by a \DppNm{Description}
of the class which is similar to the \DppNm{Description} of a parameter,

Next is an optional line that gives a \DppNm{HelpFile} for the class.
This file will appear in a separate window when the {\it right} mouse
button is released with the cursor over the button for this class.
See Section~\PageRef{Sec:HelpFile} for information on preparing and
integrating help files.

Following this are a number of optional sections and one mandatory section.
The mandatory section is the \DppNm{Kernel} which contains the code
to implement the kernel processing.

Unless the code for the node is short you may want to use include
or additional `\verb".C"' files for most of the kernel and
initialization  code.
The mandatory \verb"Kernel" section can call
another subroutine that does the processing. The best choice is
usually to use `\verb".C"' files.
The directory in which the `\DppNm{.usr}' file occurs is only used
for interactive code and not for target code. Any `\verb".C"' file
that is common to both should be paced in the subdirectory \DppNm{common}
under the directory containing the `\DppNm{.usr}' file.
If you use header files they
should be put in directory\\{\tt \$OPD\_ROOT/src/include/ObjProDSPcom}\\
\index{ObjProDSPcom} and referenced as {\tt "ObjProDSPcom/}{\it file\_name}.

\subsection{Simplified node syntax}
\index{node syntax}

Figure~\PageRef{Fig:NodeSyntax} gives a simplified \DppNm{yacc}
(or \DppNm{bison})
syntax for a node. The rules are in alphabetical order. The top level
symbol is \Index{DfNode}. Literal
terminal symbols are in {\tt typewriter} font
and enclosed in single quotes. Standard terminal symbols like
{\it integer} are in {\it italicized font}.
If a rule ends with `$\mid$'
it can be reduced to the null symbol.

Table~\PageRef{Tab:SyntaxTerminals} gives a brief explanation
for each nonterminal symbol and references for some.
The full \DppNm{yacc} (or \DppNm{bison}) syntax
is in file\\ {\tt \$OPD\_ROOT/src/util/mknode/mknod\_b.y}.\\
\index{mknod_b.y}
Note some constructs in the full syntax are for future
expansion (such as \DppNm{TargetDesignator}) and others 
are obsolete but retained for backwards compatibility.


{\small
\begin{figure}
\setlength{\parindent}{.2in}
\noindent
\Index{BaseDescription} : `{\tt \Index{BaseDescription}}' `\verb"{"' {\it text of description} `\verb"}"' \\
\Index{Body} : StateEmit Timing Kernel Instances \\
\Index{Comment} : `\DppNm{//}' {\it text to end of line } \\
\Index{Cpp} : `\verb"{"' {\it \Cpp{} code } `\verb"}"' \\
\Index{Ctor} : `{\tt \Index{Constructor}}' Cpp \\
\Index{Declaration} : ReferencedNameList DeclarationCode $\mid$ DeclarationCode \\
\Index{DeclarationCode} : `\DppNm{Class}' Cpp `\verb";"' \\
\Index{DefaultList} : NumParmValue $\mid$ `\{' NumberList `\}' \\
\Index{Description} : MenuLine FullDescription HelpFile \\ \indent $\mid$ MenuLine FullDescription \\
\Index{DfNode} : Header NodeDescription Body $\mid$ Header \\
\Index{DfNodeCtor} : BaseDfNodeCtor `,' OtherBaseList $\mid$ BaseDfNodeCtor $\mid$ \\
\Index{Dtor} : `{\tt \Index{Destructor}}' Cpp \\
\Index{FullDescription} : `{\tt \Index{Description}}' `\verb"{"' {\it text of description} `\verb"}"' \\
\Index{Header} : Includes ClassName NodeName Parameters HeaderEnd \\
\Index{HeaderEnd} : Declaration StaticDeclare StaticInit Ctor Dtor Safe \\
\Index{Help} : `{\tt \Index{HelpDefaultFile}}'  {\it string} \\
\Index{Instance} : Name '(' ConstantList ')' InstanceDescription \\
\Index{InstanceDescription} : Description $\mid$ \\
\Index{Instances} : Instances `{\tt \Index{Instance}}'  Instance ';' $\mid$ `{\tt \Index{NoDefaultInstance}}' ';' $\mid$ \\ 
\Index{InteractiveClass} : `{\tt \Index{InteractiveEntityList}}' {\it name} `\verb";"' \\
\Index{Kernel} : `{\tt \Index{Kernel}}' Cpp \\
\Index{Member} : {\it type} MemberName `(' ParameterList `)' `{\tt \Index{Wait}}' Description `;' \\
\Index{MemberHelp} : Member $\mid$ Help \\
\Index{MenuLine} : `{\tt \Index{MenuLine}}' `{\tt\{}' {\it text of description} `{\tt \}}' \\ 
\Index{NodeDescription} : Description $\mid$ BaseDescription \\
\Index{NodeDescription} : InteractiveClass DfNode $\mid$ DfNode \\
\Index{Parameter} : \\
	\indent {\it type} Name `:' ParamValue `\verb"<="' ParmValue `\verb"<="' ParmValue Description $\mid$ \\
	\indent {\it type} Name `:' ParmValue Description $\mid$ \\
	\indent{\it type} Name Size `:' ParmValue `\verb"<="' DefaultList `\verb"<="' ParmValue \\
\Index{ParameterAndCheck} : `{\tt FirstDefault}' Parameter $\mid$ \\
	\indent `{\tt FirstDefault}' Parameter {\tt \Index{CheckParameter}}' Cpp \\
\Index{ParameterList} : ParameterAndCheck $\mid$ ParameterList `,' ParameterAndCheck $\mid$  \\
\Index{Parameters} : `(' ParameterList `)' DfNodeCtor `;' \\
\Index{ReferencedNameList} : ReferencedNameList MemberHelp $\mid$ MemberHelp  \\
\Index{Safe} : `{\tt \Index{SafeDelete}}' Cpp \\
\Index{Size} : `[' {\it integer } `]' $\mid$ `[' {\it integer } `-' {\it integer } `]' $\mid$ \\
\Index{StateEmit} : `{\tt StateEmit}' Cpp \\
\Index{Timing} : `{\tt \Index{Timing}}' Cpp $\mid$ `{\tt Timing}' `(' Name `,' Name `)' Cpp  $\mid$ \\ \indent `{\tt Timing}' `('  `,' Name `)' Cpp $\mid$ `{\tt Timing}' `(' Name `,' `)' Cpp $\mid$ \\
\caption{\IntPp{} node syntax }
\label{Fig:NodeSyntax}
\end{figure}
}

\begin{table}
\begin{tabular}{|lllr|} \hline
\Index{Symbol} & Meaning & Section & Page\\ \hline
\Index{BaseDfNodeCtor} & constructor for primary base function & & \\
\Index{BaseDescription} & describes the purpose of a base class & & \\
\Index{Body} & parts needed only for an executable node & & \\
\Index{Comment} & \Cpp{} style comments can end any line & & \\
\Index{Cpp} & \Cpp{} code delimited with `\{' and `\}' & & \\
\Index{Ctor} & {\tt Ctor} constructor code & & \\
\Index{Declaration} & constructor and base class & & \\
\Index{DeclarationCode} & \Cpp{} class declarations \tref{Sec:MemObj} \\
\Index{Default} & marks first default \tref{ExpFirstDef} \\
\Index{DefaultList} & default values for an array parameter & & \\
\Index{DfNode} & node definition & & \\
\Index{DfNodeCtor} & base and member constructors & & \\
\Index{Dtor} & destructor code \tref{Sec:Dtor} \\
\Index{FullDescription} & long description of a construct & & \\
\Index{Header} & first part of node definition & & \\
\Index{Help} & default help file   \tref{Sec:HelpFile}  \\
\Index{Includes} & include files \tref{Sec:IncludeOpt} \\
\Index{InteractiveClass} & class of classes for node  \tref{Sec:ClassDataBase} \\
\Index{Kernel} & kernel code  \tref{Sec:Kernel} \\
\Index{MemberName} & member function name & & \\
\Index{Member} & member object or function \tref{Sec:MemObj} \\
\Index{MenuLine} & synopsis of object, parameter or function & & \\ 
\Index{NodeDescription} & documentation of node & & \\
\Index{NodeName} & class name of node being defined & & \\
\Index{NumParamValue} & numeric parameter value & & \\
\Index{NumberList} & list of numbers separated by a `,' & & \\
\Index{OtherBaseList} & member or base function constructor & & \\
\Index{ParamValue} & numeric (or {\tt enum} parameter value & & \\
\Index{Parameter} & name, limits and documentation & & \\
\Index{ParameterAndCheck} & full parameter definition  \tref{ParamChecking} \\
\Index{ParameterList} & for constructor or member function & & \\
\Index{Parameters} & constructor parameters and base & & \\
\Index{Safe} & code to test if node can be deleted \tref{SafeDelete} \\
\Index{Size} & allowed size of array parameter & & \\
\Index{StateEmit} & emit state code  \tref{StateEmit} \\
\Index{StaticDeclare} & members to preinitialize \tref{Sec:TarStatic} \\
\Index{StaticInit} & target preinitialization \tref{Sec:TarStatic} \\
\Index{Timing} & code for timing  \tref{Sec:NodeTiming} \\
\Index{Wait} & suspends user input until complete& & \\
\hline
\end{tabular}
\caption{Symbols in \IntPp{} syntax}
\label{Tab:SyntaxTerminals}
\end{table}


\subsection{Base classes}
\index{base classes}
\index{member functions}
\label{Sec:BaseClass}

Base classes in \IntPp{} function like and are implemented with
base classes in \Cpp{}. The concept is extended to provide interactive
member functions which are shared by all nodes with a common base
class. Multiple inheritance is not supported for interactive functions
but can be used for \Cpp{} only constructs. The base classes
and their purpose are
in Table~\PageRef{Tab:IntPpBaseClasses}. This table also lists
the parent class and the header file that defines the class.
These header files are in directory
\\{\tt \$OPD\_ROOT/src/include/ObjProDSPint/ObjProUsr}\\(for base classes
defined with a `\DppNm{.usr}' file) and
\\{\tt \$OPD\_ROOT/src/include/ObjProGui/ObjProNet}\\(for base classes
defined directly in \Cpp{}). The \DppNm{.usr}' for the base class
(if it exists) will be in some directory under {\tt \$OPD\_ROOT/src/dsp} or\\
{\tt \$OPD\_ROOT/src/dsp/dsp\_gui}.

\subsubsection{Base constructor}
\label{Sec:BaseConst}
\index{base constructor}

The base class constructor parameters determine the number of input
and output channels (\DppNm{IN} and \DppNm{OUT}) the type of data
on these channels (\DppNm{STREAM\_IN} and
\DppNm{STREAM\_OUT}) and the amount of output
data generated for a given amount of input data (\DppNm{NODE\_DELAY},
\DppNm{DELTA\_IN}, \DppNm{DELTA\_OUT} and \DppNm{OVERLAP}) and
other properties such as the node timing. The use of these
values to do process scheduling are described in \MMSusers{} in
the `Data flow model' subsection of the
chapter on `The \DPP{} language".

Additional constructor parameters are for
special classes of nodes such as those for plotting.

The parameters used in each base class are in
Table~\PageRef{Tab:IntPpBaseClasses}.
The parameters are described in alphabetical order in
Table~\PageRef{Tab:IntPpBaseClassParam} along with their type,
default value and bounds. For most parameters these characteristics
are the same for every base class that uses the parameter.
If this is not true the parameter entry is repeated for
each base class that uses
the parameter. These contain the name of the class and the limits
and defaults for that class. If there is no class name then the
entry applys to all base classes that use the parameter.
The table is split both horizontally and vertically into several
parts across pages.

\input{ctortab.tex}

\subsubsection{Inherited member functions}
\index{member functions}

Base class constructors define the generic characteristics of a node
and also determine what common interactive member functions they inherit.
Separate base classes are provided for signal creation, DSP processing
and display or output nodes. The list of these classes the nodes
that belong to them and references to their member functions are in the
chapter on `Class hierarchy' in \MMSusers{}.



\subsection{Data stream description}
\label{Sec:StreamStr}
\index{data stream}
\index{stream}

The class \DppNm{StreamStr} defined in file\\
{\tt \$OPD\_ROOT/src/include/ObjProGui/ObjProGui/strmstr.h} \\
\index{strmstr.h}
gives the \DppNm{ElementSize}, \DppNm{BlockSize} and \DppNm{StreamArithType}
for each channel. The constructor for a node creates one copy of this
structure for the input channels and another for the output channels.
Whenever practical it is best to write a node that works on as wide
variety of data types and that adjusts itself to
the data it receives. For example the \DppNm{Plot} node can
operate on real and complex input. It can also tell it its input
is from an FFT (using the \DppNm{BlockSize} parameter)
and generate a frequency axis. One does not need to set parameters
for these inputs. The \DppNm{Plot} node reads the information from
the \DppNm{StreamStr} object for its input channel.

The \DppNm{STREAM\_IN} and \DppNm{STREAM\_OUT} parameters for a node
can be set to specific values. To do this use the constructor for
\DppNm{StreamStr} that explicitly sets the values. There are
predefined objects for unblocked real (\DppNm{StreamReal})
and unblocked complex \DppNm{StreamComplex} data.
To use these use the constructor that operates on an existing
\DppNm{StreamStr} object, i. e. write\\
{\tt STREAM\_IN = new StreamStr(StreamComplex)}\\
to for a node with a complex input stream.
For a node that adjust to the input block and sample size
use the predefined object \DppNm{StreamNotSet}.

Signal generation nodes that read disk files (such as \DppNm{InputNode})
may not be able to
set the block and sample size until after they read the file that
contains this information.
Use the predefined object \DppNm{StreamNotInitialized} for these.

Most of the predefined objects set the \DppNm{ArithType} to the default
type of the simulator. A few allow you to set the output type, (\DppNm{Block})
or do type conversions(\DppNm{ToInteger} and \DppNm{ToMach}).
Only the 32 bit floating point
version of the simulator supports both integer and floating point
data streams.

It is possible to write nodes that will operate
on either 32 bit fixed point or 32 bit floating point data.
This is done using the arithmetic types defined in
Figrure~\PageRef{Fig:artyp}.

\begin{figure}
\input{artyp.tex}
\caption{\DppNm{ArithTypes} class for data stream arithmetic types}
\label{Fig:artyp}
\end{figure}

The arithmetic type of an output data stream must be defined before
any node is linked on one of its output channels.
The input arithmetic type can be defined any time before the network is
executed. There are two virtual functions that are used to
set these types. \DppNm{input\_linked} is called after the
first input channel to a node is linked. \DppNm{InitAfterLinked}
is called after the network has been completely linked but before
it is executed. If you need to propagate an arithmetic type
from the input of a node to the output you must do
this in \DppNm{input\_linked}. If you only need to adjust the
input type based on the data being input you can use \DppNm{InitAfterLinked}.
There is a standard base function \DppNm{DfNode::propagate\_arith\_type}
that will propagate the input arithmetic type from the first channel
linked to all other input channels and all output channels.
Figure~\PageRef{Fig:blockusr} is an example of how these functions are
declared. 

Information on the arithmetic type of channels is only available for
the interactive nodes and networks. Flags that determine the type
should be set in the above functions and these flags should
be declared \DppNm{Static} as described in Section~\PageRef{Sec:TarStatic}
so the values set by the interactive code will be preinitialized in
the target code.


\section{Member objects and functions}
\label{Sec:MemObj}
\index{member objects}
\index{member functions}
\index{Class}

Member objects and functions can be declared in three ways.
Members declared in the \DppNm{Class} construct are standard
\Cpp{} members. They are not accessible interactively and passed
unchanged by \IntPp{} to \Cpp{}.

Members objects declared inside the \DppNm{StaticDeclare} construct
are treated similarly for interactive execution. It is
assumed that these are initialized in the interactive simulator
prior to execution. These are then initialized to those value
when code is generated for stand alone execution as explained
in Section~\PageRef{Sec:TarStatic}.

\subsection{Interactive member functions}

The declaration for an interactive member function is similar to the
definition of an interactive class constructor. Entries for each
member function will appear in the menu data base under the class
and under each instance of the class. The functions can be
called from the \DppNm{instance} menus and can be called in \DPP{}
statements entered directly.

Member objects can be declared at the same place interactive member
functions are as the \DppNm{Member} syntactic construct. Currently
there is little difference between these and member functions declared
in the \DppNm{Class} construct.
If a variable {\it name} is declared in this way then a function
to access the variable called {\tt Get}{\it name}{\tt ()} is generated.
This is currently only a \Cpp{} and not an interactive function.


\subsection{Parameter checking}
\label{ParamChecking}
\index{parameter checking}
\index{consistency checking}

The most common form of parameter checking specifies upper
and lower inclusive bounds. The key words \DppNm{Min} and \DppNm{Max} can
be used to specify the limits for a particular data type.

For array parameters the limits apply to each value in the array. One
must also specify lower and upper limits on the array size as
shown in Figure~\PageRef{Fig:ArrayDeclare}. The array parameter
\DppNm{Coeff} in this example must contain at least 3
and no more than 1024 elements.
Each element can be between -30000 and 30000.

The type \DppNm{ScaledMachineWord} is provided to allow values to be
scaled as appropriate for a given simulator arithmetic. For the floating
point simulator the values will be as shown. For the 16 bit simulator
1.0 is multiplied by \DppNm{NornToOneMachWord} or 32768.
This is defined in file \\
\DppNm{ObjProArith/normone.h}. \\
The values inside the braces define the
default array which has four values.

\begin{figure}
\begin{verbatim}
ScaledMachWord * Coeff [ 3 - 1024 ] : -30000 <= {
      1.00018552e-01,
      3.70747893e-01,
      4.46594395e-01,
     -5.36969535e-01
} <= 30000

\end{verbatim}
\caption{Declaring an interactive array parameter}
\label{Fig:ArrayDeclare}
\end{figure}

You can include more general checks on parameters by placing
code after the \DppNm{CheckParameter} key word in the parameter
definition. Typically this is a subroutine call and not the
code to do the check. Examples are in \\
\verb"$OPD_ROOT/src/dsp/nodes/sigdsk/import.usr". The body of the
called subroutines is in \\
\verb"$OPD_ROOT/src/dsp/nodes/sigdsk/common/importi.C". 



\section{Node semantics}

There are several constructs that specify the semantics of the node
all of these (except the \DppNm{Kernel}) are optional.
These all consist of a key word followed
by \Cpp{} code enclosed in braces.

\begin{itemize}
\item{\DppNm{Kernel}} Code to process data. This section is required.
\item{\DppNm{Timing}} Time of first sample output.
\item{\DppNm{StateEmit}} Non standard state definition.
\item{\DppNm{SafeDelete}} Test if this object can be deleted.
\item{\DppNm{Destructor}} Delete an instance of the node.
\end{itemize}

\subsection{Node kernel}
\label{Sec:Kernel}
\index{kernel}
\index{DoNode}

The code following the key word \DppNm{Kernel} is used to define
the body of a member function \DppNm{DoNode} with the single
\DppNm{int32} parameter, \DppNm{k}. This is the number of `chunks'
to process. The chunk size is the product of the \DppNm{BlockSize},
the \DppNm{ElementSize} and \DppNm{IncrementOut}. (\DppNm{IncrementOut}
is set by the \DppNm{DELTA\_OUT} parameter described in
Table~\PageRef{Tab:IntPpConstParam}. The other values are
set in the same way and the other names are more consistent.

\DppNm{DoNode} will ordinarily not be called unless there is
enough available input data and output buffer space to process
\DppNm{k} blocks. If there is not a standard relationship between
the input samples available and the output space needed,
\DppNm{TimingTypeRandom} (see Section~\PageRef{Sec:NodeTiming}),
then it may not be possible to process \DppNm{k} blocks. It is
never necessary to process this much data for interactive
execution or for target execution with dynamic scheduling.
With fixed scheduling a node must process exactly the data it
is requested to process.
It is always necessary
to update the buffer pointers to reflect the data processed and
output written. 

The simplest way to process data is to use \DppNm{ReadWord} to
read an input sample and \DppNm{WriteWord} to write and output sample.
These adjust the buffer pointers and report an error if you wrap the
buffers. This is inefficient. Data can be accessed and updated
more efficiently using the routines that access data via pointers.
The declarations for these routines are given in ~\PageRef{Fig:DataAccess}
and their purpose given in
Table~\PageRef{Tab:DataAccess}. These are all member functions of
\DppNm{TargetNode} (defined in \DppNm{ObjProDSPcom/tarnod.h})
and thus available in both interactive and stand
alone execution. Many of these routines come in versions for
\DppNm{IntegerMachWord} and \DppNm{MachWord} data. This difference is
only meaningful in the floating point simulators. There is also an
\DppNm{UnsignedIntegerMachWord} data type. 


Classes \DppNm{ReadWriteSingleChannel} and
\DppNm{ReadWriteBlock} defined in \\
\DppNm{ObjProDSPcom/blckwrt.h}
can simplify the use of these routines for some applications.

\begin{figure}
\begin{verbatim}
    void UpdateRead(int32 size, int chan=0) ;
    void UpdateWrite(int32 size, int chan=0) ;

    const MachWord * GetReadPtr(int chan=0) const ;
    const MachWord * GetReadBase(int chan=0) const ;
    const MachWord * GetReadEnd(int chan=0) const ;

    MachWord * GetWritePtr(int chan=0) const ;
    MachWord * GetWriteBase(int chan=0) const ;
    MachWord * GetWriteEnd(int chan=0) const ;

    const UnsignedIntegerMachWord * GetBinReadPtr(int chan=0) const ;
    const UnsignedIntegerMachWord * GetBinReadBase(int chan=0) const ;
    const UnsignedIntegerMachWord * GetBinReadEnd(int chan=0) const ;

    UnsignedIntegerMachWord * GetBinWritePtr(int chan=0) const  ;
    UnsignedIntegerMachWord * GetBinWriteBase(int chan=0) const ;
    UnsignedIntegerMachWord * GetBinWriteEnd(int chan=0) const ;

    void WriteInteger(IntegerMachWord Data, int chan=0) ;
    void WriteWord(MachWord Data, int chan=0) ;

    IntegerMachWord ReadBinary(int chan=0)  ;
    MachWord ReadWord(int chan=0)  ;

    int32 GetAvailableData(int chan=0) const ;
    int32 GetSpace(int chan=0) const ;
    int32 GetContiguousAvailableData(int chan=0) const ;
    int32 GetContiguousSpace(int chan=0) const ;

    void WriteCxWord(CxMachWord Data, int chan=0) ;
    CxMachWord ReadCxWord(int chan=0) ;

\end{verbatim}
\caption{Data access routines, also see Table~\ref{Tab:DataAccess}}
\label{Fig:DataAccess}
\end{figure}

\begin{table}
\begin{tabular}{|ll|} \hline 
Routine &  Operation \\ \hline
\DppNm{UpdateRead} & update read pointer on {\tt chan} {\tt size} words \\
\DppNm{UpdateWrite} & update write pointer on {\tt chan} {\tt size} words \\
\DppNm{GetReadPtr} & get read pointer on {\tt chan} \\
\DppNm{GetReadBase} & get base of input buffer on {\tt chan} \\
\DppNm{GetReadEnd} & get address past end of input buffer on {\tt chan} \\
\DppNm{GetWritePtr} & get write pointer on {\tt chan} \\
\DppNm{GetWriteBase} & get base of output buffer on {\tt chan} \\
\DppNm{GetWriteEnd} & get address past end of output buffer on {\tt chan} \\
\DppNm{GetBinReadPtr} & same as \DppNm{GetReadPtr}, unsigned integer pointer \\
\DppNm{GetBinReadBase} & same as \DppNm{GetReadBase}, unsigned integer pointer \\
\DppNm{GetBinReadEnd} & same as \DppNm{GetReadEnd}, unsigned integer pointer \\
\DppNm{GetBinWritePtr} & same as \DppNm{GetWritePtr}, unsigned integer pointer \\
\DppNm{GetBinWriteBase} & same as \DppNm{GetWriteBase}, unsigned integer pointer \\
\DppNm{GetBinWriteEnd} & same as \DppNm{GetWriteEnd}, unsigned integer pointer \\
\DppNm{WriteInteger} & write one integer word, update pointers \\
\DppNm{WriteWord} & write one \DppNm{MachWord}, update pointers \\
\DppNm{ReadInteger} & read one integer word, update pointers \\
\DppNm{ReadWord} & read one \DppNm{MachWord}, update pointers \\
\DppNm{GetAvailableData} & get number of words available on input {\tt chan} \\
\DppNm{GetSpace} & get words of space on output {\tt chan} \\
\DppNm{GetContiguousAvailableData} & get number of contiguous input words on {\tt chan} \\
\DppNm{GetContiguousSpace} & get words of contiguous space on output {\tt chan} \\
\DppNm{WriteCxWord} & write one \DppNm{CxMachWord}, update pointers \\
\DppNm{ReadCxWord} & read one \DppNm{CxMachWord}, update pointers \\ \hline 
\end{tabular}
\caption{Data access routines, also see Figure~\ref{Fig:DataAccess}}
\label{Tab:DataAccess}
\end{table}

When the node completes execution it should return the {\tt enum}
\DppNm{OK} if no problems were encountered and \DppNm{FatalError}
if a error sufficient to halt network execution was encountered.
Other possible return values as defined in file
{\tt ObjProGen/errcode.h}
\index{errcode.h}
are \DppNm{OutputBuffersFull}, \DppNm{Warning},
\DppNm{EndOfData} and \DppNm{ExecutionComplete}.
These other options are primarily for internal use.

\subsubsection{Node timing}
\label{Sec:NodeTiming}
\index{timing}

Ordinarily initial node timing is computed from base function
constructor parameters. These define the relationship between
input and output data as described in \MMSusers{} in
the `Data flow model' subsection of the
chapter on `The \DPP{} language". You can override this with
the code in the \DppNm{Timing} construct or you can directly
define the virtual function\\
{\tt double} {\it class\_name}{\tt ::TimeFirst(DfNodeInLink *In, DfNodeOutLink * Out) }\\
\index{TimeFirst}
that this construct emits. With the former you do not need to use
conditionals to keep the declaration out of the target code.
This routine returns the absolute sample time of the first
sample output.



\subsubsection{Emitting the state}
\label{StateEmit}
\index{emit state}
\index{state emit}

When the state of \Dpp{} is saved a file is written that contains
a call to the constructor for each object currently defined. The parameters
to this call are the current values for them in the object. This
should work for any DSP nodes but does not work for other objects
such as networks. For these the \DppNm{StateEmit} construct defines
a virtual function  \\
{\tt const char * } {\it class\_name}::EmitState(OutTokens\& Out) \\
that emits the state. \DppNm{OutTokens} is a class used to output
text for various purposes. It is not usually needed in writing
nodes. It is defined in file {\tt ObjProGen/outtok.h}.
\index{outtok.h}

\subsection{Node destructor}
\label{Destructor}
\label{Sec:Dtor}
\index{destructor}
\index{delete node}

If the node allocates dynamic storage or can be referenced by other objects
in some way other then the standard network interface you need to
write a \Cpp{} destructor for it using the \IntPp{} \DppNm{Ctor}
construct. The should {\tt delete} any dynamically allocated objects
and remove any external references to them or to the node being deleted.

Base class constructors insure that all references through
the network are deleted and that any menu references including
those currently displayed are removed. Deleting an object can
cause displayed menus to disappear.

\subsection{Check if node is deletable}
\label{SafeDelete}
\index{emit state}

Interactively deleting objects can create problems. For example
one cannot delete a network without removing any nodes linked in
that network. Otherwise those nodes will reference a deleted object.
Most nodes are only referenced through the standard network interface.
If this is true they can be deleted at any time. However if
other objects can reference a node in non standard ways these
references must be removed as part of the destructor for the object
(see Section~\PageRef{Sec:Dtor}) or the object must be flagged
as not interactively deletable.

Before the constructor for a node is called the virtual function 
\\{\tt int CheckSafeDelete()} is called. If this returns 0 the
destructor is not called and the object is not deleted.
The \IntPp{} construct \DppNm{SafeDelete} defines this virtual
function. The first two lines of the emitted code are:
\begin{verbatim}
int Safe_Check_Return = UserEntity::CheckSafeDelete();
if (!Safe_Check_Return) return 0;
\end{verbatim}
The code you write comes after this and can include additional tests.

\subsection{Interactive code}
\label{Sec:FilesInteractive}

The code you generate is used for both target and interactive
execution. There are some things you can do to make the
interactive code more user friendly. For example if an error
condition is encountered you should report it with the a
call to {\tt State.Error()}. There must be one parameter
and can be up to 8 of type {\tt const char *}. When
concatenated these parameters should produce a meaningful error message.

You can direct messages to the user using the \Cpp{} 
stream like construct \DppNm{HelpOut}.

Debugging messages can be directed to log file \DppNm{dsp.messages}
using the stream \DppNm{LogOut}.

All of the above can be used for both stand alone and interactive code.
For example \DppNm{HelpOut} is defined is \DppNm{cerr} for stand alone
code.

If you need to write code that is only used for interactive execution
you can use the \Cpp{} define \DppNm{INTERACTIVE}. This is only defined
for code compiled for interactive execution. 

\subsection{Stand alone target code}
\label{Sec:FilesTarget}

There are many differences between code compiled for
stand alone target execution
and that compiled for interactive execution. All stand alone
nodes have the
same base class, \DppNm{TargetNode}, with a simple fixed set of
constructor parameters. The interactive node base classes have
\DppNm{TargetNode} as a parent. All the interactive code such as
code to describe parameters or set them is stripped
from the target code.

As much as possible values are precomputed and initialized as part
of the process of emitting the target \Cpp{} code. This can minimize
both code space and execution time. There are facilities to allow user
defined
variables and arrays to be initialized during interactive execution
and those values emitted as static initializers for the target code.
These are described in the next section.

\subsection{Preinitialized target code}
\label{Sec:TarStatic}

Objects and arrays declared in the \IntPp{} construct, \DppNm{StaticDeclare},
are initialized during interactive execution and those values are used as
static initializers in generating target stand alone code.
The initialization is most commonly done in two places.
Code in the \DppNm{StaticInit} construct is only output in the
interactive code and occurs in the node constructor before the code
output in the \DppNm{Ctor} construct. You can put initialization
code here that will not be needed on the target. The code in
the \DppNm{Ctor} section can assume this initialization has been
done before it starts regardless of whether the code is executing
on interactively or as  a stand alone target.

In some cases static initialization cannot be completed until the
node is linked into a network. For example this may be
necessary for a node that can operate on different input data
types. This can be done in virtual function
\DppNm{InitAfterLinked}. This function should only be defined
interactively by using \Cpp{} conditional compilation,
\verb"#ifdef INTERACTIVE" \\
or by placing it in a \verb".C" file in the same directory that the
\DppNm{.usr} file is.

\subsection{Target arithmetic}
\index{target arithmetic}
\index{arithmetic types}
\label{Sec:ArithType}

For the floating point simulator target arithmetic using the
types \DppNm{MachWord} and \DppNm{AccMachWord} is done with single
precision floating point arithmetic.

For the 16 bit simulator these two data types represent 16 and
32 bit accuracy that might be available on an integer DSP processor.
Multiply for this type is defined as if the number was a binary
faction with the decimal point to the left of the most significant
non sign bit. Thus fractions between 1 - 1/32768 to -1 are represented.
Multiplication by two full scale values will never produce an overflow
although the product of -1 $\times$ -1 will be 1 - 1/32768 and not
1 which cannot be represented.

You can write nodes that will work with both simulators but you must
be careful with normalization when using integer arithmetic.

You can define arithmetic operations that exactly match the hardware
of your target processor and create a new simulator for that arithmetic.
That is outside the scope of this manual. The files to do this
for the existing simulators are in directory \\
\verb"$OPD_ROOT/src/dsp/arith" \\
and subdirectories of this directory.
The header files are in directories under \DppNm{ObjProFlt} and
\DppNm{ObjProInt16} which are subdirectories of \\
\verb"$OPD_ROOT/src/include".\\

\section{Integrating a new node}

\subsection{Integration with the menu data base}
\label{Sec:FilesDataBase}
\label{Sec:ClassDataBase} % describe InteractiveEntityList

\IntPp{} outputs a \DppNm{.nod} file into directory \\
\verb"$OPD_ROOT/src/menus/nodes" \\
for integration of the node with the menu data base.
You must specify where this documentation is to be placed.
If you do nothing special it will treated as a DSP processing node.
You can specify the menu it is to be added to as described in
Section~\PageRef{Sec:PlaceNode}.

You can use the \DppNm{InteractiveEntityList} construct to define
the class of classes the node belongs to. If you did not give a
specific menu for it this will determine where it is linked.
The possible classes are listed in Table~\PageRef{Tab:ClassOfClasses}.

\begin{table}
\begin{tabular}{|ll|} \hline
Name & Type of objects \\ \hline
\DppNm{InteractiveNode} & DSP processing nodes (default) \\
\DppNm{InteractiveNet} & networks \\
\DppNm{InteractiveBuffer} & buffers between nodes \\
\DppNm{InteractiveScheduler} & network controllers \\
\DppNm{InteractiveSignal} & input or signal generation nodes \\
\DppNm{InteractiveDisplay} & output or display nodes \\
\DppNm{InteractiveMiscellaneous} & other types of objects \\ \hline
\end{tabular}
\caption{Groups of classes for placement in data base}
\label{Tab:ClassOfClasses}
\end{table}

\subsection{Integrating with the documentation}
\label{Sec:FilesDoc}

The two \DppNm{.tex} files are written to subdirectories \DppNm{tex}
and \DppNm{texs} these are used to integrate the node into the
\Dpp{} manuals. The \DppNm{texs} files are used in \MMSoverview{}.
The \DppNm{tex} files are used in \MMSlib{}. The \DppNm{.nod}
files are used to create the \DppNm{.tex} documentation of the data
base in \MMSusers{}.

\subsection{Integrating a node into \protect\Dpp{}}

The simplest way to integrate a node is to place it in a directory
in which there are already \DppNm{.usr} files. The standard directories
are listed in Table~\PageRef{Tab:PlacingNode}. You should manually
execute routine \\
\verb"$OPD_ROOT/bin/mknode"\\
\index{mknode}
with the new \DppNm{.usr} file as a single argument.
This will create output \DppNm{.C} and \DppNm{.h}
files. Then go to directory \\
\verb"$OPD_ROOT/src/dsp/build/fltgui" or \\
\verb"$OPD_ROOT/src/dsp/build/int16gui"\\
for the floating point or 16 bit simulators and execute the command
{\tt do\-make\-make}.
Then go back to the directory with the new \DppNm{.usr}
file and \DppNm{touch} that file so it will be processed again
with \DppNm{mknode} using the correct parameters for creating
the documentation and target files. Then you can go to 
the appropriate subdirectory (\DppNm{fltgui} or \DppNm{int16gui})
and do a \DppNm{make} to run \DppNm{mknode} and the
\Cpp{} compiler for your new node.

To rebuild \Dpp{} with your
new node go back to the master build directory for the version
you are working with\\
(\verb"$OPD_ROOT/src/dsp/build/fltgui" or \\
\verb"$OPD_ROOT/src/dsp/build/int16gui")\\
and do a \DppNm{make}.
To include your new node in target libraries
go to the master build directory \\
(\DppNm{\$OPD\_ROOT/build})
and do a \DppNm{make TOUCH\_DOMAKEMAKE}
followed with a \DppNm{make EXE}. Remember to do the latter using
\DppNm{make\_both.sh} if you want to update both the 16 bit integer
and floating point versions. Otherwise only the floating point versions
will be updated. After \Dpp{} has been built with you new node
you can update the documentation by doing \DppNm{make DOC} in
the master build directory.

\begin{table}
\begin{tabular}{|ll|} \hline
Directory under & Type of nodes \\
{\tt \$OPD\_ROOT/src/dsp/nodes} & \\ \hline
\DppNm{proc} & DSP processing nodes \\
\DppNm{proc16} & DSP nodes only for 16 bit simulator \\
\DppNm{proc32} & DSP nodes only for 32 bit simulator \\
\DppNm{sigdsk} & input nodes that read disk files \\
\DppNm{signal} & other signal nodes \\
\DppNm{ionode} & input/output nodes supported on all targets \\
\DppNm{display} & output nodes  \\ \hline
\end{tabular}
\caption{Directories to place new nodes in}
\label{Tab:PlacingNode}
\end{table}

\subsection{Removing a node from \protect\Dpp{}}

To remove a node you must remove the node source
file and all the files created by \DppNm{mknode} from the source
file when \DppNm{mknode} is
invoked with the options specified by \DppNm{makemake}.
These files are shown in Table~\PageRef{Tab:CreatedByMknode}. After
that do \DppNm{make TOUCH\_DOMAKEMAKE} and \DppNm{make EXE}
in the master build directory (\DppNm{\$OPD\_ROOT/build}). 
Note file\\
\DppNm{\$OPD\_ROOT/src/include/initinc.h}\\
references file {\it node\_name}{\tt I.h} for each node.
\DppNm{initinc.h} is created when \DppNm{domenus} is run based on
the {\tt .nod} files in \DppNm{\$OPD\_ROOT/menus/nodes}.
You must remove the {\tt .nod} file before running \DppNm{domenus}
from \DppNm{make}. Do not worry if you get an undefined reference
to the {\tt I.h} file when you run \DppNm{domakemake}. This reference
will be absent when \DppNm{initinc.h} is recreated when \DppNm{domenus}
is run.

You will also need to rebuild the files in \\
\DppNm{\$OPD\_ROOT/overview/doc} that reference the \DppNm{.tex} files.
Do a \DppNm{fgrep} in this directory on \DppNm{*.tex} for the base
name of the file {\it name}\DppNm{.usr} file you are deleting. Make sure
the two
files that reference {\it name\DppNm{.tex}}
are created by \DppNm{make} and them delete them so they will be remade
the next time the documentation is rebuilt.

\begin{table}
\begin{tabular}{|lll|} \hline
File & Purpose & Directory (. is relative to node others \\
 & &             are relative to \DppNm{\$OPD\_ROOT/src}) \\ \hline
{\it name}{\tt .C} & interactive source & . \\
{\it name}{\tt .C} & target source & \DppNm{./target} \\
{\it name}{\tt .h} & interactive source & \DppNm{include/ObjProDSPint/ObjProUsr} \\
{\it name}{\tt .h} & target source & \DppNm{include/ObjProDSPtar/ObjProUsr} \\
{\it name}{\tt .tex} & full documentation & \DppNm{./tex} \\
{\it name}{\tt .tex} & synopsis documentation & \DppNm{./texs} \\
{\it name}{\tt I.h} & default objects  & . \\
{\it name}{\tt .nod} & interactive documentation & \DppNm{menus/nodes} \\
{\it name}{\tt .e} & text for spelling check & subdierecroty \DppNm{mknode} is executed from \\
\hline
\end{tabular}
\caption{Files created by \DppNm{mknode} (with \DppNm{makemake} options) from {\it name}{\tt .usr}}
\label{Tab:CreatedByMknode}
\end{table}

