void
ARThread::OnInitialize( const SignalProperties& Input, const SignalProperties& Output )
{
  mMEMPredictor.SetModelOrder( Parameter( "ModelOrder" ) );
  mOutputType = Parameter( "OutputType" );
  if( mOutputType != Coefficients )
  {
    mTransferSpectrum.SetFirstBinCenter( Parameter( "FirstBinCenter" ).InHertz() / Input.SamplingRate() );
    mTransferSpectrum.SetBinWidth( Parameter( "BinWidth" ).InHertz() / Input.SamplingRate() );
    mTransferSpectrum.SetNumBins( Output.Elements() );
    mTransferSpectrum.SetEvaluationsPerBin( Parameter( "EvaluationsPerBin" ) );
    mSpectrum.resize( Output.Elements() );
  }
  mInput.resize( Input.Elements() );
}
void
FFTFilter::DetermineSignalProperties( SignalProperties& ioProperties, int inFFTType ) const
{
  int numChannels = Parameter( "FFTInputChannels" )->NumValues(),
      fftWindowLength = static_cast<int>( ioProperties.Elements() * Parameter( "FFTWindowLength" ).InSampleBlocks() );
  if( numChannels > 0 && fftWindowLength == 0 )
    bcierr << "FFTWindowLength must exceed a single sample's duration" << endl;
  double freqRange = ioProperties.SamplingRate() / 2.0;

  switch( inFFTType )
  {
    case eInput:
      break;

    case ePower:
    {
      ioProperties.SetName( "FFT Power Spectrum" )
                  .SetChannels( numChannels )
                  .SetElements( fftWindowLength / 2 + 1 );
      ioProperties.ElementUnit().SetOffset( 0.0 )
                                .SetGain( freqRange / ( ioProperties.Elements() - 1 ) )
                                .SetSymbol( "Hz" );
      double amplitude = ioProperties.ValueUnit().RawMax() - ioProperties.ValueUnit().RawMin();
      ioProperties.ValueUnit().SetRawMin( 0 )
                              .SetRawMax( amplitude * amplitude );
      ioProperties.ElementUnit().SetRawMin( 0 )
                                .SetRawMax( ioProperties.Elements() - 1 );
    } break;

    case eHalfcomplex:
      ioProperties.SetName( "FFT Coefficients" )
                  .SetChannels( numChannels )
                  .SetElements( fftWindowLength );
      ioProperties.ElementUnit().SetRawMin( 0 )
                                .SetRawMax( fftWindowLength - 1 )
                                .SetOffset( 0 )
                                .SetGain( 1 )
                                .SetSymbol( "" );
      break;

    default:
      throw std_logic_error( "Unknown value of FFT type" );
  }
}