Add to ofdm testing
authorokcsampson <okcsampson@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 9 Jul 2017 04:12:43 +0000 (04:12 +0000)
committerokcsampson <okcsampson@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 9 Jul 2017 04:12:43 +0000 (04:12 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3285 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/autotest.m
codec2-dev/octave/ofdm_lib.m
codec2-dev/octave/tofdm.m
codec2-dev/unittest/tofdm.c

index 05ff935c711fa3b798042752639008029fbd432e..7a83184bd3d9d5f0cec812b13d474b02c87db3ae 100644 (file)
@@ -81,4 +81,34 @@ function check(a, b, test_name, tol, its_an_angle = 0)
   end
 endfunction
 
+function check_no_abs(a, b, test_name)
+  global passes;
+  global fails;
+
+  tol = 1E-3;
+
+  [m n] = size(a);
+  if m > n
+    ll = m;
+  else
+    ll = n;
+  end
+
+  printf("%s", test_name);
+  for i=1:(25-length(test_name))
+    printf(".");
+  end
+  printf(": ");  
+  
+  e = sum(sum(a - b)/ll);
+
+  if e < tol
+    printf("OK\n");
+    passes++;
+  else
+    printf("FAIL (%f)\n",e);
+    fails++;
+  end
+endfunction
+
 
index 6d6b827dfb84d0b078a8232e0431eab38a988680..32dd02f176d736dec054294be8cfb13ba9f1b6fd 100644 (file)
@@ -31,6 +31,15 @@ function two_bits = qpsk_demod(symbol)
     two_bits = [bit1 bit0];
 endfunction
 
+function out = freq_shift(in, foff, Fs)
+  foff_rect = exp(j*2*pi*foff/Fs);
+  foff_phase_rect = exp(j*0);
+  
+  for r=1:length(in)
+    foff_phase_rect *= foff_rect;
+    out(r) = in(r)*foff_phase_rect;
+  end
+endfunction
 
 % Correlates the OFDM pilot symbol samples with a window of received
 % samples to determine the most likely timing offset.  Combines two
index f361fdd668a874c3262f858da38cd4830d9d370e..dee21c570415a43a544fd92fb876483a15d67bf5 100644 (file)
@@ -6,7 +6,7 @@
 % ------------------------------------------------------------------
 
 Nframes = 30;
-sample_clock_offset_ppm = 100;
+sample_clock_offset_ppm = 100.0;
 
 more off; format;
 ofdm_lib;
@@ -34,6 +34,7 @@ end
 % Channel simulation ----------------------------------------------
 
 rx_log = sample_clock_offset(tx_log, sample_clock_offset_ppm);
+rx_log = freq_shift(rx_log, .01f, Fs);
 
 % Rx ---------------------------------------------------------------
 
@@ -64,7 +65,7 @@ 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);
@@ -98,7 +99,7 @@ end
 % 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";
+   path_to_tofdm = "/home/ssampson/testing/tofdm";
 end
 system(path_to_tofdm);
 
@@ -141,7 +142,7 @@ stem_sig_and_error(fg++, 111, rx_bits_log_c, rx_bits_log - rx_bits_log_c, 'rx bi
 
 % Run through checklist -----------------------------
 
-check(W, W_c, 'W');
+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');
index a3fe618cb25b2a8f3b6cb993c3d1f78f98958068..b339998ec70dd18176dd54de328efc31301d3c7e 100644 (file)
 #include "codec2_ofdm.h"
 #include "octave.h"
 #include "test_bits_ofdm.h"
+#include "comp_prim.h"
 
 #define NFRAMES 30
 #define SAMPLE_CLOCK_OFFSET_PPM 100
 
-int cohpsk_fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm);
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fs_offset()
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  Simulates small Fs offset between mod and demod.
+
+\*---------------------------------------------------------------------------*/
+
+static int fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm) {
+    float f;
+    int   t1, t2;
+
+    float tin = 0.0f;
+    int tout = 0;
+
+    while (tin < n) {
+      t1 = floorf(tin);
+      t2 = ceilf(tin);
+      f = tin - t1;
+
+      out[tout].real = (1.0f - f) * in[t1].real + f * in[t2].real;
+      out[tout].imag = (1.0f - f) * in[t1].imag + f * in[t2].imag;
+
+      tout += 1;
+      tin  += 1.0f + sample_rate_ppm / 1E6f;
+    }
+
+    return tout;
+}
+
+#ifndef ARM_MATH_CM4
+  #define SINF(a) sinf(a)
+  #define COSF(a) cosf(a)
+#else
+  #define SINF(a) arm_sin_f32(a)
+  #define COSF(a) arm_cos_f32(a)
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freq_shift()
+  AUTHOR......: David Rowe
+  DATE CREATED: 26/4/2012
+
+  Frequency shift modem signal.  The use of complex input and output allows
+  single sided frequency shifting (no images).
+
+\*---------------------------------------------------------------------------*/
+
+static void freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin) {
+    float temp = (TAU * foff / OFDM_FS);
+    COMP  foff_rect = { COSF(temp), SINF(temp) };
+    int   i;
+
+    for (i = 0; i < nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
+    }
+
+    /* normalise digital oscillator as the magnitude can drift over time */
+
+    float mag = cabsolute(*foff_phase_rect);
+    foff_phase_rect->real /= mag;
+    foff_phase_rect->imag /= mag;
+}
 
 int main(int argc, char *argv[])
 {
@@ -74,7 +141,8 @@ int main(int argc, char *argv[])
     FILE          *fout;
     int            f,i,j;
 
-    ofdm = ofdm_create(); assert(ofdm != NULL);
+    ofdm = ofdm_create();
+    assert(ofdm != NULL);
 
     /* Main Loop ---------------------------------------------------------------------*/
 
@@ -99,7 +167,13 @@ int main(int argc, char *argv[])
                                Channel
     \*---------------------------------------------------------*/
 
-    cohpsk_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);
+
+    float foff = 0.01f;
+    COMP foff_phase_rect = {1.0f, 0.0f};
+
+    freq_shift(rx_log, rx_log, foff, &foff_phase_rect, samples_per_frame * NFRAMES);
+
 
     /* --------------------------------------------------------*\
                                Demod
@@ -229,33 +303,3 @@ int main(int argc, char *argv[])
     return 0;
 }
 
-/*---------------------------------------------------------------------------*\
-
-  FUNCTION....: cohpsk_fs_offset()
-  AUTHOR......: David Rowe
-  DATE CREATED: May 2015
-
-  Simulates small Fs offset between mod and demod.
-
-\*---------------------------------------------------------------------------*/
-
-int cohpsk_fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm)
-{
-    double tin, f;
-    int   tout, t1, t2;
-
-    tin = 0.0; tout = 0;
-    while (tin < n) {
-      t1 = floor(tin);
-      t2 = ceil(tin);
-      f = tin - t1;
-      out[tout].real = (1.0-f)*in[t1].real + f*in[t2].real;
-      out[tout].imag = (1.0-f)*in[t1].imag + f*in[t2].imag;
-      tout += 1;
-      tin  += 1.0 + sample_rate_ppm/1E6;
-      //printf("tin: %f tout: %d f: %f\n", tin, tout, f);
-    }
-
-    return tout;
-}
-