summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/general
diff options
context:
space:
mode:
authortrondeau2007-08-04 15:21:34 +0000
committertrondeau2007-08-04 15:21:34 +0000
commit9967e2e7664dbc96a5d1587c194cc648d01cf487 (patch)
treea86af8700d6934f9e5a82011373dd7740b539351 /gnuradio-core/src/lib/general
parente1ba40adade7ca7c1d732b4739c3889f2c6fd7a6 (diff)
downloadgnuradio-9967e2e7664dbc96a5d1587c194cc648d01cf487.tar.gz
gnuradio-9967e2e7664dbc96a5d1587c194cc648d01cf487.tar.bz2
gnuradio-9967e2e7664dbc96a5d1587c194cc648d01cf487.zip
merged -r5966:6112 on trondeau/ofdm_mod. Allows for generic constellations (supports bpsk, qpsk, 8psk, qam16, qam64, and qam256 currently), fixes some bugs in the correlation and altered default parameters for over-the-air operation. This merge fixes ticket:156 and ticket:157.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6113 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gnuradio-core/src/lib/general')
-rw-r--r--gnuradio-core/src/lib/general/general.i2
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc4
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_correlator.cc28
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_correlator.h2
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc126
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h38
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i10
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc156
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h48
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i26
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc4
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_sampler.cc4
12 files changed, 331 insertions, 117 deletions
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index a6a356f4e..e9780ea13 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -96,6 +96,7 @@
#include <gr_ofdm_correlator.h>
#include <gr_ofdm_cyclic_prefixer.h>
#include <gr_ofdm_bpsk_demapper.h>
+#include <gr_ofdm_mapper_bcv.h>
#include <gr_ofdm_bpsk_mapper.h>
#include <gr_ofdm_qpsk_mapper.h>
#include <gr_ofdm_qam_mapper.h>
@@ -203,6 +204,7 @@
%include "gr_ofdm_correlator.i"
%include "gr_ofdm_cyclic_prefixer.i"
%include "gr_ofdm_bpsk_demapper.i"
+%include "gr_ofdm_mapper_bcv.i"
%include "gr_ofdm_bpsk_mapper.i"
%include "gr_ofdm_qpsk_mapper.i"
%include "gr_ofdm_qam_mapper.i"
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
index da3288680..f634ed3f6 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
@@ -59,7 +59,7 @@ static float
randombit()
{
int r = rand()&1;
- return (float)(-1 + 2*r);
+ return (float)(1 - 2*r);
}
int
@@ -105,7 +105,7 @@ gr_ofdm_bpsk_mapper::work(int noutput_items,
i = 0;
while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
unsigned char bit = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
- out[i + zeros_on_left] = gr_complex(-1+2*(bit));
+ out[i + zeros_on_left] = gr_complex(1-2*(bit));
i++;
d_bit_offset++;
if(d_bit_offset == 8) {
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
index 4c7b67ff7..e396eeb8e 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
@@ -99,12 +99,13 @@ gr_ofdm_correlator::coarse_freq_comp(int freq_delta, int symbol_count)
{
// return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count),
// sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count));
- //return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
- assert(d_freq_shift_len + freq_delta >= 0);
- assert(symbol_count <= MAX_NUM_SYMBOLS);
+ return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
- return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count];
+ //assert(d_freq_shift_len + freq_delta >= 0);
+ //assert(symbol_count <= MAX_NUM_SYMBOLS);
+
+ //return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count];
}
bool
@@ -118,7 +119,7 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
gr_complex h_sqrd = gr_complex(0.0,0.0);
float power = 0.0F;
- while(!found && ((unsigned)abs(search_delta) < d_freq_shift_len)) {
+ while(!found && ((unsigned)abs(search_delta) <= d_freq_shift_len)) {
h_sqrd = gr_complex(0.0,0.0);
power = 0.0F;
@@ -126,17 +127,18 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
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("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
-
- // FIXME: Look at h_sqrd.read() > power
- if((h_sqrd.real() > 0.82*power) && (h_sqrd.real() < 1.1 * power)) {
+ 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
+ // FIXME: Look at h_sqrd.read() > power
+ if((h_sqrd.real() > 0.82*power) && (h_sqrd.real() < 1.1 * power)) {
found = true;
+ //printf("search delta: %d\n", search_delta);
d_coarse_freq = search_delta;
d_phase_count = 1;
//d_snr_est = 10*log10(power/(power-h_sqrd.real()));
@@ -220,6 +222,10 @@ gr_ofdm_correlator::general_work(int noutput_items,
d_phase_count++;
+ if(d_phase_count == MAX_NUM_SYMBOLS) {
+ d_phase_count = 1;
+ }
+
consume_each(1);
return 1;
}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
index 981df7e1c..55ee4e190 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
@@ -35,7 +35,7 @@ gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length
unsigned int cplen,
const std::vector<gr_complex> &known_symbol1,
const std::vector<gr_complex> &known_symbol2,
- unsigned int max_fft_shift_len=4);
+ unsigned int max_fft_shift_len=10);
/*!
* \brief take a vector of complex constellation points in from an FFT
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
index 68cadce04..d75b693a2 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
@@ -74,55 +74,57 @@ gr_ofdm_frame_sink::enter_have_header()
d_packetlen, d_packet_whitener_offset);
}
-unsigned char gr_ofdm_frame_sink::bpsk_slicer(gr_complex x)
-{
- return (unsigned char)(x.real() > 0 ? 1 : 0);
-}
-
-unsigned char gr_ofdm_frame_sink::qpsk_slicer(gr_complex x)
-{
- unsigned char i = (x.real() > 0 ? 1 : 0);
- unsigned char q = (x.imag() > 0 ? 1 : 0);
-
- return (q << 1) | i;
-}
-unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
- unsigned char *out)
+unsigned char gr_ofdm_frame_sink::slicer(const gr_complex x)
{
- unsigned int i=0, bytes_produced=0;
-
- while(i < d_occupied_carriers) {
-
- while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
- //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag());
- d_partial_byte |= bpsk_slicer(in[i++]) << (d_byte_offset++);
- }
-
- if(d_byte_offset == 8) {
- out[bytes_produced++] = d_partial_byte;
- d_byte_offset = 0;
- d_partial_byte = 0;
+ unsigned int table_size = d_sym_value_out.size();
+ unsigned int min_index = 0;
+ float min_euclid_dist = norm(x - d_sym_position[0]);
+ float euclid_dist = 0;
+
+ for (unsigned int j = 1; j < table_size; j++){
+ euclid_dist = norm(x - d_sym_position[j]);
+ if (euclid_dist < min_euclid_dist){
+ min_euclid_dist = euclid_dist;
+ min_index = j;
}
}
-
- return bytes_produced;
+ return d_sym_value_out[min_index];
}
-unsigned int gr_ofdm_frame_sink::qpsk_demapper(const gr_complex *in,
- unsigned char *out)
+unsigned int gr_ofdm_frame_sink::demapper(const gr_complex *in,
+ unsigned char *out)
{
unsigned int i=0, bytes_produced=0;
while(i < d_occupied_carriers) {
-
+ if(d_nresid > 0) {
+ d_partial_byte |= d_resid;
+ d_byte_offset += d_nresid;
+ d_nresid = 0;
+ d_resid = 0;
+ }
+
while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
- //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag());
- d_partial_byte |= qpsk_slicer(in[i++]) << (d_byte_offset);
- d_byte_offset += 2;
+ //fprintf(stderr, "%f+j%f = %d\n", in[i].real(), in[i].imag(), slicer(in[i]));
+ unsigned char bits = slicer(in[i++]);
+ if((8 - d_byte_offset) >= d_nbits) {
+ d_partial_byte |= bits << (d_byte_offset);
+ d_byte_offset += d_nbits;
+ }
+ else {
+ d_nresid = d_nbits-(8-d_byte_offset);
+ int mask = ((1<<(8-d_byte_offset))-1);
+ d_partial_byte |= (bits & mask) << d_byte_offset;
+ d_resid = bits >> (8-d_byte_offset);
+ d_byte_offset += (d_nbits - d_nresid);
+ }
+ //printf("demod symbol: %.4f + j%.4f bits: %x partial_byte: %x byte_offset: %d resid: %x nresid: %d\n",
+ // in[i-1].real(), in[i-1].imag(), bits, d_partial_byte, d_byte_offset, d_resid, d_nresid);
}
if(d_byte_offset == 8) {
+ //printf("demod byte: %x \n\n", d_partial_byte);
out[bytes_produced++] = d_partial_byte;
d_byte_offset = 0;
d_partial_byte = 0;
@@ -132,34 +134,31 @@ unsigned int gr_ofdm_frame_sink::qpsk_demapper(const gr_complex *in,
return bytes_produced;
}
+
gr_ofdm_frame_sink_sptr
-gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
- const std::string &mod)
+gr_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
{
- return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers, mod));
+ return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(sym_position, sym_value_out,
+ target_queue, occupied_carriers));
}
-gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
- const std::string &mod)
+gr_ofdm_frame_sink::gr_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
: gr_sync_block ("ofdm_frame_sink",
gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)),
gr_make_io_signature (0, 0, 0)),
d_target_queue(target_queue), d_occupied_carriers(occupied_carriers),
- d_byte_offset(0), d_partial_byte(0)
+ d_byte_offset(0), d_partial_byte(0),
+ d_resid(0), d_nresid(0)
{
- d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/4.0)];
-
- if(mod == "qpsk") {
- d_demapper = &gr_ofdm_frame_sink::qpsk_demapper;
- }
- else if(mod == "bpsk") {
- d_demapper = &gr_ofdm_frame_sink::bpsk_demapper;
- }
- else {
- throw std::invalid_argument("Modulation type must be BPSK or QPSK.");
- }
+ d_bytes_out = new unsigned char[d_occupied_carriers];
+ set_sym_value_out(sym_position, sym_value_out);
+
enter_search();
}
@@ -168,6 +167,24 @@ gr_ofdm_frame_sink::~gr_ofdm_frame_sink ()
delete [] d_bytes_out;
}
+bool
+gr_ofdm_frame_sink::set_sym_value_out(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out)
+{
+ if (sym_position.size() != sym_value_out.size())
+ return false;
+
+ if (sym_position.size()<1)
+ return false;
+
+ d_sym_position = sym_position;
+ d_sym_value_out = sym_value_out;
+ d_nbits = (unsigned long)(log10(d_sym_value_out.size()) / log10(2));
+
+ return true;
+}
+
+
int
gr_ofdm_frame_sink::work (int noutput_items,
gr_vector_const_void_star &input_items,
@@ -181,9 +198,8 @@ gr_ofdm_frame_sink::work (int noutput_items,
if (VERBOSE)
fprintf(stderr,">>> Entering state machine\n");
- //bytes = bpsk_demapper(&in[0], d_bytes_out);
- bytes = (this->*d_demapper)(&in[0], d_bytes_out);
-
+ bytes = demapper(&in[0], d_bytes_out);
+
switch(d_state) {
case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
index 13f61b782..f1c9b76fe 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
@@ -30,8 +30,9 @@ class gr_ofdm_frame_sink;
typedef boost::shared_ptr<gr_ofdm_frame_sink> gr_ofdm_frame_sink_sptr;
gr_ofdm_frame_sink_sptr
-gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
- const std::string &mod);
+gr_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
/*!
* \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs
@@ -44,8 +45,9 @@ gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_t
class gr_ofdm_frame_sink : public gr_sync_block
{
friend gr_ofdm_frame_sink_sptr
- gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
- const std::string &mod);
+ gr_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
private:
enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
@@ -69,9 +71,17 @@ class gr_ofdm_frame_sink : public gr_sync_block
int d_packet_whitener_offset; // offset into whitener string to use
int d_packetlen_cnt; // how many so far
+ std::vector<gr_complex> d_sym_position;
+ std::vector<unsigned char> d_sym_value_out;
+ unsigned int d_nbits;
+
+ unsigned char d_resid;
+ unsigned int d_nresid;
+
protected:
- gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
- const std::string &mod);
+ gr_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
void enter_search();
void enter_have_sync();
@@ -82,17 +92,13 @@ class gr_ofdm_frame_sink : public gr_sync_block
// confirm that two copies of header info are identical
return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
}
+
+ unsigned char slicer(const gr_complex x);
+ unsigned int demapper(const gr_complex *in,
+ unsigned char *out);
- unsigned char bpsk_slicer(gr_complex x);
- unsigned int bpsk_demapper(const gr_complex *in,
- unsigned char *out);
-
- unsigned char qpsk_slicer(gr_complex x);
- unsigned int qpsk_demapper(const gr_complex *in,
- unsigned char *out);
-
- // pointer to mod-specific demapper
- unsigned int (gr_ofdm_frame_sink::*d_demapper)(const gr_complex *in, unsigned char *out);
+ bool set_sym_value_out(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
public:
~gr_ofdm_frame_sink();
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
index 4f4f81d22..296eb6591 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
@@ -23,14 +23,16 @@
GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink);
gr_ofdm_frame_sink_sptr
-gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
- const std::string &mod);
+gr_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
class gr_ofdm_frame_sink : public gr_sync_block
{
protected:
- gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
- const std::string &mod);
+ gr_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
public:
~gr_ofdm_frame_sink();
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
index 76a7c94d9..4ff55b5d8 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2005 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,22 +20,166 @@
* Boston, MA 02110-1301, USA.
*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gr_ofdm_mapper_bcv.h>
#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_ofdm_mapper_bcv_sptr
+gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned int msgq_limit,
+ unsigned int occupied_carriers, unsigned int fft_length)
+{
+ return gr_ofdm_mapper_bcv_sptr (new gr_ofdm_mapper_bcv (constellation, msgq_limit,
+ occupied_carriers, fft_length));
+}
+
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
+gr_ofdm_mapper_bcv::gr_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned int msgq_limit,
+ unsigned int occupied_carriers, unsigned int fft_length)
+ : gr_sync_block ("ofdm_mapper_bcv",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
+ d_constellation(constellation),
+ d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
+ d_occupied_carriers(occupied_carriers),
+ d_fft_length(fft_length),
+ d_bit_offset(0),
+ d_pending_flag(0),
+ d_resid(0),
+ d_nresid(0)
+{
+ if (!(d_occupied_carriers <= d_fft_length))
+ throw std::invalid_argument("gr_ofdm_mapper_bcv: occupied carriers must be <= fft_length");
+
+ d_nbits = (unsigned long)(log10(d_constellation.size()) / log10(2));
+}
gr_ofdm_mapper_bcv::~gr_ofdm_mapper_bcv(void)
{
}
-gr_ofdm_mapper_bcv::gr_ofdm_mapper_bcv (unsigned bits_per_symbol,unsigned int vlen)
- : gr_sync_decimator ("ofdm_mapper_bcv",
- gr_make_io_signature (1, 1, sizeof(unsigned char)),
- gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen),
- bits_per_symbol)
+int gr_ofdm_mapper_bcv::randsym()
{
+ return (rand() % d_constellation.size());
}
+int
+gr_ofdm_mapper_bcv::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ unsigned int i=0;
+ unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+ unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
+
+ //printf("OFDM BPSK Mapper: ninput_items: %d noutput_items: %d\n", ninput_items[0], noutput_items);
+
+ if(d_eof) {
+ return -1;
+ }
+
+ if(!d_msg) {
+ d_msg = d_msgq->delete_head(); // block, waiting for a message
+ d_msg_offset = 0;
+ d_bit_offset = 0;
+ d_pending_flag = 1; // new packet, write start of packet flag
+
+ if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+ d_msg.reset();
+ return -1; // We're done; no more messages coming.
+ }
+ }
+
+ char *out_flag = 0;
+ if(output_items.size() == 2)
+ out_flag = (char *) output_items[1];
+
+
+ // Build a single symbol:
+ // Initialize all bins to 0 to set unused carriers
+ memset(out, 0, d_fft_length*sizeof(gr_complex));
+
+ i = 0;
+ unsigned char bits = 0;
+ while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+
+ // need new data to process
+ if(d_bit_offset == 0) {
+ d_msgbytes = d_msg->msg()[d_msg_offset];
+ //printf("mod message byte: %x\n", d_msgbytes);
+ }
+
+ if(d_nresid > 0) {
+ d_resid |= (((1 << d_nresid)-1) & d_msgbytes) << (d_nbits - d_nresid);
+ bits = d_resid;
+
+ out[i + zeros_on_left] = d_constellation[bits];
+ i++;
+
+ d_bit_offset += d_nresid;
+ d_nresid = 0;
+ d_resid = 0;
+ //printf("mod bit(r): %x resid: %x nresid: %d bit_offset: %d\n",
+ // bits, d_resid, d_nresid, d_bit_offset);
+ }
+ else {
+ if((8 - d_bit_offset) >= d_nbits) {
+ bits = ((1 << d_nbits)-1) & (d_msgbytes >> d_bit_offset);
+ d_bit_offset += d_nbits;
+
+ out[i + zeros_on_left] = d_constellation[bits];
+ i++;
+
+ /*
+ printf("mod bit: %x out: %.4f + j%.4f resid: %x nresid: %d bit_offset: %d\n",
+ bits, out[i-1 + zeros_on_left].real(), out[i-1 + zeros_on_left].imag(),
+ d_resid, d_nresid, d_bit_offset);
+ */
+ }
+ else {
+ unsigned int extra = 8-d_bit_offset;
+ d_resid = ((1 << extra)-1) & (d_msgbytes >> d_bit_offset);
+ d_bit_offset += extra;
+ d_nresid = d_nbits - extra;
+ }
+
+ }
+
+ if(d_bit_offset == 8) {
+ d_bit_offset = 0;
+ d_msg_offset++;
+ }
+ }
+
+ // Ran out of data to put in symbol
+ if (d_msg_offset == d_msg->length()) {
+ if(d_nresid > 0) {
+ d_resid |= 0x00;
+ bits = d_resid;
+ d_nresid = 0;
+ d_resid = 0;
+ }
+
+ while(i < d_occupied_carriers) { // finish filling out the symbol
+ out[i + zeros_on_left] = d_constellation[randsym()];
+ i++;
+ }
+
+ if (d_msg->type() == 1) // type == 1 sets EOF
+ d_eof = true;
+ d_msg.reset(); // finished packet, free message
+ assert(d_bit_offset == 0);
+ }
+
+ if (out_flag)
+ out_flag[0] = d_pending_flag;
+ d_pending_flag = 0;
+
+ return 1; // produced symbol
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h
index 7b55d90ce..a9b676a3c 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,14 +23,16 @@
#ifndef INCLUDED_GR_OFDM_MAPPER_BCV_H
#define INCLUDED_GR_OFDM_MAPPER_BCV_H
-#include <gr_sync_decimator.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
class gr_ofdm_mapper_bcv;
typedef boost::shared_ptr<gr_ofdm_mapper_bcv> gr_ofdm_mapper_bcv_sptr;
gr_ofdm_mapper_bcv_sptr
-gr_make_ofdm_mapper_bcv (unsigned int bits_per_symbol, unsigned int vlen);
-
+gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length);
/*!
* \brief take a stream of bytes in and map to a vector of complex
@@ -39,18 +41,44 @@ gr_make_ofdm_mapper_bcv (unsigned int bits_per_symbol, unsigned int vlen);
*
*/
-class gr_ofdm_mapper_bcv : public gr_sync_decimator
+class gr_ofdm_mapper_bcv : public gr_sync_block
{
friend gr_ofdm_mapper_bcv_sptr
- gr_make_ofdm_mapper_bcv (unsigned int bits_per_symbol, unsigned int vlen);
+ gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length);
+ protected:
+ gr_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length);
+
+ private:
+ std::vector<gr_complex> d_constellation;
+ gr_msg_queue_sptr d_msgq;
+ gr_message_sptr d_msg;
+ unsigned d_msg_offset;
+ bool d_eof;
+
+ unsigned int d_occupied_carriers;
+ unsigned int d_fft_length;
+ unsigned int d_bit_offset;
+ int d_pending_flag;
+
+ unsigned long d_nbits;
+ unsigned char d_msgbytes;
+
+ unsigned char d_resid;
+ unsigned int d_nresid;
-protected:
- gr_ofdm_mapper_bcv (unsigned int bits_per_symbol, unsigned int vlen);
+ int randsym();
-public:
+ public:
~gr_ofdm_mapper_bcv(void);
-};
+ gr_msg_queue_sptr msgq() const { return d_msgq; }
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
#endif
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i
index e786c70f5..30c692926 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,17 +20,27 @@
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,ofdm_mapper_bcv)
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_mapper_bcv);
gr_ofdm_mapper_bcv_sptr
-gr_make_ofdm_mapper_bcv (unsigned int bits_per_symbol,
- unsigned int vlen);
+gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation,
+ unsigned int msgq_limit,
+ unsigned int bits_per_symbol,
+ unsigned int fft_length);
-class gr_ofdm_mapper_bcv : public gr_sync_decimator
+
+class gr_ofdm_mapper_bcv : public gr_sync_block
{
protected:
- gr_ofdm_mapper_bcv (unsigned int bits_per_symbol,
- unsigned int vlen);
-
+ gr_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation,
+ unsigned int msgq_limit,
+ unsigned int bits_per_symbol,
+ unsigned int fft_length);
+
public:
+ gr_msg_queue_sptr msgq();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
index 011d15f6f..39c5bbdee 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
@@ -60,7 +60,7 @@ randombit()
{
int r1 = rand()&1;
int r2 = rand()&1;
- return gr_complex((0.707)*(-1 + 2*r1),(0.707)*(-1 + 2*r2));
+ return gr_complex((0.707)*(1 - 2*r1),(0.707)*(1 - 2*r2));
}
int
@@ -111,7 +111,7 @@ gr_ofdm_qpsk_mapper::work(int noutput_items,
unsigned char bit1 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
d_bit_offset++;
- out[i + zeros_on_left] = gr_complex((0.707)*(-1+2*(bit0)), (0.707)*(-1+2*(bit1)) );
+ out[i + zeros_on_left] = gr_complex((0.707)*(1-2*(bit0)), (0.707)*(1-2*(bit1)) );
i++;
if(d_bit_offset == 8) {
d_bit_offset = 0;
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
index 02897bb6b..56b5d50a4 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
@@ -69,11 +69,12 @@ gr_ofdm_sampler::general_work (int noutput_items,
int i=d_fft_length-1;
- while(!found && i<std::min(ninput_items[0],ninput_items[1]) )
+ while(!found && i<std::min(ninput_items[0],ninput_items[1]) ) {
if(trigger[i])
found = 1;
else
i++;
+ }
if(found) {
assert(i-d_fft_length+1 >= 0);
@@ -89,6 +90,5 @@ gr_ofdm_sampler::general_work (int noutput_items,
// ninput_items[0], ninput_items[1], noutput_items, (i-d_fft_length+1), found);
}
-
return found;
}