Work on removing constants from ofdm; cleaning up test framework
authorbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 9 Jan 2018 06:50:49 +0000 (06:50 +0000)
committerbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 9 Jan 2018 06:50:49 +0000 (06:50 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3389 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/autotest.m
codec2-dev/octave/tofdm.m
codec2-dev/src/codec2_ofdm.h
codec2-dev/src/modem_probe.c
codec2-dev/src/modem_probe.h
codec2-dev/src/ofdm.c
codec2-dev/src/ofdm_internal.h
codec2-dev/unittest/CMakeLists.txt
codec2-dev/unittest/tofdm.c

index 7a83184bd3d9d5f0cec812b13d474b02c87db3ae..624d35a1338736f217ead5659e3f87e20b2fce11 100644 (file)
@@ -44,7 +44,7 @@ function plot_sig_and_error(plotnum, subplotnum, sig, error, titlestr, axisvec)
 endfunction
 
 
-function check(a, b, test_name, tol, its_an_angle = 0)
+function pass = check(a, b, test_name, tol, its_an_angle = 0)
   global passes;
   global fails;
 
@@ -74,14 +74,16 @@ function check(a, b, test_name, tol, its_an_angle = 0)
 
   if e < tol
     printf("OK\n");
+    pass = true;
     passes++;
   else
     printf("FAIL (%f)\n",e);
+    pass = false;
     fails++;
   end
 endfunction
 
-function check_no_abs(a, b, test_name)
+function pass = check_no_abs(a, b, test_name)
   global passes;
   global fails;
 
@@ -103,9 +105,11 @@ function check_no_abs(a, b, test_name)
   e = sum(sum(a - b)/ll);
 
   if e < tol
+    pass = true;
     printf("OK\n");
     passes++;
   else
+    pass = false;
     printf("FAIL (%f)\n",e);
     fails++;
   end
index 73b99fea25db663ff782c78b04d5e123d7f29c3e..7fab085838acd4df0654e8a64bef8d00addd606d 100644 (file)
 % Octave script for comparing Octave and C versions of OFDZM modem
 
 % ------------------------------------------------------------------
+1;
 
-Nframes = 30;
-sample_clock_offset_ppm = 100;
-foff_hz = 0.5;
+function pass = run_ofdm_test(Nframes,sample_clock_offset_ppm,foff_hz)
+  %Nframes = 30;
+  %sample_clock_offset_ppm = 100;
+  %foff_hz = 5;
 
-more off; format;
-ofdm_lib;
-autotest;
+  more off; format;
+  ofdm_lib;
+  autotest;
 
-% ---------------------------------------------------------------------
-% Run Octave version 
-% ---------------------------------------------------------------------
+  % ---------------------------------------------------------------------
+  % Run Octave version 
+  % ---------------------------------------------------------------------
 
-Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
-states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
-ofdm_load_const;
+  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
+  states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
+  ofdm_load_const;
 
-rand('seed',1);
-tx_bits = round(rand(1,Nbitsperframe));
+  rand('seed',1);
+  tx_bits = round(rand(1,Nbitsperframe));
 
-% Run tx loop
+  % Run tx loop
 
-tx_bits_log = []; tx_log = [];
-for f=1:Nframes
-  tx_bits_log = [tx_bits_log tx_bits];
-  tx_log = [tx_log ofdm_mod(states, tx_bits)];
-end
-
-% Channel simulation ----------------------------------------------
+  tx_bits_log = []; tx_log = [];
+  for f=1:Nframes
+    tx_bits_log = [tx_bits_log tx_bits];
+    tx_log = [tx_log ofdm_mod(states, tx_bits)];
+  end
 
-rx_log = sample_clock_offset(tx_log, sample_clock_offset_ppm);
-rx_log = freq_shift(rx_log, foff_hz, Fs);
+  % Channel simulation ----------------------------------------------
 
-% Rx ---------------------------------------------------------------
+  rx_log = sample_clock_offset(tx_log, sample_clock_offset_ppm);
+  rx_log = freq_shift(rx_log, foff_hz, Fs);
 
-% Init rx with ideal timing so we can test with timing estimation disabled
+  % Rx ---------------------------------------------------------------
 
-Nsam = length(rx_log);
-prx = 1;
-nin = Nsamperframe+2*(M+Ncp);
-states.rxbuf(Nrxbuf-nin+1:Nrxbuf) = rx_log(prx:nin);
-prx += nin;
+  % Init rx with ideal timing so we can test with timing estimation disabled
 
-rxbuf_log = []; rxbuf_in_log = []; rx_sym_log = []; foff_hz_log = []; 
-timing_est_log = []; sample_point_log = []; 
-phase_est_pilot_log = []; rx_amp_log = [];
-rx_np_log = []; rx_bits_log = [];
+  Nsam = length(rx_log);
+  prx = 1;
+  nin = Nsamperframe+2*(M+Ncp);
+  states.rxbuf(Nrxbuf-nin+1:Nrxbuf) = rx_log(prx:nin);
+  prx += nin;
 
-states.timing_en = 1;
-states.foff_est_en = 1;
-states.phase_est_en = 1;
+  rxbuf_log = []; rxbuf_in_log = []; rx_sym_log = []; foff_hz_log = []; 
+  timing_est_log = []; sample_point_log = []; 
+  phase_est_pilot_log = []; rx_amp_log = [];
+  rx_np_log = []; rx_bits_log = [];
 
-if states.timing_en == 0
-  % manually set ideal timing instant
-  states.sample_point = Ncp;
-end
+  states.timing_en = 1;
+  states.foff_est_en = 1;
+  states.phase_est_en = 1;
 
-for f=1:Nframes
-
-  % insert samples at end of buffer, set to zero if no samples
-  % available to disable phase estimation on future pilots on last
-  % frame of simulation
-  nin = states.nin;
-  lnew = min(Nsam-prx+1,nin);
-  rxbuf_in = zeros(1,nin);
-  %printf("nin: %d prx: %d lnew: %d\n", nin, prx, lnew);
-  if lnew
-    rxbuf_in(1:lnew) = rx_log(prx:prx+lnew-1);
+  if states.timing_en == 0
+    % manually set ideal timing instant
+    states.sample_point = Ncp;
   end
-  prx += lnew;
-
-  [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
-
-  % log some states for comparison to C
-
-  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];
-  timing_est_log = [timing_est_log; states.timing_est];
-  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];
+
+  for f=1:Nframes
+
+    % insert samples at end of buffer, set to zero if no samples
+    % available to disable phase estimation on future pilots on last
+    % frame of simulation
   
-end
+    nin = states.nin;
+    lnew = min(Nsam-prx+1,nin);
+    rxbuf_in = zeros(1,nin);
+    %printf("nin: %d prx: %d lnew: %d\n", nin, prx, lnew);
+    if lnew
+      rxbuf_in(1:lnew) = rx_log(prx:prx+lnew-1);
+    end
+    prx += lnew;
+
+    [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
+
+    % log some states for comparison to C
+
+    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];
+    timing_est_log = [timing_est_log; states.timing_est];
+    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];
+    
+  end
 
-% ---------------------------------------------------------------------
-% Run C version and plot Octave and C states and differences 
-% ---------------------------------------------------------------------
+  % ---------------------------------------------------------------------
+  % Run C version and plot Octave and C states and differences 
+  % ---------------------------------------------------------------------
 
-% Override default path by setting path_to_tofdm = "/your/path/to/tofdm"
+  % Override default path by setting path_to_tofdm = "/your/path/to/tofdm"
 
-if exist("path_to_tofdm", "var") == 0
-   path_to_tofdm = "../build_linux/unittest/tofdm";
-end
-system(path_to_tofdm);
+  if exist("path_to_tofdm", "var") == 0
+    path_to_tofdm = "../build_linux/unittest/tofdm";
+  end
+  system(path_to_tofdm);
 
-load tofdm_out.txt;
+  load tofdm_out.txt;
+  % Generated with modem probe thing
+  load ofdm_test.txt;
 
-fg = 1;
-figure(fg++); clf; plot(rx_np_log,'+'); title('Octave Scatter Diagram'); axis([-1.5 1.5 -1.5 1.5]);
-figure(fg++); clf; plot(rx_np_log_c,'+'); title('C Scatter Diagram'); axis([-1.5 1.5 -1.5 1.5]);
+  fg = 1;
+  figure(fg++); clf; plot(rx_np_log,'+'); title('Octave Scatter Diagram'); axis([-1.5 1.5 -1.5 1.5]);
+  figure(fg++); clf; plot(rx_np_log_c,'+'); title('C Scatter Diagram'); axis([-1.5 1.5 -1.5 1.5]);
 
-stem_sig_and_error(fg++, 111, tx_bits_log_c, tx_bits_log - tx_bits_log_c, 'tx bits', [1 length(tx_bits_log) -1.5 1.5])
+  stem_sig_and_error(fg++, 111, tx_bits_log_c, tx_bits_log - tx_bits_log_c, 'tx bits', [1 length(tx_bits_log) -1.5 1.5])
 
-stem_sig_and_error(fg, 211, real(tx_log_c), real(tx_log - tx_log_c), 'tx re', [1 length(tx_log_c) -0.1 0.1])
-stem_sig_and_error(fg++, 212, imag(tx_log_c), imag(tx_log - tx_log_c), 'tx im', [1 length(tx_log_c) -0.1 0.1])
+  stem_sig_and_error(fg, 211, real(tx_log_c), real(tx_log - tx_log_c), 'tx re', [1 length(tx_log_c) -0.1 0.1])
+  stem_sig_and_error(fg++, 212, imag(tx_log_c), imag(tx_log - tx_log_c), 'tx im', [1 length(tx_log_c) -0.1 0.1])
 
-stem_sig_and_error(fg, 211, real(rx_log_c), real(rx_log - rx_log_c), 'rx re', [1 length(rx_log_c) -0.1 0.1])
-stem_sig_and_error(fg++, 212, imag(rx_log_c), imag(rx_log - rx_log_c), 'rx im', [1 length(rx_log_c) -0.1 0.1])
+  stem_sig_and_error(fg, 211, real(rx_log_c), real(rx_log - rx_log_c), 'rx re', [1 length(rx_log_c) -0.1 0.1])
+  stem_sig_and_error(fg++, 212, imag(rx_log_c), imag(rx_log - rx_log_c), 'rx im', [1 length(rx_log_c) -0.1 0.1])
 
-stem_sig_and_error(fg, 211, real(rxbuf_in_log_c), real(rxbuf_in_log - rxbuf_in_log_c), 'rxbuf in re', [1 length(rxbuf_in_log_c) -0.1 0.1])
-stem_sig_and_error(fg++, 212, imag(rxbuf_in_log_c), imag(rxbuf_in_log - rxbuf_in_log_c), 'rxbuf in im', [1 length(rxbuf_in_log_c) -0.1 0.1])
+  stem_sig_and_error(fg, 211, real(rxbuf_in_log_c), real(rxbuf_in_log - rxbuf_in_log_c), 'rxbuf in re', [1 length(rxbuf_in_log_c) -0.1 0.1])
+  stem_sig_and_error(fg++, 212, imag(rxbuf_in_log_c), imag(rxbuf_in_log - rxbuf_in_log_c), 'rxbuf in im', [1 length(rxbuf_in_log_c) -0.1 0.1])
 
-stem_sig_and_error(fg, 211, real(rxbuf_log_c), real(rxbuf_log - rxbuf_log_c), 'rxbuf re', [1 length(rxbuf_log_c) -0.1 0.1])
-stem_sig_and_error(fg++, 212, imag(rxbuf_log_c), imag(rxbuf_log - rxbuf_log_c), 'rxbuf im', [1 length(rxbuf_log_c) -0.1 0.1])
+  stem_sig_and_error(fg, 211, real(rxbuf_log_c), real(rxbuf_log - rxbuf_log_c), 'rxbuf re', [1 length(rxbuf_log_c) -0.1 0.1])
+  stem_sig_and_error(fg++, 212, imag(rxbuf_log_c), imag(rxbuf_log - rxbuf_log_c), 'rxbuf im', [1 length(rxbuf_log_c) -0.1 0.1])
 
-stem_sig_and_error(fg, 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(fg++, 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(fg, 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(fg++, 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])
 
-% for angles pi and -pi are the same
+  % for angles pi and -pi are the same
 
-d = phase_est_pilot_log - phase_est_pilot_log_c; d = angle(exp(j*d));
+  d = phase_est_pilot_log - phase_est_pilot_log_c; d = angle(exp(j*d));
 
-stem_sig_and_error(fg, 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(fg++, 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(fg, 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(fg++, 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(fg++, 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(fg++, 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(fg,   211, timing_est_log_c, (timing_est_log - timing_est_log_c), 'timing est', [1 length(timing_est_log_c) -1.5 1.5])
-stem_sig_and_error(fg++, 212, sample_point_log_c, (sample_point_log - sample_point_log_c), 'sample point', [1 length(sample_point_log_c) -1.5 1.5])
+  stem_sig_and_error(fg,   211, timing_est_log_c, (timing_est_log - timing_est_log_c), 'timing est', [1 length(timing_est_log_c) -1.5 1.5])
+  stem_sig_and_error(fg++, 212, sample_point_log_c, (sample_point_log - sample_point_log_c), 'sample point', [1 length(sample_point_log_c) -1.5 1.5])
 
-stem_sig_and_error(fg++, 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(fg++, 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 -----------------------------
+  % Run through checklist -----------------------------
+  pass = true;
+  pass = check_no_abs(W, W_c, 'W') && pass;
+  pass = check(tx_bits_log, tx_bits_log_c, 'tx_bits') && pass;
+  pass = check(tx_log, tx_log_c, 'tx') && pass;
+  pass = check(rx_log, rx_log_c, 'rx') && pass;
+  pass = check(rxbuf_in_log, rxbuf_in_log_c, 'rxbuf in') && pass;
+  pass = check(rxbuf_log, rxbuf_log_c, 'rxbuf') && pass;
+  pass = check(rx_sym_log, rx_sym_log_c, 'rx_sym') && pass;
+  pass = check(phase_est_pilot_log, phase_est_pilot_log_c, 'phase_est_pilot', tol=1E-3, its_an_angle=1) && pass;
+  pass = check(rx_amp_log, rx_amp_log_c, 'rx_amp') && pass;
+  pass = check(timing_est_log, timing_est_log_c', 'timing_est') && pass;
+  pass = check(sample_point_log, sample_point_log_c, 'sample_point') && pass;
+  pass = check(foff_hz_log, foff_hz_log_c', 'foff_est_hz') && pass;
+  pass = check(rx_bits_log, rx_bits_log_c, 'rx_bits') && pass;
+  
 
-check_no_abs(W, W_c, 'W');
-check(tx_bits_log, tx_bits_log_c, 'tx_bits');
-check(tx_log, tx_log_c, 'tx');
-check(rx_log, rx_log_c, 'rx');
-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(timing_est_log, timing_est_log_c, 'timing_est');
-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');
+end
 
+run_ofdm_test(30,100,.1)
\ No newline at end of file
index b335df88f27cd9241b714c8f33d37a1b174b20a3..fc1833bda454211046896e9220ce9109e2be17bd 100644 (file)
@@ -55,8 +55,8 @@ void ofdm_destroy(struct OFDM *);
 void ofdm_mod(struct OFDM *, COMP *, const int *);
 void ofdm_demod(struct OFDM *, int *, COMP *);
 int ofdm_get_nin(struct OFDM *);
-int ofdm_get_samples_per_frame(void);
-int ofdm_get_max_samples_per_frame(void);
+int ofdm_get_samples_per_frame(struct OFDM *ofdm);
+int ofdm_get_max_samples_per_frame(struct OFDM *ofdm);
 
 /* option setters */
 
index 884a1a8566b7e9b4ef42ceebae7ff986f7f619bc..b4a616564781eacaf57fa21b133d69aca82cf1dc 100644 (file)
@@ -160,6 +160,7 @@ probe_trace_info * modem_probe_get_trace(char * tracename){
        
 }
 
+
 void modem_probe_samp_i_int(char * tracename,int32_t samp[],size_t cnt){
        probe_trace_info *pti;
        datlink *ndat;
index 2faada13115ec457b4c481dd616bd3ccf35d1884..d5b76523b6bff7616f72c28561acd1dfbfa5361b 100644 (file)
@@ -29,9 +29,9 @@
 #define __MODEMPROBE_H
 #include <stdint.h>
 #include <stdlib.h>
+#include <complex.h>
 #include "comp.h"
 
-
 #ifdef MODEMPROBE_ENABLE
 
 /* Internal functions */
@@ -88,6 +88,16 @@ static inline void modem_probe_samp_c(char *tracename,COMP samp[],size_t cnt){
         modem_probe_samp_c_int(tracename,samp,cnt);
 }
 
+/*
+ * Save some number of complex samples to a named trace
+ * char *tracename - name of trace being saved to
+ * float complex samp[] - int samples
+ * size_t cnt - how many samples to save
+ */
+static inline void modem_probe_samp_cft(char *tracename,complex float samp[],size_t cnt){
+        modem_probe_samp_c_int(tracename,(COMP*)samp,cnt);
+}
+
 #else
 
 static inline void modem_probe_init(char *modname,char *runname){
@@ -110,6 +120,10 @@ static inline void modem_probe_samp_c(char *name,COMP samp[],size_t cnt){
         return;
 }
 
+static inline void modem_probe_samp_cft(char *name,complex float samp[],size_t cnt){
+        return;
+}
+
 #endif
 
 #endif
index 52079af44edd8e9bab464bfd30c86b41a7b9ef0f..cdaa9c0bd3a5924e0fa4e7eebdaba0c8c53ceb35 100644 (file)
 #include "ofdm_internal.h"
 #include "codec2_ofdm.h"
 #include "kiss_fft.h"
+#include "modem_probe.h"
 
 /* Concrete definition of 700D parameters */
-const struct OFDM_CONFIG OFDM_CONFIG_700D_C = 
-{.a = 0};
+const struct OFDM_CONFIG OFDM_CONFIG_700D_C = {
+    .Nc = 16,
+    .Ts = -1,
+    .Rs = -1,
+    .Fs = 8000,
+    .bps = 2,
+    .Tcp = -1,
+    .Ns = 8,
+    .M = 144,
+    .Ncp = 16,
+    .FtWindowWidth = 11,
+    .BitsPerFrame = 224,
+    .SampsPerFrame = 1280,
+    .SampsPerFrameMax = 1320,
+    .RxBufSize = 4320,
+    .RowsPerFrame = 7
+};
 
 /* Pointer to 700D config */ 
 const struct OFDM_CONFIG  * OFDM_CONFIG_700D = &OFDM_CONFIG_700D_C;
@@ -106,12 +122,14 @@ static void qpsk_demod(complex float symbol, int *bits) {
 
 static void idft(struct OFDM *ofdm, complex float *result, complex float *vector) {
     int row, col;
+    int Nc                  = ofdm->config.Nc;
+    int M                   = ofdm->config.M;
 
-    for (row = 0; row < OFDM_M; row++) {
+    for (row = 0; row < M; row++) {
         result[row] = 0.0f + 0.0f * I;
 
-        for (col = 0; col < (OFDM_NC + 2); col++) {
-            result[row] = result[row] + (vector[col] * (ofdm->W[col][row] / (float) OFDM_M)); /* complex result */
+        for (col = 0; col < (Nc + 2); col++) {
+            result[row] = result[row] + (vector[col] * (ofdm->W[col][row] / (float) M)); /* complex result */
         }
     }
 }
@@ -120,11 +138,13 @@ static void idft(struct OFDM *ofdm, complex float *result, complex float *vector
 
 static void dft(struct OFDM *ofdm, complex float *result, complex float *vector) {
     int row, col;
+    int Nc                  = ofdm->config.Nc;
+    int M                   = ofdm->config.M;
 
-    for (col = 0; col < (OFDM_NC + 2); col++) {
+    for (col = 0; col < (Nc + 2); col++) {
         result[col] = 0.0f + 0.0f * I;
 
-        for (row = 0; row < OFDM_M; row++) {
+        for (row = 0; row < M; row++) {
             result[col] = result[col] + (vector[row] * conjf(ofdm->W[col][row])); /* complex result */
         }
     }
@@ -150,16 +170,27 @@ static complex float vector_sum(complex float *a, int num_elements) {
 
 static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) {
     complex float csam;
-    int Ncorr = length - (OFDM_SAMPLESPERFRAME + (OFDM_M + OFDM_NCP));
-    int Fs = OFDM_FS;
-    int SFrame = OFDM_SAMPLESPERFRAME;
+    int Fs                  = ofdm->config.Fs;
+    int Rs                  = ofdm->config.Rs;
+    int Bps                 = ofdm->config.bps;
+    int Nc                  = ofdm->config.Nc;
+    int M                   = ofdm->config.M;
+    int Ncp                 = ofdm->config.Ncp;
+    int Ns                  = ofdm->config.Ns;
+    int RowsPerFrame        = ofdm->config.RowsPerFrame;
+    int SampsPerFrame       = ofdm->config.SampsPerFrame;
+    int Fcenter             = ofdm->config.Fcenter;
+    int Ncorr = length - (SampsPerFrame + (M + Ncp));
+
+    int SFrame = SampsPerFrame;
     float corr[Ncorr];
+    int NPSamp = M + Ncp;
     int i, j;
 
     for (i = 0; i < Ncorr; i++) {
         complex float temp = 0.0f + 0.0f * I;
 
-        for (j = 0; j < (OFDM_M + OFDM_NCP); j++) {
+        for (j = 0; j < (M + Ncp); j++) {
             csam = conjf(ofdm->pilot_samples[j]);
             temp = temp + (rx[i + j] * csam);
             temp = temp + (rx[i + j + SFrame] * csam);
@@ -185,8 +216,53 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) {
     kiss_fft_cfg fftcfg = kiss_fft_alloc(Fs,0,NULL,NULL);
     complex float fft_in[Fs];
     complex float fft_out[Fs];
-    
-    
+    float C[Fs];
+    /* Zero FFT input array */
+    for(i = 0; i < Fs; i++){
+        fft_in[i] = 0;
+    }
+    /* shift and copy in NPsam samples to front of buffer for FFT'ing */
+    for(i = 0; i < NPSamp; i++){
+        fft_in[i] = rx[i + t_est] * conjf(ofdm->pilot_samples[i]);
+    }
+    kiss_fft(fftcfg,(kiss_fft_cpx*)fft_in,(kiss_fft_cpx*)fft_out);
+
+    /* Copy into output corr array, taking magnitude */
+    /* TODO: May be able to skip sqrt() in abs, since we're just looking for a maximum point down the line */
+    for(i = 0; i < Fs; i++){
+        C[i] = cabsf(fft_out[i]);
+    }
+
+    /* shift and copy in NPsam samples to front of buffer for FFT'ing */
+    for(i = 0; i < NPSamp; i++){
+        fft_in[i] = rx[i + t_est + SFrame] * conjf(ofdm->pilot_samples[i]);
+    }
+    kiss_fft(fftcfg,(kiss_fft_cpx*)fft_in,(kiss_fft_cpx*)fft_out);
+
+    /* Add into output corr array */
+    for(i = 0; i < Fs; i++){
+        C[i] += cabsf(fft_out[i]);
+    }
+
+    int fmax = 30;
+    int pmax_i,nmax_i;
+    float pmax,nmax;
+    float foff_est;
+    pmax_i = nmax_i = 0;
+    pmax = nmax = 0;
+    /* Search the positive and negative sides of the FFT to +/-fmax for peak */
+    for(i = 0; i < fmax; i++){
+        if(C[i] > pmax){
+            pmax = C[i];
+            pmax_i = i;
+        }
+        if(C[Fs-i-1] > nmax){
+            nmax = C[i];
+            nmax_i = i;
+        }
+    }
+    foff_est = (pmax > nmax) ? pmax_i : (nmax_i - fmax); 
+    fprintf(stderr,"foff_est is %f\n",foff_est);
 
     return t_est;
 }
@@ -199,62 +275,109 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) {
 
 static void ofdm_txframe(struct OFDM *ofdm, complex float tx[OFDM_SAMPLESPERFRAME],
         complex float *tx_sym_lin) {
-    complex float aframe[OFDM_NS][OFDM_NC + 2];
-    complex float asymbol[OFDM_M];
-    complex float asymbol_cp[OFDM_M + OFDM_NCP];
+            
+    int Fs                  = ofdm->config.Fs;
+    int Rs                  = ofdm->config.Rs;
+    int Bps                 = ofdm->config.bps;
+    int Nc                  = ofdm->config.Nc;
+    int M                   = ofdm->config.M;
+    int Ncp                 = ofdm->config.Ncp;
+    int Ns                  = ofdm->config.Ns;
+    int RowsPerFrame        = ofdm->config.RowsPerFrame;
+    int SampsPerFrame       = ofdm->config.SampsPerFrame;
+    int Fcenter             = ofdm->config.Fcenter;
+
+    complex float aframe[Ns][Nc + 2];
+    complex float asymbol[M];
+    complex float asymbol_cp[M + Ncp];
     int i, j, k, m;
 
     /* initialize aframe to complex zero */
 
-    for (i = 0; i < OFDM_NS; i++) {
-        for (j = 0; j < (OFDM_NC + 2); j++) {
+    for (i = 0; i < Ns; i++) {
+        for (j = 0; j < (Nc + 2); j++) {
             aframe[i][j] = 0.0f + 0.0f * I;
         }
     }
 
     /* copy in a row of complex pilots to first row */
 
-    for (i = 0; i < (OFDM_NC + 2); i++) {
+    for (i = 0; i < (Nc + 2); i++) {
         aframe[0][i] = ofdm->pilots[i];
     }
 
     /* Place symbols in multi-carrier frame with pilots */
     /* This will place boundary values of complex zero around data */
 
-    for (i = 1; i <= OFDM_ROWSPERFRAME; i++) {
+    for (i = 1; i <= RowsPerFrame; i++) {
 
         /* copy in the Nc complex values with [0 Nc 0] or (Nc + 2) total */
 
-        for (j = 1; j < (OFDM_NC + 1); j++) {
-            aframe[i][j] = tx_sym_lin[((i - 1) * OFDM_NC) + (j - 1)];
+        for (j = 1; j < (Nc + 1); j++) {
+            aframe[i][j] = tx_sym_lin[((i - 1) * Nc) + (j - 1)];
         }
     }
 
     /* OFDM up-convert symbol by symbol so we can add CP */
 
-    for (i = 0, m = 0; i < OFDM_NS; i++, m += (OFDM_M + OFDM_NCP)) {
+    for (i = 0, m = 0; i < Ns; i++, m += (M + Ncp)) {
         idft(ofdm, asymbol, aframe[i]);
 
         /* Copy the last Ncp columns to the front */
 
-        for (j = (OFDM_M - OFDM_NCP), k = 0; j < OFDM_M; j++, k++) {
+        for (j = (M - Ncp), k = 0; j < M; j++, k++) {
             asymbol_cp[k] = asymbol[j];
         }
 
         /* Now copy the whole row after it */
 
-        for (j = OFDM_NCP, k = 0; k < OFDM_M; j++, k++) {
+        for (j = Ncp, k = 0; k < M; j++, k++) {
             asymbol_cp[j] = asymbol[k];
         }
 
         /* Now move row to the tx reference */
 
-        for (j = 0; j < (OFDM_M + OFDM_NCP); j++) {
+        for (j = 0; j < (M + Ncp); j++) {
             tx[m + j] = asymbol_cp[j];
         }
     }
 }
 
+/*
+ * Utility function to allocate a 2d array of dimension
+ *  [sx][sy] with elements of elem size
+ */
+void **alloc_doubleary(size_t sx,size_t sy,size_t elem){
+    size_t i;
+    char ** ary = malloc(sizeof(void*) * sx);
+    if(ary == NULL){
+        return NULL;
+    }
+    *ary = malloc(elem * sx * sy);
+    if(*ary == NULL){
+        free(ary);
+        return NULL;
+    }
+    for(i=0; i<sx; i++){
+        ary[i] = ((*ary) + (sy*i*elem));
+    }
+    return (void**) ary;
+}
+
+void free_doubleary(void ** ary){
+    if(ary == NULL){
+        return;
+    }
+    if(*ary == NULL){
+        free(ary);
+        return;
+    }
+
+    free(*ary);
+
+    free(ary);
+}
+
 /*
  * ------------
  * ofdm_create
@@ -267,25 +390,44 @@ static void ofdm_txframe(struct OFDM *ofdm, complex float tx[OFDM_SAMPLESPERFRAM
 struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) {
     struct OFDM *ofdm;
     int i, j;
-
     if ((ofdm = (struct OFDM *) malloc(sizeof (struct OFDM))) == NULL) {
         return NULL;
     }
 
     /* Copy config structure */
+    /* TODO: validate config structure */
     memcpy((void*)&ofdm->config,(void*)config,sizeof(struct OFDM_CONFIG));
+    int Fs                  = ofdm->config.Fs;
+    int Rs                  = ofdm->config.Rs;
+    int Bps                 = ofdm->config.bps;
+    int Nc                  = ofdm->config.Nc;
+    int M                   = ofdm->config.M;
+    int Ncp                 = ofdm->config.Ncp;
+    int Ns                  = ofdm->config.Ns;
+    int RowsPerFrame        = ofdm->config.RowsPerFrame;
+    int SampsPerFrame       = ofdm->config.SampsPerFrame;
+    int Fcenter             = ofdm->config.Fcenter;
+
+    /* Allocate various buffers */
+    /* TODO: cleanup after failed malloc */
+    ofdm->pilot_samples = malloc(sizeof(complex float) * (M + Ncp));
+    ofdm->pilots = malloc(sizeof(complex float) * (Nc+2));
+    ofdm->rxbuf = malloc(sizeof(complex float) * ofdm->config.RxBufSize);
+    ofdm->w = malloc(sizeof(float) * (Nc+2));
+    ofdm->rx_amp = malloc(sizeof(float) * RowsPerFrame * Nc);
+    ofdm->aphase_est_pilot_log = malloc(sizeof(float) * RowsPerFrame * Nc);
 
     /* store complex BPSK pilot symbols */
 
-    for (i = 0; i < (OFDM_NC + 2); i++) {
+    for (i = 0; i < (Nc + 2); i++) {
         ofdm->pilots[i] = ((float) pilotvalues[i]) + 0.0f * I;
     }
 
     /* carrier tables for up and down conversion */
 
-    int Nlower = floorf((OFDM_CENTRE - OFDM_RS * (OFDM_NC / 2)) / OFDM_RS);
+    int Nlower = floorf((OFDM_CENTRE - OFDM_RS * (Nc / 2)) / OFDM_RS);
 
-    for (i = 0, j = Nlower; i < (OFDM_NC + 2); i++, j++) {
+    for (i = 0, j = Nlower; i < (Nc + 2); i++, j++) {
         /*
          * 2 * pi * j/144  j=19..36
          * j = 1 kHz to 2 kHz (1.5 kHz center)
@@ -294,14 +436,18 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) {
         ofdm->w[i] = TAU * (float) j / (OFDM_FS / OFDM_RS);
     }
 
-    for (i = 0; i < (OFDM_NC + 2); i++) {
-        for (j = 0; j < OFDM_M; j++) {
+    ofdm->W = (complex float **) alloc_doubleary(Nc+2,M,sizeof(complex float));
+    ofdm->rx_sym = (complex float **) alloc_doubleary(Ns+3,Nc+2,sizeof(complex float));
+
+    for (i = 0; i < (Nc + 2); i++) {
+        
+        for (j = 0; j < M; j++) {
             ofdm->W[i][j] = cexpf(I * ofdm->w[i] * j);
         }
     }
 
-    for (i = 0; i < (OFDM_NS + 3); i++) {
-        for (j = 0; j < (OFDM_NC + 2); j++) {
+    for (i = 0; i < (Ns + 3); i++) {
+        for (j = 0; j < (Nc + 2); j++) {
             ofdm->rx_sym[i][j] = 0.0f + 0.0f * I;
         }
     }
@@ -317,11 +463,11 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) {
     ofdm->foff_est_hz = 0.0f;
     ofdm->sample_point = 0;
     ofdm->timing_est = 0;
-    ofdm->nin = OFDM_SAMPLESPERFRAME;
+    ofdm->nin = SampsPerFrame;
 
     /* create the OFDM waveform */
 
-    complex float temp[OFDM_M];
+    complex float temp[M];
 
     idft(ofdm, temp, ofdm->pilots);
 
@@ -331,13 +477,13 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) {
 
     /* first copy the last Cyclic Prefix (CP) values */
 
-    for (i = 0, j = (OFDM_M - OFDM_NCP); i < OFDM_NCP; i++, j++) {
+    for (i = 0, j = (M - Ncp); i < Ncp; i++, j++) {
         ofdm->pilot_samples[i] = temp[j];
     }
 
     /* Now copy the whole thing after the above */
 
-    for (i = OFDM_NCP, j = 0; j < OFDM_M; i++, j++) {
+    for (i = Ncp, j = 0; j < M; i++, j++) {
         ofdm->pilot_samples[i] = temp[j];
     }
 
@@ -352,12 +498,12 @@ int ofdm_get_nin(struct OFDM *ofdm) {
     return ofdm->nin;
 }
 
-int ofdm_get_samples_per_frame() {
-    return OFDM_SAMPLESPERFRAME;
+int ofdm_get_samples_per_frame(struct OFDM *ofdm) {
+    return ofdm->config.SampsPerFrame;
 }
 
-int ofdm_get_max_samples_per_frame() {
-    return OFDM_MAX_SAMPLESPERFRAME;
+int ofdm_get_max_samples_per_frame(struct OFDM *ofdm) {
+    return ofdm->config.SampsPerFrameMax;
 }
 
 void ofdm_set_verbose(struct OFDM *ofdm, int level) {
@@ -369,7 +515,7 @@ void ofdm_set_timing_enable(struct OFDM *ofdm, bool val) {
 
     if (ofdm->timing_en == false) {
         /* manually set ideal timing instant */
-        ofdm->sample_point = (OFDM_NCP - 1);
+        ofdm->sample_point = (ofdm->config.Ncp - 1);
     }
 }
 
@@ -392,19 +538,32 @@ void ofdm_set_off_est_hz(struct OFDM *ofdm, float val) {
  */
 
 void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *tx_bits) {
-    int length = OFDM_BITSPERFRAME / OFDM_BPS;
-    complex float tx[OFDM_SAMPLESPERFRAME];
+    
+    int Fs                  = ofdm->config.Fs;
+    int Rs                  = ofdm->config.Rs;
+    int Bps                 = ofdm->config.bps;
+    int Nc                  = ofdm->config.Nc;
+    int M                   = ofdm->config.M;
+    int Ncp                 = ofdm->config.Ncp;
+    int Ns                  = ofdm->config.Ns;
+    int RowsPerFrame        = ofdm->config.RowsPerFrame;
+    int SampsPerFrame       = ofdm->config.SampsPerFrame;
+    int BitsPerFrame        = ofdm->config.BitsPerFrame;
+    int Fcenter             = ofdm->config.Fcenter;
+
+    int length = BitsPerFrame / Bps;
+    complex float tx[SampsPerFrame];
     complex float tx_sym_lin[length];
     int dibit[2];
     int s, i;
 
-    if (OFDM_BPS == 1) {
+    if (Bps == 1) {
         /* Here we will have Nbitsperframe / 1 */
 
         for (s = 0; s < length; s++) {
             tx_sym_lin[s] = (float) (2 * tx_bits[s] - 1) + 0.0f * I;
         }
-    } else if (OFDM_BPS == 2) {
+    } else if (Bps == 2) {
         /* Here we will have Nbitsperframe / 2 */
 
         for (s = 0, i = 0; i < length; s += 2, i++) {
@@ -418,7 +577,7 @@ void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *t
 
     /* convert to comp */
 
-    for (i = 0; i < OFDM_SAMPLESPERFRAME; i++) {
+    for (i = 0; i < SampsPerFrame; i++) {
         result[i].real = crealf(tx[i]);
         result[i].imag = cimagf(tx[i]);
     }
@@ -432,20 +591,35 @@ void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *t
 
 void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
     complex float aphase_est_pilot_rect;
-    float aphase_est_pilot[OFDM_NC + 2];
-    float aamp_est_pilot[OFDM_NC + 2];
+    
+    int Fs                  = ofdm->config.Fs;
+    int Rs                  = ofdm->config.Rs;
+    int Bps                 = ofdm->config.bps;
+    int Nc                  = ofdm->config.Nc;
+    int M                   = ofdm->config.M;
+    int Ncp                 = ofdm->config.Ncp;
+    int Ns                  = ofdm->config.Ns;
+    int RowsPerFrame        = ofdm->config.RowsPerFrame;
+    int SampsPerFrame       = ofdm->config.SampsPerFrame;
+    int FtWindowWidth       = ofdm->config.FtWindowWidth;
+    int BitsPerFrame        = ofdm->config.BitsPerFrame;
+    int Fcenter             = ofdm->config.Fcenter;
+    int RxBufSize           = ofdm->config.RxBufSize;
+
+    float aphase_est_pilot[Nc + 2];
+    float aamp_est_pilot[Nc + 2];
     float freq_err_hz;
     int i, j, k, rr, st, en, ft_est;
 
     /* shift the buffer left based on nin */
 
-    for (i = 0, j = ofdm->nin; i < (OFDM_RXBUF - ofdm->nin); i++, j++) {
+    for (i = 0, j = ofdm->nin; i < (RxBufSize - ofdm->nin); i++, j++) {
         ofdm->rxbuf[i] = ofdm->rxbuf[j];
     }
 
     /* insert latest input samples onto tail of rxbuf */
 
-    for (i = (OFDM_RXBUF - ofdm->nin), j = 0; i < OFDM_RXBUF; i++, j++) {
+    for (i = (RxBufSize - ofdm->nin), j = 0; i < RxBufSize; i++, j++) {
         ofdm->rxbuf[i] = rxbuf_in[j].real + rxbuf_in[j].imag * I;
     }
 
@@ -453,15 +627,15 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      * get user and calculated freq offset
      */
 
-    float woff_est = TAU * ofdm->foff_est_hz / OFDM_FS;
+    float woff_est = TAU * ofdm->foff_est_hz / (float)(Fs);
 
     /* update timing estimate -------------------------------------------------- */
 
     if (ofdm->timing_en == true) {
         /* update timing at start of every frame */
 
-        st = ((OFDM_M + OFDM_NCP) + OFDM_SAMPLESPERFRAME) - floorf(OFDM_FTWINDOWWIDTH / 2) + ofdm->timing_est;
-        en = st + OFDM_SAMPLESPERFRAME - 1 + (OFDM_M + OFDM_NCP) + OFDM_FTWINDOWWIDTH;
+        st = ((M + Ncp) + SampsPerFrame) - floorf(FtWindowWidth / 2) + ofdm->timing_est;
+        en = st + SampsPerFrame - 1 + (M + Nc) + FtWindowWidth;
 
         complex float work[(en - st)];
 
@@ -471,11 +645,12 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
          */
 
         for (i = st, j = 0; i < en; i++, j++) {
+            /* TODO: Look into reducing cexpf usage */
             work[j] = ofdm->rxbuf[i] * cexpf(-I * woff_est * i);
         }
 
         ft_est = coarse_sync(ofdm, work, (en - st));
-        ofdm->timing_est += (ft_est - ceilf(OFDM_FTWINDOWWIDTH / 2));
+        ofdm->timing_est += (ft_est - ceilf(FtWindowWidth / 2));
 
         if (ofdm->verbose > 1) {
             fprintf(stdout, "  ft_est: %2d timing_est: %2d sample_point: %2d\n", ft_est, ofdm->timing_est, ofdm->sample_point);
@@ -483,8 +658,8 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
 
         /* Black magic to keep sample_point inside cyclic prefix.  Or something like that. */
 
-        ofdm->sample_point = max(ofdm->timing_est + (OFDM_NCP / 4), ofdm->sample_point);
-        ofdm->sample_point = min(ofdm->timing_est + OFDM_NCP, ofdm->sample_point);
+        ofdm->sample_point = max(ofdm->timing_est + (Ncp / 4), ofdm->sample_point);
+        ofdm->sample_point = min(ofdm->timing_est + Ncp,       ofdm->sample_point);
     }
 
     /*
@@ -526,8 +701,8 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      * The average of the four pilot symbols is our phase estimation.
      */
 
-    for (i = 0; i < (OFDM_NS + 3); i++) {
-        for (j = 0; j < (OFDM_NC + 2); j++) {
+    for (i = 0; i < (Ns + 3); i++) {
+        for (j = 0; j < (Nc + 2); j++) {
             ofdm->rx_sym[i][j] = 0.0f + 0.0f * I;
         }
     }
@@ -536,10 +711,10 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      * "Previous" pilot symbol is one modem frame above.
      */
 
-    st = (OFDM_M + OFDM_NCP) + 1 + ofdm->sample_point;
-    en = st + OFDM_M;
+    st = (M + Ncp) + 1 + ofdm->sample_point;
+    en = st + M;
 
-    complex float work[OFDM_M];
+    complex float work[M];
 
     /* down-convert at current timing instant---------------------------------- */
 
@@ -575,9 +750,9 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      * In this routine we also process the current data symbols.
      */
 
-    for (rr = 0; rr < (OFDM_NS + 1); rr++) {
-        st = (OFDM_M + OFDM_NCP) + OFDM_SAMPLESPERFRAME + (rr * (OFDM_M + OFDM_NCP)) + 1 + ofdm->sample_point;
-        en = st + OFDM_M;
+    for (rr = 0; rr < (Ns + 1); rr++) {
+        st = (M + Ncp) + SampsPerFrame + (rr * (M + Ncp)) + 1 + ofdm->sample_point;
+        en = st + M;
 
         /* down-convert at current timing instant---------------------------------- */
 
@@ -624,8 +799,8 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      * We only want the "future" pilot symbol, to perform the averaging of all pilots.
      */
 
-    st = (OFDM_M + OFDM_NCP) + (3 * OFDM_SAMPLESPERFRAME) + 1 + ofdm->sample_point;
-    en = st + OFDM_M;
+    st = (M + Ncp) + (3 * SampsPerFrame) + 1 + ofdm->sample_point;
+    en = st + M;
 
     /* down-convert at current timing instant---------------------------------- */
 
@@ -644,7 +819,7 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      * +----------------------+
      */
 
-    dft(ofdm, ofdm->rx_sym[OFDM_NS + 2], work);
+    dft(ofdm, ofdm->rx_sym[Ns + 2], work);
 
     /*
      * We are finished now with the DFT and down conversion
@@ -662,19 +837,19 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
          */
 
         complex float freq_err_rect = conjf(vector_sum(ofdm->rx_sym[1],
-                OFDM_NC + 2)) * vector_sum(ofdm->rx_sym[OFDM_NS + 1], OFDM_NC + 2);
+                Nc + 2)) * vector_sum(ofdm->rx_sym[Ns + 1], Nc + 2);
 
         /* prevent instability in atan(im/re) when real part near 0 */
 
         freq_err_rect = freq_err_rect + 1E-6f;
 
-        freq_err_hz = cargf(freq_err_rect) * OFDM_RS / (TAU * OFDM_NS);
+        freq_err_hz = cargf(freq_err_rect) * OFDM_RS / (TAU * Ns);
         ofdm->foff_est_hz += (ofdm->foff_est_gain * freq_err_hz);
     }
 
     /* OK - now estimate and correct pilot phase  ---------------------------------- */
 
-    for (i = 0; i < (OFDM_NC + 2); i++) {
+    for (i = 0; i < (Nc + 2); i++) {
         aphase_est_pilot[i] = 10.0f;
         aamp_est_pilot[i] = 0.0f;
     }
@@ -685,7 +860,7 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      * Then average the phase surrounding each of the data symbols.
      */
 
-    for (i = 1; i < (OFDM_NC + 1); i++) {
+    for (i = 1; i < (Nc + 1); i++) {
         complex float symbol[3];
 
         for (j = (i - 1), k = 0; j < (i + 2); j++, k++) {
@@ -695,7 +870,7 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
         aphase_est_pilot_rect = vector_sum(symbol, 3);
 
         for (j = (i - 1), k = 0; j < (i + 2); j++, k++) {
-            symbol[k] = ofdm->rx_sym[OFDM_NS + 1][j] * conjf(ofdm->pilots[j]); /* next pilot conjugate */
+            symbol[k] = ofdm->rx_sym[Ns + 1][j] * conjf(ofdm->pilots[j]); /* next pilot conjugate */
         }
 
         aphase_est_pilot_rect = aphase_est_pilot_rect + vector_sum(symbol, 3);
@@ -709,7 +884,7 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
         aphase_est_pilot_rect = aphase_est_pilot_rect + vector_sum(symbol, 3);
 
         for (j = (i - 1), k = 0; j < (i + 2); j++, k++) {
-            symbol[k] = ofdm->rx_sym[OFDM_NS + 2][j] * ofdm->pilots[j]; /* last pilot */
+            symbol[k] = ofdm->rx_sym[Ns + 2][j] * ofdm->pilots[j]; /* last pilot */
         }
 
         aphase_est_pilot_rect = aphase_est_pilot_rect + vector_sum(symbol, 3);
@@ -727,17 +902,18 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
      */
 
     complex float rx_corr;
+    complex float rx_np[RowsPerFrame * Nc];
     int abit[2];
     int bit_index = 0;
 
-    for (rr = 0; rr < OFDM_ROWSPERFRAME; rr++) {
+    for (rr = 0; rr < RowsPerFrame; rr++) {
         /*
          * Note the i has an index of 1 to 16, so we ignore carriers 0 and 17.
          *
          * Also note we are using sym[2..8] or the seven data symbols.
          */
 
-        for (i = 1; i < (OFDM_NC + 1); i++) {
+        for (i = 1; i < (Nc + 1); i++) {
             if (ofdm->phase_est_en == true) {
                 rx_corr = ofdm->rx_sym[rr + 2][i] * cexpf(-I * aphase_est_pilot[i]);
             } else {
@@ -749,7 +925,7 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
              * without the pilots. Thus, the name rx (no pilot) np
              */
 
-            ofdm->rx_np[(rr * OFDM_NC) + (i - 1)] = rx_corr;
+            rx_np[(rr * Nc) + (i - 1)] = rx_corr;
 
             /*
              * Note even though amp ests are the same for each col,
@@ -757,14 +933,14 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
              * so convenient to log them all
              */
 
-            ofdm->rx_amp[(rr * OFDM_NC) + (i - 1)] = aamp_est_pilot[i];
+            ofdm->rx_amp[(rr * Nc) + (i - 1)] = aamp_est_pilot[i];
 
             /*
              * Note like amps in this implementation phase ests are 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];
+            ofdm->aphase_est_pilot_log[(rr * Nc) + (i - 1)] = aphase_est_pilot[i];
 
             if (OFDM_BPS == 1) {
                 rx_bits[bit_index++] = crealf(rx_corr) > 0.0f;
@@ -782,21 +958,30 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
 
     /* Adjust nin to take care of sample clock offset */
 
-    ofdm->nin = OFDM_SAMPLESPERFRAME;
+    ofdm->nin = SampsPerFrame;
 
     if (ofdm->timing_en == true) {
-        int thresh = (OFDM_M + OFDM_NCP) / 8;
-        int tshift = (OFDM_M + OFDM_NCP) / 4;
+        int thresh = (M + Ncp) / 8;
+        int tshift = (M + Ncp) / 4;
 
         if (ofdm->timing_est > thresh) {
-            ofdm->nin = OFDM_SAMPLESPERFRAME + tshift;
+            ofdm->nin = SampsPerFrame + tshift;
             ofdm->timing_est -= tshift;
             ofdm->sample_point -= tshift;
         } else if (ofdm->timing_est < -thresh) {
-            ofdm->nin = OFDM_SAMPLESPERFRAME - tshift;
+            ofdm->nin = SampsPerFrame - tshift;
             ofdm->timing_est += tshift;
             ofdm->sample_point += tshift;
         }
     }
+
+    int timing_est_log = ofdm->timing_est + 1;
+    int sample_point_log = ofdm->sample_point + 1;
+
+    modem_probe_samp_f("foff_hz_log_c",&(ofdm->foff_est_hz),1);
+    modem_probe_samp_i("timing_est_log_c",&timing_est_log,1);
+    modem_probe_samp_i("sample_point_log_c",&sample_point_log,1);
+    modem_probe_samp_cft("rxbuf_log_c",ofdm->rxbuf,ofdm->config.RxBufSize);
+    modem_probe_samp_cft("rx_np_log_c",&rx_np[0],RowsPerFrame * Nc);
 }
 
index 1a1c576f2f8548453cf5ccf014cd3d636917daf7..8ea4fc90f95e947d4d1a5734c4ba6a69dcc3cc4f 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
 
 #include <complex.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 #include "codec2_ofdm.h"
 
@@ -43,13 +44,13 @@ extern "C" {
 
 #define TAU         (2.0f * M_PI)            /* mathematical constant */
 
-#define OFDM_NC     16                       /* N Carriers */
+#define OFDM_NCX     16                       /* N Carriers */
 #define OFDM_TS     0.018f                   /* Symbol time */
 #define OFDM_RS     (1.0f / OFDM_TS)         /* Symbol rate */
 #define OFDM_FS     8000.0f                  /* Sample rate */
 #define OFDM_BPS    2                        /* Bits per symbol */
 #define OFDM_TCP    0.002f                   /* ? */
-#define OFDM_NS     8                        /*  */
+#define OFDM_NS     8                        /* Symbols per frame (number of rows incl pilot) */
 #define OFDM_CENTRE 1500.0f                  /* Center frequency */
 
 /* To prevent C99 warning */
@@ -67,9 +68,9 @@ extern "C" {
 /* ? */
 #define OFDM_FTWINDOWWIDTH       11
 /* Bits per frame (duh) */
-#define OFDM_BITSPERFRAME        ((OFDM_NS - 1) * (OFDM_NC * OFDM_BPS))
+#define OFDM_BITSPERFRAME        ((OFDM_NS - 1) * (OFDM_NCX * OFDM_BPS))
 /* Rows per frame */
-#define OFDM_ROWSPERFRAME        (OFDM_BITSPERFRAME / (OFDM_NC * OFDM_BPS))
+#define OFDM_ROWSPERFRAME        (OFDM_BITSPERFRAME / (OFDM_NCX * OFDM_BPS))
 /* Samps per frame */
 #define OFDM_SAMPLESPERFRAME     (OFDM_NS * (OFDM_M + OFDM_NCP))
 
@@ -79,10 +80,24 @@ extern "C" {
 
 /* Dummy struct for now, will contain constant configuration for OFDM modem */
 struct OFDM_CONFIG{
-  int a;
+    int32_t            Nc;
+    int32_t            Ts;
+    int32_t            Rs;
+    int32_t            Fs;
+    int32_t            bps;
+    int32_t            Tcp;
+    int32_t            Ns;
+    int32_t            Fcenter;
+    int32_t            M;
+    int32_t            Ncp;
+    int32_t            FtWindowWidth;
+    int32_t            BitsPerFrame;
+    int32_t            SampsPerFrame;
+    int32_t            SampsPerFrameMax;
+    int32_t            RxBufSize;
+    int32_t            RowsPerFrame;
 };
 
-
 struct OFDM {
     struct OFDM_CONFIG config;
     float foff_est_gain;
@@ -97,18 +112,29 @@ struct OFDM {
     bool foff_est_en;
     bool phase_est_en;
 
-    complex float pilot_samples[OFDM_M + OFDM_NCP];
-    complex float W[OFDM_NC + 2][OFDM_M];
-    complex float rxbuf[OFDM_RXBUF];
-    complex float pilots[OFDM_NC + 2];
-    float w[OFDM_NC + 2];
+    //complex float pilot_samples[OFDM_M + OFDM_NCP];
+    //complex float W[OFDM_NCX + 2][OFDM_M];
+    //complex float rxbuf[OFDM_RXBUF];
+    //complex float pilots[OFDM_NC + 2];
+    //float w[OFDM_NC + 2];
+
+    complex float ** W;
+    complex float * pilots;
+    complex float * pilot_samples;
+    complex float * rxbuf;
+    float * w;
     
+
     /* Demodulator data */
 
-    complex float rx_sym[OFDM_NS + 3][OFDM_NC + 2];
-    complex float rx_np[OFDM_ROWSPERFRAME * OFDM_NC];
-    float rx_amp[OFDM_ROWSPERFRAME * OFDM_NC];
-    float aphase_est_pilot_log[OFDM_ROWSPERFRAME * OFDM_NC];
+    //complex float rx_sym[OFDM_NS + 3][OFDM_NCX + 2];
+    //complex float rx_np[OFDM_ROWSPERFRAME * OFDM_NCX];
+    //float rx_amp[OFDM_ROWSPERFRAME * OFDM_NCX];
+    //float aphase_est_pilot_log[OFDM_ROWSPERFRAME * OFDM_NCX];
+
+    complex float ** rx_sym;
+    float * rx_amp;
+    float * aphase_est_pilot_log;
 };
 
 #ifdef __cplusplus
index 1c5719a455d77d2712aa68cbcd84fb2bed202853..e5c12be83565deccbcfe4a6a8b1d885178ccdd3a 100644 (file)
@@ -51,7 +51,8 @@ target_link_libraries(tfmfsk m)
 add_executable(tdeframer tdeframer.c)
 target_link_libraries(tdeframer m codec2)
 
-add_executable(tofdm tofdm.c ../src/ofdm.c ../src/octave.c ../src/kiss_fft.c)
+add_definitions(-DMODEMPROBE_ENABLE -DXXXXX)
+add_executable(tofdm tofdm.c ../src/ofdm.c ../src/octave.c ../src/kiss_fft.c ../src/modem_probe.c)
 target_link_libraries(tofdm m)
 
 add_executable(tfreedv_data_channel tfreedv_data_channel.c)
index 2ffff9a2a04d719ffaee78038917acec7c98c408..21e52ae23b806e13a4b1f339f451e25aecfa7108 100644 (file)
 #include <math.h>
 #include <complex.h>
 
+#define MODEMPROBE_ENABLE
+
 #include "ofdm_internal.h"
 #include "codec2_ofdm.h"
 #include "octave.h"
 #include "test_bits_ofdm.h"
 #include "comp_prim.h"
+#include "modem_probe.h"
+
+#define OFDM_NC 16
 
 #define NFRAMES 30
-#define SAMPLE_CLOCK_OFFSET_PPM 100
-#define FOFF_HZ 0.5f
+//#define SAMPLE_CLOCK_OFFSET_PPM 100
+//#define FOFF_HZ 5.0f
 
 /*---------------------------------------------------------------------------*\
 
@@ -144,6 +149,10 @@ int main(int argc, char *argv[])
     FILE          *fout;
     int            f,i,j;
 
+    int sample_clock_offset_ppm = 100;
+    float foff_hz = 0.1;
+    int nframes = 30;
+
     ofdm = ofdm_create(OFDM_CONFIG_700D);
     assert(ofdm != NULL);
 
@@ -170,11 +179,11 @@ int main(int argc, char *argv[])
                                Channel
     \*---------------------------------------------------------*/
 
-    fs_offset(rx_log, tx_log, samples_per_frame*NFRAMES, SAMPLE_CLOCK_OFFSET_PPM);
+    fs_offset(rx_log, tx_log, samples_per_frame*NFRAMES, sample_clock_offset_ppm);
 
     COMP foff_phase_rect = {1.0f, 0.0f};
 
-    freq_shift(rx_log, rx_log, FOFF_HZ, &foff_phase_rect, samples_per_frame * NFRAMES);
+    freq_shift(rx_log, rx_log, foff_hz, &foff_phase_rect, samples_per_frame * NFRAMES);
 
     /* --------------------------------------------------------*\
                                Demod
@@ -195,6 +204,8 @@ int main(int argc, char *argv[])
 
     int nin_tot = 0;
 
+    modem_probe_init("ofdm","ofdm_test.txt");
+
     /* disable estimators for initial testing */
 
     ofdm_set_verbose(ofdm, true);
@@ -237,13 +248,15 @@ int main(int argc, char *argv[])
         /* rx vector logging -----------------------------------*/
 
         assert(nin_tot < samples_per_frame*NFRAMES);
-       memcpy(&rxbuf_in_log[nin_tot], rxbuf_in, sizeof(COMP)*nin);
+           //memcpy(&rxbuf_in_log[nin_tot], rxbuf_in, sizeof(COMP)*nin);
+        modem_probe_samp_cft("rxbuf_in_log_c",rxbuf_in,nin);
+
         nin_tot += nin;
 
-        for(i=0; i<OFDM_RXBUF; i++) {
+        /*for(i=0; i<OFDM_RXBUF; i++) {
             rxbuf_log[OFDM_RXBUF*f+i].real = crealf(ofdm->rxbuf[i]);
             rxbuf_log[OFDM_RXBUF*f+i].imag = cimagf(ofdm->rxbuf[i]);
-       }
+       }*/
 
         for (i = 0; i < (OFDM_NS + 3); i++) {
             for (j = 0; j < (OFDM_NC + 2); j++) {
@@ -254,10 +267,10 @@ int main(int argc, char *argv[])
 
         /* note corrected phase (rx no phase) is one big linear array for frame */
 
-        for (i = 0; i < OFDM_ROWSPERFRAME*OFDM_NC; i++) {
+        /*for (i = 0; i < OFDM_ROWSPERFRAME*OFDM_NC; i++) {
             rx_np_log[OFDM_ROWSPERFRAME*OFDM_NC*f + i].real = crealf(ofdm->rx_np[i]);
             rx_np_log[OFDM_ROWSPERFRAME*OFDM_NC*f + i].imag = cimagf(ofdm->rx_np[i]);
-        }
+        }*/
 
         /* note phase/amp ests the same for each col, but check them all anyway */
 
@@ -268,11 +281,12 @@ int main(int argc, char *argv[])
             }
         }
 
-        foff_hz_log[f] = ofdm->foff_est_hz;
-        timing_est_log[f] = ofdm->timing_est + 1;      /* offset by 1 to match Octave */
-        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));
+        //foff_hz_log[f] = ofdm->foff_est_hz;
+        //timing_est_log[f] = ofdm->timing_est + 1;      /* offset by 1 to match Octave */
+        //sample_point_log[f] = ofdm->sample_point + 1; /* offset by 1 to match Octave */
+     
+        modem_probe_samp_i("rx_bits_log_c",rx_bits,OFDM_BITSPERFRAME);
+        //memcpy(&rx_bits_log[OFDM_BITSPERFRAME*f], rx_bits, sizeof(rx_bits));
     }
 
     /*---------------------------------------------------------*\
@@ -280,6 +294,9 @@ int main(int argc, char *argv[])
                       by tofdm.m Octave script
     \*---------------------------------------------------------*/
 
+    modem_probe_close();
+
+
     fout = fopen("tofdm_out.txt","wt");
     assert(fout != NULL);
     fprintf(fout, "# Created by tofdm.c\n");
@@ -287,16 +304,16 @@ int main(int argc, char *argv[])
     octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, OFDM_BITSPERFRAME*NFRAMES);
     octave_save_complex(fout, "tx_log_c", (COMP*)tx_log, 1, samples_per_frame*NFRAMES,  samples_per_frame*NFRAMES);
     octave_save_complex(fout, "rx_log_c", (COMP*)rx_log, 1, samples_per_frame*NFRAMES,  samples_per_frame*NFRAMES);
-    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, "rxbuf_in_log_c", (COMP*)rxbuf_in_log, 1, nin_tot, nin_tot);
+    //octave_save_complex(fout, "rxbuf_log_c_x", (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, "timing_est_log_c", timing_est_log, NFRAMES, 1);
-    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, "foff_hz_log_c", foff_hz_log, NFRAMES, 1, 1);
+    //octave_save_int(fout, "timing_est_log_c", timing_est_log, NFRAMES, 1);
+    //ctave_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_cx", rx_bits_log, 1, OFDM_BITSPERFRAME*NFRAMES);
     fclose(fout);
 
     ofdm_destroy(ofdm);