Added fft relock on demand
This commit is contained in:
parent
645bc3463f
commit
66665622bc
|
@ -42,6 +42,8 @@ CostasBeaconSync::CostasBeaconSync(float loop_bw,
|
||||||
loop_freq = 0.0;
|
loop_freq = 0.0;
|
||||||
loop_phase = 0.0;
|
loop_phase = 0.0;
|
||||||
|
|
||||||
|
locked = false;
|
||||||
|
|
||||||
bandpass = firfilt_crcf_create(bandpass_taps, banpass_len);
|
bandpass = firfilt_crcf_create(bandpass_taps, banpass_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +59,8 @@ std::complex<float> CostasBeaconSync::work(std::complex<float> in) {
|
||||||
|
|
||||||
float error = costas_sample.imag() * costas_sample.real();
|
float error = costas_sample.imag() * costas_sample.real();
|
||||||
|
|
||||||
|
locked = std::abs(error) < 0.001;
|
||||||
|
|
||||||
loop_freq += beta * error;
|
loop_freq += beta * error;
|
||||||
loop_phase += loop_freq + alpha * error;
|
loop_phase += loop_freq + alpha * error;
|
||||||
|
|
||||||
|
@ -73,6 +77,10 @@ std::complex<float> CostasBeaconSync::work(std::complex<float> in) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CostasBeaconSync::has_lock() {
|
||||||
|
return locked;
|
||||||
|
}
|
||||||
|
|
||||||
CostasBeaconSync::~CostasBeaconSync() {
|
CostasBeaconSync::~CostasBeaconSync() {
|
||||||
firfilt_crcf_destroy(bandpass);
|
firfilt_crcf_destroy(bandpass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,15 @@ class CostasBeaconSync {
|
||||||
|
|
||||||
firfilt_crcf bandpass;
|
firfilt_crcf bandpass;
|
||||||
|
|
||||||
|
bool locked;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CostasBeaconSync(float, float, float);
|
CostasBeaconSync(float, float, float);
|
||||||
~CostasBeaconSync();
|
~CostasBeaconSync();
|
||||||
|
|
||||||
std::complex<float> work(liquid_float_complex);
|
std::complex<float> work(liquid_float_complex);
|
||||||
|
|
||||||
|
bool has_lock();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,10 +15,12 @@ FFTBeaconFinder::FFTBeaconFinder(int samplingrate) {
|
||||||
|
|
||||||
last_center = 0;
|
last_center = 0;
|
||||||
last_center_level = 0.0;
|
last_center_level = 0.0;
|
||||||
|
|
||||||
|
has_sync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::complex<float> FFTBeaconFinder::work(std::complex<float> in) {
|
std::complex<float> FFTBeaconFinder::work(std::complex<float> in) {
|
||||||
if (next_fft_in <= 0) {
|
if (next_fft_in <= 0 && !has_sync) {
|
||||||
fft_in[pos] = in;
|
fft_in[pos] = in;
|
||||||
pos += 1;
|
pos += 1;
|
||||||
if (pos == FFT_LEN) {
|
if (pos == FFT_LEN) {
|
||||||
|
@ -44,11 +46,13 @@ std::complex<float> FFTBeaconFinder::work(std::complex<float> in) {
|
||||||
int max_center = 0;
|
int max_center = 0;
|
||||||
for (int bin = -50; bin <= 50; bin++) {
|
for (int bin = -50; bin <= 50; bin++) {
|
||||||
int center_idx = spectral_bin_to_fft_idx(bin);
|
int center_idx = spectral_bin_to_fft_idx(bin);
|
||||||
float center_val = std::abs(fft_out[center_idx]) / fft_max;
|
float center_val =
|
||||||
|
std::abs(fft_out[center_idx]) / fft_max;
|
||||||
if (center_val > 0.25) {
|
if (center_val > 0.25) {
|
||||||
int left_idx = spectral_bin_to_fft_idx(bin - 127);
|
int left_idx = spectral_bin_to_fft_idx(bin - 127);
|
||||||
int right_idx = spectral_bin_to_fft_idx(bin + 127);
|
int right_idx = spectral_bin_to_fft_idx(bin + 127);
|
||||||
float left_val = std::abs(fft_out[left_idx]) / fft_max;
|
float left_val =
|
||||||
|
std::abs(fft_out[left_idx]) / fft_max;
|
||||||
float right_val =
|
float right_val =
|
||||||
std::abs(fft_out[right_idx]) / fft_max;
|
std::abs(fft_out[right_idx]) / fft_max;
|
||||||
|
|
||||||
|
@ -56,7 +60,8 @@ std::complex<float> FFTBeaconFinder::work(std::complex<float> in) {
|
||||||
<< center_val << " | " << right_val
|
<< center_val << " | " << right_val
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
if (center_val + left_val + right_val > max_levels) {
|
if (center_val + left_val + right_val >
|
||||||
|
max_levels) {
|
||||||
max_levels = center_val + left_val + right_val;
|
max_levels = center_val + left_val + right_val;
|
||||||
max_center = bin;
|
max_center = bin;
|
||||||
}
|
}
|
||||||
|
@ -74,16 +79,18 @@ std::complex<float> FFTBeaconFinder::work(std::complex<float> in) {
|
||||||
|
|
||||||
std::cout << "New center " << center_freq << " "
|
std::cout << "New center " << center_freq << " "
|
||||||
<< max_center << std::endl;
|
<< max_center << std::endl;
|
||||||
|
has_sync = true;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "No center found!" << std::endl;
|
std::cout << "No center found!" << std::endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Last center still valid" << std::endl;
|
std::cout << "Last center still valid" << std::endl;
|
||||||
|
has_sync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
next_fft_in = samplingrate / 4;
|
next_fft_in = samplingrate / 4;
|
||||||
}
|
}
|
||||||
} else {
|
} else if(next_fft_in > 0){
|
||||||
next_fft_in--;
|
next_fft_in--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +113,10 @@ int FFTBeaconFinder::spectral_bin_to_fft_idx(int bin) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FFTBeaconFinder::reset_sync() {
|
||||||
|
has_sync = false;
|
||||||
|
}
|
||||||
|
|
||||||
FFTBeaconFinder::~FFTBeaconFinder() {
|
FFTBeaconFinder::~FFTBeaconFinder() {
|
||||||
nco_crcf_destroy(coarse_correction);
|
nco_crcf_destroy(coarse_correction);
|
||||||
fft_destroy_plan(fft);
|
fft_destroy_plan(fft);
|
||||||
|
|
|
@ -23,12 +23,16 @@ class FFTBeaconFinder {
|
||||||
int last_center;
|
int last_center;
|
||||||
float last_center_level;
|
float last_center_level;
|
||||||
|
|
||||||
|
bool has_sync;
|
||||||
|
|
||||||
int spectral_bin_to_fft_idx(int);
|
int spectral_bin_to_fft_idx(int);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FFTBeaconFinder(int);
|
FFTBeaconFinder(int);
|
||||||
~FFTBeaconFinder();
|
~FFTBeaconFinder();
|
||||||
|
|
||||||
|
void reset_sync();
|
||||||
|
|
||||||
std::complex<float> work(std::complex<float>);
|
std::complex<float> work(std::complex<float>);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ blocks:
|
||||||
alias: ''
|
alias: ''
|
||||||
amp: '1'
|
amp: '1'
|
||||||
comment: ''
|
comment: ''
|
||||||
freq: '0.1'
|
freq: '0.01'
|
||||||
maxoutbuf: '0'
|
maxoutbuf: '0'
|
||||||
minoutbuf: '0'
|
minoutbuf: '0'
|
||||||
offset: '0'
|
offset: '0'
|
||||||
|
@ -158,7 +158,7 @@ blocks:
|
||||||
alias: ''
|
alias: ''
|
||||||
amp: '1'
|
amp: '1'
|
||||||
comment: ''
|
comment: ''
|
||||||
freq: '-10000'
|
freq: '-35000'
|
||||||
maxoutbuf: '0'
|
maxoutbuf: '0'
|
||||||
minoutbuf: '0'
|
minoutbuf: '0'
|
||||||
offset: '0'
|
offset: '0'
|
||||||
|
|
|
@ -15,6 +15,8 @@ int main(int argc, char const* argv[]) {
|
||||||
FFTBeaconFinder finder(1000000);
|
FFTBeaconFinder finder(1000000);
|
||||||
CostasBeaconSync sync(0.03, -0.1, 0.1);
|
CostasBeaconSync sync(0.03, -0.1, 0.1);
|
||||||
|
|
||||||
|
bool locked = false;
|
||||||
|
|
||||||
int sample_count = 0;
|
int sample_count = 0;
|
||||||
clock_t start_time = clock();
|
clock_t start_time = clock();
|
||||||
|
|
||||||
|
@ -25,8 +27,13 @@ int main(int argc, char const* argv[]) {
|
||||||
fread(in_buffer, sizeof(std::complex<float>), buffer_size, input);
|
fread(in_buffer, sizeof(std::complex<float>), buffer_size, input);
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
std::complex<float> coarse_synced = finder.work(in_buffer[i]);
|
std::complex<float> coarse_synced =
|
||||||
|
finder.work(in_buffer[i]);
|
||||||
std::complex<float> sync_correction = sync.work(coarse_synced);
|
std::complex<float> sync_correction = sync.work(coarse_synced);
|
||||||
|
if(!sync.has_lock()) {
|
||||||
|
//std::cout << "Resetting lock" << std::endl;
|
||||||
|
finder.reset_sync();
|
||||||
|
}
|
||||||
out_buffer[i] = coarse_synced * sync_correction;
|
out_buffer[i] = coarse_synced * sync_correction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue