diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-10-06 12:25:31 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2014-10-06 12:25:31 -0400 |
commit | 797b5924d310fe6d5fdcce176b6fb3d89618b7b5 (patch) | |
tree | 6b1277d4d2bfdd4abff01ff8c012a7d7dfad0bdb /gr-fec | |
parent | 4f03a54b2b802f0eff6802985ec6479738843c57 (diff) | |
parent | 41fbbc6a54fc7c3d9a9d73697f412bca234061bb (diff) |
Merge branch 'maint'
Diffstat (limited to 'gr-fec')
-rw-r--r-- | gr-fec/include/gnuradio/fec/ber_bf.h | 37 | ||||
-rw-r--r-- | gr-fec/lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-fec/lib/ber_bf_impl.cc | 16 | ||||
-rw-r--r-- | gr-fec/lib/ber_tools.cc | 117 | ||||
-rw-r--r-- | gr-fec/lib/ber_tools.h | 73 | ||||
-rw-r--r-- | gr-fec/python/fec/qa_ber_bf.py | 141 |
6 files changed, 181 insertions, 204 deletions
diff --git a/gr-fec/include/gnuradio/fec/ber_bf.h b/gr-fec/include/gnuradio/fec/ber_bf.h index cc42bcebe6..2aa01c98b0 100644 --- a/gr-fec/include/gnuradio/fec/ber_bf.h +++ b/gr-fec/include/gnuradio/fec/ber_bf.h @@ -35,7 +35,30 @@ namespace gr { * * \details * - * What does this block do? + * This block measures the bit error rate between two streams of + * packed data. It compares the bits of each streams and counts + * the number of incorrect bits between them. It outputs the log + * of the bit error rate, so a value of -X is 10^{-X} bit errors. + * + * When the \p mode is set to false (default), it is in streaming + * mode. This means that the output is constantly producing the + * current value of the BER. In this mode, there is a single + * output BER calculation per chunk of bytes passed to it, so + * there is no exact timing between calculations of BER. In this + * mode, the other two parameters to the constructor are ignored. + * + * When \p mode is true, the block is in test mode. This mode is + * used in the ber_curve_gen example and for other offline + * analysis of BER curves. Here, the block waits until at least \p + * berminerrors are observed and then produces a BER + * calculation. The parameter \p ber_limit helps make sure that + * the simulation is controlled. If the BER calculation drops + * bellow the \p ber_limit setting, the block will exit and simply + * return the set limit; the real BER is therefore some amount + * lower than this. + * + * Note that this block takes in data as packed bytes with 8-bits + * per byte used. It outputs a stream of floats as the log-scale BER. */ class FEC_API ber_bf : virtual public block { @@ -43,6 +66,18 @@ namespace gr { // gr::fec::ber_bf::sptr typedef boost::shared_ptr<ber_bf> sptr; + /*! + * Calculate the BER between two streams of data. + * + * \param test_mode false for normal streaming mode (default); + * true for test mode. + * \param berminerrors the block needs to observe this many + * errors before outputting a result. Only valid when + * test_mode=true. + * \param ber_limit if the BER calculation falls below this + * limit, produce this value and exit. Only valid when + * test_mode=true. + */ static sptr make(bool test_mode = false, int berminerrors=100, float ber_limit=-7.0); }; diff --git a/gr-fec/lib/CMakeLists.txt b/gr-fec/lib/CMakeLists.txt index e261cb5dac..3712eb7485 100644 --- a/gr-fec/lib/CMakeLists.txt +++ b/gr-fec/lib/CMakeLists.txt @@ -66,7 +66,6 @@ list(APPEND gnuradio_fec_sources repetition_encoder_impl.cc decode_ccsds_27_fb_impl.cc encode_ccsds_27_bb_impl.cc - ber_tools.cc ber_bf_impl.cc conv_bit_corr_bb_impl.cc puncture_bb_impl.cc diff --git a/gr-fec/lib/ber_bf_impl.cc b/gr-fec/lib/ber_bf_impl.cc index d7282ea699..a7c38700d6 100644 --- a/gr-fec/lib/ber_bf_impl.cc +++ b/gr-fec/lib/ber_bf_impl.cc @@ -25,7 +25,6 @@ #endif #include "ber_bf_impl.h" -#include "ber_tools.h" #include <gnuradio/io_signature.h> #include <volk/volk.h> #include <math.h> @@ -79,18 +78,11 @@ namespace gr { int items = ninput_items[0] <= ninput_items[1] ? ninput_items[0] : ninput_items[1]; if(items > 0) { - /* - for(int i = 0; i < items; ++i) { - if(inbuffer0[i] != inbuffer1[i]) { - GR_LOG_INFO(d_logger, boost::format("%1%/%2%: %3% versus %4%") \ - % i % items % inbuffer0[i] % inbuffer1[i]); - } + uint32_t ret; + for(int i = 0; i < items; i++) { + volk_32u_popcnt(&ret, static_cast<uint32_t>(inbuffer0[i]^inbuffer1[i])); + d_total_errors += ret; } - GR_LOG_INFO(d_logger, boost::format("%1% errors") \ - % (compber(inbuffer0, inbuffer1, items))); - */ - - d_total_errors += compber(inbuffer0, inbuffer1, items); d_total += items; } consume_each(items); diff --git a/gr-fec/lib/ber_tools.cc b/gr-fec/lib/ber_tools.cc deleted file mode 100644 index 043fbef216..0000000000 --- a/gr-fec/lib/ber_tools.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013-2014 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 3, 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. - */ - -#include <cstdlib> -#ifdef _MSC_VER -#define _USE_MATH_DEFINES -#include <cmath> -#endif - -#include "ber_tools.h" - -inline int -putbit(int word, int loc, int bit) -{ - return (((word)&(~((1)<<(loc))))^((bit)<<(loc))); -} - -void -gaussnoise(float *inbuffer, int buffsize, float sigma) -{ - int i; - float udrn1=0.0, udrn2=0.0, noise=0.0; - - for(i = 0; i < buffsize;i++) { - #ifdef _MSC_VER - while((udrn1 = (float)(std::rand())) < 0.0000001); - udrn2 = (float)(std::rand()); - #else - while((udrn1 = (float)drand48()) < 0.0000001); - udrn2 = (float)drand48(); - #endif - noise = sigma*sqrt(-2*log(udrn1))*cos(2*M_PI*udrn2); - inbuffer[i] += noise; - } -} - - -int -compber(unsigned char *inbuffer1, unsigned char *inbuffer2, int buffsize) -{ - int i, totaldiff=0; - int popcnt[256] = - { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 - }; - - for(i = 0; i < buffsize; i++) { - totaldiff += popcnt[inbuffer1[i]^inbuffer2[i]]; - } - - return totaldiff; -} - -void randbuffer(unsigned char *databuffer,int buffsize, int charout) -{ - int i; - unsigned char randbit; - - for(i = 0; i < buffsize; i++) { - // generate random element - randbit = (unsigned char)((0x000010000&rand())>>16); - // place in the data buffer - if(charout == 0) - databuffer[i>>3] = putbit(databuffer[i>>3],7-(i&0x7),randbit); - else - databuffer[i] = randbit; - } -} - -void -char2bin(unsigned char *inbuffer,int buffSize) -{ - int i; - unsigned char fbit=0; - - for(i = 0; i < buffSize; i++) { - if(inbuffer[i] == 0) - fbit = 0; - else - fbit = 1; - inbuffer[i>>3] = putbit(inbuffer[i>>3],7-(i&0x7),fbit); - } -} diff --git a/gr-fec/lib/ber_tools.h b/gr-fec/lib/ber_tools.h deleted file mode 100644 index 038b362974..0000000000 --- a/gr-fec/lib/ber_tools.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013-2014 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 3, 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_GNURADIO_FEC_BER_TOOLS_H -#define INCLUDED_GNURADIO_FEC_BER_TOOLS_H - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#define BERMINFRAMES (10000) -#define BERMINERRORS (100) -#define BERMAXBITS (1000000000) - -/*! - * Add BPSK gaussian noise with standard deviation equal to sigma to a - * floating point input buffer. - * - * \param inbuffer (float*) buffer containing data to receive additive - * gaussian noise - * \param buffsize (int) size of \p inbuffer - * \param sigma (float) noise power of the guassian random variables - */ -void gaussnoise(float *inbuffer, int buffsize, float sigma); - -/*! - * Compute the number of bit differences between input buffers - * - * \param inbuffer1 input stream 1 to compare against \p inbuffer2 - * \param inbuffer2 input stream 2 to be compared against - * \param buffsize number of elements in each buffer - */ -int compber(unsigned char *inbuffer1, unsigned char *inbuffer2, int buffsize); - -/*! - * Generate a random buffer of data - * - * \param databuffer pointer to buffer containing random data - * \param buffsize number of elements in each buffer - */ -void randbuffer(unsigned char *databuffer, int buffsize, int charout); - -/*! - * Pack the character buffer - * - * \param databuffer pointer to buffer containing unpacked chars - * \param buffsize number of elements in each buffer - */ -void char2bin(unsigned char *inbuffer, int buffsize); - -#endif /* INCLUDED_GNURADIO_FEC_BER_TOOLS_H */ - - diff --git a/gr-fec/python/fec/qa_ber_bf.py b/gr-fec/python/fec/qa_ber_bf.py new file mode 100644 index 0000000000..1a60c68581 --- /dev/null +++ b/gr-fec/python/fec/qa_ber_bf.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +# +# Copyright 2014 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 3, 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. +# + +from gnuradio import gr, gr_unittest +import fec_swig as fec +import blocks_swig as blocks +import numpy, copy + +class test_ber_bf(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_000(self): + # Cause a single bit error out of 8*N bits + # using streaming mode + + mode = 0 + N = 10000 + data0 = numpy.random.randint(0, 256, N).tolist() + data1 = copy.deepcopy(data0) + data1[0] ^= 0x01 + + src0 = blocks.vector_source_b(data0) + src1 = blocks.vector_source_b(data1) + op = fec.ber_bf(mode) + dst = blocks.vector_sink_f() + + self.tb.connect(src0, (op,0)) + self.tb.connect(src1, (op,1)) + self.tb.connect(op, dst) + self.tb.run() + + data = dst.data() + expected_result = [numpy.log10(1.0/(8.0*N)),] + + self.assertFloatTuplesAlmostEqual(expected_result, data, 5) + + def test_001(self): + # Cause a single bit error out of 8*N bits + # using test mode + + mode = 1 + N = 1000 + data0 = numpy.random.randint(0, 256, N).tolist() + data1 = copy.deepcopy(data0) + data1[0] ^= 0x01 + + src0 = blocks.vector_source_b(data0) + src1 = blocks.vector_source_b(data1) + op = fec.ber_bf(mode, 1) + dst = blocks.vector_sink_f() + + self.tb.connect(src0, (op,0)) + self.tb.connect(src1, (op,1)) + self.tb.connect(op, dst) + self.tb.run() + + data = dst.data() + expected_result = [numpy.log10(1.0/(8.0*N)),] + + self.assertFloatTuplesAlmostEqual(expected_result, data, 5) + + def test_002(self): + # Cause 8 bit errors out of 8*N bits + # using test mode + + mode = 1 + N = 1000 + data0 = numpy.random.randint(0, 256, N).tolist() + data1 = copy.deepcopy(data0) + data1[0] ^= 0xFF + + src0 = blocks.vector_source_b(data0) + src1 = blocks.vector_source_b(data1) + op = fec.ber_bf(mode, 1, -2.0) + dst = blocks.vector_sink_f() + + self.tb.connect(src0, (op,0)) + self.tb.connect(src1, (op,1)) + self.tb.connect(op, dst) + self.tb.run() + + data = dst.data() + expected_result = [numpy.log10(8.0/(8.0*N)),] + + self.assertFloatTuplesAlmostEqual(expected_result, data, 5) + + def test_003(self): + # Cause a 8 bit errors out of 8*N bits + # using test mode + # Exit if BER < -2.0 + + mode = 1 + N = 1000 + data0 = numpy.random.randint(0, 256, N).tolist() + data1 = copy.deepcopy(data0) + data1[0] ^= 0xFF + + src0 = blocks.vector_source_b(data0) + src1 = blocks.vector_source_b(data1) + op = fec.ber_bf(mode, 10, -2.0) + dst = blocks.vector_sink_f() + + self.tb.connect(src0, (op,0)) + self.tb.connect(src1, (op,1)) + self.tb.connect(op, dst) + self.tb.run() + + data = dst.data() + expected_result = [-2.0,] + + print data + print expected_result + + self.assertFloatTuplesAlmostEqual(expected_result, data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_ber_bf, "test_ber_bf.xml") |