From e336852e23d13be86cb2c4d6466835b120ab7530 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Tue, 26 May 2015 10:51:01 +0000 Subject: [PATCH] Fs offset tests passing, C and Octave match over 35 frames git-svn-id: https://svn.code.sf.net/p/freetel/code@2150 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/tcohpsk.m | 27 +++++++++++++++++++++------ codec2-dev/src/cohpsk.c | 32 ++++++++++++++++++++++++++++++++ codec2-dev/src/cohpsk_internal.h | 2 ++ codec2-dev/unittest/tcohpsk.c | 17 ++++++++++++----- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/codec2-dev/octave/tcohpsk.m b/codec2-dev/octave/tcohpsk.m index 7364a06b..4e4de76f 100644 --- a/codec2-dev/octave/tcohpsk.m +++ b/codec2-dev/octave/tcohpsk.m @@ -71,13 +71,13 @@ Fs = 7500; if strcmp(test, 'compare to c') frames = 35; - foff = 0; - dfoff = 0; + foff = 58.7; + dfoff = -0.5/Fs; EsNodB = 8; fading_en = 0; hf_delay_ms = 2; compare_with_c = 1; - sample_rate_ppm = 0; + sample_rate_ppm = -1000; ssb_tx_filt = 0; end @@ -91,7 +91,7 @@ if strcmp(test, 'awgn') fading_en = 0; hf_delay_ms = 2; compare_with_c = 0; - sample_rate_ppm = 0; + sample_rate_ppm = -1000; end % Similar to AWGN - should be BER around 0.015 to 0.02 @@ -333,7 +333,21 @@ end % simulate difference in sample clocks -ch_fdm_frame_log = resample(ch_fdm_frame_log, (1E6 + sample_rate_ppm), 1E6); +%ch_fdm_frame_log = resample(ch_fdm_frame_log, (1E6 + sample_rate_ppm), 1E6); + +ch_fdm_frame_log_out = zeros(1, length(ch_fdm_frame_log)); +tin=1; +tout=1; +while tin < length(ch_fdm_frame_log) + t1 = floor(tin); + t2 = ceil(tin); + f = tin - t1; + ch_fdm_frame_log_out(tout) = (1-f)*ch_fdm_frame_log(t1) + f*ch_fdm_frame_log(t2); + tout += 1; + tin += 1+sample_rate_ppm/1E6; + %printf("tin: %f tout: %f f: %f\n", tin, tout, f); +end +ch_fdm_frame_log = ch_fdm_frame_log_out; % Now run demod ---------------------------------------------------------------- @@ -543,12 +557,13 @@ if compare_with_c stem_sig_and_error(8, 211, rx_amp_log_c, rx_amp_log - rx_amp_log_c, 'Amp Est', [1 n -1.5 1.5]) phi_log_diff = rx_phi_log - rx_phi_log_c; phi_log_diff(find(phi_log_diff > pi)) -= 2*pi; + phi_log_diff(find(phi_log_diff < -pi)) += 2*pi; stem_sig_and_error(8, 212, rx_phi_log_c, phi_log_diff, 'Phase Est', [1 n -4 4]) stem_sig_and_error(9, 211, real(rx_symb_log_c), real(rx_symb_log - rx_symb_log_c), 'rx symb re', [1 n -1.5 1.5]) stem_sig_and_error(9, 212, imag(rx_symb_log_c), imag(rx_symb_log - rx_symb_log_c), 'rx symb im', [1 n -1.5 1.5]) stem_sig_and_error(10, 111, rx_bits_log_c, rx_bits_log - rx_bits_log_c, 'rx bits', [1 length(rx_bits_log) -1.5 1.5]) - stem_sig_and_error(11, 111, f_est_log_c - Fcentre, f_est_log - f_est_log_c, 'f est', [1 length(f_est_log) foff-5 foff+5]) + stem_sig_and_error(11, 111, f_est_log_c, f_est_log - f_est_log_c, 'f est', [1 length(f_est_log) min(f_est_log) max(f_est_log)]) stem_sig_and_error(12, 111, rx_timing_log_c, rx_timing_log_c - rx_timing_log, 'rx timing', [1 length(rx_timing_log) -M M]) check(tx_bits_log, tx_bits_log_c, 'tx_bits'); diff --git a/codec2-dev/src/cohpsk.c b/codec2-dev/src/cohpsk.c index e26c310e..69806802 100644 --- a/codec2-dev/src/cohpsk.c +++ b/codec2-dev/src/cohpsk.c @@ -1027,3 +1027,35 @@ void cohpsk_demod(struct COHPSK *coh, int rx_bits[], int *reliable_sync_bit, COM *nin_frame = (NSYMROWPILOT-1)*COHPSK_M + nin; //printf("%f %d %d\n", coh->rx_timing, nin, *nin_frame); } + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: cohpsk_fs_offset() + AUTHOR......: David Rowe + DATE CREATED: May 2015 + + Simulates small Fs offset between mod and demod. + +\*---------------------------------------------------------------------------*/ + +int cohpsk_fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm) +{ + double tin, f; + int tout, t1, t2; + + tin = 0.0; tout = 0; + while (tin < n) { + t1 = floor(tin); + t2 = ceil(tin); + f = tin - t1; + out[tout].real = (1.0-f)*in[t1].real + f*in[t2].real; + out[tout].imag = (1.0-f)*in[t1].imag + f*in[t2].imag; + tout += 1; + tin += 1.0 + sample_rate_ppm/1E6; + //printf("tin: %f tout: %d f: %f\n", tin, tout, f); + } + + return tout; +} + diff --git a/codec2-dev/src/cohpsk_internal.h b/codec2-dev/src/cohpsk_internal.h index 5a8c0474..9fc82963 100644 --- a/codec2-dev/src/cohpsk_internal.h +++ b/codec2-dev/src/cohpsk_internal.h @@ -98,4 +98,6 @@ void fine_freq_correct(struct COHPSK *coh, int sync, int next_sync); int sync_state_machine(struct COHPSK *coh, int sync, int next_sync); void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin); +int cohpsk_fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm); + #endif diff --git a/codec2-dev/unittest/tcohpsk.c b/codec2-dev/unittest/tcohpsk.c index 49a0c9ce..d0cc5d59 100644 --- a/codec2-dev/unittest/tcohpsk.c +++ b/codec2-dev/unittest/tcohpsk.c @@ -48,9 +48,10 @@ #define SYNC_FRAMES 12 /* sync state uses up extra log storage as we reprocess several times */ #define FRAMESL (SYNC_FRAMES*FRAMES) /* worst case is every frame is out of sync */ -#define FOFF 0 //55.5 -#define DFOFF 0 //(-0.5/(float)COHPSK_FS) +#define FOFF 58.7 +#define DFOFF (-0.5/(float)COHPSK_FS) #define ESNODB 8 +#define PPM -1000 extern float pilots_coh[][PILOTS_NC]; @@ -69,6 +70,7 @@ int main(int argc, char *argv[]) COMP tx_symb_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND]; COMP tx_fdm_frame_log[COHPSK_M*NSYMROWPILOT*FRAMES]; COMP ch_fdm_frame_log[COHPSK_M*NSYMROWPILOT*FRAMES]; + COMP ch_fdm_frame_log_out[(COHPSK_M*NSYMROWPILOT+1)*FRAMES]; //COMP rx_fdm_frame_bb_log[M*NSYMROWPILOT*FRAMES]; //COMP ch_symb_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND]; COMP ct_symb_ff_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND]; @@ -99,7 +101,7 @@ int main(int argc, char *argv[]) float EsNo, variance; COMP scaled_noise; int reliable_sync_bit; - int ch_fdm_frame_log_index, nin_frame, tmp; + int ch_fdm_frame_log_index, nin_frame, tmp, nout; coh = cohpsk_create(); fdmdv = coh->fdmdv; @@ -192,6 +194,11 @@ int main(int argc, char *argv[]) } } + /* Fs offset simulation */ + + nout = cohpsk_fs_offset(ch_fdm_frame_log_out, ch_fdm_frame_log, COHPSK_M*NSYMROWPILOT*FRAMES, PPM); + assert(nout < (COHPSK_M*NSYMROWPILOT+1)*FRAMES); + nin_frame = COHPSK_SAMPLES_PER_FRAME; ch_fdm_frame_log_index = 0; @@ -206,7 +213,7 @@ int main(int argc, char *argv[]) assert(ch_fdm_frame_log_index < COHPSK_M*NSYMROWPILOT*FRAMES); tmp = nin_frame; - cohpsk_demod(coh, rx_bits, &reliable_sync_bit, &ch_fdm_frame_log[ch_fdm_frame_log_index], &nin_frame); + cohpsk_demod(coh, rx_bits, &reliable_sync_bit, &ch_fdm_frame_log_out[ch_fdm_frame_log_index], &nin_frame); ch_fdm_frame_log_index += tmp; /* --------------------------------------------------------*\ @@ -252,7 +259,7 @@ int main(int argc, char *argv[]) octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, COHPSK_BITS_PER_FRAME*FRAMES); octave_save_complex(fout, "tx_symb_log_c", (COMP*)tx_symb_log, NSYMROWPILOT*FRAMES, COHPSK_NC*ND, COHPSK_NC*ND); octave_save_complex(fout, "tx_fdm_frame_log_c", (COMP*)tx_fdm_frame_log, 1, COHPSK_M*NSYMROWPILOT*FRAMES, COHPSK_M*NSYMROWPILOT*FRAMES); - octave_save_complex(fout, "ch_fdm_frame_log_c", (COMP*)ch_fdm_frame_log, 1, COHPSK_M*NSYMROWPILOT*FRAMES, COHPSK_M*NSYMROWPILOT*FRAMES); + octave_save_complex(fout, "ch_fdm_frame_log_c", (COMP*)ch_fdm_frame_log_out, 1, nout-1, nout-1); //octave_save_complex(fout, "rx_fdm_frame_bb_log_c", (COMP*)rx_fdm_frame_bb_log, 1, M*NSYMROWPILOT*FRAMES, M*NSYMROWPILOT*FRAMES); octave_save_complex(fout, "rx_baseband_log_c", (COMP*)coh->rx_baseband_log, COHPSK_NC*ND, coh->rx_baseband_log_col_index, coh->rx_baseband_log_col_sz); octave_save_complex(fout, "rx_filt_log_c", (COMP*)coh->rx_filt_log, COHPSK_NC*ND, coh->rx_filt_log_col_index, coh->rx_filt_log_col_sz); -- 2.25.1