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.
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.
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.
These convert parameter values between units. In BCI2000, values representing time may be given without units--then, the numeric value represents time in terms of a Sample Block's duration. Alternatively, these values may be given with a time unit such as ms. Similarly, frequencies may be given in terms of the system's sampling rate, or in Hertz when appended with Hz. Voltage values may be appended with V, muV or similar; when no unit is specified, the numeric value is assumed to be in Microvolts.
Gives a parameter's value as the corresponding number of sample blocks. When a unit other than a time unit is specified in the parameter value, an error is reported.
Provides a parameter's value in seconds, or milliseconds, respectively. When the parameter contains a unit other than a time unit, an error is reported.
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 a signal's effective sampling rate when the signal's SignalProperties are specified as an argument. When a unit other than a frequency unit is present in the parameter value, an error is reported.
will return a parameter's value in terms of the system sampling rate. When a unit other than a frequency unit is present in the parameter value, an error is reported.
returns a parameter's value in Hertz. When the parameter's value is a plain number, it is taken to represent multiples of the system sampling rate.
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".
gives a parameter's value in units of Volts or Microvolts, respectively. A plain number is taken to represent Microvolts.
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.
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.