void LinearClassifier::Initialize( const SignalProperties& Input, const SignalProperties& /*Output*/ ) { const ParamRef& Classifier = Parameter( "Classifier" ); size_t numEntries = Classifier->NumRows(); mInputChannels.resize( numEntries ); mInputElements.resize( numEntries ); mOutputChannels.resize( numEntries ); mWeights.resize( numEntries ); for( size_t entry = 0; entry < numEntries; ++entry ) { mInputChannels[ entry ] = Input.ChannelIndex( Classifier( entry, 0 ) ); mInputElements[ entry ] = Input.ElementIndex( Classifier( entry, 1 ) ); mOutputChannels[ entry ] = Classifier( entry, 2 ) - 1; mWeights[ entry ] = Classifier( entry, 3 ); } }
void FFTFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { for( int i = 0; i < Parameter( "FFTInputChannels" )->NumValues(); ++i ) { int channelIndex = Input.ChannelIndex( Parameter( "FFTInputChannels" )( i ) ); if( channelIndex < 0 || channelIndex >= Input.Channels() ) bcierr << "Invalid channel specification \"" << Parameter( "FFTInputChannels" )( i ) << "\" in FFTInputChannels, evaluates to " << channelIndex << endl; } bool fftRequired = ( ( int )Parameter( "FFTOutputSignal" ) != eInput || ( int )Parameter( "VisualizeFFT" ) ) && ( Parameter( "FFTInputChannels" )->NumValues() > 0 ); if( fftRequired ) { if( mFFT.LibAvailable() ) { FFTLibWrapper preflightFFT; int fftWindowLength = Parameter( "SampleBlockSize" ) * MeasurementUnits::ReadAsTime( Parameter( "FFTWindowLength" ) ); if( !preflightFFT.Initialize( fftWindowLength ) ) bcierr << "Requested parameters are not supported by FFT library" << endl; } else bcierr << "The FFT Filter could not find the " << mFFT.LibName() << " library. " << "For legal reasons, this library is not part of the BCI2000 distribution. " << "Please download the latest version of fftw3.dll from " << "http://www.fftw.org/install/windows.html" << endl; } if( int( Parameter( "VisualizeFFT" ) ) ) { SignalProperties temp; DetermineSignalProperties( temp, ePower ); } Output = Input; DetermineSignalProperties( Output, Parameter( "FFTOutputSignal" ) ); }
void FFTFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { for( int i = 0; i < Parameter( "FFTInputChannels" )->NumValues(); ++i ) { double channelIndex = Input.ChannelIndex( Parameter( "FFTInputChannels" )( i ) ); if( channelIndex < 0 || channelIndex >= Input.Channels() ) bcierr << "Invalid channel specification \"" << Parameter( "FFTInputChannels" )( i ) << "\" in FFTInputChannels, evaluates to " << channelIndex << endl; } bool fftRequired = ( int( Parameter( "FFTOutputSignal" ) ) != eInput || int( Parameter( "VisualizeFFT" ) ) ) && ( Parameter( "FFTInputChannels" )->NumValues() > 0 ); if( fftRequired ) { if( mFFT.LibAvailable() ) { RealFFT preflightFFT; int fftWindowLength = static_cast<int>( Input.Elements() * Parameter( "FFTWindowLength" ).InSampleBlocks() ); if( !preflightFFT.Initialize( fftWindowLength ) ) bcierr << "Requested parameters are not supported by FFT library" << endl; } else bcierr << "The FFT Filter could not find the " << mFFT.LibName() << " library." << endl; } if( int( Parameter( "VisualizeFFT" ) ) || int( Parameter( "FFTOutputSignal" ) ) == ePower ) { SignalProperties temp( Input ); DetermineSignalProperties( temp, ePower ); } Output = Input; DetermineSignalProperties( Output, Parameter( "FFTOutputSignal" ) ); }
void FFTFilter::Initialize( const SignalProperties& Input, const SignalProperties& Output ) { mFFTOutputSignal = ( eFFTOutputSignal )( int )Parameter( "FFTOutputSignal" ); mFFTWindowLength = Parameter( "SampleBlockSize" ) * MeasurementUnits::ReadAsTime( Parameter( "FFTWindowLength" ) ); mFFTWindow = ( eFFTWindow )( int )Parameter( "FFTWindow" ); mFFTInputChannels.clear(); mSpectra.clear(); for( size_t i = 0; i < mVisualizations.size(); ++i ) mVisualizations[ i ].Send( CfgID::Visible, false ); mVisualizations.clear(); mVisualizeFFT = int( Parameter( "VisualizeFFT" ) ); if( mVisualizeFFT ) { mVisProperties = Input; DetermineSignalProperties( mVisProperties, ePower ); } for( int i = 0; i < Parameter( "FFTInputChannels" )->NumValues(); ++i ) { mFFTInputChannels.push_back( Input.ChannelIndex( Parameter( "FFTInputChannels" )( i ) ) ); mSpectra.push_back( GenericSignal( Output.Elements(), 1 ) ); if( mVisualizeFFT ) { ostringstream oss_i; oss_i << i + 1; mVisualizations.push_back( GenericVisualization( string( "FFT" ) + oss_i.str() ) ); ostringstream oss_ch; oss_ch << "FFT for Ch "; if( Parameter( "FFTInputChannels" )->Labels().IsTrivial() ) oss_ch << i + 1; else oss_ch << Parameter( "FFTInputChannels" )->Labels()[ i ]; mVisualizations.back().Send( CfgID::WindowTitle, oss_ch.str().c_str() ) .Send( CfgID::GraphType, CfgID::Field2d ) .Send( mVisProperties ) .Send( CfgID::Visible, true ); } } mWindow.clear(); mWindow.resize( mFFTWindowLength, 1.0 ); float phasePerSample = M_PI / float( mFFTWindowLength ); // Window coefficients: None Hamming Hann Blackman const float a1[] = { 0, 0.46, 0.5, 0.5, }, a2[] = { 0, 0, 0, 0.08 }; for( int i = 0; i < mFFTWindowLength; ++i ) mWindow[ i ] = 1.0 - a1[ mFFTWindow ] - a2[ mFFTWindow ] + a1[ mFFTWindow ] * cos( float( i ) * phasePerSample ) + a2[ mFFTWindow ] * cos( float( i ) * 2 * phasePerSample ); mValueBuffers.resize( mFFTInputChannels.size() ); ResetValueBuffers( mFFTWindowLength ); bool fftRequired = ( mVisualizeFFT || mFFTOutputSignal != eInput) && mFFTInputChannels.size() > 0; if( !fftRequired ) { mFFTInputChannels.clear(); mSpectra.clear(); } else mFFT.Initialize( mFFTWindowLength ); }
void LinearClassifier::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { // Determine the classifier matrix format: int controlSignalChannels = 0; const ParamRef& Classifier = Parameter( "Classifier" ); if( Classifier->NumColumns() != 4 ) bcierr << "Classifier parameter must have 4 columns " << "(input channel, input element, output channel, weight)" << endl; else { for( int row = 0; row < Classifier->NumRows(); ++row ) { if( Classifier( row, 2 ) < 1 ) bcierr << "Output channels must be positive integers" << endl; float ch = Input.ChannelIndex( Classifier( row, 0 ) ); if( ch < 0 ) bcierr << DescribeEntry( row, 0 ) << " points to negative input index" << endl; else if( ::floor( ch ) > Input.Channels() ) bcierr << "Channel specification in " << DescribeEntry( row, 0 ) << " exceeds number of input channels" << endl; if( ::fmod( ch, 1.0f ) > 1e-2 ) bciout << "Channel specification in physical units: " << DescribeEntry( row, 0 ) << " does not exactly meet a single channel" << endl; float el = Input.ElementIndex( Classifier( row, 1 ) ); if( el < 0 ) bcierr << DescribeEntry( row, 1 ) << " points to negative input index" << endl; if( ::floor( el ) > Input.Elements() ) bcierr << "Element (bin) specification in " << DescribeEntry( row, 1 ) << " exceeds number of input elements" << endl; if( ::fmod( el, 1.0f ) > 1e-2 ) bciout << "Element (bin) specification in physical units: " << DescribeEntry( row, 1 ) << " does not exactly meet a single element" << endl; int outputChannel = Classifier( row, 2 ); controlSignalChannels = max( controlSignalChannels, outputChannel ); } } // Requested output signal properties. Output = SignalProperties( controlSignalChannels, 1, Input.Type() ); // Output description. Output.ChannelUnit() = Input.ChannelUnit(); Output.ValueUnit().SetRawMin( Input.ValueUnit().RawMin() ) .SetRawMax( Input.ValueUnit().RawMax() ); float secsPerBlock = Parameter( "SampleBlockSize" ) / Parameter( "SamplingRate" ); Output.ElementUnit().SetOffset( 0 ).SetGain( secsPerBlock ).SetSymbol( "s" ); int visualizationTime = Output.ElementUnit().PhysicalToRaw( "15s" ); Output.ElementUnit().SetRawMin( 0 ).SetRawMax( visualizationTime - 1 ); }
void FFTFilter::Initialize( const SignalProperties& Input, const SignalProperties& /*Output*/ ) { mFFTOutputSignal = ( eFFTOutputSignal )( int )Parameter( "FFTOutputSignal" ); mFFTWindowLength = static_cast<int>( Input.Elements() * Parameter( "FFTWindowLength" ).InSampleBlocks() ); mFFTWindow = ( eFFTWindow )( int )Parameter( "FFTWindow" ); mFFTInputChannels.clear(); for( size_t i = 0; i < mVisualizations.size(); ++i ) mVisualizations[ i ].Send( CfgID::Visible, false ); mVisualizations.clear(); mVisualizeFFT = int( Parameter( "VisualizeFFT" ) ); if( mVisualizeFFT || mFFTOutputSignal == ePower ) { mVisProperties = Input; DetermineSignalProperties( mVisProperties, ePower ); PhysicalUnit elementUnit = mVisProperties.ElementUnit(); mVisProperties.SetChannels( mVisProperties.Elements() ); for( int i = 0; i < mVisProperties.Channels(); ++i ) mVisProperties.ChannelLabels()[i] = elementUnit.RawToPhysical( mVisProperties.Channels() - i - 1 ); mVisProperties.SetElements( 1 ); mVisProperties.ElementUnit() = Input.ElementUnit(); mVisProperties.ElementUnit().SetGain( mVisProperties.ElementUnit().Gain() * Input.Elements() ); mPowerSpectrum = GenericSignal( mVisProperties ); } for( int i = 0; i < Parameter( "FFTInputChannels" )->NumValues(); ++i ) { size_t ch = static_cast<size_t>( Input.ChannelIndex( Parameter( "FFTInputChannels" )( i ) ) ); mFFTInputChannels.push_back( ch ); if( mVisualizeFFT ) { ostringstream oss_i; oss_i << i + 1; mVisualizations.push_back( GenericVisualization( string( "FFT" ) + oss_i.str() ) ); ostringstream oss_ch; oss_ch << "FFT for Ch "; if( Input.ChannelLabels().IsTrivial() ) oss_ch << i + 1; else oss_ch << Input.ChannelLabels()[ch]; mVisualizations.back().Send( mVisProperties ) .Send( CfgID::WindowTitle, oss_ch.str().c_str() ) .Send( CfgID::GraphType, CfgID::Field2d ) .Send( CfgID::Visible, true ); } } mWindow.clear(); mWindow.resize( mFFTWindowLength, 1.0 ); float phasePerSample = static_cast<float>( M_PI ) / static_cast<float>( mFFTWindowLength ); // Window coefficients: None Hamming Hann Blackman const float a1[] = { 0, 0.46f, 0.5f, 0.5f, }, a2[] = { 0, 0, 0, 0.08f }; for( int i = 0; i < mFFTWindowLength; ++i ) mWindow[ i ] = 1.0f - a1[ mFFTWindow ] - a2[ mFFTWindow ] + a1[ mFFTWindow ] * cos( static_cast<float>( i ) * phasePerSample ) + a2[ mFFTWindow ] * cos( static_cast<float>( i ) * 2.0f * phasePerSample ); mValueBuffers.resize( mFFTInputChannels.size() ); ResetValueBuffers( mFFTWindowLength ); bool fftRequired = ( mVisualizeFFT || mFFTOutputSignal != eInput) && mFFTInputChannels.size() > 0; if( !fftRequired ) mFFTInputChannels.clear(); else mFFT.Initialize( mFFTWindowLength ); }