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; i<LPC_ORD_LOW; i++) {
f = (4000.0/PI)*lsps[i];
mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5);
void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]);
void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
int *bit_errors, float rx_bits_sd[]);
+int cohpsk_error_pattern_size(void);
void cohpsk_set_frame(struct COHPSK *coh, int frame);
#endif
/* debug/development function(s) */
void fdmdv_dump_osc_mags(struct FDMDV *f);
-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);
#ifdef __cplusplus
}
/* sample correlation over 2D grid of time and fine freq points */
- max_corr = 0;
+ max_corr = max_mag = 0;
for (f_fine=-20; f_fine<=20; f_fine+=0.25) {
for (t=0; t<NSYMROWPILOT; t++) {
corr_with_pilots(&corr, &mag, coh, t, f_fine);
COMP rx_fdm_frame_bb[COHPSK_M+COHPSK_M/P];
COMP rx_baseband[COHPSK_NC*ND][COHPSK_M+COHPSK_M/P];
COMP rx_filt[COHPSK_NC*ND][P+1];
- float env[NT*P], __attribute__((unused)) rx_timing;
+ float env[NT*P], rx_timing;
COMP rx_onesym[COHPSK_NC*ND];
float beta, g;
COMP adiff, amod_strip, mod_strip;
ch_fdm_frame_index = 0;
+ rx_timing = 0;
for (r=0; r<nsymb; r++) {
fdmdv_freq_shift_coh(rx_fdm_frame_bb, &ch_fdm_frame[ch_fdm_frame_index], -(*f_est), &fdmdv->fbb_phase_rx, nin);
/* 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)
}
}
- 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;
+}
+
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;
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 */
/* 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 */
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;
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) {
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;
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;
/* 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; i<COHPSK_BITS_PER_FRAME; i++)
- // error_positions_hist[i] += error_pattern[i];
+ if (f->test_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; i<f->n_speech_samples; i++)
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;