mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next
This commit is contained in:
		
							
								
								
									
										2
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ GNSS-SDR Authorship | |||||||
|  |  | ||||||
| The GNSS-SDR project is hosted and sponsored by the Centre Tecnològic de | The GNSS-SDR project is hosted and sponsored by the Centre Tecnològic de | ||||||
| Telecomunicacions de Catalunya (CTTC), a non-profit research foundation located | Telecomunicacions de Catalunya (CTTC), a non-profit research foundation located | ||||||
| in Castelldefels (40.396764 N, 3.713379 E), 20 km south of Barcelona, Spain. | in Castelldefels (41.27504 N, 1.987709 E), 20 km south of Barcelona, Spain. | ||||||
| GNSS-SDR is the by-product of GNSS research conducted at the Communications | GNSS-SDR is the by-product of GNSS research conducted at the Communications | ||||||
| Systems Division of CTTC, and it is the combined effort of students, | Systems Division of CTTC, and it is the combined effort of students, | ||||||
| software engineers and researchers from different institutions around the World. | software engineers and researchers from different institutions around the World. | ||||||
|   | |||||||
| @@ -43,38 +43,112 @@ using google::LogMessage; | |||||||
| FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role, | FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role, | ||||||
|     unsigned int in_streams, unsigned int out_streams) : config_(configuration), role_(role), in_streams_(in_streams), out_streams_(out_streams) |     unsigned int in_streams, unsigned int out_streams) : config_(configuration), role_(role), in_streams_(in_streams), out_streams_(out_streams) | ||||||
| { | { | ||||||
|     size_t item_size; |     std::string default_input_item_type = "gr_complex"; | ||||||
|     (*this).init(); |     std::string default_output_item_type = "gr_complex"; | ||||||
|     int decimation_factor; |     std::string default_taps_item_type = "float"; | ||||||
|  |     std::string default_dump_filename = "../data/input_filter.dat"; | ||||||
|  |     double default_intermediate_freq = 0.0; | ||||||
|  |     double default_sampling_freq = 4000000.0; | ||||||
|  |     int default_number_of_taps = 6; | ||||||
|  |     unsigned int default_number_of_bands = 2; | ||||||
|  |     std::vector<double> default_bands = {0.0, 0.4, 0.6, 1.0}; | ||||||
|  |     std::vector<double> default_ampl = {1.0, 1.0, 0.0, 0.0}; | ||||||
|  |     std::vector<double> default_error_w = {1.0, 1.0}; | ||||||
|  |     std::string default_filter_type = "bandpass"; | ||||||
|  |     int default_grid_density = 16; | ||||||
|     int default_decimation_factor = 1; |     int default_decimation_factor = 1; | ||||||
|     decimation_factor = config_->property(role_ + ".decimation_factor", default_decimation_factor); |  | ||||||
|  |     DLOG(INFO) << "role " << role_; | ||||||
|  |  | ||||||
|  |     input_item_type_ = config_->property(role_ + ".input_item_type", default_input_item_type); | ||||||
|  |     output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type); | ||||||
|  |     taps_item_type_ = config_->property(role_ + ".taps_item_type", default_taps_item_type); | ||||||
|  |     dump_ = config_->property(role_ + ".dump", false); | ||||||
|  |     dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); | ||||||
|  |     intermediate_freq_ = config_->property(role_ + ".IF", default_intermediate_freq); | ||||||
|  |     sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq); | ||||||
|  |     int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps); | ||||||
|  |     unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands); | ||||||
|  |     std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type); | ||||||
|  |     decimation_factor_ = config_->property(role_ + ".decimation_factor", default_decimation_factor); | ||||||
|  |  | ||||||
|  |     if (filter_type.compare("lowpass") != 0) | ||||||
|  |         { | ||||||
|  |             std::vector<double> taps_d; | ||||||
|  |             std::vector<double> bands; | ||||||
|  |             std::vector<double> ampl; | ||||||
|  |             std::vector<double> error_w; | ||||||
|  |             std::string option; | ||||||
|  |             double option_value; | ||||||
|  |  | ||||||
|  |             for (unsigned int i = 0; i < number_of_bands; i++) | ||||||
|  |                 { | ||||||
|  |                     option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_begin"; | ||||||
|  |                     option_value = config_->property(role_ + option, default_bands[i]); | ||||||
|  |                     bands.push_back(option_value); | ||||||
|  |  | ||||||
|  |                     option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_end"; | ||||||
|  |                     option_value = config_->property(role_ + option, default_bands[i]); | ||||||
|  |                     bands.push_back(option_value); | ||||||
|  |  | ||||||
|  |                     option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_begin"; | ||||||
|  |                     option_value = config_->property(role_ + option, default_bands[i]); | ||||||
|  |                     ampl.push_back(option_value); | ||||||
|  |  | ||||||
|  |                     option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_end"; | ||||||
|  |                     option_value = config_->property(role_ + option, default_bands[i]); | ||||||
|  |                     ampl.push_back(option_value); | ||||||
|  |  | ||||||
|  |                     option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_error"; | ||||||
|  |                     option_value = config_->property(role_ + option, default_bands[i]); | ||||||
|  |                     error_w.push_back(option_value); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             int grid_density = config_->property(role_ + ".grid_density", default_grid_density); | ||||||
|  |             taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density); | ||||||
|  |             taps_.reserve(taps_d.size()); | ||||||
|  |             for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++) | ||||||
|  |                 { | ||||||
|  |                     taps_.push_back(static_cast<float>(*it)); | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             double default_bw = (sampling_freq_ / decimation_factor_) / 2; | ||||||
|  |             double bw_ = config_->property(role_ + ".bw", default_bw); | ||||||
|  |             double default_tw = bw_ / 10.0; | ||||||
|  |             double tw_ = config_->property(role_ + ".tw", default_tw); | ||||||
|  |             taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     size_t item_size; | ||||||
|  |  | ||||||
|     if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("gr_complex") == 0) && (output_item_type_.compare("gr_complex") == 0)) |     if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("gr_complex") == 0) && (output_item_type_.compare("gr_complex") == 0)) | ||||||
|         { |         { | ||||||
|             item_size = sizeof(gr_complex);    //output |             item_size = sizeof(gr_complex);    //output | ||||||
|             input_size_ = sizeof(gr_complex);  //input |             input_size_ = sizeof(gr_complex);  //input | ||||||
|             freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); |             freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); | ||||||
|             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")"; |             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")"; | ||||||
|         } |         } | ||||||
|     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("float") == 0) && (output_item_type_.compare("gr_complex") == 0)) |     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("float") == 0) && (output_item_type_.compare("gr_complex") == 0)) | ||||||
|         { |         { | ||||||
|             item_size = sizeof(gr_complex); |             item_size = sizeof(gr_complex); | ||||||
|             input_size_ = sizeof(float);  //input |             input_size_ = sizeof(float);  //input | ||||||
|             freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); |             freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); | ||||||
|             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_fcf_->unique_id() << ")"; |             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_fcf_->unique_id() << ")"; | ||||||
|         } |         } | ||||||
|     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("gr_complex") == 0)) |     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("gr_complex") == 0)) | ||||||
|         { |         { | ||||||
|             item_size = sizeof(gr_complex); |             item_size = sizeof(gr_complex); | ||||||
|             input_size_ = sizeof(int16_t);  //input |             input_size_ = sizeof(int16_t);  //input | ||||||
|             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); |             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); | ||||||
|             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; |             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; | ||||||
|         } |         } | ||||||
|     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("cshort") == 0)) |     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("cshort") == 0)) | ||||||
|         { |         { | ||||||
|             item_size = sizeof(lv_16sc_t); |             item_size = sizeof(lv_16sc_t); | ||||||
|             input_size_ = sizeof(int16_t);  //input |             input_size_ = sizeof(int16_t);  //input | ||||||
|             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); |             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); | ||||||
|             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; |             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; | ||||||
|             complex_to_float_ = gr::blocks::complex_to_float::make(); |             complex_to_float_ = gr::blocks::complex_to_float::make(); | ||||||
|             float_to_short_1_ = gr::blocks::float_to_short::make(); |             float_to_short_1_ = gr::blocks::float_to_short::make(); | ||||||
| @@ -86,7 +160,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration | |||||||
|             item_size = sizeof(gr_complex); |             item_size = sizeof(gr_complex); | ||||||
|             input_size_ = sizeof(int8_t);  //input |             input_size_ = sizeof(int8_t);  //input | ||||||
|             gr_char_to_short_ = gr::blocks::char_to_short::make(); |             gr_char_to_short_ = gr::blocks::char_to_short::make(); | ||||||
|             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); |             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); | ||||||
|             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; |             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; | ||||||
|         } |         } | ||||||
|     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("byte") == 0) && (output_item_type_.compare("cbyte") == 0)) |     else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("byte") == 0) && (output_item_type_.compare("cbyte") == 0)) | ||||||
| @@ -94,7 +168,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration | |||||||
|             item_size = sizeof(lv_8sc_t); |             item_size = sizeof(lv_8sc_t); | ||||||
|             input_size_ = sizeof(int8_t);  //input |             input_size_ = sizeof(int8_t);  //input | ||||||
|             gr_char_to_short_ = gr::blocks::char_to_short::make(); |             gr_char_to_short_ = gr::blocks::char_to_short::make(); | ||||||
|             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); |             freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); | ||||||
|             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; |             DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; | ||||||
|             complex_to_complex_byte_ = make_complex_float_to_complex_byte(); |             complex_to_complex_byte_ = make_complex_float_to_complex_byte(); | ||||||
|         } |         } | ||||||
| @@ -311,83 +385,3 @@ gr::basic_block_sptr FreqXlatingFirFilter::get_right_block() | |||||||
|             LOG(ERROR) << " Unknown input filter input/output item type conversion"; |             LOG(ERROR) << " Unknown input filter input/output item type conversion"; | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void FreqXlatingFirFilter::init() |  | ||||||
| { |  | ||||||
|     std::string default_input_item_type = "gr_complex"; |  | ||||||
|     std::string default_output_item_type = "gr_complex"; |  | ||||||
|     std::string default_taps_item_type = "float"; |  | ||||||
|     std::string default_dump_filename = "../data/input_filter.dat"; |  | ||||||
|     double default_intermediate_freq = 0.0; |  | ||||||
|     double default_sampling_freq = 4000000.0; |  | ||||||
|     int default_number_of_taps = 6; |  | ||||||
|     unsigned int default_number_of_bands = 2; |  | ||||||
|     std::vector<double> default_bands = {0.0, 0.4, 0.6, 1.0}; |  | ||||||
|     std::vector<double> default_ampl = {1.0, 1.0, 0.0, 0.0}; |  | ||||||
|     std::vector<double> default_error_w = {1.0, 1.0}; |  | ||||||
|     std::string default_filter_type = "bandpass"; |  | ||||||
|     int default_grid_density = 16; |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "role " << role_; |  | ||||||
|  |  | ||||||
|     input_item_type_ = config_->property(role_ + ".input_item_type", default_input_item_type); |  | ||||||
|     output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type); |  | ||||||
|     taps_item_type_ = config_->property(role_ + ".taps_item_type", default_taps_item_type); |  | ||||||
|     dump_ = config_->property(role_ + ".dump", false); |  | ||||||
|     dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); |  | ||||||
|     intermediate_freq_ = config_->property(role_ + ".IF", default_intermediate_freq); |  | ||||||
|     sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq); |  | ||||||
|     int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps); |  | ||||||
|     unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands); |  | ||||||
|     std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type); |  | ||||||
|  |  | ||||||
|     if (filter_type.compare("lowpass") != 0) |  | ||||||
|         { |  | ||||||
|             std::vector<double> taps_d; |  | ||||||
|             std::vector<double> bands; |  | ||||||
|             std::vector<double> ampl; |  | ||||||
|             std::vector<double> error_w; |  | ||||||
|             std::string option; |  | ||||||
|             double option_value; |  | ||||||
|  |  | ||||||
|             for (unsigned int i = 0; i < number_of_bands; i++) |  | ||||||
|                 { |  | ||||||
|                     option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_begin"; |  | ||||||
|                     option_value = config_->property(role_ + option, default_bands[i]); |  | ||||||
|                     bands.push_back(option_value); |  | ||||||
|  |  | ||||||
|                     option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_end"; |  | ||||||
|                     option_value = config_->property(role_ + option, default_bands[i]); |  | ||||||
|                     bands.push_back(option_value); |  | ||||||
|  |  | ||||||
|                     option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_begin"; |  | ||||||
|                     option_value = config_->property(role_ + option, default_bands[i]); |  | ||||||
|                     ampl.push_back(option_value); |  | ||||||
|  |  | ||||||
|                     option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_end"; |  | ||||||
|                     option_value = config_->property(role_ + option, default_bands[i]); |  | ||||||
|                     ampl.push_back(option_value); |  | ||||||
|  |  | ||||||
|                     option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_error"; |  | ||||||
|                     option_value = config_->property(role_ + option, default_bands[i]); |  | ||||||
|                     error_w.push_back(option_value); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|             int grid_density = config_->property(role_ + ".grid_density", default_grid_density); |  | ||||||
|             taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density); |  | ||||||
|             taps_.reserve(taps_d.size()); |  | ||||||
|             for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++) |  | ||||||
|                 { |  | ||||||
|                     taps_.push_back(static_cast<float>(*it)); |  | ||||||
|                 } |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             double default_bw = 2000000.0; |  | ||||||
|             double bw_ = config_->property(role_ + ".bw", default_bw); |  | ||||||
|             double default_tw = bw_ / 10.0; |  | ||||||
|             double tw_ = config_->property(role_ + ".tw", default_tw); |  | ||||||
|             taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_); |  | ||||||
|         } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -95,6 +95,7 @@ private: | |||||||
|     gr::filter::freq_xlating_fir_filter_fcf::sptr freq_xlating_fir_filter_fcf_; |     gr::filter::freq_xlating_fir_filter_fcf::sptr freq_xlating_fir_filter_fcf_; | ||||||
|     gr::filter::freq_xlating_fir_filter_scf::sptr freq_xlating_fir_filter_scf_; |     gr::filter::freq_xlating_fir_filter_scf::sptr freq_xlating_fir_filter_scf_; | ||||||
|     ConfigurationInterface* config_; |     ConfigurationInterface* config_; | ||||||
|  |     int decimation_factor_; | ||||||
|     bool dump_; |     bool dump_; | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::string input_item_type_; |     std::string input_item_type_; | ||||||
| @@ -114,7 +115,6 @@ private: | |||||||
|     gr::blocks::float_to_short::sptr float_to_short_2_; |     gr::blocks::float_to_short::sptr float_to_short_2_; | ||||||
|     short_x2_to_cshort_sptr short_x2_to_cshort_; |     short_x2_to_cshort_sptr short_x2_to_cshort_; | ||||||
|     complex_float_to_complex_byte_sptr complex_to_complex_byte_; |     complex_float_to_complex_byte_sptr complex_to_complex_byte_; | ||||||
|     void init(); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif  // GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_ | #endif  // GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_ | ||||||
|   | |||||||
| @@ -0,0 +1,278 @@ | |||||||
|  | /*! | ||||||
|  |  * \file volk_gnsssdr_32f_fast_resamplerxnpuppet_32f.h | ||||||
|  |  * \brief VOLK_GNSSSDR puppet for the multiple 32-bit float vector fast resampler kernel. | ||||||
|  |  * \authors <ul> | ||||||
|  |  *          <li> Cillian O'Driscoll 2017 cillian.odriscoll at gmail dot com | ||||||
|  |  *          <li> Javier Arribas, 2018. javiarribas(at)gmail.com | ||||||
|  |  *          </ul> | ||||||
|  |  * | ||||||
|  |  * VOLK_GNSSSDR puppet for integrating the multiple resampler into the test system | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef INCLUDED_volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_H | ||||||
|  | #define INCLUDED_volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_H | ||||||
|  |  | ||||||
|  | #include "volk_gnsssdr/volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h" | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr_malloc.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_GENERIC | ||||||
|  | static inline void volk_gnsssdr_32f_fast_resamplerxnpuppet_32f_generic(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | { | ||||||
|  |     int code_length_chips = 2046; | ||||||
|  |     float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  |     int num_out_vectors = 3; | ||||||
|  |     float rem_code_phase_chips = -0.234; | ||||||
|  |     unsigned int n; | ||||||
|  |     float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  |  | ||||||
|  |     float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  |     for (n = 0; n < num_out_vectors; n++) | ||||||
|  |         { | ||||||
|  |             result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     volk_gnsssdr_32f_xn_fast_resampler_32f_xn_generic(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  |  | ||||||
|  |     memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  |  | ||||||
|  |     for (n = 0; n < num_out_vectors; n++) | ||||||
|  |         { | ||||||
|  |             volk_gnsssdr_free(result_aux[n]); | ||||||
|  |         } | ||||||
|  |     volk_gnsssdr_free(result_aux); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif /* LV_HAVE_GENERIC */ | ||||||
|  |  | ||||||
|  | //#ifdef LV_HAVE_SSE3 | ||||||
|  | //static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_a_sse3(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    int code_length_chips = 2046; | ||||||
|  | //    float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  | //    int num_out_vectors = 3; | ||||||
|  | //    float rem_code_phase_chips = -0.234; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  | // | ||||||
|  | //    float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  | //        } | ||||||
|  | // | ||||||
|  | //    volk_gnsssdr_32f_xn_resampler_32f_xn_a_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  | // | ||||||
|  | //    memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  | // | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            volk_gnsssdr_free(result_aux[n]); | ||||||
|  | //        } | ||||||
|  | //    volk_gnsssdr_free(result_aux); | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_SSE3 | ||||||
|  | //static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_u_sse3(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    int code_length_chips = 2046; | ||||||
|  | //    float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  | //    int num_out_vectors = 3; | ||||||
|  | //    float rem_code_phase_chips = -0.234; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  | // | ||||||
|  | //    float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  | //        } | ||||||
|  | // | ||||||
|  | //    volk_gnsssdr_32f_xn_resampler_32f_xn_u_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  | // | ||||||
|  | //    memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  | // | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            volk_gnsssdr_free(result_aux[n]); | ||||||
|  | //        } | ||||||
|  | //    volk_gnsssdr_free(result_aux); | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_SSE4_1 | ||||||
|  | //static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_u_sse4_1(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    int code_length_chips = 2046; | ||||||
|  | //    float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  | //    int num_out_vectors = 3; | ||||||
|  | //    float rem_code_phase_chips = -0.234; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  | // | ||||||
|  | //    float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  | //        } | ||||||
|  | // | ||||||
|  | //    volk_gnsssdr_32f_xn_resampler_32f_xn_u_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  | // | ||||||
|  | //    memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  | // | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            volk_gnsssdr_free(result_aux[n]); | ||||||
|  | //        } | ||||||
|  | //    volk_gnsssdr_free(result_aux); | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_SSE4_1 | ||||||
|  | //static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_a_sse4_1(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    int code_length_chips = 2046; | ||||||
|  | //    float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  | //    int num_out_vectors = 3; | ||||||
|  | //    float rem_code_phase_chips = -0.234; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  | // | ||||||
|  | //    float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  | //        } | ||||||
|  | // | ||||||
|  | //    volk_gnsssdr_32f_xn_resampler_32f_xn_a_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  | // | ||||||
|  | //    memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  | // | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            volk_gnsssdr_free(result_aux[n]); | ||||||
|  | //        } | ||||||
|  | //    volk_gnsssdr_free(result_aux); | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_AVX | ||||||
|  | //static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_a_avx(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    int code_length_chips = 2046; | ||||||
|  | //    float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  | //    int num_out_vectors = 3; | ||||||
|  | //    float rem_code_phase_chips = -0.234; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  | // | ||||||
|  | //    float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  | //        } | ||||||
|  | // | ||||||
|  | //    volk_gnsssdr_32f_xn_resampler_32f_xn_a_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  | // | ||||||
|  | //    memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  | // | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            volk_gnsssdr_free(result_aux[n]); | ||||||
|  | //        } | ||||||
|  | //    volk_gnsssdr_free(result_aux); | ||||||
|  | //} | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_AVX | ||||||
|  | //static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_u_avx(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    int code_length_chips = 2046; | ||||||
|  | //    float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  | //    int num_out_vectors = 3; | ||||||
|  | //    float rem_code_phase_chips = -0.234; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  | // | ||||||
|  | //    float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  | //        } | ||||||
|  | // | ||||||
|  | //    volk_gnsssdr_32f_xn_resampler_32f_xn_u_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  | // | ||||||
|  | //    memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  | // | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            volk_gnsssdr_free(result_aux[n]); | ||||||
|  | //        } | ||||||
|  | //    volk_gnsssdr_free(result_aux); | ||||||
|  | //} | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_NEONV7 | ||||||
|  | //static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_neon(float* result, const float* local_code, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    int code_length_chips = 2046; | ||||||
|  | //    float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); | ||||||
|  | //    int num_out_vectors = 3; | ||||||
|  | //    float rem_code_phase_chips = -0.234; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    float shifts_chips[3] = {-0.1, 0.0, 0.1}; | ||||||
|  | // | ||||||
|  | //    float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); | ||||||
|  | //        } | ||||||
|  | // | ||||||
|  | //    volk_gnsssdr_32f_xn_resampler_32f_xn_neon(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); | ||||||
|  | // | ||||||
|  | //    memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); | ||||||
|  | // | ||||||
|  | //    for (n = 0; n < num_out_vectors; n++) | ||||||
|  | //        { | ||||||
|  | //            volk_gnsssdr_free(result_aux[n]); | ||||||
|  | //        } | ||||||
|  | //    volk_gnsssdr_free(result_aux); | ||||||
|  | //} | ||||||
|  | //#endif | ||||||
|  |  | ||||||
|  | #endif  // INCLUDED_volk_gnsssdr_32f_fast_resamplerpuppet_32f_H | ||||||
| @@ -0,0 +1,626 @@ | |||||||
|  | /*! | ||||||
|  |  * \file volk_gnsssdr_32f_xn_fast_resampler_32f_xn.h | ||||||
|  |  * \brief VOLK_GNSSSDR kernel: Resamples 1 complex 32-bit float vectors using zero hold resample algorithm | ||||||
|  |  * and produces the delayed replicas by copying and rotating the resulting resampled signal. | ||||||
|  |  * \authors <ul> | ||||||
|  |  *          <li> Cillian O'Driscoll, 2017. cillian.odirscoll(at)gmail.com | ||||||
|  |  *          <li> Javier Arribas, 2018. javiarribas(at)gmail.com | ||||||
|  |  *          </ul> | ||||||
|  |  * | ||||||
|  |  * VOLK_GNSSSDR kernel that resamples N 32-bit float vectors using zero hold resample algorithm. | ||||||
|  |  * It is optimized to resample a single GNSS local code signal replica into 1 vector fractional-resampled and fractional-delayed | ||||||
|  |  * and produces the delayed replicas by copying and rotating the resulting resampled signal. | ||||||
|  |  * (i.e. it creates the Early, Prompt, and Late code replicas) | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \page volk_gnsssdr_32f_xn_fast_resampler_32f_xn | ||||||
|  |  * | ||||||
|  |  * \b Overview | ||||||
|  |  * | ||||||
|  |  * Resamples a 32-bit floating point vector , providing \p num_out_vectors outputs. | ||||||
|  |  * | ||||||
|  |  * <b>Dispatcher Prototype</b> | ||||||
|  |  * \code | ||||||
|  |  * void volk_gnsssdr_32f_xn_fast_resampler_32f_xn(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  |  * \endcode | ||||||
|  |  * | ||||||
|  |  * \b Inputs | ||||||
|  |  * \li local_code:            Vector to be resampled. | ||||||
|  |  * \li rem_code_phase_chips:  Remnant code phase [chips]. | ||||||
|  |  * \li code_phase_step_chips: Phase increment per sample [chips/sample]. | ||||||
|  |  * \li shifts_chips:          Vector of floats that defines the spacing (in chips) between the replicas of \p local_code | ||||||
|  |  * \li code_length_chips:     Code length in chips. | ||||||
|  |  * \li num_out_vectors        Number of output vectors. | ||||||
|  |  * \li num_points:            The number of data values to be in the resampled vector. | ||||||
|  |  * | ||||||
|  |  * \b Outputs | ||||||
|  |  * \li result:                Pointer to a vector of pointers where the results will be stored. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef INCLUDED_volk_gnsssdr_32f_xn_fast_resampler_32f_xn_H | ||||||
|  | #define INCLUDED_volk_gnsssdr_32f_xn_fast_resampler_32f_xn_H | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <math.h> | ||||||
|  | #include <stdlib.h> /* abs */ | ||||||
|  | #include <stdint.h> /* int64_t */ | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr_common.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_GENERIC | ||||||
|  |  | ||||||
|  | static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_generic(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | { | ||||||
|  |     int local_code_chip_index; | ||||||
|  |     int current_correlator_tap; | ||||||
|  |     int n; | ||||||
|  |     //first correlator | ||||||
|  |     for (n = 0; n < num_points; n++) | ||||||
|  |         { | ||||||
|  |             // resample code for current tap | ||||||
|  |             local_code_chip_index = (int)floor(code_phase_step_chips * (float)n + shifts_chips[0] - rem_code_phase_chips); | ||||||
|  |             //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  |             if (local_code_chip_index < 0) local_code_chip_index += (int)code_length_chips * (abs(local_code_chip_index) / code_length_chips + 1); | ||||||
|  |             local_code_chip_index = local_code_chip_index % code_length_chips; | ||||||
|  |             result[0][n] = local_code[local_code_chip_index]; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     //adjacent correlators | ||||||
|  |     unsigned int shift_samples = 0; | ||||||
|  |     for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  |         { | ||||||
|  |             shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); | ||||||
|  |             memcpy(&result[current_correlator_tap][0], &result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); | ||||||
|  |             memcpy(&result[current_correlator_tap][num_points - shift_samples], &result[0][0], shift_samples * sizeof(float)); | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /*LV_HAVE_GENERIC*/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //#ifdef LV_HAVE_SSE3 | ||||||
|  | //#include <pmmintrin.h> | ||||||
|  | //static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    float** _result = result; | ||||||
|  | //    const unsigned int quarterPoints = num_points / 4; | ||||||
|  | //    int current_correlator_tap; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    unsigned int k; | ||||||
|  | //    const __m128 ones = _mm_set1_ps(1.0f); | ||||||
|  | //    const __m128 fours = _mm_set1_ps(4.0f); | ||||||
|  | //    const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); | ||||||
|  | //    const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); | ||||||
|  | // | ||||||
|  | //    __VOLK_ATTR_ALIGNED(16) | ||||||
|  | //    int local_code_chip_index[4]; | ||||||
|  | //    int local_code_chip_index_; | ||||||
|  | // | ||||||
|  | //    const __m128i zeros = _mm_setzero_si128(); | ||||||
|  | //    const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); | ||||||
|  | //    const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); | ||||||
|  | //    __m128i local_code_chip_index_reg, aux_i, negatives, i; | ||||||
|  | //    __m128 aux, aux2, shifts_chips_reg, fi, igx, j, c, cTrunc, base; | ||||||
|  | // | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            shifts_chips_reg = _mm_set_ps1((float)shifts_chips[current_correlator_tap]); | ||||||
|  | //            aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); | ||||||
|  | //            __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); | ||||||
|  | //            for (n = 0; n < quarterPoints; n++) | ||||||
|  | //                { | ||||||
|  | //                    aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); | ||||||
|  | //                    aux = _mm_add_ps(aux, aux2); | ||||||
|  | //                    // floor | ||||||
|  | //                    i = _mm_cvttps_epi32(aux); | ||||||
|  | //                    fi = _mm_cvtepi32_ps(i); | ||||||
|  | //                    igx = _mm_cmpgt_ps(fi, aux); | ||||||
|  | //                    j = _mm_and_ps(igx, ones); | ||||||
|  | //                    aux = _mm_sub_ps(fi, j); | ||||||
|  | //                    // fmod | ||||||
|  | //                    c = _mm_div_ps(aux, code_length_chips_reg_f); | ||||||
|  | //                    i = _mm_cvttps_epi32(c); | ||||||
|  | //                    cTrunc = _mm_cvtepi32_ps(i); | ||||||
|  | //                    base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); | ||||||
|  | //                    local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); | ||||||
|  | // | ||||||
|  | //                    negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); | ||||||
|  | //                    aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); | ||||||
|  | //                    local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); | ||||||
|  | //                    _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); | ||||||
|  | //                    for (k = 0; k < 4; ++k) | ||||||
|  | //                        { | ||||||
|  | //                            _result[current_correlator_tap][n * 4 + k] = local_code[local_code_chip_index[k]]; | ||||||
|  | //                        } | ||||||
|  | //                    indexn = _mm_add_ps(indexn, fours); | ||||||
|  | //                } | ||||||
|  | //            for (n = quarterPoints * 4; n < num_points; n++) | ||||||
|  | //                { | ||||||
|  | //                    // resample code for current tap | ||||||
|  | //                    local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); | ||||||
|  | //                    //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  | //                    if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); | ||||||
|  | //                    local_code_chip_index_ = local_code_chip_index_ % code_length_chips; | ||||||
|  | //                    _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_SSE3 | ||||||
|  | //#include <pmmintrin.h> | ||||||
|  | //static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    float** _result = result; | ||||||
|  | //    const unsigned int quarterPoints = num_points / 4; | ||||||
|  | //    int current_correlator_tap; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    unsigned int k; | ||||||
|  | //    const __m128 ones = _mm_set1_ps(1.0f); | ||||||
|  | //    const __m128 fours = _mm_set1_ps(4.0f); | ||||||
|  | //    const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); | ||||||
|  | //    const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); | ||||||
|  | // | ||||||
|  | //    __VOLK_ATTR_ALIGNED(16) | ||||||
|  | //    int local_code_chip_index[4]; | ||||||
|  | //    int local_code_chip_index_; | ||||||
|  | // | ||||||
|  | //    const __m128i zeros = _mm_setzero_si128(); | ||||||
|  | //    const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); | ||||||
|  | //    const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); | ||||||
|  | //    __m128i local_code_chip_index_reg, aux_i, negatives, i; | ||||||
|  | //    __m128 aux, aux2, shifts_chips_reg, fi, igx, j, c, cTrunc, base; | ||||||
|  | // | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            shifts_chips_reg = _mm_set_ps1((float)shifts_chips[current_correlator_tap]); | ||||||
|  | //            aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); | ||||||
|  | //            __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); | ||||||
|  | //            for (n = 0; n < quarterPoints; n++) | ||||||
|  | //                { | ||||||
|  | //                    aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); | ||||||
|  | //                    aux = _mm_add_ps(aux, aux2); | ||||||
|  | //                    // floor | ||||||
|  | //                    i = _mm_cvttps_epi32(aux); | ||||||
|  | //                    fi = _mm_cvtepi32_ps(i); | ||||||
|  | //                    igx = _mm_cmpgt_ps(fi, aux); | ||||||
|  | //                    j = _mm_and_ps(igx, ones); | ||||||
|  | //                    aux = _mm_sub_ps(fi, j); | ||||||
|  | //                    // fmod | ||||||
|  | //                    c = _mm_div_ps(aux, code_length_chips_reg_f); | ||||||
|  | //                    i = _mm_cvttps_epi32(c); | ||||||
|  | //                    cTrunc = _mm_cvtepi32_ps(i); | ||||||
|  | //                    base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); | ||||||
|  | //                    local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); | ||||||
|  | // | ||||||
|  | //                    negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); | ||||||
|  | //                    aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); | ||||||
|  | //                    local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); | ||||||
|  | //                    _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); | ||||||
|  | //                    for (k = 0; k < 4; ++k) | ||||||
|  | //                        { | ||||||
|  | //                            _result[current_correlator_tap][n * 4 + k] = local_code[local_code_chip_index[k]]; | ||||||
|  | //                        } | ||||||
|  | //                    indexn = _mm_add_ps(indexn, fours); | ||||||
|  | //                } | ||||||
|  | //            for (n = quarterPoints * 4; n < num_points; n++) | ||||||
|  | //                { | ||||||
|  | //                    // resample code for current tap | ||||||
|  | //                    local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); | ||||||
|  | //                    //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  | //                    if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); | ||||||
|  | //                    local_code_chip_index_ = local_code_chip_index_ % code_length_chips; | ||||||
|  | //                    _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //} | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_SSE4_1 | ||||||
|  | //#include <smmintrin.h> | ||||||
|  | //static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    float** _result = result; | ||||||
|  | //    const unsigned int quarterPoints = num_points / 4; | ||||||
|  | //    int current_correlator_tap; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    unsigned int k; | ||||||
|  | //    const __m128 fours = _mm_set1_ps(4.0f); | ||||||
|  | //    const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); | ||||||
|  | //    const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); | ||||||
|  | // | ||||||
|  | //    __VOLK_ATTR_ALIGNED(16) | ||||||
|  | //    int local_code_chip_index[4]; | ||||||
|  | //    int local_code_chip_index_; | ||||||
|  | // | ||||||
|  | //    const __m128i zeros = _mm_setzero_si128(); | ||||||
|  | //    const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); | ||||||
|  | //    const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); | ||||||
|  | //    __m128i local_code_chip_index_reg, aux_i, negatives, i; | ||||||
|  | //    __m128 aux, aux2, shifts_chips_reg, c, cTrunc, base; | ||||||
|  | // | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            shifts_chips_reg = _mm_set_ps1((float)shifts_chips[current_correlator_tap]); | ||||||
|  | //            aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); | ||||||
|  | //            __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); | ||||||
|  | //            for (n = 0; n < quarterPoints; n++) | ||||||
|  | //                { | ||||||
|  | //                    aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); | ||||||
|  | //                    aux = _mm_add_ps(aux, aux2); | ||||||
|  | //                    // floor | ||||||
|  | //                    aux = _mm_floor_ps(aux); | ||||||
|  | // | ||||||
|  | //                    // fmod | ||||||
|  | //                    c = _mm_div_ps(aux, code_length_chips_reg_f); | ||||||
|  | //                    i = _mm_cvttps_epi32(c); | ||||||
|  | //                    cTrunc = _mm_cvtepi32_ps(i); | ||||||
|  | //                    base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); | ||||||
|  | //                    local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); | ||||||
|  | // | ||||||
|  | //                    negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); | ||||||
|  | //                    aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); | ||||||
|  | //                    local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); | ||||||
|  | //                    _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); | ||||||
|  | //                    for (k = 0; k < 4; ++k) | ||||||
|  | //                        { | ||||||
|  | //                            _result[current_correlator_tap][n * 4 + k] = local_code[local_code_chip_index[k]]; | ||||||
|  | //                        } | ||||||
|  | //                    indexn = _mm_add_ps(indexn, fours); | ||||||
|  | //                } | ||||||
|  | //            for (n = quarterPoints * 4; n < num_points; n++) | ||||||
|  | //                { | ||||||
|  | //                    // resample code for current tap | ||||||
|  | //                    local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); | ||||||
|  | //                    //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  | //                    if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); | ||||||
|  | //                    local_code_chip_index_ = local_code_chip_index_ % code_length_chips; | ||||||
|  | //                    _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_SSE4_1 | ||||||
|  | //#include <smmintrin.h> | ||||||
|  | //static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    float** _result = result; | ||||||
|  | //    const unsigned int quarterPoints = num_points / 4; | ||||||
|  | //    int current_correlator_tap; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    unsigned int k; | ||||||
|  | //    const __m128 fours = _mm_set1_ps(4.0f); | ||||||
|  | //    const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); | ||||||
|  | //    const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); | ||||||
|  | // | ||||||
|  | //    __VOLK_ATTR_ALIGNED(16) | ||||||
|  | //    int local_code_chip_index[4]; | ||||||
|  | //    int local_code_chip_index_; | ||||||
|  | // | ||||||
|  | //    const __m128i zeros = _mm_setzero_si128(); | ||||||
|  | //    const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); | ||||||
|  | //    const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); | ||||||
|  | //    __m128i local_code_chip_index_reg, aux_i, negatives, i; | ||||||
|  | //    __m128 aux, aux2, shifts_chips_reg, c, cTrunc, base; | ||||||
|  | // | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            shifts_chips_reg = _mm_set_ps1((float)shifts_chips[current_correlator_tap]); | ||||||
|  | //            aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); | ||||||
|  | //            __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); | ||||||
|  | //            for (n = 0; n < quarterPoints; n++) | ||||||
|  | //                { | ||||||
|  | //                    aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); | ||||||
|  | //                    aux = _mm_add_ps(aux, aux2); | ||||||
|  | //                    // floor | ||||||
|  | //                    aux = _mm_floor_ps(aux); | ||||||
|  | // | ||||||
|  | //                    // fmod | ||||||
|  | //                    c = _mm_div_ps(aux, code_length_chips_reg_f); | ||||||
|  | //                    i = _mm_cvttps_epi32(c); | ||||||
|  | //                    cTrunc = _mm_cvtepi32_ps(i); | ||||||
|  | //                    base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); | ||||||
|  | //                    local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); | ||||||
|  | // | ||||||
|  | //                    negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); | ||||||
|  | //                    aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); | ||||||
|  | //                    local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); | ||||||
|  | //                    _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); | ||||||
|  | //                    for (k = 0; k < 4; ++k) | ||||||
|  | //                        { | ||||||
|  | //                            _result[current_correlator_tap][n * 4 + k] = local_code[local_code_chip_index[k]]; | ||||||
|  | //                        } | ||||||
|  | //                    indexn = _mm_add_ps(indexn, fours); | ||||||
|  | //                } | ||||||
|  | //            for (n = quarterPoints * 4; n < num_points; n++) | ||||||
|  | //                { | ||||||
|  | //                    // resample code for current tap | ||||||
|  | //                    local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); | ||||||
|  | //                    //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  | //                    if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); | ||||||
|  | //                    local_code_chip_index_ = local_code_chip_index_ % code_length_chips; | ||||||
|  | //                    _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_AVX | ||||||
|  | //#include <immintrin.h> | ||||||
|  | //static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_a_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    float** _result = result; | ||||||
|  | //    const unsigned int avx_iters = num_points / 8; | ||||||
|  | //    int current_correlator_tap; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    unsigned int k; | ||||||
|  | //    const __m256 eights = _mm256_set1_ps(8.0f); | ||||||
|  | //    const __m256 rem_code_phase_chips_reg = _mm256_set1_ps(rem_code_phase_chips); | ||||||
|  | //    const __m256 code_phase_step_chips_reg = _mm256_set1_ps(code_phase_step_chips); | ||||||
|  | // | ||||||
|  | //    __VOLK_ATTR_ALIGNED(32) | ||||||
|  | //    int local_code_chip_index[8]; | ||||||
|  | //    int local_code_chip_index_; | ||||||
|  | // | ||||||
|  | //    const __m256 zeros = _mm256_setzero_ps(); | ||||||
|  | //    const __m256 code_length_chips_reg_f = _mm256_set1_ps((float)code_length_chips); | ||||||
|  | //    const __m256 n0 = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); | ||||||
|  | // | ||||||
|  | //    __m256i local_code_chip_index_reg, i; | ||||||
|  | //    __m256 aux, aux2, aux3, shifts_chips_reg, c, cTrunc, base, negatives, indexn; | ||||||
|  | // | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            shifts_chips_reg = _mm256_set1_ps((float)shifts_chips[current_correlator_tap]); | ||||||
|  | //            aux2 = _mm256_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); | ||||||
|  | //            indexn = n0; | ||||||
|  | //            for (n = 0; n < avx_iters; n++) | ||||||
|  | //                { | ||||||
|  | //                    __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[current_correlator_tap][8 * n + 7], 1, 0); | ||||||
|  | //                    __VOLK_GNSSSDR_PREFETCH_LOCALITY(&local_code_chip_index[8], 1, 3); | ||||||
|  | //                    aux = _mm256_mul_ps(code_phase_step_chips_reg, indexn); | ||||||
|  | //                    aux = _mm256_add_ps(aux, aux2); | ||||||
|  | //                    // floor | ||||||
|  | //                    aux = _mm256_floor_ps(aux); | ||||||
|  | // | ||||||
|  | //                    // fmod | ||||||
|  | //                    c = _mm256_div_ps(aux, code_length_chips_reg_f); | ||||||
|  | //                    i = _mm256_cvttps_epi32(c); | ||||||
|  | //                    cTrunc = _mm256_cvtepi32_ps(i); | ||||||
|  | //                    base = _mm256_mul_ps(cTrunc, code_length_chips_reg_f); | ||||||
|  | //                    local_code_chip_index_reg = _mm256_cvttps_epi32(_mm256_sub_ps(aux, base)); | ||||||
|  | // | ||||||
|  | //                    // no negatives | ||||||
|  | //                    c = _mm256_cvtepi32_ps(local_code_chip_index_reg); | ||||||
|  | //                    negatives = _mm256_cmp_ps(c, zeros, 0x01); | ||||||
|  | //                    aux3 = _mm256_and_ps(code_length_chips_reg_f, negatives); | ||||||
|  | //                    aux = _mm256_add_ps(c, aux3); | ||||||
|  | //                    local_code_chip_index_reg = _mm256_cvttps_epi32(aux); | ||||||
|  | // | ||||||
|  | //                    _mm256_store_si256((__m256i*)local_code_chip_index, local_code_chip_index_reg); | ||||||
|  | //                    for (k = 0; k < 8; ++k) | ||||||
|  | //                        { | ||||||
|  | //                            _result[current_correlator_tap][n * 8 + k] = local_code[local_code_chip_index[k]]; | ||||||
|  | //                        } | ||||||
|  | //                    indexn = _mm256_add_ps(indexn, eights); | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //    _mm256_zeroupper(); | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            for (n = avx_iters * 8; n < num_points; n++) | ||||||
|  | //                { | ||||||
|  | //                    // resample code for current tap | ||||||
|  | //                    local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); | ||||||
|  | //                    //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  | //                    if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); | ||||||
|  | //                    local_code_chip_index_ = local_code_chip_index_ % code_length_chips; | ||||||
|  | //                    _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_AVX | ||||||
|  | //#include <immintrin.h> | ||||||
|  | //static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_u_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    float** _result = result; | ||||||
|  | //    const unsigned int avx_iters = num_points / 8; | ||||||
|  | //    int current_correlator_tap; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    unsigned int k; | ||||||
|  | //    const __m256 eights = _mm256_set1_ps(8.0f); | ||||||
|  | //    const __m256 rem_code_phase_chips_reg = _mm256_set1_ps(rem_code_phase_chips); | ||||||
|  | //    const __m256 code_phase_step_chips_reg = _mm256_set1_ps(code_phase_step_chips); | ||||||
|  | // | ||||||
|  | //    __VOLK_ATTR_ALIGNED(32) | ||||||
|  | //    int local_code_chip_index[8]; | ||||||
|  | //    int local_code_chip_index_; | ||||||
|  | // | ||||||
|  | //    const __m256 zeros = _mm256_setzero_ps(); | ||||||
|  | //    const __m256 code_length_chips_reg_f = _mm256_set1_ps((float)code_length_chips); | ||||||
|  | //    const __m256 n0 = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); | ||||||
|  | // | ||||||
|  | //    __m256i local_code_chip_index_reg, i; | ||||||
|  | //    __m256 aux, aux2, aux3, shifts_chips_reg, c, cTrunc, base, negatives, indexn; | ||||||
|  | // | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            shifts_chips_reg = _mm256_set1_ps((float)shifts_chips[current_correlator_tap]); | ||||||
|  | //            aux2 = _mm256_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); | ||||||
|  | //            indexn = n0; | ||||||
|  | //            for (n = 0; n < avx_iters; n++) | ||||||
|  | //                { | ||||||
|  | //                    __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[current_correlator_tap][8 * n + 7], 1, 0); | ||||||
|  | //                    __VOLK_GNSSSDR_PREFETCH_LOCALITY(&local_code_chip_index[8], 1, 3); | ||||||
|  | //                    aux = _mm256_mul_ps(code_phase_step_chips_reg, indexn); | ||||||
|  | //                    aux = _mm256_add_ps(aux, aux2); | ||||||
|  | //                    // floor | ||||||
|  | //                    aux = _mm256_floor_ps(aux); | ||||||
|  | // | ||||||
|  | //                    // fmod | ||||||
|  | //                    c = _mm256_div_ps(aux, code_length_chips_reg_f); | ||||||
|  | //                    i = _mm256_cvttps_epi32(c); | ||||||
|  | //                    cTrunc = _mm256_cvtepi32_ps(i); | ||||||
|  | //                    base = _mm256_mul_ps(cTrunc, code_length_chips_reg_f); | ||||||
|  | //                    local_code_chip_index_reg = _mm256_cvttps_epi32(_mm256_sub_ps(aux, base)); | ||||||
|  | // | ||||||
|  | //                    // no negatives | ||||||
|  | //                    c = _mm256_cvtepi32_ps(local_code_chip_index_reg); | ||||||
|  | //                    negatives = _mm256_cmp_ps(c, zeros, 0x01); | ||||||
|  | //                    aux3 = _mm256_and_ps(code_length_chips_reg_f, negatives); | ||||||
|  | //                    aux = _mm256_add_ps(c, aux3); | ||||||
|  | //                    local_code_chip_index_reg = _mm256_cvttps_epi32(aux); | ||||||
|  | // | ||||||
|  | //                    _mm256_store_si256((__m256i*)local_code_chip_index, local_code_chip_index_reg); | ||||||
|  | //                    for (k = 0; k < 8; ++k) | ||||||
|  | //                        { | ||||||
|  | //                            _result[current_correlator_tap][n * 8 + k] = local_code[local_code_chip_index[k]]; | ||||||
|  | //                        } | ||||||
|  | //                    indexn = _mm256_add_ps(indexn, eights); | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //    _mm256_zeroupper(); | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            for (n = avx_iters * 8; n < num_points; n++) | ||||||
|  | //                { | ||||||
|  | //                    // resample code for current tap | ||||||
|  | //                    local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); | ||||||
|  | //                    //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  | //                    if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); | ||||||
|  | //                    local_code_chip_index_ = local_code_chip_index_ % code_length_chips; | ||||||
|  | //                    _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //#ifdef LV_HAVE_NEONV7 | ||||||
|  | //#include <arm_neon.h> | ||||||
|  | // | ||||||
|  | //static inline void volk_gnsssdr_32f_xn_fast_resampler_32f_xn_neon(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) | ||||||
|  | //{ | ||||||
|  | //    float** _result = result; | ||||||
|  | //    const unsigned int neon_iters = num_points / 4; | ||||||
|  | //    int current_correlator_tap; | ||||||
|  | //    unsigned int n; | ||||||
|  | //    unsigned int k; | ||||||
|  | //    const int32x4_t ones = vdupq_n_s32(1); | ||||||
|  | //    const float32x4_t fours = vdupq_n_f32(4.0f); | ||||||
|  | //    const float32x4_t rem_code_phase_chips_reg = vdupq_n_f32(rem_code_phase_chips); | ||||||
|  | //    const float32x4_t code_phase_step_chips_reg = vdupq_n_f32(code_phase_step_chips); | ||||||
|  | // | ||||||
|  | //    __VOLK_ATTR_ALIGNED(16) | ||||||
|  | //    int32_t local_code_chip_index[4]; | ||||||
|  | //    int32_t local_code_chip_index_; | ||||||
|  | // | ||||||
|  | //    const int32x4_t zeros = vdupq_n_s32(0); | ||||||
|  | //    const float32x4_t code_length_chips_reg_f = vdupq_n_f32((float)code_length_chips); | ||||||
|  | //    const int32x4_t code_length_chips_reg_i = vdupq_n_s32((int32_t)code_length_chips); | ||||||
|  | //    int32x4_t local_code_chip_index_reg, aux_i, negatives, i; | ||||||
|  | //    float32x4_t aux, aux2, shifts_chips_reg, fi, c, j, cTrunc, base, indexn, reciprocal; | ||||||
|  | //    __VOLK_ATTR_ALIGNED(16) | ||||||
|  | //    const float vec[4] = {0.0f, 1.0f, 2.0f, 3.0f}; | ||||||
|  | //    uint32x4_t igx; | ||||||
|  | //    reciprocal = vrecpeq_f32(code_length_chips_reg_f); | ||||||
|  | //    reciprocal = vmulq_f32(vrecpsq_f32(code_length_chips_reg_f, reciprocal), reciprocal); | ||||||
|  | //    reciprocal = vmulq_f32(vrecpsq_f32(code_length_chips_reg_f, reciprocal), reciprocal);  // this refinement is required! | ||||||
|  | //    float32x4_t n0 = vld1q_f32((float*)vec); | ||||||
|  | // | ||||||
|  | //    for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) | ||||||
|  | //        { | ||||||
|  | //            shifts_chips_reg = vdupq_n_f32((float)shifts_chips[current_correlator_tap]); | ||||||
|  | //            aux2 = vsubq_f32(shifts_chips_reg, rem_code_phase_chips_reg); | ||||||
|  | //            indexn = n0; | ||||||
|  | //            for (n = 0; n < neon_iters; n++) | ||||||
|  | //                { | ||||||
|  | //                    __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[current_correlator_tap][4 * n + 3], 1, 0); | ||||||
|  | //                    __VOLK_GNSSSDR_PREFETCH(&local_code_chip_index[4]); | ||||||
|  | //                    aux = vmulq_f32(code_phase_step_chips_reg, indexn); | ||||||
|  | //                    aux = vaddq_f32(aux, aux2); | ||||||
|  | // | ||||||
|  | //                    //floor | ||||||
|  | //                    i = vcvtq_s32_f32(aux); | ||||||
|  | //                    fi = vcvtq_f32_s32(i); | ||||||
|  | //                    igx = vcgtq_f32(fi, aux); | ||||||
|  | //                    j = vcvtq_f32_s32(vandq_s32(vreinterpretq_s32_u32(igx), ones)); | ||||||
|  | //                    aux = vsubq_f32(fi, j); | ||||||
|  | // | ||||||
|  | //                    // fmod | ||||||
|  | //                    c = vmulq_f32(aux, reciprocal); | ||||||
|  | //                    i = vcvtq_s32_f32(c); | ||||||
|  | //                    cTrunc = vcvtq_f32_s32(i); | ||||||
|  | //                    base = vmulq_f32(cTrunc, code_length_chips_reg_f); | ||||||
|  | //                    aux = vsubq_f32(aux, base); | ||||||
|  | //                    local_code_chip_index_reg = vcvtq_s32_f32(aux); | ||||||
|  | // | ||||||
|  | //                    negatives = vreinterpretq_s32_u32(vcltq_s32(local_code_chip_index_reg, zeros)); | ||||||
|  | //                    aux_i = vandq_s32(code_length_chips_reg_i, negatives); | ||||||
|  | //                    local_code_chip_index_reg = vaddq_s32(local_code_chip_index_reg, aux_i); | ||||||
|  | // | ||||||
|  | //                    vst1q_s32((int32_t*)local_code_chip_index, local_code_chip_index_reg); | ||||||
|  | // | ||||||
|  | //                    for (k = 0; k < 4; ++k) | ||||||
|  | //                        { | ||||||
|  | //                            _result[current_correlator_tap][n * 4 + k] = local_code[local_code_chip_index[k]]; | ||||||
|  | //                        } | ||||||
|  | //                    indexn = vaddq_f32(indexn, fours); | ||||||
|  | //                } | ||||||
|  | //            for (n = neon_iters * 4; n < num_points; n++) | ||||||
|  | //                { | ||||||
|  | //                    __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[current_correlator_tap][n], 1, 0); | ||||||
|  | //                    // resample code for current tap | ||||||
|  | //                    local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); | ||||||
|  | //                    //Take into account that in multitap correlators, the shifts can be negative! | ||||||
|  | //                    if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); | ||||||
|  | //                    local_code_chip_index_ = local_code_chip_index_ % code_length_chips; | ||||||
|  | //                    _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; | ||||||
|  | //                } | ||||||
|  | //        } | ||||||
|  | //} | ||||||
|  | // | ||||||
|  | //#endif | ||||||
|  |  | ||||||
|  | #endif /*INCLUDED_volk_gnsssdr_32f_xn_fast_resampler_32f_xn_H*/ | ||||||
| @@ -93,6 +93,7 @@ std::vector<volk_gnsssdr_test_case_t> init_test_list(volk_gnsssdr_test_params_t | |||||||
|     QA(VOLK_INIT_PUPP(volk_gnsssdr_16i_resamplerxnpuppet_16i, volk_gnsssdr_16i_xn_resampler_16i_xn, test_params)) |     QA(VOLK_INIT_PUPP(volk_gnsssdr_16i_resamplerxnpuppet_16i, volk_gnsssdr_16i_xn_resampler_16i_xn, test_params)) | ||||||
|     QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_resamplerxnpuppet_32fc, volk_gnsssdr_32fc_xn_resampler_32fc_xn, test_params)) |     QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_resamplerxnpuppet_32fc, volk_gnsssdr_32fc_xn_resampler_32fc_xn, test_params)) | ||||||
|     QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_resampler_32f_xn, test_params)) |     QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_resampler_32f_xn, test_params)) | ||||||
|  |     QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_fast_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_fast_resampler_32f_xn, test_params)) | ||||||
|     QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_dot_prod_16ic_xn, test_params)) |     QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_dot_prod_16ic_xn, test_params)) | ||||||
|     QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn, test_params_int16)) |     QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn, test_params_int16)) | ||||||
|     QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn, test_params_int16)) |     QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn, test_params_int16)) | ||||||
|   | |||||||
| @@ -90,8 +90,10 @@ int unpack_spir_gss6450_samples::work(int noutput_items, | |||||||
|                     i_data[k] = bs[i_shift + k]; |                     i_data[k] = bs[i_shift + k]; | ||||||
|                     q_data[k] = bs[q_shift + k]; |                     q_data[k] = bs[q_shift + k]; | ||||||
|                 } |                 } | ||||||
|             out[i] = gr_complex(static_cast<float>(compute_two_complement(i_data.to_ulong())) + 0.5, |             //out[i] = gr_complex(static_cast<float>(compute_two_complement(i_data.to_ulong())) + 0.5, | ||||||
|                 static_cast<float>(compute_two_complement(q_data.to_ulong())) + 0.5); |             //    static_cast<float>(compute_two_complement(q_data.to_ulong())) + 0.5); | ||||||
|  |             out[i] = gr_complex(static_cast<float>(compute_two_complement(q_data.to_ulong())) + 0.5, | ||||||
|  |                 static_cast<float>(compute_two_complement(i_data.to_ulong())) + 0.5); | ||||||
|             n_sample++; |             n_sample++; | ||||||
|             if (n_sample == samples_per_int) |             if (n_sample == samples_per_int) | ||||||
|                 { |                 { | ||||||
|   | |||||||
| @@ -363,6 +363,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl | |||||||
|         } |         } | ||||||
|  |  | ||||||
|     // --- Initializations --- |     // --- Initializations --- | ||||||
|  |     multicorrelator_cpu.set_fast_resampler(trk_parameters.use_fast_resampler); | ||||||
|     // Initial code frequency basis of NCO |     // Initial code frequency basis of NCO | ||||||
|     d_code_freq_chips = d_code_chip_rate; |     d_code_freq_chips = d_code_chip_rate; | ||||||
|     // Residual code phase (in chips) |     // Residual code phase (in chips) | ||||||
| @@ -742,8 +743,7 @@ void dll_pll_veml_tracking::run_dll_pll() | |||||||
|     d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(d_carr_error_hz); |     d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(d_carr_error_hz); | ||||||
|     // New carrier Doppler frequency estimation |     // New carrier Doppler frequency estimation | ||||||
|     d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_carr_error_filt_hz; |     d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_carr_error_filt_hz; | ||||||
|     // New code Doppler frequency estimation |  | ||||||
|     d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate; |  | ||||||
|  |  | ||||||
|     // ################## DLL ########################################################## |     // ################## DLL ########################################################## | ||||||
|     // DLL discriminator |     // DLL discriminator | ||||||
| @@ -757,6 +757,9 @@ void dll_pll_veml_tracking::run_dll_pll() | |||||||
|         } |         } | ||||||
|     // Code discriminator filter |     // Code discriminator filter | ||||||
|     d_code_error_filt_chips = d_code_loop_filter.get_code_nco(d_code_error_chips);  // [chips/second] |     d_code_error_filt_chips = d_code_loop_filter.get_code_nco(d_code_error_chips);  // [chips/second] | ||||||
|  |  | ||||||
|  |     // New code Doppler frequency estimation | ||||||
|  |     d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate - d_code_error_filt_chips; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -778,13 +781,12 @@ void dll_pll_veml_tracking::update_tracking_vars() | |||||||
| { | { | ||||||
|     T_chip_seconds = 1.0 / d_code_freq_chips; |     T_chip_seconds = 1.0 / d_code_freq_chips; | ||||||
|     T_prn_seconds = T_chip_seconds * static_cast<double>(d_code_length_chips); |     T_prn_seconds = T_chip_seconds * static_cast<double>(d_code_length_chips); | ||||||
|     double code_error_filt_secs = T_prn_seconds * d_code_error_filt_chips * T_chip_seconds;  //[seconds] |  | ||||||
|  |  | ||||||
|     // ################## CARRIER AND CODE NCO BUFFER ALIGNMENT ####################### |     // ################## CARRIER AND CODE NCO BUFFER ALIGNMENT ####################### | ||||||
|     // keep alignment parameters for the next input buffer |     // keep alignment parameters for the next input buffer | ||||||
|     // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation |     // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation | ||||||
|     T_prn_samples = T_prn_seconds * trk_parameters.fs_in; |     T_prn_samples = T_prn_seconds * trk_parameters.fs_in; | ||||||
|     K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * trk_parameters.fs_in; |     K_blk_samples = T_prn_samples + d_rem_code_phase_samples; | ||||||
|     //d_current_prn_length_samples = static_cast<int>(round(K_blk_samples));  // round to a discrete number of samples |     //d_current_prn_length_samples = static_cast<int>(round(K_blk_samples));  // round to a discrete number of samples | ||||||
|     d_current_prn_length_samples = static_cast<int>(std::floor(K_blk_samples));  // round to a discrete number of samples |     d_current_prn_length_samples = static_cast<int>(std::floor(K_blk_samples));  // round to a discrete number of samples | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ | |||||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include <cmath> | #include <cmath> | ||||||
|  |  | ||||||
|  |  | ||||||
| cpu_multicorrelator_real_codes::cpu_multicorrelator_real_codes() | cpu_multicorrelator_real_codes::cpu_multicorrelator_real_codes() | ||||||
| { | { | ||||||
|     d_sig_in = nullptr; |     d_sig_in = nullptr; | ||||||
| @@ -47,6 +46,7 @@ cpu_multicorrelator_real_codes::cpu_multicorrelator_real_codes() | |||||||
|     d_local_codes_resampled = nullptr; |     d_local_codes_resampled = nullptr; | ||||||
|     d_code_length_chips = 0; |     d_code_length_chips = 0; | ||||||
|     d_n_correlators = 0; |     d_n_correlators = 0; | ||||||
|  |     d_use_fast_resampler = true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -84,6 +84,7 @@ bool cpu_multicorrelator_real_codes::set_local_code_and_taps( | |||||||
|     d_local_code_in = local_code_in; |     d_local_code_in = local_code_in; | ||||||
|     d_shifts_chips = shifts_chips; |     d_shifts_chips = shifts_chips; | ||||||
|     d_code_length_chips = code_length_chips; |     d_code_length_chips = code_length_chips; | ||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -99,14 +100,28 @@ bool cpu_multicorrelator_real_codes::set_input_output_vectors(std::complex<float | |||||||
|  |  | ||||||
| void cpu_multicorrelator_real_codes::update_local_code(int correlator_length_samples, float rem_code_phase_chips, float code_phase_step_chips) | void cpu_multicorrelator_real_codes::update_local_code(int correlator_length_samples, float rem_code_phase_chips, float code_phase_step_chips) | ||||||
| { | { | ||||||
|     volk_gnsssdr_32f_xn_resampler_32f_xn(d_local_codes_resampled, |     if (d_use_fast_resampler) | ||||||
|         d_local_code_in, |         { | ||||||
|         rem_code_phase_chips, |             volk_gnsssdr_32f_xn_fast_resampler_32f_xn(d_local_codes_resampled, | ||||||
|         code_phase_step_chips, |                 d_local_code_in, | ||||||
|         d_shifts_chips, |                 rem_code_phase_chips, | ||||||
|         d_code_length_chips, |                 code_phase_step_chips, | ||||||
|         d_n_correlators, |                 d_shifts_chips, | ||||||
|         correlator_length_samples); |                 d_code_length_chips, | ||||||
|  |                 d_n_correlators, | ||||||
|  |                 correlator_length_samples); | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             volk_gnsssdr_32f_xn_resampler_32f_xn(d_local_codes_resampled, | ||||||
|  |                 d_local_code_in, | ||||||
|  |                 rem_code_phase_chips, | ||||||
|  |                 code_phase_step_chips, | ||||||
|  |                 d_shifts_chips, | ||||||
|  |                 d_code_length_chips, | ||||||
|  |                 d_n_correlators, | ||||||
|  |                 correlator_length_samples); | ||||||
|  |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -141,3 +156,9 @@ bool cpu_multicorrelator_real_codes::free() | |||||||
|         } |         } | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void cpu_multicorrelator_real_codes::set_fast_resampler( | ||||||
|  |     bool use_fast_resampler) | ||||||
|  | { | ||||||
|  |     d_use_fast_resampler = use_fast_resampler; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -46,6 +46,7 @@ class cpu_multicorrelator_real_codes | |||||||
| { | { | ||||||
| public: | public: | ||||||
|     cpu_multicorrelator_real_codes(); |     cpu_multicorrelator_real_codes(); | ||||||
|  |     void set_fast_resampler(bool use_fast_resampler); | ||||||
|     ~cpu_multicorrelator_real_codes(); |     ~cpu_multicorrelator_real_codes(); | ||||||
|     bool init(int max_signal_length_samples, int n_correlators); |     bool init(int max_signal_length_samples, int n_correlators); | ||||||
|     bool set_local_code_and_taps(int code_length_chips, const float *local_code_in, float *shifts_chips); |     bool set_local_code_and_taps(int code_length_chips, const float *local_code_in, float *shifts_chips); | ||||||
| @@ -61,6 +62,7 @@ private: | |||||||
|     const float *d_local_code_in; |     const float *d_local_code_in; | ||||||
|     std::complex<float> *d_corr_out; |     std::complex<float> *d_corr_out; | ||||||
|     float *d_shifts_chips; |     float *d_shifts_chips; | ||||||
|  |     bool d_use_fast_resampler; | ||||||
|     int d_code_length_chips; |     int d_code_length_chips; | ||||||
|     int d_n_correlators; |     int d_n_correlators; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ | |||||||
| Dll_Pll_Conf::Dll_Pll_Conf() | Dll_Pll_Conf::Dll_Pll_Conf() | ||||||
| { | { | ||||||
|     /* DLL/PLL tracking configuration */ |     /* DLL/PLL tracking configuration */ | ||||||
|  |     use_fast_resampler = true; | ||||||
|     fs_in = 0.0; |     fs_in = 0.0; | ||||||
|     vector_length = 0; |     vector_length = 0; | ||||||
|     dump = false; |     dump = false; | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ public: | |||||||
|     float early_late_space_narrow_chips; |     float early_late_space_narrow_chips; | ||||||
|     float very_early_late_space_narrow_chips; |     float very_early_late_space_narrow_chips; | ||||||
|     int extend_correlation_symbols; |     int extend_correlation_symbols; | ||||||
|  |     bool use_fast_resampler; | ||||||
|     int cn0_samples; |     int cn0_samples; | ||||||
|     int carrier_lock_det_mav_samples; |     int carrier_lock_det_mav_samples; | ||||||
|     int cn0_min; |     int cn0_min; | ||||||
|   | |||||||
| @@ -230,7 +230,7 @@ public: | |||||||
|         double DLL_narrow_bw_hz, |         double DLL_narrow_bw_hz, | ||||||
|         int extend_correlation_symbols); |         int extend_correlation_symbols); | ||||||
|  |  | ||||||
|     bool acquire_GPS_L1CA_signal(int SV_ID); |     bool acquire_signal(int SV_ID); | ||||||
|     gr::top_block_sptr top_block; |     gr::top_block_sptr top_block; | ||||||
|     std::shared_ptr<GNSSBlockFactory> factory; |     std::shared_ptr<GNSSBlockFactory> factory; | ||||||
|     std::shared_ptr<InMemoryConfiguration> config; |     std::shared_ptr<InMemoryConfiguration> config; | ||||||
| @@ -381,7 +381,7 @@ void TrackingPullInTest::configure_receiver( | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | bool TrackingPullInTest::acquire_signal(int SV_ID) | ||||||
| { | { | ||||||
|     // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) |     // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) | ||||||
|     gr::top_block_sptr top_block; |     gr::top_block_sptr top_block; | ||||||
| @@ -406,7 +406,8 @@ bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | |||||||
|         { |         { | ||||||
|             tmp_gnss_synchro.System = 'G'; |             tmp_gnss_synchro.System = 'G'; | ||||||
|             std::string signal = "1C"; |             std::string signal = "1C"; | ||||||
|             signal.copy(tmp_gnss_synchro.Signal, 2, 0); |             const char* str = signal.c_str();                                  // get a C style null terminated string | ||||||
|  |             std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3);  // copy string into synchro char array: 2 char + null | ||||||
|             tmp_gnss_synchro.PRN = SV_ID; |             tmp_gnss_synchro.PRN = SV_ID; | ||||||
|             System_and_Signal = "GPS L1 CA"; |             System_and_Signal = "GPS L1 CA"; | ||||||
|             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); |             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); | ||||||
| @@ -416,7 +417,8 @@ bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | |||||||
|         { |         { | ||||||
|             tmp_gnss_synchro.System = 'E'; |             tmp_gnss_synchro.System = 'E'; | ||||||
|             std::string signal = "1B"; |             std::string signal = "1B"; | ||||||
|             signal.copy(tmp_gnss_synchro.Signal, 2, 0); |             const char* str = signal.c_str();                                  // get a C style null terminated string | ||||||
|  |             std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3);  // copy string into synchro char array: 2 char + null | ||||||
|             tmp_gnss_synchro.PRN = SV_ID; |             tmp_gnss_synchro.PRN = SV_ID; | ||||||
|             System_and_Signal = "Galileo E1B"; |             System_and_Signal = "Galileo E1B"; | ||||||
|             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); |             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); | ||||||
| @@ -426,7 +428,8 @@ bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | |||||||
|         { |         { | ||||||
|             tmp_gnss_synchro.System = 'G'; |             tmp_gnss_synchro.System = 'G'; | ||||||
|             std::string signal = "2S"; |             std::string signal = "2S"; | ||||||
|             signal.copy(tmp_gnss_synchro.Signal, 2, 0); |             const char* str = signal.c_str();                                  // get a C style null terminated string | ||||||
|  |             std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3);  // copy string into synchro char array: 2 char + null | ||||||
|             tmp_gnss_synchro.PRN = SV_ID; |             tmp_gnss_synchro.PRN = SV_ID; | ||||||
|             System_and_Signal = "GPS L2CM"; |             System_and_Signal = "GPS L2CM"; | ||||||
|             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); |             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); | ||||||
| @@ -436,7 +439,8 @@ bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | |||||||
|         { |         { | ||||||
|             tmp_gnss_synchro.System = 'E'; |             tmp_gnss_synchro.System = 'E'; | ||||||
|             std::string signal = "5X"; |             std::string signal = "5X"; | ||||||
|             signal.copy(tmp_gnss_synchro.Signal, 2, 0); |             const char* str = signal.c_str();                                  // get a C style null terminated string | ||||||
|  |             std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3);  // copy string into synchro char array: 2 char + null | ||||||
|             tmp_gnss_synchro.PRN = SV_ID; |             tmp_gnss_synchro.PRN = SV_ID; | ||||||
|             System_and_Signal = "Galileo E5a"; |             System_and_Signal = "Galileo E5a"; | ||||||
|             config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); |             config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); | ||||||
| @@ -451,7 +455,8 @@ bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | |||||||
|         { |         { | ||||||
|             tmp_gnss_synchro.System = 'E'; |             tmp_gnss_synchro.System = 'E'; | ||||||
|             std::string signal = "5X"; |             std::string signal = "5X"; | ||||||
|             signal.copy(tmp_gnss_synchro.Signal, 2, 0); |             const char* str = signal.c_str();                                  // get a C style null terminated string | ||||||
|  |             std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3);  // copy string into synchro char array: 2 char + null | ||||||
|             tmp_gnss_synchro.PRN = SV_ID; |             tmp_gnss_synchro.PRN = SV_ID; | ||||||
|             System_and_Signal = "Galileo E5a"; |             System_and_Signal = "Galileo E5a"; | ||||||
|             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); |             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); | ||||||
| @@ -461,7 +466,8 @@ bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | |||||||
|         { |         { | ||||||
|             tmp_gnss_synchro.System = 'G'; |             tmp_gnss_synchro.System = 'G'; | ||||||
|             std::string signal = "L5"; |             std::string signal = "L5"; | ||||||
|             signal.copy(tmp_gnss_synchro.Signal, 2, 0); |             const char* str = signal.c_str();                                  // get a C style null terminated string | ||||||
|  |             std::memcpy(static_cast<void*>(tmp_gnss_synchro.Signal), str, 3);  // copy string into synchro char array: 2 char + null | ||||||
|             tmp_gnss_synchro.PRN = SV_ID; |             tmp_gnss_synchro.PRN = SV_ID; | ||||||
|             System_and_Signal = "GPS L5I"; |             System_and_Signal = "GPS L5I"; | ||||||
|             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); |             config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); | ||||||
| @@ -522,8 +528,21 @@ bool TrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) | |||||||
|     code_delay_measurements_map.clear(); |     code_delay_measurements_map.clear(); | ||||||
|     acq_samplestamp_map.clear(); |     acq_samplestamp_map.clear(); | ||||||
|  |  | ||||||
|  |     unsigned int MAX_PRN_IDX = 0; | ||||||
|  |  | ||||||
|     for (unsigned int PRN = 1; PRN < 33; PRN++) |     switch (tmp_gnss_synchro.System) | ||||||
|  |         { | ||||||
|  |         case 'G': | ||||||
|  |             MAX_PRN_IDX = 33; | ||||||
|  |             break; | ||||||
|  |         case 'E': | ||||||
|  |             MAX_PRN_IDX = 37; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             MAX_PRN_IDX = 33; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) | ||||||
|         { |         { | ||||||
|             tmp_gnss_synchro.PRN = PRN; |             tmp_gnss_synchro.PRN = PRN; | ||||||
|             acquisition->set_gnss_synchro(&tmp_gnss_synchro); |             acquisition->set_gnss_synchro(&tmp_gnss_synchro); | ||||||
| @@ -625,7 +644,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) | |||||||
|     if (FLAGS_enable_external_signal_file) |     if (FLAGS_enable_external_signal_file) | ||||||
|         { |         { | ||||||
|             //create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters |             //create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters | ||||||
|             ASSERT_EQ(acquire_GPS_L1CA_signal(FLAGS_test_satellite_PRN), true); |             ASSERT_EQ(acquire_signal(FLAGS_test_satellite_PRN), true); | ||||||
|             bool found_satellite = doppler_measurements_map.find(FLAGS_test_satellite_PRN) != doppler_measurements_map.end(); |             bool found_satellite = doppler_measurements_map.find(FLAGS_test_satellite_PRN) != doppler_measurements_map.end(); | ||||||
|             EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << FLAGS_test_satellite_PRN << " is not acquired"; |             EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << FLAGS_test_satellite_PRN << " is not acquired"; | ||||||
|             if (!found_satellite) return; |             if (!found_satellite) return; | ||||||
| @@ -743,7 +762,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) | |||||||
|                                 top_block->connect(head_samples, 0, tracking->get_left_block(), 0); |                                 top_block->connect(head_samples, 0, tracking->get_left_block(), 0); | ||||||
|                                 top_block->connect(tracking->get_right_block(), 0, sink, 0); |                                 top_block->connect(tracking->get_right_block(), 0, sink, 0); | ||||||
|                                 top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); |                                 top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); | ||||||
|                                 file_source->seek(2 * FLAGS_skip_samples + acq_samplestamp_samples, 0);  //skip head. ibyte, two bytes per complex sample |                                 file_source->seek(2 * FLAGS_skip_samples, 0);  //skip head. ibyte, two bytes per complex sample | ||||||
|                             }) << "Failure connecting the blocks of tracking test."; |                             }) << "Failure connecting the blocks of tracking test."; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -841,7 +860,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) | |||||||
|                                                                 } |                                                                 } | ||||||
|                                                             else |                                                             else | ||||||
|                                                                 { |                                                                 { | ||||||
|                                                                     g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); |                                                                     g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); | ||||||
|                                                                 } |                                                                 } | ||||||
|  |  | ||||||
|                                                             g1.set_grid(); |                                                             g1.set_grid(); | ||||||
| @@ -857,18 +876,17 @@ TEST_F(TrackingPullInTest, ValidationOfResults) | |||||||
|                                                                     g1.plot_xy(trk_timestamp_s, v_late, "Very Late", decimate); |                                                                     g1.plot_xy(trk_timestamp_s, v_late, "Very Late", decimate); | ||||||
|                                                                 } |                                                                 } | ||||||
|                                                             g1.set_legend(); |                                                             g1.set_legend(); | ||||||
|                                                             //g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); |                                                             g1.savetops("Correlators_outputs"); | ||||||
|                                                             //g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); |  | ||||||
|  |  | ||||||
|                                                             Gnuplot g2("points"); |                                                             Gnuplot g2("points"); | ||||||
|                                                             g2.showonscreen();  // window output |                                                             g2.showonscreen();  // window output | ||||||
|                                                             if (!FLAGS_enable_external_signal_file) |                                                             if (!FLAGS_enable_external_signal_file) | ||||||
|                                                                 { |                                                                 { | ||||||
|                                                                     g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); |                                                                     g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); | ||||||
|                                                                 } |                                                                 } | ||||||
|                                                             else |                                                             else | ||||||
|                                                                 { |                                                                 { | ||||||
|                                                                     g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); |                                                                     g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); | ||||||
|                                                                 } |                                                                 } | ||||||
|  |  | ||||||
|                                                             g2.set_grid(); |                                                             g2.set_grid(); | ||||||
| @@ -876,8 +894,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) | |||||||
|                                                             g2.set_ylabel("Quadrature"); |                                                             g2.set_ylabel("Quadrature"); | ||||||
|                                                             //g2.cmd("set size ratio -1"); |                                                             //g2.cmd("set size ratio -1"); | ||||||
|                                                             g2.plot_xy(promptI, promptQ); |                                                             g2.plot_xy(promptI, promptQ); | ||||||
|                                                             //g2.savetops("Constellation"); |                                                             g2.savetops("Constellation"); | ||||||
|                                                             //g2.savetopdf("Constellation", 18); |  | ||||||
|  |  | ||||||
|                                                             Gnuplot g3("linespoints"); |                                                             Gnuplot g3("linespoints"); | ||||||
|                                                             if (!FLAGS_enable_external_signal_file) |                                                             if (!FLAGS_enable_external_signal_file) | ||||||
| @@ -886,7 +903,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) | |||||||
|                                                                 } |                                                                 } | ||||||
|                                                             else |                                                             else | ||||||
|                                                                 { |                                                                 { | ||||||
|                                                                     g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); |                                                                     g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); | ||||||
|                                                                 } |                                                                 } | ||||||
|                                                             g3.set_grid(); |                                                             g3.set_grid(); | ||||||
|                                                             g3.set_xlabel("Time [s]"); |                                                             g3.set_xlabel("Time [s]"); | ||||||
| @@ -897,8 +914,8 @@ TEST_F(TrackingPullInTest, ValidationOfResults) | |||||||
|                                                                 std::to_string(static_cast<int>(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); |                                                                 std::to_string(static_cast<int>(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); | ||||||
|  |  | ||||||
|                                                             g3.set_legend(); |                                                             g3.set_legend(); | ||||||
|                                                             //g3.savetops("CN0_output"); |                                                             g3.savetops("CN0_output"); | ||||||
|                                                             //g3.savetopdf("CN0_output", 18); |  | ||||||
|                                                             g3.showonscreen();  // window output |                                                             g3.showonscreen();  // window output | ||||||
|                                                         } |                                                         } | ||||||
|                                                 } |                                                 } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez