% Symbol rate processing for rx side (demodulator) -------------------------------------------------------
-function [rx_symb rx_bits amp_ phi_ EsNo_ cohpsk] = qpsk_symbols_to_bits(cohpsk, ct_symb_buf)
+function [rx_symb rx_bits rx_symb_linear amp_ phi_ EsNo_ cohpsk] = qpsk_symbols_to_bits(cohpsk, ct_symb_buf)
framesize = cohpsk.framesize;
Nsymb = cohpsk.Nsymb;
Nsymbrow = cohpsk.Nsymbrow;
for c=1:Nc
corr = pilot2(:,c)' * ct_symb_buf(sampling_points,c);
mag = sum(abs(ct_symb_buf(sampling_points,c)));
-
+
phi_(:, c) = angle(corr);
amp_(:, c) = mag/length(sampling_points);
end
phase_offset = 0;
w_offset = pi/16;
+ ct_symb_buf = zeros(2*Nsymbrowpilot, Nc);
+
% simulation starts here-----------------------------------
for nn = 1:Ntrials+2
tx_bits = round(rand(1,framesize));
end
- [s_ch tx_bits prev_sym_tx] = bits_to_qpsk_symbols(sim_in, tx_bits, code_param, prev_sym_tx);
+ [tx_symb tx_bits prev_sym_tx] = bits_to_qpsk_symbols(sim_in, tx_bits, code_param, prev_sym_tx);
tx_bits_buf(1:framesize) = tx_bits_buf(framesize+1:2*framesize);
tx_bits_buf(framesize+1:2*framesize) = tx_bits;
+ s_ch = tx_symb;
+
% HF channel simulation ------------------------------------
hf_fading = ones(1,Nsymb);
s_ch = s_ch + noise;
- [rx_symb rx_bits amp_ phi_ EsNo_ sim_in] = qpsk_symbols_to_bits(sim_in, s_ch);
+ ct_symb_buf(1:Nsymbrowpilot,:) = ct_symb_buf(Nsymbrowpilot+1:2*Nsymbrowpilot,:);
+ ct_symb_buf(Nsymbrowpilot+1:2*Nsymbrowpilot,:) = s_ch;
+
+ [rx_symb rx_bits rx_symb_linear amp_ phi_ EsNo_ sim_in] = qpsk_symbols_to_bits(sim_in, ct_symb_buf(1:Nsymbrowpilot+Npilotsframe,:));
phi_log = [phi_log; phi_];
amp_log = [amp_log; amp_];
- % Wait until we have 3 frames to do pilot assisted phase estimation
+ % Wait until we have enough frames to do pilot assisted phase estimation
- if nn > 2
+ if nn > 1
rx_symb_log = [rx_symb_log rx_symb_linear];
EsNo__log = [EsNo__log EsNo_];
if verbose
av_tx_pwr = (s_ch_tx_log * s_ch_tx_log')/length(s_ch_tx_log);
- printf("EsNo est (dB): %3.1f Terrs: %d Tbits: %d BER %4.2f QPSK BER theory %4.2f av_tx_pwr: %3.2f",
- mean(10*log10(EsNo__log)), Terrs, Tbits,
+ printf("EsNo (dB): %3.1f Terrs: %d Tbits: %d BER %5.3f QPSK BER theory %5.3f av_tx_pwr: %3.2f",
+ EsNodB, Terrs, Tbits,
Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
if ldpc_code
printf("\n LDPC: Terrs: %d BER: %4.2f Ferrs: %d FER: %4.2f",
ct_symb_ff_log = [ct_symb_ff_log; acohpsk.ct_symb_ff_buf(1:acohpsk.Nsymbrowpilot,:)];
if (sync == 4) || (next_sync == 4)
- [rx_symb rx_bits amp_ phi_ EsNo_] = qpsk_symbols_to_bits(acohpsk, acohpsk.ct_symb_ff_buf);
+ [rx_symb rx_bits rx_symb_linear amp_ phi_ EsNo_] = qpsk_symbols_to_bits(acohpsk, acohpsk.ct_symb_ff_buf);
rx_symb_log = [rx_symb_log; rx_symb];
rx_amp_log = [rx_amp_log; amp_];
rx_phi_log = [rx_phi_log; phi_];
sim_in.ldpc_code_rate = 1;
sim_in.ldpc_code = 0;
- sim_in.Ntrials = 35;
+ sim_in.Ntrials = 500;
sim_in.Esvec = 8;
sim_in.hf_sim = 0;
sim_in.hf_mag_only = 0;
more off;
%test_curves();
-%test_single();
+test_single();
%rate_Fs_tx("tx_zero.raw");
%rate_Fs_tx("tx.raw");
%rate_Fs_rx("tx_-4dB.wav")
%rate_Fs_rx("tx.raw")
%test_freq_off_est("tx.raw",40,6400)
-gen_test_bits();
+%gen_test_bits();
#define COHPSK_BITS_PER_FRAME 32 /* hard coded for now */
#define COHPSK_NC 4 /* hard coded for now */
#define COHPSK_SAMPLES_PER_FRAME 960
+#define COHPSK_RS 50
+#define COHPSK_FS 8000
#include "comp.h"
#include "codec2_fdmdv.h"
[ ] fading channel
[ ] freq drift
[ ] timing drift
- [ ] tune and meas impl loss perf for above
+ [ ] tune perf/impl loss to get closer to ideal
[ ] freq offset/drift feedback loop
[ ] smaller freq est block size to min ram req
float freq_hz;
assert(COHPSK_SAMPLES_PER_FRAME == M*NSYMROWPILOT);
+ assert(COHPSK_RS == RS);
+ assert(COHPSK_FS == FS);
coh = (struct COHPSK*)malloc(sizeof(struct COHPSK));
if (coh == NULL)
bin_est = num/den;
coh->f_est = floor(bin_est/sc+0.5);
- fprintf(stderr, "coarse freq est: %f\n", coh->f_est);
+ fprintf(stderr, " coarse freq est: %f\n", coh->f_est);
*next_sync = 1;
}
fprintf(stderr, " fine freq f: %f max_corr: %f max_mag: %f ct: %d\n", coh->f_fine_est, max_corr, max_mag, coh->ct);
if (max_corr/max_mag > 0.9) {
- fprintf(stderr, "in sync!\n");
+ fprintf(stderr, " in sync!\n");
*next_sync = 4;
coh->sync_timer = 0;
}
#include "comp_prim.h"
#include "noise_samples.h"
-#define FRAMES 350
-#define FOFFHZ 10.5
+#define FRAMES 350
+#define FOFF_HZ 10.5
+#define ES_NO_DB 12.0
int main(int argc, char *argv[])
{
int noise_r, noise_end;
float corr;
int state, next_state, nerrors, nbits, reliable_sync_bit;
+ float EsNo, variance;
+ COMP scaled_noise;
+ float EsNodB, foff_hz;
+
+ EsNodB = ES_NO_DB;
+ foff_hz = FOFF_HZ;
+ if (argc == 3) {
+ EsNodB = atof(argv[1]);
+ foff_hz = atof(argv[2]);
+ }
+ fprintf(stderr, "EsNodB: %4.2f foff: %4.2f Hz\n", EsNodB, foff_hz);
coh = cohpsk_create();
assert(coh != NULL);
noise_r = 0;
noise_end = sizeof(noise)/sizeof(COMP);
+ /* each carrier has power = 2, total power 2Nc, total symbol rate
+ NcRs, noise BW B=Fs Es/No = (C/Rs)/(N/B), N = var =
+ 2NcFs/NcRs(Es/No) = 2Fs/Rs(Es/No) */
+
+ EsNo = pow(10.0, EsNodB/10.0);
+ variance = 2.0*COHPSK_FS/(COHPSK_RS*EsNo);
+
/* Main Loop ---------------------------------------------------------------------*/
for(f=0; f<FRAMES; f++) {
Channel
\*---------------------------------------------------------*/
- fdmdv_freq_shift(ch_fdm, tx_fdm, FOFFHZ, &phase_ch, COHPSK_SAMPLES_PER_FRAME);
+ fdmdv_freq_shift(ch_fdm, tx_fdm, foff_hz, &phase_ch, COHPSK_SAMPLES_PER_FRAME);
for(r=0; r<COHPSK_SAMPLES_PER_FRAME; r++) {
- ch_fdm[r] = cadd(ch_fdm[r], noise[noise_r]);
- noise_r++;
- if (noise_r > noise_end)
- noise_r = 0;
- }
+ scaled_noise = fcmult(sqrt(variance), noise[noise_r]);
+ ch_fdm[r] = cadd(ch_fdm[r], scaled_noise);
+ noise_r++;
+ if (noise_r > noise_end)
+ noise_r = 0;
+ }
/* --------------------------------------------------------*\
Demod
corr += (1.0 - 2.0*(rx_bits[i] & 0x1)) * (1.0 - 2.0*ptest_bits_coh_rx[i]);
}
- /* state logic to sybc up to test data */
+ /* state logic to sync up to test data */
next_state = state;
if (state == 0) {
- fprintf(stderr, "corr %f\n", corr);
if (reliable_sync_bit && (corr == COHPSK_BITS_PER_FRAME)) {
next_state = 1;
ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME;
nerrors = COHPSK_BITS_PER_FRAME - corr;
nbits = COHPSK_BITS_PER_FRAME;
+ fprintf(stderr, " test data sync\n");
+
}
}
state = next_state;
}
- printf("BER: %3.2f Nbits: %d Nerrors: %d\n", (float)nerrors/nbits, nbits, nerrors);
+ printf("%4.3f %d %d\n", (float)nerrors/nbits, nbits, nerrors);
cohpsk_destroy(coh);