⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contin_adv_t.cpp

📁 this is the simulation model for wireless communication
💻 CPP
字号:
//
//  File = contin_adv_T.cpp
//

#include <stdlib.h>
#include <fstream>
#include <strstream>
#include "parmfile.h"
#include "model_error.h"
#include "contin_adv_T.h"
#include "model_graph.h"
#include "sinc.h"
extern ParmFile *ParmInput;
extern PracSimModel *ActiveModel;

//==================================================================
// general constructor that supports any of the possible delay modes

template< class T >
ContinuousAdvance< T >::ContinuousAdvance( char* instance_name,
                                PracSimModel* outer_model,
                                Signal<T>* in_signal,
                                Signal<T>* out_signal,
                                Control<float> *new_advance,
                                Control<bool> *advance_change_enabled )
              :PracSimModel(instance_name,
                            outer_model)
{  
  this->Constructor_Common_Tasks( instance_name, in_signal, out_signal);
  //------------------------------------------
  //  Controls

  New_Advance = new_advance;
  Advance_Change_Enabled = advance_change_enabled;

  return;
  }
//==================================================================
//  Constructor 2
//  This constructor supports any delay mode except DELAY_MODE_GATED
//  (The calling sequence does not pass the gating control.)

template< class T >
ContinuousAdvance< T >::ContinuousAdvance( char* instance_name,
                                PracSimModel* outer_model,
                                Signal<T>* in_signal,
                                Signal<T>* out_signal,
                                Control<float> *new_advance )
              :PracSimModel(instance_name,
                            outer_model)
{  
  this->Constructor_Common_Tasks( instance_name, in_signal, out_signal);
  //------------------------------------------
  //  Controls

  New_Advance = new_advance;

  switch (Advance_Mode)
    {
    case ADVANCE_MODE_NONE:
    case ADVANCE_MODE_FIXED:
    case ADVANCE_MODE_DYNAMIC:
      break;
    case ADVANCE_MODE_GATED:
      {
      ostrstream temp_stream;
      temp_stream << "ADVANCE_MODE_GATED is not supported by called constructor (2)"
                   << ends;
      char *message = temp_stream.str();
      PsModelError(FATAL, message);
      delete []message;
      }
      break;
    }
  return;
  }
//======================================================================
//  Constructor 3
//  This constructor supports only ADVANCE_MODE_NONE and ADVANCE_MODE_FIXED
//  (The calling sequence does not pass the delay control or 
//   the gating control.)

template< class T >
ContinuousAdvance< T >::ContinuousAdvance( char* instance_name,
                                PracSimModel* outer_model,
                                Signal<T>* in_signal,
                                Signal<T>* out_signal )
              :PracSimModel(instance_name,
                            outer_model)
{  
  this->Constructor_Common_Tasks( instance_name, in_signal, out_signal);

  switch (Advance_Mode)
    {
    case ADVANCE_MODE_NONE:
    case ADVANCE_MODE_FIXED:
      break;
    case ADVANCE_MODE_DYNAMIC:
      {
      ostrstream temp_stream;
      temp_stream << "ADVANCE_MODE_DYNAMIC is not supported by called contructor (3)"
                   << ends;
      char *message = temp_stream.str();
      PsModelError(FATAL, message);
      delete []message;
      }
      break;
    case ADVANCE_MODE_GATED:
      {
      ostrstream temp_stream;
      temp_stream << "ADVANCE_MODE_GATED is not supported by called constructor (3)"
                   << ends;
      char *message = temp_stream.str();
      PsModelError(FATAL, message);
      delete []message;
      }
      break;
    }
  return;
  }
//===================================================================
template< class T >
void ContinuousAdvance< T >::Constructor_Common_Tasks( char* instance_name,
                                              Signal<T>* in_signal,
                                              Signal<T>* out_signal)
{
  MODEL_NAME(ContinuousAdvance);
  ActiveModel = this;

  //-----------------------------------
  // Read configuration parameters
  OPEN_PARM_BLOCK;

  Advance_Mode = GetAdvanceModeParm("Advance_Mode\0");
  BasicResults << "   " << "Advance_Mode = " << Advance_Mode << endl;

  Interp_Mode = GetInterpModeParm("Interp_Mode\0");
  BasicResults << "   " << "Interp_Mode = " << Interp_Mode << endl;

  if( Interp_Mode == INTERP_MODE_SINC )
    {
    GET_INT_PARM(Num_Sidelobes);
    }
  else
    {
    Num_Sidelobes = 0;
    }

  GET_DOUBLE_PARM(Max_Advance);

  GET_DOUBLE_PARM(Initial_Advance);

  //-----------------------------------
  //  Signals

  In_Sig = in_signal;
  Out_Sig = out_signal;

  MAKE_OUTPUT( Out_Sig );
  MAKE_INPUT( In_Sig );
};
//================================================
template< class T >
ContinuousAdvance<T>::~ContinuousAdvance( void ){ };

//=======================================================

template< class T >
void ContinuousAdvance<T>::Initialize()
  {
  double active_adv_in_samps;
  //---------------------------------------
  //  Initialize derived parameters

  Samp_Intvl = In_Sig->GetSampIntvl();
  Block_Size = In_Sig->GetBlockSize();
  //---------------------------------------
  //  Initialize physical buffer

  Max_Buffer_Len = 1 + Num_Sidelobes + int(Max_Advance / Samp_Intvl);

  Start_Of_Buffer = new T[Max_Buffer_Len];
  for(int i=0; i<Max_Buffer_Len; i++)
    {
    *(Start_Of_Buffer+i) = 0;
    }
  //---------------------------------------
  //  Initialize active portion of buffer

  Active_Advance = Initial_Advance;
  active_adv_in_samps = Active_Advance/Samp_Intvl;
  Active_Buffer_Len = 1 + int(floor(active_adv_in_samps));

  Interp_Weight = active_adv_in_samps - floor(active_adv_in_samps); //correct one
  if(Interp_Weight > 0.999999) Interp_Weight = 1.0;
  if(Interp_Weight < 0.000001) Interp_Weight = 0.0;
  One_Minus_Weight = 1.0 - Interp_Weight;

  End_Of_Buffer = Start_Of_Buffer + Max_Buffer_Len - 1;
  Write_Ptr = Start_Of_Buffer;
  Read_Ptr = Start_Of_Buffer + Max_Buffer_Len - Active_Buffer_Len;

}

//=======================================
template< class T >
int ContinuousAdvance<T>::Execute()
{
  T *start_of_buffer, *end_of_buffer;
  T *read_ptr, *write_ptr;
  T input_samp, *input_signal_ptr;
  T output_samp, *output_signal_ptr;
  T *oldest_lead_samp_ptr, *newest_lag_samp_ptr;
  T *samp_ptr;
  T left_samp, right_samp;
  int num_sidelobes;
  int max_buffer_len;
  int is, block_size;
  double samp_intvl;
  float interp_weight, one_minus_weight;

  //-----------------------------------------
  // Get pointers for input and output signals
  
  output_signal_ptr = GET_OUTPUT_PTR(Out_Sig);
  input_signal_ptr = GET_INPUT_PTR(In_Sig);

  //------------------------------------------------
  //  Do actions peculiar to each delay mode

  switch (Advance_Mode)
    {
    //- - - - - - - - - - - - - - - - - - - - - - 
    case ADVANCE_MODE_NONE:
      {
      //...copy input directly to output
      for(is=0; is<Block_Size; is++)
        {
        input_samp = *input_signal_ptr++;
        *output_signal_ptr++ =input_samp;
        }
      return(_MES_AOK);
      }
    //- - - - - - - - - - - - - - - - - - - - - - 
    case ADVANCE_MODE_FIXED:
      {
      break;
      }
    //- - - - - - - - - - - - - - - - - - - - - - 
    case ADVANCE_MODE_GATED:
      {
      //  If advance change is NOT enabled, get out of switch.
      //  If advance change IS enabled, fall through to next case
      //  and get new value for Active_Delay.

      if( Advance_Change_Enabled->GetValue() == false )
        {
        break;
        }
      }
    //- - - - - - - - - - - - - - - - - - - - - - 
    case ADVANCE_MODE_DYNAMIC:
      {
      Active_Advance = New_Advance->GetValue();
      double active_adv_in_samps = Active_Advance/Samp_Intvl;
      Active_Buffer_Len = 1 + int(floor(active_adv_in_samps));
      Interp_Weight = active_adv_in_samps - floor(active_adv_in_samps);
      if(Interp_Weight > 0.999999) Interp_Weight = 1.0;
      if(Interp_Weight < 0.000001) Interp_Weight = 0.0;
      One_Minus_Weight = 1.0 - Interp_Weight;

      Read_Ptr = Write_Ptr - Active_Buffer_Len;
      if(Read_Ptr < Start_Of_Buffer) Read_Ptr += Max_Buffer_Len;

      break;
      }
    } // end of switch on Delay_Mode

  //------------------------------------------------
  //  copy frequently used items into local storage

  block_size = Block_Size;
  samp_intvl = Samp_Intvl;
  read_ptr = Read_Ptr;
  write_ptr = Write_Ptr;
  start_of_buffer = Start_Of_Buffer;
  end_of_buffer = End_Of_Buffer;
  interp_weight = Interp_Weight;
  one_minus_weight = One_Minus_Weight;

  //-----------------------------------------------------
  // if active delay is zero, just copy input to output

  if(Active_Advance == 0)
    {
    for(is=0; is<block_size; is++)
      {
      input_samp = *input_signal_ptr++;
      *output_signal_ptr++ =input_samp;
      }
    return(_MES_AOK);
    }

  //---------------------------------------------------
  //  error condition if active delay exceeds max delay

  if(Active_Advance > Max_Advance)
    {
    ostrstream temp_stream;
    temp_stream << "Active_Advance (" << Active_Advance
                 << ") is greater than Max_Advance ("
                 << Max_Advance << ")." << ends;
    char *message = temp_stream.str();
    PsModelError(FATAL, message);
    delete []message;

    }

  //--------------------------------------------------
  //  normal sample processing

  switch (Interp_Mode)
    {
    case INTERP_MODE_LINEAR:
      for(is=0; is<block_size; is++)
        {
        input_samp = *input_signal_ptr++;

        //---------------------------------------------------------------
        // get samps that bracket desired time instant from delay buffer
    
        left_samp = *read_ptr++;
        if(read_ptr > end_of_buffer) read_ptr = start_of_buffer;
        if(Active_Advance < Samp_Intvl)
          right_samp = input_samp;
        else
          right_samp = *read_ptr;

        //------------------------------------------
        // do interpolation to get output value

        output_samp = interp_weight*left_samp + one_minus_weight*right_samp;

        //------------------------------------
        // put input sample into delay buffer

        *write_ptr++ = input_samp;
        if(write_ptr > end_of_buffer) write_ptr = start_of_buffer;

        *output_signal_ptr++ =output_samp;
        }
      break;
    case INTERP_MODE_SINC:
      num_sidelobes = Num_Sidelobes;
      max_buffer_len = Max_Buffer_Len;
      for(is=0; is<block_size; is++)
        {
        input_samp = *input_signal_ptr++;

        //---------------------------------------------------------------
        // get samps that bracket desired time instant from delay buffer
    
        oldest_lead_samp_ptr = read_ptr - num_sidelobes + 1;
        if(oldest_lead_samp_ptr < start_of_buffer) oldest_lead_samp_ptr += max_buffer_len;
        left_samp = *read_ptr++;

        if(read_ptr > end_of_buffer) read_ptr = start_of_buffer;
        newest_lag_samp_ptr = read_ptr + max_buffer_len - 1;
        if(newest_lag_samp_ptr > end_of_buffer) newest_lag_samp_ptr -=max_buffer_len; 

        if(Active_Advance < Samp_Intvl)
          right_samp = input_samp;
        else
          right_samp = *read_ptr;

        //------------------------------------------
        // do interpolation to get output value

        output_samp = 0.0;
        int lobe_idx;

        //  Add in sidelobe contributions from leading samples

        samp_ptr = oldest_lead_samp_ptr;
        for(lobe_idx=num_sidelobes-1; lobe_idx>=0; lobe_idx--)
          {
          output_samp += (*samp_ptr++) * float(sinc(double(one_minus_weight + lobe_idx)));
          if(samp_ptr > end_of_buffer) samp_ptr = start_of_buffer;
          }

        //  Add in sidelobe contributions from leading samples

        for(lobe_idx=0; lobe_idx<num_sidelobes; lobe_idx++)
          {
          output_samp += float(sinc(double(interp_weight + lobe_idx))) * (*samp_ptr++);
          if(samp_ptr > end_of_buffer) samp_ptr = start_of_buffer;
          }

        //------------------------------------
        // put input sample into delay buffer

        *write_ptr++ = input_samp;
        if(write_ptr > end_of_buffer) write_ptr = start_of_buffer;

        *output_signal_ptr++ =output_samp;
        }
      break;
    default:
      ostrstream temp_stream;
      temp_stream << "Requested interpolation mode is not supported"
                   << ends;
      char *message = temp_stream.str();
      PsModelError(FATAL, message);
      delete []message;
    } // end of switch om Interp_Mode

  Read_Ptr = read_ptr;
  Write_Ptr = write_ptr;
  return(_MES_AOK);
}
template ContinuousAdvance< int >;
template ContinuousAdvance< float >;
template ContinuousAdvance< std::complex<float> >;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -