mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 08:47:24 -05:00
EDACS and Analog Monitoring - Apply Filtering Stack (DE,DC,PE, CL); Misc;
This commit is contained in:
@@ -1250,6 +1250,12 @@ void edacs(dsd_opts * opts, dsd_state * state);
|
||||
unsigned long long int edacs_bch (unsigned long long int message);
|
||||
void eot_cc(dsd_opts * opts, dsd_state * state); //end of TX return to CC
|
||||
|
||||
//misc generic audio filtering for analog at 48k/1
|
||||
void analog_deemph_filter(short * input, int len);
|
||||
void analog_preemph_filter(short * input, int len);
|
||||
void analog_dc_block_filter(short * input, int len);
|
||||
void analog_clipping_filter(short * input, int len);
|
||||
|
||||
//csv imports
|
||||
int csvGroupImport(dsd_opts * opts, dsd_state * state);
|
||||
int csvLCNImport(dsd_opts * opts, dsd_state * state);
|
||||
|
||||
@@ -288,12 +288,21 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
if (opts->audio_in_type != 3 && opts->monitor_input_audio == 1)
|
||||
opts->rtl_rms = raw_rms(state->analog_out, 960, 1);
|
||||
|
||||
//debug
|
||||
// opts->rtl_rms = 101;
|
||||
//raw wav file saving -- only write when not NXDN, dPMR, or M17 due to noise that can cause tons of false positives when no sync
|
||||
if (opts->wav_out_raw != NULL && opts->frame_nxdn48 == 0 && opts->frame_nxdn96 == 0 && opts->frame_dpmr == 0 && opts->frame_m17 == 0)
|
||||
{
|
||||
sf_write_short(opts->wav_out_raw, state->analog_out, 960);
|
||||
sf_write_sync (opts->wav_out_raw);
|
||||
}
|
||||
|
||||
//make it a little quieter
|
||||
// for (int x = 0; x < 960; x++)
|
||||
// state->analog_out[x] /= 4;
|
||||
//test running analog audio through a de-emphasis filter
|
||||
analog_deemph_filter(state->analog_out, 960);
|
||||
//and dc_block filter analog_dc_block_filter
|
||||
analog_dc_block_filter(state->analog_out, 960);
|
||||
//test running analog audio through a pre-emphasis filter
|
||||
analog_preemph_filter(state->analog_out, 960);
|
||||
//test running analog short sample clipping filter
|
||||
analog_clipping_filter(state->analog_out, 960);
|
||||
|
||||
//seems to be working now, but RMS values are lower on actual analog signal than on no signal but noise
|
||||
if ( (opts->rtl_rms > opts->rtl_squelch_level) && opts->monitor_input_audio == 1 && state->carrier == 0 ) //added carrier check here in lieu of disabling it above
|
||||
@@ -323,12 +332,12 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
state->last_vc_sync_time = time(NULL);
|
||||
}
|
||||
|
||||
//raw wav file saving -- only write when not NXDN, dPMR, or M17 due to noise that can cause tons of false positives when no sync
|
||||
if (opts->wav_out_raw != NULL && opts->frame_nxdn48 == 0 && opts->frame_nxdn96 == 0 && opts->frame_dpmr == 0 && opts->frame_m17 == 0)
|
||||
{
|
||||
sf_write_short(opts->wav_out_raw, state->analog_out, 960);
|
||||
sf_write_sync (opts->wav_out_raw);
|
||||
}
|
||||
//raw wav file saving -- save the WAV file samples before we apply filtering to them
|
||||
// if (opts->wav_out_raw != NULL && opts->frame_nxdn48 == 0 && opts->frame_nxdn96 == 0 && opts->frame_dpmr == 0 && opts->frame_m17 == 0)
|
||||
// {
|
||||
// sf_write_short(opts->wav_out_raw, state->analog_out, 960);
|
||||
// sf_write_sync (opts->wav_out_raw);
|
||||
// }
|
||||
|
||||
memset (state->analog_out, 0, sizeof(state->analog_out));
|
||||
state->analog_sample_counter = 0;
|
||||
|
||||
@@ -91,20 +91,57 @@ long int gen_rms(short *samples, int len, int step)
|
||||
return rms;
|
||||
}
|
||||
|
||||
//super generic pre-emphasis filter with alpha value of 1 for short sample input / output
|
||||
static short pstate = 1;
|
||||
void analog_preemph_filter(short * input, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
//debug
|
||||
// fprintf (stderr, " I:%d;", input[i]);
|
||||
|
||||
input[i] = input[i] - 1 * pstate;
|
||||
pstate = input[i];
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, " O:%d;;", input[i]);
|
||||
|
||||
//increase gain value slightly
|
||||
input[i] *= 1.5;
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, " O2:%d;;;", input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//super generic short sample clipping filter, prevent short values from exceeding tolerable clip value
|
||||
void analog_clipping_filter(short * input, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (input[i] > 32760)
|
||||
input[i] = 32760;
|
||||
else if (input[i] < -32760)
|
||||
input[i] = -32760;
|
||||
}
|
||||
}
|
||||
|
||||
//modified from version found in rtl_fm
|
||||
static short avg = 0;
|
||||
void analog_deemph_filter(short * input, int len)
|
||||
{
|
||||
// static short avg; // cheating...
|
||||
int i, d;
|
||||
// static short avg; // cheating...
|
||||
int i, d;
|
||||
|
||||
// int a = (int)round(1.0/((1.0-exp(-1.0/(96000 * 75e-6))))); //48000 is rate out, but doubling it sounds 'beefier'
|
||||
int a = 8; //result of calc above is 8, so save a cycle on the low end CPUs
|
||||
|
||||
// de-emph IIR
|
||||
// avg = avg * (1 - alpha) + sample * alpha;
|
||||
// de-emph IIR
|
||||
// avg = avg * (1 - alpha) + sample * alpha;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
d = input[i] - avg;
|
||||
if (d > 0)
|
||||
@@ -113,7 +150,7 @@ void analog_deemph_filter(short * input, int len)
|
||||
avg += (d - a/2) / a;
|
||||
|
||||
input[i] = (short)avg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//modified from version found in rtl_fm
|
||||
@@ -136,6 +173,10 @@ void analog_dc_block_filter(short * input, int len)
|
||||
//listening to and playing back analog audio
|
||||
void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn)
|
||||
{
|
||||
//reset static states for new channel
|
||||
pstate = 1;
|
||||
avg = 0;
|
||||
dc_avg = 0;
|
||||
|
||||
int i, result;
|
||||
int count = 5; //RMS has a 5 count (5 * 180ms) now before cutting off;
|
||||
@@ -270,7 +311,7 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
||||
sr += digitize (opts, state, (int)analog1[i]);
|
||||
}
|
||||
|
||||
//test running analog audio through a deemphasis filter
|
||||
//test running analog audio through a de-emphasis filter
|
||||
analog_deemph_filter(analog1, 960);
|
||||
analog_deemph_filter(analog2, 960);
|
||||
analog_deemph_filter(analog3, 960);
|
||||
@@ -278,7 +319,14 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
||||
analog_dc_block_filter(analog1, 960);
|
||||
analog_dc_block_filter(analog2, 960);
|
||||
analog_dc_block_filter(analog3, 960);
|
||||
|
||||
//test running analog audio through a pre-emphasis filter
|
||||
analog_preemph_filter(analog1, 960);
|
||||
analog_preemph_filter(analog2, 960);
|
||||
analog_preemph_filter(analog3, 960);
|
||||
//test running analog short sample clipping filter
|
||||
analog_clipping_filter(analog1, 960);
|
||||
analog_clipping_filter(analog2, 960);
|
||||
analog_clipping_filter(analog3, 960);
|
||||
|
||||
//reconfigured to use seperate audio out stream that is always 48k short
|
||||
if (opts->audio_out_type == 0 && opts->slot1_on == 1)
|
||||
@@ -769,11 +817,11 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
||||
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
//only set bandwidth IF we have an original one to fall back to (experimental, but requires user to set the -B 12000 value manually)
|
||||
// if (opts->setmod_bw != 0 && command == 0xEE) SetModulation(opts->rigctl_sockfd, 7000); //narrower bandwidth, but has issues with dotting sequence
|
||||
// else if (opts->setmod_bw != 0) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
//only set bandwidth IF we have an original one to fall back to (experimental, but requires user to set the -B 12000 or -B 24000 value manually)
|
||||
if (opts->setmod_bw != 0 && command == 0xEE) SetModulation(opts->rigctl_sockfd, 7000); //narrower bandwidth, but has issues with dotting sequence
|
||||
else if (opts->setmod_bw != 0) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
|
||||
if (opts->setmod_bw != 0) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
// if (opts->setmod_bw != 0) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||
|
||||
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[lcn-1]); //minus one because our index starts at zero
|
||||
state->edacs_tuned_lcn = lcn;
|
||||
|
||||
Reference in New Issue
Block a user