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