% ------------------------------------------------------------------
-Nframes = 30;
+Nframes = 3;
sample_clock_offset_ppm = 100;
foff_hz = 0.5;
more off; format;
ofdm_lib;
autotest;
+ldpc
+
+% attempt to start up CML, path will be different on your machine
+
+path_to_cml = '/home/david/Desktop/cml/mex';
+addpath(path_to_cml);
+cml_support = 0;
+if exist("Somap") == 0
+ printf("Can't find CML mex directory so we won't run those tests for now...\n");
+else
+ printf("OK found CML mex directory so will add those tests...\n");
+ cml_support = 1;
+end
% ---------------------------------------------------------------------
% Run Octave version
states.sample_point = Ncp;
end
+if cml_support
+ Nuwtxtsymbolsperframe = (states.Nuwbits+states.Ntxtbits)/bps;
+ S_matrix = [1, j, -j, -1];
+ EsNo = 10;
+ symbol_likelihood_log = bit_likelihood_log = [];
+end
for f=1:Nframes
sample_point_log = [sample_point_log; states.sample_point];
rx_np_log = [rx_np_log arx_np];
rx_bits_log = [rx_bits_log rx_bits];
+
+ % Optional testing of LDPC functions
+
+ if cml_support
+ symbol_likelihood = Demod2D(arx_np(Nuwtxtsymbolsperframe+1:end), S_matrix, EsNo, arx_amp(Nuwtxtsymbolsperframe+1:end));
+ bit_likelihood = Somap(symbol_likelihood);
+ [m n] = size(symbol_likelihood);
+ symbol_likelihood_log = [symbol_likelihood_log; reshape(symbol_likelihood,m*n,1)];
+ bit_likelihood_log = [bit_likelihood_log; bit_likelihood'];
+ end
end
check(sample_point_log, sample_point_log_c, 'sample_point');
check(foff_hz_log, foff_hz_log_c, 'foff_est_hz');
check(rx_bits_log, rx_bits_log_c, 'rx_bits');
+check(symbol_likelihood_log, symbol_likelihood_log_c, 'symbol_likelihood_log');
+check(bit_likelihood_log, bit_likelihood_log_c, 'bit_likelihood_log');
add_executable(ofdm_mod ofdm_mod.c)
target_link_libraries(ofdm_mod ${CMAKE_REQUIRED_LIBRARIES} codec2)
-add_executable(ofdm_demod ofdm_demod.c octave.c)
+add_executable(ofdm_demod ofdm_demod.c octave.c mpdecode_core.c)
target_link_libraries(ofdm_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
add_executable(fmfsk_mod fmfsk_mod.c)
/*
- output[] is symbol likelihood
+ Determine symbol likelihood from received QPSK symbols.
- Note we assume fading[] is real, it is also possible to compute
- with complex fading.
+ Notes:
+
+ 1) We assume fading[] is real, it is also possible to compute
+ with complex fading, see CML library Demod2D.c source code.
+ 2) Using doubles, as experience with FSK in drs232_ldpc.c showed
+ doubles were required to obtain the same answers as Octave.
*/
-void Demod2D(float symbol_likelihood[], /* output, M*number_symbols */
- COMP r[], /* received QPSK symbols, number_symbols */
- COMP S_matrix[], /* constellation of size M */
- float EsNo,
- float fading[], /* real fading values, number_symbols */
- int number_symbols)
+void Demod2D(double symbol_likelihood[], /* output, M*number_symbols */
+ COMP r[], /* received QPSK symbols, number_symbols */
+ COMP S_matrix[], /* constellation of size M */
+ float EsNo,
+ float fading[], /* real fading values, number_symbols */
+ int number_symbols)
{
int M=4;
int i,j;
- float tempsr, tempsi, Er, Ei;
+ double tempsr, tempsi, Er, Ei;
/* determine output */
Er = r[i].real - tempsr;
Ei = r[i].imag - tempsi;
symbol_likelihood[i*M+j] = -EsNo*(Er*Er+Ei*Ei);
+ //printf("symbol_likelihood[%d][%d] = %f\n", i,j,symbol_likelihood[i*M+j]);
}
+ //exit(0);
}
}
-void Somap(float bit_likelihood[], /* number_bits, bps*number_symbols */
- float symbol_likelihood[], /* M*number_symbols */
- int number_symbols)
+void Somap(double bit_likelihood[], /* number_bits, bps*number_symbols */
+ double symbol_likelihood[], /* M*number_symbols */
+ int number_symbols)
{
- int M=2, bps = 2;
- int n,i,j,k,mask;
- float num[bps], den[bps];
- float metric;
+ int M=4, bps = 2;
+ int n,i,j,k,mask;
+ double num[bps], den[bps];
+ double metric;
for (n=0; n<number_symbols; n++) { /* loop over symbols */
for (k=0;k<bps;k++) {
}
}
+
int extract_output(char out_char[], int DecodedBits[], int ParityCheckCount[], int max_iter, int CodeLength, int NumberParityBits) {
int i, j;
void sd_to_llr(double llr[], double sd[], int n);
-void Demod2D(float symbol_likelihood[], COMP r[], COMP S_matrix[], float EsNo, float fading[], int number_symbols);
-void SomapDemod2D(float bit_likelihood[], float symbol_likelihood[]);
+void Demod2D(double symbol_likelihood[], COMP r[], COMP S_matrix[], float EsNo, float fading[], int number_symbols);
+void Somap(double bit_likelihood[], double symbol_likelihood[], int number_symbols);
struct v_node {
int degree;
#define NDISCARD 20 /* BER2measure disctrds first 20 frames */
#define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */
-/* QPSK constellation for symbol likelihood calculations */
-
-static COMP S_matrix[] = {
- { 1.0f, 0.0f},
- { 0.0f, 1.0f},
- { 0.0f, -1.0f},
- {-1.0f, 0.0f}
-};
-
int opt_exists(char *argv[], int argc, char opt[]) {
int i;
for (i=0; i<argc; i++) {
int sync_end;
};
+/* QPSK constellation for symbol likelihood calculations */
+
+static COMP S_matrix[] = {
+ { 1.0f, 0.0f},
+ { 0.0f, 1.0f},
+ { 0.0f, -1.0f},
+ {-1.0f, 0.0f}
+};
+
#ifdef __cplusplus
}
#endif
target_link_libraries(tdeframer m codec2)
add_definitions(-DMODEMPROBE_ENABLE -DXXXXX)
-add_executable(tofdm tofdm.c ../src/ofdm.c ../src/octave.c ../src/kiss_fft.c ../src/modem_probe.c)
+add_executable(tofdm tofdm.c ../src/ofdm.c ../src/octave.c ../src/kiss_fft.c ../src/modem_probe.c ../src/mpdecode_core.c)
target_link_libraries(tofdm m)
add_executable(tfreedv_data_channel tfreedv_data_channel.c)
#include "octave.h"
#include "test_bits_ofdm.h"
#include "comp_prim.h"
+#include "mpdecode_core.h"
-#define NFRAMES 30
+#define NFRAMES 3
#define SAMPLE_CLOCK_OFFSET_PPM 100
-#define FOFF_HZ 0.5f
+#define FOFF_HZ 0.5f
-#define ASCALE (2E5*1.1491/2.0) /* scale from shorts back to floats */
+#define ASCALE (2E5*1.1491/2.0) /* scale from shorts back to floats */
+
+#define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */
/*---------------------------------------------------------------------------*\
float timing_mx_log[NFRAMES];
float coarse_foff_est_hz_log[NFRAMES];
int sample_point_log[NFRAMES];
-
+ float symbol_likelihood_log[ (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) * NFRAMES];
+ float bit_likelihood_log[CODED_BITSPERFRAME * NFRAMES];
+
FILE *fout;
int f,i,j;
}
#endif
+ /* uncoded OFDM modem ---------------------------------------*/
+
ofdm_demod(ofdm, rx_bits, rxbuf_in);
#ifdef TESTING_FILE
printf("f: %d Nerr: %d\n", f, Nerrs);
#endif
+ /* LDPC functions --------------------------------------*/
+
+ double symbol_likelihood[ (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) ];
+ double bit_likelihood[CODED_BITSPERFRAME];
+ float EsNo = 10;
+
+ /* first few symbols are used for UW and txt bits, find start of (224,112) LDPC codeword */
+
+ assert((OFDM_NUWBITS+OFDM_NTXTBITS+CODED_BITSPERFRAME) == OFDM_BITSPERFRAME);
+
+ COMP ldpc_codeword_symbols[(CODED_BITSPERFRAME/OFDM_BPS)];
+ for(i=0, j=(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS; i<(CODED_BITSPERFRAME/OFDM_BPS); i++,j++) {
+ ldpc_codeword_symbols[i].real = crealf(ofdm->rx_np[j]);
+ ldpc_codeword_symbols[i].imag = cimagf(ofdm->rx_np[j]);
+ }
+ float *ldpc_codeword_symbol_amps = &ofdm->rx_amp[(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS];
+
+ Demod2D(symbol_likelihood, ldpc_codeword_symbols, S_matrix, EsNo, ldpc_codeword_symbol_amps, CODED_BITSPERFRAME/OFDM_BPS);
+ Somap(bit_likelihood, symbol_likelihood, CODED_BITSPERFRAME/OFDM_BPS);
+
/* rx vector logging -----------------------------------*/
assert(nin_tot < samples_per_frame*NFRAMES);
sample_point_log[f] = ofdm->sample_point + 1; /* offset by 1 to match Octave */
memcpy(&rx_bits_log[OFDM_BITSPERFRAME*f], rx_bits, sizeof(rx_bits));
+
+ for(i=0; i<(CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS); i++) {
+ symbol_likelihood_log[ (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) * f + i] = symbol_likelihood[i];
+ }
+ for(i=0; i<CODED_BITSPERFRAME; i++) {
+ bit_likelihood_log[CODED_BITSPERFRAME*f + i] = bit_likelihood[i];
+ }
}
/*---------------------------------------------------------*\
octave_save_int(fout, "sample_point_log_c", sample_point_log, NFRAMES, 1);
octave_save_complex(fout, "rx_np_log_c", (COMP*)rx_np_log, 1, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES);
octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, OFDM_BITSPERFRAME*NFRAMES);
+ octave_save_float(fout, "symbol_likelihood_log_c", symbol_likelihood_log, (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) * NFRAMES, 1, 1);
+ octave_save_float(fout, "bit_likelihood_log_c", bit_likelihood_log, CODED_BITSPERFRAME * NFRAMES, 1, 1);
fclose(fout);
ofdm_destroy(ofdm);