示例#1
0
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 );
  }
}
示例#2
0
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" ) );
}
示例#4
0
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 );
}
示例#5
0
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 );
}