static float cabsolute(COMP a)
{
- return sqrt(pow(a.real, 2.0) + pow(a.imag, 2.0));
+ return sqrt(a.real*a.real + a.imag*a.imag);
}
/*---------------------------------------------------------------------------*\
}
f->foff = 0.0;
- f->foff_rect.real = 1.0;
- f->foff_rect.imag = 0.0;
f->foff_phase_rect.real = 1.0;
f->foff_phase_rect.imag = 0.0;
void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq[])
{
- int i,c;
- COMP two = {2.0, 0.0};
- COMP pilot;
+ int i,c;
+ COMP two = {2.0, 0.0};
+ COMP pilot;
+ float mag;
for(i=0; i<M; i++) {
tx_fdm[i].real = 0.0;
/* normalise digital oscilators as the magnitude can drfift over time */
for (c=0; c<Nc+1; c++) {
- phase_tx[c].real /= cabsolute(phase_tx[c]);
- phase_tx[c].imag /= cabsolute(phase_tx[c]);
+ mag = cabsolute(phase_tx[c]);
+ phase_tx[c].real /= mag;
+ phase_tx[c].imag /= mag;
}
}
for(i=0; i<NPILOTLPF-nin; i++)
pilot_lpf[i] = pilot_lpf[nin+i];
- for(i=NPILOTLPF-nin, j=0; i<NPILOTLPF; i++,j++) {
+ for(i=NPILOTLPF-nin, j=NPILOTCOEFF; i<NPILOTLPF; i++,j++) {
pilot_lpf[i].real = 0.0; pilot_lpf[i].imag = 0.0;
- for(k=0; k<NPILOTCOEFF; k++)
- pilot_lpf[i] = cadd(pilot_lpf[i], fcmult(pilot_coeff[k], pilot_baseband[j+k]));
+ for(k=0; k<NPILOTCOEFF; k++) {
+ pilot_lpf[i] = cadd(pilot_lpf[i], fcmult(pilot_coeff[k], pilot_baseband[j-k]));
+ //pilot_lpf[i] = pilot_baseband[j-NPILOTCOEFF+1];
+ }
}
- /* decimate to improve DFT resolution, window and DFT */
+ /* decimate to improve DFT resolution, window and DFT */
mpilot = FS/(2*200); /* calc decimation rate given new sample rate is twice LPF freq */
for(i=0; i<MPILOTFFT; i++) {
/*
Down convert latest M samples of pilot by multiplying by ideal
BPSK pilot signal we have generated locally. The peak of the
- resulting signal is sensitive to the time shift between the
- received and local version of the pilot, so we do it twice at
- different time shifts and choose the maximum.
+ DFT of the resulting signal is sensitive to the time shift
+ between the received and local version of the pilot, so we do it
+ twice at different time shifts and choose the maximum.
*/
for(i=0; i<NPILOTBASEBAND-nin; i++) {
}
for(i=0,j=NPILOTBASEBAND-nin; i<nin; i++,j++) {
- f->pilot_baseband1[j] = cmult(rx_fdm[i], cconj(pilot[i]));
+ f->pilot_baseband1[j] = cmult(rx_fdm[i], cconj(pilot[i]));
f->pilot_baseband2[j] = cmult(rx_fdm[i], cconj(prev_pilot[i]));
}
\*---------------------------------------------------------------------------*/
void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff,
- COMP *foff_rect, COMP *foff_phase_rect, int nin)
+ COMP *foff_phase_rect, int nin)
{
+ COMP foff_rect;
+ float mag;
int i;
- foff_rect->real = cos(2.0*PI*foff/FS);
- foff_rect->imag = sin(2.0*PI*foff/FS);
+ foff_rect.real = cos(2.0*PI*foff/FS);
+ foff_rect.imag = sin(2.0*PI*foff/FS);
for(i=0; i<nin; i++) {
- *foff_phase_rect = cmult(*foff_phase_rect, *foff_rect);
+ *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
}
/* normalise digital oscilator as the magnitude can drfift over time */
- foff_phase_rect->real /= cabsolute(*foff_phase_rect);
- foff_phase_rect->imag /= cabsolute(*foff_phase_rect);
+ mag = cabsolute(*foff_phase_rect);
+ foff_phase_rect->real /= mag;
+ foff_phase_rect->imag /= mag;
}
/*---------------------------------------------------------------------------*\
void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin)
{
- int i,c;
+ int i,c;
+ float mag;
/* maximum number of input samples to demod */
/* normalise digital oscilators as the magnitude can drift over time */
for (c=0; c<Nc+1; c++) {
- phase_rx[c].real /= cabsolute(phase_rx[c]);
- phase_rx[c].imag /= cabsolute(phase_rx[c]);
+ mag = cabsolute(phase_rx[c]);
+ phase_rx[c].real /= mag;
+ phase_rx[c].imag /= mag;
}
}
leads to sensible scatter plots */
for(c=0; c<Nc; c++) {
- norm = 1.0/(cabsolute(prev_rx_symbols[c])+1E-6);
- phase_difference[c] = cmult(cmult(rx_symbols[c], fcmult(norm,cconj(prev_rx_symbols[c]))), pi_on_4);
+ norm = 1.0/(1E-6 + cabsolute(prev_rx_symbols[c]));
+ prev_rx_symbols[c] = fcmult(norm, prev_rx_symbols[c]);
+ phase_difference[c] = cmult(prev_rx_symbols[c], cconj(prev_rx_symbols[c]));
+ phase_difference[c] = cmult(phase_difference[c],pi_on_4);
}
/* map (Nc,1) DQPSK symbols back into an (1,Nc*Nb) array of bits */
if (fdmdv->sync == 0)
fdmdv->foff = foff_coarse;
- fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, *nin);
+ fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_phase_rect, *nin);
/* baseband processing */
fprintf(stderr,"\nfreq[]:\n");
for(i=0; i<=f->Nc; i++)
fprintf(stderr," %1.3f", cabsolute(f->freq[i]));
- fprintf(stderr,"\nfoff_rect %1.3f foff_phase_rect: %1.3f", cabsolute(f->foff_rect), cabsolute(f->foff_phase_rect));
+ fprintf(stderr,"\nfoff_phase_rect: %1.3f", cabsolute(f->foff_phase_rect));
fprintf(stderr,"\nphase_rx[]:\n");
for(i=0; i<=f->Nc; i++)
fprintf(stderr," %1.3f", cabsolute(f->phase_rx[i]));
#define FRAMES 25
#define CHANNEL_BUF_SIZE (10*M)
+extern float pilot_coeff[];
+
int main(int argc, char *argv[])
{
struct FDMDV *fdmdv;
int tx_bits[FDMDV_BITS_PER_FRAME];
- COMP tx_symbols[NC+1];
+ COMP tx_symbols[FDMDV_NC+1];
COMP tx_baseband[NC+1][M];
COMP tx_fdm[M];
float channel[CHANNEL_BUF_SIZE];
COMP rx_filt[NC+1][P+1];
float rx_timing;
float env[NT*P];
- COMP rx_symbols[NC+1];
+ COMP rx_symbols[FDMDV_NC+1];
int rx_bits[FDMDV_BITS_PER_FRAME];
float foff_fine;
int sync_bit, reliable_sync_bit;
int tx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
- COMP tx_symbols_log[(NC+1)*FRAMES];
+ COMP tx_symbols_log[(FDMDV_NC+1)*FRAMES];
COMP tx_baseband_log[(NC+1)][M*FRAMES];
COMP tx_fdm_log[M*FRAMES];
COMP pilot_baseband1_log[NPILOTBASEBAND*FRAMES];
int rx_filt_log_col_index;
float env_log[NT*P*FRAMES];
float rx_timing_log[FRAMES];
- COMP rx_symbols_log[NC+1][FRAMES];
- float sig_est_log[NC+1][FRAMES];
- float noise_est_log[NC+1][FRAMES];
+ COMP rx_symbols_log[FDMDV_NC+1][FRAMES];
+ COMP phase_difference_log[FDMDV_NC+1][FRAMES];
+ float sig_est_log[FDMDV_NC+1][FRAMES];
+ float noise_est_log[FDMDV_NC+1][FRAMES];
int rx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
float foff_fine_log[FRAMES];
int sync_bit_log[FRAMES];
printf("sizeof FDMDV states: %d bytes\n", sizeof(struct FDMDV));
for(f=0; f<FRAMES; f++) {
-
+
/* --------------------------------------------------------*\
Modulator
\*---------------------------------------------------------*/
fdmdv_get_test_bits(fdmdv, tx_bits);
bits_to_dqpsk_symbols(tx_symbols, FDMDV_NC, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit, 0);
- memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(NC+1));
+ memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(FDMDV_NC+1));
tx_filter(tx_baseband, FDMDV_NC, tx_symbols, fdmdv->tx_filter_memory);
fdm_upconvert(tx_fdm, FDMDV_NC, tx_baseband, fdmdv->phase_tx, fdmdv->freq);
if ((f !=2) && (f != 3))
nin = M;
*/
+ nin = M;
/* add M tx samples to end of buffer */
assert((channel_count + M) < CHANNEL_BUF_SIZE);
/* freq offset estimation and correction */
foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin);
+ foff_coarse = 0;
+ fdmdv->sync = 0;
if (fdmdv->sync == 0)
fdmdv->foff = foff_coarse;
- fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, fdmdv->foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, nin);
+ fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, foff_coarse, &fdmdv->foff_phase_rect, nin);
/* baseband processing */
rx_filter(rx_filt, FDMDV_NC, rx_baseband, fdmdv->rx_filter_memory, nin);
rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, nin);
foff_fine = qpsk_to_bits(rx_bits, &sync_bit, FDMDV_NC, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols, 0);
+ //for(i=0; i<FDMDV_NC;i++)
+ // printf("rx_symbols: %f %f prev_rx_symbols: %f %f phase_difference: %f %f\n", rx_symbols[i].real, rx_symbols[i].imag,
+ // fdmdv->prev_rx_symbols[i].real, fdmdv->prev_rx_symbols[i].imag, fdmdv->phase_difference[i].real, fdmdv->phase_difference[i].imag);
+ //if (f==1)
+ // exit(0);
snr_update(fdmdv->sig_est, fdmdv->noise_est, FDMDV_NC, fdmdv->phase_difference);
- memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(NC+1));
+ memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(FDMDV_NC+1));
next_nin = M;
\*---------------------------------------------------------*/
memcpy(&tx_bits_log[FDMDV_BITS_PER_FRAME*f], tx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME);
- memcpy(&tx_symbols_log[(NC+1)*f], tx_symbols, sizeof(COMP)*(NC+1));
- for(c=0; c<NC+1; c++)
+ memcpy(&tx_symbols_log[(FDMDV_NC+1)*f], tx_symbols, sizeof(COMP)*(FDMDV_NC+1));
+ for(c=0; c<FDMDV_NC+1; c++)
for(i=0; i<M; i++)
tx_baseband_log[c][f*M+i] = tx_baseband[c][i];
memcpy(&tx_fdm_log[M*f], tx_fdm, sizeof(COMP)*M);
- /* freq offset estimation */
-
memcpy(&pilot_baseband1_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband1, sizeof(COMP)*NPILOTBASEBAND);
memcpy(&pilot_baseband2_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband2, sizeof(COMP)*NPILOTBASEBAND);
memcpy(&pilot_lpf1_log[f*NPILOTLPF], fdmdv->pilot_lpf1, sizeof(COMP)*NPILOTLPF);
memcpy(&env_log[NT*P*f], env, sizeof(float)*NT*P);
rx_timing_log[f] = rx_timing;
nin_log[f] = nin;
- for(c=0; c<NC+1; c++)
+ for(c=0; c<FDMDV_NC+1; c++) {
rx_symbols_log[c][f] = rx_symbols[c];
+ phase_difference_log[c][f] = fdmdv->phase_difference[c];
+ }
/* qpsk_to_bits() */
memcpy(&rx_bits_log[FDMDV_BITS_PER_FRAME*f], rx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME);
- for(c=0; c<NC+1; c++) {
+ for(c=0; c<FDMDV_NC+1; c++) {
sig_est_log[c][f] = fdmdv->sig_est[c];
noise_est_log[c][f] = fdmdv->noise_est[c];
}
assert(fout != NULL);
fprintf(fout, "# Created by tfdmdv.c\n");
octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, FDMDV_BITS_PER_FRAME*FRAMES);
- octave_save_complex(fout, "tx_symbols_log_c", tx_symbols_log, 1, (NC+1)*FRAMES, (NC+1)*FRAMES);
- octave_save_complex(fout, "tx_baseband_log_c", (COMP*)tx_baseband_log, (NC+1), M*FRAMES, M*FRAMES);
+ octave_save_complex(fout, "tx_symbols_log_c", tx_symbols_log, 1, (FDMDV_NC+1)*FRAMES, (FDMDV_NC+1)*FRAMES);
+ octave_save_complex(fout, "tx_baseband_log_c", (COMP*)tx_baseband_log, (FDMDV_NC+1), M*FRAMES, M*FRAMES);
octave_save_complex(fout, "tx_fdm_log_c", (COMP*)tx_fdm_log, 1, M*FRAMES, M*FRAMES);
octave_save_complex(fout, "pilot_lut_c", (COMP*)fdmdv->pilot_lut, 1, NPILOT_LUT, NPILOT_LUT);
octave_save_complex(fout, "pilot_baseband1_log_c", pilot_baseband1_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);
octave_save_complex(fout, "pilot_baseband2_log_c", pilot_baseband2_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);
+ octave_save_float(fout, "pilot_coeff_c", pilot_coeff, 1, NPILOTCOEFF, NPILOTCOEFF);
octave_save_complex(fout, "pilot_lpf1_log_c", pilot_lpf1_log, 1, NPILOTLPF*FRAMES, NPILOTLPF*FRAMES);
octave_save_complex(fout, "pilot_lpf2_log_c", pilot_lpf2_log, 1, NPILOTLPF*FRAMES, NPILOTLPF*FRAMES);
octave_save_complex(fout, "S1_log_c", S1_log, 1, MPILOTFFT*FRAMES, MPILOTFFT*FRAMES);
octave_save_complex(fout, "S2_log_c", S2_log, 1, MPILOTFFT*FRAMES, MPILOTFFT*FRAMES);
octave_save_float(fout, "foff_log_c", foff_log, 1, FRAMES, FRAMES);
octave_save_float(fout, "foff_coarse_log_c", foff_coarse_log, 1, FRAMES, FRAMES);
- octave_save_complex(fout, "rx_baseband_log_c", (COMP*)rx_baseband_log, (NC+1), rx_baseband_log_col_index, (M+M/P)*FRAMES);
- octave_save_complex(fout, "rx_filt_log_c", (COMP*)rx_filt_log, (NC+1), rx_filt_log_col_index, (P+1)*FRAMES);
+ octave_save_complex(fout, "rx_baseband_log_c", (COMP*)rx_baseband_log, (FDMDV_NC+1), rx_baseband_log_col_index, (M+M/P)*FRAMES);
+ octave_save_complex(fout, "rx_filt_log_c", (COMP*)rx_filt_log, (FDMDV_NC+1), rx_filt_log_col_index, (P+1)*FRAMES);
octave_save_float(fout, "env_log_c", env_log, 1, NT*P*FRAMES, NT*P*FRAMES);
octave_save_float(fout, "rx_timing_log_c", rx_timing_log, 1, FRAMES, FRAMES);
- octave_save_complex(fout, "rx_symbols_log_c", (COMP*)rx_symbols_log, (NC+1), FRAMES, FRAMES);
- octave_save_float(fout, "sig_est_log_c", (float*)sig_est_log, (NC+1), FRAMES, FRAMES);
- octave_save_float(fout, "noise_est_log_c", (float*)noise_est_log, (NC+1), FRAMES, FRAMES);
+ octave_save_complex(fout, "rx_symbols_log_c", (COMP*)rx_symbols_log, (FDMDV_NC+1), FRAMES, FRAMES);
+ octave_save_complex(fout, "phase_difference_log_c", (COMP*)phase_difference_log, (FDMDV_NC+1), FRAMES, FRAMES);
+ octave_save_float(fout, "sig_est_log_c", (float*)sig_est_log, (FDMDV_NC+1), FRAMES, FRAMES);
+ octave_save_float(fout, "noise_est_log_c", (float*)noise_est_log, (FDMDV_NC+1), FRAMES, FRAMES);
octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, FDMDV_BITS_PER_FRAME*FRAMES);
octave_save_float(fout, "foff_fine_log_c", foff_fine_log, 1, FRAMES, FRAMES);
octave_save_int(fout, "sync_bit_log_c", sync_bit_log, 1, FRAMES);