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.クロックレート.2サンプル間にいくつのシンボルが入っているかを示す.最大値は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 } ----
まずは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 } ----

表示オプション

横に並べて表示:
変化行の前後のみ表示: