endfunction
-% Estimate frequency offset of FDM signal using BPSK pilot. This is quite
-% sensitive to pilot tone level wrt other carriers
-
-function [foff s1 s2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin)
- global M;
- global Npilotbaseband;
- global pilot_baseband1;
- global pilot_baseband2;
- global pilot_lpf1;
- global pilot_lpf2;
-
- % down convert latest nin samples of pilot by multiplying by
- % ideal BPSK pilot signal we have generated locally. This
- % 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.
-
- pilot_baseband1(1:Npilotbaseband-nin) = pilot_baseband1(nin+1:Npilotbaseband);
- pilot_baseband2(1:Npilotbaseband-nin) = pilot_baseband2(nin+1:Npilotbaseband);
- for i=1:nin
- pilot_baseband1(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot(i));
- pilot_baseband2(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot_prev(i));
- end
-
- [foff1 max1 pilot_lpf1 s1] = lpf_peak_pick(pilot_baseband1, pilot_lpf1, nin);
- [foff2 max2 pilot_lpf2 s2] = lpf_peak_pick(pilot_baseband2, pilot_lpf2, nin);
-
- if max1 > max2
- foff = foff1;
- else
- foff = foff2;
- end
-endfunction
-
-
% LPF and peak pick part of freq est, put in a function as we call it twice
function [foff imax pilot_lpf S] = lpf_peak_pick(pilot_baseband, pilot_lpf, nin)
Mpilot = Fs/(2*200); % calc decimation rate given new sample rate is twice LPF freq
h = hanning(Npilotlpf);
s = pilot_lpf(1:Mpilot:Npilotlpf) .* h(1:Mpilot:Npilotlpf)';
- S = abs(fft(s, Mpilotfft));
+ s = [s zeros(1,Mpilotfft-Npilotlpf/Mpilot)];
+ S = fft(s, Mpilotfft);
% peak pick and convert to Hz
endfunction
+% Estimate frequency offset of FDM signal using BPSK pilot. This is quite
+% sensitive to pilot tone level wrt other carriers
+
+function [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin)
+ global M;
+ global Npilotbaseband;
+ global pilot_baseband1;
+ global pilot_baseband2;
+ global pilot_lpf1;
+ global pilot_lpf2;
+
+ % down convert latest nin samples of pilot by multiplying by
+ % ideal BPSK pilot signal we have generated locally. This
+ % 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.
+
+ pilot_baseband1(1:Npilotbaseband-nin) = pilot_baseband1(nin+1:Npilotbaseband);
+ pilot_baseband2(1:Npilotbaseband-nin) = pilot_baseband2(nin+1:Npilotbaseband);
+ for i=1:nin
+ pilot_baseband1(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot(i));
+ pilot_baseband2(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot_prev(i));
+ end
+
+ [foff1 max1 pilot_lpf1 S1] = lpf_peak_pick(pilot_baseband1, pilot_lpf1, nin);
+ [foff2 max2 pilot_lpf2 S2] = lpf_peak_pick(pilot_baseband2, pilot_lpf2, nin);
+
+ if max1 > max2
+ foff = foff1;
+ else
+ foff = foff2;
+ end
+endfunction
+
+
% Estimate optimum timing offset, re-filter receive symbols
function [rx_symbols rx_timing] = rx_est_timing(rx_filt, rx_baseband, nin)
% Generate reference vectors using Octave implementation of FDMDV modem
+global passes;
+global fails;
passes = fails = 0;
frames = 25;
prev_tx_symbols = ones(Nc+1,1);
pilot_baseband2_log = [];
pilot_lpf1_log = [];
pilot_lpf2_log = [];
-s1_log = [];
-s2_log = [];
+S1_log = [];
+S2_log = [];
for f=1:frames
[pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, M);
- [foff s1 s2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, M);
+ [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, M);
pilot_baseband1_log = [pilot_baseband1_log pilot_baseband1];
pilot_baseband2_log = [pilot_baseband2_log pilot_baseband2];
pilot_lpf1_log = [pilot_lpf1_log pilot_lpf1];
pilot_lpf2_log = [pilot_lpf2_log pilot_lpf2];
- s1_log = [s1_log s1];
- s2_log = [s2_log s2];
+ S1_log = [S1_log S1];
+ S2_log = [S2_log S2];
end
plot_sig_and_error(6, 211, real(pilot_lpf1_log), real(pilot_lpf1_log - pilot_lpf1_log_c), 'pilot lpf1 real' )
plot_sig_and_error(6, 212, real(pilot_lpf2_log), real(pilot_lpf2_log - pilot_lpf2_log_c), 'pilot lpf2 real' )
-plot_sig_and_error(7, 211, real(s1_log), real(s1_log - s1_log_c), 's1 real' )
-plot_sig_and_error(7, 212, real(s2_log), real(s2_log - s2_log_c), 's2 real' )
+plot_sig_and_error(7, 211, real(S1_log), real(S1_log - S1_log_c), 'S1 real' )
+plot_sig_and_error(7, 212, imag(S1_log), imag(S1_log - S1_log_c), 'S1 imag' )
+
+plot_sig_and_error(8, 211, real(S2_log), real(S2_log - S2_log_c), 'S2 real' )
+plot_sig_and_error(8, 212, imag(S2_log), imag(S2_log - S2_log_c), 'S2 imag' )
% ---------------------------------------------------------------------------------------
% AUTOMATED CHECKS ------------------------------------------
% ---------------------------------------------------------------------------------------
-if sum(tx_bits_log - tx_bits_log_c) == 0
- printf("fdmdv_get_test_bits..: OK\n");
- passes++;
-else;
- printf("fdmdv_get_test_bits..: FAIL\n");
- fails++;
-end
-
-if sum(tx_symbols_log - tx_symbols_log_c) == 0
- printf("bits_to_dqpsk_symbols: OK\n");
- passes++;
-else;
- printf("bits_to_dqpsk_symbols: FAIL\n");
- fails++;
-end
-
-if sum(tx_baseband_log - tx_baseband_log_c) < 1E-3
- printf("tx_filter............: OK\n");
- passes++;
-else;
- printf("tx_filter............: FAIL\n");
- fails++;
-end
-
-if sum(tx_fdm_log - tx_fdm_log_c) < 1E-3
- printf("tx_fdm...............: OK\n");
- passes++;
-else;
- printf("tx_fdm...............: FAIL\n");
- fails++;
-end
+function check(a, b, test_name)
+ global passes;
+ global fails;
-if sum(pilot_lut - pilot_lut_c) < 1E-3
- printf("pilot_lut............: OK\n");
- passes++;
-else;
- printf("pilot_lut............: FAIL\n");
- fails++;
-end
-
-[m n] = size(pilot_baseband1_log);
-if sum(pilot_baseband1_log - pilot_baseband1_log_c)/n < 1E-3
- printf("pilot_baseband1_log..: OK\n");
- passes++;
-else;
- printf("pilot_baseband1_log..: FAIL\n");
- fails++;
-end
+ [m n] = size(a);
+ printf("%s", test_name);
+ for i=1:(25-length(test_name))
+ printf(".");
+ end
+ printf(": ");
+
+ if sum(a - b)/n < 1E-3
+ printf("OK\n");
+ passes++;
+ else
+ printf("FAIL\n");
+ fails++;
+ end
+endfunction
-[m n] = size(pilot_baseband2_log);
-if sum(pilot_baseband2_log - pilot_baseband2_log_c)/n < 1E-3
- printf("pilot_baseband2_log..: OK\n");
- passes++;
-else;
- printf("pilot_baseband2_log..: FAIL\n");
- fails++;
-end
+check(tx_bits_log, tx_bits_log_c, 'fdmdv_get_test_bits');
+check(tx_symbols_log, tx_symbols_log_c, 'bits_to_dqpsk_symbols');
+check(tx_baseband_log, tx_baseband_log_c, 'tx_filter');
+check(tx_fdm_log, tx_fdm_log_c, 'tx_fdm');
+check(pilot_lut, pilot_lut_c, 'pilot_lut');
+check(pilot_baseband1_log, pilot_baseband1_log_c, 'pilot lpf1');
+check(pilot_baseband2_log, pilot_baseband2_log_c, 'pilot lpf2');
+check(S1_log, S1_log_c, 'S1');
+check(S2_log, S2_log_c, 'S2');
printf("\npasses: %d fails: %d\n", passes, fails);
\*---------------------------------------------------------------------------*/
-void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP s[], int nin)
+void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP S[], int nin)
{
int i,j,k;
int mpilot;
mpilot = FS/(2*200); /* calc decimation rate given new sample rate is twice LPF freq */
for(i=0; i<MPILOTFFT; i++) {
- s[i].real = 0.0; s[i].imag = 0.0;
+ S[i].real = 0.0; S[i].imag = 0.0;
}
-
for(i=0,j=0; i<NPILOTLPF; i+=mpilot,j++) {
- s[j] = fcmult(hanning[i], pilot_lpf[i]);
- //s[j] = pilot_lpf[i];
+ S[j] = fcmult(hanning[i], pilot_lpf[i]);
}
-#ifdef TT
- fft(&s[0].real, MPILOTFFT, 1);
+
+ fft(&S[0].real, MPILOTFFT, -1);
/* peak pick and convert to Hz */
imax = 0.0;
ix = 0;
for(i=0; i<MPILOTFFT; i++) {
- mag = s[i].real*s[i].real + s[i].imag*s[i].imag;
+ mag = sqrt(S[i].real*S[i].real + S[i].imag*S[i].imag);
if (mag > imax) {
imax = mag;
ix = i;
else
*foff = (ix)*r;
*max = imax;
-#endif
+
}
/*---------------------------------------------------------------------------*\
f->pilot_baseband2[j] = fcmult(rx_fdm[i], cconj(prev_pilot[i]));
}
- lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->s1, nin);
- lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->s2, nin);
- //for(i=0; i<MPILOTFFT; i++) {
- // printf("%f %f\n", f->s1[i].real, f->s1[i].imag);
- //}
+ lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->S1, nin);
+ lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->S2, nin);
-#ifdef T
if (max1 > max2)
foff = foff1;
else
foff = foff2;
return foff;
-#endif
- return 0;
}
COMP pilot_baseband2[NPILOTBASEBAND];
COMP pilot_lpf1[NPILOTLPF];
COMP pilot_lpf2[NPILOTLPF];
- COMP s1[MPILOTFFT];
- COMP s2[MPILOTFFT];
+ COMP S1[MPILOTFFT];
+ COMP S2[MPILOTFFT];
};
/*---------------------------------------------------------------------------*\
void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq);
void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin);
-void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP s[], int nin);
+void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP S[], int nin);
#endif
COMP pilot_baseband2_log[NPILOTBASEBAND*FRAMES];
COMP pilot_lpf1_log[NPILOTLPF*FRAMES];
COMP pilot_lpf2_log[NPILOTLPF*FRAMES];
- COMP s1_log[32*FRAMES];
- COMP s2_log[32*FRAMES];
+ COMP S1_log[MPILOTFFT*FRAMES];
+ COMP S2_log[MPILOTFFT*FRAMES];
FILE *fout;
int f,c,i;
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(&pilot_lpf2_log[f*NPILOTLPF], fdmdv->pilot_lpf2, sizeof(COMP)*NPILOTLPF);
- memcpy(&s1_log[f*32], fdmdv->s1, sizeof(COMP)*32);
- memcpy(&s2_log[f*32], fdmdv->s2, sizeof(COMP)*32);
+ memcpy(&S1_log[f*MPILOTFFT], fdmdv->S1, sizeof(COMP)*MPILOTFFT);
+ memcpy(&S2_log[f*MPILOTFFT], fdmdv->S2, sizeof(COMP)*MPILOTFFT);
}
/* dump logs to Octave file for evaluation by tfdmdv.m Octave script */
octave_save_complex(fout, "pilot_baseband2_log_c", pilot_baseband2_log, 1, NPILOTBASEBAND*FRAMES);
octave_save_complex(fout, "pilot_lpf1_log_c", pilot_lpf1_log, 1, NPILOTLPF*FRAMES);
octave_save_complex(fout, "pilot_lpf2_log_c", pilot_lpf2_log, 1, NPILOTLPF*FRAMES);
- octave_save_complex(fout, "s1_log_c", s1_log, 1, 32*FRAMES);
- octave_save_complex(fout, "s2_log_c", s2_log, 1, 32*FRAMES);
+ octave_save_complex(fout, "S1_log_c", S1_log, 1, MPILOTFFT*FRAMES);
+ octave_save_complex(fout, "S2_log_c", S2_log, 1, MPILOTFFT*FRAMES);
fclose(fout);
codec2_destroy(fdmdv);