From ff58d3a6fad556b90e7267f7f2757b7163065326 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Fri, 22 Mar 2024 18:10:15 -0400 Subject: [PATCH] User Toggles and Displays for Filters; --- include/dsd.h | 6 ++++++ src/dsd_audio.c | 20 +++++++++++-------- src/dsd_main.c | 10 ++++++++++ src/dsd_ncurses.c | 49 +++++++++++++++++++++++++++++++++++++++++++---- src/dsd_symbol.c | 16 ++++++++++++---- src/edacs-fme.c | 44 ++++++++++++++++++++++++++++++------------ src/m17.c | 32 ++++++++++++++++++++++++++----- 7 files changed, 144 insertions(+), 33 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index 6a962b6..f30fa6c 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -436,6 +436,12 @@ typedef struct int slot1_on; int slot2_on; + //enable filter options + int use_lpf; + int use_hpf; + int use_pbf; + int use_hpf_d; + //'DSP' Format Output uint8_t use_dsp_output; char dsp_out_file[2048]; diff --git a/src/dsd_audio.c b/src/dsd_audio.c index 36a110a..54792b7 100644 --- a/src/dsd_audio.c +++ b/src/dsd_audio.c @@ -308,8 +308,9 @@ processAudio (dsd_opts * opts, dsd_state * state) *state->audio_out_buf_p = (short) *state->audio_out_float_buf_p; //tap the pointer here and store the short upsample buffer samples state->s_lu[n] = (short) *state->audio_out_float_buf_p; - //hpf test - // state->s_lu[n] = HPFilter_Update(&state->HRCFilterL, state->s_lu[n]); + //hpf + if (opts->use_hpf_d == 1) + state->s_lu[n] = HPFilter_Update(&state->HRCFilterL, state->s_lu[n]); state->audio_out_buf_p++; state->audio_out_float_buf_p++; } @@ -330,8 +331,9 @@ processAudio (dsd_opts * opts, dsd_state * state) *state->audio_out_buf_p = (short) *state->audio_out_temp_buf_p; //tap the pointer here and store the short buffer samples state->s_l[n] = (short) *state->audio_out_temp_buf_p; - //hpf test - // state->s_l[n] = HPFilter_Update(&state->HRCFilterL, state->s_l[n]); + //hpf + if (opts->use_hpf_d == 1) + state->s_l[n] = HPFilter_Update(&state->HRCFilterL, state->s_l[n]); //debug // fprintf (stderr, " %d", state->s_l[n]); state->audio_out_buf_p++; @@ -459,8 +461,9 @@ processAudioR (dsd_opts * opts, dsd_state * state) *state->audio_out_buf_pR = (short) *state->audio_out_float_buf_pR; //tap the pointer here and store the short upsample buffer samples state->s_ru[n] = (short) *state->audio_out_float_buf_pR; - //hpf test - // state->s_ru[n] = HPFilter_Update(&state->HRCFilterR, state->s_ru[n]); + //hpf + if (opts->use_hpf_d == 1) + state->s_ru[n] = HPFilter_Update(&state->HRCFilterR, state->s_ru[n]); state->audio_out_buf_pR++; state->audio_out_float_buf_pR++; } @@ -481,8 +484,9 @@ processAudioR (dsd_opts * opts, dsd_state * state) *state->audio_out_buf_pR = (short) *state->audio_out_temp_buf_pR; //tap the pointer here and store the short buffer samples state->s_r[n] = (short) *state->audio_out_temp_buf_pR; - //hpf test - // state->s_r[n] = HPFilter_Update(&state->HRCFilterR, state->s_r[n]); + //hpf + if (opts->use_hpf_d == 1) + state->s_r[n] = HPFilter_Update(&state->HRCFilterR, state->s_r[n]); state->audio_out_buf_pR++; state->audio_out_temp_buf_pR++; state->audio_out_idxR++; diff --git a/src/dsd_main.c b/src/dsd_main.c index 1785542..64738f5 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -768,6 +768,12 @@ initOpts (dsd_opts * opts) opts->slot1_on = 1; opts->slot2_on = 1; + //enable filter options + opts->use_lpf = 0; + opts->use_hpf = 1; + opts->use_pbf = 1; + opts->use_hpf_d = 0; + //dsp structured file opts->dsp_out_file[0] = 0; opts->use_dsp_output = 0; @@ -2470,6 +2476,10 @@ main (int argc, char **argv) opts.m17encoder = 1; opts.pulse_digi_rate_out = 48000; opts.pulse_digi_out_channels = 1; + //filters disabled by default, use ncurses VBN switches + opts.use_lpf = 0; + opts.use_hpf = 0; + opts.use_pbf = 0; sprintf (opts.output_name, "M17 Encoder"); } else if (optarg[0] == 'B') //Captial B to Run the M17 BRT encoder diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index 0a715a0..d38e6b4 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -2395,6 +2395,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (opts->floating_point == 1) printw (" FLOAT: %02.0f%%;", opts->audio_gain*2); if (opts->audio_gain == 0) printw (" (+|-) Auto"); if (opts->audio_gain > 0) printw (" (+|-) Manual"); + if (opts->use_hpf_d == 1) printw (" HPF"); if (opts->call_alert == 1) printw (" *CA!"); //Call Alert // if (state->audio_smoothing == 1 && opts->floating_point == 0) printw (" Smoothing On;"); //only on short printw (" \n"); @@ -2402,8 +2403,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if ( opts->audio_out_type == 0 && (opts->frame_provoice == 1 || opts->monitor_input_audio == 1) ) { - printw ("| Pulse Analog Output: %i kHz; %i Ch; G: %02.0f%% (/|*) Manual", opts->pulse_raw_rate_out/1000, opts->pulse_raw_out_channels, opts->audio_gainA); - if (opts->audio_in_type != 3) printw (" RMS: %04ld;", opts->rtl_rms); + printw ("| Pulse Analog Output: %i kHz; %i Ch; G: %02.0f%% (/|*) Manual ", opts->pulse_raw_rate_out/1000, opts->pulse_raw_out_channels, opts->audio_gainA); + if (opts->audio_in_type != 3) printw ("RMS: %04ld; ", opts->rtl_rms); + if (opts->use_lpf == 1) printw ("F: |LP|"); else printw ("F: | |"); + if (opts->use_hpf == 1) printw ("HP|"); else printw (" |"); + if (opts->use_pbf == 1) printw ("PB|"); else printw (" |"); printw (" \n"); } @@ -2413,6 +2417,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (opts->pulse_digi_out_channels == 2) printw (" G: %02.0f%%", state->aout_gainR*2); if (opts->audio_gain == 0) printw (" (+/-) Auto"); if (opts->audio_gain > 0) printw (" (+/-) Manual"); + if (opts->use_hpf_d == 1) printw (" HPF"); if (opts->call_alert == 1) printw (" *CA!"); //Call Alert // if (state->audio_smoothing == 1 && opts->floating_point == 0) printw (" Smoothing On;"); //only on short if ( (opts->audio_out_type == 5 && opts->pulse_digi_rate_out == 48000 && opts->pulse_digi_out_channels == 1) && (opts->frame_provoice == 1 || opts->monitor_input_audio == 1) ) @@ -2426,13 +2431,18 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (opts->pulse_digi_out_channels == 2) printw (" G: %02.0f%%", state->aout_gainR*2); if (opts->audio_gain == 0) printw (" (+/-) Auto"); if (opts->audio_gain > 0) printw (" (+/-) Manual"); + if (opts->use_hpf_d == 1) printw (" HPF"); if (opts->call_alert == 1) printw (" *CA!"); //Call Alert if ( (opts->audio_out_type == 5 && opts->pulse_digi_rate_out == 48000 && opts->pulse_digi_out_channels == 1) && (opts->frame_provoice == 1 || opts->monitor_input_audio == 1) ) printw (" - Monitor RMS: %04ld ", opts->rtl_rms); printw (" \n"); if (opts->udp_sockfdA != 0) //Analog Output on udp port +2 { - printw ("| UDP Analog Output: %s:%d; 48 kHz 1 Ch; Analog Output; ", opts->udp_hostname, opts->udp_portno+2); + printw ("| UDP Analog Output: %s:%d; 48 kHz 1 Ch; ", opts->udp_hostname, opts->udp_portno+2); + if (opts->audio_in_type != 3) printw ("RMS: %04ld; ", opts->rtl_rms); + if (opts->use_lpf == 1) printw ("F: |LP|"); else printw ("F: | |"); + if (opts->use_hpf == 1) printw ("HP|"); else printw (" |"); + if (opts->use_pbf == 1) printw ("PB|"); else printw (" |"); printw (" \n"); } } @@ -2553,7 +2563,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) printw ( "[%d] \n", (48000*opts->wav_interpolator)/state->samplesPerSymbol); if (opts->m17encoder == 1) printw ("| Encoding: [%s] ", opts->output_name); if (opts->m17encoder == 1) printw (" Toggle (\\); "); - if (opts->m17encoder == 1) printw (" Mic Gain (/|*): %02.0f%% \n", opts->audio_gainA); + if (opts->m17encoder == 1) printw (" Mic Gain (/|*): %02.0f%% ", opts->audio_gainA); + if (opts->m17encoder == 1) + { + if (opts->use_lpf == 1) printw ("F: |LP|"); else printw ("F: | |"); + if (opts->use_hpf == 1) printw ("HP|"); else printw (" |"); + if (opts->use_pbf == 1) printw ("PB|"); else printw (" |"); + printw ("\n"); + } printw ("| Decoding: [%s] ", opts->output_name); if (opts->aggressive_framesync == 0) printw ("CRC/(RAS) "); //debug -- troubleshoot voice tuning after grant on DMR CC, subsequent grant may not tune because tuner isn't available @@ -4383,6 +4400,30 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) } + if (c == 86) // 'V' Key, toggle LPF + { + if (opts->use_lpf == 0) opts->use_lpf = 1; + else opts->use_lpf = 0; + } + + if (c == 66) // 'B' Key, toggle HPF + { + if (opts->use_hpf == 0) opts->use_hpf = 1; + else opts->use_hpf = 0; + } + + if (c == 78) // 'N' Key, toggle PBF + { + if (opts->use_pbf == 0) opts->use_pbf = 1; + else opts->use_pbf = 0; + } + + if (c == 72) // 'H' Key, toggle HPF on digital + { + if (opts->use_hpf_d == 0) opts->use_hpf_d = 1; + else opts->use_hpf_d = 0; + } + if (opts->m17encoder == 1 && c == 92) //'\' key - toggle M17 encoder Encode + TX { if (state->m17encoder_tx == 0) state->m17encoder_tx = 1; diff --git a/src/dsd_symbol.c b/src/dsd_symbol.c index a5eaab8..46b4e9b 100644 --- a/src/dsd_symbol.c +++ b/src/dsd_symbol.c @@ -279,16 +279,24 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync) } //low pass filter - // lpf(state, state->analog_out, 960); + if (opts->use_lpf == 1) + lpf(state, state->analog_out, 960); //high pass filter - hpf (state, state->analog_out, 960); + if (opts->use_hpf == 1) + hpf (state, state->analog_out, 960); //pass band filter - pbf(state, state->analog_out, 960); + if (opts->use_pbf == 1) + pbf(state, state->analog_out, 960); //manual gain control - analog_gain (opts, state, state->analog_out, 960); + if (opts->audio_gainA > 0.0f) + analog_gain (opts, state, state->analog_out, 960); + + //automatic gain control + else + agsm(opts, state, state->analog_out, 960); //Running RMS after filtering does remove the analog spike from the RMS value //but noise floor noise will still produce higher values diff --git a/src/edacs-fme.c b/src/edacs-fme.c index 088e8bf..55da62f 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -215,24 +215,44 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn state->dmr_payload_p = state->dmr_payload_buf + 200; // low pass filter - // lpf (state, analog1, 960); - // lpf (state, analog2, 960); - // lpf (state, analog3, 960); + if (opts->use_lpf == 1) + { + lpf (state, analog1, 960); + lpf (state, analog2, 960); + lpf (state, analog3, 960); + } //high pass filter - hpf (state, analog1, 960); - hpf (state, analog2, 960); - hpf (state, analog3, 960); + if (opts->use_hpf == 1) + { + hpf (state, analog1, 960); + hpf (state, analog2, 960); + hpf (state, analog3, 960); + } //pass band filter - pbf (state, analog1, 960); - pbf (state, analog2, 960); - pbf (state, analog3, 960); + if (opts->use_pbf == 1) + { + pbf (state, analog1, 960); + pbf (state, analog2, 960); + pbf (state, analog3, 960); + } //manual gain control - analog_gain (opts, state, analog1, 960); - analog_gain (opts, state, analog2, 960); - analog_gain (opts, state, analog3, 960); + if (opts->audio_gainA > 0.0f) + { + analog_gain (opts, state, analog1, 960); + analog_gain (opts, state, analog2, 960); + analog_gain (opts, state, analog3, 960); + } + + //automatic gain control + else + { + agsm (opts, state, analog1, 960); + agsm (opts, state, analog2, 960); + agsm (opts, state, analog3, 960); + } //NOTE: Ideally, we would run raw_rms for TCP/VS here, but the analog spike on EDACS (STM) //system gets filtered out, and when they hold the radio open and don't talk, diff --git a/src/m17.c b/src/m17.c index 729c170..edc3d16 100644 --- a/src/m17.c +++ b/src/m17.c @@ -1844,18 +1844,40 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) if (opts->audio_in_type == 3) opts->rtl_rms = rtl_return_rms(); else opts->rtl_rms = raw_rms(voice1, nsam, 1) / 2; //dividing by two so mic isn't so sensitive on vox - //run hpf if from the dongle, mic input doesn't need it, and if using SDR++, use the high pass filter there instead - if (opts->audio_in_type == 3) + //low pass filter + if (opts->use_lpf == 1) + { + lpf (state, voice1, 160); + lpf (state, voice2, 160); + } + + //high pass filter + if (opts->use_hpf == 1) { hpf (state, voice1, 160); hpf (state, voice2, 160); + } + + //passband filter + if (opts->use_pbf == 1) + { pbf (state, voice1, 160); pbf (state, voice2, 160); } - //manual adjustment to gain, after filtering them - analog_gain (opts, state, voice1, 160); - analog_gain (opts, state, voice2, 160); + //manual gain control + if (opts->audio_gainA > 0.0f) + { + analog_gain (opts, state, voice1, 160); + analog_gain (opts, state, voice2, 160); + } + + //automatic gain control + else + { + agsm (opts, state, voice1, 160); + agsm (opts, state, voice2, 160); + } //NOTE: Similar to EDACS analog, if calculating raw rms here after filtering, //anytime the walkie-talkie is held open but no voice, the center spike is removed,