diff options
author | trondeau | 2007-06-10 18:16:11 +0000 |
---|---|---|
committer | trondeau | 2007-06-10 18:16:11 +0000 |
commit | a663f5b481679d8a352c668825cee92f548f3fcc (patch) | |
tree | 9286d4480cd964413b6e87aa6656d9e90e43ab13 /gnuradio-core/src/lib/general | |
parent | 616296d9e9e091360101f7f68b0c03ec1a6e382d (diff) | |
download | gnuradio-a663f5b481679d8a352c668825cee92f548f3fcc.tar.gz gnuradio-a663f5b481679d8a352c668825cee92f548f3fcc.tar.bz2 gnuradio-a663f5b481679d8a352c668825cee92f548f3fcc.zip |
Merging OFDM features branch r5661:5759 into trunk. OFDM works over the air with BPSK and QPSK modulations on subcarriers. Passes make distcheck.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5761 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gnuradio-core/src/lib/general')
25 files changed, 1314 insertions, 140 deletions
diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index d774baa1c..35aac0a22 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -102,7 +102,10 @@ libgeneral_la_SOURCES = \ gr_ofdm_mapper_bcv.cc \ gr_ofdm_bpsk_demapper.cc \ gr_ofdm_bpsk_mapper.cc \ + gr_ofdm_qpsk_mapper.cc \ + gr_ofdm_qam_mapper.cc \ gr_ofdm_frame_sink.cc \ + gr_ofdm_insert_preamble.cc \ gr_ofdm_sampler.cc \ gr_pa_2x2_phase_combiner.cc \ gr_packet_sink.cc \ @@ -121,6 +124,7 @@ libgeneral_la_SOURCES = \ gr_pwr_squelch_ff.cc \ gr_quadrature_demod_cf.cc \ gr_random.cc \ + gr_regenerate_bb.cc \ gr_remez.cc \ gr_reverse.cc \ gr_rms_cf.cc \ @@ -240,8 +244,11 @@ grinclude_HEADERS = \ gr_ofdm_demapper_vcb.h \ gr_ofdm_mapper_bcv.h \ gr_ofdm_bpsk_mapper.h \ + gr_ofdm_qpsk_mapper.h \ + gr_ofdm_qam_mapper.h \ gr_ofdm_bpsk_demapper.h \ gr_ofdm_frame_sink.h \ + gr_ofdm_insert_preamble.h \ gr_ofdm_sampler.h \ gr_pa_2x2_phase_combiner.h \ gr_packet_sink.h \ @@ -260,6 +267,7 @@ grinclude_HEADERS = \ gr_pwr_squelch_ff.h \ gr_quadrature_demod_cf.h \ gr_random.h \ + gr_regenerate_bb.h \ gr_remez.h \ gr_reverse.h \ gr_rms_cf.h \ @@ -381,7 +389,10 @@ swiginclude_HEADERS = \ gr_ofdm_mapper_bcv.i \ gr_ofdm_bpsk_demapper.i \ gr_ofdm_bpsk_mapper.i \ + gr_ofdm_qpsk_mapper.i \ + gr_ofdm_qam_mapper.i \ gr_ofdm_frame_sink.i \ + gr_ofdm_insert_preamble.i \ gr_ofdm_sampler.i \ gr_pa_2x2_phase_combiner.i \ gr_packet_sink.i \ @@ -399,6 +410,7 @@ swiginclude_HEADERS = \ gr_pwr_squelch_cc.i \ gr_pwr_squelch_ff.i \ gr_quadrature_demod_cf.i \ + gr_regenerate_bb.i \ gr_remez.i \ gr_rms_cf.i \ gr_rms_ff.i \ diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 1fdb4239a..b362d24d0 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -97,8 +97,12 @@ #include <gr_ofdm_cyclic_prefixer.h> #include <gr_ofdm_bpsk_demapper.h> #include <gr_ofdm_bpsk_mapper.h> +#include <gr_ofdm_qpsk_mapper.h> +#include <gr_ofdm_qam_mapper.h> #include <gr_ofdm_frame_sink.h> +#include <gr_ofdm_insert_preamble.h> #include <gr_ofdm_sampler.h> +#include <gr_regenerate_bb.h> #include <gr_costas_loop_cc.h> #include <gr_pa_2x2_phase_combiner.h> #include <gr_kludge_copy.h> @@ -200,8 +204,12 @@ %include "gr_ofdm_cyclic_prefixer.i" %include "gr_ofdm_bpsk_demapper.i" %include "gr_ofdm_bpsk_mapper.i" +%include "gr_ofdm_qpsk_mapper.i" +%include "gr_ofdm_qam_mapper.i" %include "gr_ofdm_frame_sink.i" +%include "gr_ofdm_insert_preamble.i" %include "gr_ofdm_sampler.i" +%include "gr_regenerate_bb.i" %include "gr_costas_loop_cc.i" %include "gr_pa_2x2_phase_combiner.i" %include "gr_kludge_copy.i" diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc index 89ab3ce0e..73b61a9a0 100644 --- a/gnuradio-core/src/lib/general/gr_delay.cc +++ b/gnuradio-core/src/lib/general/gr_delay.cc @@ -52,7 +52,7 @@ gr_delay::work (int noutput_items, const char *iptr; char *optr; - for(int i = 0; i < input_items.size(); i++) { + for(size_t i = 0; i < input_items.size(); i++) { iptr = (const char *) input_items[i]; optr = (char *) output_items[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 f0b52c325..5b4631227 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc @@ -26,23 +26,18 @@ #include <gr_ofdm_bpsk_mapper.h> #include <gr_io_signature.h> -#include <vector> +#include <stdexcept> gr_ofdm_bpsk_mapper_sptr gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, - unsigned int occupied_carriers, unsigned int fft_length, - const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2) + unsigned int occupied_carriers, unsigned int fft_length) { - return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length, - known_symbol1, known_symbol2)); + return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (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_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit, - unsigned int occupied_carriers, unsigned int fft_length, - const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2) + unsigned int occupied_carriers, unsigned int fft_length) : gr_sync_block ("ofdm_bpsk_mapper", gr_make_io_signature (0, 0, 0), gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))), @@ -50,20 +45,18 @@ gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit, d_occupied_carriers(occupied_carriers), d_fft_length(fft_length), d_bit_offset(0), - d_header_sent(0), - d_known_symbol1(known_symbol1), - d_known_symbol2(known_symbol2) + d_pending_flag(0) { - assert(d_occupied_carriers <= d_fft_length); - assert(d_occupied_carriers == d_known_symbol1.size()); - assert(d_occupied_carriers == d_known_symbol2.size()); + if (!(d_occupied_carriers <= d_fft_length)) + throw std::invalid_argument("gr_ofdm_bpsk_mapper: occupied carriers must be <= fft_length"); } gr_ofdm_bpsk_mapper::~gr_ofdm_bpsk_mapper(void) { } -float randombit() +static float +randombit() { int r = rand()&1; return (float)(-1 + 2*r); @@ -90,47 +83,25 @@ gr_ofdm_bpsk_mapper::work(int noutput_items, d_msg = d_msgq->delete_head(); // block, waiting for a message d_msg_offset = 0; d_bit_offset = 0; - d_header_sent = 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; + return -1; // We're done; no more messages coming. } } - if(output_items.size() == 2) { - char *sig = (char *)output_items[1]; - if(d_header_sent == 1) { - sig[0] = 1; - } - else { - sig[0] = 0; - } - } + 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)); - if(d_header_sent == 0) { - for(i=0; i < d_occupied_carriers; i++) { - out[i+zeros_on_left] = d_known_symbol1[i]; - } - d_header_sent++; - - return 1; - } - - if(d_header_sent == 1) { - for(i=0; i < d_occupied_carriers; i++) { - out[i+zeros_on_left] = d_known_symbol2[i]; - } - d_header_sent++; - - return 1; - } - 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; @@ -150,14 +121,16 @@ gr_ofdm_bpsk_mapper::work(int noutput_items, i++; } - if (d_msg->type() == 1) // type == 1 sets EOF + if (d_msg->type() == 1) // type == 1 sets EOF d_eof = true; - d_msg.reset(); // finished packet, free message - + d_msg.reset(); // finished packet, free message assert(d_bit_offset == 0); - return 1; // produced one symbol } - + + 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_bpsk_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h index 41b2f5bed..da78ca475 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h +++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.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 * @@ -27,19 +27,16 @@ #include <gr_sync_block.h> #include <gr_message.h> #include <gr_msg_queue.h> -#include <vector> class gr_ofdm_bpsk_mapper; typedef boost::shared_ptr<gr_ofdm_bpsk_mapper> gr_ofdm_bpsk_mapper_sptr; gr_ofdm_bpsk_mapper_sptr gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, - unsigned occupied_carriers, unsigned int fft_length, - const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2); + unsigned occupied_carriers, unsigned int fft_length); /*! - * \brief take a stream of bytes in and map to a vector of complex + * \brief take a message in and map to a vector of complex * constellation points suitable for IFFT input to be used in an ofdm * modulator. Simple BPSK version. */ @@ -47,28 +44,22 @@ gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, class gr_ofdm_bpsk_mapper : public gr_sync_block { friend gr_ofdm_bpsk_mapper_sptr - gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, - unsigned occupied_carriers, unsigned int fft_length, - const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2); - + gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length); protected: gr_ofdm_bpsk_mapper (unsigned msgq_limit, - unsigned occupied_carriers, unsigned int fft_length, - const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2); - + unsigned occupied_carriers, unsigned int fft_length); + private: 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; - unsigned int d_header_sent; - std::vector<gr_complex> d_known_symbol1, d_known_symbol2; + unsigned int d_occupied_carriers; + unsigned int d_fft_length; + unsigned int d_bit_offset; + int d_pending_flag; public: ~gr_ofdm_bpsk_mapper(void); diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i index d0094062a..2af37d641 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i +++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.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,25 +20,20 @@ * Boston, MA 02110-1301, USA. */ -#include <vector> - GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper); gr_ofdm_bpsk_mapper_sptr gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, unsigned int bits_per_symbol, - unsigned int fft_length, - const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2); + unsigned int fft_length); + class gr_ofdm_bpsk_mapper : public gr_sync_block { protected: gr_ofdm_bpsk_mapper (unsigned int msgq_limit, unsigned int bits_per_symbol, - unsigned int fft_length, - const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2); + unsigned int fft_length); public: gr_msg_queue_sptr msgq(); diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc index 3973b8374..4eb6626a1 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc @@ -30,28 +30,32 @@ #define VERBOSE 0 #define M_TWOPI (2*M_PI) +#define MAX_NUM_SYMBOLS 1000 gr_ofdm_correlator_sptr 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) + const std::vector<gr_complex> &known_symbol2, + unsigned int max_fft_shift_len) { return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, fft_length, cplen, - known_symbol1, known_symbol2)); + known_symbol1, known_symbol2, + max_fft_shift_len)); } gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int fft_length, unsigned int cplen, const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2) + const std::vector<gr_complex> &known_symbol2, + unsigned int max_fft_shift_len) : gr_block ("ofdm_correlator", 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), d_cplen(cplen), - d_freq_shift_len(5), + d_freq_shift_len(max_fft_shift_len), d_known_symbol1(known_symbol1), d_known_symbol2(known_symbol2), d_coarse_freq(0), @@ -62,16 +66,24 @@ gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int std::vector<gr_complex>::iterator i1, i2; - int i = 0; + unsigned int i = 0, j = 0; gr_complex one(1.0, 0.0); for(i1 = d_known_symbol1.begin(), i2 = d_known_symbol2.begin(); i1 != d_known_symbol1.end(); i1++, i2++) { d_diff_corr_factor[i] = one / ((*i1) * conj(*i2)); i++; } + + d_phase_lut = new gr_complex[(2*d_freq_shift_len+1) * MAX_NUM_SYMBOLS]; + for(i = 0; i <= 2*d_freq_shift_len; i++) { + for(j = 0; j < MAX_NUM_SYMBOLS; j++) { + d_phase_lut[j + i*MAX_NUM_SYMBOLS] = gr_expj(-M_TWOPI*d_cplen/d_fft_length*(i-d_freq_shift_len)*j); + } + } } gr_ofdm_correlator::~gr_ofdm_correlator(void) { + delete [] d_phase_lut; } void @@ -87,7 +99,12 @@ 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); + //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 d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count]; } bool @@ -132,14 +149,17 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr d_snr_est = 10*log10(fabs(h_sqrd.real()/h_sqrd.imag())); } +#if VERBOSE printf("CORR: Found, bin %d\tSNR Est %f dB\tcorr power fraction %f\n", search_delta, d_snr_est, h_sqrd.real()/power); +#endif + // search_delta,10*log10(h_sqrd.real()/fabs(h_sqrd.imag())),h_sqrd.real()/power); break; } else { if(search_delta <= 0) - search_delta = (-search_delta) + 1; + search_delta = (-search_delta) + 2; else search_delta = -search_delta; } @@ -161,10 +181,6 @@ gr_ofdm_correlator::calculate_equalizer(const gr_complex *previous, const gr_com d_hestimate[i] = 0.5F * (d_known_symbol1[i] / previous[i+zeros_on_left+d_coarse_freq] + d_known_symbol2[i] / (coarse_freq_comp(d_coarse_freq,1)* current[i+zeros_on_left+d_coarse_freq])); - -#if VERBOSE - fprintf(stderr, "%f %f ", d_hestimate[i].real(), d_hestimate[i].imag()); -#endif } #if VERBOSE fprintf(stderr, "\n"); diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h index 44a6847af..36aa1f0b6 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h +++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h @@ -34,7 +34,8 @@ gr_ofdm_correlator_sptr 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); + const std::vector<gr_complex> &known_symbol2, + unsigned int max_fft_shift_len=4); /*! * \brief take a vector of complex constellation points in from an FFT @@ -65,18 +66,21 @@ class gr_ofdm_correlator : public gr_block * 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. + * \param max_fft_shift_len Set's the maximum distance you can look between bins for correlation */ friend gr_ofdm_correlator_sptr 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); + const std::vector<gr_complex> &known_symbol2, + unsigned int max_fft_shift_len); protected: gr_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); + const std::vector<gr_complex> &known_symbol2, + unsigned int max_fft_shift_len); private: unsigned char slicer(gr_complex x); @@ -96,6 +100,8 @@ class gr_ofdm_correlator : public gr_block unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction float d_snr_est; // !< an estimation of the signal to noise ratio + gr_complex *d_phase_lut; // !< look-up table for coarse frequency compensation + void forecast(int noutput_items, gr_vector_int &ninput_items_required); public: diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i index 40f9f83ff..700faaa09 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i +++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i @@ -29,7 +29,8 @@ 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); + const std::vector<gr_complex> &known_symbol2, + unsigned int max_fft_shift_len=4); class gr_ofdm_correlator : public gr_sync_decimator { @@ -38,7 +39,8 @@ class gr_ofdm_correlator : public gr_sync_decimator unsigned int fft_length, unsigned int cplen, const std::vector<gr_complex> &known_symbol1, - const std::vector<gr_complex> &known_symbol2); + const std::vector<gr_complex> &known_symbol2, + unsigned int max_fft_shift_len); public: float snr() { return d_snr_est; } 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 acaf1258b..c04aca3d7 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc @@ -79,6 +79,14 @@ 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) { @@ -101,23 +109,56 @@ unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in, return bytes_produced; } +unsigned int gr_ofdm_frame_sink::qpsk_demapper(const gr_complex *in, + unsigned char *out) +{ + 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 |= qpsk_slicer(in[i++]) << (d_byte_offset); + d_byte_offset += 2; + } + + if(d_byte_offset == 8) { + out[bytes_produced++] = d_partial_byte; + d_byte_offset = 0; + d_partial_byte = 0; + } + } + + return bytes_produced; +} gr_ofdm_frame_sink_sptr -gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers) +gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers, + const std::string &mod) { - return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers)); + return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers, mod)); } -gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int 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_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_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/8.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."); + } enter_search(); } @@ -134,15 +175,15 @@ gr_ofdm_frame_sink::work (int noutput_items, { const gr_complex *in = (const gr_complex *) input_items[0]; const char *sig = (const char *) input_items[1]; - int count_tones=0, count_items=0; unsigned int j = 0; unsigned int bytes=0; if (VERBOSE) fprintf(stderr,">>> Entering state machine\n"); - bytes = bpsk_demapper(&in[0], d_bytes_out); - + //bytes = bpsk_demapper(&in[0], d_bytes_out); + bytes = (this->*d_demapper)(&in[0], d_bytes_out); + switch(d_state) { case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt @@ -155,12 +196,13 @@ gr_ofdm_frame_sink::work (int noutput_items, break; case STATE_HAVE_SYNC: - if(sig[0]) - printf("ERROR -- Found SYNC in HAVE_SYNC\n"); - if (VERBOSE) + if (VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_SYNC\n"); fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", d_headerbytelen_cnt, d_header); - + } + j = 0; while(j < bytes) { d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF); @@ -174,10 +216,9 @@ gr_ofdm_frame_sink::work (int noutput_items, // we have a full header, check to see if it has been received properly if (header_ok()){ enter_have_header(); - printf("\nPacket Length: %d\n", d_packetlen); - //for(int k=0; k < d_packetlen; k++) - // printf("%02x", d_packet[k]); - //printf("\n"); + + if (VERBOSE) + printf("\nPacket Length: %d\n", d_packetlen); while((j < bytes) && (d_packetlen_cnt < d_packetlen)) { d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; @@ -201,10 +242,11 @@ gr_ofdm_frame_sink::work (int noutput_items, break; case STATE_HAVE_HEADER: - if(sig[0]) - printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen); - if (VERBOSE) - fprintf(stderr,"Packet Build\n"); + if (VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen); + fprintf(stderr,"Packet Build\n"); + } j = 0; while(j < bytes) { 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 d77c76741..8f38abb04 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005,2006 Free Software Foundation, Inc. + * Copyright 2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,30 +30,22 @@ 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); +gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + const std::string &mod); /*! - * \brief Given a stream of bits and access_code flags, assemble packets. - * \ingroup sink - * - * input: stream of bytes from gr_correlate_access_code_bb - * output: none. Pushes assembled packet into target queue - * - * The framer expects a fixed length header of 2 16-bit shorts - * containing the payload length, followed by the payload. If the - * 2 16-bit shorts are not identical, this packet is ignored. Better - * algs are welcome. - * - * The input data consists of bytes that have two bits used. - * Bit 0, the LSB, contains the data bit. - * Bit 1 if set, indicates that the corresponding bit is the - * the first bit of the packet. That is, this bit is the first - * one after the access code. + * \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs + * them into packets, and sends to to a message queue sink. + + * NOTE: The mod input parameter simply chooses a pre-defined demapper/slicer. Eventually, + * we want to be able to pass in a reference to an object to do the demapping and slicing + * for a given modulation type. */ 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); + gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + const std::string &mod); private: enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER}; @@ -78,7 +70,8 @@ class gr_ofdm_frame_sink : public gr_sync_block int d_packetlen_cnt; // how many so far protected: - gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones); + gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + const std::string &mod); void enter_search(); void enter_have_sync(); @@ -94,6 +87,13 @@ class gr_ofdm_frame_sink : public gr_sync_block 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); + 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 b05c8b795..32a0ec9fd 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2006 Free Software Foundation, Inc. + * Copyright 2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,12 +23,14 @@ 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); +gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + const std::string &mod); class gr_ofdm_frame_sink : public gr_sync_block { protected: - gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones); + gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + const std::string &mod); public: ~gr_ofdm_frame_sink(); diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc new file mode 100644 index 000000000..41b23fcd5 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc @@ -0,0 +1,186 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gr_ofdm_insert_preamble.h> +#include <gr_io_signature.h> +#include <stdexcept> +#include <iostream> + +gr_ofdm_insert_preamble_sptr +gr_make_ofdm_insert_preamble(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble) +{ + return gr_ofdm_insert_preamble_sptr(new gr_ofdm_insert_preamble(fft_length, + preamble)); +} + +gr_ofdm_insert_preamble::gr_ofdm_insert_preamble + (int fft_length, + const std::vector<std::vector<gr_complex> > &preamble) + : gr_block("ofdm_insert_preamble", + gr_make_io_signature2(2, 2, + sizeof(gr_complex)*fft_length, + sizeof(char)), + gr_make_io_signature2(1, 2, + sizeof(gr_complex)*fft_length, + sizeof(char))), + d_fft_length(fft_length), + d_preamble(preamble), + d_state(ST_IDLE), + d_nsymbols_output(0), + d_pending_flag(0) +{ + // sanity check preamble symbols + for (size_t i = 0; i < d_preamble.size(); i++){ + if (d_preamble[i].size() != (size_t) d_fft_length) + throw std::invalid_argument("gr_ofdm_insert_preamble: invalid length for preamble symbol"); + } + + enter_idle(); +} + + +gr_ofdm_insert_preamble::~gr_ofdm_insert_preamble() +{ +} + +int +gr_ofdm_insert_preamble::general_work (int noutput_items, + gr_vector_int &ninput_items_v, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + int ninput_items = std::min(ninput_items_v[0], ninput_items_v[1]); + const gr_complex *in_sym = (const gr_complex *) input_items[0]; + const unsigned char *in_flag = (const unsigned char *) input_items[1]; + + gr_complex *out_sym = (gr_complex *) output_items[0]; + unsigned char *out_flag = 0; + if (output_items.size() == 2) + out_flag = (unsigned char *) output_items[1]; + + + int no = 0; // number items output + int ni = 0; // number items read from input + + +#define write_out_flag() \ + do { if (out_flag) \ + out_flag[no] = d_pending_flag; \ + d_pending_flag = 0; \ + } while(0) + + + while (no < noutput_items && ni < ninput_items){ + switch(d_state){ + case ST_IDLE: + if (in_flag[ni] & 0x1) // this is first symbol of new payload + enter_preamble(); + else + ni++; // eat one input symbol + break; + + case ST_PREAMBLE: + assert(in_flag[ni] & 0x1); + if (d_nsymbols_output >= (int) d_preamble.size()){ + // we've output all the preamble + enter_first_payload(); + } + else { + memcpy(&out_sym[no * d_fft_length], + &d_preamble[d_nsymbols_output][0], + d_fft_length*sizeof(gr_complex)); + + write_out_flag(); + no++; + d_nsymbols_output++; + } + break; + + case ST_FIRST_PAYLOAD: + // copy first payload symbol from input to output + memcpy(&out_sym[no * d_fft_length], + &in_sym[ni * d_fft_length], + d_fft_length * sizeof(gr_complex)); + + write_out_flag(); + no++; + ni++; + enter_payload(); + break; + + case ST_PAYLOAD: + if (in_flag[ni] & 0x1){ // this is first symbol of a new payload + enter_preamble(); + break; + } + + // copy a symbol from input to output + memcpy(&out_sym[no * d_fft_length], + &in_sym[ni * d_fft_length], + d_fft_length * sizeof(gr_complex)); + + write_out_flag(); + no++; + ni++; + break; + + default: + std::cerr << "gr_ofdm_insert_preamble: (can't happen) invalid state, resetting\n"; + enter_idle(); + } + } + + consume_each(ni); + return no; +} + +void +gr_ofdm_insert_preamble::enter_idle() +{ + d_state = ST_IDLE; + d_nsymbols_output = 0; + d_pending_flag = 0; +} + +void +gr_ofdm_insert_preamble::enter_preamble() +{ + d_state = ST_PREAMBLE; + d_nsymbols_output = 0; + d_pending_flag = 1; +} + +void +gr_ofdm_insert_preamble::enter_first_payload() +{ + d_state = ST_FIRST_PAYLOAD; +} + +void +gr_ofdm_insert_preamble::enter_payload() +{ + d_state = ST_PAYLOAD; +} diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h new file mode 100644 index 000000000..48622b06d --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h @@ -0,0 +1,102 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GR_OFDM_INSERT_PREAMBLE_H +#define INCLUDED_GR_OFDM_INSERT_PREAMBLE_H + +#include <gr_block.h> +#include <vector> + +class gr_ofdm_insert_preamble; +typedef boost::shared_ptr<gr_ofdm_insert_preamble> gr_ofdm_insert_preamble_sptr; + +gr_ofdm_insert_preamble_sptr +gr_make_ofdm_insert_preamble(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble); + +/*! + * \brief insert "pre-modulated" preamble symbols before each payload. + * + * <pre> + * input 1: stream of vectors of gr_complex [fft_length] + * These are the modulated symbols of the payload. + * + * input 2: stream of char. The LSB indicates whether the corresponding + * symbol on input 1 is the first symbol of the payload or not. + * It's a 1 if the corresponding symbol is the first symbol, + * otherwise 0. + * + * N.B., this implies that there must be at least 1 symbol in the payload. + * + * + * output 1: stream of vectors of gr_complex [fft_length] + * These include the preamble symbols and the payload symbols. + * + * output 2: stream of char. The LSB indicates whether the corresponding + * symbol on input 1 is the first symbol of a packet (i.e., the + * first symbol of the preamble.) It's a 1 if the corresponding + * symbol is the first symbol, otherwise 0. + * </pre> + * + * \param fft_length length of each symbol in samples. + * \param preamble vector of symbols that represent the pre-modulated preamble. + */ + +class gr_ofdm_insert_preamble : public gr_block +{ + friend gr_ofdm_insert_preamble_sptr + gr_make_ofdm_insert_preamble(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble); + +protected: + gr_ofdm_insert_preamble(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble); + +private: + enum state_t { + ST_IDLE, + ST_PREAMBLE, + ST_FIRST_PAYLOAD, + ST_PAYLOAD + }; + + int d_fft_length; + const std::vector<std::vector<gr_complex> > d_preamble; + state_t d_state; + int d_nsymbols_output; + int d_pending_flag; + + void enter_idle(); + void enter_preamble(); + void enter_first_payload(); + void enter_payload(); + + +public: + ~gr_ofdm_insert_preamble(); + + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_GR_OFDM_INSERT_PREAMBLE_H */ diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i new file mode 100644 index 000000000..183e91b0e --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,ofdm_insert_preamble); + +gr_ofdm_insert_preamble_sptr +gr_make_ofdm_insert_preamble(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble); + + +class gr_ofdm_insert_preamble : public gr_block +{ + protected: + gr_ofdm_insert_preamble(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble); +}; diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc new file mode 100644 index 000000000..8e774fe76 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc @@ -0,0 +1,249 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_ofdm_qam_mapper.h> +#include <gr_io_signature.h> +#include <stdexcept> + +gr_ofdm_qam_mapper_sptr +gr_make_ofdm_qam_mapper (unsigned int msgq_limit, + unsigned int occupied_carriers, unsigned int fft_length, + int m) +{ + return gr_ofdm_qam_mapper_sptr (new gr_ofdm_qam_mapper (msgq_limit, occupied_carriers, fft_length, m)); +} + +// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet +gr_ofdm_qam_mapper::gr_ofdm_qam_mapper (unsigned int msgq_limit, + unsigned int occupied_carriers, unsigned int fft_length, + int m) + : gr_sync_block ("ofdm_qam_mapper", + gr_make_io_signature (0, 0, 0), + gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))), + 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_mod_order(m) +{ + if (!(d_occupied_carriers <= d_fft_length)) + throw std::invalid_argument("gr_ofdm_qam_mapper: occupied carriers must be <= fft_length"); + + bool ok = false; + if(m == 2) { + ok = true; + } + if(m == 4) { + ok = true; + } + if(m == 16) { + ok = true; + } + if(m == 64) { + ok = true; + } + if(m == 256) { + ok = true; + } + + if(!ok) + throw std::invalid_argument("Order M must be [2, 4, 16, 64, 256]"); + + make_constellation(); +} + +gr_ofdm_qam_mapper::~gr_ofdm_qam_mapper(void) +{ +} + +void gr_ofdm_qam_mapper::make_constellation() +{ + int i = 0, j = 0, ii = 0, jj = 0; + // number of bits/symbol (log2(M)) + int k = (int)(log10(d_mod_order) / log10(2.0)); + + int a, b; + float re, im; + float coeff = 1; + std::vector<int> bits_i, bits_q; + + int rr = 0; + int ss = 0; + int ll = bits_i.size(); + + for(i=0; i < d_mod_order; i++) { + a = (i & (0x01 << (k-1))) >> (k-1); + b = (i & (0x01 << (k-2))) >> (k-2); + for(j=2; j < k; j+=2) { + bits_i.push_back( (i & (0x01 << (k-j-1))) >> (k-j-1)); + bits_q.push_back( (i & (0x01 << (k-(j+1)-1))) >> (k-(j+1)-1)); + } + + ss = 0; + ll = bits_i.size(); + for(ii = 0; ii < ll; ii++) { + rr = 0; + for(jj = 0; jj < (ll-ii); jj++) { + rr = abs(bits_i[jj] - rr); + } + ss += rr * pow(2.0, ii+1.0); + } + re = (2.0*a-1.0)*(ss+1.0); + + ss = 0; + ll = bits_q.size(); + for(ii = 0; ii < ll; ii++) { + rr = 0; + for(jj = 0; jj < (ll-ii); jj++) { + rr = abs(bits_q[jj] - rr); + } + ss += rr*pow(2.0, ii+1.0); + } + im = (2.0*b-1.0)*(ss+1.0); + + a = std::max(re, im); + if(a > coeff) { + coeff = a; + } + d_constellation_map.push_back(gr_complex(re, im)); + } + + d_constellation_map[0] = gr_complex(-3, -3); + d_constellation_map[1] = gr_complex(-3, -1); + d_constellation_map[2] = gr_complex(-3, 1); + d_constellation_map[3] = gr_complex(-3, 3); + d_constellation_map[4] = gr_complex(-1, -3); + d_constellation_map[5] = gr_complex(-1, -1); + d_constellation_map[6] = gr_complex(-1, 1); + d_constellation_map[7] = gr_complex(-1, 3); + d_constellation_map[8] = gr_complex(1, -3); + d_constellation_map[9] = gr_complex(1, -1); + d_constellation_map[10] = gr_complex(1, 1); + d_constellation_map[11] = gr_complex(1, 3); + d_constellation_map[12] = gr_complex(3, -3); + d_constellation_map[13] = gr_complex(3, -1); + d_constellation_map[14] = gr_complex(3, 1); + d_constellation_map[15] = gr_complex(3, 3); + + coeff = sqrt(31.0)/2.0; + for(i = 0; i < d_constellation_map.size(); i++) { + d_constellation_map[i] /= coeff; + printf("const[%d]: %f + j%f\n", i, d_constellation_map[i].real(), d_constellation_map[i].imag()); + } +} + +static float +randombit() +{ + int r = rand()&1; + return (float)(-1 + 2*r); +} + +int +gr_ofdm_qam_mapper::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 QAM 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; + while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) { + unsigned char bit0 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01; + d_bit_offset++; + + unsigned char bit1 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01; + d_bit_offset++; + + unsigned char bit2 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01; + d_bit_offset++; + + unsigned char bit3 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01; + d_bit_offset++; + + unsigned char bit = (bit0 << 3) | (bit1 << 2) | (bit2 << 1) | (bit3 << 0); + + out[i + zeros_on_left] = d_constellation_map[bit]; + i++; + 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()) { + while(i < d_occupied_carriers) { // finish filling out the symbol + out[i + zeros_on_left] = d_constellation_map[rand() & 0x0F]; + 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_qam_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h new file mode 100644 index 000000000..2b2a8e39f --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_OFDM_QAM_MAPPER_H +#define INCLUDED_GR_OFDM_QAM_MAPPER_H + + +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> + +class gr_ofdm_qam_mapper; +typedef boost::shared_ptr<gr_ofdm_qam_mapper> gr_ofdm_qam_mapper_sptr; + +gr_ofdm_qam_mapper_sptr +gr_make_ofdm_qam_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length, + int m=4); + +/*! + * \brief take a message in and map to a vector of complex + * constellation points suitable for IFFT input to be used in an ofdm + * modulator. Simple QAM version. + */ + +class gr_ofdm_qam_mapper : public gr_sync_block +{ + friend gr_ofdm_qam_mapper_sptr + gr_make_ofdm_qam_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length, + int m); + protected: + gr_ofdm_qam_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length, + int m); + + private: + 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; + + int d_mod_order; + std::vector<gr_complex> d_constellation_map; + + void make_constellation(); + + public: + ~gr_ofdm_qam_mapper(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_qam_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i new file mode 100644 index 000000000..84fd0851c --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,ofdm_qam_mapper); + +gr_ofdm_qam_mapper_sptr +gr_make_ofdm_qam_mapper (unsigned int msgq_limit, + unsigned int bits_per_symbol, + unsigned int fft_length, + int m=16); + + +class gr_ofdm_qam_mapper : public gr_sync_block +{ + protected: + gr_ofdm_qam_mapper (unsigned int msgq_limit, + unsigned int bits_per_symbol, + unsigned int fft_length, + int m); + + 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 new file mode 100644 index 000000000..cad14c706 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc @@ -0,0 +1,141 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_ofdm_qpsk_mapper.h> +#include <gr_io_signature.h> +#include <stdexcept> + +gr_ofdm_qpsk_mapper_sptr +gr_make_ofdm_qpsk_mapper (unsigned int msgq_limit, + unsigned int occupied_carriers, unsigned int fft_length) +{ + return gr_ofdm_qpsk_mapper_sptr (new gr_ofdm_qpsk_mapper (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_qpsk_mapper::gr_ofdm_qpsk_mapper (unsigned int msgq_limit, + unsigned int occupied_carriers, unsigned int fft_length) + : gr_sync_block ("ofdm_qpsk_mapper", + gr_make_io_signature (0, 0, 0), + gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))), + 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) +{ + if (!(d_occupied_carriers <= d_fft_length)) + throw std::invalid_argument("gr_ofdm_qpsk_mapper: occupied carriers must be <= fft_length"); +} + +gr_ofdm_qpsk_mapper::~gr_ofdm_qpsk_mapper(void) +{ +} + +static gr_complex +randombit() +{ + int r1 = rand()&1; + int r2 = rand()&1; + return gr_complex((0.707)*(-1 + 2*r1),(0.707)*(-1 + 2*r2)); +} + +int +gr_ofdm_qpsk_mapper::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 QPSK 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; + while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) { + unsigned char bit0 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01; + d_bit_offset++; + + 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)) ); + i++; + 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()) { + while(i < d_occupied_carriers) { // finish filling out the symbol + out[i + zeros_on_left] = randombit(); + 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_qpsk_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h new file mode 100644 index 000000000..93bd8f987 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_OFDM_QPSK_MAPPER_H +#define INCLUDED_GR_OFDM_QPSK_MAPPER_H + + +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> + +class gr_ofdm_qpsk_mapper; +typedef boost::shared_ptr<gr_ofdm_qpsk_mapper> gr_ofdm_qpsk_mapper_sptr; + +gr_ofdm_qpsk_mapper_sptr +gr_make_ofdm_qpsk_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length); + +/*! + * \brief take a message in and map to a vector of complex + * constellation points suitable for IFFT input to be used in an ofdm + * modulator. Simple QPSK version. + */ + +class gr_ofdm_qpsk_mapper : public gr_sync_block +{ + friend gr_ofdm_qpsk_mapper_sptr + gr_make_ofdm_qpsk_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length); + protected: + gr_ofdm_qpsk_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length); + + private: + 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; + + public: + ~gr_ofdm_qpsk_mapper(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_qpsk_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i new file mode 100644 index 000000000..5f19f08f3 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,ofdm_qpsk_mapper); + +gr_ofdm_qpsk_mapper_sptr +gr_make_ofdm_qpsk_mapper (unsigned int msgq_limit, + unsigned int bits_per_symbol, + unsigned int fft_length); + + +class gr_ofdm_qpsk_mapper : public gr_sync_block +{ + protected: + gr_ofdm_qpsk_mapper (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_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc index 5f5a91fd2..1ca738a29 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc @@ -67,7 +67,7 @@ gr_ofdm_sampler::general_work (int noutput_items, int found=0; - unsigned int i=d_fft_length-1; + int i=d_fft_length-1; while(!found && i<std::min(ninput_items[0],ninput_items[1]) ) if(trigger[i]) @@ -77,7 +77,7 @@ gr_ofdm_sampler::general_work (int noutput_items, if(found) { assert(i-d_fft_length+1 >= 0); - for(unsigned int j=i-d_fft_length+1;j<=i;j++) + for(int j=i-d_fft_length+1;j<=i;j++) *optr++ = iptr[j]; consume_each(i-d_fft_length+2); //printf("OFDM Sampler found: ninput_items: %d/%d noutput_items: %d consumed: %d found: %d\n", diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.cc b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc new file mode 100644 index 000000000..6b0535e18 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc @@ -0,0 +1,74 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_regenerate_bb.h> +#include <gr_io_signature.h> + +gr_regenerate_bb_sptr +gr_make_regenerate_bb (int period, unsigned int max_regen) +{ + return gr_regenerate_bb_sptr (new gr_regenerate_bb (period, max_regen)); +} + +gr_regenerate_bb::gr_regenerate_bb (int period, unsigned int max_regen) + : gr_sync_block ("regenerate_bb", + gr_make_io_signature (1, 1, sizeof (char)), + gr_make_io_signature (1, 1, sizeof (char))), + d_period(period), + d_max_regen(max_regen), + d_regen_count(0) +{ +} + +int +gr_regenerate_bb::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const char *iptr = (const char *) input_items[0]; + char *optr = (char *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + optr[i] = 0; + + if(iptr[i] == 1) { + d_countdown = d_period; + optr[i] = 1; + d_regen_count = 0; + } + + if(d_regen_count <= d_max_regen) { + d_countdown--; + + if(d_countdown == 0) { + optr[i] = 1; + d_countdown = d_period; + d_regen_count++; + } + } + } + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.h b/gnuradio-core/src/lib/general/gr_regenerate_bb.h new file mode 100644 index 000000000..446e658ae --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_REGENERATE_BB_H +#define INCLUDED_GR_REGENERATE_BB_H + +#include <gr_sync_block.h> + +class gr_regenerate_bb; +typedef boost::shared_ptr<gr_regenerate_bb> gr_regenerate_bb_sptr; + +gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500); + +/*! + * \brief Detect the peak of a signal + * \ingroup block + * + * If a peak is detected, this block outputs a 1 repeated every period samples + * until reset by detection of another 1 on the input + */ +class gr_regenerate_bb : public gr_sync_block +{ + friend gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen); + + gr_regenerate_bb (int period, unsigned int max_regen); + + private: + int d_period; + int d_countdown; + unsigned int d_max_regen; + unsigned int d_regen_count; + + public: + + 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_regenerate_bb.i b/gnuradio-core/src/lib/general/gr_regenerate_bb.i new file mode 100644 index 000000000..6afd84d8d --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.i @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,regenerate_bb) + +gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500); + +class gr_regenerate_bb : public gr_sync_block +{ + private: + gr_regenerate_bb (int period, unsigned int max_regen); +}; |