Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 50 additions & 7 deletions src/ch.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ int main(int argc, char *argv[])
float hf_gain;
COMP *ch_fdm_delay = NULL, aspread, aspread_2ms, delayed, direct;
float tx_pwr, tx_pwr_fade, noise_pwr, user_multipath_delay;
int frames, i, j, k, Fs, ret, nclipped, noutclipped, ssbfilt_en, complex_out, ctest;
float sam, peak, clip, papr, CNo, snr3k, gain;
int frames, i, j, k, Fs, ret, nclipped, noutclipped, ssbfilt_en,
complex_out, ctest, impulse_en, impulse_clock, impulse_wait_samples,
impulse_state;
float sam, peak, clip, papr, CNo, snr3k, gain, impulse_period;

if (argc < 3) {
helpmsg:
Expand All @@ -97,7 +99,7 @@ int main(int argc, char *argv[])
"usage: %s InputRealModemRawFile OutputRealModemRawFile [Options]\n"
"\n"
" real int16 input -> Gain -> Hilbert Transform -> clipper -> freq shift ->\n"
" Multipath -> AWGN noise -> SSB filter -> real int16 output\n"
" Multipath -> AWGN+impulse noise -> SSB filter -> real int16 output\n"
"\n"
"[--clip int16] Hilbert clipper (clip complex signal magnitude, default 32767)\n"
"[--complexout] Optional int16 IQ complex output (default real int16)\n"
Expand All @@ -111,7 +113,8 @@ int main(int argc, char *argv[])
"[--mpd] Multipath disturbed 2.0Hz Doppler, 4.0ms delay\n"
"[--ssbfilt 0|1] SSB bandwidth filter (default 1 on)\n"
"[--mulipath_delay ms] Optionally adjust multipath delay\n"
"[--No dBHz] AWGN Noise density dB/Hz (default -100)"
"[--No dBHz] AWGN Noise density dB/Hz (default -100)\n"
"[--impulse ms] simulate impulse noise with mean ms\n"
"\n"
, argv[0]);
exit(1);
Expand All @@ -135,6 +138,7 @@ int main(int argc, char *argv[])
Fs = 8000; foff_hz = 0.0; fading_en = 0; ctest = 0;
clip =32767; gain = 1.0;
ssbfilt_en = 1; complex_out = 0;
impulse_en = 0; impulse_period = 0.0; impulse_state = 0;
fading_dir = strdup(DEFAULT_FADING_DIR); user_multipath_delay = -1.0;

int o = 0;
Expand All @@ -155,10 +159,11 @@ int main(int argc, char *argv[])
{"mpd", no_argument, 0, 'd'},
{"multipath_delay", required_argument, 0, 'm'},
{"No", required_argument, 0, 'n'},
{0, 0, 0, 0}
{"impulse", required_argument, 0, 'j'},
{0, 0, 0, 0}
};

o = getopt_long(argc,argv,"c:df:g:im:n:opr:s:tu:h",long_opts,&opt_idx);
o = getopt_long(argc,argv,"c:df:g:im:n:opr:s:tu:hj:",long_opts,&opt_idx);

switch(o) {
case 'c':
Expand Down Expand Up @@ -200,6 +205,10 @@ int main(int argc, char *argv[])
case 'u':
fading_dir = strdup(optarg);
break;
case 'j':
impulse_en = 1;
impulse_period = atof(optarg);
break;
case 'h':
case '?':
goto helpmsg;
Expand All @@ -215,7 +224,8 @@ int main(int argc, char *argv[])
// units more sensible, and fix all the tests that depend on this scaling
No = pow(10.0, NodB/10.0)*1000*1000;
variance = Fs*No;

impulse_clock = 0; impulse_wait_samples = 0;

tx_pwr = tx_pwr_fade = noise_pwr = 0.0;
noutclipped = 0; nclipped = 0;
peak = 0.0;
Expand Down Expand Up @@ -408,6 +418,39 @@ int main(int argc, char *argv[])
noise_pwr += pow(scaled_noise.real, 2.0) + pow(scaled_noise.imag, 2.0);
}

/* Impulse noise --------------------------------------*/

/* we simulate front end overload (e.g. static crash) by
dropping out the channel for 10ms */

if (impulse_en) {
for(i=0; i<BUF_N; i++) {
impulse_clock++;
int next_state = impulse_state;
switch(impulse_state) {
case 0:
if (impulse_clock >= impulse_wait_samples) {
impulse_clock = 0;
impulse_wait_samples = 0.01*Fs;
next_state = 1;
}
break;
case 1:
ch_fdm[i].real = 32767; ch_fdm[i].imag = 32767;
if (impulse_clock >= impulse_wait_samples) {
impulse_clock = 0;
// std dev of time to next impulse is mean period/2
float impulse_wait_s = impulse_period/1000.0 + (impulse_period/2000.0)*gaussian();
if (impulse_wait_s < 0) impulse_wait_s = 0;
impulse_wait_samples = impulse_wait_s*Fs;
next_state = 0;
}
break;
}
impulse_state = next_state;
}
}

/* FIR filter to simulate (a rather flat) SSB filter. We
filter the complex signal by shifting it down to DC and
using real coefficients. */
Expand Down