From 673bbe3c3fb6588054513384489d9d57f9be2aa0 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sat, 9 Mar 2024 17:16:57 -0500 Subject: [PATCH] Support for: - Per channel turning on/off signal detection - Per Source setting signal detection threshold or using auto detection - Per conventional call signal/noise in JSON / Call Info - Per conventional call freq_error in JSON / Call Info --- docs/CONFIGURE.md | 3 +++ trunk-recorder/call.h | 1 + .../call_concluder/call_concluder.cc | 8 +++++++ trunk-recorder/call_conventional.cc | 12 +++++++--- trunk-recorder/call_conventional.h | 4 +++- trunk-recorder/call_impl.cc | 15 ++++++++---- trunk-recorder/call_impl.h | 2 ++ trunk-recorder/config.cc | 4 ++++ trunk-recorder/global_structs.h | 5 ++++ trunk-recorder/gr_blocks/channelizer.cc | 12 +++------- trunk-recorder/gr_blocks/channelizer.h | 3 --- .../gr_blocks/signal_detector_cvf_impl.h | 1 + trunk-recorder/gr_blocks/xlat_channelizer.cc | 15 +----------- trunk-recorder/gr_blocks/xlat_channelizer.h | 4 +--- trunk-recorder/recorders/analog_recorder.cc | 19 +++++++++++---- trunk-recorder/recorders/analog_recorder.h | 1 + trunk-recorder/recorders/dmr_recorder.h | 1 + trunk-recorder/recorders/dmr_recorder_impl.cc | 20 +++++++++++----- trunk-recorder/recorders/dmr_recorder_impl.h | 1 + trunk-recorder/recorders/p25_recorder_impl.cc | 17 +++++++------ trunk-recorder/recorders/recorder.h | 1 + trunk-recorder/recorders/sigmf_recorder.h | 1 + .../recorders/sigmf_recorder_impl.cc | 24 ++++++++++++------- .../recorders/sigmf_recorder_impl.h | 1 + trunk-recorder/setup_systems.cc | 9 ++++--- trunk-recorder/source.cc | 5 ++-- trunk-recorder/source.h | 1 - trunk-recorder/systems/p25_trunking.cc | 2 +- trunk-recorder/systems/smartnet_trunking.cc | 6 +---- trunk-recorder/talkgroup.cc | 2 +- trunk-recorder/talkgroup.h | 1 + trunk-recorder/talkgroups.cc | 18 +++++++------- 32 files changed, 135 insertions(+), 84 deletions(-) diff --git a/docs/CONFIGURE.md b/docs/CONFIGURE.md index a76c77c6e..ba668787c 100644 --- a/docs/CONFIGURE.md +++ b/docs/CONFIGURE.md @@ -156,6 +156,7 @@ There is a list of available Plugins [here](./Plugins.md). | gain | ✓ | | number | The RF gain setting for the SDR. Use a program like GQRX to find a good value. | | digitalRecorders | | | number | The number of Digital Recorders to have attached to this source. This is essentially the number of simultaneous calls you can record at the same time in the frequency range that this Source will be tuned to. It is limited by the CPU power of the machine. Some experimentation might be needed to find the appropriate number. *This is only required for Trunk systems. Channels in Conventional systems have dedicated recorders and do not need to be included here.* | | analogRecorders | | | number | The number of Analog Recorder to have attached to this source. The same as Digital Recorders except for Analog Voice channels. *This is only required for Trunk systems. Channels in Conventional systems have dedicated recorders and do not need to be included here.* | +| signalDetectorThreshold | | | number | If set, a static threshold will be used for the Signal Detector on all conventional recorder. Otherwise, the threshold value for the noise floor will be automatically be determined. Only set this is you are having problems. The value is in dB, but is generally higher than the Squelch value because the power is measured differently | | ppm | | 0 | number | The tuning error for the SDR in ppm (parts per million), as an alternative to `error` above. Use a program like GQRX to find an accurate value. | | agc | | false | **true** / **false** | Whether or not to enable the SDR's automatic gain control (if supported). This is false by default. It is not recommended to set this as it often yields worse performance compared to a manual gain setting. | | gainSettings | | | { "stageName": value} | Set the gain for any stage. The value for this setting should be passed as an object, where the key specifies the name of the gain stage and the value is the amount of gain, as an int. For example:
````"gainSettings": { "IF": 10, "BB": 11},```` | @@ -495,6 +496,8 @@ This file allows for you to specify additional information about conventional ch | Tag | | The Service Tag for the Talkgroup | | Comment | | Use this field to capture comments about a talkgroup. It will be ignored by Trunk Recorder. | | Enable | | Set to 'false' if you do not want this talkgroup/channel to created | +| Signal Detector | | Set to `false` if you do not want to use the Signal Detector for this channel. The Signal Detector scans a source's bandwidth and only enables a channel if a signal over a threshold is detected. If it not used, the channel will always be enabled and the Squelch will be running which uses more CPU. Default is `true`| +| Squelch | | Value in dB to use for the Squelch for this channel. If this is not set then the System Squelch value will be used instead. | The **Enable** Column is optional and defaults to *True*. It only needs to be added to rows that you do not want to have recorded. For those rows, set **Enable** to *False*. diff --git a/trunk-recorder/call.h b/trunk-recorder/call.h index 7fafd3231..2b112e097 100644 --- a/trunk-recorder/call.h +++ b/trunk-recorder/call.h @@ -76,6 +76,7 @@ class Call { virtual bool get_duplex() = 0; virtual double get_signal() = 0; virtual double get_noise() = 0; + virtual int get_freq_error() = 0; virtual void set_signal(double s) = 0; virtual void set_noise(double n) = 0; virtual std::string get_talkgroup_display() = 0; diff --git a/trunk-recorder/call_concluder/call_concluder.cc b/trunk-recorder/call_concluder/call_concluder.cc index 8c2de4082..0295e0748 100644 --- a/trunk-recorder/call_concluder/call_concluder.cc +++ b/trunk-recorder/call_concluder/call_concluder.cc @@ -60,6 +60,11 @@ int create_call_json(Call_Data_t& call_info) { nlohmann::ordered_json json_data = { {"freq", int(call_info.freq)}, + {"freq_error", int(call_info.freq_error)}, + {"signal", int(call_info.signal)}, + {"noise", int(call_info.noise)}, + {"tdma_slot", int(call_info.tdma_slot)}, + {"phase2_tdma", int(call_info.phase2_tdma)}, {"start_time", call_info.start_time}, {"stop_time", call_info.stop_time}, {"emergency", int(call_info.emergency)}, @@ -298,6 +303,9 @@ Call_Data_t Call_Concluder::create_call_data(Call *call, System *sys, Config con call_info.error_count = 0; call_info.spike_count = 0; call_info.freq = call->get_freq(); + call_info.freq_error = call->get_freq_error(); + call_info.signal = call->get_signal(); + call_info.noise = call->get_noise(); call_info.encrypted = call->get_encrypted(); call_info.emergency = call->get_emergency(); call_info.priority = call->get_priority(); diff --git a/trunk-recorder/call_conventional.cc b/trunk-recorder/call_conventional.cc index 3c8db38b1..252cf6712 100644 --- a/trunk-recorder/call_conventional.cc +++ b/trunk-recorder/call_conventional.cc @@ -4,15 +4,17 @@ #include "recorders/recorder.h" #include -Call_conventional::Call_conventional(long t, double f, System *s, Config c, double squelch_db) : Call_impl(t, f, s, c) { +Call_conventional::Call_conventional(long t, double f, System *s, Config c, double squelch_db, bool signal_detection) : Call_impl(t, f, s, c) { this->squelch_db = squelch_db; + this->signal_detection = signal_detection; + BOOST_LOG_TRIVIAL(info) << "[" << sys->get_short_name() << "]\tFreq: " << format_freq(f) << "\tSquelch: " << squelch_db << " dB\tSignal Detection: " << signal_detection; } void Call_conventional::restart_call() { call_num = call_counter++; idle_count = 0; - signal = 999; - noise = 999; + signal = DB_UNSET; + noise = DB_UNSET; curr_src_id = -1; start_time = time(NULL); stop_time = time(NULL); @@ -43,4 +45,8 @@ void Call_conventional::recording_started() { double Call_conventional::get_squelch_db() { return squelch_db; +} + +bool Call_conventional::get_signal_detection() { + return signal_detection; } \ No newline at end of file diff --git a/trunk-recorder/call_conventional.h b/trunk-recorder/call_conventional.h index 625db94d6..245a53ddd 100644 --- a/trunk-recorder/call_conventional.h +++ b/trunk-recorder/call_conventional.h @@ -10,15 +10,17 @@ class Recorder; class Call_conventional : public Call_impl { public: - Call_conventional(long t, double f, System *s, Config c, double squelch_db); + Call_conventional(long t, double f, System *s, Config c, double squelch_db, bool signal_detection); time_t get_start_time(); bool is_conventional() { return true; } void restart_call(); void set_recorder(Recorder *r); void recording_started(); double get_squelch_db(); + bool get_signal_detection(); private: double squelch_db; + bool signal_detection; }; #endif diff --git a/trunk-recorder/call_impl.cc b/trunk-recorder/call_impl.cc index b79202c0f..962986965 100644 --- a/trunk-recorder/call_impl.cc +++ b/trunk-recorder/call_impl.cc @@ -30,11 +30,12 @@ Call *Call::make(TrunkMessage message, System *s, Config c) { Call_impl::Call_impl(long t, double f, System *s, Config c) { config = c; call_num = call_counter++; - noise = 999; - signal = 999; + noise = + signal = DB_UNSET; final_length = 0; idle_count = 0; curr_freq = 0; + freq_error = 0; curr_src_id = -1; talkgroup = t; sys = s; @@ -62,12 +63,13 @@ Call_impl::Call_impl(long t, double f, System *s, Config c) { Call_impl::Call_impl(TrunkMessage message, System *s, Config c) { config = c; call_num = call_counter++; - noise = 999; - signal = 999; + noise = DB_UNSET; + signal = DB_UNSET; final_length = 0; idle_count = 0; curr_src_id = -1; curr_freq = 0; + freq_error = 0; talkgroup = message.talkgroup; sys = s; start_time = time(NULL); @@ -146,6 +148,7 @@ void Call_impl::conclude_call() { if (was_update) { BOOST_LOG_TRIVIAL(info) << "[" << sys->get_short_name() << "]\t\033[0;34m" << this->get_call_num() << "C\033[0m\tTG: " << this->get_talkgroup_display() << "\tFreq: " << format_freq(get_freq()) << "\t\u001b[33mCall was UPDATE not GRANT\u001b[0m"; } + freq_error = this->get_recorder()->get_freq_error(); this->get_recorder()->stop(); transmission_list = this->get_recorder()->get_transmission_list(); if (this->get_sigmf_recording() == true) { @@ -189,6 +192,10 @@ double Call_impl::get_freq() { return curr_freq; } +int Call_impl::get_freq_error() { + return freq_error; +} + double Call_impl::get_final_length() { return final_length; } diff --git a/trunk-recorder/call_impl.h b/trunk-recorder/call_impl.h index 7f5588e7d..5b2dbe795 100644 --- a/trunk-recorder/call_impl.h +++ b/trunk-recorder/call_impl.h @@ -78,6 +78,7 @@ class Call_impl : public Call { bool get_duplex(); double get_signal(); double get_noise(); + int get_freq_error(); void set_signal(double s); void set_noise(double n); std::string get_talkgroup_display(); @@ -102,6 +103,7 @@ class Call_impl : public Call { double curr_freq; double noise; double signal; + int freq_error; std::vector transmission_list; System *sys; std::string short_name; diff --git a/trunk-recorder/config.cc b/trunk-recorder/config.cc index a6952aaa4..98c9bddc7 100644 --- a/trunk-recorder/config.cc +++ b/trunk-recorder/config.cc @@ -515,6 +515,10 @@ bool load_config(string config_file, Config &config, gr::top_block_sptr &tb, std source->set_gain_mode(agc); } + if (element.contains("signalDetectorThreshold")) { + source->set_signal_detector_threshold(element["signalDetectorThreshold"]); + } + if (element.contains("gainSettings")) { for (auto it = element["gainSettings"].begin(); it != element["gainSettings"].end(); ++it) { diff --git a/trunk-recorder/global_structs.h b/trunk-recorder/global_structs.h index 427328342..39ba8a4c0 100644 --- a/trunk-recorder/global_structs.h +++ b/trunk-recorder/global_structs.h @@ -5,6 +5,8 @@ #include #include +const int DB_UNSET = 999; + struct Transmission { long source; long start_time; @@ -96,6 +98,9 @@ struct Call_Data_t { std::string talkgroup_group; long call_num; double freq; + int freq_error; + double signal; + double noise; long start_time; long stop_time; long error_count; diff --git a/trunk-recorder/gr_blocks/channelizer.cc b/trunk-recorder/gr_blocks/channelizer.cc index 92729e9bb..6b7cffb31 100644 --- a/trunk-recorder/gr_blocks/channelizer.cc +++ b/trunk-recorder/gr_blocks/channelizer.cc @@ -55,8 +55,6 @@ channelizer::channelizer(double input_rate, int samples_per_symbol, double symbo double resampled_rate; const float pi = M_PI; - valve = gr::blocks::copy::make(sizeof(gr_complex)); - valve->set_enabled(false); lo = gr::analog::sig_source_c::make(d_input_rate, gr::analog::GR_SIN_WAVE, 0, 1.0, 0.0); mixer = gr::blocks::multiply_cc::make(); @@ -147,13 +145,13 @@ channelizer::channelizer(double input_rate, int samples_per_symbol, double symbo rms_agc = gr::blocks::rms_agc::make(0.45, 0.85); fll_band_edge = gr::digital::fll_band_edge_cc::make(sps, def_excess_bw, 2 * sps + 1, (2.0 * pi) / sps / 250); // OP25 has this set to 350 instead of 250 - connect(self(), 0, valve, 0); + if (double_decim) { - connect(valve, 0, bandpass_filter, 0); + connect(self(), 0, bandpass_filter, 0); connect(bandpass_filter, 0, mixer, 0); connect(bfo, 0, mixer, 1); } else { - connect(valve, 0, mixer, 0); + connect(self(), 0, mixer, 0); connect(lo, 0, mixer, 1); } connect(mixer, 0, lowpass_filter, 0); @@ -218,10 +216,6 @@ void channelizer::tune_offset(double f) { } } -void channelizer::set_enabled(bool enabled) { - valve->set_enabled(enabled); -} - void channelizer::set_squelch_db(double squelch_db) { squelch->set_threshold(squelch_db); } diff --git a/trunk-recorder/gr_blocks/channelizer.h b/trunk-recorder/gr_blocks/channelizer.h index b769aa765..acfcd7b1d 100644 --- a/trunk-recorder/gr_blocks/channelizer.h +++ b/trunk-recorder/gr_blocks/channelizer.h @@ -54,7 +54,6 @@ class channelizer : public gr::hier_block2 { std::vector cutoff_filter_coeffs; gr::analog::pwr_squelch_cc::sptr squelch; - gr::blocks::copy::sptr valve; gr::digital::fll_band_edge_cc::sptr fll_band_edge; gr::blocks::rms_agc::sptr rms_agc; @@ -88,12 +87,10 @@ class channelizer : public gr::hier_block2 { static constexpr double smartnet_symbol_rate = 3600; int get_freq_error(); - bool is_enabled(); bool is_squelched(); double get_pwr(); void tune_offset(double f); void set_samples_per_symbol(int samples_per_symbol); - void set_enabled(bool enabled); void set_squelch_db(double squelch_db); void set_analog_squelch(bool analog_squelch); }; diff --git a/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h b/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h index 5583b0c9d..67facba15 100644 --- a/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h +++ b/trunk-recorder/gr_blocks/signal_detector_cvf_impl.h @@ -102,6 +102,7 @@ class signal_detector_cvf_impl : public signal_detector_cvf { void set_window_type(int d_window); void set_threshold(float d_threshold) { + d_auto_threshold = false; signal_detector_cvf_impl::d_threshold = d_threshold; } diff --git a/trunk-recorder/gr_blocks/xlat_channelizer.cc b/trunk-recorder/gr_blocks/xlat_channelizer.cc index e14ec7003..e1aef3bb4 100644 --- a/trunk-recorder/gr_blocks/xlat_channelizer.cc +++ b/trunk-recorder/gr_blocks/xlat_channelizer.cc @@ -54,8 +54,6 @@ xlat_channelizer::xlat_channelizer(double input_rate, int samples_per_symbol, do // long if_rate = 12500; const float pi = M_PI; - valve = gr::blocks::copy::make(sizeof(gr_complex)); - valve->set_enabled(false); int decimation = floor(input_rate / channel_rate); double resampled_rate = float(input_rate) / float(decimation); @@ -126,9 +124,6 @@ xlat_channelizer::xlat_channelizer(double input_rate, int samples_per_symbol, do rms_agc = gr::blocks::rms_agc::make(0.45, 0.85); fll_band_edge = gr::digital::fll_band_edge_cc::make(sps, def_excess_bw, 2 * sps + 1, (2.0 * pi) / sps / 250); // OP25 has this set to 350 instead of 250 - /* - connect(self(), 0, valve, 0); - connect(valve, 0, freq_xlat, 0);*/ connect(self(), 0, freq_xlat, 0); if (d_conventional) { @@ -167,7 +162,7 @@ double xlat_channelizer::get_pwr() { if (d_conventional) { return squelch->get_pwr(); } else { - return 999; + return DB_UNSET; } } @@ -179,14 +174,6 @@ void xlat_channelizer::tune_offset(double f) { freq_xlat->set_center_freq(-freq); } -bool xlat_channelizer::is_enabled() { - return valve->enabled(); -} - -void xlat_channelizer::set_enabled(bool enabled) { - valve->set_enabled(enabled); -} - void xlat_channelizer::set_squelch_db(double squelch_db) { squelch->set_threshold(squelch_db); } diff --git a/trunk-recorder/gr_blocks/xlat_channelizer.h b/trunk-recorder/gr_blocks/xlat_channelizer.h index 2e3db5a9b..feae43cef 100644 --- a/trunk-recorder/gr_blocks/xlat_channelizer.h +++ b/trunk-recorder/gr_blocks/xlat_channelizer.h @@ -29,6 +29,7 @@ #endif #include "../formatter.h" +#include "../global_structs.h" class xlat_channelizer : public gr::hier_block2 { public: @@ -54,12 +55,10 @@ class xlat_channelizer : public gr::hier_block2 { static constexpr double smartnet_symbol_rate = 3600; int get_freq_error(); - bool is_enabled(); bool is_squelched(); double get_pwr(); void tune_offset(double f); void set_samples_per_symbol(int samples_per_symbol); - void set_enabled(bool enabled); void set_squelch_db(double squelch_db); void set_analog_squelch(bool analog_squelch); @@ -86,7 +85,6 @@ class xlat_channelizer : public gr::hier_block2 { std::vector cutoff_filter_coeffs; gr::analog::pwr_squelch_cc::sptr squelch; - gr::blocks::copy::sptr valve; gr::digital::fll_band_edge_cc::sptr fll_band_edge; gr::blocks::rms_agc::sptr rms_agc; diff --git a/trunk-recorder/recorders/analog_recorder.cc b/trunk-recorder/recorders/analog_recorder.cc index 9511be547..eb2b776c8 100644 --- a/trunk-recorder/recorders/analog_recorder.cc +++ b/trunk-recorder/recorders/analog_recorder.cc @@ -289,6 +289,10 @@ double analog_recorder::get_freq() { return chan_freq; } +int analog_recorder::get_freq_error() { // get frequency error from FLL and convert to Hz + return prefilter->get_freq_error(); +} + void analog_recorder::set_source(long src) { wav_sink->set_source(src); } @@ -350,9 +354,8 @@ bool analog_recorder::start(Call *call) { talkgroup = call->get_talkgroup(); chan_freq = call->get_freq(); - Call_conventional *conventional_call = dynamic_cast(call); - squelch_db = conventional_call->get_squelch_db(); - prefilter->set_squelch_db(squelch_db); + + BOOST_LOG_TRIVIAL(info) << "[" << call->get_short_name() << "]\t\033[0;34m" << call->get_call_num() << "C\033[0m\tTG: " << this->call->get_talkgroup_display() << "\tFreq: " << format_freq(chan_freq) << "\t\u001b[32mStarting Analog Recorder Num [" << rec_num << "]\u001b[0m \tSquelch: " << squelch_db; // BOOST_LOG_TRIVIAL(error) << "Setting squelch to: " << squelch_db << " block says: " << squelch->threshold(); @@ -371,10 +374,18 @@ bool analog_recorder::start(Call *call) { state = ACTIVE; if (conventional) { - set_enabled(false); + Call_conventional *conventional_call = dynamic_cast(call); + squelch_db = conventional_call->get_squelch_db(); + if (conventional_call->get_signal_detection()) { + set_enabled(false); + } else { + set_enabled(true); // If signal detection is not being used, open up the Value/Selector from the start + } } else { + squelch_db = system->get_squelch_db(); set_enabled(true); } + prefilter->set_squelch_db(squelch_db); return true; } diff --git a/trunk-recorder/recorders/analog_recorder.h b/trunk-recorder/recorders/analog_recorder.h index fdabbf86d..13f3aa0cc 100644 --- a/trunk-recorder/recorders/analog_recorder.h +++ b/trunk-recorder/recorders/analog_recorder.h @@ -80,6 +80,7 @@ class analog_recorder : public gr::hier_block2, public Recorder { bool start(Call *call); void stop(); double get_freq(); + int get_freq_error(); void set_source(long src); Source *get_source(); long get_talkgroup(); diff --git a/trunk-recorder/recorders/dmr_recorder.h b/trunk-recorder/recorders/dmr_recorder.h index cf8118f45..ef95f03ec 100644 --- a/trunk-recorder/recorders/dmr_recorder.h +++ b/trunk-recorder/recorders/dmr_recorder.h @@ -37,6 +37,7 @@ class dmr_recorder : virtual public gr::hier_block2, virtual public Recorder { virtual bool start(Call *call) = 0; virtual void stop() = 0; virtual double get_freq() = 0; + virtual int get_freq_error() = 0; virtual int get_num() = 0; virtual void set_tdma(bool phase2) = 0; virtual void switch_tdma(bool phase2) = 0; diff --git a/trunk-recorder/recorders/dmr_recorder_impl.cc b/trunk-recorder/recorders/dmr_recorder_impl.cc index 46d4713a8..cbc322637 100644 --- a/trunk-recorder/recorders/dmr_recorder_impl.cc +++ b/trunk-recorder/recorders/dmr_recorder_impl.cc @@ -193,6 +193,10 @@ double dmr_recorder_impl::get_freq() { return chan_freq; } +int dmr_recorder_impl::get_freq_error() { // get frequency error from FLL and convert to Hz + return prefilter->get_freq_error(); +} + double dmr_recorder_impl::get_current_length() { return wav_sink_slot0->total_length_in_seconds(); } @@ -259,10 +263,6 @@ bool dmr_recorder_impl::start(Call *call) { chan_freq = call->get_freq(); this->call = call; - Call_conventional *conventional_call = dynamic_cast(call); - squelch_db = conventional_call->get_squelch_db(); - prefilter->set_squelch_db(squelch_db); - BOOST_LOG_TRIVIAL(info) << "[" << call->get_short_name() << "]\t\033[0;34m" << call->get_call_num() << "C\033[0m\tTG: " << this->call->get_talkgroup_display() << "\tFreq: " << format_freq(chan_freq) << "\t\u001b[32mStarting DMR Recorder Num [" << rec_num << "]\u001b[0m\tTDMA: " << call->get_phase2_tdma() << "\tSlot: " << call->get_tdma_slot(); int offset_amount = (center_freq - chan_freq); @@ -273,11 +273,19 @@ bool dmr_recorder_impl::start(Call *call) { wav_sink_slot1->start_recording(call, 1); state = ACTIVE; - if (conventional) { + if (conventional) { + Call_conventional *conventional_call = dynamic_cast(call); + squelch_db = conventional_call->get_squelch_db(); + if (conventional_call->get_signal_detection()) { set_enabled(false); } else { - set_enabled(true); + set_enabled(true); // If signal detection is not being used, open up the Value/Selector from the start } + } else { + squelch_db = system->get_squelch_db(); + set_enabled(true); + } + prefilter->set_squelch_db(squelch_db); recording_count++; } else { diff --git a/trunk-recorder/recorders/dmr_recorder_impl.h b/trunk-recorder/recorders/dmr_recorder_impl.h index a9fd8d4e6..6af296e77 100644 --- a/trunk-recorder/recorders/dmr_recorder_impl.h +++ b/trunk-recorder/recorders/dmr_recorder_impl.h @@ -94,6 +94,7 @@ class dmr_recorder_impl : public dmr_recorder { bool start(Call *call); void stop(); double get_freq(); + int get_freq_error(); int get_num(); void set_tdma(bool phase2); void switch_tdma(bool phase2); diff --git a/trunk-recorder/recorders/p25_recorder_impl.cc b/trunk-recorder/recorders/p25_recorder_impl.cc index d5b2a94ea..dc007c60c 100644 --- a/trunk-recorder/recorders/p25_recorder_impl.cc +++ b/trunk-recorder/recorders/p25_recorder_impl.cc @@ -317,12 +317,6 @@ bool p25_recorder_impl::start(Call *call) { chan_freq = call->get_freq(); this->call = call; - if (conventional) { - Call_conventional *conventional_call = dynamic_cast(call); - squelch_db = conventional_call->get_squelch_db(); - prefilter->set_squelch_db(squelch_db); - } - BOOST_LOG_TRIVIAL(info) << "[" << call->get_short_name() << "]\t\033[0;34m" << call->get_call_num() << "C\033[0m\tTG: " << this->call->get_talkgroup_display() << "\tFreq: " << format_freq(chan_freq) << "\t\u001b[32mStarting P25 Recorder Num [" << rec_num << "]\u001b[0m\tTDMA: " << call->get_phase2_tdma() << "\tSlot: " << call->get_tdma_slot() << "\tQPSK: " << qpsk_mod; int offset_amount = (center_freq - chan_freq); @@ -337,11 +331,20 @@ bool p25_recorder_impl::start(Call *call) { fsk4_p25_decode->start(call); } state = ACTIVE; + if (conventional) { - set_enabled(false); + Call_conventional *conventional_call = dynamic_cast(call); + squelch_db = conventional_call->get_squelch_db(); + if (conventional_call->get_signal_detection()) { + set_enabled(false); + } else { + set_enabled(true); // If signal detection is not being used, open up the Value/Selector from the start + } } else { + squelch_db = system->get_squelch_db(); set_enabled(true); } + prefilter->set_squelch_db(squelch_db); recording_count++; diff --git a/trunk-recorder/recorders/recorder.h b/trunk-recorder/recorders/recorder.h index 491d1c83b..65387c0cf 100644 --- a/trunk-recorder/recorders/recorder.h +++ b/trunk-recorder/recorders/recorder.h @@ -88,6 +88,7 @@ class Recorder { virtual void stop(){}; virtual void set_tdma_slot(int slot){}; virtual double get_freq() { return 0; }; + virtual int get_freq_error() { return 0; }; virtual Source *get_source() { return NULL; }; virtual std::vector get_transmission_list() { return {}; }; virtual void set_source(long src){}; diff --git a/trunk-recorder/recorders/sigmf_recorder.h b/trunk-recorder/recorders/sigmf_recorder.h index 9fd2741f2..9e67067a0 100644 --- a/trunk-recorder/recorders/sigmf_recorder.h +++ b/trunk-recorder/recorders/sigmf_recorder.h @@ -37,6 +37,7 @@ class sigmf_recorder : virtual public gr::hier_block2, virtual public Recorder { virtual bool start(Call *call) = 0; virtual void stop() = 0; virtual double get_freq() = 0; + virtual int get_freq_error() = 0; virtual int get_num() = 0; virtual double get_current_length() = 0; virtual void set_enabled(bool enabled) {}; diff --git a/trunk-recorder/recorders/sigmf_recorder_impl.cc b/trunk-recorder/recorders/sigmf_recorder_impl.cc index 4242e2063..f413b598c 100644 --- a/trunk-recorder/recorders/sigmf_recorder_impl.cc +++ b/trunk-recorder/recorders/sigmf_recorder_impl.cc @@ -89,6 +89,10 @@ double sigmf_recorder_impl::get_freq() { return freq; } +int sigmf_recorder_impl::get_freq_error() { // get frequency error from FLL and convert to Hz + return prefilter->get_freq_error(); +} + double sigmf_recorder_impl::get_current_length() { return 0; } @@ -134,12 +138,6 @@ bool sigmf_recorder_impl::start(Call *call) { System *system = call->get_system(); talkgroup = call->get_talkgroup(); freq = call->get_freq(); - - if (conventional) { - Call_conventional *conventional_call = dynamic_cast(call); - squelch_db = conventional_call->get_squelch_db(); - prefilter->set_squelch_db(squelch_db); - } int offset_amount = (center - freq); prefilter->tune_offset(offset_amount); @@ -161,11 +159,21 @@ bool sigmf_recorder_impl::start(Call *call) { raw_sink->open(filename); state = ACTIVE; - if (conventional) { + + if (conventional) { + Call_conventional *conventional_call = dynamic_cast(call); + squelch_db = conventional_call->get_squelch_db(); + if (conventional_call->get_signal_detection()) { set_enabled(false); } else { - set_enabled(true); + set_enabled(true); // If signal detection is not being used, open up the Value/Selector from the start } + } else { + squelch_db = system->get_squelch_db(); + set_enabled(true); + } + prefilter->set_squelch_db(squelch_db); + std::string src_description = source->get_driver() + ": " + source->get_device() + " - " + source->get_antenna(); time_t now; time(&now); diff --git a/trunk-recorder/recorders/sigmf_recorder_impl.h b/trunk-recorder/recorders/sigmf_recorder_impl.h index 9bc284eaa..f31a9d428 100644 --- a/trunk-recorder/recorders/sigmf_recorder_impl.h +++ b/trunk-recorder/recorders/sigmf_recorder_impl.h @@ -83,6 +83,7 @@ class sigmf_recorder_impl : public sigmf_recorder { bool start(Call *call); void stop(); double get_freq(); + int get_freq_error(); int get_num(); double get_current_length(); void set_enabled(bool enabled); diff --git a/trunk-recorder/setup_systems.cc b/trunk-recorder/setup_systems.cc index e945d8f1d..e8c1c29fc 100644 --- a/trunk-recorder/setup_systems.cc +++ b/trunk-recorder/setup_systems.cc @@ -21,16 +21,19 @@ bool setup_conventional_channel(System *system, double frequency, long channel_i if (system->has_channel_file()) { Talkgroup *tg = system->find_talkgroup_by_freq(frequency); tone_freq = tg->tone; + + // If there is a per channel squelch setting, use it, otherwise use the system squelch setting if (tg->squelch_db != 999) { - call = new Call_conventional(tg->number, tg->freq, system, config, tg->squelch_db); + call = new Call_conventional(tg->number, tg->freq, system, config, tg->squelch_db, tg->signal_detection); } else { - call = new Call_conventional(tg->number, tg->freq, system, config, system->get_squelch_db()); + call = new Call_conventional(tg->number, tg->freq, system, config, system->get_squelch_db(), tg->signal_detection); } call->set_talkgroup_tag(tg->alpha_tag); } else { - call = new Call_conventional(channel_index, frequency, system, config, system->get_squelch_db()); + call = new Call_conventional(channel_index, frequency, system, config, system->get_squelch_db(), true); // signal detection is always true when a channel file is not used } + BOOST_LOG_TRIVIAL(info) << "[" << system->get_short_name() << "]\tMonitoring " << system->get_system_type() << " channel: " << format_freq(frequency) << " Talkgroup: " << channel_index; if (system->get_system_type() == "conventional") { analog_recorder_sptr rec; diff --git a/trunk-recorder/source.cc b/trunk-recorder/source.cc index b82986864..4bc4ab2f4 100644 --- a/trunk-recorder/source.cc +++ b/trunk-recorder/source.cc @@ -70,6 +70,7 @@ Source::Source(double c, double r, double e, std::string drv, std::string dev, C // parameters for signal_detector_cvf float threshold_sensitivity = 0.9; + bool auto_threshold = true; float threshold = -45; int fft_len = 1024; float average = 0.8; @@ -77,7 +78,7 @@ Source::Source(double c, double r, double e, std::string drv, std::string dev, C float min_bw = 0.0; float max_bw = 50000; - signal_detector = signal_detector_cvf::make(rate, fft_len, 0, threshold, threshold_sensitivity, true, average, quantization, min_bw, max_bw, ""); + signal_detector = signal_detector_cvf::make(rate, fft_len, 0, threshold, threshold_sensitivity, auto_threshold, average, quantization, min_bw, max_bw, ""); BOOST_LOG_TRIVIAL(info) << "Made the Signal Detector"; if (driver == "osmosdr") { @@ -418,7 +419,6 @@ void Source::enable_detected_recorders() { Recorder *recorder = *it; if (!recorder->is_enabled()) { recorder->set_enabled(true); - BOOST_LOG_TRIVIAL(info) << "\t[ " << recorder->get_num() << " ] " << recorder->get_type_string() << "\tEnabled - Freq: " << format_freq(recorder->get_freq()) << "\t Detected Signal: " << floor(rssi) << "dBM (Threshold: " << floor(threshold) << "dBM)"; } } @@ -426,6 +426,7 @@ void Source::enable_detected_recorders() { } void Source::set_signal_detector_threshold(float threshold) { + BOOST_LOG_TRIVIAL(info) << " - Setting Signal Detector Threshold to: " << threshold; signal_detector->set_threshold(threshold); } diff --git a/trunk-recorder/source.h b/trunk-recorder/source.h index e571bbefb..484b1e007 100644 --- a/trunk-recorder/source.h +++ b/trunk-recorder/source.h @@ -102,7 +102,6 @@ class Source { /* -- Gain -- */ void set_if_gain(int i); int get_if_gain(); - void set_gain_mode(bool m); bool get_gain_mode(); void set_gain(int r); diff --git a/trunk-recorder/systems/p25_trunking.cc b/trunk-recorder/systems/p25_trunking.cc index b68b06348..8c9d78d96 100644 --- a/trunk-recorder/systems/p25_trunking.cc +++ b/trunk-recorder/systems/p25_trunking.cc @@ -131,7 +131,7 @@ p25_trunking::p25_trunking(double f, double c, long s, gr::msg_queue::sptr queue qpsk_mod = qpsk; prefilter = xlat_channelizer::make(input_rate, channelizer::phase1_samples_per_symbol, channelizer::phase1_symbol_rate, center_freq, false); - prefilter->set_enabled(true); + initialize_p25(); connect(self(),0, prefilter, 0); diff --git a/trunk-recorder/systems/smartnet_trunking.cc b/trunk-recorder/systems/smartnet_trunking.cc index 01077f2a3..9f59ab114 100644 --- a/trunk-recorder/systems/smartnet_trunking.cc +++ b/trunk-recorder/systems/smartnet_trunking.cc @@ -60,14 +60,10 @@ smartnet_trunking::smartnet_trunking(float f, smartnet_decode_sptr decode = smartnet_make_decode(queue, sys_num); -prefilter = xlat_channelizer::make(input_rate, channelizer::smartnet_samples_per_symbol, channelizer::smartnet_symbol_rate, center_freq, false); -prefilter->set_enabled(true); + prefilter = xlat_channelizer::make(input_rate, channelizer::smartnet_samples_per_symbol, channelizer::smartnet_symbol_rate, center_freq, false); connect(self(), 0, prefilter, 0); connect(prefilter, 0, pll_demod, 0); - - //connect(cutoff_filter, 0, carriertrack, 0); - //connect(carriertrack, 0, pll_demod, 0); connect(pll_demod, 0, softbits, 0); connect(softbits, 0, slicer, 0); connect(slicer, 0, start_correlator, 0); diff --git a/trunk-recorder/talkgroup.cc b/trunk-recorder/talkgroup.cc index bdd03ad8f..d908264dd 100644 --- a/trunk-recorder/talkgroup.cc +++ b/trunk-recorder/talkgroup.cc @@ -15,7 +15,7 @@ Talkgroup::Talkgroup(int sys_num, long num, std::string mode, std::string alpha_ // This talkgroup is for a Trunked system and freq and tone are not used this->freq = 0; this->tone = 0; - this->squelch_db = 999; + this->squelch_db = DB_UNSET; this->signal_detection = false; } diff --git a/trunk-recorder/talkgroup.h b/trunk-recorder/talkgroup.h index 0dbcce4a2..ceca81f9c 100644 --- a/trunk-recorder/talkgroup.h +++ b/trunk-recorder/talkgroup.h @@ -4,6 +4,7 @@ #include #include #include +#include "global_structs.h" //#include class Talkgroup { diff --git a/trunk-recorder/talkgroups.cc b/trunk-recorder/talkgroups.cc index 8e6725e76..8c345539b 100644 --- a/trunk-recorder/talkgroups.cc +++ b/trunk-recorder/talkgroups.cc @@ -125,14 +125,14 @@ void Talkgroups::load_channels(int sys_num, std::string filename) { format.trim({' ', '\t'}); CSVReader reader(filename, format); std::vector headers = reader.get_col_names(); - std::vector defined_headers = {"TG Number", "Tone", "Frequency", "Alpha Tag", "Description", "Category", "Tag", "Enable", "Comment", "Signal Detection", "Squelch"}; + std::vector defined_headers = {"TG Number", "Tone", "Frequency", "Alpha Tag", "Description", "Category", "Tag", "Enable", "Comment", "Signal Detector", "Squelch"}; if (headers[0] != "TG Number") { BOOST_LOG_TRIVIAL(error) << "Column Headers are required for Channel CSV files"; BOOST_LOG_TRIVIAL(error) << "The first column must be 'TG Number'"; BOOST_LOG_TRIVIAL(error) << "Required columns are: 'TG Number', 'Tone', 'Frequency',"; - BOOST_LOG_TRIVIAL(error) << "Optional columns are: 'Alpha Tag', 'Description', 'Category', 'Tag', 'Enable', 'Comment', 'Signal Detection', 'Squelch'"; + BOOST_LOG_TRIVIAL(error) << "Optional columns are: 'Alpha Tag', 'Description', 'Category', 'Tag', 'Enable', 'Comment', 'Signal Detector', 'Squelch'"; exit(0); } else { BOOST_LOG_TRIVIAL(info) << "Found Columns: " << internals::format_row(reader.get_col_names(), ", "); @@ -142,7 +142,7 @@ void Talkgroups::load_channels(int sys_num, std::string filename) { if (find(defined_headers.begin(), defined_headers.end(), headers[i]) == defined_headers.end()) { BOOST_LOG_TRIVIAL(error) << "Unknown column header: " << headers[i]; BOOST_LOG_TRIVIAL(error) << "Required columns are: 'TG Number', 'Tone', 'Frequency',"; - BOOST_LOG_TRIVIAL(error) << "Optional columns are: 'Alpha Tag', 'Description', 'Category', 'Tag', 'Enable', 'Comment', 'Signal Detection', 'Squelch'"; + BOOST_LOG_TRIVIAL(error) << "Optional columns are: 'Alpha Tag', 'Description', 'Category', 'Tag', 'Enable', 'Comment', 'Signal Detector', 'Squelch'"; exit(0); } } @@ -155,8 +155,8 @@ void Talkgroups::load_channels(int sys_num, std::string filename) { std::string description = ""; std::string tag = ""; std::string group = ""; - double squelch_db = 999; - bool signal_detection = true; + double squelch_db = DB_UNSET; + bool signal_detector = true; double freq = 0; double tone = 0; bool enable = true; @@ -200,9 +200,9 @@ void Talkgroups::load_channels(int sys_num, std::string filename) { squelch_db = row["Squelch"].get(); } - if ((reader.index_of("Signal Detection") >= 0) && row["Signal Detection"].is_str()) { - if (boost::iequals(row["Signal Detection"].get(), "false")) { - signal_detection = false; + if ((reader.index_of("Signal Detector") >= 0) && row["Signal Detector"].is_str()) { + if (boost::iequals(row["Signal Detector"].get(), "false")) { + signal_detector = false; } } @@ -213,7 +213,7 @@ void Talkgroups::load_channels(int sys_num, std::string filename) { } } if (enable) { - tg = new Talkgroup(sys_num, tg_number, freq, tone, alpha_tag, description, tag, group, squelch_db, signal_detection); + tg = new Talkgroup(sys_num, tg_number, freq, tone, alpha_tag, description, tag, group, squelch_db, signal_detector); talkgroups.push_back(tg); lines_pushed++; }