commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r4610 - gnuradio/branches/developers/n4hy/ofdm/gnuradi


From: trondeau
Subject: [Commit-gnuradio] r4610 - gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general
Date: Fri, 23 Feb 2007 09:53:50 -0700 (MST)

Author: trondeau
Date: 2007-02-23 09:53:49 -0700 (Fri, 23 Feb 2007)
New Revision: 4610

Modified:
   
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
   
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
   
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
Log:
bug fixes and improvements to ofdm correlator

Modified: 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
===================================================================
--- 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
  2007-02-23 09:37:54 UTC (rev 4609)
+++ 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
  2007-02-23 16:53:49 UTC (rev 4610)
@@ -28,17 +28,20 @@
 #include <gr_io_signature.h>
 
 #define VERBOSE   1
+#define M_TWOPI (2*M_PI)
 
 gr_ofdm_correlator_sptr
-gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen, 
+                        unsigned int cplen,
                         std::vector<gr_complex> known_symbol1, 
                         std::vector<gr_complex> known_symbol2)
 {
-  return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, 
vlen,
+  return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, 
vlen, cplen,
                                                          known_symbol1, 
known_symbol2));
 }
 
-gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned 
int vlen,
+gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned 
int vlen, 
+                                       unsigned int cplen,
                                        std::vector<gr_complex> known_symbol1, 
                                        std::vector<gr_complex> known_symbol2)
   : gr_block ("ofdm_correlator",
@@ -46,8 +49,12 @@
              gr_make_io_signature (1, 1, 
sizeof(gr_complex)*occupied_carriers)),
     d_occupied_carriers(occupied_carriers),
     d_vlen(vlen),
+    d_cplen(cplen),
+    d_freq_shift_len(5),
     d_known_symbol1(known_symbol1),
-    d_known_symbol2(known_symbol2)
+    d_known_symbol2(known_symbol2),
+    d_coarse_freq(0),
+    d_phase_count(0)
 {
   d_diff_corr_factor.resize(d_occupied_carriers);
   d_hestimate.resize(d_occupied_carriers);
@@ -74,28 +81,54 @@
     ninput_items_required[i] = 2;
 }
 
+gr_complex
+gr_ofdm_correlator::coarse_freq_comp(int freq_delta, int symbol_count)
+{
+  return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count),
+                   sin(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count));
+}
+
 bool
 gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex 
*current, 
                              int zeros_on_left)
 {
   unsigned int i = 0;
+  int search_delta = 0;
   bool found = false;
 
   gr_complex h_sqrd = gr_complex(0.0,0.0);
   float power = 0.0F;
 
-  for(i = 0; i < d_occupied_carriers; i++) {
-    h_sqrd = h_sqrd + previous[i+zeros_on_left] * 
conj(current[i+zeros_on_left]) * d_diff_corr_factor[i];
-    power = power + norm(current[i+zeros_on_left]);
-  }
+  while(!found && (abs(search_delta) < d_freq_shift_len)) {
+    h_sqrd = gr_complex(0.0,0.0);
+    power = 0.0F;
 
-  if(h_sqrd.real() > 0.75*power) {
-    found = true;
-  }
+    for(i = 0; i < d_occupied_carriers; i++) {
+      h_sqrd = h_sqrd + previous[i+zeros_on_left+search_delta] * 
+       
conj(coarse_freq_comp(search_delta,1)*current[i+zeros_on_left+search_delta]) * 
+       d_diff_corr_factor[i];
+      power = power + norm(current[i+zeros_on_left+search_delta]); // No need 
to do coarse freq here
+    }
+    
 #if VERBOSE
-  printf("h_sqrd = ( %f, %f )\t power = %f\t real(h)/p = %f\t angle = %f\n", 
-        h_sqrd.real(), h_sqrd.imag(), power, h_sqrd.real()/power, 
arg(h_sqrd)); 
+      printf("bin %d\th_sqrd = ( %f, %f )\t power = %f\t real(h)/p = %f\t 
angle = %f\n", 
+            search_delta, h_sqrd.real(), h_sqrd.imag(), power, 
h_sqrd.real()/power, arg(h_sqrd)); 
 #endif
+
+    if(h_sqrd.real() > 0.75*power) {
+      found = true;
+      d_coarse_freq = search_delta;
+      d_phase_count = 1;
+      printf("found at search delta: %d\n", search_delta);
+      break;
+    }
+    else {
+      if(search_delta <= 0)
+       search_delta = (-search_delta) + 1;
+      else
+       search_delta = -search_delta;
+    }
+  }
   return found;
 }
 
@@ -108,7 +141,7 @@
   for(i = 0; i < d_occupied_carriers; i++) {
     // FIXME possibly add small epsilon in divisor to protect from div 0
     //hesttemp = d_known_symbol1[i] / previous[i+zeros_on_left];
-    hesttemp = d_known_symbol2[i] / current[i+zeros_on_left];
+    hesttemp = d_known_symbol2[i] / 
(coarse_freq_comp(d_coarse_freq,1)*current[i+zeros_on_left+d_coarse_freq]);
     
     d_hestimate[i] = hesttemp;
 
@@ -144,9 +177,9 @@
   }
 
   for(i = 0; i < d_occupied_carriers; i++) {
-    out[i] = d_hestimate[i]*current[i+zeros_on_left];
+    out[i] = 
d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)*current[i+zeros_on_left+d_coarse_freq];
   }
-  
+  d_phase_count++;
   consume_each(1);
   return 1;
 }

Modified: 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
===================================================================
--- 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
   2007-02-23 09:37:54 UTC (rev 4609)
+++ 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
   2007-02-23 16:53:49 UTC (rev 4610)
@@ -32,23 +32,49 @@
 
 gr_ofdm_correlator_sptr 
 gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+                        unsigned int cplen,
                         std::vector<gr_complex> known_symbol1, 
                         std::vector<gr_complex> known_symbol2);
 
 /*!
  * \brief take a vector of complex constellation points in from an FFT
- * and demodulate to a stream of bits. Simple BPSK version.
+ * and performs a correlation and equalization.
+ * \inblock blocks
+ *
+ * This block takes the output of an FFT of a received OFDM symbol and finds 
the 
+ * start of a frame based on two known symbols. It also looks at the 
surrounding
+ * bins in the FFT output for the correlation in case there is a large 
frequency
+ * shift in the data. This block assumes that the fine frequency shift has 
already
+ * been corrected and that the samples fall in the middle of one FFT bin.
+ *
+ * It then uses one of those known
+ * symbosl to estimate the channel response overa all subcarriers and does a 
simple 
+ * 1-tap equalization on all subcarriers. This corrects for the phase and 
amplitude
+ * distortion caused by the channel.
  */
 
 class gr_ofdm_correlator : public gr_block
 {
+  /*! 
+   * \brief Build an OFDM correlator and equalizer.
+   * \param occupied_carriers   The number of subcarriers with data in the 
received symbol
+   * \param vlen                The size of the FFT vector (occupied_carriers 
+ unused carriers)
+   * \param known_symbol1       A vector of complex numbers representing a 
known symbol at the
+   *                            start of a frame (usually a BPSK PN sequence)
+   * \param known_symbol2       A vector of complex numbers representing a 
known symbol at the
+   *                            start of a frame after known_symbol1 (usually 
a BPSK PN sequence). 
+   *                            Both of these start symbols are differentially 
correlated to compensate
+   *                            for phase changes between symbols. 
+   */
   friend gr_ofdm_correlator_sptr
-    gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
-                            std::vector<gr_complex> known_symbol1, 
-                            std::vector<gr_complex> known_symbol2);
+  gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+                          unsigned int cplen,
+                          std::vector<gr_complex> known_symbol1, 
+                          std::vector<gr_complex> known_symbol2);
   
  protected:
   gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+                     unsigned int cplen,
                      std::vector<gr_complex> known_symbol1, 
                      std::vector<gr_complex> known_symbol2);
   
@@ -56,13 +82,18 @@
   unsigned char slicer(gr_complex x);
   bool correlate(const gr_complex *previous, const gr_complex *current, int 
zeros_on_left);
   void calculate_equalizer(const gr_complex *current, int zeros_on_left);
+  gr_complex coarse_freq_comp(int freq_delta, int count);
+  
+  unsigned int d_occupied_carriers;  // !< \brief number of subcarriers with 
data
+  unsigned int d_vlen;               // !< \brief length of FFT vector
+  unsigned int d_cplen;              // !< \brief length of cyclic prefix in 
samples
+  unsigned int d_freq_shift_len;     // !< \brief number of surrounding bins 
to look at for correlation
+  std::vector<gr_complex> d_known_symbol1, d_known_symbol2; // !< \brief known 
symbols at start of frame
+  std::vector<gr_complex> d_diff_corr_factor; // !< \brief factor used in 
correlation
+  std::vector<gr_complex> d_hestimate; // !< channel estimate
+  signed int d_coarse_freq; // !< \brief search distance in number of bins
+  unsigned int d_phase_count;        // !< \brief accumulator for coarse freq 
correction
 
-  unsigned int d_occupied_carriers;
-  unsigned int d_vlen;
-  std::vector<gr_complex> d_known_symbol1, d_known_symbol2;
-  std::vector<gr_complex> d_diff_corr_factor;
-  std::vector<gr_complex> d_hestimate;
-
   void forecast(int noutput_items, gr_vector_int &ninput_items_required);
 
  public:

Modified: 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
===================================================================
--- 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
   2007-02-23 09:37:54 UTC (rev 4609)
+++ 
gnuradio/branches/developers/n4hy/ofdm/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
   2007-02-23 16:53:49 UTC (rev 4610)
@@ -27,6 +27,7 @@
 gr_ofdm_correlator_sptr 
 gr_make_ofdm_correlator (unsigned int occupied_carriers, 
                         unsigned int vlen,
+                        unsigned int cplen,
                         std::vector<gr_complex> known_symbol1, 
                         std::vector<gr_complex> known_symbol2);
 
@@ -35,6 +36,7 @@
  protected:
   gr_ofdm_correlator (unsigned int occupied_carriers,
                      unsigned int vlen,
+                     unsigned int cplen,
                      std::vector<gr_complex> known_symbol1, 
                      std::vector<gr_complex> known_symbol2);
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]