General purpose functions

If you take a peek in your home folder, Spektar has created a small folder structure. Among other content, you will find a functions directory.

Anatomy of a function

In general terms, Spektar functions correspond conceptually to C functions or Java methods. The consist of a delaration, and body, where declaration in turn consists of return value, package, function name and parameters, and function body consists of statements.

Within a function, same rules for scripting apply as for component scripting. To put this all together, best let’s look at an example.

/**
This is documentation section. Some HTML is tolerated.

 * star when appears as first non-whitespace char is ignored
 
@function rms Calculate root mean square of an array
@param x The input array
@param num The input array size
@returns The rms of the array
*/
float #rms(float[] $x, int $num) {
	double $sum = 0;
	for (int $i = 0 ; $i < $num ; $i++) {
		$sum += $x[$i] * $x[$i] ;
	}
	$sum = $sum / $num;
	$sum = #math:sqrt($sum);
	return (float) $sum;
}

Packages

If you simply drop function source code into a {user-home}/Spektar/functions/base that function immediately becomes available to all components and scripts. There is no installation required. This also explains why function declaration doesn’t require package.

Invoking a function from a certain package is done by prefixing the function with package name and : sign as below:

float $rms = #base:rms( $mydata, 32);

Naming

Function and package names must consists of letters and numbers only and must start with a letter. Lowercase is preferred and CamelCase is ok.

In terms of files, file must be named as follows:

{function-name}[-version].fn

Function name in filename must be exactly the same as function name in the declaration. Version is optional, and if missing, the file is considered to contain newest / latest version of the function.

Versioning

Version is defined as a single integer number.

An installation may contain multiple versions of a function. If you don’t specify the version in your script, system will select the latest version.

You can specify desired version when calling a function as follows:

float $rms = #base:rms:1( $mydata, 32);

Documenting functions

In the above example we’ve also illustrated how functions can be documented. We essentially follow JavaDoc standards, but in summary:

  1. Function file must start with /** which denotes documentation start
  2. Documentation section ends with */
  3. Any line starting with whitespace and * is trimmed to exclude that prefix
  4. Any line starting with @ is processed as below and not included in doc text

Processing @ is done as follows:

  1. Line starting with @function defines short, one sentence summary of the purpose of the function.
  2. Any line starting with @param - expects parameter name and description.
  3. Any line starting with @return - expects short description of the return value

Dependencies

Spektar will automatically handle dependencies while exporting (e.g. to C or Java), as long as functions being used are referenced correctly and available in the functions folder hierarchy.

Return values

As with the rest of the scripting system, return values can be primitive types common for C and Java - specifically int, float, double and array types int[] and float[]. Also, function return can be void - meaning that function does not return a value.

Additional types are also supported, e.g. you can return a buffer, buffer8 or a resource.

Special functions

Following special functions are available in scripts.

Function Parameters Description Example
makeFloat(int num) num - size of the array Makes a float array of length num. float[] $buffer = #makeFloat(32);
makeInt(int num) num - size of the array Makes a integer array of length num. int[] $buffer = #makeInt(32);
makeResource() none Creates a new instance of a resource resource $res = #makeResource();
makeBuffer() none Creates a new instance of a buffer buffer $b = #makeBuffer();
makeBuffer8() none Creates a new instance of a buffer8 buffer8 $b = #makeBuffer8();
makeRawInt(float v) v float value Bitwise copy from float to int int $midimsg = #makeRawInt( $midiInPort );
makeRawFloat(int v) v integer value Bitwise copy from int to float float $midiout = #makeRawFloat( $midiMessage );
makeFree(<type> v) v - the memory to release equivalent to C function free, ingored for jav. You only need to free memory allocated by calling makeFloat or makeInt #makeFree(buffer);
attr:<type>(attrName) type type of the attribute, attrName String constant Retrieve component attribute, converted to the specified type. Types supported are shown in the table below this one. Attributes can be set at design time and are injected at the time of translation from the script to C / C++ / Java. #attr:floatArray("fir-coefficients"); would retrieve parameter called fir-coefficients, parse it as a comma-separated list and return as an array of floats ( float[] )
math:*() Various Standard mathematical functions supporting sin, sinh, cos, cosh, exp, floor, tan, asin, acos, atan, log, log10, pow, abs and random at the minimum. May support extended list of mathematical functions depending on execution environment. #math:sin(6.26*$f*$t);
resource:resource(resourceId) resourceId - integer constant, assigned during resource registration Loads the resource metadata. resource $res = #resource:resource(3);
resource:audio(resourceId) resourceId - integer constant, assigned during resource registration Loads the resource content as buffer. buffer $res = #resource:audio(3);
resource:raw(resourceId) resourceId - integer constant, assigned during resource registration Loads the resource content as buffer8. buffer8 $res = #resource:raw(3);

Following attribute types are supported for attr: special function.

float reads a single float from the attribute. As attributes are stored as text, this also means parsing float from string
floatArray reads an array of floats from the attribute. Expects attribute content to be a comma-separated list of float values.
int reads a single integer from the attribute.
string reads a string from the attribute.

Always make sure the attributes are present and set correctly if using attr functions. If the specified attribute is not present, underlying functions - when translated to target language - may throw an exception, return null pointers or even crash the application.