RTL - RMS based soft squelch and tweaks; #125

This commit is contained in:
lwvmobile 2023-05-19 11:27:13 -04:00
parent bf4a4b574c
commit 0842613b24
7 changed files with 52 additions and 16 deletions

View File

@ -270,6 +270,7 @@ typedef struct
int rtl_udp_port; int rtl_udp_port;
int rtl_bandwidth; int rtl_bandwidth;
int rtl_started; int rtl_started;
int rtl_rms;
int monitor_input_audio; int monitor_input_audio;
int pulse_raw_rate_in; int pulse_raw_rate_in;
int pulse_raw_rate_out; int pulse_raw_rate_out;
@ -1108,6 +1109,7 @@ void cleanup_rtlsdr_stream();
void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state); void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state);
void rtlsdr_sighandler(); void rtlsdr_sighandler();
void rtl_dev_tune(dsd_opts * opts, long int frequency); void rtl_dev_tune(dsd_opts * opts, long int frequency);
int rtl_return_rms();
#endif #endif
//DMR TRELLIS //DMR TRELLIS
void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload); void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload);

View File

@ -448,6 +448,18 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
state->minref = state->min; state->minref = state->min;
} }
//if using an rtl input method, do not look for sync patterns if the rms value is lower than our 'soft squelch' level
if (opts->audio_in_type == 3 && opts->rtl_rms < opts->rtl_squelch_level) //tests show floor level around 40, and signal breaking 100, default is 100 for level
{
if (opts->frame_nxdn48 == 1 || opts->frame_nxdn96 == 1 || opts->frame_dpmr == 1)
{
goto SYNC_TEST_END;
//should we update min/max here? yes or no?
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
}
}
strncpy (synctest, (synctest_p - 23), 24); strncpy (synctest, (synctest_p - 23), 24);
if (opts->frame_p25p1 == 1) if (opts->frame_p25p1 == 1)
{ {
@ -1553,6 +1565,8 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
} }
#endif //End Provoice Conventional #endif //End Provoice Conventional
SYNC_TEST_END: ; //do nothing
} // t >= 10 } // t >= 10
if (exitflag == 1) if (exitflag == 1)

View File

@ -169,10 +169,11 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->edacs_tuned_lcn = -1; state->edacs_tuned_lcn = -1;
//only for EDACS/PV //only for EDACS/PV
if (opts->frame_provoice == 1 && opts->wav_out_file != NULL) if (opts->p25_trunk == 1 && opts->frame_provoice == 1 && opts->wav_out_file != NULL)
{ {
closeWavOutFile(opts, state); closeWavOutFile(opts, state);
} }
state->last_cc_sync_time = time(NULL); state->last_cc_sync_time = time(NULL);
//test to switch back to 10/4 P1 QPSK for P25 FDMA CC //test to switch back to 10/4 P1 QPSK for P25 FDMA CC
@ -528,13 +529,14 @@ initOpts (dsd_opts * opts)
//all RTL user options -- enabled AGC by default due to weak signal related issues //all RTL user options -- enabled AGC by default due to weak signal related issues
opts->rtl_dev_index = 0; //choose which device we want by index number opts->rtl_dev_index = 0; //choose which device we want by index number
opts->rtl_gain_value = 0; //mid value, 0 - AGC - 0 to 49 acceptable values opts->rtl_gain_value = 0; //mid value, 0 - AGC - 0 to 49 acceptable values
opts->rtl_squelch_level = 0; //fully open by default, want to specify level for things like NXDN with false positives opts->rtl_squelch_level = 100; //100 by default, but only affects NXDN and dPMR during framesync test, compared to RMS value
opts->rtl_volume_multiplier = 1; //sample multiplier; This multiplies the sample value to produce a higher 'inlvl' opts->rtl_volume_multiplier = 1; //sample multiplier; This multiplies the sample value to produce a higher 'inlvl'
opts->rtl_udp_port = 0; //set UDP port for RTL remote -- 0 by default, will be making this optional for some external/legacy use cases (edacs-fm, etc) opts->rtl_udp_port = 0; //set UDP port for RTL remote -- 0 by default, will be making this optional for some external/legacy use cases (edacs-fm, etc)
opts->rtl_bandwidth = 12; //changed recommended default to 12, 24 for ProVoice opts->rtl_bandwidth = 6; //default was 12, but changed to 6 due to newer handling of rtl_bandwidth
opts->rtlsdr_ppm_error = 0; //initialize ppm with 0 value; bug reported by N. opts->rtlsdr_ppm_error = 0; //initialize ppm with 0 value;
opts->rtlsdr_center_freq = 850000000; //set to an initial value (if user is using a channel map, then they won't need to specify anything other than -i rtl if desired) opts->rtlsdr_center_freq = 850000000; //set to an initial value (if user is using a channel map, then they won't need to specify anything other than -i rtl if desired)
opts->rtl_started = 0; opts->rtl_started = 0;
opts->rtl_rms = 0; //root means square power level on rtl input signal
//end RTL user options //end RTL user options
opts->pulse_raw_rate_in = 48000; opts->pulse_raw_rate_in = 48000;
opts->pulse_raw_rate_out = 48000; // opts->pulse_raw_rate_out = 48000; //
@ -1063,9 +1065,9 @@ usage ()
printf (" NOTE: all arguments after rtl are optional now for trunking, but user configuration is recommended\n"); printf (" NOTE: all arguments after rtl are optional now for trunking, but user configuration is recommended\n");
printf (" dev <num> RTL-SDR Device Index Number\n"); printf (" dev <num> RTL-SDR Device Index Number\n");
printf (" freq <num> RTL-SDR Frequency (851800000 or 851.8M) \n"); printf (" freq <num> RTL-SDR Frequency (851800000 or 851.8M) \n");
printf (" gain <num> RTL-SDR Device Gain (0-49)(default = 28)(0 = Hardware AGC, not recommended)\n"); printf (" gain <num> RTL-SDR Device Gain (0-49)(default = 0; Hardware AGC recommended)\n");
printf (" ppm <num> RTL-SDR PPM Error (default = 0)\n"); printf (" ppm <num> RTL-SDR PPM Error (default = 0)\n");
printf (" bw <num> RTL-SDR VFO Bandwidth kHz (default = 12)(6, 8, 12, 24) \n"); printf (" bw <num> RTL-SDR Bandwidth kHz (default = 6)(4, 6, 8, 12, 16, 24) \n");
printf (" sq <num> RTL-SDR Squelch Level (Optional)\n"); printf (" sq <num> RTL-SDR Squelch Level (Optional)\n");
printf (" udp <num> RTL-SDR UDP Remote Port (Optional -- External Use Only)\n"); printf (" udp <num> RTL-SDR UDP Remote Port (Optional -- External Use Only)\n");
printf (" Example: dsd-fme-zdev -fs -i rtl -C cap_plus_channel.csv -T\n"); //put a good example here, probably trunking so user doesn't have to enter the 'optional' arguments printf (" Example: dsd-fme-zdev -fs -i rtl -C cap_plus_channel.csv -T\n"); //put a good example here, probably trunking so user doesn't have to enter the 'optional' arguments
@ -1149,7 +1151,7 @@ usage ()
printf (" (NOTE: P25 Data Channels Not Enabled (no handling) \n"); printf (" (NOTE: P25 Data Channels Not Enabled (no handling) \n");
printf (" -U <port> Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++)\n"); printf (" -U <port> Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++)\n");
printf (" -B <Hertz> Set RIGCTL Setmod Bandwidth in Hertz (0 - default - OFF)\n"); printf (" -B <Hertz> Set RIGCTL Setmod Bandwidth in Hertz (0 - default - OFF)\n");
printf (" P25 - 7000-12000; P25 (QPSK) - 12000; NXDN48 - 4000; DMR - 7000; EDACS/PV - 12500;\n"); printf (" P25 - 7000-12000; P25 (QPSK) - 12000; NXDN48 - 7000; NXDN96: 9000; DMR - 7000; EDACS/PV - 12500;\n");
printf (" May vary based on system stregnth, etc.\n"); printf (" May vary based on system stregnth, etc.\n");
printf (" -t <secs> Set Trunking or Fast Scan VC/sync loss hangtime in seconds. (default = 1 second) (decimal values permitted) \n"); printf (" -t <secs> Set Trunking or Fast Scan VC/sync loss hangtime in seconds. (default = 1 second) (decimal values permitted) \n");
printf ("\n"); printf ("\n");
@ -1343,7 +1345,7 @@ main (int argc, char **argv)
} }
#ifdef AERO_BUILD #ifdef AERO_BUILD
fprintf (stderr, "Build Version: v2.0.1-7 Win32 \n"); fprintf (stderr, "Build Version: v2.0.1-8 Win32 \n");
#else #else
fprintf (stderr, "Build Version: %s \n", GIT_TAG); fprintf (stderr, "Build Version: %s \n", GIT_TAG);
#endif #endif
@ -2253,7 +2255,7 @@ main (int argc, char **argv)
opts.rtl_bandwidth = bw; opts.rtl_bandwidth = bw;
} }
else else
opts.rtl_bandwidth = 12; //safe default opts.rtl_bandwidth = 6; //new safe default
} }
else goto RTLEND; else goto RTLEND;

View File

@ -2133,15 +2133,16 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
} }
if (opts->audio_in_type == 3) if (opts->audio_in_type == 3)
{ {
printw ("| RTL Dev: %d;", opts->rtl_dev_index); printw ("| RTL: %d;", opts->rtl_dev_index);
if (opts->rtl_gain_value == 0) if (opts->rtl_gain_value == 0)
printw (" Gain: AGC;"); printw (" Gain: AGC;");
else else
printw (" Gain: %idB;", opts->rtl_gain_value); printw (" Gain: %idB;", opts->rtl_gain_value);
printw (" PPM: %i;", opts->rtlsdr_ppm_error); printw (" PPM: %i;", opts->rtlsdr_ppm_error);
printw (" SQ: %i;", opts->rtl_squelch_level); printw (" SQ: %i;", opts->rtl_squelch_level);
printw (" RMS: %03i;", opts->rtl_rms);
printw (" BW: %i kHz;", opts->rtl_bandwidth); printw (" BW: %i kHz;", opts->rtl_bandwidth);
printw (" FREQ: %i Hz;", opts->rtlsdr_center_freq); printw (" FREQ: %i;", opts->rtlsdr_center_freq);
if (opts->rtl_udp_port != 0) printw ("\n| External Tuning on UDP Port: %i", opts->rtl_udp_port); if (opts->rtl_udp_port != 0) printw ("\n| External Tuning on UDP Port: %i", opts->rtl_udp_port);
printw ("\n"); printw ("\n");
} }
@ -3437,6 +3438,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->p25_trunk == 1 && opts->audio_in_type == 3) rtl_dev_tune (opts, state->p25_cc_freq); if (opts->p25_trunk == 1 && opts->audio_in_type == 3) rtl_dev_tune (opts, state->p25_cc_freq);
#endif #endif
state->last_cc_sync_time = time(NULL);
} }
if (state->lasttgR != 0 && opts->frame_provoice != 1 && c == 50) //'2' key, lockout slot 2 tdma tgR from tuning/playback during session if (state->lasttgR != 0 && opts->frame_provoice != 1 && c == 50) //'2' key, lockout slot 2 tdma tgR from tuning/playback during session
@ -3490,6 +3493,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->p25_trunk == 1 && opts->audio_in_type == 3) rtl_dev_tune (opts, state->p25_cc_freq); if (opts->p25_trunk == 1 && opts->audio_in_type == 3) rtl_dev_tune (opts, state->p25_cc_freq);
#endif #endif
state->last_cc_sync_time = time(NULL);
} }
if (c == 48) //'0' key, toggle upsampled audio smoothing if (c == 48) //'0' key, toggle upsampled audio smoothing

View File

@ -137,6 +137,7 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
state->pulse_raw_out_buffer = sample; //steal raw out buffer sample here? state->pulse_raw_out_buffer = sample; //steal raw out buffer sample here?
pa_simple_write(opts->pulse_raw_dev_out, (void*)&state->pulse_raw_out_buffer, 2, NULL); pa_simple_write(opts->pulse_raw_dev_out, (void*)&state->pulse_raw_out_buffer, 2, NULL);
} }
opts->rtl_rms = rtl_return_rms();
#endif #endif
} }

View File

@ -155,6 +155,8 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
rtl_dev_tune (opts, state->p25_cc_freq); rtl_dev_tune (opts, state->p25_cc_freq);
#endif #endif
} }
state->last_cc_sync_time = time(NULL); //allow tuners a second to catch up, particularly rtl input
} }
break; break;
@ -795,7 +797,7 @@ void NXDN_decode_srv_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
//poll for current frequency, will always be the control channel //poll for current frequency, will always be the control channel
//this PDU is constantly pumped out on the CC CAC Message //this PDU is constantly pumped out on the CC CAC Message
if (opts->p25_trunk == 1) if (opts->p25_trunk == 1 && opts->p25_is_tuned == 0) //changed this so the rtl tuning lag doesn't set RTCH frequency after tuning but before landing
{ {
long int ccfreq = 0; long int ccfreq = 0;
//if using rigctl, we can poll for the current frequency //if using rigctl, we can poll for the current frequency
@ -805,7 +807,7 @@ void NXDN_decode_srv_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
if (ccfreq != 0) state->p25_cc_freq = ccfreq; if (ccfreq != 0) state->p25_cc_freq = ccfreq;
} }
//if using rtl input, we can ask for the current frequency tuned //if using rtl input, we can ask for the current frequency tuned
else if (opts->audio_in_type == 3) else if (opts->audio_in_type == 3) //after changing to rtl_dev_tune, this may lag a bit due to delay in sample delivery?
{ {
ccfreq = (long int)opts->rtlsdr_center_freq; ccfreq = (long int)opts->rtlsdr_center_freq;
if (ccfreq != 0) state->p25_cc_freq = ccfreq; if (ccfreq != 0) state->p25_cc_freq = ccfreq;

View File

@ -628,9 +628,9 @@ int verbose_set_frequency(rtlsdr_dev_t *dev, uint32_t frequency)
int r; int r;
r = rtlsdr_set_center_freq(dev, frequency); r = rtlsdr_set_center_freq(dev, frequency);
if (r < 0) { if (r < 0) {
fprintf (stderr, "WARNING: Failed to set center freq.\n"); fprintf (stderr, " WARNING: Failed to set center freq.\n");
} else { } else {
fprintf (stderr, "Tuned to %u Hz.\n", frequency); fprintf (stderr, " Tuned to %u Hz.\n", frequency);
} }
return r; return r;
} }
@ -984,7 +984,7 @@ void open_rtlsdr_stream(dsd_opts *opts)
} }
dongle.dev_index = opts->rtl_dev_index; dongle.dev_index = opts->rtl_dev_index;
demod.squelch_level = opts->rtl_squelch_level; // demod.squelch_level = opts->rtl_squelch_level; //no longer used here, used in framesync vc rms value under select conditions
fprintf (stderr, "Setting RTL VFO Bandwidth to %d Hz\n", rtl_bandwidth); fprintf (stderr, "Setting RTL VFO Bandwidth to %d Hz\n", rtl_bandwidth);
fprintf (stderr, "Setting RTL Sample Multiplier to %d\n", bandwidth_multiplier); fprintf (stderr, "Setting RTL Sample Multiplier to %d\n", bandwidth_multiplier);
fprintf (stderr, "Setting RTL Squelch Level to %d\n", demod.squelch_level); fprintf (stderr, "Setting RTL Squelch Level to %d\n", demod.squelch_level);
@ -1087,10 +1087,20 @@ void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state)
pthread_rwlock_unlock(&output.rw); pthread_rwlock_unlock(&output.rw);
} }
//function may lag since it isn't running as its own thread
void rtl_dev_tune(dsd_opts * opts, long int frequency) void rtl_dev_tune(dsd_opts * opts, long int frequency)
{ {
int r; int r;
dongle.freq = opts->rtlsdr_center_freq = frequency; dongle.freq = opts->rtlsdr_center_freq = frequency;
optimal_settings(dongle.freq, demod.rate_in); optimal_settings(dongle.freq, demod.rate_in);
r = verbose_set_frequency(dongle.dev, dongle.freq); r = verbose_set_frequency(dongle.dev, dongle.freq);
dongle.mute = BUFFER_DUMP; //test this here -- seems to help with sample lag sending stale samples
}
//return RMS value (root means square) power level -- used as soft squelch inside of framesync
int rtl_return_rms()
{
int sr = 0;
sr = rms(demod.lowpassed, demod.lp_len, 1);
return (sr);
} }