commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r7583 - gnuradio/branches/developers/trondeau/ofdmfix/


From: trondeau
Subject: [Commit-gnuradio] r7583 - gnuradio/branches/developers/trondeau/ofdmfix/gnuradio-core/src/lib/general
Date: Wed, 6 Feb 2008 07:55:37 -0700 (MST)

Author: trondeau
Date: 2008-02-06 07:55:37 -0700 (Wed, 06 Feb 2008)
New Revision: 7583

Modified:
   
gnuradio/branches/developers/trondeau/ofdmfix/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
Log:
Take it from me, kids, never prematurely optimize. Reverting back to 
correlating to not only find frequency offset but also to find when preamble is 
received. This is already taken care of by the ofdm synchronizer, but we need a 
(good) way of telling this block, and my old way was not it.

Modified: 
gnuradio/branches/developers/trondeau/ofdmfix/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
===================================================================
--- 
gnuradio/branches/developers/trondeau/ofdmfix/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
    2008-02-06 14:18:36 UTC (rev 7582)
+++ 
gnuradio/branches/developers/trondeau/ofdmfix/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
    2008-02-06 14:55:37 UTC (rev 7583)
@@ -48,7 +48,7 @@
                                                      const 
std::vector<gr_complex> &known_symbol,
                                                      unsigned int 
max_fft_shift_len)
   : gr_block ("ofdm_frame_acquisition",
-             gr_make_io_signature2 (2, 2, sizeof(gr_complex)*fft_length, 
sizeof(char)),
+             gr_make_io_signature  (1, 1, sizeof(gr_complex)*fft_length),
              gr_make_io_signature2 (2, 2, 
sizeof(gr_complex)*occupied_carriers, sizeof(char))),
     d_occupied_carriers(occupied_carriers),
     d_fft_length(fft_length),
@@ -101,44 +101,64 @@
   //return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + 
symbol_count];
 }
 
-
-
 bool
 gr_ofdm_frame_acquisition::correlate(const gr_complex *symbol, int 
zeros_on_left)
 {
-  unsigned int i = 0, j = 0;
+  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;
 
   std::fill(d_symbol_phase_diff.begin(), d_symbol_phase_diff.end(), 0);
   for(i = 0; i < d_fft_length-2; i++) {
     d_symbol_phase_diff[i] = fabs(gr_fast_atan2f(symbol[i]) - 
gr_fast_atan2f(symbol[i+2]));
   }
 
-  int index = 0;
-  float max = 0, sum=0;
-  for(i =  zeros_on_left - d_freq_shift_len; i < zeros_on_left + 
d_freq_shift_len; i+=2) {
-    sum = 0;
-    for(j = 0; j < d_occupied_carriers; j++) {
-      sum += (d_known_phase_diff[j] * d_symbol_phase_diff[i+j]);
+  
+  while(!found && ((unsigned)abs(search_delta) <= d_freq_shift_len)) {
+    h_sqrd = gr_complex(0.0,0.0);
+    power = 0.0F;
+    
+    //FIXME: power calculation doesn't really make sense 
+    for(i = 0; i < d_occupied_carriers; i++) {
+      h_sqrd += (d_known_phase_diff[i] * 
d_symbol_phase_diff[i+zeros_on_left+search_delta]);
+      power += d_known_phase_diff[i]*d_known_phase_diff[i];
     }
-    if(fabs(sum) > max) {
-      max = sum;
-      index = i;
+    
+    if(VERBOSE) {
+      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));
     }
-  }
 
-  d_coarse_freq = index - zeros_on_left;
+    //FIXME: these threshold values are arbitrary, although the decision 
metric is very good
+    // even at very low SNR
+    if((h_sqrd.real() > 0.95*power) && (h_sqrd.real() < 1.1*power)) {
+      found = true;
+      d_coarse_freq = search_delta;
+      d_phase_count = 1;
+     
+      //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));
 
-  if(VERBOSE) {
-    fprintf(stderr, "Coarse Freq Offset: %d\n", d_coarse_freq);
-    for(i = 0; i < 40; i++) {
-      fprintf(stderr, "%+.4f   %+.4f\n", d_known_phase_diff[i], 
-             d_symbol_phase_diff[zeros_on_left+d_coarse_freq+i]);
+      if(VERBOSE) {
+       printf("CORR: Found, bin %d\tdB\tcorr power fraction %f\n",
+              search_delta, h_sqrd.real()/power);
+      }
+      break;
     }
+    else {
+      if(search_delta <= 0)
+       search_delta = (-search_delta) + 2;
+      else
+       search_delta = -search_delta;
+    }
   }
-
-  return true;  //FIXME: don't need ot return anything now
+  return found;
 }
 
+
 void
 gr_ofdm_frame_acquisition::calculate_equalizer(const gr_complex *symbol, int 
zeros_on_left)
 {
@@ -184,7 +204,6 @@
                                        gr_vector_void_star &output_items)
 {
   const gr_complex *symbol = (const gr_complex *)input_items[0];
-  const char *trigger = (const char *)input_items[1];
 
   gr_complex *out = (gr_complex *) output_items[0];
   char *sig = (char *) output_items[1];
@@ -193,19 +212,15 @@
   int zeros_on_left = (int)ceil(unoccupied_carriers/2.0);
 
   int found = 0;
-  for(int i = 0; i < ninput_items[1]; i++) {
-    found += trigger[i];
-  }
-
+  found = correlate(symbol, zeros_on_left);
   if(found) {
     d_phase_count = 1;
-    correlate(symbol, zeros_on_left);
     calculate_equalizer(symbol, zeros_on_left);
     sig[0] = 1;
   }
   else {
     sig[0] = 0;
-  }
+  } 
 
   for(unsigned int i = 0; i < d_occupied_carriers; i++) {
     out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)
@@ -217,7 +232,6 @@
     d_phase_count = 1;
   }
 
-  consume(0,1);
-  consume(1,ninput_items[1]);
+  consume_each(1);
   return 1;
 }





reply via email to

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