The ArrayState classes (FloatArrayState, IntArrayState, ComplexArrayState, FixArrayState and StringArrayState) are used to store arrays of data.
For example,
defparameter
{
name { taps }
type { floatarray }
default { "0.0 0.0 0.0 0.0" }
desc { "An array of length four." }
}
defines an array of type double with dimension four, with each element initialized to zero. Alternatively, you can specify a filename with a prefix <. If you have a file named xxx that contains the default values for an array parameter, you can write,
default { "< xxx" }
If you expect others to be able to use your primitive, however, you should specify the default filename using a full path. For instance,
default { "< $MLD_USER/My_Library/xxx" }
For default files installed in the MLDesigner directory tree, this should read:
default { "< $MLD/directory/xxx" }
The format of the file is also a sequence of data separated by spaces (or newlines, tabs, or commas). File input can be combined with direct data input as in
default { "< xxx 2.0" }
default { "0.5 < xxx < yyy" }
A repeat notation is also supported for ArrayState objects. The two value strings
default { "1.0 [5]" }
default { "1.0 1.0 1.0 1.0 1.0" }
are equivalent. Any integer expression may appear inside the brackets []. The number of elements in an ArrayState can be determined by calling its size method. The size is not specified explicitly, but is calculated by scanning the default value.
As an example of how to access the elements of an ArrayState, suppose fState is of type FloatState and aState is of type FloatArrayState. The accesses, like those in the following lines, are common:
fState = aState[1] + 0.5;
aState[1] = (double)fState * 10.0;
aState[0] = (double)fState * aState[2];
For a more complete example of the use of FloatArrayState, consider the FIRFloat primitive defined below. Note that this is a simplified version of the SDFFIRFloat primitive that does not permit interpolation or decimation.
defprimitive
{
name { FIRFloat }
domain { SDF }
desc
{
A Finite Impulse Response (FIR) filter.
}
input
{
name { Input }
type { float }
desc { "Input signal." }
}
output
{
name { Output }
type { float }
desc { "Output signal." }
}
defparameter
{
name { Coefficients }
type { floatarray }
default { "-.040609 -.001628 .17853 .37665 .37665 .17853 -.001628 -.040609" }
desc { "Filter tap values." }
}
setup
{
// tell the PortHole the maximum delay we will use
Input.setSDFParams(1, Coefficients.size()-1);
}
go
{
double out = 0.0;
for (int i = 0; i < Coefficients.size(); i++)
out += Coefficients[i] * (double)(Input%i);
Output%0 << out;
}
}
Notice the setup method; this is necessary to allocate a buffer in the signalIn input port large enough to hold the particles that are accessed in the go method. Notice the use of the size method of the FloatArrayState.
We now illustrate a PTCL interpreter session using the above FIRFloat primitive. Assume there is a module called SineGen that generates a sine wave. You can use it with the FIRFloat primitive, as in:
PTclShell> domain SDF
PTclShell> primitive foop SineGen
PTclShell> primitive fir FIRFloat
PTclShell> primitive printer Printer
PTclShell> connect foop output fir Input
PTclShell> connect fir Output printer input
PTclShell> run
PTclShell> print fir
Star: main.fir
...
States:
Coefficients type: FLOATARRAY A_DYNAMIC
...
PTclShell> paramvalue fir Coefficients initial
-.040609 -.001628 .17853 .37665 .37665 .17853 -.001628 -.040609
PTclShell> paramvalue fir Coefficients current
-0.040609
-0.001628
0.17853
0.37665
0.37665
0.17853
-0.001628
-0.040609
Then you can redefine Coefficients by reading them from a file coeffs, which contains the data:
1.1
-2.2
3.3
-4.4
The resulting interpreter commands are:
PTclShell> setparam fir Coefficients "<coeffs 5.5"
PTclShell> run
PTclShell> paramvalue fir Coefficients initial
<coeffs 5.5
PTclShell> paramvalue fir Coefficients current
1.1
-2.2
3.3
-4.4
5.5
This illustrates that both the contents and the size of a FloatArrayState are changed by a setparam command. Also, notice that file values may be combined with string values. When
< filename
occurs in an initial value, it is processed exactly as if the whole file is substituted at that point.