Modified Costas loop; descramble sync data before unmapping

This commit is contained in:
2024-10-14 23:52:56 -04:00
parent cfbbacdd0f
commit 5d097d7df8
6 changed files with 298 additions and 61 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ public:
/**
* @brief Default constructor.
*/
BitStream() : bit_index(0), max_bit_idx(0) {}
BitStream() : std::vector<uint8_t>(), bit_index(0), max_bit_idx(0) {}
/**
* @brief Constructs a BitStream from an existing vector of bytes.
+14 -15
View File
@@ -39,8 +39,8 @@ private:
class CostasLoop {
public:
CostasLoop(const double _carrier_freq, const double _sample_rate, const std::vector<std::complex<double>>& _symbolMap, const double _vco_gain)
: carrier_freq(_carrier_freq), sample_rate(_sample_rate), vco_gain(_vco_gain), k_factor(-1 / (_sample_rate * _vco_gain)),
CostasLoop(const double _carrier_freq, const double _sample_rate, const std::vector<std::complex<double>>& _symbolMap, const double _vco_gain, const double _alpha, const double _beta)
: carrier_freq(_carrier_freq), sample_rate(_sample_rate), vco_gain(_vco_gain), alpha(_alpha), beta(_beta), freq_error(0.0), k_factor(-1 / (_sample_rate * _vco_gain)),
prev_in_iir(0), prev_out_iir(0), prev_in_vco(0), feedback(1.0, 0.0),
error_total(0), out_iir_total(0), in_vco_total(0),
srrc_filter(SRRCFilter(48, _sample_rate, 2400, 0.35)) {}
@@ -67,26 +67,22 @@ public:
std::complex<double> limited = limiter(filtered);
// IIR Filter
double in_iir = std::asin(std::clamp(multiplied.imag() * limited.real() - multiplied.real() * limited.imag(), -1.0, 1.0));
error_total += in_iir;
double error_real = (limited.real() > 0 ? 1.0 : -1.0) * limited.imag();
double error_imag = (limited.imag() > 0 ? 1.0 : -1.0) * limited.real();
double phase_error = error_real - error_imag;
phase_error = 0.5 * (std::abs(phase_error + 1) - std::abs(phase_error - 1));
double out_iir = 1.0001 * in_iir - prev_in_iir + prev_out_iir;
prev_in_iir = in_iir;
prev_out_iir = out_iir;
out_iir_total += out_iir;
freq_error += beta * phase_error;
double phase_adjust = alpha * phase_error + freq_error;
// VCO Block
double in_vco = out_iir + prev_in_vco;
in_vco_total += in_vco;
prev_in_vco = in_vco;
current_phase += 2 * M_PI * carrier_freq / sample_rate + k_factor * phase_adjust;
if (current_phase > M_PI) current_phase -= 2 * M_PI;
else if (current_phase < -M_PI) current_phase += 2 * M_PI;
// Generate feedback signal for next iteration
double feedback_real = std::cos(current_phase);
double feedback_imag = -std::sin(current_phase);
feedback = std::complex<double>(feedback_real, feedback_imag);
current_phase += 2 * M_PI * carrier_freq / sample_rate + k_factor * in_vco;
if (current_phase > 2 * M_PI) current_phase -= 2 * M_PI;
}
return output_signal;
@@ -105,6 +101,9 @@ private:
double in_vco_total;
SRRCFilter srrc_filter;
double vco_gain;
double alpha;
double beta;
double freq_error;
std::complex<double> limiter(const std::complex<double>& sample) const {
double limited_I = std::clamp(sample.real(), -1.0, 1.0);