From bf8bef489a06c0b9d3dc5292e838e5b66f8193e4 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sun, 28 Jun 2015 04:28:51 +0000 Subject: [PATCH] a little more work on squelch git-svn-id: https://svn.code.sf.net/p/freetel/code@2221 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/src/cohpsk.c | 5 ++- codec2-dev/src/freedv_api.c | 72 ++++++++++++++++++++++++++----------- codec2-dev/src/freedv_api.h | 3 ++ codec2-dev/src/freedv_rx.c | 3 ++ 4 files changed, 62 insertions(+), 21 deletions(-) diff --git a/codec2-dev/src/cohpsk.c b/codec2-dev/src/cohpsk.c index 69755127..0304c8bd 100644 --- a/codec2-dev/src/cohpsk.c +++ b/codec2-dev/src/cohpsk.c @@ -1113,13 +1113,16 @@ void cohpsk_get_demod_stats(struct COHPSK *coh, struct MODEM_STATS *stats) { int c,r; COMP pi_4; + float new_snr_est; pi_4.real = cosf(M_PI/4.0); pi_4.imag = sinf(M_PI/4.0); stats->Nc = COHPSK_NC*ND; assert(stats->Nc <= MODEM_STATS_NC_MAX); - stats->snr_est = 20*log10((coh->sig_rms+1E-6)/(coh->noise_rms+1E-6)) - 10*log10(3000.0/700.0); + new_snr_est = 20*log10((coh->sig_rms+1E-6)/(coh->noise_rms+1E-6)) - 10*log10(3000.0/700.0); + stats->snr_est = 0.9*stats->snr_est + 0.1*new_snr_est; + //fprintf(stderr, "sig_rms: %f noise_rms: %f snr_est: %f\n", coh->sig_rms, coh->noise_rms, stats->snr_est); stats->sync = coh->sync; stats->foff = coh->f_est - FDMDV_FCENTRE; diff --git a/codec2-dev/src/freedv_api.c b/codec2-dev/src/freedv_api.c index cf919c0c..64aeb79e 100644 --- a/codec2-dev/src/freedv_api.c +++ b/codec2-dev/src/freedv_api.c @@ -71,8 +71,9 @@ struct freedv *freedv_open(int mode) { return NULL; f->mode = mode; - f->test_frames = 0; + f->test_frames = f->smooth_symbols = 0; f->snr_squelch_thresh = 2.0; + f->squelch_en = 1; if (mode == FREEDV_MODE_1600) { Nc = 16; @@ -122,6 +123,9 @@ struct freedv *freedv_open(int mode) { f->n_speech_samples = codec2_samples_per_frame(f->codec2); if (mode == FREEDV_MODE_700) f->n_speech_samples = 2*codec2_samples_per_frame(f->codec2); + f->prev_rx_bits = (float*)malloc(sizeof(float)*2*codec2_bits_per_frame(f->codec2)); + if (f->prev_rx_bits == NULL) + return NULL; nbit = codec2_bits_per_frame(f->codec2); nbyte = (nbit + 7) / 8; @@ -158,6 +162,7 @@ struct freedv *freedv_open(int mode) { void freedv_close(struct freedv *freedv) { assert(freedv != NULL); + free(freedv->prev_rx_bits); free(freedv->packed_codec_bits); free(freedv->codec_bits); free(freedv->tx_bits); @@ -582,9 +587,10 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) { /* squelch if beneath SNR threshold or test frames enabled */ - if ((f->stats.snr_est < f->snr_squelch_thresh) || f->test_frames) { + if ((f->squelch_en && (f->stats.snr_est < f->snr_squelch_thresh)) || f->test_frames) { for(i=0; in_speech_samples; i++) speech_out[i] = 0; + fprintf(stderr, "sq! "); } nout = f->n_speech_samples; @@ -594,8 +600,14 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) { /* if not in sync pass through analog samples */ /* this lets us "hear" whats going on, e.g. during tuning */ - for(i=0; isquelch_en == 0) { + for(i=0; itest_frames == 0) { data_flag_index = codec2_get_spare_bit_index(f->codec2); + /* optional smoothing of codec symbols */ + + if (f->smooth_symbols) { + float tmp; + + for(i=0; icodec2, speech_out, f->packed_codec_bits); - if (f->stats.snr_est < f->snr_squelch_thresh) { + if (f->squelch_en && (f->stats.snr_est < f->snr_squelch_thresh)) { for(i=0; in_speech_samples; i++) speech_out[i] = 0; + fprintf(stderr, "sq! "); } speech_out += codec2_samples_per_frame(f->codec2); } @@ -675,23 +699,31 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) { } if (sync == 0) { - float t,a,b,s; - int t1,t2; - - /* if not in sync pass through analog samples */ - /* this lets us "hear" whats going on, e.g. during tuning */ - /* need to linearly interp as Fs in and out slightly different */ - - for(i=0, t=0.0; in_speech_samples; i++, t+=(float)f->modem_sample_rate/FS) { - t1 = floor(t); t2 = ceil(t); - a = t - t1; - b = t2 - t1; - s = b*demod_in[t1].real + a*demod_in[t2].real; - speech_out[i] = FDMDV_SCALE*s; + if (f->squelch_en) { + for(i=0; in_speech_samples; i++) + speech_out[i] = 0; + nout = f->n_speech_samples; + } + else { + float t,a,b,s; + int t1,t2; + + /* if not in sync pass through analog samples */ + /* this lets us "hear" whats going on, e.g. during tuning */ + /* need to linearly interp as Fs in and out slightly different */ + + for(i=0, t=0.0; in_speech_samples; i++, t+=(float)f->modem_sample_rate/FS) { + t1 = floor(t); t2 = ceil(t); + a = t - t1; + b = t2 - t1; + s = b*demod_in[t1].real + a*demod_in[t2].real; + speech_out[i] = FDMDV_SCALE*s; + } + nout = f->n_speech_samples; + //fprintf(stderr, "%d %d %d\n", f->n_speech_samples, speech_out[0], speech_out[nin_prev-1]); } - nout = f->n_speech_samples; - //fprintf(stderr, "%d %d %d\n", f->n_speech_samples, speech_out[0], speech_out[nin_prev-1]); } + } diff --git a/codec2-dev/src/freedv_api.h b/codec2-dev/src/freedv_api.h index c8c3b819..275c1fb2 100644 --- a/codec2-dev/src/freedv_api.h +++ b/codec2-dev/src/freedv_api.h @@ -62,6 +62,8 @@ struct freedv { int *fdmdv_bits; int *rx_bits; int tx_sync_bit; + int smooth_symbols; + float *prev_rx_bits; int *ptest_bits_coh; int *ptest_bits_coh_end; @@ -75,6 +77,7 @@ struct freedv { int sync; float snr_est; float snr_squelch_thresh; + float squelch_en; int nin; struct VARICODE_DEC varicode_dec_states; diff --git a/codec2-dev/src/freedv_rx.c b/codec2-dev/src/freedv_rx.c index d9496696..b39dd575 100644 --- a/codec2-dev/src/freedv_rx.c +++ b/codec2-dev/src/freedv_rx.c @@ -90,6 +90,9 @@ int main(int argc, char *argv[]) { if ( (argc > 4) && (strcmp(argv[4], "--testframes") == 0) ) { freedv->test_frames = 1; } + if ( (argc > 4) && (strcmp(argv[4], "--smooth") == 0) ) { + freedv->smooth_symbols = 1; + } speech_out = (short*)malloc(sizeof(short)*freedv->n_speech_samples); assert(speech_out != NULL); -- 2.25.1