Changeset 9750

Show
Ignore:
Timestamp:
10/08/08 13:28:59
Author:
jamieson
Message:

Changes with Mythili Vutukuru and help of John Corgan to integrate
with the existing codebase.

This code has not been tested or built yet.

Based on authors' repository at internal svn revision r2712.
Reconciled with GNU Radio trunk r7324 by removing backported files.

Changes to the GNU Radio OFDM implementation by Matt Ettus, Tom
Rondeau, and Bob McGwier?, adding the following features: robust packet
detection, convolutional coding and decoding (using Achilleas
Anastasopoulos' gr-trellis code and modifications of same)
interleaving/deinterleaving, different modulation/coding rates on
header vs packet body, synchronization (frequency offset correction
and symbol timing correction) improvements, and improvements to the
peak detection algorithm. Also added packet framing code.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gnuradio/branches/features/coded-ofdm/Makefile.common

    r6321 r9750  
    6161                    -I$(top_srcdir)/gnuradio-core/src/lib/swig \ 
    6262                    -I$(top_builddir)/gnuradio-core/src/lib/swig \ 
     63                                -I$(top_srcdir)/gr-trellis/src/lib \ 
     64                                -I$(top_builddir)/gr-trellis/src/lib \ 
    6365                    $(FFTW3F_CFLAGS) 
    6466 
  • gnuradio/branches/features/coded-ofdm/gnuradio-core/src/lib/general/Makefile.am

    r7324 r9750  
    5050        gr_clock_recovery_mm_ff.cc      \ 
    5151        gr_complex_to_interleaved_short.cc \ 
     52        gr_complex_to_interleaved_float.cc \ 
    5253        gr_complex_to_xxx.cc            \ 
    5354        gr_conjugate_cc.cc              \ 
     
    9798        gr_null_sink.cc                 \ 
    9899        gr_null_source.cc               \ 
    99         gr_ofdm_frame_acquisition.cc    \ 
     100        gr_ofdm_frame_acquisition.cc            \ 
     101        gr_ofdm_detector.cc \ 
     102        gr_coded_ofdm_demod.cc \ 
     103        gr_coded_ofdm_demod2softin.cc \ 
     104        gr_ofdm_interleaver.cc \ 
     105        gr_ofdm_deinterleaver.cc \ 
     106        gr_ofdm_header_decode_vbb.cc \ 
    100107        gr_ofdm_cyclic_prefixer.cc      \ 
    101108        gr_ofdm_demapper_vcb.cc         \ 
     
    106113        gr_ofdm_qam_mapper.cc           \ 
    107114        gr_ofdm_frame_sink.cc           \ 
     115        gr_coded_ofdm_frame_sink.cc             \ 
    108116        gr_ofdm_insert_preamble.cc      \ 
    109117        gr_ofdm_sampler.cc              \ 
    110118        gr_pa_2x2_phase_combiner.cc     \ 
    111119        gr_packet_sink.cc               \ 
    112         gr_peak_detector2_fb.cc               
     120        gr_peak_detector2_fb.cc
    113121        gr_phase_modulator_fc.cc        \ 
    114122        gr_pll_carriertracking_cc.cc    \ 
     
    132140        gr_rms_ff.cc                    \ 
    133141        gr_short_to_float.cc            \ 
     142        gr_short_to_char.cc             \ 
    134143        gr_simple_correlator.cc         \ 
    135144        gr_simple_framer.cc             \ 
     
    170179        qa_gr_fxpt.cc                   \ 
    171180        qa_gr_fxpt_nco.cc               \ 
    172         qa_gr_fxpt_vco.cc                
     181        qa_gr_fxpt_vco.cc               \ 
     182        qa_gr_math.cc 
     183 
    173184 
    174185 
     
    190201        gr_clock_recovery_mm_ff.h       \ 
    191202        gr_complex_to_interleaved_short.h \ 
     203        gr_complex_to_interleaved_float.h \ 
    192204        gr_complex_to_xxx.h             \ 
    193205        gr_conjugate_cc.h               \ 
     
    241253        gr_null_sink.h                  \ 
    242254        gr_null_source.h                \ 
    243         gr_ofdm_frame_acquisition.h     \ 
     255        gr_ofdm_frame_acquisition.h             \ 
     256        gr_ofdm_constants.h \ 
     257        gr_ofdm_struct_dot11a.h \ 
     258        gr_ofdm_detector.h              \ 
     259        gr_coded_ofdm_demod.h           \ 
     260        gr_coded_ofdm_demod2softin.h           \ 
     261        gr_ofdm_interleaver.h \ 
     262        gr_ofdm_deinterleaver.h \ 
     263        gr_ofdm_header_decode_vbb.h \ 
    244264        gr_ofdm_cyclic_prefixer.h       \ 
    245265        gr_ofdm_demapper_vcb.h          \ 
     
    250270        gr_ofdm_bpsk_demapper.h         \ 
    251271        gr_ofdm_frame_sink.h            \ 
     272        gr_coded_ofdm_frame_sink.h              \ 
    252273        gr_ofdm_insert_preamble.h       \ 
    253274        gr_ofdm_sampler.h               \ 
    254275        gr_pa_2x2_phase_combiner.h      \ 
    255276        gr_packet_sink.h                \ 
    256         gr_peak_detector2_fb.h         
     277        gr_peak_detector2_fb.h
    257278        gr_phase_modulator_fc.h         \ 
    258279        gr_pll_carriertracking_cc.h     \ 
     
    276297        gr_rms_ff.h                     \ 
    277298        gr_short_to_float.h             \ 
     299        gr_short_to_char.h              \ 
    278300        gr_simple_correlator.h          \ 
    279301        gr_simple_framer.h              \ 
     
    326348        qa_gr_fxpt_nco.h                \ 
    327349        qa_gr_fxpt_vco.h                \ 
    328         sine_table.h                     
     350        sine_table.h                      \ 
     351        qa_gr_math.h 
    329352 
    330353swiginclude_HEADERS =                   \ 
     
    344367        gr_clock_recovery_mm_ff.i       \ 
    345368        gr_complex_to_interleaved_short.i \ 
     369        gr_complex_to_interleaved_float.i \ 
    346370        gr_complex_to_xxx.i             \ 
    347371        gr_conjugate_cc.i               \ 
     
    386410        gr_null_sink.i                  \ 
    387411        gr_null_source.i                \ 
    388         gr_ofdm_frame_acquisition.i     \ 
     412        gr_ofdm_frame_acquisition.i             \ 
     413        gr_ofdm_constants.i \ 
     414        gr_ofdm_detector.i              \ 
     415        gr_coded_ofdm_demod.i           \ 
     416        gr_coded_ofdm_demod2softin.i \ 
     417        gr_ofdm_interleaver.i \ 
     418        gr_ofdm_deinterleaver.i \ 
     419        gr_ofdm_header_decode_vbb.i \ 
    389420        gr_ofdm_cyclic_prefixer.i       \ 
    390421        gr_ofdm_demapper_vcb.i          \ 
     
    395426        gr_ofdm_qam_mapper.i            \ 
    396427        gr_ofdm_frame_sink.i            \ 
     428        gr_coded_ofdm_frame_sink.i              \ 
    397429        gr_ofdm_insert_preamble.i       \ 
    398430        gr_ofdm_sampler.i               \ 
    399431        gr_pa_2x2_phase_combiner.i      \ 
    400432        gr_packet_sink.i                \ 
    401         gr_peak_detector2_fb.i         
     433        gr_peak_detector2_fb.i
    402434        gr_phase_modulator_fc.i         \ 
    403435        gr_pll_carriertracking_cc.i     \ 
     
    419451        gr_rms_ff.i                     \ 
    420452        gr_short_to_float.i             \ 
     453        gr_short_to_char.i              \ 
    421454        gr_simple_correlator.i          \ 
    422455        gr_simple_framer.i              \ 
  • gnuradio/branches/features/coded-ofdm/gnuradio-core/src/lib/general/general.i

    r7324 r9750  
    4343#include <gr_float_to_uchar.h> 
    4444#include <gr_short_to_float.h> 
     45#include <gr_short_to_char.h> 
    4546#include <gr_char_to_float.h> 
    4647#include <gr_uchar_to_float.h> 
     
    5354#include <gr_complex_to_xxx.h> 
    5455#include <gr_complex_to_interleaved_short.h> 
     56#include <gr_complex_to_interleaved_float.h> 
    5557#include <gr_interleaved_short_to_complex.h> 
    5658#include <gr_endianness.h> 
     
    102104#include <gr_ofdm_qam_mapper.h> 
    103105#include <gr_ofdm_frame_sink.h> 
     106#include <gr_coded_ofdm_frame_sink.h> 
    104107#include <gr_ofdm_insert_preamble.h> 
    105108#include <gr_ofdm_sampler.h> 
     109#include <gr_ofdm_detector.h> 
     110#include <gr_coded_ofdm_demod.h> 
     111#include <gr_coded_ofdm_demod2softin.h> 
     112#include <gr_ofdm_interleaver.h> 
     113#include <gr_ofdm_deinterleaver.h> 
     114#include <gr_ofdm_constants.h> 
     115#include <gr_ofdm_header_decode_vbb.h> 
     116#include <gr_peak_detector2_fb.h> 
    106117#include <gr_regenerate_bb.h> 
    107118#include <gr_costas_loop_cc.h> 
     
    152163%include "gr_float_to_uchar.i" 
    153164%include "gr_short_to_float.i" 
     165%include "gr_short_to_char.i" 
    154166%include "gr_char_to_float.i" 
    155167%include "gr_uchar_to_float.i" 
     
    162174%include "gr_complex_to_xxx.i" 
    163175%include "gr_complex_to_interleaved_short.i" 
     176%include "gr_complex_to_interleaved_float.i" 
    164177%include "gr_endianness.i" 
    165178%include "gr_interleaved_short_to_complex.i" 
     
    211224%include "gr_ofdm_qam_mapper.i" 
    212225%include "gr_ofdm_frame_sink.i" 
     226%include "gr_coded_ofdm_frame_sink.i" 
    213227%include "gr_ofdm_insert_preamble.i" 
    214228%include "gr_ofdm_sampler.i" 
     229%include "gr_ofdm_detector.i" 
     230%include "gr_coded_ofdm_demod.i" 
     231%include "gr_coded_ofdm_demod2softin.i" 
     232%include "gr_ofdm_interleaver.i" 
     233%include "gr_ofdm_deinterleaver.i" 
     234%include "gr_ofdm_constants.i" 
     235%include "gr_ofdm_header_decode_vbb.i" 
     236%include "gr_peak_detector2_fb.i" 
    215237%include "gr_regenerate_bb.i" 
    216238%include "gr_costas_loop_cc.i" 
  • gnuradio/branches/features/coded-ofdm/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc

    r7324 r9750  
    2828#include <gr_io_signature.h> 
    2929#include <gr_expj.h> 
    30 #include <gr_math.h> 
    31  
    32 #define VERBOSE 0 
     30 
     31#define VERBOSE 1 
    3332#define M_TWOPI (2*M_PI) 
    3433#define MAX_NUM_SYMBOLS 1000 
     
    3736gr_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int fft_length,  
    3837                                unsigned int cplen, 
    39                                 const std::vector<gr_complex> &known_symbol, 
     38                                const std::vector<gr_complex> &known_symbol1,  
     39                                const std::vector<gr_complex> &known_symbol2, 
    4040                                unsigned int max_fft_shift_len) 
    4141{ 
    4242  return gr_ofdm_frame_acquisition_sptr (new gr_ofdm_frame_acquisition (occupied_carriers, fft_length, cplen, 
    43                                                                         known_symbol, max_fft_shift_len)); 
     43                                                                        known_symbol1, known_symbol2, 
     44                                                                        max_fft_shift_len)); 
    4445} 
    4546 
    4647gr_ofdm_frame_acquisition::gr_ofdm_frame_acquisition (unsigned occupied_carriers, unsigned int fft_length,  
    4748                                                      unsigned int cplen, 
    48                                                       const std::vector<gr_complex> &known_symbol, 
     49                                                      const std::vector<gr_complex> &known_symbol1,  
     50                                                      const std::vector<gr_complex> &known_symbol2, 
    4951                                                      unsigned int max_fft_shift_len) 
    5052  : gr_block ("ofdm_frame_acquisition", 
    5153              gr_make_io_signature2 (2, 2, sizeof(gr_complex)*fft_length, sizeof(char)), 
    52               gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char))), 
     54              gr_make_io_signature4 (3, 4, sizeof(gr_complex)*occupied_carriers,  
     55                               sizeof(char), sizeof(float), 
     56                               sizeof(gr_complex)*occupied_carriers)), 
    5357    d_occupied_carriers(occupied_carriers), 
    5458    d_fft_length(fft_length), 
    5559    d_cplen(cplen), 
    5660    d_freq_shift_len(max_fft_shift_len), 
    57     d_known_symbol(known_symbol), 
     61    d_known_symbol1(known_symbol1), 
     62    d_known_symbol2(known_symbol2), 
    5863    d_coarse_freq(0), 
    59     d_phase_count(0) 
    60 
    61   d_symbol_phase_diff.resize(d_fft_length); 
    62   d_known_phase_diff.resize(d_occupied_carriers); 
     64    d_phase_count(0), 
     65    d_max_snr_est(0) 
     66
     67  d_diff_corr_factor.resize(d_occupied_carriers); 
    6368  d_hestimate.resize(d_occupied_carriers); 
    6469 
     70  std::vector<gr_complex>::iterator i1, i2; 
     71 
    6572  unsigned int i = 0, j = 0; 
    66  
    67   std::fill(d_known_phase_diff.begin(), d_known_phase_diff.end(), 0); 
    68   for(i = 0; i < d_known_symbol.size()-2; i+=2) { 
    69     d_known_phase_diff[i] = fabs(gr_fast_atan2f(d_known_symbol[i]) - gr_fast_atan2f(d_known_symbol[i+2]))
     73  gr_complex one(1.0, 0.0); 
     74  for(i1 = d_known_symbol1.begin(), i2 = d_known_symbol2.begin(); i1 != d_known_symbol1.end(); i1++, i2++) { 
     75    d_diff_corr_factor[i] = one / ((*i1) * conj(*i2)); 
     76    i++
    7077  } 
    7178   
     
    8188{ 
    8289  delete [] d_phase_lut; 
     90  printf("gr_ofdm_frame_acquisition destructor: MAX_SNR: %f\n", d_max_snr_est); 
    8391} 
    8492 
     
    8896  unsigned ninputs = ninput_items_required.size (); 
    8997  for (unsigned i = 0; i < ninputs; i++) 
    90     ninput_items_required[i] = 1
     98    ninput_items_required[i] = 2
    9199} 
    92100 
     
    99107  return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count); 
    100108 
     109  //assert(d_freq_shift_len + freq_delta >= 0); 
     110  //assert(symbol_count <= MAX_NUM_SYMBOLS); 
     111 
    101112  //return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count]; 
    102113} 
    103114 
    104  
    105  
    106115bool 
    107 gr_ofdm_frame_acquisition::correlate(const gr_complex *symbol, int zeros_on_left) 
    108 
    109   unsigned int i = 0, j = 0; 
    110  
    111   std::fill(d_symbol_phase_diff.begin(), d_symbol_phase_diff.end(), 0); 
    112   for(i = 0; i < d_fft_length-2; i++) { 
    113     d_symbol_phase_diff[i] = fabs(gr_fast_atan2f(symbol[i]) - gr_fast_atan2f(symbol[i+2])); 
    114   } 
    115  
    116   int index = 0; 
    117   float max = 0, sum=0; 
    118   for(i =  zeros_on_left - d_freq_shift_len; i < zeros_on_left + d_freq_shift_len; i+=2) { 
    119     sum = 0; 
    120     for(j = 0; j < d_occupied_carriers; j++) { 
    121       sum += (d_known_phase_diff[j] * d_symbol_phase_diff[i+j]); 
    122     } 
    123     if(fabs(sum) > max) { 
    124       max = sum; 
    125       index = i; 
    126     } 
    127   } 
    128  
    129   d_coarse_freq = index - zeros_on_left; 
    130  
    131   if(VERBOSE) { 
    132     fprintf(stderr, "Coarse Freq Offset: %d\n", d_coarse_freq); 
    133     for(i = 0; i < 40; i++) { 
    134       fprintf(stderr, "%+.4f   %+.4f\n", d_known_phase_diff[i],  
    135               d_symbol_phase_diff[zeros_on_left+d_coarse_freq+i]); 
    136     } 
    137   } 
    138  
    139   return true;  //FIXME: don't need ot return anything now 
    140 
     116gr_ofdm_frame_acquisition::correlate(const gr_complex *previous, const gr_complex *current,  
     117                                     int zeros_on_left) 
     118
     119  unsigned int i = 0; 
     120  int search_delta = 0; 
     121  bool found = 0; 
     122 
     123  gr_complex h_sqrd = gr_complex(0.0,0.0); 
     124  float power = 0.0F; 
     125 
     126  float max_ratio = 0.0; 
     127  float max_h_real, max_h_imag; 
     128  int max_search_delta = 0; 
     129 
     130  //sweep all possible offsets 
     131  while((unsigned)abs(search_delta) <= d_freq_shift_len) { 
     132    h_sqrd = gr_complex(0.0,0.0); 
     133    power = 0.0F; 
     134 
     135    for(i = 0; i < d_occupied_carriers; i++) { 
     136      h_sqrd = h_sqrd + previous[i+zeros_on_left+search_delta] *  
     137        conj(coarse_freq_comp(search_delta,1)*current[i+zeros_on_left+search_delta]) *  
     138        d_diff_corr_factor[i]; 
     139       
     140      power = power + norm(current[i+zeros_on_left+search_delta]); // No need to do coarse freq here 
     141    } 
     142     
     143    float ratio =  h_sqrd.real()/power; 
     144 
     145#if VERBOSE > 1 
     146    printf("bin %d\th_sqrd = ( %f, %f )\t power = %f\t real(h)/p = %f\t angle = %f\n",  
     147           search_delta, h_sqrd.real(), h_sqrd.imag(), power, ratio, arg(h_sqrd));  
     148#endif       
     149 
     150    if(ratio > 0.5 && ratio < 1.5 && ratio > max_ratio) { 
     151      max_ratio = ratio; 
     152      max_h_real =  h_sqrd.real(); 
     153      max_h_imag =  h_sqrd.imag(); 
     154      max_search_delta = search_delta; 
     155 
     156    } 
     157      if(search_delta <= 0) 
     158        search_delta = (-search_delta) + 2; 
     159      else 
     160        search_delta = -search_delta; 
     161  } 
     162 
     163  if(max_ratio > 0) { 
     164      found = true; 
     165      d_coarse_freq = max_search_delta; 
     166      d_phase_count = 1; 
     167       
     168      // check for low noise power; sets maximum SNR at 100 dB 
     169      if(fabs(max_h_imag) <= 1e-12) { 
     170        d_snr_est = 100.0; 
     171      } 
     172      else { 
     173        d_snr_est = 10*log10(fabs(max_h_real/max_h_imag)); 
     174      } 
     175 
     176#if VERBOSE 
     177      printf("CORR: Found, bin %d\tSNR Est %f dB\tcorr power fraction %f\n",  
     178             max_search_delta, d_snr_est, max_ratio); 
     179#endif 
     180 
     181      if(d_snr_est > d_max_snr_est) 
     182        d_max_snr_est = d_snr_est; 
     183 
     184  } 
     185   
     186  return found; 
     187
     188 
     189#define AVERAGE_MAG 0 
     190#define AVERAGE_PHASE 0 
     191#define HEST_AV_WINDOW 3 
    141192 
    142193void 
    143 gr_ofdm_frame_acquisition::calculate_equalizer(const gr_complex *symbol, int zeros_on_left) 
    144 
    145   unsigned int i=0; 
    146  
    147   // Set first tap of equalizer 
    148   d_hestimate[0] = d_known_symbol[0] /  
    149     (coarse_freq_comp(d_coarse_freq,1)*symbol[zeros_on_left+d_coarse_freq]); 
    150  
    151   // set every even tap based on known symbol 
    152   // linearly interpolate between set carriers to set zero-filled carriers 
    153   // FIXME: is this the best way to set this? 
    154   for(i = 2; i < d_occupied_carriers; i+=2) { 
    155     d_hestimate[i] = d_known_symbol[i] /  
    156       (coarse_freq_comp(d_coarse_freq,1)*(symbol[i+zeros_on_left+d_coarse_freq])); 
    157     d_hestimate[i-1] = (d_hestimate[i] + d_hestimate[i-2]) / gr_complex(2.0, 0.0);     
    158   } 
    159  
    160   // with even number of carriers; last equalizer tap is wrong 
    161   if(!(d_occupied_carriers & 1)) { 
    162     d_hestimate[d_occupied_carriers-1] = d_hestimate[d_occupied_carriers-2]; 
    163   } 
    164  
    165   if(VERBOSE) { 
    166     fprintf(stderr, "Equalizer setting:\n"); 
    167     for(i = 0; i < d_occupied_carriers; i++) { 
    168       gr_complex sym = coarse_freq_comp(d_coarse_freq,1)*symbol[i+zeros_on_left+d_coarse_freq]; 
    169       gr_complex output = sym * d_hestimate[i]; 
    170       fprintf(stderr, "sym: %+.4f + j%+.4f  ks: %+.4f + j%+.4f  eq: %+.4f + j%+.4f  ==>  %+.4f + j%+.4f\n",  
    171               sym .real(), sym.imag(), 
    172               d_known_symbol[i].real(), d_known_symbol[i].imag(), 
    173               d_hestimate[i].real(), d_hestimate[i].imag(), 
    174               output.real(), output.imag()); 
    175     } 
    176     fprintf(stderr, "\n"); 
     194gr_ofdm_frame_acquisition::calculate_equalizer(const gr_complex *previous, const gr_complex *current,  
     195                                        int zeros_on_left) 
     196
     197  int i=0; 
     198  std::vector<gr_complex> h_est; 
     199  h_est.resize(d_occupied_carriers); 
     200 
     201#if VERBOSE>1 
     202  printf("gr_ofdm_frame_acq: equalizer settings\n"); 
     203#endif 
     204 
     205  for(i = 0; i < (int)d_occupied_carriers; i++) { 
     206    // FIXME possibly add small epsilon in divisor to protect from div 0 
     207    //d_hestimate[i] = 0.5F * (d_known_symbol1[i] / previous[i+zeros_on_left] + 
     208    //                      d_known_symbol2[i] / (coarse_freq_comp(d_coarse_freq,1)* 
     209    //                                            current[i+zeros_on_left+d_coarse_freq])); 
     210    h_est[i] = 0.5F * (d_known_symbol1[i] / previous[i+zeros_on_left+d_coarse_freq] + 
     211                             d_known_symbol2[i] / (coarse_freq_comp(d_coarse_freq,1)* 
     212                                                   current[i+zeros_on_left+d_coarse_freq])); 
     213  } 
     214 
     215  for (i = 0; i < (int)d_occupied_carriers; i++) { 
     216    float tmp_mag = 0.0f, tmp_phase = 0.0f; 
     217    int n; 
     218 
     219#if AVERAGE_MAG 
     220    n = 0; 
     221    for (int j = std::max(0, i - HEST_AV_WINDOW);  
     222         j < std::min(i + HEST_AV_WINDOW - 1, (int)d_occupied_carriers - 1); 
     223         j++, n++) { 
     224      tmp_mag += sqrt(norm(h_est[j])); 
     225    } 
     226    tmp_mag /= n; 
     227#else 
     228    tmp_mag = sqrt(norm(h_est[i])); 
     229#endif 
     230 
     231#if AVERAGE_PHASE 
     232    n = 0; 
     233    for (int j = std::max(0, i - HEST_AV_WINDOW);  
     234         j < std::min(i + HEST_AV_WINDOW - 1, (int)d_occupied_carriers - 1); 
     235         j++, n++) { 
     236      tmp_phase += arg(h_est[j]); 
     237    } 
     238    tmp_phase /= n; 
     239#else 
     240    tmp_phase = arg(h_est[i]); 
     241#endif 
     242 
     243    d_hestimate[i] = std::polar(tmp_mag, tmp_phase); 
     244     
     245#if VERBOSE>1 
     246    printf("%03d %+4.3e%+4.3ej sqrtnorm %4.3e arg %f original: %+4.3e%+4.3ej\n",  
     247           i, d_hestimate[i].real(), d_hestimate[i].imag(),  
     248           sqrt(norm(d_hestimate[i])), arg(d_hestimate[i]), 
     249           h_est[i].real(), h_est[i].imag()); 
     250#endif 
    177251  } 
    178252} 
     
    184258                                        gr_vector_void_star &output_items) 
    185259{ 
    186   const gr_complex *symbol = (const gr_complex *)input_items[0]; 
    187   const char *trigger = (const char *)input_items[1]; 
     260  const gr_complex *in = (const gr_complex *)input_items[0]; 
     261  const gr_complex *previous = &in[0]; 
     262  const gr_complex *current = &in[d_fft_length]; 
     263 
     264  const char *in_sig = (const char *)input_items[1]; 
    188265 
    189266  gr_complex *out = (gr_complex *) output_items[0]; 
    190267  char *sig = (char *) output_items[1]; 
    191    
     268  float *snr_est = (float *)output_items[2]; 
     269 
     270 
    192271  int unoccupied_carriers = d_fft_length - d_occupied_carriers; 
    193272  int zeros_on_left = (int)ceil(unoccupied_carriers/2.0); 
    194273 
    195   int found = 0; 
    196   for(int i = 0; i < ninput_items[1]; i++) { 
    197     found += trigger[i]; 
    198   } 
    199  
    200   if(found) { 
    201     d_phase_count = 1; 
    202     correlate(symbol, zeros_on_left); 
    203     calculate_equalizer(symbol, zeros_on_left); 
    204     sig[0] = 1; 
     274  if(in_sig[0]) { 
     275    bool corr = correlate(previous, current, zeros_on_left); 
     276    calculate_equalizer(previous, current, zeros_on_left); 
     277    if (corr) { 
     278      sig[0] = 1; 
     279 
     280      if (output_items.size() == 4) { // debugging output is connected 
     281        gr_complex *equalizer_out = (gr_complex *)output_items[3]; 
     282        for (int i = 0; i < (int)d_occupied_carriers; i++) 
     283          equalizer_out[i] = d_hestimate[i]; 
     284      } 
     285    } else 
     286      sig[0] = 0; 
     287    snr_est[0] = d_snr_est; 
     288 
    205289  } 
    206290  else { 
    207291    sig[0] = 0; 
    208   } 
    209  
    210   for(unsigned int i = 0; i < d_occupied_carriers; i++) { 
    211     out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count) 
    212       *symbol[i+zeros_on_left+d_coarse_freq]; 
     292    snr_est[0] = 0.0; 
     293  } 
     294 
     295  for(int i = 0; i < (int)d_occupied_carriers; i++) { 
     296    out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)*current[i+zeros_on_left+d_coarse_freq]; 
    213297  } 
    214298   
     299 
    215300  d_phase_count++; 
    216301  if(d_phase_count == MAX_NUM_SYMBOLS) { 
     
    218303  } 
    219304 
    220   consume(0,1); 
    221   consume(1,ninput_items[1]); 
     305  consume_each(1); 
    222306  return 1; 
    223307} 
  • gnuradio/branches/features/coded-ofdm/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.h

    r7324 r9750  
    3434gr_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int fft_length, 
    3535                                unsigned int cplen, 
    36                                 const std::vector<gr_complex> &known_symbol,  
    37                                 unsigned int max_fft_shift_len=10); 
     36                                const std::vector<gr_complex> &known_symbol1,  
     37                                const std::vector<gr_complex> &known_symbol2, 
     38                                unsigned int max_fft_shift_len=30); 
    3839 
    3940/*! 
     
    7172  gr_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int fft_length, 
    7273                                  unsigned int cplen, 
    73                                   const std::vector<gr_complex> &known_symbol,  
     74                                  const std::vector<gr_complex> &known_symbol1,  
     75                                  const std::vector<gr_complex> &known_symbol2, 
    7476                                  unsigned int max_fft_shift_len); 
    7577   
     
    7779  gr_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int fft_length, 
    7880                             unsigned int cplen, 
    79                              const std::vector<gr_complex> &known_symbol,  
     81                             const std::vector<gr_complex> &known_symbol1,  
     82                             const std::vector<gr_complex> &known_symbol2, 
    8083                             unsigned int max_fft_shift_len); 
    8184   
    8285 private: 
    8386  unsigned char slicer(gr_complex x); 
    84   bool correlate(const gr_complex *symbol, int zeros_on_left); 
    85   void calculate_equalizer(const gr_complex *symbol, int zeros_on_left); 
     87  bool correlate(const gr_complex *previous, const gr_complex *current, int zeros_on_left); 
     88  void calculate_equalizer(const gr_complex *previous,  
     89                           const gr_complex *current, int zeros_on_left); 
    8690  gr_complex coarse_freq_comp(int freq_delta, int count); 
    8791   
     
    9094  unsigned int d_cplen;              // !< \brief length of cyclic prefix in samples 
    9195  unsigned int d_freq_shift_len;     // !< \brief number of surrounding bins to look at for correlation 
    92   std::vector<gr_complex> d_known_symbol; // !< \brief known symbols at start of frame 
    93   std::vector<float> d_known_phase_diff; // !< \brief factor used in correlation from known symbol 
    94   std::vector<float> d_symbol_phase_diff; // !< \brief factor used in correlation from received symbol 
     96  std::vector<gr_complex> d_known_symbol1, d_known_symbol2; // !< \brief known symbols at start of frame 
     97  std::vector<gr_complex> d_diff_corr_factor; // !< \brief factor used in correlation 
    9598  std::vector<gr_complex> d_hestimate;  // !< channel estimate 
    96   int d_coarse_freq;             // !< \brief search distance in number of bins 
     99  signed int d_coarse_freq;             // !< \brief search distance in number of bins 
    97100  unsigned int d_phase_count;           // !< \brief accumulator for coarse freq correction 
    98101  float d_snr_est;                      // !< an estimation of the signal to noise ratio 
     102  float d_max_snr_est; 
    99103 
    100104  gr_complex *d_phase_lut;  // !< look-up table for coarse frequency compensation 
  • gnuradio/branches/features/coded-ofdm/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.i

    r7324 r9750  
    2929                                unsigned int fft_length, 
    3030                                unsigned int cplen, 
    31                                 const std::vector<gr_complex> &known_symbol,  
     31                                const std::vector<gr_complex> &known_symbol1,  
     32                                const std::vector<gr_complex> &known_symbol2, 
    3233