diff --git a/src/ch.c b/src/ch.c index 57411bd9b..89f7a2b4e 100644 --- a/src/ch.c +++ b/src/ch.c @@ -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: @@ -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" @@ -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); @@ -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; @@ -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': @@ -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; @@ -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; @@ -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= 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. */