endfunction
-function check(a, b, test_name, tol)
+function check(a, b, test_name, tol, its_an_angle = 0)
global passes;
global fails;
end
printf(": ");
- e = sum(sum(abs(a - b))/ll);
+ if its_an_angle
+ % take into account pi is close to -pi for angles in rads
+ e = sum(sum(abs(exp(j*a) - exp(j*b)))/ll);
+ else
+ e = sum(sum(abs(a - b))/ll);
+ end
+
if e < tol
printf("OK\n");
passes++;
title('Scatter');
figure(2); clf;
- plot(phase_est_pilot_log(:,2:Nc+1),'g+', 'markersize', 5);
+ plot(phase_est_pilot_log,'g+', 'markersize', 5);
title('Phase est');
axis([1 Nrp -pi pi]);
end
rx_bits = [rx_bits abit];
end % c=2:Nc+1
- aphase_est_pilot_log = [aphase_est_pilot_log; aphase_est_pilot];
+ aphase_est_pilot_log = [aphase_est_pilot_log; aphase_est_pilot(2:Nc+1)];
end
% Adjust nin to take care of sample clock offset
states.rxbuf(Nrxbuf-nin+1:Nrxbuf) = rx(prx:nin);
prx += nin;
-rxbuf_log = []; rxbuf_in_log = []; rx_sym_log = []; foff_hz_log = []; rx_bits_log = [];
+rxbuf_log = []; rxbuf_in_log = []; rx_sym_log = []; foff_hz_log = [];
+phase_est_pilot_log = []; rx_amp_log = [];
+rx_bits_log = [];
states.timing_en = 0;
states.foff_est_en = 1;
rxbuf_in_log = [rxbuf_in_log rxbuf_in];
rxbuf_log = [rxbuf_log states.rxbuf];
rx_sym_log = [rx_sym_log; states.rx_sym];
+ phase_est_pilot_log = [phase_est_pilot_log; aphase_est_pilot_log];
+ rx_amp_log = [rx_amp_log arx_amp];
foff_hz_log = [foff_hz_log; states.foff_est_hz];
rx_bits_log = [rx_bits_log rx_bits];
if exist("path_to_tofdm", "var") == 0
path_to_tofdm = "../build_linux/unittest/tofdm";
end
-system(path_to_tofdm)
+system(path_to_tofdm);
load tofdm_out.txt;
stem_sig_and_error(5, 211, real(rx_sym_log_c), real(rx_sym_log - rx_sym_log_c), 'rx sym re', [1 length(rx_sym_log_c) -1.5 1.5])
stem_sig_and_error(5, 212, imag(rx_sym_log_c), imag(rx_sym_log - rx_sym_log_c), 'rx sym im', [1 length(rx_sym_log_c) -1.5 1.5])
-stem_sig_and_error(6, 111, foff_hz_log_c, (foff_hz_log - foff_hz_log_c), 'foff hz', [1 length(foff_hz_log_c) -1.5 1.5])
+% for angles pi and -pi are the same
+d = phase_est_pilot_log - phase_est_pilot_log_c; d = angle(exp(j*d));
+stem_sig_and_error(6, 211, phase_est_pilot_log_c, d, 'phase est pilot', [1 length(phase_est_pilot_log_c) -1.5 1.5])
+stem_sig_and_error(6, 212, rx_amp_log_c, rx_amp_log - rx_amp_log_c, 'rx amp', [1 length(rx_amp_log_c) -1.5 1.5])
-stem_sig_and_error(7, 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(7, 111, foff_hz_log_c, (foff_hz_log - foff_hz_log_c), 'foff hz', [1 length(foff_hz_log_c) -1.5 1.5])
+
+stem_sig_and_error(8, 111, rx_bits_log_c, rx_bits_log - rx_bits_log_c, 'rx bits', [1 length(rx_bits_log) -1.5 1.5])
% Run through checklist -----------------------------
check(rxbuf_in_log, rxbuf_in_log_c, 'rxbuf in');
check(rxbuf_log, rxbuf_log_c, 'rxbuf');
check(rx_sym_log, rx_sym_log_c, 'rx_sym');
+check(phase_est_pilot_log, phase_est_pilot_log_c, 'phase_est_pilot', tol=1E-3, its_an_angle=1);
+check(rx_amp_log, rx_amp_log_c, 'rx_amp');
check(foff_hz_log, foff_hz_log_c, 'foff_est_hz');
check(rx_bits_log, rx_bits_log_c, 'rx_bits');
aphase_est_pilot_rect += vector_sum(symbol, 3);
aphase_est_pilot[i] = cargf(aphase_est_pilot_rect);
+
+ /* TODO David: WTF 12.0 constant? Something to do with LDPC input scaling? */
+
aamp_est_pilot[i] = cabsf(aphase_est_pilot_rect / 12.0f);
}
}
ofdm->rx_np[(rr * OFDM_ROWSPERFRAME) + (i - 1)] = rx_corr;
- ofdm->rx_amp[(rr * OFDM_ROWSPERFRAME) + (i - 1)] = aamp_est_pilot[i];
+
+ /* note even though amp ests are the same for each col,
+ the FEC decoder likes to have one amplitude per symbol
+ so convenient to log them all */
+
+ ofdm->rx_amp[(rr * OFDM_NC) + (i - 1)] = aamp_est_pilot[i];
+
+ /* note like amps in this implementation phase ests the
+ same for each col, but we log them for each symbol anyway */
+
+ ofdm->aphase_est_pilot_log[(rr * OFDM_NC) + (i - 1)] = aphase_est_pilot[i];
if (OFDM_BPS == 1) {
rx_bits[bit_index++] = crealf(rx_corr) > 0.0f;
rx_bits[bit_index++] = abit[1];
rx_bits[bit_index++] = abit[0];
}
- }
- ofdm->aphase_est_pilot_log[(rr * OFDM_ROWSPERFRAME) + (i - 1)] = aphase_est_pilot[i];
+ }
+
}
/* Adjust nin to take care of sample clock offset */
int max_samples_per_frame = ofdm_get_max_samples_per_frame();
struct OFDM *ofdm;
- COMP tx[samples_per_frame]; /* one frame of tx samples */
+ COMP tx[samples_per_frame]; /* one frame of tx samples */
+
int rx_bits[OFDM_BITSPERFRAME]; /* one frame of rx bits */
/* log arrays */
COMP rxbuf_in_log[max_samples_per_frame*NFRAMES];
COMP rxbuf_log[OFDM_RXBUF*NFRAMES];
COMP rx_sym_log[(OFDM_NS + 3)*NFRAMES][OFDM_NC + 2];
+ float phase_est_pilot_log[OFDM_ROWSPERFRAME*NFRAMES][OFDM_NC];
+ float rx_amp_log[OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES];
float foff_hz_log[NFRAMES];
int rx_bits_log[OFDM_BITSPERFRAME*NFRAMES];
}
}
+ /* note phase/amp ests the same for each col, but check them all anyway */
+
+ for (i = 0; i < OFDM_ROWSPERFRAME; i++) {
+ for (j = 0; j < OFDM_NC; j++) {
+ phase_est_pilot_log[OFDM_ROWSPERFRAME*f+i][j] = ofdm->aphase_est_pilot_log[OFDM_NC*i+j];
+ rx_amp_log[OFDM_ROWSPERFRAME*OFDM_NC*f+OFDM_NC*i+j] = ofdm->rx_amp[OFDM_NC*i+j];
+ }
+ }
+
foff_hz_log[f] = ofdm->foff_est_hz;
memcpy(&rx_bits_log[OFDM_BITSPERFRAME*f], rx_bits, sizeof(rx_bits));
octave_save_complex(fout, "rxbuf_in_log_c", (COMP*)rxbuf_in_log, 1, nin_tot, nin_tot);
octave_save_complex(fout, "rxbuf_log_c", (COMP*)rxbuf_log, 1, OFDM_RXBUF*NFRAMES, OFDM_RXBUF*NFRAMES);
octave_save_complex(fout, "rx_sym_log_c", (COMP*)rx_sym_log, (OFDM_NS + 3)*NFRAMES, OFDM_NC + 2, OFDM_NC + 2);
+ octave_save_float(fout, "phase_est_pilot_log_c", (float*)phase_est_pilot_log, OFDM_ROWSPERFRAME*NFRAMES, OFDM_NC, OFDM_NC);
+ octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, 1, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES);
octave_save_float(fout, "foff_hz_log_c", foff_hz_log, NFRAMES, 1, 1);
octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, OFDM_BITSPERFRAME*NFRAMES);
fclose(fout);