[Top][All Lists]
[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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7583 - gnuradio/branches/developers/trondeau/ofdmfix/gnuradio-core/src/lib/general,
trondeau <=