mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	Adding and integrating sincos kernel
This commit is contained in:
		| @@ -40,7 +40,7 @@ | |||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
| #include "gnss_signal_processing.h" | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
| @@ -277,6 +277,7 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init() | |||||||
|     d_gnss_synchro->Acq_samplestamp_samples = 0; |     d_gnss_synchro->Acq_samplestamp_samples = 0; | ||||||
|     d_mag = 0.0; |     d_mag = 0.0; | ||||||
|     d_input_power = 0.0; |     d_input_power = 0.0; | ||||||
|  |     const double GALILEO_TWO_PI = 6.283185307179600; | ||||||
|  |  | ||||||
|     // Count the number of bins |     // Count the number of bins | ||||||
|     d_num_doppler_bins = 0; |     d_num_doppler_bins = 0; | ||||||
| @@ -293,7 +294,9 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init() | |||||||
|         { |         { | ||||||
|             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); |             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); | ||||||
|             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; |             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; | ||||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], d_freq + doppler, d_fs_in, d_fft_size); |             float phase_step_rad = GALILEO_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||||
|  |  | ||||||
|  |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     /* CAF Filtering to resolve doppler ambiguity. Phase and quadrature must be processed |     /* CAF Filtering to resolve doppler ambiguity. Phase and quadrature must be processed | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ | |||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
| #include "gnss_signal_processing.h" | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
| @@ -157,7 +157,7 @@ void galileo_pcps_8ms_acquisition_cc::init() | |||||||
|     d_gnss_synchro->Acq_samplestamp_samples = 0; |     d_gnss_synchro->Acq_samplestamp_samples = 0; | ||||||
|     d_mag = 0.0; |     d_mag = 0.0; | ||||||
|     d_input_power = 0.0; |     d_input_power = 0.0; | ||||||
|  |     const double GALILEO_TWO_PI = 6.283185307179600; | ||||||
|     // Count the number of bins |     // Count the number of bins | ||||||
|     d_num_doppler_bins = 0; |     d_num_doppler_bins = 0; | ||||||
|     for (int doppler = static_cast<int>(-d_doppler_max); |     for (int doppler = static_cast<int>(-d_doppler_max); | ||||||
| @@ -173,7 +173,8 @@ void galileo_pcps_8ms_acquisition_cc::init() | |||||||
|         { |         { | ||||||
|             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); |             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); | ||||||
|             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; |             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; | ||||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], d_freq + doppler, d_fs_in, d_fft_size); |             float phase_step_rad = static_cast<float>(GALILEO_TWO_PI) * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||||
|  |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,9 +38,9 @@ | |||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "gnss_signal_processing.h" | #include "gnss_signal_processing.h" | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| #include <gnuradio/fxpt.h>  // fixed point sine and cosine |  | ||||||
| #include "GPS_L1_CA.h" //GPS_TWO_PI | #include "GPS_L1_CA.h" //GPS_TWO_PI | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -174,18 +174,8 @@ void pcps_acquisition_cc::set_local_code(std::complex<float> * code) | |||||||
|  |  | ||||||
| void pcps_acquisition_cc::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) | void pcps_acquisition_cc::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) | ||||||
| { | { | ||||||
|     float sin_f, cos_f; |     float phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(d_fs_in); | ||||||
|     float phase_step_rad= GPS_TWO_PI * freq/ static_cast<float>(d_fs_in); |     volk_gnsssdr_s32f_sincos_32fc(carrier_vector, - phase_step_rad, correlator_length_samples); | ||||||
|  |  | ||||||
|     int phase_step_rad_i = gr::fxpt::float_to_fixed(phase_step_rad); |  | ||||||
|     int phase_rad_i = 0; |  | ||||||
|  |  | ||||||
|     for(int i = 0; i < correlator_length_samples; i++) |  | ||||||
|         { |  | ||||||
|             gr::fxpt::sincos(phase_rad_i, &sin_f, &cos_f); |  | ||||||
|             carrier_vector[i] = gr_complex(cos_f, -sin_f); |  | ||||||
|             phase_rad_i += phase_step_rad_i; |  | ||||||
|         } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void pcps_acquisition_cc::init() | void pcps_acquisition_cc::init() | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ | |||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
| #include "nco_lib.h" | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "concurrent_map.h" | #include "concurrent_map.h" | ||||||
| #include "gnss_signal_processing.h" | #include "gnss_signal_processing.h" | ||||||
| #include "gps_sdr_signal_processing.h" | #include "gps_sdr_signal_processing.h" | ||||||
| @@ -184,14 +184,16 @@ void pcps_acquisition_fine_doppler_cc::forecast (int noutput_items, | |||||||
| void pcps_acquisition_fine_doppler_cc::reset_grid() | void pcps_acquisition_fine_doppler_cc::reset_grid() | ||||||
| { | { | ||||||
|     d_well_count = 0; |     d_well_count = 0; | ||||||
|     for (int i=0; i<d_num_doppler_points; i++) |     for (int i = 0; i < d_num_doppler_points; i++) | ||||||
|         { |         { | ||||||
|             for (unsigned int j=0; j < d_fft_size; j++) |             for (unsigned int j = 0; j < d_fft_size; j++) | ||||||
|                 { |                 { | ||||||
|                     d_grid_data[i][j] = 0.0; |                     d_grid_data[i][j] = 0.0; | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff() | void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff() | ||||||
| { | { | ||||||
|     // create the carrier Doppler wipeoff signals |     // create the carrier Doppler wipeoff signals | ||||||
| @@ -200,13 +202,12 @@ void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff() | |||||||
|     d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_points]; |     d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_points]; | ||||||
|     for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++) |     for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++) | ||||||
|         { |         { | ||||||
|  |  | ||||||
|             doppler_hz = d_config_doppler_min + d_doppler_step*doppler_index; |             doppler_hz = d_config_doppler_min + d_doppler_step*doppler_index; | ||||||
|             // doppler search steps |             // doppler search steps | ||||||
|             // compute the carrier doppler wipe-off signal and store it |             // compute the carrier doppler wipe-off signal and store it | ||||||
|             phase_step_rad = static_cast<float>(GPS_TWO_PI) * ( d_freq + doppler_hz ) / static_cast<float>(d_fs_in); |             phase_step_rad = static_cast<float>(GPS_TWO_PI) * ( d_freq + doppler_hz ) / static_cast<float>(d_fs_in); | ||||||
|             d_grid_doppler_wipeoffs[doppler_index] = new gr_complex[d_fft_size]; |             d_grid_doppler_wipeoffs[doppler_index] = new gr_complex[d_fft_size]; | ||||||
|             fxp_nco(d_grid_doppler_wipeoffs[doppler_index], d_fft_size,0, phase_step_rad); |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,7 +41,6 @@ | |||||||
| #include "gnss_signal_processing.h" | #include "gnss_signal_processing.h" | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include <gnuradio/fxpt.h>  // fixed point sine and cosine |  | ||||||
| #include "GPS_L1_CA.h" //GPS_TWO_PI | #include "GPS_L1_CA.h" //GPS_TWO_PI | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
| @@ -177,18 +176,8 @@ void pcps_acquisition_sc::set_local_code(std::complex<float> * code) | |||||||
|  |  | ||||||
| void pcps_acquisition_sc::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) | void pcps_acquisition_sc::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) | ||||||
| { | { | ||||||
|     float sin_f, cos_f; |     float phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(d_fs_in); | ||||||
|     float phase_step_rad= GPS_TWO_PI * freq/ static_cast<float>(d_fs_in); |     volk_gnsssdr_s32f_sincos_32fc(carrier_vector, - phase_step_rad, correlator_length_samples); | ||||||
|  |  | ||||||
|     int phase_step_rad_i = gr::fxpt::float_to_fixed(phase_step_rad); |  | ||||||
|     int phase_rad_i = 0; |  | ||||||
|  |  | ||||||
|     for(int i = 0; i < correlator_length_samples; i++) |  | ||||||
|         { |  | ||||||
|             gr::fxpt::sincos(phase_rad_i, &sin_f, &cos_f); |  | ||||||
|             carrier_vector[i] = gr_complex(cos_f, -sin_f); |  | ||||||
|             phase_rad_i += phase_step_rad_i; |  | ||||||
|         } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void pcps_acquisition_sc::init() | void pcps_acquisition_sc::init() | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ | |||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
| #include "nco_lib.h" | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "concurrent_map.h" | #include "concurrent_map.h" | ||||||
| #include "gnss_signal_processing.h" | #include "gnss_signal_processing.h" | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| @@ -252,7 +252,7 @@ void pcps_assisted_acquisition_cc::redefine_grid() | |||||||
|             // compute the carrier doppler wipe-off signal and store it |             // compute the carrier doppler wipe-off signal and store it | ||||||
|             phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in); |             phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in); | ||||||
|             d_grid_doppler_wipeoffs[doppler_index] = new gr_complex[d_fft_size]; |             d_grid_doppler_wipeoffs[doppler_index] = new gr_complex[d_fft_size]; | ||||||
|             fxp_nco(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, 0, phase_step_rad); |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -39,8 +39,9 @@ | |||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
| #include "gnss_signal_processing.h" | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
|  | #include "GPS_L1_CA.h" //GPS_TWO_PI | ||||||
|  |  | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
| @@ -188,8 +189,9 @@ void pcps_cccwsr_acquisition_cc::init() | |||||||
|             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); |             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); | ||||||
|  |  | ||||||
|             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; |             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; | ||||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], |             float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||||
|                                  d_freq + doppler, d_fs_in, d_fft_size); |  | ||||||
|  |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -39,8 +39,9 @@ | |||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
| #include "gnss_signal_processing.h" | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
|  | #include "GPS_L1_CA.h" //GPS_TWO_PI | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| @@ -174,8 +175,8 @@ void pcps_multithread_acquisition_cc::init() | |||||||
|             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); |             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); | ||||||
|  |  | ||||||
|             int doppler = -(int)d_doppler_max + d_doppler_step * doppler_index; |             int doppler = -(int)d_doppler_max + d_doppler_step * doppler_index; | ||||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], |             float phase_step_rad = static_cast<float>(GPS_TWO_PI) * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||||
|                                  d_freq + doppler, d_fs_in, d_fft_size); |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -56,11 +56,11 @@ | |||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
| #include "gnss_signal_processing.h" | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| #include "fft_base_kernels.h" | #include "fft_base_kernels.h" | ||||||
| #include "fft_internal.h" | #include "fft_internal.h" | ||||||
|  | #include "GPS_L1_CA.h" //GPS_TWO_PI | ||||||
|  |  | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
| @@ -315,9 +315,9 @@ void pcps_opencl_acquisition_cc::init() | |||||||
|         { |         { | ||||||
|             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); |             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); | ||||||
|  |  | ||||||
|             int doppler= -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; |             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; | ||||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], |             float phase_step_rad = static_cast<float>(GPS_TWO_PI) * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||||
|                                  d_freq + doppler, d_fs_in, d_fft_size); |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|  |  | ||||||
|             if (d_opencl == 0) |             if (d_opencl == 0) | ||||||
|                 { |                 { | ||||||
|   | |||||||
| @@ -34,9 +34,9 @@ | |||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| #include "gnss_signal_processing.h" | #include "GPS_L1_CA.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
| @@ -220,9 +220,9 @@ void pcps_quicksync_acquisition_cc::init() | |||||||
|         { |         { | ||||||
|             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_samples_per_code * d_folding_factor * sizeof(gr_complex), volk_get_alignment())); |             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_samples_per_code * d_folding_factor * sizeof(gr_complex), volk_get_alignment())); | ||||||
|             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; |             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; | ||||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], |             float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||||
|                     d_freq + doppler, d_fs_in, |  | ||||||
|                     d_samples_per_code * d_folding_factor); |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_samples_per_code * d_folding_factor); | ||||||
|         } |         } | ||||||
|     // DLOG(INFO) << "end init"; |     // DLOG(INFO) << "end init"; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -53,8 +53,9 @@ | |||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <volk/volk.h> | #include <volk/volk.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
| #include "control_message_factory.h" | #include "control_message_factory.h" | ||||||
| #include "gnss_signal_processing.h" | #include "GPS_L1_CA.h" //GPS_TWO_PI | ||||||
|  |  | ||||||
| using google::LogMessage; | using google::LogMessage; | ||||||
|  |  | ||||||
| @@ -185,9 +186,9 @@ void pcps_tong_acquisition_cc::init() | |||||||
|             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); |             d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_malloc(d_fft_size * sizeof(gr_complex), volk_get_alignment())); | ||||||
|  |  | ||||||
|             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; |             int doppler = -static_cast<int>(d_doppler_max) + d_doppler_step * doppler_index; | ||||||
|  |             float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast<float>(d_fs_in); | ||||||
|  |  | ||||||
|             complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index], |             volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], - phase_step_rad, d_fft_size); | ||||||
|                                  d_freq + doppler, d_fs_in, d_fft_size); |  | ||||||
|  |  | ||||||
|             d_grid_data[doppler_index] = static_cast<float*>(volk_malloc(d_fft_size * sizeof(float), volk_get_alignment())); |             d_grid_data[doppler_index] = static_cast<float*>(volk_malloc(d_fft_size * sizeof(float), volk_get_alignment())); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,543 @@ | |||||||
|  | /*! | ||||||
|  |  * \file volk_gnsssdr_s32f_sincos_32fc.h | ||||||
|  |  * \brief VOLK_GNSSSDR kernel: Computes the sine and cosine of a vector of floats. | ||||||
|  |  * \authors <ul> | ||||||
|  |  *          <li> Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es | ||||||
|  |  *          </ul> | ||||||
|  |  * | ||||||
|  |  * VOLK_GNSSSDR kernel that computes the sine and cosine of a vector of floats. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2015  (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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \page volk_gnsssdr_s32f_sincos_32fc | ||||||
|  |  * | ||||||
|  |  * \b Overview | ||||||
|  |  * | ||||||
|  |  * VOLK_GNSSSDR kernel that computes the sine and cosine with a fixed | ||||||
|  |  * phase increment \p phase_inc per sample, providing the output in a complex vector (cosine, sine) | ||||||
|  |  * | ||||||
|  |  * <b>Dispatcher Prototype</b> | ||||||
|  |  * \code | ||||||
|  |  * void volk_gnsssdr_s32f_sincos_32fc(lv_32fc_t* out, const float phase_inc, unsigned int num_points) | ||||||
|  |  * \endcode | ||||||
|  |  * | ||||||
|  |  * \b Inputs | ||||||
|  |  * \li phase_inc:      Phase increment per sample, in radians. | ||||||
|  |  * \li num_points:     Number of components in \p in to be computed. | ||||||
|  |  * | ||||||
|  |  * \b Outputs | ||||||
|  |  * \li out:            Vector of the form lv_32fc_t out[n] = lv_cmake(cos(in[n]), sin(in[n])) | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef INCLUDED_volk_gnsssdr_s32f_sincos_32fc_H | ||||||
|  | #define INCLUDED_volk_gnsssdr_s32f_sincos_32fc_H | ||||||
|  |  | ||||||
|  | #include <math.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr_common.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_SSE2 | ||||||
|  | #include <emmintrin.h> | ||||||
|  | /* Adapted from http://gruntthepeon.free.fr/ssemath/sse_mathfun.h, original code from Julien Pommier  */ | ||||||
|  | /* Based on algorithms from the cephes library http://www.netlib.org/cephes/   */ | ||||||
|  | static inline void volk_gnsssdr_s32f_sincos_32fc_a_sse2(lv_32fc_t* out, const float phase_inc, unsigned int num_points) | ||||||
|  | { | ||||||
|  |     lv_32fc_t* bPtr = out; | ||||||
|  |  | ||||||
|  |     const unsigned int sse_iters = num_points / 4; | ||||||
|  |     unsigned int number = 0; | ||||||
|  |     float _phase; | ||||||
|  |  | ||||||
|  |     __m128 sine, cosine, aux, x, four_phases_reg; | ||||||
|  |     __m128 xmm1, xmm2, xmm3 = _mm_setzero_ps(), sign_bit_sin, y; | ||||||
|  |     __m128i emm0, emm2, emm4; | ||||||
|  |  | ||||||
|  |     /* declare some SSE constants */ | ||||||
|  |     static const int _ps_inv_sign_mask[4] __attribute__((aligned(16))) = { ~0x80000000, ~0x80000000, ~0x80000000, ~0x80000000 }; | ||||||
|  |     static const int _ps_sign_mask[4] __attribute__((aligned(16))) = { (int)0x80000000, (int)0x80000000, (int)0x80000000, (int)0x80000000 }; | ||||||
|  |  | ||||||
|  |     static const float _ps_cephes_FOPI[4] __attribute__((aligned(16))) = { 1.27323954473516, 1.27323954473516, 1.27323954473516, 1.27323954473516 }; | ||||||
|  |     static const int _pi32_1[4]  __attribute__((aligned(16))) = { 1, 1, 1, 1 }; | ||||||
|  |     static const int _pi32_inv1[4]  __attribute__((aligned(16))) = { ~1, ~1, ~1, ~1 }; | ||||||
|  |     static const int _pi32_2[4]  __attribute__((aligned(16))) = { 2, 2, 2, 2}; | ||||||
|  |     static const int _pi32_4[4]  __attribute__((aligned(16))) = { 4, 4, 4, 4}; | ||||||
|  |  | ||||||
|  |     static const float _ps_minus_cephes_DP1[4] __attribute__((aligned(16))) = { -0.78515625, -0.78515625, -0.78515625, -0.78515625 }; | ||||||
|  |     static const float _ps_minus_cephes_DP2[4] __attribute__((aligned(16))) = { -2.4187564849853515625e-4, -2.4187564849853515625e-4, -2.4187564849853515625e-4, -2.4187564849853515625e-4 }; | ||||||
|  |     static const float _ps_minus_cephes_DP3[4] __attribute__((aligned(16))) = { -3.77489497744594108e-8, -3.77489497744594108e-8, -3.77489497744594108e-8, -3.77489497744594108e-8 }; | ||||||
|  |     static const float _ps_coscof_p0[4] __attribute__((aligned(16))) = { 2.443315711809948E-005, 2.443315711809948E-005, 2.443315711809948E-005, 2.443315711809948E-005 }; | ||||||
|  |     static const float _ps_coscof_p1[4] __attribute__((aligned(16))) = { -1.388731625493765E-003, -1.388731625493765E-003, -1.388731625493765E-003, -1.388731625493765E-003 }; | ||||||
|  |     static const float _ps_coscof_p2[4] __attribute__((aligned(16))) = { 4.166664568298827E-002, 4.166664568298827E-002, 4.166664568298827E-002, 4.166664568298827E-002 }; | ||||||
|  |     static const float _ps_sincof_p0[4] __attribute__((aligned(16))) = { -1.9515295891E-4, -1.9515295891E-4, -1.9515295891E-4, -1.9515295891E-4 }; | ||||||
|  |     static const float _ps_sincof_p1[4] __attribute__((aligned(16))) = { 8.3321608736E-3, 8.3321608736E-3, 8.3321608736E-3, 8.3321608736E-3 }; | ||||||
|  |     static const float _ps_sincof_p2[4] __attribute__((aligned(16))) = { -1.6666654611E-1, -1.6666654611E-1, -1.6666654611E-1, -1.6666654611E-1 }; | ||||||
|  |     static const float _ps_0p5[4] __attribute__((aligned(16))) = { 0.5f, 0.5f, 0.5f, 0.5f }; | ||||||
|  |     static const float _ps_1[4] __attribute__((aligned(16))) = { 1.0f, 1.0f, 1.0f, 1.0f }; | ||||||
|  |  | ||||||
|  |     float four_phases[4] __attribute__((aligned(16))) = { 0.0f, phase_inc, 2 * phase_inc, 3 * phase_inc }; | ||||||
|  |     float four_phases_inc[4] __attribute__((aligned(16))) = { 4 * phase_inc, 4 * phase_inc, 4 * phase_inc, 4 * phase_inc }; | ||||||
|  |     four_phases_reg = _mm_load_ps(four_phases); | ||||||
|  |     const __m128 four_phases_inc_reg = _mm_load_ps(four_phases_inc); | ||||||
|  |  | ||||||
|  |     for(;number < sse_iters; number++) | ||||||
|  |         { | ||||||
|  |             x = four_phases_reg; | ||||||
|  |  | ||||||
|  |             sign_bit_sin = x; | ||||||
|  |             /* take the absolute value */ | ||||||
|  |             x = _mm_and_ps(x, *(__m128*)_ps_inv_sign_mask); | ||||||
|  |             /* extract the sign bit (upper one) */ | ||||||
|  |             sign_bit_sin = _mm_and_ps(sign_bit_sin, *(__m128*)_ps_sign_mask); | ||||||
|  |  | ||||||
|  |             /* scale by 4/Pi */ | ||||||
|  |             y = _mm_mul_ps(x, *(__m128*)_ps_cephes_FOPI); | ||||||
|  |  | ||||||
|  |             /* store the integer part of y in emm2 */ | ||||||
|  |             emm2 = _mm_cvttps_epi32(y); | ||||||
|  |  | ||||||
|  |             /* j=(j+1) & (~1) (see the cephes sources) */ | ||||||
|  |             emm2 = _mm_add_epi32(emm2, *(__m128i *)_pi32_1); | ||||||
|  |             emm2 = _mm_and_si128(emm2, *(__m128i *)_pi32_inv1); | ||||||
|  |             y = _mm_cvtepi32_ps(emm2); | ||||||
|  |  | ||||||
|  |             emm4 = emm2; | ||||||
|  |  | ||||||
|  |             /* get the swap sign flag for the sine */ | ||||||
|  |             emm0 = _mm_and_si128(emm2, *(__m128i *)_pi32_4); | ||||||
|  |             emm0 = _mm_slli_epi32(emm0, 29); | ||||||
|  |             __m128 swap_sign_bit_sin = _mm_castsi128_ps(emm0); | ||||||
|  |  | ||||||
|  |             /* get the polynom selection mask for the sine*/ | ||||||
|  |             emm2 = _mm_and_si128(emm2, *(__m128i *)_pi32_2); | ||||||
|  |             emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128()); | ||||||
|  |             __m128 poly_mask = _mm_castsi128_ps(emm2); | ||||||
|  |  | ||||||
|  |             /* The magic pass: "Extended precision modular arithmetic” | ||||||
|  |                x = ((x - y * DP1) - y * DP2) - y * DP3; */ | ||||||
|  |             xmm1 = *(__m128*)_ps_minus_cephes_DP1; | ||||||
|  |             xmm2 = *(__m128*)_ps_minus_cephes_DP2; | ||||||
|  |             xmm3 = *(__m128*)_ps_minus_cephes_DP3; | ||||||
|  |             xmm1 = _mm_mul_ps(y, xmm1); | ||||||
|  |             xmm2 = _mm_mul_ps(y, xmm2); | ||||||
|  |             xmm3 = _mm_mul_ps(y, xmm3); | ||||||
|  |             x = _mm_add_ps(x, xmm1); | ||||||
|  |             x = _mm_add_ps(x, xmm2); | ||||||
|  |             x = _mm_add_ps(x, xmm3); | ||||||
|  |  | ||||||
|  |             emm4 = _mm_sub_epi32(emm4, *(__m128i *)_pi32_2); | ||||||
|  |             emm4 = _mm_andnot_si128(emm4, *(__m128i *)_pi32_4); | ||||||
|  |             emm4 = _mm_slli_epi32(emm4, 29); | ||||||
|  |             __m128 sign_bit_cos = _mm_castsi128_ps(emm4); | ||||||
|  |  | ||||||
|  |             sign_bit_sin = _mm_xor_ps(sign_bit_sin, swap_sign_bit_sin); | ||||||
|  |  | ||||||
|  |             /* Evaluate the first polynom  (0 <= x <= Pi/4) */ | ||||||
|  |             __m128 z = _mm_mul_ps(x,x); | ||||||
|  |             y = *(__m128*)_ps_coscof_p0; | ||||||
|  |  | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             y = _mm_add_ps(y, *(__m128*)_ps_coscof_p1); | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             y = _mm_add_ps(y, *(__m128*)_ps_coscof_p2); | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             __m128 tmp = _mm_mul_ps(z, *(__m128*)_ps_0p5); | ||||||
|  |             y = _mm_sub_ps(y, tmp); | ||||||
|  |             y = _mm_add_ps(y, *(__m128*)_ps_1); | ||||||
|  |  | ||||||
|  |             /* Evaluate the second polynom  (Pi/4 <= x <= 0) */ | ||||||
|  |             __m128 y2 = *(__m128*)_ps_sincof_p0; | ||||||
|  |             y2 = _mm_mul_ps(y2, z); | ||||||
|  |             y2 = _mm_add_ps(y2, *(__m128*)_ps_sincof_p1); | ||||||
|  |             y2 = _mm_mul_ps(y2, z); | ||||||
|  |             y2 = _mm_add_ps(y2, *(__m128*)_ps_sincof_p2); | ||||||
|  |             y2 = _mm_mul_ps(y2, z); | ||||||
|  |             y2 = _mm_mul_ps(y2, x); | ||||||
|  |             y2 = _mm_add_ps(y2, x); | ||||||
|  |  | ||||||
|  |             /* select the correct result from the two polynoms */ | ||||||
|  |             xmm3 = poly_mask; | ||||||
|  |             __m128 ysin2 = _mm_and_ps(xmm3, y2); | ||||||
|  |             __m128 ysin1 = _mm_andnot_ps(xmm3, y); | ||||||
|  |             y2 = _mm_sub_ps(y2,ysin2); | ||||||
|  |             y = _mm_sub_ps(y, ysin1); | ||||||
|  |  | ||||||
|  |             xmm1 = _mm_add_ps(ysin1,ysin2); | ||||||
|  |             xmm2 = _mm_add_ps(y,y2); | ||||||
|  |  | ||||||
|  |             /* update the sign */ | ||||||
|  |             sine = _mm_xor_ps(xmm1, sign_bit_sin); | ||||||
|  |             cosine = _mm_xor_ps(xmm2, sign_bit_cos); | ||||||
|  |  | ||||||
|  |             /* write the output */ | ||||||
|  |             aux = _mm_unpacklo_ps(cosine, sine); | ||||||
|  |             _mm_store_ps((float*)bPtr, aux); | ||||||
|  |             bPtr += 2; | ||||||
|  |             aux = _mm_unpackhi_ps(cosine, sine); | ||||||
|  |             _mm_store_ps((float*)bPtr, aux); | ||||||
|  |             bPtr += 2; | ||||||
|  |  | ||||||
|  |             four_phases_reg = _mm_add_ps(four_phases_reg, four_phases_inc_reg); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     _phase = phase_inc * (sse_iters * 4); | ||||||
|  |     for(number = sse_iters * 4; number < num_points; number++) | ||||||
|  |         { | ||||||
|  |             *bPtr++ = lv_cmake((float)cos(_phase), (float)sin(_phase) ); | ||||||
|  |             _phase += phase_inc; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /* LV_HAVE_SSE2  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_SSE2 | ||||||
|  | #include <emmintrin.h> | ||||||
|  | /* Adapted from http://gruntthepeon.free.fr/ssemath/sse_mathfun.h, original code from Julien Pommier  */ | ||||||
|  | /* Based on algorithms from the cephes library http://www.netlib.org/cephes/   */ | ||||||
|  | static inline void volk_gnsssdr_s32f_sincos_32fc_u_sse2(lv_32fc_t* out, const float phase_inc, unsigned int num_points) | ||||||
|  | { | ||||||
|  |     lv_32fc_t* bPtr = out; | ||||||
|  |  | ||||||
|  |     const unsigned int sse_iters = num_points / 4; | ||||||
|  |     unsigned int number = 0; | ||||||
|  |     float _phase; | ||||||
|  |  | ||||||
|  |     __m128 sine, cosine, aux, x, four_phases_reg; | ||||||
|  |     __m128 xmm1, xmm2, xmm3 = _mm_setzero_ps(), sign_bit_sin, y; | ||||||
|  |     __m128i emm0, emm2, emm4; | ||||||
|  |  | ||||||
|  |     /* declare some SSE constants */ | ||||||
|  |     static const int _ps_inv_sign_mask[4] __attribute__((aligned(16))) = { ~0x80000000, ~0x80000000, ~0x80000000, ~0x80000000 }; | ||||||
|  |     static const int _ps_sign_mask[4] __attribute__((aligned(16))) = { (int)0x80000000, (int)0x80000000, (int)0x80000000, (int)0x80000000 }; | ||||||
|  |  | ||||||
|  |     static const float _ps_cephes_FOPI[4] __attribute__((aligned(16))) = { 1.27323954473516, 1.27323954473516, 1.27323954473516, 1.27323954473516 }; | ||||||
|  |     static const int _pi32_1[4]  __attribute__((aligned(16))) = { 1, 1, 1, 1 }; | ||||||
|  |     static const int _pi32_inv1[4]  __attribute__((aligned(16))) = { ~1, ~1, ~1, ~1 }; | ||||||
|  |     static const int _pi32_2[4]  __attribute__((aligned(16))) = { 2, 2, 2, 2}; | ||||||
|  |     static const int _pi32_4[4]  __attribute__((aligned(16))) = { 4, 4, 4, 4}; | ||||||
|  |  | ||||||
|  |     static const float _ps_minus_cephes_DP1[4] __attribute__((aligned(16))) = { -0.78515625, -0.78515625, -0.78515625, -0.78515625 }; | ||||||
|  |     static const float _ps_minus_cephes_DP2[4] __attribute__((aligned(16))) = { -2.4187564849853515625e-4, -2.4187564849853515625e-4, -2.4187564849853515625e-4, -2.4187564849853515625e-4 }; | ||||||
|  |     static const float _ps_minus_cephes_DP3[4] __attribute__((aligned(16))) = { -3.77489497744594108e-8, -3.77489497744594108e-8, -3.77489497744594108e-8, -3.77489497744594108e-8 }; | ||||||
|  |     static const float _ps_coscof_p0[4] __attribute__((aligned(16))) = { 2.443315711809948E-005, 2.443315711809948E-005, 2.443315711809948E-005, 2.443315711809948E-005 }; | ||||||
|  |     static const float _ps_coscof_p1[4] __attribute__((aligned(16))) = { -1.388731625493765E-003, -1.388731625493765E-003, -1.388731625493765E-003, -1.388731625493765E-003 }; | ||||||
|  |     static const float _ps_coscof_p2[4] __attribute__((aligned(16))) = { 4.166664568298827E-002, 4.166664568298827E-002, 4.166664568298827E-002, 4.166664568298827E-002 }; | ||||||
|  |     static const float _ps_sincof_p0[4] __attribute__((aligned(16))) = { -1.9515295891E-4, -1.9515295891E-4, -1.9515295891E-4, -1.9515295891E-4 }; | ||||||
|  |     static const float _ps_sincof_p1[4] __attribute__((aligned(16))) = { 8.3321608736E-3, 8.3321608736E-3, 8.3321608736E-3, 8.3321608736E-3 }; | ||||||
|  |     static const float _ps_sincof_p2[4] __attribute__((aligned(16))) = { -1.6666654611E-1, -1.6666654611E-1, -1.6666654611E-1, -1.6666654611E-1 }; | ||||||
|  |     static const float _ps_0p5[4] __attribute__((aligned(16))) = { 0.5f, 0.5f, 0.5f, 0.5f }; | ||||||
|  |     static const float _ps_1[4] __attribute__((aligned(16))) = { 1.0f, 1.0f, 1.0f, 1.0f }; | ||||||
|  |  | ||||||
|  |     float four_phases[4] __attribute__((aligned(16))) = { 0.0f, phase_inc, 2 * phase_inc, 3 * phase_inc }; | ||||||
|  |     float four_phases_inc[4] __attribute__((aligned(16))) = { 4 * phase_inc, 4 * phase_inc, 4 * phase_inc, 4 * phase_inc }; | ||||||
|  |     four_phases_reg = _mm_load_ps(four_phases); | ||||||
|  |     const __m128 four_phases_inc_reg = _mm_load_ps(four_phases_inc); | ||||||
|  |  | ||||||
|  |     for(;number < sse_iters; number++) | ||||||
|  |         { | ||||||
|  |             x = four_phases_reg; | ||||||
|  |  | ||||||
|  |             sign_bit_sin = x; | ||||||
|  |             /* take the absolute value */ | ||||||
|  |             x = _mm_and_ps(x, *(__m128*)_ps_inv_sign_mask); | ||||||
|  |             /* extract the sign bit (upper one) */ | ||||||
|  |             sign_bit_sin = _mm_and_ps(sign_bit_sin, *(__m128*)_ps_sign_mask); | ||||||
|  |  | ||||||
|  |             /* scale by 4/Pi */ | ||||||
|  |             y = _mm_mul_ps(x, *(__m128*)_ps_cephes_FOPI); | ||||||
|  |  | ||||||
|  |             /* store the integer part of y in emm2 */ | ||||||
|  |             emm2 = _mm_cvttps_epi32(y); | ||||||
|  |  | ||||||
|  |             /* j=(j+1) & (~1) (see the cephes sources) */ | ||||||
|  |             emm2 = _mm_add_epi32(emm2, *(__m128i *)_pi32_1); | ||||||
|  |             emm2 = _mm_and_si128(emm2, *(__m128i *)_pi32_inv1); | ||||||
|  |             y = _mm_cvtepi32_ps(emm2); | ||||||
|  |  | ||||||
|  |             emm4 = emm2; | ||||||
|  |  | ||||||
|  |             /* get the swap sign flag for the sine */ | ||||||
|  |             emm0 = _mm_and_si128(emm2, *(__m128i *)_pi32_4); | ||||||
|  |             emm0 = _mm_slli_epi32(emm0, 29); | ||||||
|  |             __m128 swap_sign_bit_sin = _mm_castsi128_ps(emm0); | ||||||
|  |  | ||||||
|  |             /* get the polynom selection mask for the sine*/ | ||||||
|  |             emm2 = _mm_and_si128(emm2, *(__m128i *)_pi32_2); | ||||||
|  |             emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128()); | ||||||
|  |             __m128 poly_mask = _mm_castsi128_ps(emm2); | ||||||
|  |  | ||||||
|  |             /* The magic pass: "Extended precision modular arithmetic” | ||||||
|  |                x = ((x - y * DP1) - y * DP2) - y * DP3; */ | ||||||
|  |             xmm1 = *(__m128*)_ps_minus_cephes_DP1; | ||||||
|  |             xmm2 = *(__m128*)_ps_minus_cephes_DP2; | ||||||
|  |             xmm3 = *(__m128*)_ps_minus_cephes_DP3; | ||||||
|  |             xmm1 = _mm_mul_ps(y, xmm1); | ||||||
|  |             xmm2 = _mm_mul_ps(y, xmm2); | ||||||
|  |             xmm3 = _mm_mul_ps(y, xmm3); | ||||||
|  |             x = _mm_add_ps(x, xmm1); | ||||||
|  |             x = _mm_add_ps(x, xmm2); | ||||||
|  |             x = _mm_add_ps(x, xmm3); | ||||||
|  |  | ||||||
|  |             emm4 = _mm_sub_epi32(emm4, *(__m128i *)_pi32_2); | ||||||
|  |             emm4 = _mm_andnot_si128(emm4, *(__m128i *)_pi32_4); | ||||||
|  |             emm4 = _mm_slli_epi32(emm4, 29); | ||||||
|  |             __m128 sign_bit_cos = _mm_castsi128_ps(emm4); | ||||||
|  |  | ||||||
|  |             sign_bit_sin = _mm_xor_ps(sign_bit_sin, swap_sign_bit_sin); | ||||||
|  |  | ||||||
|  |             /* Evaluate the first polynom  (0 <= x <= Pi/4) */ | ||||||
|  |             __m128 z = _mm_mul_ps(x,x); | ||||||
|  |             y = *(__m128*)_ps_coscof_p0; | ||||||
|  |  | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             y = _mm_add_ps(y, *(__m128*)_ps_coscof_p1); | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             y = _mm_add_ps(y, *(__m128*)_ps_coscof_p2); | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             y = _mm_mul_ps(y, z); | ||||||
|  |             __m128 tmp = _mm_mul_ps(z, *(__m128*)_ps_0p5); | ||||||
|  |             y = _mm_sub_ps(y, tmp); | ||||||
|  |             y = _mm_add_ps(y, *(__m128*)_ps_1); | ||||||
|  |  | ||||||
|  |             /* Evaluate the second polynom  (Pi/4 <= x <= 0) */ | ||||||
|  |             __m128 y2 = *(__m128*)_ps_sincof_p0; | ||||||
|  |             y2 = _mm_mul_ps(y2, z); | ||||||
|  |             y2 = _mm_add_ps(y2, *(__m128*)_ps_sincof_p1); | ||||||
|  |             y2 = _mm_mul_ps(y2, z); | ||||||
|  |             y2 = _mm_add_ps(y2, *(__m128*)_ps_sincof_p2); | ||||||
|  |             y2 = _mm_mul_ps(y2, z); | ||||||
|  |             y2 = _mm_mul_ps(y2, x); | ||||||
|  |             y2 = _mm_add_ps(y2, x); | ||||||
|  |  | ||||||
|  |             /* select the correct result from the two polynoms */ | ||||||
|  |             xmm3 = poly_mask; | ||||||
|  |             __m128 ysin2 = _mm_and_ps(xmm3, y2); | ||||||
|  |             __m128 ysin1 = _mm_andnot_ps(xmm3, y); | ||||||
|  |             y2 = _mm_sub_ps(y2,ysin2); | ||||||
|  |             y = _mm_sub_ps(y, ysin1); | ||||||
|  |  | ||||||
|  |             xmm1 = _mm_add_ps(ysin1,ysin2); | ||||||
|  |             xmm2 = _mm_add_ps(y,y2); | ||||||
|  |  | ||||||
|  |             /* update the sign */ | ||||||
|  |             sine = _mm_xor_ps(xmm1, sign_bit_sin); | ||||||
|  |             cosine = _mm_xor_ps(xmm2, sign_bit_cos); | ||||||
|  |  | ||||||
|  |             /* write the output */ | ||||||
|  |             aux = _mm_unpacklo_ps(cosine, sine); | ||||||
|  |             _mm_storeu_ps((float*)bPtr, aux); | ||||||
|  |             bPtr += 2; | ||||||
|  |             aux = _mm_unpackhi_ps(cosine, sine); | ||||||
|  |             _mm_storeu_ps((float*)bPtr, aux); | ||||||
|  |             bPtr += 2; | ||||||
|  |  | ||||||
|  |             four_phases_reg = _mm_add_ps(four_phases_reg, four_phases_inc_reg); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     _phase = phase_inc * (sse_iters * 4); | ||||||
|  |     for(number = sse_iters * 4; number < num_points; number++) | ||||||
|  |         { | ||||||
|  |             *bPtr++ = lv_cmake((float)cos(_phase), (float)sin(_phase) ); | ||||||
|  |             _phase += phase_inc; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /* LV_HAVE_SSE2  */ | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_GENERIC | ||||||
|  |  | ||||||
|  | static inline void volk_gnsssdr_s32f_sincos_32fc_generic(lv_32fc_t* out, const float phase_inc, unsigned int num_points) | ||||||
|  | { | ||||||
|  |     float _phase = 0.0; | ||||||
|  |     for(unsigned int i = 0; i < num_points; i++) | ||||||
|  |         { | ||||||
|  |             *out++ = lv_cmake((float)cos(_phase), (float)sin(_phase) ); | ||||||
|  |             _phase += phase_inc; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /* LV_HAVE_GENERIC  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_GENERIC | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr_sine_table.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | static inline void volk_gnsssdr_s32f_sincos_32fc_generic_fxpt(lv_32fc_t* out, const float phase_inc, unsigned int num_points) | ||||||
|  | { | ||||||
|  |     float _in, s, c; | ||||||
|  |     int32_t x, sin_index, cos_index, d; | ||||||
|  |     const float PI = 3.14159265358979323846; | ||||||
|  |     const float TWO_TO_THE_31_DIV_PI = 2147483648.0 / PI; | ||||||
|  |     const float TWO_PI = PI * 2; | ||||||
|  |     const int32_t bitlength = 32; | ||||||
|  |     const int32_t Nbits = 10; | ||||||
|  |     const int32_t diffbits = bitlength - Nbits; | ||||||
|  |     uint32_t ux; | ||||||
|  |     float _phase = 0.0; | ||||||
|  |     for(unsigned int i = 0; i < num_points; i++) | ||||||
|  |         { | ||||||
|  |             _in = _phase; | ||||||
|  |             d = (int32_t)floor(_in / TWO_PI + 0.5); | ||||||
|  |             _in -= d * TWO_PI; | ||||||
|  |             x = (int32_t) ((float)_in * TWO_TO_THE_31_DIV_PI); | ||||||
|  |  | ||||||
|  |             ux = x; | ||||||
|  |             sin_index = ux >> diffbits; | ||||||
|  |             s = sine_table_10bits[sin_index][0] * (ux >> 1) + sine_table_10bits[sin_index][1]; | ||||||
|  |  | ||||||
|  |             ux = x + 0x40000000; | ||||||
|  |             cos_index = ux >> diffbits; | ||||||
|  |             c = sine_table_10bits[cos_index][0] * (ux >> 1) + sine_table_10bits[cos_index][1]; | ||||||
|  |  | ||||||
|  |             *out++ = lv_cmake((float)c, (float)s ); | ||||||
|  |             _phase += phase_inc; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /* LV_HAVE_GENERIC  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_NEON | ||||||
|  | #include <arm_neon.h> | ||||||
|  | /* Adapted from http://gruntthepeon.free.fr/ssemath/neon_mathfun.h, original code from Julien Pommier  */ | ||||||
|  | /* Based on algorithms from the cephes library http://www.netlib.org/cephes/   */ | ||||||
|  | static inline void volk_gnsssdr_s32f_sincos_32fc_neon(lv_32fc_t* out, const float phase_inc, unsigned int num_points) | ||||||
|  | { | ||||||
|  |     lv_32fc_t* bPtr = out; | ||||||
|  |     const unsigned int neon_iters = num_points / 4; | ||||||
|  |  | ||||||
|  |     __VOLK_ATTR_ALIGNED(16) float32_t four_phases[4] = { 0.0f , phase_inc, 2 * phase_inc,  3 * phase_inc }; | ||||||
|  |     float four_inc = 4 * phase_inc; | ||||||
|  |     __VOLK_ATTR_ALIGNED(16) float32_t four_phases_inc[4] = { four_inc, four_inc, four_inc, four_inc }; | ||||||
|  |  | ||||||
|  |     float32x4_t four_phases_reg = vld1q_f32(four_phases); | ||||||
|  |     float32x4_t four_phases_inc_reg = vld1q_f32(four_phases_inc); | ||||||
|  |  | ||||||
|  |     const float32_t c_minus_cephes_DP1 = -0.78515625; | ||||||
|  |     const float32_t c_minus_cephes_DP2 = -2.4187564849853515625e-4; | ||||||
|  |     const float32_t c_minus_cephes_DP3 = -3.77489497744594108e-8; | ||||||
|  |     const float32_t c_sincof_p0 = -1.9515295891E-4; | ||||||
|  |     const float32_t c_sincof_p1 = 8.3321608736E-3; | ||||||
|  |     const float32_t c_sincof_p2 = -1.6666654611E-1; | ||||||
|  |     const float32_t c_coscof_p0 = 2.443315711809948E-005; | ||||||
|  |     const float32_t c_coscof_p1 = -1.388731625493765E-003; | ||||||
|  |     const float32_t c_coscof_p2 = 4.166664568298827E-002; | ||||||
|  |     const float32_t c_cephes_FOPI = 1.27323954473516; | ||||||
|  |  | ||||||
|  |     unsigned int number = 0; | ||||||
|  |     float _phase; | ||||||
|  |  | ||||||
|  |     float32x4_t x, xmm1, xmm2, xmm3, y, y1, y2, ys, yc, z; | ||||||
|  |     float32x4x2_t result; | ||||||
|  |  | ||||||
|  |     uint32x4_t emm2, poly_mask, sign_mask_sin, sign_mask_cos; | ||||||
|  |  | ||||||
|  |     for(;number < neon_iters; number++) | ||||||
|  |         { | ||||||
|  |             x = four_phases_reg; | ||||||
|  |             __builtin_prefetch(aPtr + 8); | ||||||
|  |  | ||||||
|  |             sign_mask_sin = vcltq_f32(x, vdupq_n_f32(0)); | ||||||
|  |             x = vabsq_f32(x); | ||||||
|  |  | ||||||
|  |             /* scale by 4/Pi */ | ||||||
|  |             y = vmulq_f32(x, vdupq_n_f32(c_cephes_FOPI)); | ||||||
|  |  | ||||||
|  |             /* store the integer part of y in mm0 */ | ||||||
|  |             emm2 = vcvtq_u32_f32(y); | ||||||
|  |             /* j=(j+1) & (~1) (see the cephes sources) */ | ||||||
|  |             emm2 = vaddq_u32(emm2, vdupq_n_u32(1)); | ||||||
|  |             emm2 = vandq_u32(emm2, vdupq_n_u32(~1)); | ||||||
|  |             y = vcvtq_f32_u32(emm2); | ||||||
|  |  | ||||||
|  |             /* get the polynom selection mask | ||||||
|  |                     there is one polynom for 0 <= x <= Pi/4 | ||||||
|  |                     and another one for Pi/4<x<=Pi/2 | ||||||
|  |  | ||||||
|  |                     Both branches will be computed. | ||||||
|  |              */ | ||||||
|  |             poly_mask = vtstq_u32(emm2, vdupq_n_u32(2)); | ||||||
|  |  | ||||||
|  |             /* The magic pass: "Extended precision modular arithmetic" | ||||||
|  |                     x = ((x - y * DP1) - y * DP2) - y * DP3; */ | ||||||
|  |             xmm1 = vmulq_n_f32(y, c_minus_cephes_DP1); | ||||||
|  |             xmm2 = vmulq_n_f32(y, c_minus_cephes_DP2); | ||||||
|  |             xmm3 = vmulq_n_f32(y, c_minus_cephes_DP3); | ||||||
|  |             x = vaddq_f32(x, xmm1); | ||||||
|  |             x = vaddq_f32(x, xmm2); | ||||||
|  |             x = vaddq_f32(x, xmm3); | ||||||
|  |  | ||||||
|  |             sign_mask_sin = veorq_u32(sign_mask_sin, vtstq_u32(emm2, vdupq_n_u32(4))); | ||||||
|  |             sign_mask_cos = vtstq_u32(vsubq_u32(emm2, vdupq_n_u32(2)), vdupq_n_u32(4)); | ||||||
|  |  | ||||||
|  |             /* Evaluate the first polynom  (0 <= x <= Pi/4) in y1, | ||||||
|  |                     and the second polynom      (Pi/4 <= x <= 0) in y2 */ | ||||||
|  |             z = vmulq_f32(x,x); | ||||||
|  |  | ||||||
|  |             y1 = vmulq_n_f32(z, c_coscof_p0); | ||||||
|  |             y2 = vmulq_n_f32(z, c_sincof_p0); | ||||||
|  |             y1 = vaddq_f32(y1, vdupq_n_f32(c_coscof_p1)); | ||||||
|  |             y2 = vaddq_f32(y2, vdupq_n_f32(c_sincof_p1)); | ||||||
|  |             y1 = vmulq_f32(y1, z); | ||||||
|  |             y2 = vmulq_f32(y2, z); | ||||||
|  |             y1 = vaddq_f32(y1, vdupq_n_f32(c_coscof_p2)); | ||||||
|  |             y2 = vaddq_f32(y2, vdupq_n_f32(c_sincof_p2)); | ||||||
|  |             y1 = vmulq_f32(y1, z); | ||||||
|  |             y2 = vmulq_f32(y2, z); | ||||||
|  |             y1 = vmulq_f32(y1, z); | ||||||
|  |             y2 = vmulq_f32(y2, x); | ||||||
|  |             y1 = vsubq_f32(y1, vmulq_f32(z, vdupq_n_f32(0.5f))); | ||||||
|  |             y2 = vaddq_f32(y2, x); | ||||||
|  |             y1 = vaddq_f32(y1, vdupq_n_f32(1)); | ||||||
|  |  | ||||||
|  |             /* select the correct result from the two polynoms */ | ||||||
|  |             ys = vbslq_f32(poly_mask, y1, y2); | ||||||
|  |             yc = vbslq_f32(poly_mask, y2, y1); | ||||||
|  |             result.val[1] = vbslq_f32(sign_mask_sin, vnegq_f32(ys), ys); | ||||||
|  |             result.val[0] = vbslq_f32(sign_mask_cos, yc, vnegq_f32(yc)); | ||||||
|  |  | ||||||
|  |             vst2q_f32((float32_t*)bPtr, result); | ||||||
|  |             bPtr += 4; | ||||||
|  |  | ||||||
|  |             four_phases_reg = vaddq_f32(four_phases_reg, four_phases_inc_reg); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     _phase = phase_inc * (neon_iters * 4); | ||||||
|  |     for(number = neon_iters * 4; number < num_points; number++) | ||||||
|  |         { | ||||||
|  |             *bPtr++ = lv_cmake((float)cos(_phase), (float)sin(_phase) ); | ||||||
|  |             _phase += phase_inc; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /* LV_HAVE_NEON  */ | ||||||
|  |  | ||||||
|  | #endif /* INCLUDED_volk_gnsssdr_s32f_sincos_32fc_H */ | ||||||
| @@ -61,6 +61,8 @@ std::vector<volk_gnsssdr_test_case_t> init_test_list(volk_gnsssdr_test_params_t | |||||||
|     // ... or more tolerance *****  ADDED BY GNSS-SDR |     // ... or more tolerance *****  ADDED BY GNSS-SDR | ||||||
|     volk_gnsssdr_test_params_t test_params_int16 = volk_gnsssdr_test_params_t(16, test_params.scalar(), |     volk_gnsssdr_test_params_t test_params_int16 = volk_gnsssdr_test_params_t(16, test_params.scalar(), | ||||||
|                 test_params.vlen(), test_params.iter(), test_params.benchmark_mode(), test_params.kernel_regex()); |                 test_params.vlen(), test_params.iter(), test_params.benchmark_mode(), test_params.kernel_regex()); | ||||||
|  |     volk_gnsssdr_test_params_t test_params_inacc2 = volk_gnsssdr_test_params_t(2e-1, test_params.scalar(), | ||||||
|  |                 test_params.vlen(), test_params.iter(), test_params.benchmark_mode(), test_params.kernel_regex()); | ||||||
|  |  | ||||||
|     std::vector<volk_gnsssdr_test_case_t> test_cases = boost::assign::list_of |     std::vector<volk_gnsssdr_test_case_t> test_cases = boost::assign::list_of | ||||||
|  |  | ||||||
| @@ -76,6 +78,7 @@ std::vector<volk_gnsssdr_test_case_t> init_test_list(volk_gnsssdr_test_params_t | |||||||
|         (VOLK_INIT_TEST(volk_gnsssdr_8u_x2_multiply_8u, test_params_more_iters)) |         (VOLK_INIT_TEST(volk_gnsssdr_8u_x2_multiply_8u, test_params_more_iters)) | ||||||
|         (VOLK_INIT_TEST(volk_gnsssdr_64f_accumulator_64f, test_params)) |         (VOLK_INIT_TEST(volk_gnsssdr_64f_accumulator_64f, test_params)) | ||||||
|         (VOLK_INIT_TEST(volk_gnsssdr_32f_sincos_32fc, test_params_inacc)) |         (VOLK_INIT_TEST(volk_gnsssdr_32f_sincos_32fc, test_params_inacc)) | ||||||
|  |         (VOLK_INIT_TEST(volk_gnsssdr_s32f_sincos_32fc, test_params_inacc2)) | ||||||
|         (VOLK_INIT_TEST(volk_gnsssdr_32fc_convert_8ic, test_params)) |         (VOLK_INIT_TEST(volk_gnsssdr_32fc_convert_8ic, test_params)) | ||||||
|         (VOLK_INIT_TEST(volk_gnsssdr_32fc_convert_16ic, test_params_more_iters)) |         (VOLK_INIT_TEST(volk_gnsssdr_32fc_convert_16ic, test_params_more_iters)) | ||||||
|         (VOLK_INIT_TEST(volk_gnsssdr_16ic_x2_dot_prod_16ic, test_params)) |         (VOLK_INIT_TEST(volk_gnsssdr_16ic_x2_dot_prod_16ic, test_params)) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez