diff options
Diffstat (limited to 'gnuradio-core/src')
-rw-r--r-- | gnuradio-core/src/lib/general/general.i | 2 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc | 4 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_correlator.cc | 28 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_correlator.h | 2 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc | 126 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h | 38 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i | 10 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc | 156 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h | 48 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i | 26 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc | 4 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_ofdm_sampler.cc | 4 | ||||
-rw-r--r-- | gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py | 51 | ||||
-rw-r--r-- | gnuradio-core/src/python/gnuradio/blksimpl/psk.py | 6 | ||||
-rw-r--r-- | gnuradio-core/src/python/gnuradio/gruimpl/crc.py | 4 |
15 files changed, 375 insertions, 134 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; } diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py index d4fef81ec..b040d8c7f 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py +++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py @@ -24,6 +24,7 @@ import math from numpy import fft from gnuradio import gr, ofdm_packet_utils import gnuradio.gr.gr_threading as _threading +import psk, qam from gnuradio.blksimpl.ofdm_receiver import ofdm_receiver @@ -81,15 +82,21 @@ class ofdm_mod(gr.hier_block): padded_preambles.append(padded) symbol_length = options.fft_length + options.cp_length - - # The next step will all us to pass a constellation into a generic mapper function instead - # of using these hard-coded versions - if self._modulation == "bpsk": - self._pkt_input = gr.ofdm_bpsk_mapper(msgq_limit, options.occupied_tones, options.fft_length) - elif self._modulation == "qpsk": - self._pkt_input = gr.ofdm_qpsk_mapper(msgq_limit, options.occupied_tones, options.fft_length) - else: - print "Modulation type not supported (must be \"bpsk\" or \"qpsk\"" + + mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} + arity = mods[self._modulation] + + rot = 1 + if self._modulation == "qpsk": + rot = (0.707+0.707j) + + if(self._modulation.find("psk") >= 0): + rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) + elif(self._modulation.find("qam") >= 0): + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + #print rotated_const + self._pkt_input = gr.ofdm_mapper_bcv(rotated_const, msgq_limit, + options.occupied_tones, options.fft_length) self.preambles = gr.ofdm_insert_preamble(self._fft_length, padded_preambles) self.ifft = gr.fft_vcc(self._fft_length, False, win, True) @@ -104,7 +111,8 @@ class ofdm_mod(gr.hier_block): self._print_verbage() if options.log: - fg.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat")) + fg.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, + "ofdm_mapper_c.dat")) gr.hier_block.__init__(self, fg, None, self.scale) @@ -119,8 +127,8 @@ class ofdm_mod(gr.hier_block): msg = gr.message(1) # tell self._pkt_input we're not sending any more packets else: # print "original_payload =", string_to_hex_list(payload) - pkt = ofdm_packet_utils.make_packet(payload, 1, 1, self._pad_for_usrp) - + pkt = ofdm_packet_utils.make_packet(payload, 1, 1, self._pad_for_usrp, whitening=True) + #print "pkt =", string_to_hex_list(pkt) msg = gr.message_from_string(pkt) self._pkt_input.msgq().insert_tail(msg) @@ -208,9 +216,22 @@ class ofdm_demod(gr.hier_block): self.ofdm_recv = ofdm_receiver(fg, self._fft_length, self._cp_length, self._occupied_tones, self._snr, preambles, options.log) - self.ofdm_demod = gr.ofdm_frame_sink(self._rcvd_pktq, - self._occupied_tones, - self._modulation) + + mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} + arity = mods[self._modulation] + + rot = 1 + if self._modulation == "qpsk": + rot = (0.707+0.707j) + + if(self._modulation.find("psk") >= 0): + rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) + elif(self._modulation.find("qam") >= 0): + rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + #print rotated_const + self.ofdm_demod = gr.ofdm_frame_sink(rotated_const, range(arity), + self._rcvd_pktq, + self._occupied_tones) fg.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0)) fg.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1)) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/psk.py b/gnuradio-core/src/python/gnuradio/blksimpl/psk.py index 5dcf4935e..acedf3b69 100644 --- a/gnuradio-core/src/python/gnuradio/blksimpl/psk.py +++ b/gnuradio-core/src/python/gnuradio/blksimpl/psk.py @@ -53,6 +53,12 @@ constellation = { 8 : make_constellation(8) # 8PSK } +gray_constellation = { + 2 : make_gray_constellation(2), # BPSK + 4 : make_gray_constellation(4), # QPSK + 8 : make_gray_constellation(8) # 8PSK + } + # ----------------------- # Do Gray code # ----------------------- diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/crc.py b/gnuradio-core/src/python/gnuradio/gruimpl/crc.py index ad8ce8879..d31aca0ea 100644 --- a/gnuradio-core/src/python/gnuradio/gruimpl/crc.py +++ b/gnuradio-core/src/python/gnuradio/gruimpl/crc.py @@ -1,5 +1,5 @@ # -# Copyright 2005 Free Software Foundation, Inc. +# Copyright 2005,2007 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -25,7 +25,7 @@ import struct def gen_and_append_crc32(s): crc = gr.crc32(s) - return s + struct.pack(">I", hexint(crc)) + return s + struct.pack(">I", hexint(crc) & 0xFFFFFFFF) def check_crc32(s): if len(s) < 4: |