gr_mpsk_receiver()

「gr_mpsk_receiver()」の編集履歴(バックアップ)一覧に戻る

gr_mpsk_receiver() - (2011/07/30 (土) 22:22:11) のソース

まずはworkの部分
 int
 gr_mpsk_receiver_cc::general_work (int noutput_items, 
 				   gr_vector_int &ninput_items,
 				   gr_vector_const_void_star &input_items,
 				   gr_vector_void_star &output_items)
 {
   const gr_complex *in = (const gr_complex *) input_items[0];
   gr_complex *out = (gr_complex *) output_items[0];
 
   int i=0, o=0;
 
   while((o < noutput_items) && (i < ninput_items[0])) {
     while((d_mu > 1) && (i < ninput_items[0]))  {
       mm_sampler(in[i]);   // puts symbols into a buffer and adjusts d_mu
       i++;
     }
     
     if(i < ninput_items[0]) {
       gr_complex interp_sample = d_interp->interpolate(&d_dl[d_dl_idx], d_mu);
        
       mm_error_tracking(interp_sample);     // corrects M&M sample time
       phase_error_tracking(interp_sample);  // corrects phase and frequency offsets 
 
       out[o++] = interp_sample;
     }
   }
 
   #if 0
   printf("ninput_items: %d   noutput_items: %d   consuming: %d   returning: %d\n", 
 	 ninput_items[0], noutput_items, i, o);
   #endif
 
   consume_each(i);
   return o;
 }

 //コンストラクタ
 /*!
   * \brief Constructor to synchronize incoming M-PSK symbols
   *
   * \param M	        modulation order of the M-PSK modulation
   * \param theta	any constant phase rotation from the real axis of the constellation
   * \param alpha	gain parameter to adjust the phase in the Costas loop (~0.01)
   * \param beta        gain parameter to adjust the frequency in the Costas loop (~alpha^2/4)	
   * \param fmin        minimum normalized frequency value the loop can achieve
   * \param fmax        maximum normalized frequency value the loop can achieve
   * \param mu          initial parameter for the interpolator [0,1]
   * \param gain_mu     gain parameter of the M&M error signal to adjust mu (~0.05)
   * \param omega       initial value for the number of symbols between samples (~number of samples/symbol)
   * \param gain_omega  gain parameter to adjust omega based on the error (~omega^2/4)
   * \param omega_rel   sets the maximum (omega*(1+omega_rel)) and minimum (omega*(1+omega_rel)) omega (~0.005)
   *
   * The constructor also chooses which phase detector and decision maker to use in the work loop based on the
   * value of M.
 */

 gr_mpsk_receiver_cc::gr_mpsk_receiver_cc (unsigned int M, float theta,  
 					  float alpha, float beta,
 					  float fmin, float fmax,
 					  float mu, float gain_mu, 
 					  float omega, float gain_omega, float omega_rel)
   : gr_block ("mpsk_receiver_cc",
 	      gr_make_io_signature (1, 1, sizeof (gr_complex)),
 	      gr_make_io_signature (1, 1, sizeof (gr_complex))),
     d_M(M), d_theta(theta), 
     d_alpha(alpha), d_beta(beta), d_freq(0), d_max_freq(fmax), d_min_freq(fmin), d_phase(0),
     d_current_const_point(0),
     d_mu(mu), d_gain_mu(gain_mu), d_gain_omega(gain_omega), 
     d_omega_rel(omega_rel), d_max_omega(0), d_min_omega(0),
     d_p_2T(0), d_p_1T(0), d_p_0T(0), d_c_2T(0), d_c_1T(0), d_c_0T(0)
 {
   //補間サンプルを計算
   d_interp = new gri_mmse_fir_interpolator_cc();//Compute intermediate samples between signal samples x(k*Ts)
   d_dl_idx = 0;
   //omega(interpolation.クロックレート.サンプル間にいくつのシンボルが入っているかを示す.最大値はsamples/symbol)をセットする.
   set_omega(omega); // \param omega\ initial value for the number of symbols between samples (~number of samples/symbol)
   if (omega <= 0.0) //omegaは0より大きくないとだめ
     throw std::out_of_range ("clock rate must be > 0");
   if (gain_mu <  0  || gain_omega < 0) 
     throw std::out_of_range ("Gains must be non-negative");
   
   assert(d_interp->ntaps() <= DLLEN); //DLLEN(=8)はdelay line lengthらしい。。
   
   // zero double length delay line.
   for (unsigned int i = 0; i < 2 * DLLEN; i++)
     d_dl[i] = gr_complex(0.0,0.0); //d_dlはDDLENの二倍確保
 
   // build the constellation vector from M
   make_constellation();
   
   // Select a phase detector and a decision maker for the modulation order
   switch(d_M) {
   case 2:  // optimized algorithms for BPSK
    /*!
    * \brief Phase error detector for BPSK modulation.
    * \param sample   the I&Q sample from which to determine the phase error
    * This function determines the phase error using a simple BPSK phase error detector by multiplying the real
    * and imaginary (the error signal) components together. As the imaginary part goes to 0, so does this error.
    * \returns the approximated phase error.
   */
     //float phase_error_detector_bpsk(gr_complex sample) const;位相誤り検波
     d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_bpsk; 
     d_decision = &gr_mpsk_receiver_cc::decision_bpsk; //bpsk用のスライサー(0以上or0以下).エラーを最小化するコンスタレーションを返す。
     break; 
 
   case 4: // optimized algorithms for QPSK
     d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_qpsk; //qpsk;
     d_decision = &gr_mpsk_receiver_cc::decision_qpsk;
     break;
 
   default: // generic algorithms for any M (power of 2?) but not pretty
     d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_generic;
     d_decision = &gr_mpsk_receiver_cc::decision_generic;
     break;
   }
 }
 
 //シンボル一つずつをバッファーに入れてd_muを調節する。muは少数部分遅延
 void
 gr_mpsk_receiver_cc::mm_sampler(const gr_complex symbol)
 {
   gr_complex sample, nco;
 
   d_mu--;             // skip a number of symbols between sampling
   d_phase += d_freq;  // increment the phase based on the frequency of the rotation
 
   // Keep phase clamped and not walk to infinity
   while(d_phase > M_TWOPI)
     d_phase -= M_TWOPI;
   while(d_phase < -M_TWOPI)
     d_phase += M_TWOPI;
   
   nco = gr_expj(d_phase+d_theta);   // get the NCO value for derotating the current sample
   sample = nco*symbol;      // get the downconverted symbol
   
   // Fill up the delay line for the interpolator
   //バッファにダウンコーバートしたシンボルを入れる
   d_dl[d_dl_idx] = sample;
   //オーバーフロウのためバッファの後半部にこいつを入れる。
   d_dl[(d_dl_idx + DLLEN)] = sample;  // put this in the second half of the buffer for overflows
   //境界で遅延ラインインデックスをキープする
   d_dl_idx = (d_dl_idx+1) % DLLEN;    // Keep the delay line index in bounds
 }

----