Skip to content

Commit

Permalink
Configurable de-emphasis time constant for analog recorders (#975)
Browse files Browse the repository at this point in the history
* configurable de-emphasis tau for analog recorder

* virtual override

* fix2

* fix3

* fix4

* fix5

* fix6

* Default 750 + docs
  • Loading branch information
algertc authored Oct 12, 2024
1 parent fad87da commit a64b639
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 17 deletions.
1 change: 1 addition & 0 deletions docs/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ There is a list of available Plugins [here](./Plugins.md).
| decodeFSync | | false | **true** / **false** | *Conventional systems only* enable the Fleet Sync signaling decoder. |
| decodeStar | | false | **true** / **false** | *Conventional systems only* enable the Star signaling decoder. |
| decodeTPS | | false | **true** / **false** | *Conventional systems only* enable the Motorola Tactical Public Safety (aka FDNY Fireground) signaling decoder. |
| deemphasisTau | | 0.000750 | number | *Conventional systems only* configure the de-emphasis time constant. 750µs for NFM (default), 75µs for WFM North America, 50µs for WFM most other regions. |
| enabled | | true | **true** / **false** | control whether a configured system is enabled or disabled |

***
Expand Down
4 changes: 3 additions & 1 deletion trunk-recorder/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ bool load_config(string config_file, Config &config, gr::top_block_sptr &tb, std
double digital_levels = element.value("digitalLevels", 1.0);
double analog_levels = element.value("analogLevels", 8.0);
double squelch_db = element.value("squelch", -160.0);
float tau = element.value("deemphasisTau", 0.000750); // Default to 750us if not specified
int max_dev = element.value("maxDev", 5000);
double filter_width = element.value("filterWidth", 1.0);
bool conversation_mode = element.value("conversationMode", true);
Expand All @@ -325,7 +326,7 @@ bool load_config(string config_file, Config &config, gr::top_block_sptr &tb, std
BOOST_LOG_TRIVIAL(info) << "Modulation: qpsk";
qpsk_mod = true;
}

system->set_tau(tau);
system->set_squelch_db(squelch_db);
system->set_analog_levels(analog_levels);
system->set_digital_levels(digital_levels);
Expand All @@ -337,6 +338,7 @@ bool load_config(string config_file, Config &config, gr::top_block_sptr &tb, std
BOOST_LOG_TRIVIAL(info) << "Analog Recorder Maximum Deviation: " << element.value("maxDev", 4000);
BOOST_LOG_TRIVIAL(info) << "Filter Width: " << filter_width;
BOOST_LOG_TRIVIAL(info) << "Squelch: " << element.value("squelch", -160);
BOOST_LOG_TRIVIAL(info) << "De-emphasis Tau: " << tau;
system->set_api_key(element.value("apiKey", ""));
BOOST_LOG_TRIVIAL(info) << "API Key: " << system->get_api_key();
system->set_bcfy_api_key(element.value("broadcastifyApiKey", ""));
Expand Down
40 changes: 27 additions & 13 deletions trunk-recorder/recorders/analog_recorder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,60 @@ std::vector<float> design_filter(double interpolation, double deci) {
}

analog_recorder_sptr make_analog_recorder(Source *src, Recorder_Type type) {
return gnuradio::get_initial_sptr(new analog_recorder(src, type, -1));
return gnuradio::get_initial_sptr(new analog_recorder(src, static_cast<System*>(nullptr), type, -1));
}

analog_recorder_sptr make_analog_recorder(Source *src, Recorder_Type type, float tone_freq) {
return gnuradio::get_initial_sptr(new analog_recorder(src, type, tone_freq));
return gnuradio::get_initial_sptr(new analog_recorder(src, static_cast<System*>(nullptr), type, tone_freq));
}

void analog_recorder::set_tau(float tau) {
d_tau = tau;
calculate_iir_taps(d_tau);
if (deemph) {
deemph->set_taps(d_fftaps, d_fbtaps);
}
}

float analog_recorder::get_tau() const {
return d_tau;
}


/*! \brief Calculate taps for FM de-emph IIR filter. */
void analog_recorder::calculate_iir_taps(double tau) {
void analog_recorder::calculate_iir_taps(float tau) {
// copied from fm_emph.py in gr-analog
double w_c; // Digital corner frequency
double w_ca; // Prewarped analog corner frequency
double k, z1, p1, b0;
double fs = system_channel_rate;
double fs = static_cast<float>(system_channel_rate);

w_c = 1.0 / tau;
w_ca = 2.0 * fs * tan(w_c / (2.0 * fs));
w_c = 1.0f / tau;
w_ca = 2.0f * fs * std::tan(w_c / (2.0f * fs));

// Resulting digital pole, zero, and gain term from the bilinear
// transformation of H(s) = w_ca / (s + w_ca) to
// H(z) = b0 (1 - z1 z^-1)/(1 - p1 z^-1)
k = -w_ca / (2.0 * fs);
z1 = -1.0;
p1 = (1.0 + k) / (1.0 - k);
b0 = -k / (1.0 - k);
k = -w_ca / (2.0f * fs);
z1 = -1.0f;
p1 = (1.0f + k) / (1.0f - k);
b0 = -k / (1.0f - k);

d_fftaps[0] = b0;
d_fftaps[1] = -z1 * b0;
d_fbtaps[0] = 1.0;
d_fbtaps[0] = 1.0f;
d_fbtaps[1] = -p1;
}

analog_recorder::analog_recorder(Source *src, Recorder_Type type, float tone_freq)
analog_recorder::analog_recorder(Source *src, System *system, Recorder_Type type, float tone_freq)
: gr::hier_block2("analog_recorder",
gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(0, 0, sizeof(float))),
Recorder(type) {
// int nchars;

source = src;
this->system = system;
chan_freq = source->get_center();
center_freq = source->get_center();
config = source->get_config();
Expand Down Expand Up @@ -140,7 +154,7 @@ analog_recorder::analog_recorder(Source *src, Recorder_Type type, float tone_fre
converter = gr::blocks::float_to_short::make(1, 32767);

/* de-emphasis */
d_tau = 0.000075; // 75us
d_tau = (system != nullptr) ? system->get_tau() : 0.000075f; // Default to 75us if system is not provided
d_fftaps.resize(2);
d_fbtaps.resize(2);
calculate_iir_taps(d_tau);
Expand Down
9 changes: 6 additions & 3 deletions trunk-recorder/recorders/analog_recorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class analog_recorder : public gr::hier_block2, public Recorder {
friend analog_recorder_sptr make_analog_recorder(Source *src, Recorder_Type type, float tone_freq);

protected:
analog_recorder(Source *src, Recorder_Type type, float tone_freq);
analog_recorder(Source *src, System *system, Recorder_Type type, float tone_freq);

public:
~analog_recorder();
Expand Down Expand Up @@ -105,6 +105,8 @@ class analog_recorder : public gr::hier_block2, public Recorder {
void plugin_callback_handler(int16_t *samples, int sampleCount);
double get_output_sample_rate();
double since_last_write();
void set_tau(float tau);
float get_tau() const;

private:
double center_freq, chan_freq;
Expand All @@ -130,12 +132,13 @@ class analog_recorder : public gr::hier_block2, public Recorder {
/* De-emph IIR filter taps */
std::vector<double> d_fftaps; /*! Feed forward taps. */
std::vector<double> d_fbtaps; /*! Feed back taps. */
double d_tau; /*! De-emphasis time constant. */
float d_tau; /*! De-emphasis time constant. */

Call *call;
Config *config;
Source *source;
void calculate_iir_taps(double tau);
System *system;
void calculate_iir_taps(float tau);

/* GR blocks */
// channelizer::sptr prefilter;
Expand Down
1 change: 1 addition & 0 deletions trunk-recorder/setup_systems.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ bool setup_conventional_channel(System *system, double frequency, long channel_i
rec = source->create_conventional_recorder(tb);
}
rec->start(call);
rec->set_tau(system->get_tau()); //set the tau value for the recorder from the system config
call->set_is_analog(true);
call->set_recorder((Recorder *)rec.get());
call->set_state(RECORDING);
Expand Down
2 changes: 2 additions & 0 deletions trunk-recorder/systems/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class System {
virtual bool get_qpsk_mod() = 0;
virtual void set_squelch_db(double s) = 0;
virtual double get_squelch_db() = 0;
virtual void set_tau(float tau) = 0;
virtual float get_tau() const = 0;
virtual void set_max_dev(int max_dev) = 0;
virtual int get_max_dev() = 0;
virtual void set_filter_width(double f) = 0;
Expand Down
8 changes: 8 additions & 0 deletions trunk-recorder/systems/system_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ double System_impl::get_squelch_db() {
return squelch_db;
}

void System_impl::set_tau(float t){
tau = t;
}

float System_impl::get_tau() const{
return tau;
}

void System_impl::set_filter_width(double filter_width) {
this->filter_width = filter_width;
}
Expand Down
3 changes: 3 additions & 0 deletions trunk-recorder/systems/system_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class System_impl : public System {
bool conversation_mode;
bool qpsk_mod;
double squelch_db;
float tau;
double analog_levels;
double digital_levels;

Expand Down Expand Up @@ -154,6 +155,8 @@ class System_impl : public System {
bool get_qpsk_mod();
void set_squelch_db(double s);
double get_squelch_db();
void set_tau(float tau) override;
float get_tau() const override;
void set_max_dev(int max_dev);
int get_max_dev();
void set_filter_width(double f);
Expand Down

0 comments on commit a64b639

Please sign in to comment.