2012-07-12 21:17:37 +00:00
|
|
|
/*!
|
2020-11-07 21:43:19 +00:00
|
|
|
* \file gnss_signal_replica.cc
|
|
|
|
* \brief This library gathers a few functions used for GNSS signal replica
|
|
|
|
* generation regardless of system used
|
2012-07-12 21:17:37 +00:00
|
|
|
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
|
|
|
*
|
|
|
|
*
|
2020-07-28 14:57:15 +00:00
|
|
|
* -----------------------------------------------------------------------------
|
2012-07-12 21:17:37 +00:00
|
|
|
*
|
2020-12-30 12:35:06 +00:00
|
|
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
2012-07-12 21:17:37 +00:00
|
|
|
* This file is part of GNSS-SDR.
|
|
|
|
*
|
2020-12-30 12:35:06 +00:00
|
|
|
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
2020-02-08 00:20:02 +00:00
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
2012-07-12 21:17:37 +00:00
|
|
|
*
|
2020-07-28 14:57:15 +00:00
|
|
|
* -----------------------------------------------------------------------------
|
2012-07-12 21:17:37 +00:00
|
|
|
*/
|
|
|
|
|
2020-11-07 21:43:19 +00:00
|
|
|
#include "gnss_signal_replica.h"
|
2020-07-05 18:20:02 +00:00
|
|
|
#include "MATH_CONSTANTS.h"
|
2018-02-26 02:15:53 +00:00
|
|
|
#include <gnuradio/fxpt_nco.h>
|
2019-08-24 15:34:12 +00:00
|
|
|
#include <cstddef> // for size_t
|
2012-07-12 21:17:37 +00:00
|
|
|
|
|
|
|
|
2020-05-07 10:13:49 +00:00
|
|
|
const auto AUX_CEIL2 = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
|
2015-05-06 08:53:27 +00:00
|
|
|
|
2020-12-29 13:47:28 +00:00
|
|
|
void complex_exp_gen(own::span<std::complex<float>> dest, double freq, double sampling_freq)
|
2012-08-04 08:41:32 +00:00
|
|
|
{
|
2015-05-05 14:14:46 +00:00
|
|
|
gr::fxpt_nco d_nco;
|
2020-12-29 13:47:28 +00:00
|
|
|
d_nco.set_freq(static_cast<float>((TWO_PI * freq) / sampling_freq));
|
|
|
|
d_nco.sincos(dest.data(), dest.size(), 1);
|
2012-07-12 21:17:37 +00:00
|
|
|
}
|
|
|
|
|
2012-10-28 12:38:11 +00:00
|
|
|
|
2020-12-29 13:47:28 +00:00
|
|
|
void complex_exp_gen_conj(own::span<std::complex<float>> dest, double freq, double sampling_freq)
|
2012-10-18 10:24:41 +00:00
|
|
|
{
|
2015-05-05 14:14:46 +00:00
|
|
|
gr::fxpt_nco d_nco;
|
2020-12-29 13:47:28 +00:00
|
|
|
d_nco.set_freq(-static_cast<float>((TWO_PI * freq) / sampling_freq));
|
|
|
|
d_nco.sincos(dest.data(), dest.size(), 1);
|
2012-10-18 10:24:41 +00:00
|
|
|
}
|
|
|
|
|
2018-08-13 08:18:05 +00:00
|
|
|
|
2020-12-29 13:47:28 +00:00
|
|
|
void hex_to_binary_converter(own::span<int32_t> dest, char from)
|
2012-07-12 21:17:37 +00:00
|
|
|
{
|
2020-12-29 13:47:28 +00:00
|
|
|
switch (from)
|
2018-03-03 01:03:39 +00:00
|
|
|
{
|
|
|
|
case '0':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '1':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '2':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '3':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '4':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '5':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '6':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '7':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = 1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '8':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case '9':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case 'A':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case 'B':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = 1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case 'C':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case 'D':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = 1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case 'E':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = 1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
|
|
|
case 'F':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = -1;
|
|
|
|
dest[1] = -1;
|
|
|
|
dest[2] = -1;
|
|
|
|
dest[3] = -1;
|
2018-03-03 01:03:39 +00:00
|
|
|
break;
|
2019-07-18 20:57:45 +00:00
|
|
|
default:
|
|
|
|
break;
|
2018-03-03 01:03:39 +00:00
|
|
|
}
|
2012-07-12 21:17:37 +00:00
|
|
|
}
|
|
|
|
|
2018-08-13 08:18:05 +00:00
|
|
|
|
2020-12-29 13:47:28 +00:00
|
|
|
std::string hex_to_binary_string(char from)
|
2020-11-07 20:33:26 +00:00
|
|
|
{
|
2020-12-29 13:47:28 +00:00
|
|
|
std::string dest("0000");
|
|
|
|
switch (from)
|
2020-11-07 20:33:26 +00:00
|
|
|
{
|
|
|
|
case '0':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '1':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '2':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '3':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '4':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '5':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '6':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '7':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '0';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '8':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case '9':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case 'A':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case 'B':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '0';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case 'C':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case 'D':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '0';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case 'E':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '0';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
case 'F':
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[0] = '1';
|
|
|
|
dest[1] = '1';
|
|
|
|
dest[2] = '1';
|
|
|
|
dest[3] = '1';
|
2020-11-07 20:33:26 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2020-12-29 13:47:28 +00:00
|
|
|
return dest;
|
2020-11-07 20:33:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-29 13:47:28 +00:00
|
|
|
void resampler(const own::span<float> from, own::span<float> dest, float fs_in,
|
|
|
|
float fs_out)
|
2017-09-11 14:21:05 +00:00
|
|
|
{
|
2020-12-29 13:47:28 +00:00
|
|
|
uint32_t codeValueIndex;
|
2017-09-11 14:21:05 +00:00
|
|
|
float aux;
|
2020-12-29 13:47:28 +00:00
|
|
|
const float t_out = 1.0F / fs_out; // Output sampling period
|
|
|
|
const size_t dest_size = dest.size();
|
|
|
|
for (size_t i = 0; i < dest_size - 1; i++)
|
2017-09-11 14:21:05 +00:00
|
|
|
{
|
2020-12-29 13:47:28 +00:00
|
|
|
aux = (t_out * (static_cast<float>(i) + 1.0F)) * fs_in;
|
|
|
|
codeValueIndex = AUX_CEIL2(aux) - 1;
|
|
|
|
dest[i] = from[codeValueIndex];
|
2017-09-11 14:21:05 +00:00
|
|
|
}
|
2020-07-21 12:31:45 +00:00
|
|
|
// Correct the last index (due to number rounding issues)
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[dest_size - 1] = from[from.size() - 1];
|
2017-09-11 14:21:05 +00:00
|
|
|
}
|
2012-08-04 11:39:01 +00:00
|
|
|
|
2018-08-13 08:18:05 +00:00
|
|
|
|
2020-12-29 13:47:28 +00:00
|
|
|
void resampler(own::span<const std::complex<float>> from, own::span<std::complex<float>> dest, float fs_in,
|
|
|
|
float fs_out)
|
2012-07-12 21:17:37 +00:00
|
|
|
{
|
2020-12-29 13:47:28 +00:00
|
|
|
uint32_t codeValueIndex;
|
2015-05-06 08:53:27 +00:00
|
|
|
float aux;
|
2020-12-29 13:47:28 +00:00
|
|
|
const float t_out = 1.0F / fs_out; // Output sampling period
|
|
|
|
const size_t dest_size = dest.size();
|
|
|
|
for (size_t i = 0; i < dest_size - 1; i++)
|
2012-07-12 21:17:37 +00:00
|
|
|
{
|
2020-12-29 13:47:28 +00:00
|
|
|
aux = (t_out * (static_cast<float>(i) + 1.0F)) * fs_in;
|
|
|
|
codeValueIndex = AUX_CEIL2(aux) - 1;
|
|
|
|
dest[i] = from[codeValueIndex];
|
2012-07-12 21:17:37 +00:00
|
|
|
}
|
2020-07-21 12:31:45 +00:00
|
|
|
// Correct the last index (due to number rounding issues)
|
2020-12-29 13:47:28 +00:00
|
|
|
dest[dest_size - 1] = from[from.size() - 1];
|
2012-07-12 21:17:37 +00:00
|
|
|
}
|