From: drowe67 Date: Wed, 15 Jul 2015 04:42:22 +0000 (+0000) Subject: support for error pattern logging in freedv api X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=de007cdd0a8cb3afc8a68f71d4e2c237cbbe55aa;p=freetel-svn-tracking.git support for error pattern logging in freedv api git-svn-id: https://svn.code.sf.net/p/freetel/code@2237 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/codec2.c b/codec2-dev/src/codec2.c index debb89eb..8482fb87 100644 --- a/codec2-dev/src/codec2.c +++ b/codec2-dev/src/codec2.c @@ -1396,7 +1396,7 @@ void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]) e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD_LOW); e_index = encode_energy(e, 3); pack_natural_or_gray(bits, &nbit, e_index, 3, c2->gray); - + for(i=0; ifbb_phase_rx, nin); @@ -958,6 +959,7 @@ void cohpsk_demod(struct COHPSK *coh, float rx_bits[], int *sync_good, COMP rx_f /* we can test +/- 20Hz, so we break this up into 3 tests to cover +/- 60Hz */ max_ratio = 0.0; + f_est = 0.0; for (coh->f_est = FDMDV_FCENTRE-40.0; coh->f_est <= FDMDV_FCENTRE+40.0; coh->f_est += 40.0) { if (coh->verbose) @@ -1212,14 +1214,33 @@ void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[], } } - if (*state == 1) { + /* if 5 frames with large BER reset test frame sync */ + + if (*state > 0) { + if (*bit_errors > 8) { + if (*state == 6) + next_state = 0; + else + next_state = *state+1; + } + else + next_state = 1; + } + + if (*state > 0) { coh->ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME; if (coh->ptest_bits_coh_rx >= coh->ptest_bits_coh_end) { coh->ptest_bits_coh_rx = (int*)test_bits_coh; } } + + //fprintf(stderr, "state: %d next_state: %d bit_errors: %d\n", *state, next_state, *bit_errors); *state = next_state; } +int cohpsk_error_pattern_size(void) { + return COHPSK_BITS_PER_FRAME; +} + diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index 9feb6b77..7ff16c59 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -1819,12 +1819,15 @@ static float randn() { Simple channel simulation function to aid in testing. Target SNR uses noise measured in a 3 kHz bandwidth. + Doesn't use fdmdv states so can be called from anywhere, e.g. non + fdmdv applications. + TODO: Measured SNR is coming out a few dB higher than target_snr, this needs to be fixed. \*---------------------------------------------------------------------------*/ -void fdmdv_simulate_channel(struct FDMDV *f, COMP samples[], int nin, float target_snr) +void fdmdv_simulate_channel(float *sig_pwr_av, COMP samples[], int nin, float target_snr) { float sig_pwr, target_snr_linear, noise_pwr, noise_pwr_1Hz, noise_pwr_4000Hz, noise_gain; int i; @@ -1837,12 +1840,12 @@ void fdmdv_simulate_channel(struct FDMDV *f, COMP samples[], int nin, float targ sig_pwr /= nin; - f->sig_pwr_av = 0.9*f->sig_pwr_av + 0.1*sig_pwr; + *sig_pwr_av = 0.9**sig_pwr_av + 0.1*sig_pwr; /* det noise to meet target SNR */ target_snr_linear = powf(10.0, target_snr/10.0); - noise_pwr = f->sig_pwr_av/target_snr_linear; /* noise pwr in a 3000 Hz BW */ + noise_pwr = *sig_pwr_av/target_snr_linear; /* noise pwr in a 3000 Hz BW */ noise_pwr_1Hz = noise_pwr/3000.0; /* noise pwr in a 1 Hz bandwidth */ noise_pwr_4000Hz = noise_pwr_1Hz*4000.0; /* noise pwr in a 4000 Hz BW, which due to fs=8000 Hz in our simulation noise BW */ diff --git a/codec2-dev/src/fdmdv_mod.c b/codec2-dev/src/fdmdv_mod.c index 662fd80f..5fac650a 100644 --- a/codec2-dev/src/fdmdv_mod.c +++ b/codec2-dev/src/fdmdv_mod.c @@ -130,7 +130,7 @@ int main(int argc, char *argv[]) /* optional freq shift and channel simulation */ fdmdv_freq_shift(tx_fdm, tx_fdm, foff, &foff_phase_rect, 2*FDMDV_NOM_SAMPLES_PER_FRAME); - fdmdv_simulate_channel(fdmdv, tx_fdm, 2*FDMDV_NOM_SAMPLES_PER_FRAME, 10.0); + fdmdv_simulate_channel(&sig_pwr_av, tx_fdm, 2*FDMDV_NOM_SAMPLES_PER_FRAME, 10.0); #endif /* scale and save to disk as shorts */ diff --git a/codec2-dev/src/freedv_api.c b/codec2-dev/src/freedv_api.c index 9e846cfc..6baf8d79 100644 --- a/codec2-dev/src/freedv_api.c +++ b/codec2-dev/src/freedv_api.c @@ -72,6 +72,8 @@ struct freedv *freedv_open(int mode) { f->mode = mode; f->test_frames = f->smooth_symbols = 0; + f->freedv_put_error_pattern = NULL; + f->error_pattern_callback_state = NULL; f->snr_squelch_thresh = 2.0; f->squelch_en = 1; @@ -97,6 +99,7 @@ struct freedv *freedv_open(int mode) { if ((f->tx_bits == NULL) || (f->rx_bits == NULL)) return NULL; f->evenframe = 0; + f->sz_error_pattern = fdmdv_error_pattern_size(f->fdmdv); } if (mode == FREEDV_MODE_700) { @@ -111,6 +114,7 @@ struct freedv *freedv_open(int mode) { f->tx_bits = (int*)malloc(nbit*sizeof(int)); if (f->tx_bits == NULL) return NULL; + f->sz_error_pattern = cohpsk_error_pattern_size(); } f->test_frame_sync_state = 0; @@ -578,7 +582,10 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) { if (f->test_frame_count == 0) { f->total_bit_errors += bit_errors; f->total_bits += ntest_bits; - } + if (f->freedv_put_error_pattern != NULL) { + (*f->freedv_put_error_pattern)(f->error_pattern_callback_state, error_pattern, fdmdv_error_pattern_size(f->fdmdv)); + } + } f->test_frame_count++; if (f->test_frame_count == 4) f->test_frame_count = 0; @@ -699,11 +706,12 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) { /* test data, lets see if we can sync to the test data sequence */ cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors, rx_bits); - if (f->test_frame_sync_state == 1) { - //for(i=0; itest_frame_sync_state) { f->total_bit_errors += bit_errors; f->total_bits += COHPSK_BITS_PER_FRAME; + if (f->freedv_put_error_pattern != NULL) { + (*f->freedv_put_error_pattern)(f->error_pattern_callback_state, error_pattern, COHPSK_BITS_PER_FRAME); + } } for(i=0; in_speech_samples; i++) diff --git a/codec2-dev/src/freedv_api.h b/codec2-dev/src/freedv_api.h index eac86c77..556e01ce 100644 --- a/codec2-dev/src/freedv_api.h +++ b/codec2-dev/src/freedv_api.h @@ -73,6 +73,12 @@ struct freedv { int test_frame_count; int total_bits; int total_bit_errors; + int sz_error_pattern; + + /* optional user defined function to pass error pattern when a test frame is received */ + + void *error_pattern_callback_state; + void (*freedv_put_error_pattern)(void *error_pattern_callback_state, short error_pattern[], int sz_error_pattern); int sync; int evenframe;