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
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
% 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 ----------------------------------------------------------------
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');
*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;
+}
+
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
#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];
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];
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;
}
}
+ /* 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;
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;
/* --------------------------------------------------------*\
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);