From c7dbfcc7d78275f76d8c2a8ef21e3100721874be Mon Sep 17 00:00:00 2001 From: trondeau Date: Mon, 4 Jun 2007 16:08:44 +0000 Subject: merge ordm/receiver branch -r5574:5659. Reworks OFDM receiver with refactored OFDM blocks. A few bug fixes for other blocks have also been slipped in. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5661 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/Makefile.am | 13 +- gnuradio-core/src/lib/general/general.i | 6 +- gnuradio-core/src/lib/general/gr_conjugate_cc.cc | 27 ++- gnuradio-core/src/lib/general/gr_delay.cc | 2 +- gnuradio-core/src/lib/general/gr_dpll_bb.cc | 84 ++++++++ gnuradio-core/src/lib/general/gr_dpll_bb.h | 57 +++++ gnuradio-core/src/lib/general/gr_dpll_bb.i | 31 +++ gnuradio-core/src/lib/general/gr_dpll_ff.cc | 86 -------- gnuradio-core/src/lib/general/gr_dpll_ff.h | 59 ------ gnuradio-core/src/lib/general/gr_dpll_ff.i | 33 --- .../src/lib/general/gr_ofdm_bpsk_mapper.cc | 168 ++++++++------- .../src/lib/general/gr_ofdm_bpsk_mapper.h | 49 +++-- .../src/lib/general/gr_ofdm_bpsk_mapper.i | 29 +-- .../src/lib/general/gr_ofdm_correlator.cc | 54 +++-- gnuradio-core/src/lib/general/gr_ofdm_correlator.h | 34 +-- gnuradio-core/src/lib/general/gr_ofdm_correlator.i | 16 +- .../src/lib/general/gr_ofdm_frame_sink.cc | 235 +++++++++++++++++++++ gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h | 105 +++++++++ gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i | 35 +++ gnuradio-core/src/lib/general/gr_ofdm_sampler.cc | 6 +- gnuradio-core/src/lib/general/gr_skiphead.cc | 76 ++++--- gnuradio-core/src/lib/general/gr_skiphead.h | 26 ++- gnuradio-core/src/lib/general/gr_skiphead.i | 14 +- gnuradio-core/src/lib/general/gr_stream_mux.cc | 158 ++++---------- gnuradio-core/src/lib/general/gr_stream_mux.h | 16 +- 25 files changed, 888 insertions(+), 531 deletions(-) create mode 100644 gnuradio-core/src/lib/general/gr_dpll_bb.cc create mode 100644 gnuradio-core/src/lib/general/gr_dpll_bb.h create mode 100644 gnuradio-core/src/lib/general/gr_dpll_bb.i delete mode 100644 gnuradio-core/src/lib/general/gr_dpll_ff.cc delete mode 100644 gnuradio-core/src/lib/general/gr_dpll_ff.h delete mode 100644 gnuradio-core/src/lib/general/gr_dpll_ff.i create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i (limited to 'gnuradio-core/src/lib/general') diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index c76130039..d774baa1c 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -63,7 +63,7 @@ libgeneral_la_SOURCES = \ gr_diff_decoder_bb.cc \ gr_diff_encoder_bb.cc \ gr_diff_phasor_cc.cc \ - gr_dpll_ff.cc \ + gr_dpll_bb.cc \ gr_fake_channel_coder_pp.cc \ gr_fast_atan2f.cc \ gr_feedforward_agc_cc.cc \ @@ -102,6 +102,7 @@ libgeneral_la_SOURCES = \ gr_ofdm_mapper_bcv.cc \ gr_ofdm_bpsk_demapper.cc \ gr_ofdm_bpsk_mapper.cc \ + gr_ofdm_frame_sink.cc \ gr_ofdm_sampler.cc \ gr_pa_2x2_phase_combiner.cc \ gr_packet_sink.cc \ @@ -197,7 +198,7 @@ grinclude_HEADERS = \ gr_deinterleave.h \ gr_delay.h \ gr_diff_phasor_cc.h \ - gr_dpll_ff.h \ + gr_dpll_bb.h \ gr_expj.h \ gr_fake_channel_coder_pp.h \ gr_feedforward_agc_cc.h \ @@ -240,7 +241,8 @@ grinclude_HEADERS = \ gr_ofdm_mapper_bcv.h \ gr_ofdm_bpsk_mapper.h \ gr_ofdm_bpsk_demapper.h \ - gr_ofdm_sampler.h \ + gr_ofdm_frame_sink.h \ + gr_ofdm_sampler.h \ gr_pa_2x2_phase_combiner.h \ gr_packet_sink.h \ gr_phase_modulator_fc.h \ @@ -342,7 +344,7 @@ swiginclude_HEADERS = \ gr_diff_decoder_bb.i \ gr_diff_encoder_bb.i \ gr_diff_phasor_cc.i \ - gr_dpll_ff.i \ + gr_dpll_bb.i \ gr_deinterleave.i \ gr_delay.i \ gr_fake_channel_coder_pp.i \ @@ -379,7 +381,8 @@ swiginclude_HEADERS = \ gr_ofdm_mapper_bcv.i \ gr_ofdm_bpsk_demapper.i \ gr_ofdm_bpsk_mapper.i \ - gr_ofdm_sampler.i \ + gr_ofdm_frame_sink.i \ + gr_ofdm_sampler.i \ gr_pa_2x2_phase_combiner.i \ gr_packet_sink.i \ gr_phase_modulator_fc.i \ diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 64144a05a..1fdb4239a 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -84,7 +84,7 @@ #include #include #include -#include +#include #include #include #include @@ -97,6 +97,7 @@ #include #include #include +#include #include #include #include @@ -186,7 +187,7 @@ %include "gr_packet_sink.i" %include "gr_lms_dfe_cc.i" %include "gr_lms_dfe_ff.i" -%include "gr_dpll_ff.i" +%include "gr_dpll_bb.i" %include "gr_pll_freqdet_cf.i" %include "gr_pll_refout_cc.i" %include "gr_pll_carriertracking_cc.i" @@ -199,6 +200,7 @@ %include "gr_ofdm_cyclic_prefixer.i" %include "gr_ofdm_bpsk_demapper.i" %include "gr_ofdm_bpsk_mapper.i" +%include "gr_ofdm_frame_sink.i" %include "gr_ofdm_sampler.i" %include "gr_costas_loop_cc.i" %include "gr_pa_2x2_phase_combiner.i" diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc index 0a5b3790e..453c6d338 100644 --- a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc +++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc @@ -53,19 +53,24 @@ gr_conjugate_cc::work (int noutput_items, int size = noutput_items; while (size >= 8){ - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; + optr[0] = conj(iptr[0]); + optr[1] = conj(iptr[1]); + optr[2] = conj(iptr[2]); + optr[3] = conj(iptr[3]); + optr[4] = conj(iptr[4]); + optr[5] = conj(iptr[5]); + optr[6] = conj(iptr[6]); + optr[7] = conj(iptr[7]); size -= 8; + optr += 8; + iptr += 8; + } + + while (size-- > 0) { + *optr = conj(*iptr); + iptr++; + optr++; } - while (size-- > 0) - *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++; - return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc index 12c50e4b6..89ab3ce0e 100644 --- a/gnuradio-core/src/lib/general/gr_delay.cc +++ b/gnuradio-core/src/lib/general/gr_delay.cc @@ -56,7 +56,7 @@ gr_delay::work (int noutput_items, iptr = (const char *) input_items[i]; optr = (char *) output_items[i]; - memcpy(optr, iptr + delay()*d_itemsize, noutput_items*d_itemsize); + memcpy(optr, iptr, noutput_items*d_itemsize); } return noutput_items; diff --git a/gnuradio-core/src/lib/general/gr_dpll_bb.cc b/gnuradio-core/src/lib/general/gr_dpll_bb.cc new file mode 100644 index 000000000..d5b726528 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_dpll_bb.cc @@ -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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +gr_dpll_bb_sptr +gr_make_dpll_bb (float period, float gain) +{ + return gr_dpll_bb_sptr (new gr_dpll_bb (period, gain)); +} + +gr_dpll_bb::gr_dpll_bb (float period, float gain) + : gr_sync_block ("dpll_bb", + gr_make_io_signature (1, 1, sizeof (char)), + gr_make_io_signature (1, 1, sizeof (char))), + d_restart(0),d_pulse_phase(0) +{ + d_pulse_frequency = 1.0/period; + d_gain = gain; + d_decision_threshold = 1.0 - 0.5*d_pulse_frequency; +#if 1 + fprintf(stderr,"frequency = %f period = %f gain = %f threshold = %f\n", + d_pulse_frequency, + period, + d_gain, + d_decision_threshold); +#endif + set_history(1); // so we can look behind us +} + +int +gr_dpll_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) { + if (d_restart == 0) { + d_pulse_phase = 1; + } else { + if (d_pulse_phase > 0.5) d_pulse_phase += d_gain*(1.0-d_pulse_phase); + else d_pulse_phase -= d_gain*d_pulse_phase; + } + d_restart = 3; + } + if (d_pulse_phase > d_decision_threshold) { + d_pulse_phase -= 1.0; + if (d_restart > 0) { + d_restart -= 1; + optr[i] = 1; + } + } + d_pulse_phase += d_pulse_frequency; + } + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_dpll_bb.h b/gnuradio-core/src/lib/general/gr_dpll_bb.h new file mode 100644 index 000000000..c80612bc5 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_dpll_bb.h @@ -0,0 +1,57 @@ +/* -*- 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_DPLL_BB_H +#define INCLUDED_GR_DPLL_BB_H + +#include + +class gr_dpll_bb; +typedef boost::shared_ptr gr_dpll_bb_sptr; + +gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain); + +/*! + * \brief Detect the peak of a signal + * \ingroup block + * + * If a peak is detected, this block outputs a 1, + * or it outputs 0's. + */ +class gr_dpll_bb : public gr_sync_block +{ + friend gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain); + + gr_dpll_bb (float period, float gain); + + private: + unsigned char d_restart; + float d_pulse_phase, d_pulse_frequency,d_gain,d_decision_threshold; + + 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_dpll_bb.i b/gnuradio-core/src/lib/general/gr_dpll_bb.i new file mode 100644 index 000000000..ae95e2dfb --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_dpll_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,dpll_bb) + + gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain); + +class gr_dpll_bb : public gr_sync_block +{ + private: + gr_dpll_bb (float period, float gain); +}; diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.cc b/gnuradio-core/src/lib/general/gr_dpll_ff.cc deleted file mode 100644 index ae868fce5..000000000 --- a/gnuradio-core/src/lib/general/gr_dpll_ff.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- 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. - */ - -// WARNING: this file is machine generated. Edits will be over written - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -gr_dpll_ff_sptr -gr_make_dpll_ff (float period, float gain) -{ - return gr_dpll_ff_sptr (new gr_dpll_ff (period, gain)); -} - -gr_dpll_ff::gr_dpll_ff (float period, float gain) - : gr_sync_block ("dpll_ff", - gr_make_io_signature (1, 1, sizeof (float)), - gr_make_io_signature (1, 1, sizeof (float))), - d_restart(0),d_pulse_phase(0) -{ - d_pulse_frequency = 1.0/period; - d_gain = gain; - d_decision_threshold = 1.0 - 0.5*d_pulse_frequency; -#if 1 - fprintf(stderr,"frequency = %f period = %f gain = %f threshold = %f\n", - d_pulse_frequency, - period, - d_gain, - d_decision_threshold); -#endif - set_history(1); // so we can look behind us -} - -int -gr_dpll_ff::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - float *iptr = (float *) input_items[0]; - float *optr = (float *) output_items[0]; - - for (int i = 0; i < noutput_items; i++){ - optr[i]= (float)0; - if(iptr[i] ==(float)1) { - if (d_restart == 0) { - d_pulse_phase = 1; - } else { - if (d_pulse_phase > 0.5) d_pulse_phase += d_gain*(1.0-d_pulse_phase); - else d_pulse_phase -= d_gain*d_pulse_phase; - } - d_restart = 3; - } - if (d_pulse_phase > d_decision_threshold) { - d_pulse_phase -= 1.0; - if (d_restart > 0) { - d_restart -= 1; - optr[i] = (float)1; - } - } - d_pulse_phase += d_pulse_frequency; - } - return noutput_items; -} diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.h b/gnuradio-core/src/lib/general/gr_dpll_ff.h deleted file mode 100644 index 1de1efa85..000000000 --- a/gnuradio-core/src/lib/general/gr_dpll_ff.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- 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. - */ - -// WARNING: this file is machine generated. Edits will be over written - -#ifndef INCLUDED_GR_DPLL_FF_H -#define INCLUDED_GR_DPLL_FF_H - -#include - -class gr_dpll_ff; -typedef boost::shared_ptr gr_dpll_ff_sptr; - -gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain); - -/*! - * \brief Detect the peak of a signal - * \ingroup block - * - * If a peak is detected, this block outputs a 1, - * or it outputs 0's. - */ -class gr_dpll_ff : public gr_sync_block -{ - friend gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain); - - gr_dpll_ff (float period, float gain); - - private: - unsigned char d_restart; - float d_pulse_phase, d_pulse_frequency,d_gain,d_decision_threshold; - - 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_dpll_ff.i b/gnuradio-core/src/lib/general/gr_dpll_ff.i deleted file mode 100644 index 9606fba52..000000000 --- a/gnuradio-core/src/lib/general/gr_dpll_ff.i +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- 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. - */ - -// WARNING: this file is machine generated. Edits will be over written - -GR_SWIG_BLOCK_MAGIC(gr,dpll_ff) - - gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain); - -class gr_dpll_ff : public gr_sync_block -{ - private: - gr_dpll_ff (float period, float gain); -}; 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 df4632398..f0b52c325 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,30 +29,32 @@ #include gr_ofdm_bpsk_mapper_sptr -gr_make_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen, - std::vector known_symbol1, std::vector known_symbol2) +gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, + unsigned int occupied_carriers, unsigned int fft_length, + const std::vector &known_symbol1, + const std::vector &known_symbol2) { - return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (mtu, occupied_carriers, vlen, + return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length, known_symbol1, known_symbol2)); } -gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen, - std::vector known_symbol1, - std::vector known_symbol2) - : gr_block ("ofdm_bpsk_mapper", - gr_make_io_signature (1, 1, 2*sizeof(int) + sizeof(unsigned char)*mtu), - gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen)), - d_mtu(mtu), +// 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 &known_symbol1, + const std::vector &known_symbol2) + : 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))), + d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false), d_occupied_carriers(occupied_carriers), - d_vlen(vlen), - d_packet_offset(0), + d_fft_length(fft_length), d_bit_offset(0), d_header_sent(0), d_known_symbol1(known_symbol1), d_known_symbol2(known_symbol2) - { - assert(d_occupied_carriers < d_vlen); + assert(d_occupied_carriers <= d_fft_length); assert(d_occupied_carriers == d_known_symbol1.size()); assert(d_occupied_carriers == d_known_symbol2.size()); } @@ -61,99 +63,101 @@ gr_ofdm_bpsk_mapper::~gr_ofdm_bpsk_mapper(void) { } -void -gr_ofdm_bpsk_mapper::forecast (int noutput_items, gr_vector_int &ninput_items_required) +float randombit() { - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = 1; + int r = rand()&1; + return (float)(-1 + 2*r); } int -gr_ofdm_bpsk_mapper::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +gr_ofdm_bpsk_mapper::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { - const gr_frame *in = (const gr_frame *) input_items[0]; gr_complex *out = (gr_complex *)output_items[0]; unsigned int i=0; - unsigned int num_symbols = 0, pkt_length; + 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); - pkt_length = in[0].length; - - std::vector::iterator ks_itr; - if(d_header_sent == 0) { - ks_itr = d_known_symbol1.begin(); - } - else if(d_header_sent == 1) { - ks_itr = d_known_symbol2.begin(); + if(d_eof) { + return -1; } - if(d_header_sent < 2) { - // Add training symbols here - for(i=0; i < (ceil((d_vlen - d_occupied_carriers)/2.0)); i++) { - out[i] = gr_complex(0,0); + if(!d_msg) { + d_msg = d_msgq->delete_head(); // block, waiting for a message + d_msg_offset = 0; + d_bit_offset = 0; + d_header_sent = 0; + + if((d_msg->length() == 0) && (d_msg->type() == 1)) { + d_msg.reset(); + return -1; } - for(;i> (d_bit_offset++)) & 0x01; - out[i++] = gr_complex(-1+2*(bit)); - if(d_bit_offset == 8) { - d_bit_offset = 0; - d_packet_offset++; - } + 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)); + i++; + d_bit_offset++; + if(d_bit_offset == 8) { + d_bit_offset = 0; + d_msg_offset++; } + } - // Ran out of data to put in symbols - if(d_packet_offset == pkt_length) { - while(i < d_vlen-zeros_on_right) { - out[i++] = gr_complex(0,0); - } - - d_packet_offset = 0; - assert(d_bit_offset == 0); - num_symbols++; - d_header_sent = 0; - consume_each(1); - return num_symbols; + // 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] = gr_complex(randombit(),0); + i++; } - - // Ran out of space in symbol - out += d_vlen; - num_symbols++; + + if (d_msg->type() == 1) // type == 1 sets EOF + d_eof = true; + d_msg.reset(); // finished packet, free message + + assert(d_bit_offset == 0); + return 1; // produced one symbol } - consume_each(0); - return num_symbols; + + 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 1ae6c75d8..41b2f5bed 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h +++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h @@ -24,17 +24,19 @@ #define INCLUDED_GR_OFDM_BPSK_MAPPER_H -#include -#include +#include +#include +#include #include class gr_ofdm_bpsk_mapper; typedef boost::shared_ptr gr_ofdm_bpsk_mapper_sptr; gr_ofdm_bpsk_mapper_sptr -gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen, - std::vector known_symbol1, - std::vector known_symbol2); +gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length, + const std::vector &known_symbol1, + const std::vector &known_symbol2); /*! * \brief take a stream of bytes in and map to a vector of complex @@ -42,35 +44,40 @@ gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int * modulator. Simple BPSK version. */ -class gr_ofdm_bpsk_mapper : public gr_block +class gr_ofdm_bpsk_mapper : public gr_sync_block { friend gr_ofdm_bpsk_mapper_sptr - gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen, - std::vector known_symbol1, - std::vector known_symbol2); + gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length, + const std::vector &known_symbol1, + const std::vector &known_symbol2); protected: - gr_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen, - std::vector known_symbol1, - std::vector known_symbol2); + gr_ofdm_bpsk_mapper (unsigned msgq_limit, + unsigned occupied_carriers, unsigned int fft_length, + const std::vector &known_symbol1, + const std::vector &known_symbol2); private: - unsigned int d_mtu; + 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_vlen; - unsigned int d_packet_offset; + unsigned int d_fft_length; unsigned int d_bit_offset; unsigned int d_header_sent; std::vector d_known_symbol1, d_known_symbol2; - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - public: ~gr_ofdm_bpsk_mapper(void); - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + + 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); }; 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 12b86dc33..d0094062a 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i +++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i @@ -22,27 +22,28 @@ #include -GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper) +GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper); gr_ofdm_bpsk_mapper_sptr -gr_make_ofdm_bpsk_mapper (unsigned int mtu, +gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, unsigned int bits_per_symbol, - unsigned int vlen, - std::vector known_symbol1, - std::vector known_symbol2); + unsigned int fft_length, + const std::vector &known_symbol1, + const std::vector &known_symbol2); -class gr_ofdm_bpsk_mapper : public gr_block +class gr_ofdm_bpsk_mapper : public gr_sync_block { protected: - gr_ofdm_bpsk_mapper (unsigned int mtu, + gr_ofdm_bpsk_mapper (unsigned int msgq_limit, unsigned int bits_per_symbol, - unsigned int vlen, - std::vector known_symbol1, - std::vector known_symbol2); + unsigned int fft_length, + const std::vector &known_symbol1, + const std::vector &known_symbol2); public: - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + 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_correlator.cc b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc index 21fbc6b3e..3973b8374 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc @@ -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 * @@ -26,29 +26,30 @@ #include #include +#include #define VERBOSE 0 #define M_TWOPI (2*M_PI) gr_ofdm_correlator_sptr -gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen, +gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length, unsigned int cplen, - std::vector known_symbol1, - std::vector known_symbol2) + const std::vector &known_symbol1, + const std::vector &known_symbol2) { - return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, vlen, cplen, + return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, fft_length, cplen, known_symbol1, known_symbol2)); } -gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int vlen, +gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int fft_length, unsigned int cplen, - std::vector known_symbol1, - std::vector known_symbol2) + const std::vector &known_symbol1, + const std::vector &known_symbol2) : gr_block ("ofdm_correlator", - gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen), - gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers)), + 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_vlen(vlen), + d_fft_length(fft_length), d_cplen(cplen), d_freq_shift_len(5), d_known_symbol1(known_symbol1), @@ -84,8 +85,9 @@ gr_ofdm_correlator::forecast (int noutput_items, gr_vector_int &ninput_items_req gr_complex gr_ofdm_correlator::coarse_freq_comp(int freq_delta, int symbol_count) { - return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count), - sin(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count)); + // 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); } bool @@ -99,7 +101,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 && (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; @@ -115,11 +117,20 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr search_delta, h_sqrd.real(), h_sqrd.imag(), power, h_sqrd.real()/power, arg(h_sqrd)); #endif - if(h_sqrd.real() > 0.75*power) { + // FIXME: Look at h_sqrd.read() > power + if((h_sqrd.real() > 0.82*power) && (h_sqrd.real() < 1.1 * power)) { found = true; d_coarse_freq = search_delta; d_phase_count = 1; - d_snr_est = 10*log10(power/(power-h_sqrd.real())); + //d_snr_est = 10*log10(power/(power-h_sqrd.real())); + + // check for low noise power; sets maximum SNR at 100 dB + if(fabs(h_sqrd.imag()) <= 1e-12) { + d_snr_est = 100.0; + } + else { + d_snr_est = 10*log10(fabs(h_sqrd.real()/h_sqrd.imag())); + } printf("CORR: Found, bin %d\tSNR Est %f dB\tcorr power fraction %f\n", search_delta, d_snr_est, h_sqrd.real()/power); @@ -168,23 +179,30 @@ gr_ofdm_correlator::general_work(int noutput_items, { const gr_complex *in = (const gr_complex *)input_items[0]; const gr_complex *previous = &in[0]; - const gr_complex *current = &in[d_vlen]; + const gr_complex *current = &in[d_fft_length]; gr_complex *out = (gr_complex *) output_items[0]; + char *sig = (char *) output_items[1]; unsigned int i=0; - int unoccupied_carriers = d_vlen - d_occupied_carriers; + int unoccupied_carriers = d_fft_length - d_occupied_carriers; int zeros_on_left = (int)ceil(unoccupied_carriers/2.0); bool corr = correlate(previous, current, zeros_on_left); if(corr) { calculate_equalizer(previous, current, zeros_on_left); + sig[0] = 1; + } + else { + sig[0] = 0; } for(i = 0; i < d_occupied_carriers; i++) { out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)*current[i+zeros_on_left+d_coarse_freq]; } + + d_phase_count++; consume_each(1); return 1; diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h index 4c44cca32..44a6847af 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h +++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.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 * @@ -31,10 +31,10 @@ class gr_ofdm_correlator; typedef boost::shared_ptr gr_ofdm_correlator_sptr; gr_ofdm_correlator_sptr -gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen, +gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length, unsigned int cplen, - std::vector known_symbol1, - std::vector known_symbol2); + const std::vector &known_symbol1, + const std::vector &known_symbol2); /*! * \brief take a vector of complex constellation points in from an FFT @@ -48,7 +48,7 @@ gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen, * been corrected and that the samples fall in the middle of one FFT bin. * * It then uses one of those known - * symbosl to estimate the channel response overa all subcarriers and does a simple + * symbols to estimate the channel response over all subcarriers and does a simple * 1-tap equalization on all subcarriers. This corrects for the phase and amplitude * distortion caused by the channel. */ @@ -58,7 +58,7 @@ class gr_ofdm_correlator : public gr_block /*! * \brief Build an OFDM correlator and equalizer. * \param occupied_carriers The number of subcarriers with data in the received symbol - * \param vlen The size of the FFT vector (occupied_carriers + unused carriers) + * \param fft_length The size of the FFT vector (occupied_carriers + unused carriers) * \param known_symbol1 A vector of complex numbers representing a known symbol at the * start of a frame (usually a BPSK PN sequence) * \param known_symbol2 A vector of complex numbers representing a known symbol at the @@ -67,16 +67,16 @@ class gr_ofdm_correlator : public gr_block * for phase changes between symbols. */ friend gr_ofdm_correlator_sptr - gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen, + gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length, unsigned int cplen, - std::vector known_symbol1, - std::vector known_symbol2); + const std::vector &known_symbol1, + const std::vector &known_symbol2); protected: - gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen, + gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length, unsigned int cplen, - std::vector known_symbol1, - std::vector known_symbol2); + const std::vector &known_symbol1, + const std::vector &known_symbol2); private: unsigned char slicer(gr_complex x); @@ -86,15 +86,15 @@ class gr_ofdm_correlator : public gr_block gr_complex coarse_freq_comp(int freq_delta, int count); unsigned int d_occupied_carriers; // !< \brief number of subcarriers with data - unsigned int d_vlen; // !< \brief length of FFT vector + unsigned int d_fft_length; // !< \brief length of FFT vector unsigned int d_cplen; // !< \brief length of cyclic prefix in samples unsigned int d_freq_shift_len; // !< \brief number of surrounding bins to look at for correlation std::vector d_known_symbol1, d_known_symbol2; // !< \brief known symbols at start of frame std::vector d_diff_corr_factor; // !< \brief factor used in correlation - std::vector d_hestimate; // !< channel estimate - signed int d_coarse_freq; // !< \brief search distance in number of bins - unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction - float d_snr_est; // !< an estimation of the signal to noise ratio + std::vector d_hestimate; // !< channel estimate + signed int d_coarse_freq; // !< \brief search distance in number of bins + unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction + float d_snr_est; // !< an estimation of the signal to noise ratio void forecast(int noutput_items, gr_vector_int &ninput_items_required); diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i index fbbf6a8af..40f9f83ff 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i +++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.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 * @@ -22,23 +22,23 @@ #include -GR_SWIG_BLOCK_MAGIC(gr,ofdm_correlator) +GR_SWIG_BLOCK_MAGIC(gr,ofdm_correlator); gr_ofdm_correlator_sptr gr_make_ofdm_correlator (unsigned int occupied_carriers, - unsigned int vlen, + unsigned int fft_length, unsigned int cplen, - std::vector known_symbol1, - std::vector known_symbol2); + const std::vector &known_symbol1, + const std::vector &known_symbol2); class gr_ofdm_correlator : public gr_sync_decimator { protected: gr_ofdm_correlator (unsigned int occupied_carriers, - unsigned int vlen, + unsigned int fft_length, unsigned int cplen, - std::vector known_symbol1, - std::vector known_symbol2); + const std::vector &known_symbol1, + const std::vector &known_symbol2); 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 new file mode 100644 index 000000000..acaf1258b --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc @@ -0,0 +1,235 @@ +/* -*- 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 +#include +#include +#include + +#define VERBOSE 0 + +inline void +gr_ofdm_frame_sink::enter_search() +{ + if (VERBOSE) + fprintf(stderr, "@ enter_search\n"); + + d_state = STATE_SYNC_SEARCH; + +} + +inline void +gr_ofdm_frame_sink::enter_have_sync() +{ + if (VERBOSE) + fprintf(stderr, "@ enter_have_sync\n"); + + d_state = STATE_HAVE_SYNC; + + // clear state of demapper + d_byte_offset = 0; + d_partial_byte = 0; + + d_header = 0; + d_headerbytelen_cnt = 0; +} + +inline void +gr_ofdm_frame_sink::enter_have_header() +{ + d_state = STATE_HAVE_HEADER; + + // header consists of two 16-bit shorts in network byte order + // payload length is lower 12 bits + // whitener offset is upper 4 bits + d_packetlen = (d_header >> 16) & 0x0fff; + d_packet_whitener_offset = (d_header >> 28) & 0x000f; + d_packetlen_cnt = 0; + + if (VERBOSE) + fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", + 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 int gr_ofdm_frame_sink::bpsk_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 |= 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; + } + } + + return bytes_produced; +} + + + +gr_ofdm_frame_sink_sptr +gr_make_ofdm_frame_sink(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)); +} + + +gr_ofdm_frame_sink::gr_ofdm_frame_sink(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_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/8.0)]; + + enter_search(); +} + +gr_ofdm_frame_sink::~gr_ofdm_frame_sink () +{ + delete [] d_bytes_out; +} + +int +gr_ofdm_frame_sink::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_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); + + switch(d_state) { + + case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt + if (VERBOSE) + fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items); + + if (sig[0]) { // Found it, set up for header decode + enter_have_sync(); + } + break; + + case STATE_HAVE_SYNC: + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_SYNC\n"); + if (VERBOSE) + 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); + j++; + + if (++d_headerbytelen_cnt == HEADERBYTELEN) { + + if (VERBOSE) + fprintf(stderr, "got header: 0x%08x\n", d_header); + + // 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"); + + while((j < bytes) && (d_packetlen_cnt < d_packetlen)) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + } + + if(d_packetlen_cnt == d_packetlen) { + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + } + } + else { + enter_search(); // bad header + } + } + } + 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"); + + j = 0; + while(j < bytes) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + + if (d_packetlen_cnt == d_packetlen){ // packet is filled + // build a message + // NOTE: passing header field as arg1 is not scalable + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + break; + } + } + break; + + default: + assert(0); + + } // switch + + return 1; +} diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h new file mode 100644 index 000000000..d77c76741 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h @@ -0,0 +1,105 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006 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_FRAME_SINK_H +#define INCLUDED_GR_OFDM_FRAME_SINK_H + +#include +#include + +class gr_ofdm_frame_sink; +typedef boost::shared_ptr 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); + +/*! + * \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. + */ +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); + + private: + enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER}; + + static const int MAX_PKT_LEN = 4096; + static const int HEADERBYTELEN = 4; + + gr_msg_queue_sptr d_target_queue; // where to send the packet when received + state_t d_state; + unsigned int d_header; // header bits + int d_headerbytelen_cnt; // how many so far + + unsigned char *d_bytes_out; // hold the current bytes produced by the demapper + + unsigned int d_occupied_carriers; + unsigned int d_byte_offset; + unsigned int d_partial_byte; + + unsigned char d_packet[MAX_PKT_LEN]; // assembled payload + int d_packetlen; // length of packet + int d_packet_whitener_offset; // offset into whitener string to use + int d_packetlen_cnt; // how many so far + + protected: + gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones); + + void enter_search(); + void enter_have_sync(); + void enter_have_header(); + + bool header_ok() + { + // confirm that two copies of header info are identical + return ((d_header >> 16) ^ (d_header & 0xffff)) == 0; + } + + unsigned char bpsk_slicer(gr_complex x); + unsigned int bpsk_demapper(const gr_complex *in, + unsigned char *out); + + public: + ~gr_ofdm_frame_sink(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_GR_OFDM_FRAME_SINK_H */ diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i new file mode 100644 index 000000000..b05c8b795 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006 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_frame_sink); + +gr_ofdm_frame_sink_sptr +gr_make_ofdm_frame_sink(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); + + public: + ~gr_ofdm_frame_sink(); +}; diff --git a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc index 9ac5abdcd..5f5a91fd2 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc @@ -38,7 +38,7 @@ gr_make_ofdm_sampler (unsigned int fft_length, gr_ofdm_sampler::gr_ofdm_sampler (unsigned int fft_length, unsigned int symbol_length) : gr_block ("ofdm_sampler", - gr_make_io_signature (2, 2, sizeof (gr_complex)), + gr_make_io_signature2 (2, 2, sizeof (gr_complex), sizeof(char)), gr_make_io_signature (1, 1, sizeof (gr_complex)*fft_length)), d_fft_length(fft_length), d_symbol_length(symbol_length) { @@ -61,7 +61,7 @@ gr_ofdm_sampler::general_work (int noutput_items, gr_vector_void_star &output_items) { gr_complex *iptr = (gr_complex *) input_items[0]; - gr_complex *trigger = (gr_complex *) input_items[1]; + char *trigger = (char *) input_items[1]; gr_complex *optr = (gr_complex *) output_items[0]; @@ -70,7 +70,7 @@ gr_ofdm_sampler::general_work (int noutput_items, unsigned int i=d_fft_length-1; while(!found && i 0.5) + if(trigger[i]) found = 1; else i++; diff --git a/gnuradio-core/src/lib/general/gr_skiphead.cc b/gnuradio-core/src/lib/general/gr_skiphead.cc index 4a1f87511..e395cbf66 100644 --- a/gnuradio-core/src/lib/general/gr_skiphead.cc +++ b/gnuradio-core/src/lib/general/gr_skiphead.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,45 +26,57 @@ #include #include -gr_skiphead::gr_skiphead (size_t sizeof_stream_item, int nitems) - : gr_sync_block ("skiphead", - gr_make_io_signature (1, 1, sizeof_stream_item), - gr_make_io_signature (1, 1, sizeof_stream_item)), - d_nitems (nitems), d_nskipped_items (0) +gr_skiphead::gr_skiphead (size_t itemsize, size_t nitems_to_skip) + : gr_block ("skiphead", + gr_make_io_signature(1, 1, itemsize), + gr_make_io_signature(1, 1, itemsize)), + d_nitems_to_skip(nitems_to_skip), d_nitems(0) { } -gr_block_sptr -gr_make_skiphead (size_t sizeof_stream_item, int nitems) +gr_skiphead_sptr +gr_make_skiphead (size_t itemsize, size_t nitems_to_skip) { - return gr_block_sptr (new gr_skiphead (sizeof_stream_item, nitems)); + return gr_skiphead_sptr (new gr_skiphead (itemsize, nitems_to_skip)); } int -gr_skiphead::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +gr_skiphead::general_work(int noutput_items, + gr_vector_int &ninput_items_ignored, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { - int items_to_skip = d_nitems - d_nskipped_items; - if (items_to_skip <=0) - { - //Done with skipping, copy all input to the output; - memcpy (output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item (0)); - return noutput_items; - } else if (items_to_skip < noutput_items) - { - memcpy (output_items[0], &(((char *)input_items[0])[items_to_skip*input_signature()->sizeof_stream_item (0)]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0)); - //memcpy (output_items[0], &((input_items[0])[items_to_skip]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0)); - //memcpy (output_items[0], input_items[0]+items_to_skip*input_signature()->sizeof_stream_item (0), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0)); - d_nskipped_items += items_to_skip; - consume_each (items_to_skip); - return (noutput_items -items_to_skip); - } else - { - d_nskipped_items += noutput_items; - consume_each (items_to_skip); - return 0; + const char *in = (const char *) input_items[0]; + char *out = (char *) output_items[0]; + + int ninput_items = noutput_items; // we've got at least this many input items + int ii = 0; // input index + + while (ii < ninput_items){ + + long long ni_total = ii + d_nitems; // total items processed so far + if (ni_total < d_nitems_to_skip){ // need to skip some more + + int n_to_skip = (int) std::min(d_nitems_to_skip - ni_total, + (long long)(ninput_items - ii)); + ii += n_to_skip; + } + + else { // nothing left to skip. copy away + + int n_to_copy = ninput_items - ii; + if (n_to_copy > 0){ + size_t itemsize = output_signature()->sizeof_stream_item(0); + memcpy(out, in + (ii*itemsize), n_to_copy*itemsize); + } + + d_nitems += ninput_items; + consume_each(ninput_items); + return n_to_copy; + } } - return -1;//Should never get here + d_nitems += ninput_items; + consume_each(ninput_items); + return 0; } diff --git a/gnuradio-core/src/lib/general/gr_skiphead.h b/gnuradio-core/src/lib/general/gr_skiphead.h index 81898ef40..6e2c78272 100644 --- a/gnuradio-core/src/lib/general/gr_skiphead.h +++ b/gnuradio-core/src/lib/general/gr_skiphead.h @@ -26,6 +26,10 @@ #include #include // size_t +class gr_skiphead; +typedef boost::shared_ptr gr_skiphead_sptr; + + /*! * \brief skips the first N items, from then on copies items to the output * \ingroup block @@ -33,22 +37,24 @@ * Useful for building test cases and sources which have metadata or junk at the start */ -class gr_skiphead : public gr_sync_block +class gr_skiphead : public gr_block { - friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems); - gr_skiphead (size_t sizeof_stream_item, int nitems); + friend gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip); + gr_skiphead (size_t itemsize, size_t nitems_to_skip); - int d_nitems; - int d_nskipped_items; + long long d_nitems_to_skip; + long long d_nitems; // total items seen public: - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; -gr_block_sptr -gr_make_skiphead (size_t sizeof_stream_item, int nitems); +gr_skiphead_sptr +gr_make_skiphead (size_t itemsize, size_t nitems_to_skip); #endif /* INCLUDED_GR_SKIPHEAD_H */ diff --git a/gnuradio-core/src/lib/general/gr_skiphead.i b/gnuradio-core/src/lib/general/gr_skiphead.i index 8942f184e..c725e26bb 100644 --- a/gnuradio-core/src/lib/general/gr_skiphead.i +++ b/gnuradio-core/src/lib/general/gr_skiphead.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,11 +20,11 @@ * Boston, MA 02110-1301, USA. */ -%ignore gr_skiphead; +GR_SWIG_BLOCK_MAGIC(gr,skiphead); + +gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip); + class gr_skiphead : public gr_block { - friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems); - gr_skiphead (size_t sizeof_stream_item, int nitems); + friend gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip); + gr_skiphead (size_t itemsize, size_t nitems_to_skip); }; - -%rename(skiphead) gr_make_skiphead; -gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems); diff --git a/gnuradio-core/src/lib/general/gr_stream_mux.cc b/gnuradio-core/src/lib/general/gr_stream_mux.cc index 1eaad29a2..e7e45de74 100644 --- a/gnuradio-core/src/lib/general/gr_stream_mux.cc +++ b/gnuradio-core/src/lib/general/gr_stream_mux.cc @@ -44,6 +44,10 @@ gr_stream_mux::gr_stream_mux (size_t itemsize, const std::vector &lengths) d_residual(0), d_lengths(lengths) { + if(d_lengths[d_stream] == 0) { + increment_stream(); + } + d_residual = d_lengths[d_stream]; } gr_stream_mux::~gr_stream_mux(void) @@ -55,9 +59,17 @@ gr_stream_mux::forecast (int noutput_items, gr_vector_int &ninput_items_required { unsigned ninputs = ninput_items_required.size (); for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = 0; + ninput_items_required[i] = (d_lengths[i] == 0 ? 0 : 1); } +void gr_stream_mux::increment_stream() +{ + do { + d_stream = (d_stream+1) % d_lengths.size(); + } while(d_lengths[d_stream] == 0); + + d_residual = d_lengths[d_stream]; +} int gr_stream_mux::general_work(int noutput_items, @@ -65,128 +77,46 @@ gr_stream_mux::general_work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - char *out = (char *) output_items[0]; const char *in; + int out_index = 0; + std::vector input_index(d_lengths.size(), 0); - int acc = 0; - int N=0; - int M=0; - std::vector consume_vector(d_lengths.size(), 0); + if(VERBOSE) { + printf("mux: nouput_items: %d d_stream: %d\n", noutput_items, d_stream); + for(size_t i = 0; i < d_lengths.size(); i++) + printf("\tninput_items[%d]: %d\n", i, ninput_items[i]); + } - #if VERBOSE - printf("mux: nouput_items: %d d_stream: %d\n", noutput_items, d_stream); - for(int i = 0; i < d_lengths.size(); i++) - printf("\tninput_items[%d]: %d\n", i, ninput_items[i]); - #endif + while (1) { + int r = std::min(noutput_items - out_index, + std::min(d_residual, + ninput_items[d_stream] - input_index[d_stream])); + if(VERBOSE) { + printf("mux: r=%d\n", r); + printf("\tnoutput_items - out_index: %d\n", + noutput_items - out_index); + printf("\td_residual: %d\n", + d_residual); + printf("\tninput_items[d_stream] - input_index[d_stream]: %d\n", + ninput_items[d_stream] - input_index[d_stream]); + } - in = (const char *) input_items[d_stream]; + if(r <= 0) { + return out_index; + } - if(d_residual) { - #if VERBOSE - printf("Cleaning up residual bytes (%d) from stream %d\n", d_residual, d_stream); - #endif + in = (const char *) input_items[d_stream] + input_index[d_stream]*d_itemsize; - // get the number of items available in input stream up to the - // num items required - N=std::min(d_residual, ninput_items[d_stream]); - - // get the number of items we can put into the output buffer - M=std::min(N, noutput_items); - - // copy the items to the output buff - memcpy(out, in, M*d_itemsize); + memcpy(&out[out_index*d_itemsize], in, r*d_itemsize); + out_index += r; + input_index[d_stream] += r; + d_residual -= r; - // increment the output accumulator - acc += M; - - // keep track of items consumed - consume_vector[d_stream]=M; + consume(d_stream, r); - // keep track if there are residual items left from the input stream - d_residual -= M; - - #if VERBOSE - printf("Stream: %d (%x) Wrote: %d bytes Output has: %d bytes residual: %d bytes\n", - d_stream, in, M, acc, d_residual); - #endif - - // if no residual items, we're done with this input stream for - // this round - if (!d_residual) { - if(d_stream == d_lengths.size() - 1) { - d_stream=0; // wrap stream pointer - } - else { - d_stream++; // or increment the stream pointer - } - #if VERBOSE - printf("Going to next stream: %d\n", d_stream); - #endif - in = ((const char *) (input_items[d_stream])) + d_itemsize*consume_vector[d_stream]; - } - } - - if(!d_residual) { - while (acc -#include #include class gr_stream_mux; @@ -66,14 +65,15 @@ class gr_stream_mux : public gr_block protected: gr_stream_mux (size_t itemsize, const std::vector &lengths); + private: - size_t d_itemsize; - unsigned int d_stream; - int d_residual; - int d_times; - int d_unconsume; - //gr_vector_int d_unconsume; - gr_vector_int d_lengths; + size_t d_itemsize; + unsigned int d_stream; // index of currently selected stream + int d_residual; // number if items left to put into current stream + gr_vector_int d_lengths; // number if items to pack per stream + + void increment_stream(); + public: ~gr_stream_mux(void); -- cgit