From e348cd246c6563ea211b7f8e05d3f1d938729df8 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sun, 18 Feb 2024 17:20:12 -0500 Subject: [PATCH] Calc signal strength less often - improve threshold --- lib/op25_repeater/lib/dmr_slot.cc | 20 +++++ .../gr_blocks/signal_detector_cvf.h | 2 + .../gr_blocks/signal_detector_cvf_impl.cc | 75 ++++++++++++++----- .../gr_blocks/signal_detector_cvf_impl.h | 6 +- trunk-recorder/source.cc | 21 ++++-- trunk-recorder/source.h | 2 +- 6 files changed, 99 insertions(+), 27 deletions(-) diff --git a/lib/op25_repeater/lib/dmr_slot.cc b/lib/op25_repeater/lib/dmr_slot.cc index 59a14f8de..a8bcd871c 100644 --- a/lib/op25_repeater/lib/dmr_slot.cc +++ b/lib/op25_repeater/lib/dmr_slot.cc @@ -565,6 +565,10 @@ dmr_slot::decode_vlch(uint8_t* vlch) { // send up the stack std::string lc_msg(12,0); for (int i = 0; i < 12; i++) { + if (d_lc.size() <= i) { + std::cerr << "ERROR: d_lc.size()=" << d_lc.size() << " i=" << i << std::endl; + break; + } lc_msg[i] = d_lc[i]; } send_msg(lc_msg, M_DMR_SLOT_VLC); @@ -594,6 +598,10 @@ dmr_slot::decode_tlc(uint8_t* tlc) { // send up the stack std::string lc_msg(12,0); for (int i = 0; i < 12; i++) { + if (d_lc.size() <= i) { + std::cerr << "ERROR: d_lc.size()=" << d_lc.size() << " i=" << i << std::endl; + break; + } lc_msg[i] = d_lc[i]; } send_msg(lc_msg, M_DMR_SLOT_TLC); @@ -754,6 +762,14 @@ dmr_slot::decode_embedded_lc() { memset(data, 0, 128 * sizeof(bool)); unsigned int b = 0; for (unsigned int a = 0; a < 128; a++) { + if (a >= sizeof(d_emb)) { + std::cerr << "EMB LC data incomplete, size: " << sizeof(d_emb) << std::endl; + break; + } + if (b >= 128) { + std::cerr << "EMB LC data overflow, b: " << b << std::endl; + break; + } data[b] = d_emb[a]; b += 16; if (b > 127) @@ -809,6 +825,10 @@ dmr_slot::decode_embedded_lc() { // send up the stack std::string lc_msg(9,0); for (int i = 0; i < 9; i++) { + if (d_lc.size() <= i) { + std::cerr << "EMB LC data incomplete, size: " << d_lc.size() << std::endl; + break; + } lc_msg[i] = d_lc[i]; } send_msg(lc_msg, M_DMR_SLOT_ELC); diff --git a/trunk-recorder/gr_blocks/signal_detector_cvf.h b/trunk-recorder/gr_blocks/signal_detector_cvf.h index d29c7b948..edbe07ea3 100644 --- a/trunk-recorder/gr_blocks/signal_detector_cvf.h +++ b/trunk-recorder/gr_blocks/signal_detector_cvf.h @@ -62,6 +62,7 @@ struct Detected_Signal { int avg_rssi; int max_rssi; int min_rssi; + int threshold; std::vector rssi; double center_freq; double bandwidth; @@ -105,6 +106,7 @@ class signal_detector_cvf : virtual public gr::sync_decimator float average = 0.8, float quantization = 0.01, float min_bw = 0.0, + float max_bw = 50000, const char* filename = ""); virtual void set_samp_rate(double d_samp_rate) = 0; diff --git a/trunk-recorder/gr_blocks/signal_detector_cvf_impl.cc b/trunk-recorder/gr_blocks/signal_detector_cvf_impl.cc index 84d753e99..652e4283c 100644 --- a/trunk-recorder/gr_blocks/signal_detector_cvf_impl.cc +++ b/trunk-recorder/gr_blocks/signal_detector_cvf_impl.cc @@ -40,6 +40,7 @@ signal_detector_cvf::sptr signal_detector_cvf::make(double samp_rate, float average, float quantization, float min_bw, + float max_bw, const char *filename) { return gnuradio::get_initial_sptr(new signal_detector_cvf_impl(samp_rate, fft_len, @@ -50,9 +51,15 @@ signal_detector_cvf::sptr signal_detector_cvf::make(double samp_rate, average, quantization, min_bw, + max_bw, filename)); } +uint64_t signal_detector_cvf_impl::time_since_epoch_millisec() { + using namespace std::chrono; + return duration_cast(system_clock::now().time_since_epoch()).count(); +} + /* * The private constructor */ @@ -65,6 +72,7 @@ signal_detector_cvf_impl::signal_detector_cvf_impl(double samp_rate, float average, float quantization, float min_bw, + float max_bw, const char *filename) : sync_decimator("signal_detector_cvf", gr::io_signature::make(1, 1, sizeof(gr_complex)), @@ -81,13 +89,18 @@ signal_detector_cvf_impl::signal_detector_cvf_impl(double samp_rate, #endif d_threshold = threshold; d_sensitivity = sensitivity; - d_auto_threshold = true; //auto_threshold; + d_auto_threshold = auto_threshold; d_average = average; d_quantization = quantization; d_min_bw = min_bw; + d_max_bw = max_bw; d_filename = filename; d_detected_signals = std::vector(); + last_conventional_channel_detection_check = time_since_epoch_millisec(); + + BOOST_LOG_TRIVIAL(info) << "signal_detector_cvf_impl: " << "samp_rate: " << samp_rate << " fft_len: " << fft_len << " window_type: " << window_type << " threshold: " << threshold << " sensitivity: " << sensitivity << " auto_threshold: " << auto_threshold << " average: " << average << " quantization: " << quantization << " min_bw: " << min_bw << " filename: " << filename; + BOOST_LOG_TRIVIAL(info) << "signal_detector_cvf_impl: " << "FFT Bucket Size: " << samp_rate / fft_len << " Hz Quatization: " << (int)floor(d_quantization * d_samp_rate); // allocate buffers d_tmpbuf = static_cast(volk_malloc(sizeof(float) * d_fft_len, volk_get_alignment())); @@ -109,6 +122,7 @@ signal_detector_cvf_impl::signal_detector_cvf_impl(double samp_rate, } d_freq = build_freq(); + } /* @@ -215,16 +229,33 @@ void signal_detector_cvf_impl::build_threshold() { memcpy(d_tmp_pxx, d_pxx_out, sizeof(float) * d_fft_len); // sort bins d_threshold = 500; + std::sort(d_tmp_pxx, d_tmp_pxx + d_fft_len); + + float range = d_tmp_pxx[d_fft_len - 1] - d_tmp_pxx[0]; + float median = d_tmp_pxx[d_fft_len / 2]; + + // search specified normized jump - for (unsigned int i = 0; i < d_fft_len; i++) { - if ((d_tmp_pxx[i + 1] - d_tmp_pxx[i]) / range > 1 - d_sensitivity) { + // since we are looking one ahead we want to stop before the end. + for (unsigned int i = 0; i < d_fft_len-1; i++) { + if ((d_tmp_pxx[i + 1] - d_tmp_pxx[i]) / range > 1 - d_sensitivity) { d_threshold = d_tmp_pxx[i]; break; } } + + if (d_threshold == 500) { + /*BOOST_LOG_TRIVIAL(error) << "Could not find threshold - range: " << range << " d_sensitivity: " << d_sensitivity << " Max RSSI: " << d_tmp_pxx[d_fft_len - 1] << " Min RSSI: " << d_tmp_pxx[0]; + for (unsigned int i =0; i < 5; i++) { + BOOST_LOG_TRIVIAL(error) << "RSSI[" << d_tmp_pxx[d_fft_len - 1 - i] << "] change: " << (d_tmp_pxx[d_fft_len - 1 - i] - d_tmp_pxx[d_fft_len - 2 - i]) / range; + }*/ + d_threshold = d_tmp_pxx[d_fft_len - 1]; + } + //BOOST_LOG_TRIVIAL(info) << "Median: " << median << " Range: " << range << " Max RSSI: " << d_tmp_pxx[d_fft_len - 1] << " Min RSSI: " << d_tmp_pxx[0] << " Threshold: " << d_threshold; + } // find bins above threshold and adjacent bins for each signal @@ -266,10 +297,15 @@ std::vector signal_detector_cvf_impl::find_signal_edges() { signal_started = false; double bandwidth = d_freq[signal.end_bin] - d_freq[signal.start_bin]; - signal.bandwidth = quantization * round(bandwidth / quantization); - signal.center_freq = (d_freq[signal.start_bin] + d_freq[signal.end_bin]) / 2; - - detected_signals.push_back(signal); + double quantized_bandwidth = quantization * round(bandwidth / quantization); + signal.bandwidth = quantized_bandwidth; + //BOOST_LOG_TRIVIAL(info) << "Bandwidth: " << bandwidth << " bins: " << d_freq[signal.end_bin] << " - " << d_freq[signal.start_bin] << " Center: " << (d_freq[signal.start_bin] + d_freq[signal.end_bin]) / 2 << " Threshold: " << d_threshold << " RSSI: " << signal.max_rssi << " Quantization: " << quantization << " Rounded Bandwidth: " << quantization * round(bandwidth / quantization) << std::endl; + + if (quantized_bandwidth >= d_min_bw && quantized_bandwidth <= d_max_bw) { + signal.center_freq = (d_freq[signal.start_bin] + d_freq[signal.end_bin]) / 2; + signal.threshold = d_threshold; + detected_signals.push_back(signal); + } } } } @@ -353,19 +389,24 @@ int signal_detector_cvf_impl::work(int noutput_items, const gr_complex *in = (const gr_complex *)input_items[0]; // float* out = (float*)output_items[0]; - periodogram(d_pxx, in); + uint64_t current_time_ms = time_since_epoch_millisec(); + if ((current_time_ms - last_conventional_channel_detection_check) >= 100.0) { //0.05) { - // averaging - for (unsigned int i = 0; i < d_fft_len; i++) { - d_pxx_out[i] = d_avg_filter[i].filter(d_pxx[i]); - } + periodogram(d_pxx, in); - if (d_auto_threshold) { - build_threshold(); - } + // averaging + for (unsigned int i = 0; i < d_fft_len; i++) { + d_pxx_out[i] = d_avg_filter[i].filter(d_pxx[i]); + } - gr::thread::scoped_lock guard(d_mutex); - d_detected_signals = find_signal_edges(); + if (d_auto_threshold) { + build_threshold(); + } + + gr::thread::scoped_lock guard(d_mutex); + d_detected_signals = find_signal_edges(); + last_conventional_channel_detection_check = current_time_ms; + } // BOOST_LOG_TRIVIAL(info) << "d_detected_signals.size() = " << d_detected_signals.size() << std::endl; return 1; // one vector has been processed diff --git a/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h b/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h index f73348f36..5583b0c9d 100644 --- a/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h +++ b/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h @@ -37,7 +37,7 @@ class signal_detector_cvf_impl : public signal_detector_cvf { bool d_auto_threshold; unsigned int d_fft_len; unsigned int d_tmpbuflen; - float d_threshold, d_sensitivity, d_average, d_quantization, d_min_bw; + float d_threshold, d_sensitivity, d_average, d_quantization, d_min_bw, d_max_bw; float *d_pxx, *d_tmp_pxx, *d_pxx_out, *d_tmpbuf; double d_samp_rate; @@ -47,7 +47,7 @@ class signal_detector_cvf_impl : public signal_detector_cvf { #else gr::fft::window::win_type d_window_type; #endif - + uint64_t last_conventional_channel_detection_check; std::vector d_window; std::vector> d_signal_edges; std::vector> d_rf_map; @@ -59,6 +59,7 @@ class signal_detector_cvf_impl : public signal_detector_cvf { #endif std::vector d_freq; const char *d_filename; + uint64_t time_since_epoch_millisec(); public: signal_detector_cvf_impl(double samp_rate, @@ -70,6 +71,7 @@ class signal_detector_cvf_impl : public signal_detector_cvf { float average, float quantization, float min_bw, + float max_bw, const char *filename); ~signal_detector_cvf_impl(); diff --git a/trunk-recorder/source.cc b/trunk-recorder/source.cc index 133734a62..1db10341c 100644 --- a/trunk-recorder/source.cc +++ b/trunk-recorder/source.cc @@ -67,7 +67,11 @@ Source::Source(double c, double r, double e, std::string drv, std::string dev, C next_selector_port = 0; recorder_selector = gr::blocks::selector::make(sizeof(gr_complex), 0, 0); - signal_detector = signal_detector_cvf::make(rate, 1024, 0, -45, 0.8, false, 0.8, 0.01, 0.0, ""); + float threshold_sensitivity = 0.95; + if (rate > 3000000) { + threshold_sensitivity = 0.95; + } + signal_detector = signal_detector_cvf::make(rate, 1024, 0, -45, threshold_sensitivity, true, 0.8, 0.01, 0.0, 50000, ""); BOOST_LOG_TRIVIAL(info) << "Made the Signal Detector"; if (driver == "osmosdr") { @@ -219,7 +223,6 @@ void Source::attach_selector(gr::top_block_sptr tb) { void Source::attach_detector(gr::top_block_sptr tb) { if (!attached_detector) { attached_detector = true; - signal_detector = signal_detector_cvf::make(rate, 1024, 0, -45, 0.8, false, 0.8, 0.01, 0.0, ""); tb->connect(source_block, 0, signal_detector, 0); } } @@ -360,9 +363,11 @@ int Source::get_if_gain() { /* -- Recorders -- */ -std::vector Source::find_conventional_recorders_by_freq(double freq) { +std::vector Source::find_conventional_recorders_by_freq(Detected_Signal signal) { + double freq = center + signal.center_freq; + double bandwidth = signal.bandwidth; std::vector recorders; - long max_freq_diff = 5000; + long max_freq_diff = 12500; for (std::vector::iterator it = digital_conv_recorders.begin(); it != digital_conv_recorders.end(); it++) { p25_recorder_sptr rx = *it; double recorder_freq = rx->get_freq(); @@ -401,11 +406,13 @@ std::vector Source::get_detected_recorders() { for (std::vector::iterator it = signals.begin(); it != signals.end(); it++) { Detected_Signal signal = *it; - float freq = center + signal.center_freq; - // float bandwidth = signal.bandwidth; // available data but not needed for anything + double freq = center + signal.center_freq; + double bandwidth = signal.bandwidth; // available data but not needed for anything float rssi = signal.max_rssi; - std::vector recorders = find_conventional_recorders_by_freq(freq); + + + std::vector recorders = find_conventional_recorders_by_freq(signal); for (std::vector::iterator it = recorders.begin(); it != recorders.end(); it++) { Recorder *recorder = *it; if (!recorder->is_enabled()) { diff --git a/trunk-recorder/source.h b/trunk-recorder/source.h index 08f0c060b..6f34d8d11 100644 --- a/trunk-recorder/source.h +++ b/trunk-recorder/source.h @@ -129,7 +129,7 @@ class Source { int get_num_available_analog_recorders(); int get_num_available_digital_recorders(); void set_signal_detector_threshold(float t); - std::vector find_conventional_recorders_by_freq(double freq); + std::vector find_conventional_recorders_by_freq(Detected_Signal ds); std::vector get_detected_recorders(); void set_selector_port_enabled(unsigned int port, bool enabled); bool is_selector_port_enabled(unsigned int port);