Typically the structure is declared statically in the function implementing the node command for the class. The first time the command is called, Rivl_NodeClassInit is called to initialize the structure with default values. This is followed by code overriding default values as necessary.
Rivl_DestroyNodeClass destroys the class indicated by classPtr. This is typically used when a node command and its associated class are deleted or redefined dynamically. All existing nodes of the class are invalidated; henceforth any attempt to compute signal data from that node results in an error. The fields of Rivl_NodeClass are described below. At the end of each description the default value of the field is given; this is the value placed in the field by Rivl_NodeClassInit.
There is no default for name; it must be specified.
void ComputeHaveRegionProc( Tcl_Interp *interp, Rivl_Signal signal, Rivl_Region *inHaves, Rivl_Region outHave, Rivl_Point sampleRate;)signal is the node's output signal. inHaves is an array with one element for each input. inHaves[i] contains the have region for input signal i; this is equivalent to the result of calling Rivl_SignalHaveRegion on signal->inputs[i] with sampleRate.
computeHaveRegionProc must place the output signal's have region into outHave. On entry, outHave is initialized to an allocated region with a default value depending on the type of node. For leaf nodes, outHave is initialized to the infinite region. For non-leaf nodes, outHave is initialized to a copy of inHaves[0]. sampleRate is the sample rate at which the output have region should be expressed. Any spatial value that contributes to the calculation of outHave should first be multiplied by sampleRate. See the "sample rate" section below for an explanation.
If classPtr->autoPrepareHaveRegionsFlag is FALSE, the input have regions are not precomputed. In this case, inHaves is an array with the same dimensions but undefined contents. This flag is used in rare cases where the input have regions must be computed in a special way; for example, with a different sample rate than the output.
The procedure Rivl_ComputeHaveRegionFromSize may be used as a value for computeHaveRegionProc; it sets outHave to the rectangle from (0,0) to the signal's size. This is appropriate for many leaf nodes.
The default for computeHaveRegionProc sets outHave to the infinite region for leaf nodes, and the union of all inHaves for non-leaf nodes. Note that the latter is different from the default value of outHave passed into computeHaveRegionProc.
void ComputeNeedRegionsProc ( Tcl_Interp *interp; Rivl_Signal signal; Rivl_Region *inNeeds; Rivl_Region outNeed; Rivl_Point sampleRate;)signal is the node's output signal. outNeed is the current need region -- the region of signal being computed. inNeeds is an array with one element for each input. Each inNeeds[i] must be filled with the need region of input i with respect to outNeed. The inNeeds elements are initialized to copies of outNeed.
sampleRate is the sample rate at which outNeed is expressed and at which inNeeds should be expressed. Any spatial value that contributes to the calculation of inNeeds should first be multiplied by sampleRate. See the "sample rate" section below for an explanation.
computeNeedRegionsProc is used to compute the inNeeds parameter that is passed to computeDataProc. Its result also indirectly affects the inBufs parameter if autoComputeInputsFlag is TRUE. computeNeedRegionsProc is ignored for leaf nodes.
The default for computeNeedRegionProc does nothing, leaving a copy of outNeed in each inNeeds[i].
int ComputeDataProc ( Tcl_Interp *interp; Rivl_Signal signal; Rivl_Region *inNeeds; Rivl_Region outNeed; Rivl_Buf *inBufs; Rivl_Buf *outBufPtr; Rivl_Point sampleRate;)outNeed contains the region to compute. inNeeds is an array with one element for each input, where inNeeds[i] contains the need region for input signal i with respect to outNeed. inNeeds is obtained by calling classInfo->computeNeedRegions. If cropInputNeedRegionsFlag is TRUE, then each inNeeds[i] is intersected with the have region of input signal i.
inBufs is an array with one element for each input. If autoComputeInputsFlag is TRUE, then each inBufs[i] contains the data for input signal i in the region inNeeds[i]. The data in inBufs[i] outside the region inNeeds[i] is undefined. The area of inBufs[i] is taken from the clip box of inNeeds[i].
If autoComputeInputsFlag is FALSE, then inHaves is an array with the same dimensions but undefined contents. In this case the function must compute any desired input data by calling Rivl_ComputeSignalData manually. autoComputeInputsFlag is ignored for leaf nodes.
computeDataProc must compute the data in outNeed and return it via one of two methods. The first method is to fill the buffer pointed to by outBuf, which is an allocated buffer guaranteed to hold at least the region outNeed. The function should not modify values in outBuf outside the region outNeed. The second method is to point outBuf to a new buffer containing the requested data. The node class indicates which method it will use by setting imCreateFlag to FALSE for the first method and TRUE for the second method (FALSE is the default).
The need regions and buffers are in terms of sampleRate. Any spatial value that contributes to the computation should first be multiplied by sampleRate. See SAMPLE RATE, below, for an explanation.
If computeDataProc completes successfully, it should return TCL_OK. Otherwise, it should place an error message in interp->result and return TCL_ERROR. There is no default for computeDataProc; it must be specified. If you want the node to pass its input data untouched, then set autoComputeInputsFlag to FALSE and call Rivl_ComputeSignalData manually. See the implementation of sig_dup for an example.
void FreeProc ( Tcl_Interp *interp; Rivl_Node node;)node contains the node that is being freed. freeProc should release resources associated with node->data, including freeing node->data if it points to a malloc'd structure. It should not free the structure pointed to by node; that is handled automatically by Rivl.
The default for freeProc checks to see if node->data is non-NULL;
if so, it calls free()
on it. Thus you need only define
freeProc if there are items within node->data that need to be
manually deallocated, or if node->data is set to a value that is
not a malloc address.
The default is FALSE.
The default is TRUE. Set this to FALSE only if you want to compute the input have regions manually for some reason.
The default is FALSE. The advantage of this is that the input buffer sizes will be predictable, making it a little easier to write non-local transforms. The disadvantage is that the buffers may use more storage than necessary.
The default is TRUE. Set this to FALSE if you want to manually compute the input signal(s) data in computeDataProc. For example, you might want to compute input data directly into the output buffer and operate on it there.
RIVL/doc/examples/node.c
for an example of how
sampleRate is used.