% Symbol rate processing for tx side (modulator) -------------------------------------------------------
+% legacy DQPSK mod for comparative testing
+
function [tx_symb prev_tx_symb] = bits_to_dqpsk_symbols(sim_in, tx_bits, prev_tx_symb)
Nc = sim_in.Nc;
Nsymbrow = sim_in.Nsymbrow;
endfunction
+% legacy DQPSK demod for comparative testing
+
function [rx_symb rx_bits rx_symb_linear prev_rx_symb] = dqpsk_symbols_to_bits(sim_in, rx_symb, prev_rx_symb)
Nc = sim_in.Nc;
Nsymbrow = sim_in.Nsymbrow;
tx_symb = [pilot(1,:); pilot(2,:); tx_symb;];
- % Optionally copy to other carriers (diversity)
+ % copy to other carriers (diversity)
tmp = tx_symb;
for d=1:Nd-1
sampling_points = [1 2 7 8];
pilot2 = [cohpsk.pilot(1,:); cohpsk.pilot(2,:); cohpsk.pilot(1,:); cohpsk.pilot(2,:);];
- phi_ = zeros(Nsymbrow, Nc);
- amp_ = zeros(Nsymbrow, Nc);
+ phi_ = zeros(Nsymbrow, Nc*Nd);
+ amp_ = zeros(Nsymbrow, Nc*Nd);
for c=1:Nc*Nd
%corr = pilot2(:,c)' * ct_symb_buf(sampling_points,c);
[m b] = linreg(sampling_points, y, length(sampling_points));
yfit = m*[3 4 5 6] + b;
phi_(:, c) = angle(yfit);
-
+ %for r=1:Nsymbrow
+ % printf(" %f", phi_(r,c));
+ %end
+ %printf("\n");
mag = sum(abs(ct_symb_buf(sampling_points,c)));
amp_(:, c) = mag/length(sampling_points);
end
Ndft = cohpsk.Ndft;
if sync == 0
- f_start = Fcentre - ((Nc/2)+2)*Fsep;
+ f_start = Fcentre - ((Nc/2)+2)*Fsep;
f_stop = Fcentre + ((Nc/2)+2)*Fsep;
ll = length(ch_fdm_frame);
h = 0.5 - 0.5*cos(2*pi*(0:ll-1)/(ll-1));
x = bin_start-1:bin_stop-1;
bin_est = x*T(bin_start:bin_stop)'/sum(T(bin_start:bin_stop));
cohpsk.f_est = floor(bin_est/sc+0.5);
- printf("coarse freq est: %f\n", cohpsk.f_est);
+ printf(" coarse freq est: %f\n", cohpsk.f_est);
next_sync = 1;
end
Rs = cohpsk.Rs;
Nsymbrowpilot = cohpsk.Nsymbrowpilot;
Nc = cohpsk.Nc;
+ Nd = cohpsk.Nd;
% update memory in symbol buffer
f_fine_rect = exp(-j*f_fine*2*pi*sampling_points/Rs)';
for t=0:cohpsk.Nsymbrowpilot-1
corr = 0; mag = 0;
- for c=1:Nc
+ for c=1:Nc*Nd
f_corr_vec = f_fine_rect .* ct_symb_buf(t+sampling_points,c);
for p=1:length(sampling_points)
- corr += pilot2(p,c) * f_corr_vec(p);
+ corr += pilot2(p,c-Nc*floor((c-1)/Nc)) * f_corr_vec(p);
mag += abs(f_corr_vec(p));
end
end
printf(" fine freq f: %f max_corr: %f max_mag: %f ct: %d\n", cohpsk.f_fine_est, abs(max_corr), max_mag, cohpsk.ct);
if max_corr/max_mag > 0.9
- printf("in sync!\n");
+ printf(" in sync!\n");
next_sync = 4;
else
next_sync = 0;
afdmdv.gt_alpha5_root = gt_alpha5_root;
afdmdv.Fsep = 75;
afdmdv.phase_tx = ones(afdmdv.Nc+1,1);
-freq_hz = Fsep*( -afdmdv.Nc/2 - 0.5 + (1:afdmdv.Nc+1) );
+freq_hz = afdmdv.Fsep*( -Nc*Nd/2 - 0.5 + (1:Nc*Nd) );
afdmdv.freq_pol = 2*pi*freq_hz/Fs;
afdmdv.freq = exp(j*afdmdv.freq_pol);
afdmdv.Fcentre = 1500;
end
-if 0
stem_sig_and_error(1, 111, tx_bits_log_c(1:n), tx_bits_log(1:n) - tx_bits_log_c(1:n), 'tx bits', [1 n -1.5 1.5])
stem_sig_and_error(2, 211, real(tx_symb_log_c(1:n)), real(tx_symb_log(1:n) - tx_symb_log_c(1:n)), 'tx symb re', [1 n -1.5 1.5])
stem_sig_and_error(2, 212, imag(tx_symb_log_c(1:n)), imag(tx_symb_log(1:n) - tx_symb_log_c(1:n)), 'tx symb im', [1 n -1.5 1.5])
stem_sig_and_error(6, 212, imag(ch_symb_log_c), imag(ch_symb_log - ch_symb_log_c), 'ch symb im', [1 n -1.5 1.5])
stem_sig_and_error(7, 211, real(ct_symb_ff_log_c), real(ct_symb_ff_log - ct_symb_ff_log_c), 'ct symb ff re', [1 n -1.5 1.5])
stem_sig_and_error(7, 212, imag(ct_symb_ff_log_c), imag(ct_symb_ff_log - ct_symb_ff_log_c), 'ct symb ff im', [1 n -1.5 1.5])
-
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])
stem_sig_and_error(8, 212, rx_phi_log_c, rx_phi_log - rx_phi_log_c, '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])
Tbits_c = length(tx_bits_prev_log);
ber_c = Nerrs_c/Tbits_c;
ber = Nerrs/Tbits;
-end
printf("EsNodB: %4.1f ber_c: %3.2f Nerrs_c: %d Tbits_c: %d\n", EsNodB, ber_c, Nerrs_c, Tbits_c);
#define COHPSK_SAMPLES_PER_FRAME 960
#define COHPSK_RS 50
#define COHPSK_FS 8000
+#define COHPSK_ND 2 /* diversity factor */
#include "comp.h"
#include "codec2_fdmdv.h"
struct COHPSK *cohpsk_create(void);
void cohpsk_destroy(struct COHPSK *coh);
-void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC], int tx_bits[], int nbits);
-void qpsk_symbols_to_bits(struct COHPSK *coh, int rx_bits[], COMP ct_symb_buf[][COHPSK_NC]);
+void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC*COHPSK_ND], int tx_bits[], int nbits);
+void qpsk_symbols_to_bits(struct COHPSK *coh, int rx_bits[], COMP ct_symb_buf[][COHPSK_NC*COHPSK_ND]);
void coarse_freq_offset_est(struct COHPSK *coh, struct FDMDV *fdmdv, COMP ch_fdm_frame[], int sync, int *next_sync);
-void frame_sync_fine_freq_est(struct COHPSK *coh, COMP ch_symb[][COHPSK_NC], int sync, int *next_sync);
+void frame_sync_fine_freq_est(struct COHPSK *coh, COMP ch_symb[][COHPSK_NC*COHPSK_ND], int sync, int *next_sync);
void fine_freq_correct(struct COHPSK *coh, int sync, int next_sync);
int sync_state_machine(struct COHPSK *coh, int sync, int next_sync);
int r,c,p,i;
float freq_hz;
+ assert(COHPSK_NC == PILOTS_NC);
assert(COHPSK_SAMPLES_PER_FRAME == M*NSYMROWPILOT);
assert(COHPSK_RS == RS);
assert(COHPSK_FS == FS);
+ assert(COHPSK_ND == ND);
coh = (struct COHPSK*)malloc(sizeof(struct COHPSK));
if (coh == NULL)
for(r=0; r<2*NPILOTSFRAME; ) {
for(p=0; p<NPILOTSFRAME; r++, p++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC; c++) {
coh->pilot2[r][c] = pilots_coh[p][c];
}
}
/* Clear symbol buffer memory */
for (r=0; r<NCT_SYMB_BUF; r++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
coh->ct_symb_buf[r][c].real = 0.0;
coh->ct_symb_buf[r][c].imag = 0.0;
}
/* set up fdmdv states so we can use those modem functions */
- fdmdv = fdmdv_create(PILOTS_NC - 1);
- for(c=0; c<PILOTS_NC; c++) {
+ fdmdv = fdmdv_create(COHPSK_NC*ND - 1);
+ for(c=0; c<COHPSK_NC*ND; c++) {
fdmdv->phase_tx[c].real = 1.0;
fdmdv->phase_tx[c].imag = 0.0;
- freq_hz = fdmdv->fsep*( -PILOTS_NC/2 - 0.5 + c + 1.0 );
+ freq_hz = fdmdv->fsep*( -(COHPSK_NC*ND)/2 - 0.5 + c + 1.0 );
fdmdv->freq[c].real = cosf(2.0*M_PI*freq_hz/FS);
fdmdv->freq[c].imag = sinf(2.0*M_PI*freq_hz/FS);
fdmdv->freq_pol[c] = 2.0*M_PI*freq_hz/FS;
\*---------------------------------------------------------------------------*/
-void bits_to_qpsk_symbols(COMP tx_symb[][PILOTS_NC], int tx_bits[], int nbits)
+void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC*ND], int tx_bits[], int nbits)
{
- int i, r, c, p_r, data_r;
+ int i, r, c, p_r, data_r, d;
short bits;
- assert(COHPSK_NC == PILOTS_NC);
- assert((NSYMROW*PILOTS_NC)*2 == nbits);
+ /* check number of bits supplied matchs number of QPSK symbols in the frame */
+
+ assert((NSYMROW*COHPSK_NC)*2 == nbits);
/*
Insert two rows of Nc pilots at beginning of data frame.
- Organise QPSK symbols into a NSYMBROWS rows by PILOTS_NC cols matrix,
+ Organise QPSK symbols into a NSYMBROWS rows by PILOTS_NC*ND cols matrix,
each column is a carrier, time flows down the cols......
Note: the "& 0x1" prevents and non binary tx_bits[] screwing up
our lives. Call me defensive.
+
+ sqrtf(ND) term ensures the same energy/symbol for different
+ diversity factors.
*/
r = 0;
for(p_r=0; p_r<2; p_r++) {
- for(c=0; c<PILOTS_NC; c++) {
- tx_symb[r][c].real = pilots_coh[p_r][c];
+ for(c=0; c<COHPSK_NC; c++) {
+ tx_symb[r][c].real = pilots_coh[p_r][c]/sqrtf(ND);
tx_symb[r][c].imag = 0.0;
}
r++;
}
for(data_r=0; data_r<NSYMROW; data_r++, r++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC; c++) {
i = c*NSYMROW + data_r;
bits = (tx_bits[2*i]&0x1)<<1 | (tx_bits[2*i+1]&0x1);
- tx_symb[r][c] = qpsk_mod[bits];
+ tx_symb[r][c] = fcmult(1.0/sqrtf(ND),qpsk_mod[bits]);
}
}
assert(p_r == NPILOTSFRAME);
assert(r == NSYMROWPILOT);
+
+ /* copy to other carriers (diversity) */
+
+ for(d=1; d<ND; d++) {
+ for(r=0; r<NSYMROWPILOT; r++) {
+ for(c=0; c<COHPSK_NC; c++) {
+ tx_symb[r][c+COHPSK_NC*d] = tx_symb[r][c];
+ }
+ }
+ }
+
}
Rate Rs demodulator. Extract pilot symbols and estimate amplitude and phase
of each carrier. Correct phase of data symbols and convert to bits.
- Further improvement. In channels with rapidly changing phase by
- moderate Eb/No, we could perhaps do better by interpolating the
- phase across symbols rather than using the same phi_ for all symbols.
+ Further improvement. In channels with slowly changing phase we
+ could optionally use pilots from several past and future symbols.
\*---------------------------------------------------------------------------*/
-void qpsk_symbols_to_bits(struct COHPSK *coh, int rx_bits[], COMP ct_symb_buf[][COHPSK_NC])
+void qpsk_symbols_to_bits(struct COHPSK *coh, int rx_bits[], COMP ct_symb_buf[][COHPSK_NC*ND])
{
- int p, r, c, i;
+ int p, r, c, i, pc, d;
float x[NPILOTSFRAME+2], x1;
COMP y[NPILOTSFRAME+2], yfit;
COMP m, b;
- COMP corr, rot, pi_on_4, phi_rect;
+ COMP corr, rot, pi_on_4, phi_rect, div_symb;
float mag, phi_, amp_;
pi_on_4.real = cosf(M_PI/4); pi_on_4.imag = sinf(M_PI/4);
- /* Average pilots to get phase and amplitude estimates we assume
- there are two pilots at the start of each frame and two at the
- end */
-
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
//#define AVERAGE
#ifdef AVERAGE
+ /* Average pilots to get phase and amplitude estimates using
+ two pilots at the start of each frame and two at the end */
+
corr.real = 0.0; corr.imag = 0.0; mag = 0.0;
for(p=0; p<NPILOTSFRAME+2; p++) {
corr = cadd(corr, fcmult(coh->pilot2[p][c], ct_symb_buf[sampling_points[p]][c]));
}
#else
- /* set up lin reg model and interpolate phase */
+ /* Set up lin reg model and interpolate phase. Works better than average for channels with
+ quickly changing phase, like HF. */
for(p=0; p<NPILOTSFRAME+2; p++) {
x[p] = sampling_points[p];
- y[p] = fcmult(coh->pilot2[p][c], ct_symb_buf[sampling_points[p]][c]);
+ pc = c % COHPSK_NC;
+ y[p] = fcmult(coh->pilot2[p][pc], ct_symb_buf[sampling_points[p]][c]);
+ //printf("%f %f\n", y[p].real, y[p].imag);
}
+ //printf("\n");
linreg(&m, &b, x, y, NPILOTSFRAME+2);
for(r=0; r<NSYMROW; r++) {
x1 = (float)(r+NPILOTSFRAME);
yfit = cadd(fcmult(x1,m),b);
coh->phi_[r][c] = atan2(yfit.imag, yfit.real);
+ //printf(" %f", coh->phi_[r][c]);
}
-
+ //printf("\n");
/* amplitude estimation */
mag = 0.0;
}
#endif
}
+ //exit(0);
+ /* now correct phase of data symbols */
- /* now correct phase of data symbols and make decn on bits */
-
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
//rot.real = 1.0; rot.imag = 0.0;
for (r=0; r<NSYMROW; r++) {
phi_rect.real = cosf(coh->phi_[r][c]); phi_rect.imag = -sinf(coh->phi_[r][c]);
- i = c*NSYMROW + r;
coh->rx_symb[r][c] = cmult(ct_symb_buf[NPILOTSFRAME + r][c], phi_rect);
//printf("%d %d %f %f\n", r,c, coh->rx_symb[r][c].real, coh->rx_symb[r][c].imag);
//printf("phi_ %d %d %f %f\n", r,c, ct_symb_buf[NPILOTSFRAME + r][c].real, ct_symb_buf[NPILOTSFRAME + r][c].imag);
- rot = cmult(coh->rx_symb[r][c], pi_on_4);
+ }
+ }
+
+ /* and finally optional diversity combination and make decn on bits */
+
+ for(c=0; c<COHPSK_NC; c++) {
+ for(r=0; r<NSYMROW; r++) {
+ div_symb = coh->rx_symb[r][c];
+ for (d=1; d<ND; d++) {
+ div_symb = cadd(div_symb, coh->rx_symb[r][c + COHPSK_NC*d]);
+ }
+ rot = cmult(div_symb, pi_on_4);
+ i = c*NSYMROW + r;
rx_bits[2*i+1] = rot.real < 0;
rx_bits[2*i] = rot.imag < 0;
}
}
-
}
int bin_start, bin_stop, i;
if (sync == 0) {
- f_start = FDMDV_FCENTRE - (((float)(PILOTS_NC-1)/2)+2)*FSEP;
- f_stop = FDMDV_FCENTRE + (((float)(PILOTS_NC-1)/2)+2)*FSEP;
+ f_start = FDMDV_FCENTRE - (((float)(COHPSK_NC*ND-1)/2)+2)*FSEP;
+ f_stop = FDMDV_FCENTRE + (((float)(COHPSK_NC*ND-1)/2)+2)*FSEP;
sc = (float)COARSE_FEST_NDFT/FS;
bin_start = floorf(f_start*sc+0.5);
bin_stop = floorf(f_stop*sc+0.5);
{
COMP corr, f_fine_rect, f_corr;
float mag;
- int c, p;
+ int c, p, pc;
corr.real = 0.0; corr.imag = 0.0; mag = 0.0;
- for (c=0; c<PILOTS_NC; c++) {
+ for (c=0; c<COHPSK_NC*ND; c++) {
for (p=0; p<NPILOTSFRAME+2; p++) {
f_fine_rect.real = cosf(f_fine*2.0*M_PI*(sampling_points[p]+1.0)/RS);
f_fine_rect.imag = sinf(f_fine*2.0*M_PI*(sampling_points[p]+1.0)/RS);
f_corr = cmult(f_fine_rect, coh->ct_symb_buf[t+sampling_points[p]][c]);
- corr = cadd(corr, fcmult(coh->pilot2[p][c], f_corr));
+ pc = c % COHPSK_NC;
+ corr = cadd(corr, fcmult(coh->pilot2[p][pc], f_corr));
mag += cabsolute(f_corr);
}
}
/*---------------------------------------------------------------------------*\
- FUNCTION....: frame_sync_fine_timing_est()
+ FUNCTION....: frame_sync_fine_freq_est()
AUTHOR......: David Rowe
DATE CREATED: April 2015
\*---------------------------------------------------------------------------*/
-void frame_sync_fine_freq_est(struct COHPSK *coh, COMP ch_symb[][PILOTS_NC], int sync, int *next_sync)
+void frame_sync_fine_freq_est(struct COHPSK *coh, COMP ch_symb[][COHPSK_NC*ND], int sync, int *next_sync)
{
int r,c,i,t;
float f_fine, mag, max_corr, max_mag;
/* update memory in symbol buffer */
for (r=0; r<NCT_SYMB_BUF-NSYMROWPILOT; r++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
coh->ct_symb_buf[r][c] = coh->ct_symb_buf[r+NSYMROWPILOT][c];
}
}
for (r=NCT_SYMB_BUF-NSYMROWPILOT,i=0; r<NCT_SYMB_BUF; r++,i++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
coh->ct_symb_buf[r][c] = ch_symb[i][c];
//printf("%d %d %f %f\n", i,c,ch_symb[i][c].real, ch_symb[i][c].imag);
}
for(r=0; r<NSYMROWPILOT+2; r++) {
coh->ff_phase = cmult(coh->ff_phase, cconj(coh->ff_rect));
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
coh->ct_symb_ff_buf[r][c] = coh->ct_symb_buf[coh->ct+r][c];
coh->ct_symb_ff_buf[r][c] = cmult(coh->ct_symb_ff_buf[r][c], coh->ff_phase);
}
/* second and subsequent frames, just fine freq correct the latest Nsymbrowpilot */
for(r=0; r<2; r++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
coh->ct_symb_ff_buf[r][c] = coh->ct_symb_ff_buf[r+NSYMROWPILOT][c];
}
}
for(; r<NSYMROWPILOT+2; r++) {
coh->ff_phase = cmult(coh->ff_phase, cconj(coh->ff_rect));
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
coh->ct_symb_ff_buf[r][c] = coh->ct_symb_buf[coh->ct+r][c];
//printf("%d %d %f %f\n", r,c,coh->ct_symb_ff_buf[r][c].real, coh->ct_symb_ff_buf[r][c].imag);
coh->ct_symb_ff_buf[r][c] = cmult(coh->ct_symb_ff_buf[r][c], coh->ff_phase);
/* check that sync is still good, fall out of sync on 3 consecutive bad frames */
corr_with_pilots(&corr, &mag, coh, coh->ct, coh->f_fine_est);
+ // printf("%f\n", cabsolute(corr)/mag);
- if (cabsolute(corr)/mag < 0.9)
+ if (cabsolute(corr)/mag < 0.5)
coh->sync_timer++;
else
coh->sync_timer = 0;
void cohpsk_mod(struct COHPSK *coh, COMP tx_fdm[], int tx_bits[])
{
struct FDMDV *fdmdv = coh->fdmdv;
- COMP tx_symb[NSYMROWPILOT][PILOTS_NC];
- COMP tx_onesym[PILOTS_NC];
+ COMP tx_symb[NSYMROWPILOT][COHPSK_NC*ND];
+ COMP tx_onesym[COHPSK_NC*ND];
int r,c;
bits_to_qpsk_symbols(tx_symb, tx_bits, COHPSK_BITS_PER_FRAME);
for(r=0; r<NSYMROWPILOT; r++) {
- for(c=0; c<PILOTS_NC; c++)
+ for(c=0; c<COHPSK_NC*ND; c++)
tx_onesym[c] = tx_symb[r][c];
tx_filter_and_upconvert(&tx_fdm[r*M], fdmdv->Nc , tx_onesym, fdmdv->tx_filter_memory,
fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
{
struct FDMDV *fdmdv = coh->fdmdv;
COMP rx_fdm_frame_bb[M*NSYMROWPILOT];
- COMP rx_baseband[PILOTS_NC][M+M/P];
- COMP rx_filt[PILOTS_NC][P+1];
+ COMP rx_baseband[COHPSK_NC*ND][M+M/P];
+ COMP rx_filt[COHPSK_NC*ND][P+1];
float env[NT*P], __attribute__((unused)) rx_timing;
- COMP ch_symb[NSYMROWPILOT][PILOTS_NC];
- COMP rx_onesym[PILOTS_NC];
+ COMP ch_symb[NSYMROWPILOT][COHPSK_NC*ND];
+ COMP rx_onesym[COHPSK_NC*ND];
int sync, next_sync, nin, r, c;
next_sync = sync = coh->sync;
rx_filter(rx_filt, fdmdv->Nc, rx_baseband, coh->rx_filter_memory, nin);
rx_timing = rx_est_timing(rx_onesym, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, nin);
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
ch_symb[r][c] = rx_onesym[c];
}
}
#define COARSE_FEST_NDFT 1024
#define NCT_SYMB_BUF (2*NSYMROWPILOT+2)
+#define ND 2 /* diversity factor ND 1 is no diveristy, ND we have orginal plus
+ one copy */
#include "fdmdv_internal.h"
#include "kiss_fft.h"
struct COHPSK {
- float pilot2[2*NPILOTSFRAME][PILOTS_NC];
- float phi_[NSYMROW][PILOTS_NC]; /* phase estimates for this frame of rx data symbols */
- float amp_[NSYMROW][PILOTS_NC]; /* amplitude estimates for this frame of rx data symbols */
- COMP rx_symb[NSYMROW][PILOTS_NC]; /* demodulated symbols */
+ float pilot2[2*NPILOTSFRAME][COHPSK_NC];
+ float phi_[NSYMROW][COHPSK_NC*ND]; /* phase estimates for this frame of rx data symbols */
+ float amp_[NSYMROW][COHPSK_NC*ND]; /* amplitude estimates for this frame of rx data symbols */
+ COMP rx_symb[NSYMROW][COHPSK_NC*ND]; /* demodulated symbols */
kiss_fft_cfg fft_coarse_fest;
float f_est;
- COMP rx_filter_memory[PILOTS_NC][NFILTER];
- COMP ct_symb_buf[NCT_SYMB_BUF][PILOTS_NC];
+ COMP rx_filter_memory[COHPSK_NC*ND][NFILTER];
+ COMP ct_symb_buf[NCT_SYMB_BUF][COHPSK_NC*ND];
int ct; /* coarse timing offset in symbols */
float f_fine_est;
COMP ff_rect;
COMP ff_phase;
- COMP ct_symb_ff_buf[NSYMROWPILOT+2][PILOTS_NC];
+ COMP ct_symb_ff_buf[NSYMROWPILOT+2][COHPSK_NC*ND];
int sync;
int sync_timer;
{
struct COHPSK *coh;
int tx_bits[COHPSK_BITS_PER_FRAME];
- COMP tx_symb[NSYMROWPILOT][PILOTS_NC];
+ COMP tx_symb[NSYMROWPILOT][COHPSK_NC*ND];
COMP tx_fdm_frame[M*NSYMROWPILOT];
COMP ch_fdm_frame[M*NSYMROWPILOT];
COMP rx_fdm_frame_bb[M*NSYMROWPILOT];
- COMP ch_symb[NSYMROWPILOT][PILOTS_NC];
+ COMP ch_symb[NSYMROWPILOT][COHPSK_NC*ND];
int rx_bits[COHPSK_BITS_PER_FRAME];
int tx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
- COMP tx_symb_log[NSYMROWPILOT*FRAMES][PILOTS_NC];
+ COMP tx_symb_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND];
COMP tx_fdm_frame_log[M*NSYMROWPILOT*FRAMES];
COMP ch_fdm_frame_log[M*NSYMROWPILOT*FRAMES];
COMP rx_fdm_frame_bb_log[M*NSYMROWPILOT*FRAMES];
- COMP ch_symb_log[NSYMROWPILOT*FRAMES][PILOTS_NC];
- COMP ct_symb_ff_log[NSYMROWPILOT*FRAMES][PILOTS_NC];
- float rx_amp_log[NSYMROW*FRAMES][PILOTS_NC];
- float rx_phi_log[NSYMROW*FRAMES][PILOTS_NC];
- COMP rx_symb_log[NSYMROW*FRAMES][PILOTS_NC];
+ COMP ch_symb_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND];
+ COMP ct_symb_ff_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND];
+ float rx_amp_log[NSYMROW*FRAMES][COHPSK_NC*ND];
+ float rx_phi_log[NSYMROW*FRAMES][COHPSK_NC*ND];
+ COMP rx_symb_log[NSYMROW*FRAMES][COHPSK_NC*ND];
int rx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
FILE *fout;
COMP phase_ch;
struct FDMDV *fdmdv;
- COMP rx_baseband[PILOTS_NC][M+M/P];
+ COMP rx_baseband[COHPSK_NC*ND][M+M/P];
int nin;
- COMP rx_filt[PILOTS_NC][P+1];
- COMP rx_filt_log[PILOTS_NC][(P+1)*NSYMROWPILOT*FRAMES];
+ COMP rx_filt[COHPSK_NC*ND][P+1];
+ COMP rx_filt_log[COHPSK_NC*ND][(P+1)*NSYMROWPILOT*FRAMES];
int rx_filt_log_col_index = 0;
float env[NT*P];
float __attribute__((unused)) rx_timing;
- COMP tx_onesym[PILOTS_NC];
- COMP rx_onesym[PILOTS_NC];
+ COMP tx_onesym[COHPSK_NC*ND];
+ COMP rx_onesym[COHPSK_NC*ND];
int rx_baseband_log_col_index = 0;
- COMP rx_baseband_log[PILOTS_NC][(M+M/P)*NSYMROWPILOT*FRAMES];
+ COMP rx_baseband_log[COHPSK_NC*ND][(M+M/P)*NSYMROWPILOT*FRAMES];
int sync, next_sync, log_bits;
float EsNo, variance;
bits_to_qpsk_symbols(tx_symb, (int*)tx_bits, COHPSK_BITS_PER_FRAME);
for(r=0; r<NSYMROWPILOT; r++) {
- for(c=0; c<PILOTS_NC; c++)
+ for(c=0; c<COHPSK_NC*ND; c++)
tx_onesym[c] = tx_symb[r][c];
tx_filter_and_upconvert(&tx_fdm_frame[r*M], fdmdv->Nc , tx_onesym, fdmdv->tx_filter_memory,
fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
rx_filter(rx_filt, fdmdv->Nc, rx_baseband, coh->rx_filter_memory, nin);
rx_timing = rx_est_timing(rx_onesym, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, nin);
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
ch_symb[r][c] = rx_onesym[c];
}
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
for(i=0; i<nin; i++) {
rx_baseband_log[c][rx_baseband_log_col_index + i] = rx_baseband[c][i];
}
}
rx_baseband_log_col_index += nin;
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
for(i=0; i<P; i++) {
rx_filt_log[c][rx_filt_log_col_index + i] = rx_filt[c][i];
}
memcpy(&rx_fdm_frame_bb_log[M*NSYMROWPILOT*f], rx_fdm_frame_bb, sizeof(COMP)*M*NSYMROWPILOT);
for(r=0; r<NSYMROWPILOT; r++, log_r++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
tx_symb_log[log_r][c] = tx_symb[r][c];
ch_symb_log[log_r][c] = ch_symb[r][c];
ct_symb_ff_log[log_r][c] = coh->ct_symb_ff_buf[r][c];
if ((sync == 4) || (next_sync == 4)) {
for(r=0; r<NSYMROW; r++, log_data_r++) {
- for(c=0; c<PILOTS_NC; c++) {
+ for(c=0; c<COHPSK_NC*ND; c++) {
rx_amp_log[log_data_r][c] = coh->amp_[r][c];
rx_phi_log[log_data_r][c] = coh->phi_[r][c];
rx_symb_log[log_data_r][c] = coh->rx_symb[r][c];
assert(fout != NULL);
fprintf(fout, "# Created by tcohpsk.c\n");
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, PILOTS_NC, PILOTS_NC);
+ 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, M*NSYMROWPILOT*FRAMES, M*NSYMROWPILOT*FRAMES);
octave_save_complex(fout, "ch_fdm_frame_log_c", (COMP*)ch_fdm_frame_log, 1, M*NSYMROWPILOT*FRAMES, M*NSYMROWPILOT*FRAMES);
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*)rx_baseband_log, PILOTS_NC, rx_baseband_log_col_index, (M+M/P)*FRAMES*NSYMROWPILOT);
- octave_save_complex(fout, "rx_filt_log_c", (COMP*)rx_filt_log, PILOTS_NC, rx_filt_log_col_index, (P+1)*FRAMES*NSYMROWPILOT);
- octave_save_complex(fout, "ch_symb_log_c", (COMP*)ch_symb_log, NSYMROWPILOT*FRAMES, PILOTS_NC, PILOTS_NC);
- octave_save_complex(fout, "ct_symb_ff_log_c", (COMP*)ct_symb_ff_log, NSYMROWPILOT*FRAMES, PILOTS_NC, PILOTS_NC);
- octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, log_data_r, PILOTS_NC, PILOTS_NC);
- octave_save_float(fout, "rx_phi_log_c", (float*)rx_phi_log, log_data_r, PILOTS_NC, PILOTS_NC);
- octave_save_complex(fout, "rx_symb_log_c", (COMP*)rx_symb_log, log_data_r, PILOTS_NC, PILOTS_NC);
+ octave_save_complex(fout, "rx_baseband_log_c", (COMP*)rx_baseband_log, COHPSK_NC*ND, rx_baseband_log_col_index, (M+M/P)*FRAMES*NSYMROWPILOT);
+ octave_save_complex(fout, "rx_filt_log_c", (COMP*)rx_filt_log, COHPSK_NC*ND, rx_filt_log_col_index, (P+1)*FRAMES*NSYMROWPILOT);
+ octave_save_complex(fout, "ch_symb_log_c", (COMP*)ch_symb_log, NSYMROWPILOT*FRAMES, COHPSK_NC*ND, COHPSK_NC*ND);
+ octave_save_complex(fout, "ct_symb_ff_log_c", (COMP*)ct_symb_ff_log, NSYMROWPILOT*FRAMES, COHPSK_NC*ND, COHPSK_NC*ND);
+ octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+ octave_save_float(fout, "rx_phi_log_c", (float*)rx_phi_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+ octave_save_complex(fout, "rx_symb_log_c", (COMP*)rx_symb_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, COHPSK_BITS_PER_FRAME*log_bits);
fclose(fout);