Programming Reference:Accessing Parameters and States
On this page, we discuss how to access BCI2000 parameters from filter components that derive from GenericFilter, or from extension components deriving from the EnvironmentExtension class.
There are two kinds of access to parameters and states: High-level access allows to easily manipulate parameter and state values, and is appropriate most of the time. Low-level access allows to directly manipulate the data structures lying beneath the surface of parameter and state values. This might be necessary to, e.g., iterate over all parameters or states present.
Low Level Access
is provided by the following symbols:
- Parameters syntactically behaves like a ParamList*,
- States behaves like a StateList*,
- and Statevector behaves like a StateVector*.
As an example,
float myParameterValue = 0.0; Param* param = Parameters->GetParamPtr( "MyParameter" ); if( param ) myParameterValue = ::atof( param->GetValue() ); else bcierr << "Could not access \"MyParameter\"" << endl;
Unlike true pointers, these symbols cannot be assigned any values, cannot be assigned to variables, or have other manipulating operators applied. For example, the lines
delete Parameters; Parameters = new ParamList;
will all result in compiler errors.
High-level Access
is possible through a number of symbols which offer built-in checking and error reporting:
Parameter(Name)[(Index 1[, Index 2])
This symbol stands for the value of the named parameter. Indices may be given in numerical or textual form; if omitted, they default to 0. The type of the symbol Parameter() may be numerical or a string type, depending on its use. (If the compiler complains about ambiguities, use explicit typecasts.) If a parameter with the given name does not exist, an error message is written into bcierr. If the specified indices do not exist, an exception is thrown.
Examples:
int myValue = Parameter( "MyParam" ); string myOtherValue = Parameter( "MyOtherParam" ); Parameter( "My3rdParam" )( 2, 3 ) = my3rdValue;
OptionalParameter(Name[, Default Value])(Index 1[, Index 2])
This symbol behaves like the symbol Parameter() but will not report an error if the parameter does not exist. Instead, it will return the default value given in its first argument. Assignments to this symbol are not possible.
Unit Parsing Functions
may be appended when accessing a parameter:
AsSeconds, AsMilliseconds
AsHertz
AsVolts, AsMicrovolts
These functions return the parameter's value, parsing out physical units as indicated by function names.
Example:
double amplitude = Parameter( "Amplitude" ).AsMicrovolts();
will return when the parameter's value is "10muV" or "1e-5". When an inconsistent unit is present (such as in "10ms"), an error will be reported.
Conversion Functions
In addition to unit parsing functions, there are conversion functions available as well:
InBlocks()
will return a parameter's value in terms of system sample blocks when the value is given in seconds (with a trailing "s" unit). A value without a unit is considered to be expressed directly in sample blocks.
Example:
double stimulusDuration = Parameter( "StimulusDuration" ).InBlocks();
will return 5 when the sampling rate is 250Hz, sample block size is 10, and the value of the StimulusDuration parameter is "200ms".
RelativeFreq( [SignalProperties] )
will return a parameter's value in terms of the system sampling rate when no SignalProperties object is given, and in terms of a signal's effective sampling rate when its SignalProperties are specified as an argument.
Example:
double hpCorner = Parameter( "HPCorner" ).RelativeFreq( Input );
will return 0.5 when the input signal's effective sampling rate is 250Hz, and the parameter's value is "125Hz".
State(Name)
This symbol allows for reading a state's value from the state vector and setting a state's value in the state vector. Trying to access a state that is not accessible will result in an error reported via bcierr.
Examples:
short currentStateOfAffairs = State( "OfAffairs" ); State( "OfAffairs" ) = nextStateOfAffairs;
OptionalState(Name[, Default Value])
Analagous to OptionalParameter(), this symbol does not report an error if the specified state does not exist but returns the given default value. Assignments to this symbol are not possible.
Converters to and from numeric types
State values may be of numeric types other than unsigned. For conversion, functions are provided as in the following examples:
float f = State( "MyFloatState" ).AsFloat(); State( "MyFloatState" ).AsFloat() = 1.23; int i = State( "MySignedState" ).AsSigned(); State( "MySignedState" ).AsSigned() = -3; State( "MyUnsignedState" ).AsUnsigned() = 2;
Note that the AsUnsigned() converter function is provided for completeness only. When no conversion is given, state values are treated as unsigned as well.
See also
Programming Reference:Parameters, Programming Reference:States