diff options
Diffstat (limited to 'gnuradio-core/src')
106 files changed, 3137 insertions, 342 deletions
diff --git a/gnuradio-core/src/guile/tests/gengen_ctors.test b/gnuradio-core/src/guile/tests/gengen_ctors.test index 6e1213c63..6bac05394 100644 --- a/gnuradio-core/src/guile/tests/gengen_ctors.test +++ b/gnuradio-core/src/guile/tests/gengen_ctors.test @@ -161,12 +161,6 @@ ;;; ./gengen/gr_moving_average_ss.h (pass-if (true? (gr:moving-average-ss 1 0 4096))) -;;; ./gengen/gr_multiply_cc.h -(pass-if (true? (gr:multiply-cc 1))) - -;;; ./gengen/gr_multiply_const_cc.h -(pass-if (true? (gr:multiply-const-cc 1))) - ;;; ./gengen/gr_multiply_const_ff.h (pass-if (true? (gr:multiply-const-ff 1))) diff --git a/gnuradio-core/src/lib/CMakeLists.txt b/gnuradio-core/src/lib/CMakeLists.txt index 52339fc6c..86f88242c 100644 --- a/gnuradio-core/src/lib/CMakeLists.txt +++ b/gnuradio-core/src/lib/CMakeLists.txt @@ -42,6 +42,7 @@ list(APPEND test_gnuradio_core_sources bug_work_around_6.cc) # Setup the include and linker paths ######################################################################## include_directories(${GNURADIO_CORE_INCLUDE_DIRS}) +include_directories(${VOLK_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) @@ -63,11 +64,19 @@ list(APPEND gnuradio_core_libs ${FFTW3F_LIBRARIES} ) +if(FFTW3F_THREADS_LIBRARIES) + list(APPEND gnuradio_core_libs ${FFTW3F_THREADS_LIBRARIES} ) + add_definitions("-DFFTW3F_THREADS") +endif() + #need to link with librt on ubuntu 11.10 for shm_* if(LINUX) list(APPEND gnuradio_core_libs rt) endif() +# Link against libvolk +list(APPEND gnuradio_core_libs volk) + add_library(gnuradio-core SHARED ${gnuradio_core_sources}) target_link_libraries(gnuradio-core ${gnuradio_core_libs}) GR_LIBRARY_FOO(gnuradio-core RUNTIME_COMPONENT "core_runtime" DEVEL_COMPONENT "core_devel") diff --git a/gnuradio-core/src/lib/Makefile.am b/gnuradio-core/src/lib/Makefile.am index fc1b7917b..21e721073 100644 --- a/gnuradio-core/src/lib/Makefile.am +++ b/gnuradio-core/src/lib/Makefile.am @@ -51,6 +51,7 @@ libgnuradio_core_la_LIBADD = \ runtime/libruntime.la \ hier/libhier.la \ $(GRUEL_LA) \ + $(VOLK_LA) \ $(FFTW3F_LIBS) \ $(GSL_LIBS) \ $(CBLAS_LIBS) \ diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc index 9fa98cc69..5968e487e 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc @@ -30,7 +30,6 @@ #endif #include <gr_fft_filter_ccc.h> -//#include <gri_fft_filter_ccc_sse.h> #include <gri_fft_filter_ccc_generic.h> #include <gr_io_signature.h> #include <gri_fft.h> @@ -43,13 +42,17 @@ #include <iostream> #include <string.h> -gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps) +gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, + const std::vector<gr_complex> &taps, + int nthreads) { - return gnuradio::get_initial_sptr(new gr_fft_filter_ccc (decimation, taps)); + return gnuradio::get_initial_sptr(new gr_fft_filter_ccc (decimation, taps, nthreads)); } -gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps) +gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, + const std::vector<gr_complex> &taps, + int nthreads) : gr_sync_decimator ("fft_filter_ccc", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature (1, 1, sizeof (gr_complex)), @@ -57,11 +60,13 @@ gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, const std::vector<gr_compl d_updated(false) { set_history(1); + #if 1 // don't enable the sse version until handling it is worked out - d_filter = new gri_fft_filter_ccc_generic(decimation, taps); + d_filter = new gri_fft_filter_ccc_generic(decimation, taps, nthreads); #else d_filter = new gri_fft_filter_ccc_sse(decimation, taps); #endif + d_new_taps = taps; d_nsamples = d_filter->set_taps(taps); set_output_multiple(d_nsamples); @@ -85,6 +90,23 @@ gr_fft_filter_ccc::taps () const return d_new_taps; } +void +gr_fft_filter_ccc::set_nthreads(int n) +{ + if(d_filter) + d_filter->set_nthreads(n); +} + +int +gr_fft_filter_ccc::nthreads() const +{ + if(d_filter) + return d_filter->nthreads(); + else + return 0; +} + + int gr_fft_filter_ccc::work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h index 1b72a1c00..d037597e8 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h @@ -27,7 +27,9 @@ class gr_fft_filter_ccc; typedef boost::shared_ptr<gr_fft_filter_ccc> gr_fft_filter_ccc_sptr; -GR_CORE_API gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps); +GR_CORE_API gr_fft_filter_ccc_sptr +gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps, + int nthreads=1); //class gri_fft_filter_ccc_sse; class gri_fft_filter_ccc_generic; @@ -39,7 +41,9 @@ class gri_fft_filter_ccc_generic; class GR_CORE_API gr_fft_filter_ccc : public gr_sync_decimator { private: - friend GR_CORE_API gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps); + friend GR_CORE_API gr_fft_filter_ccc_sptr + gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps, + int nthreads); int d_nsamples; bool d_updated; @@ -55,8 +59,10 @@ class GR_CORE_API gr_fft_filter_ccc : public gr_sync_decimator * * \param decimation >= 1 * \param taps complex filter taps + * \param nthreads number of threads for the FFT to use */ - gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps); + gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps, + int nthreads=1); public: ~gr_fft_filter_ccc (); @@ -64,6 +70,16 @@ class GR_CORE_API gr_fft_filter_ccc : public gr_sync_decimator void set_taps (const std::vector<gr_complex> &taps); std::vector<gr_complex> taps () const; + /*! + * \brief Set number of threads to use. + */ + void set_nthreads(int n); + + /*! + * \brief Get number of threads being used. + */ + int nthreads() const; + 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/filter/gr_fft_filter_ccc.i b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i index 812920d8b..acdc347a6 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i @@ -24,17 +24,23 @@ GR_SWIG_BLOCK_MAGIC(gr,fft_filter_ccc) gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, - const std::vector<gr_complex> &taps + const std::vector<gr_complex> &taps, + int nthreads=1 ) throw (std::invalid_argument); class gr_fft_filter_ccc : public gr_sync_decimator { private: - gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps); + gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps, + int nthreads=1); public: ~gr_fft_filter_ccc (); void set_taps (const std::vector<gr_complex> &taps); std::vector<gr_complex> taps () const; + + void set_nthreads(int n); + int nthreads() const; + }; diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc index c0a9b3483..e4a669150 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc @@ -26,7 +26,6 @@ #include <gr_fft_filter_fff.h> #include <gri_fft_filter_fff_generic.h> -//#include <gri_fft_filter_fff_sse.h> #include <gr_io_signature.h> #include <assert.h> #include <stdexcept> @@ -35,13 +34,17 @@ #include <iostream> #include <string.h> -gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps) +gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, + const std::vector<float> &taps, + int nthreads) { - return gnuradio::get_initial_sptr(new gr_fft_filter_fff (decimation, taps)); + return gnuradio::get_initial_sptr(new gr_fft_filter_fff (decimation, taps, nthreads)); } -gr_fft_filter_fff::gr_fft_filter_fff (int decimation, const std::vector<float> &taps) +gr_fft_filter_fff::gr_fft_filter_fff (int decimation, + const std::vector<float> &taps, + int nthreads) : gr_sync_decimator ("fft_filter_fff", gr_make_io_signature (1, 1, sizeof (float)), gr_make_io_signature (1, 1, sizeof (float)), @@ -51,10 +54,11 @@ gr_fft_filter_fff::gr_fft_filter_fff (int decimation, const std::vector<float> & set_history(1); #if 1 // don't enable the sse version until handling it is worked out - d_filter = new gri_fft_filter_fff_generic(decimation, taps); + d_filter = new gri_fft_filter_fff_generic(decimation, taps, nthreads); #else d_filter = new gri_fft_filter_fff_sse(decimation, taps); #endif + d_new_taps = taps; d_nsamples = d_filter->set_taps(taps); set_output_multiple(d_nsamples); @@ -78,6 +82,22 @@ gr_fft_filter_fff::taps () const return d_new_taps; } +void +gr_fft_filter_fff::set_nthreads(int n) +{ + if(d_filter) + d_filter->set_nthreads(n); +} + +int +gr_fft_filter_fff::nthreads() const +{ + if(d_filter) + return d_filter->nthreads(); + else + return 0; +} + int gr_fft_filter_fff::work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h index ddd8dcac2..2eeb8c646 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h @@ -27,7 +27,9 @@ class gr_fft_filter_fff; typedef boost::shared_ptr<gr_fft_filter_fff> gr_fft_filter_fff_sptr; -GR_CORE_API gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps); +GR_CORE_API gr_fft_filter_fff_sptr +gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps, + int nthreads=1); class gri_fft_filter_fff_generic; //class gri_fft_filter_fff_sse; @@ -39,7 +41,9 @@ class gri_fft_filter_fff_generic; class GR_CORE_API gr_fft_filter_fff : public gr_sync_decimator { private: - friend GR_CORE_API gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps); + friend GR_CORE_API gr_fft_filter_fff_sptr + gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps, + int nthreads); int d_nsamples; bool d_updated; @@ -55,15 +59,27 @@ class GR_CORE_API gr_fft_filter_fff : public gr_sync_decimator * * \param decimation >= 1 * \param taps float filter taps + * \param nthreads number of threads for the FFT to use */ - gr_fft_filter_fff (int decimation, const std::vector<float> &taps); - + gr_fft_filter_fff (int decimation, const std::vector<float> &taps, + int nthreads=1); + public: ~gr_fft_filter_fff (); void set_taps (const std::vector<float> &taps); std::vector<float> taps () const; + /*! + * \brief Set number of threads to use. + */ + void set_nthreads(int n); + + /*! + * \brief Get number of threads being used. + */ + int nthreads() const; + 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/filter/gr_fft_filter_fff.i b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i index 7e2cde977..c8118e09e 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i @@ -24,17 +24,22 @@ GR_SWIG_BLOCK_MAGIC(gr,fft_filter_fff) gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, - const std::vector<float> &taps + const std::vector<float> &taps, + int nthreads=1 ) throw (std::invalid_argument); class gr_fft_filter_fff : public gr_sync_decimator { private: - gr_fft_filter_fff (int decimation, const std::vector<float> &taps); + gr_fft_filter_fff (int decimation, const std::vector<float> &taps, + int nthreads=1); public: ~gr_fft_filter_fff (); void set_taps (const std::vector<float> &taps); std::vector<float> taps () const; + void set_nthreads(int n); + int nthreads() const; + }; diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc index 891905dd0..1a9273af0 100644 --- a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc +++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc @@ -26,6 +26,7 @@ #include <gri_fft_filter_ccc_generic.h> #include <gri_fft.h> +#include <volk/volk.h> #include <assert.h> #include <stdexcept> #include <cstdio> @@ -33,8 +34,9 @@ #include <fftw3.h> gri_fft_filter_ccc_generic::gri_fft_filter_ccc_generic (int decimation, - const std::vector<gr_complex> &taps) - : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0) + const std::vector<gr_complex> &taps, + int nthreads) + : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0), d_nthreads(nthreads) { set_taps(taps); } @@ -43,6 +45,7 @@ gri_fft_filter_ccc_generic::~gri_fft_filter_ccc_generic () { delete d_fwdfft; delete d_invfft; + gri_fft_free(d_xformed_taps); } #if 0 @@ -111,12 +114,28 @@ gri_fft_filter_ccc_generic::compute_sizes(int ntaps) if (d_fftsize != old_fftsize){ // compute new plans delete d_fwdfft; delete d_invfft; - d_fwdfft = new gri_fft_complex(d_fftsize, true); - d_invfft = new gri_fft_complex(d_fftsize, false); - d_xformed_taps.resize(d_fftsize); + d_fwdfft = new gri_fft_complex(d_fftsize, true, d_nthreads); + d_invfft = new gri_fft_complex(d_fftsize, false, d_nthreads); + d_xformed_taps = gri_fft_malloc_complex(d_fftsize); } } +void +gri_fft_filter_ccc_generic::set_nthreads(int n) +{ + d_nthreads = n; + if(d_fwdfft) + d_fwdfft->set_nthreads(n); + if(d_invfft) + d_invfft->set_nthreads(n); +} + +int +gri_fft_filter_ccc_generic::nthreads() const +{ + return d_nthreads; +} + int gri_fft_filter_ccc_generic::filter (int nitems, const gr_complex *input, gr_complex *output) { @@ -134,12 +153,10 @@ gri_fft_filter_ccc_generic::filter (int nitems, const gr_complex *input, gr_comp d_fwdfft->execute(); // compute fwd xform gr_complex *a = d_fwdfft->get_outbuf(); - gr_complex *b = &d_xformed_taps[0]; + gr_complex *b = d_xformed_taps; gr_complex *c = d_invfft->get_inbuf(); - for (j = 0; j < d_fftsize; j+=1) { // filter in the freq domain - c[j] = a[j] * b[j]; - } + volk_32fc_x2_multiply_32fc_a(c, a, b, d_fftsize); d_invfft->execute(); // compute inv xform diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h index 4db7ba50f..899b59e03 100644 --- a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h +++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h @@ -42,9 +42,10 @@ class GR_CORE_API gri_fft_filter_ccc_generic int d_decimation; gri_fft_complex *d_fwdfft; // forward "plan" gri_fft_complex *d_invfft; // inverse "plan" + int d_nthreads; // number of FFTW threads to use std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add - std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps std::vector<gr_complex> d_new_taps; + gr_complex *d_xformed_taps; // Fourier xformed taps void compute_sizes(int ntaps); int tailsize() const { return d_ntaps - 1; } @@ -57,8 +58,10 @@ class GR_CORE_API gri_fft_filter_ccc_generic * in other blocks for complex vectors (such as gr_fft_filter_ccc). * \param decimation The decimation rate of the filter (int) * \param taps The filter taps (complex) + * \param nthreads The number of threads for the FFT to use (int) */ - gri_fft_filter_ccc_generic (int decimation, const std::vector<gr_complex> &taps); + gri_fft_filter_ccc_generic (int decimation, const std::vector<gr_complex> &taps, + int nthreads=1); ~gri_fft_filter_ccc_generic (); /*! @@ -68,6 +71,16 @@ class GR_CORE_API gri_fft_filter_ccc_generic * \param taps The filter taps (complex) */ int set_taps (const std::vector<gr_complex> &taps); + + /*! + * \brief Set number of threads to use. + */ + void set_nthreads(int n); + + /*! + * \brief Get number of threads being used. + */ + int nthreads() const; /*! * \brief Perform the filter operation diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc index b3fbe1d1a..0989c9621 100644 --- a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc +++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc @@ -26,14 +26,16 @@ #include <gri_fft_filter_fff_generic.h> #include <gri_fft.h> +#include <volk/volk.h> #include <assert.h> #include <stdexcept> #include <cstdio> #include <cstring> gri_fft_filter_fff_generic::gri_fft_filter_fff_generic (int decimation, - const std::vector<float> &taps) - : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0) + const std::vector<float> &taps, + int nthreads) + : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0), d_nthreads(nthreads) { set_taps(taps); } @@ -42,6 +44,7 @@ gri_fft_filter_fff_generic::~gri_fft_filter_fff_generic () { delete d_fwdfft; delete d_invfft; + gri_fft_free(d_xformed_taps); } /* @@ -100,10 +103,26 @@ gri_fft_filter_fff_generic::compute_sizes(int ntaps) delete d_invfft; d_fwdfft = new gri_fft_real_fwd(d_fftsize); d_invfft = new gri_fft_real_rev(d_fftsize); - d_xformed_taps.resize(d_fftsize/2+1); + d_xformed_taps = gri_fft_malloc_complex(d_fftsize/2+1); } } +void +gri_fft_filter_fff_generic::set_nthreads(int n) +{ + d_nthreads = n; + if(d_fwdfft) + d_fwdfft->set_nthreads(n); + if(d_invfft) + d_invfft->set_nthreads(n); +} + +int +gri_fft_filter_fff_generic::nthreads() const +{ + return d_nthreads; +} + int gri_fft_filter_fff_generic::filter (int nitems, const float *input, float *output) { @@ -121,12 +140,10 @@ gri_fft_filter_fff_generic::filter (int nitems, const float *input, float *outpu d_fwdfft->execute(); // compute fwd xform gr_complex *a = d_fwdfft->get_outbuf(); - gr_complex *b = &d_xformed_taps[0]; + gr_complex *b = d_xformed_taps; gr_complex *c = d_invfft->get_inbuf(); - for (j = 0; j < d_fftsize/2+1; j++) { // filter in the freq domain - c[j] = a[j] * b[j]; - } + volk_32fc_x2_multiply_32fc_a(c, a, b, d_fftsize/2+1); d_invfft->execute(); // compute inv xform diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h index 86658043a..6ac30cef5 100644 --- a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h +++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h @@ -39,9 +39,10 @@ class GR_CORE_API gri_fft_filter_fff_generic int d_decimation; gri_fft_real_fwd *d_fwdfft; // forward "plan" gri_fft_real_rev *d_invfft; // inverse "plan" + int d_nthreads; // number of FFTW threads to use std::vector<float> d_tail; // state carried between blocks for overlap-add - std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps std::vector<float> d_new_taps; + gr_complex *d_xformed_taps; // Fourier xformed taps void compute_sizes(int ntaps); @@ -55,8 +56,10 @@ class GR_CORE_API gri_fft_filter_fff_generic * in other blocks for floating point vectors (such as gr_fft_filter_fff). * \param decimation The decimation rate of the filter (int) * \param taps The filter taps (float) + * \param nthreads The number of threads for the FFT to use (int) */ - gri_fft_filter_fff_generic (int decimation, const std::vector<float> &taps); + gri_fft_filter_fff_generic (int decimation, const std::vector<float> &taps, + int nthreads=1); ~gri_fft_filter_fff_generic (); /*! @@ -68,6 +71,16 @@ class GR_CORE_API gri_fft_filter_fff_generic int set_taps (const std::vector<float> &taps); /*! + * \brief Set number of threads to use. + */ + void set_nthreads(int n); + + /*! + * \brief Get number of threads being used. + */ + int nthreads() const; + + /*! * \brief Perform the filter operation * * \param nitems The number of items to produce diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h index b2832b3f6..673802dbb 100644 --- a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h +++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h @@ -38,6 +38,10 @@ class gr_fir_fff; * Although mu, the fractional delay, is specified as a float, it is actually * quantized. 0.0 <= mu <= 1.0. That is, mu is quantized in the interpolate * method to 32nd's of a sample. + * + * For more information, in the GNU Radio source code, see: + * \li gnuradio-core/src/gen_interpolator_taps/README + * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt */ class GR_CORE_API gri_mmse_fir_interpolator { diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h index 2feef114b..5b04600b3 100644 --- a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h +++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h @@ -39,6 +39,10 @@ class gr_fir_ccf; * Although mu, the fractional delay, is specified as a float, it is actually * quantized. 0.0 <= mu <= 1.0. That is, mu is quantized in the interpolate * method to 32nd's of a sample. + * + * For more information, in the GNU Radio source code, see: + * \li gnuradio-core/src/gen_interpolator_taps/README + * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt */ class GR_CORE_API gri_mmse_fir_interpolator_cc { diff --git a/gnuradio-core/src/lib/general/.gitignore b/gnuradio-core/src/lib/general/.gitignore index 4f3696f58..795dc793c 100644 --- a/gnuradio-core/src/lib/general/.gitignore +++ b/gnuradio-core/src/lib/general/.gitignore @@ -125,9 +125,6 @@ /gr_add_const_vss.cc /gr_add_const_vss.h /gr_add_const_vss.i -/gr_add_ff.cc -/gr_add_ff.h -/gr_add_ff.i /gr_add_ii.cc /gr_add_ii.h /gr_add_ii.i @@ -158,24 +155,12 @@ /gr_divide_ss.cc /gr_divide_ss.h /gr_divide_ss.i -/gr_multiply_cc.cc -/gr_multiply_cc.h -/gr_multiply_cc.i -/gr_multiply_const_cc.cc -/gr_multiply_const_cc.h -/gr_multiply_const_cc.i -/gr_multiply_const_ff.cc -/gr_multiply_const_ff.h -/gr_multiply_const_ff.i /gr_multiply_const_ii.cc /gr_multiply_const_ii.h /gr_multiply_const_ii.i /gr_multiply_const_ss.cc /gr_multiply_const_ss.h /gr_multiply_const_ss.i -/gr_multiply_ff.cc -/gr_multiply_ff.h -/gr_multiply_ff.i /gr_multiply_ii.cc /gr_multiply_ii.h /gr_multiply_ii.i diff --git a/gnuradio-core/src/lib/general/CMakeLists.txt b/gnuradio-core/src/lib/general/CMakeLists.txt index 6ecaa930a..2bc639cd3 100644 --- a/gnuradio-core/src/lib/general/CMakeLists.txt +++ b/gnuradio-core/src/lib/general/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2010-2011 Free Software Foundation, Inc. +# Copyright 2010-2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -178,6 +178,7 @@ endif(ENABLE_PYTHON) ######################################################################## set(gr_core_general_triple_threats complex_vec_test + gr_add_ff gr_additive_scrambler_bb gr_agc_cc gr_agc_ff @@ -187,6 +188,7 @@ set(gr_core_general_triple_threats gr_bin_statistics_f gr_bytes_to_syms gr_char_to_float + gr_char_to_short gr_check_counting_s gr_check_lfsr_32k_s gr_complex_to_interleaved_short @@ -229,6 +231,11 @@ set(gr_core_general_triple_threats gr_kludge_copy gr_lfsr_32k_source_s gr_map_bb + gr_multiply_cc + gr_multiply_ff + gr_multiply_const_cc + gr_multiply_const_ff + gr_multiply_conjugate_cc gr_nlog10_ff gr_nop gr_null_sink @@ -256,6 +263,7 @@ set(gr_core_general_triple_threats gr_rms_ff gr_repeat gr_short_to_float + gr_short_to_char gr_simple_correlator gr_simple_framer gr_simple_squelch_cc diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index 0122932cf..5b4a702e1 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2001,2002,2004,2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright 2001,2002,2004,2006-2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -37,6 +37,7 @@ EXTRA_DIST += \ libgeneral_la_SOURCES = \ complex_vec_test.cc \ + gr_add_ff.cc \ gr_additive_scrambler_bb.cc \ gr_agc_cc.cc \ gr_agc_ff.cc \ @@ -46,6 +47,7 @@ libgeneral_la_SOURCES = \ gr_bin_statistics_f.cc \ gr_bytes_to_syms.cc \ gr_char_to_float.cc \ + gr_char_to_short.cc \ gr_check_counting_s.cc \ gr_check_lfsr_32k_s.cc \ gr_circular_file.cc \ @@ -93,6 +95,11 @@ libgeneral_la_SOURCES = \ gr_lfsr_32k_source_s.cc \ gr_map_bb.cc \ gr_misc.cc \ + gr_multiply_cc.cc \ + gr_multiply_ff.cc \ + gr_multiply_const_cc.cc \ + gr_multiply_const_ff.cc \ + gr_multiply_conjugate_cc.cc \ gr_nlog10_ff.cc \ gr_nop.cc \ gr_null_sink.cc \ @@ -122,6 +129,7 @@ libgeneral_la_SOURCES = \ gr_reverse.cc \ gr_rms_cf.cc \ gr_rms_ff.cc \ + gr_short_to_char.cc \ gr_short_to_float.cc \ gr_int_to_float.cc \ gr_simple_correlator.cc \ @@ -187,6 +195,7 @@ grinclude_HEADERS = \ gr_core_api.h \ complex_vec_test.h \ gr_additive_scrambler_bb.h \ + gr_add_ff.h \ gr_agc_cc.h \ gr_agc_ff.h \ gr_agc2_cc.h \ @@ -195,6 +204,7 @@ grinclude_HEADERS = \ gr_bin_statistics_f.h \ gr_bytes_to_syms.h \ gr_char_to_float.h \ + gr_char_to_short.h \ gr_check_counting_s.h \ gr_check_lfsr_32k_s.h \ gr_circular_file.h \ @@ -246,6 +256,11 @@ grinclude_HEADERS = \ gr_map_bb.h \ gr_math.h \ gr_misc.h \ + gr_multiply_cc.h \ + gr_multiply_ff.h \ + gr_multiply_const_cc.h \ + gr_multiply_const_ff.h \ + gr_multiply_conjugate_cc.h \ gr_nco.h \ gr_nlog10_ff.h \ gr_nop.h \ @@ -276,6 +291,7 @@ grinclude_HEADERS = \ gr_reverse.h \ gr_rms_cf.h \ gr_rms_ff.h \ + gr_short_to_char.h \ gr_short_to_float.h \ gr_int_to_float.h \ gr_simple_correlator.h \ @@ -353,6 +369,7 @@ swiginclude_HEADERS = \ complex_vec_test.i \ general.i \ gr_additive_scrambler_bb.i \ + gr_add_ff.i \ gr_agc_cc.i \ gr_agc_ff.i \ gr_agc2_cc.i \ @@ -361,6 +378,7 @@ swiginclude_HEADERS = \ gr_bin_statistics_f.i \ gr_bytes_to_syms.i \ gr_char_to_float.i \ + gr_char_to_short.i \ gr_check_counting_s.i \ gr_check_lfsr_32k_s.i \ gr_complex_to_interleaved_short.i \ @@ -403,6 +421,11 @@ swiginclude_HEADERS = \ gr_kludge_copy.i \ gr_lfsr_32k_source_s.i \ gr_map_bb.i \ + gr_multiply_cc.i \ + gr_multiply_ff.i \ + gr_multiply_const_cc.i \ + gr_multiply_const_ff.i \ + gr_multiply_conjugate_cc.i \ gr_nlog10_ff.i \ gr_nop.i \ gr_null_sink.i \ @@ -430,6 +453,7 @@ swiginclude_HEADERS = \ gr_rms_cf.i \ gr_rms_ff.i \ gr_repeat.i \ + gr_short_to_char.i \ gr_short_to_float.i \ gr_simple_correlator.i \ gr_simple_framer.i \ diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 5a701bf80..89738b01a 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -44,8 +44,10 @@ #include <gr_float_to_char.h> #include <gr_float_to_uchar.h> #include <gr_short_to_float.h> +#include <gr_short_to_char.h> #include <gr_int_to_float.h> #include <gr_char_to_float.h> +#include <gr_char_to_short.h> #include <gr_uchar_to_float.h> #include <gr_frequency_modulator_fc.h> #include <gr_phase_modulator_fc.h> @@ -104,6 +106,11 @@ #include <gr_diff_decoder_bb.h> #include <gr_framer_sink_1.h> #include <gr_map_bb.h> +#include <gr_multiply_cc.h> +#include <gr_multiply_ff.h> +#include <gr_multiply_const_cc.h> +#include <gr_multiply_const_ff.h> +#include <gr_multiply_conjugate_cc.h> #include <gr_feval.h> #include <gr_pwr_squelch_cc.h> #include <gr_pwr_squelch_ff.h> @@ -134,6 +141,7 @@ #include <gr_burst_tagger.h> #include <gr_cpm.h> #include <gr_correlate_access_code_tag_bb.h> +#include <gr_add_ff.h> %} %include "gri_control_loop.i" @@ -158,8 +166,10 @@ %include "gr_float_to_char.i" %include "gr_float_to_uchar.i" %include "gr_short_to_float.i" +%include "gr_short_to_char.i" %include "gr_int_to_float.i" %include "gr_char_to_float.i" +%include "gr_char_to_short.i" %include "gr_uchar_to_float.i" %include "gr_frequency_modulator_fc.i" %include "gr_phase_modulator_fc.i" @@ -218,6 +228,11 @@ %include "gr_diff_decoder_bb.i" %include "gr_framer_sink_1.i" %include "gr_map_bb.i" +%include "gr_multiply_cc.i" +%include "gr_multiply_ff.i" +%include "gr_multiply_const_cc.i" +%include "gr_multiply_const_ff.i" +%include "gr_multiply_conjugate_cc.i" %include "gr_feval.i" %include "gr_pwr_squelch_cc.i" %include "gr_pwr_squelch_ff.i" @@ -248,3 +263,4 @@ %include "gr_burst_tagger.i" %include "gr_cpm.i" %include "gr_correlate_access_code_tag_bb.i" +%include "gr_add_ff.i" diff --git a/gnuradio-core/src/lib/general/general_generated.i b/gnuradio-core/src/lib/general/general_generated.i index a41f30a3d..e12f2b0ec 100644 --- a/gnuradio-core/src/lib/general/general_generated.i +++ b/gnuradio-core/src/lib/general/general_generated.i @@ -12,7 +12,6 @@ #include <gr_add_const_vff.h> #include <gr_add_const_vii.h> #include <gr_add_const_vss.h> -#include <gr_add_ff.h> #include <gr_add_ii.h> #include <gr_add_ss.h> #include <gr_add_vcc.h> @@ -29,16 +28,12 @@ #include <gr_divide_ff.h> #include <gr_divide_ii.h> #include <gr_divide_ss.h> -#include <gr_multiply_cc.h> -#include <gr_multiply_const_cc.h> -#include <gr_multiply_const_ff.h> #include <gr_multiply_const_ii.h> #include <gr_multiply_const_ss.h> #include <gr_multiply_const_vcc.h> #include <gr_multiply_const_vff.h> #include <gr_multiply_const_vii.h> #include <gr_multiply_const_vss.h> -#include <gr_multiply_ff.h> #include <gr_multiply_ii.h> #include <gr_multiply_ss.h> #include <gr_multiply_vcc.h> @@ -89,7 +84,6 @@ %include <gr_add_const_vff.i> %include <gr_add_const_vii.i> %include <gr_add_const_vss.i> -%include <gr_add_ff.i> %include <gr_add_ii.i> %include <gr_add_ss.i> %include <gr_add_vcc.i> @@ -106,16 +100,12 @@ %include <gr_divide_ff.i> %include <gr_divide_ii.i> %include <gr_divide_ss.i> -%include <gr_multiply_cc.i> -%include <gr_multiply_const_cc.i> -%include <gr_multiply_const_ff.i> %include <gr_multiply_const_ii.i> %include <gr_multiply_const_ss.i> %include <gr_multiply_const_vcc.i> %include <gr_multiply_const_vff.i> %include <gr_multiply_const_vii.i> %include <gr_multiply_const_vss.i> -%include <gr_multiply_ff.i> %include <gr_multiply_ii.i> %include <gr_multiply_ss.i> %include <gr_multiply_vcc.i> diff --git a/gnuradio-core/src/lib/general/gr_add_ff.cc b/gnuradio-core/src/lib/general/gr_add_ff.cc new file mode 100644 index 000000000..fc5455c98 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_add_ff.cc @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_add_ff.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_add_ff_sptr +gr_make_add_ff(size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_add_ff(vlen)); +} + +gr_add_ff::gr_add_ff (size_t vlen) + : gr_sync_block("add_ff", + gr_make_io_signature (1, -1, sizeof(float)*vlen), + gr_make_io_signature (1, 1, sizeof(float)*vlen)), + d_vlen (vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); +} + +int +gr_add_ff::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + float *out = (float *) output_items[0]; + int noi = d_vlen*noutput_items; + + memcpy(out, input_items[0], noi*sizeof(float)); + if(is_unaligned()) { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_add_32f_u(out, out, (const float*)input_items[i], noi); + } + else { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_add_32f_a(out, out, (const float*)input_items[i], noi); + } + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_add_ff.h b/gnuradio-core/src/lib/general/gr_add_ff.h new file mode 100644 index 000000000..6421f8da2 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_add_ff.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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_GR_ADD_FF_H +#define INCLUDED_GR_ADD_FF_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_add_ff; +typedef boost::shared_ptr<gr_add_ff> gr_add_ff_sptr; + +GR_CORE_API gr_add_ff_sptr +gr_make_add_ff (size_t vlen=1); + +/*! + * \brief Add streams of complex values + * \ingroup math_blk + */ + +class GR_CORE_API gr_add_ff : public gr_sync_block +{ + private: + friend GR_CORE_API gr_add_ff_sptr + gr_make_add_ff (size_t vlen); + gr_add_ff (size_t vlen); + + size_t d_vlen; + + public: + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_ADD_FF_H */ diff --git a/gnuradio-core/src/lib/general/gr_add_ff.i b/gnuradio-core/src/lib/general/gr_add_ff.i new file mode 100644 index 000000000..3c30640b1 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_add_ff.i @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,add_ff) + +gr_add_ff_sptr +gr_make_add_ff (size_t vlen=1); + +class gr_add_ff : public gr_sync_block +{ +public: + +}; diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.cc b/gnuradio-core/src/lib/general/gr_burst_tagger.cc index 4b3847b08..bd713d663 100644 --- a/gnuradio-core/src/lib/general/gr_burst_tagger.cc +++ b/gnuradio-core/src/lib/general/gr_burst_tagger.cc @@ -43,10 +43,39 @@ gr_burst_tagger::gr_burst_tagger(size_t itemsize) std::stringstream str; str << name() << unique_id(); - d_key = pmt::pmt_string_to_symbol("burst"); + d_true_key = pmt::pmt_string_to_symbol("burst"); + d_true_value = pmt::PMT_T; + + d_false_key = pmt::pmt_string_to_symbol("burst"); + d_false_value = pmt::PMT_F; + d_id = pmt::pmt_string_to_symbol(str.str()); } +void +gr_burst_tagger::set_true_tag (const std::string &key, bool value) +{ + d_true_key = pmt::pmt_string_to_symbol(key); + if(value == true) { + d_true_value = pmt::PMT_T; + } + else { + d_true_value = pmt::PMT_F; + } +} + +void +gr_burst_tagger::set_false_tag (const std::string &key, bool value) +{ + d_false_key = pmt::pmt_string_to_symbol(key); + if(value == true) { + d_false_value = pmt::PMT_T; + } + else { + d_false_value = pmt::PMT_F; + } +} + gr_burst_tagger::~gr_burst_tagger() { } @@ -66,18 +95,15 @@ gr_burst_tagger::work(int noutput_items, if(trigger[i] > 0) { if(d_state == false) { d_state = true; - pmt::pmt_t value = pmt::PMT_T; - add_item_tag(0, nitems_written(0)+i, d_key, value, d_id); + add_item_tag(0, nitems_written(0)+i, d_true_key, d_true_value, d_id); } } else { if(d_state == true) { d_state = false; - pmt::pmt_t value = pmt::PMT_F; - add_item_tag(0, nitems_written(0)+i, d_key, value, d_id); + add_item_tag(0, nitems_written(0)+i, d_false_key, d_false_value, d_id); } } } - return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.h b/gnuradio-core/src/lib/general/gr_burst_tagger.h index 7547ba9cc..663a146f2 100644 --- a/gnuradio-core/src/lib/general/gr_burst_tagger.h +++ b/gnuradio-core/src/lib/general/gr_burst_tagger.h @@ -40,14 +40,21 @@ class GR_CORE_API gr_burst_tagger : public gr_sync_block { size_t d_itemsize; bool d_state; - pmt::pmt_t d_key; + pmt::pmt_t d_true_key; + pmt::pmt_t d_true_value; + + pmt::pmt_t d_false_key; + pmt::pmt_t d_false_value; + pmt::pmt_t d_id; - + friend GR_CORE_API gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize); gr_burst_tagger(size_t itemsize); public: ~gr_burst_tagger(); + void set_true_tag (const std::string &key, bool value); + void set_false_tag (const std::string &key, bool value); int work(int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.i b/gnuradio-core/src/lib/general/gr_burst_tagger.i index ebf1eea8c..868941fc6 100644 --- a/gnuradio-core/src/lib/general/gr_burst_tagger.i +++ b/gnuradio-core/src/lib/general/gr_burst_tagger.i @@ -28,4 +28,8 @@ class gr_burst_tagger : public gr_sync_block { private: gr_burst_tagger(size_t itemsize); + + public: + void set_true_tag(const std::string &key, bool value); + void set_false_tag(const std::string &key, bool value); }; diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.cc b/gnuradio-core/src/lib/general/gr_char_to_float.cc index e68f8d208..ffe8ee4a1 100644 --- a/gnuradio-core/src/lib/general/gr_char_to_float.cc +++ b/gnuradio-core/src/lib/general/gr_char_to_float.cc @@ -26,30 +26,47 @@ #include <gr_char_to_float.h> #include <gr_io_signature.h> -#include <gri_char_to_float.h> +#include <volk/volk.h> gr_char_to_float_sptr -gr_make_char_to_float () +gr_make_char_to_float (size_t vlen, float scale) { - return gnuradio::get_initial_sptr(new gr_char_to_float ()); + return gnuradio::get_initial_sptr(new gr_char_to_float (vlen, scale)); } -gr_char_to_float::gr_char_to_float () +gr_char_to_float::gr_char_to_float (size_t vlen, float scale) : gr_sync_block ("gr_char_to_float", - gr_make_io_signature (1, 1, sizeof (char)), - gr_make_io_signature (1, 1, sizeof (float))) + gr_make_io_signature (1, 1, sizeof (char)*vlen), + gr_make_io_signature (1, 1, sizeof (float)*vlen)), + d_vlen(vlen), d_scale(scale) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); +} + +float +gr_char_to_float::scale() const +{ + return d_scale; +} + +void +gr_char_to_float::set_scale(float scale) +{ + d_scale = scale; } int gr_char_to_float::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { - const char *in = (const char *) input_items[0]; + const int8_t *in = (const int8_t *) input_items[0]; float *out = (float *) output_items[0]; - gri_char_to_float (in, out, noutput_items); - + // Note: the unaligned benchmarked much faster than the aligned + volk_8i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items); + return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.h b/gnuradio-core/src/lib/general/gr_char_to_float.h index b20d2066f..4ad8e59a8 100644 --- a/gnuradio-core/src/lib/general/gr_char_to_float.h +++ b/gnuradio-core/src/lib/general/gr_char_to_float.h @@ -30,7 +30,7 @@ class gr_char_to_float; typedef boost::shared_ptr<gr_char_to_float> gr_char_to_float_sptr; GR_CORE_API gr_char_to_float_sptr -gr_make_char_to_float (); +gr_make_char_to_float (size_t vlen=1, float scale=1); /*! * \brief Convert stream of chars to a stream of float @@ -39,10 +39,18 @@ gr_make_char_to_float (); class GR_CORE_API gr_char_to_float : public gr_sync_block { - friend GR_CORE_API gr_char_to_float_sptr gr_make_char_to_float (); - gr_char_to_float (); + private: + friend GR_CORE_API gr_char_to_float_sptr + gr_make_char_to_float (size_t vlen, float scale); + gr_char_to_float (size_t vlen, float scale); + + size_t d_vlen; + float d_scale; public: + float scale() const; + void set_scale(float scale); + virtual 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_char_to_float.i b/gnuradio-core/src/lib/general/gr_char_to_float.i index 0403b621d..65ad861f2 100644 --- a/gnuradio-core/src/lib/general/gr_char_to_float.i +++ b/gnuradio-core/src/lib/general/gr_char_to_float.i @@ -22,9 +22,12 @@ GR_SWIG_BLOCK_MAGIC(gr,char_to_float) -gr_char_to_float_sptr gr_make_char_to_float (); +gr_char_to_float_sptr +gr_make_char_to_float (size_t vlen=1, float scale=1); class gr_char_to_float : public gr_sync_block { - gr_char_to_float (); +public: + float scale() const; + void set_scale(float scale); }; diff --git a/gnuradio-core/src/lib/general/gr_char_to_short.cc b/gnuradio-core/src/lib/general/gr_char_to_short.cc new file mode 100644 index 000000000..8b6cd0be1 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_char_to_short.cc @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_char_to_short.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_char_to_short_sptr +gr_make_char_to_short (size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_char_to_short (vlen)); +} + +gr_char_to_short::gr_char_to_short (size_t vlen) + : gr_sync_block ("gr_char_to_short", + gr_make_io_signature (1, 1, sizeof (char)*vlen), + gr_make_io_signature (1, 1, sizeof (short)*vlen)), + d_vlen(vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(char); + set_alignment(alignment_multiple); +} + +int +gr_char_to_short::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const int8_t *in = (const int8_t *) input_items[0]; + int16_t *out = (int16_t *) output_items[0]; + + if(is_unaligned()) { + volk_8i_convert_16i_u(out, in, d_vlen*noutput_items); + } + else { + volk_8i_convert_16i_a(out, in, d_vlen*noutput_items); + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_char_to_short.h b/gnuradio-core/src/lib/general/gr_char_to_short.h new file mode 100644 index 000000000..58f9a62b0 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_char_to_short.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 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_GR_CHAR_TO_SHORT_H +#define INCLUDED_GR_CHAR_TO_SHORT_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_char_to_short; +typedef boost::shared_ptr<gr_char_to_short> gr_char_to_short_sptr; + +GR_CORE_API gr_char_to_short_sptr +gr_make_char_to_short (size_t vlen=1); + +/*! + * \brief Convert stream of chars to a stream of float + * \ingroup converter_blk + */ + +class GR_CORE_API gr_char_to_short : public gr_sync_block +{ + private: + friend GR_CORE_API gr_char_to_short_sptr + gr_make_char_to_short (size_t vlen); + gr_char_to_short (size_t vlen); + + size_t d_vlen; + + public: + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_CHAR_TO_SHORT_H */ diff --git a/gnuradio-core/src/lib/general/gr_char_to_short.i b/gnuradio-core/src/lib/general/gr_char_to_short.i new file mode 100644 index 000000000..48ddbf26b --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_char_to_short.i @@ -0,0 +1,30 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,char_to_short) + +gr_char_to_short_sptr gr_make_char_to_short (size_t vlen=1); + +class gr_char_to_short : public gr_sync_block +{ + +}; diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc index a59c127f3..108a92835 100644 --- a/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc +++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2008,2010 Free Software Foundation, Inc. + * Copyright 2004,2008,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -27,6 +27,7 @@ #include <gr_complex_to_xxx.h> #include <gr_io_signature.h> #include <gr_math.h> +#include <volk/volk.h> // ---------------------------------------------------------------- @@ -42,6 +43,9 @@ gr_complex_to_float::gr_complex_to_float (unsigned int vlen) gr_make_io_signature (1, 2, sizeof (float) * vlen)), d_vlen(vlen) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); } int @@ -56,16 +60,26 @@ gr_complex_to_float::work (int noutput_items, switch (output_items.size ()){ case 1: - for (int i = 0; i < noi; i++){ - out0[i] = in[i].real (); + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out0[i] = in[i].real (); + } + } + else { + volk_32fc_deinterleave_real_32f_a(out0, in, noi); } break; case 2: out1 = (float *) output_items[1]; - for (int i = 0; i < noi; i++){ - out0[i] = in[i].real (); - out1[i] = in[i].imag (); + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out0[i] = in[i].real (); + out1[i] = in[i].imag (); + } + } + else { + volk_32fc_deinterleave_32f_x2_a(out0, out1, in, noi); } break; @@ -90,6 +104,9 @@ gr_complex_to_real::gr_complex_to_real (unsigned int vlen) gr_make_io_signature (1, 1, sizeof (float) * vlen)), d_vlen(vlen) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); } int @@ -101,9 +118,15 @@ gr_complex_to_real::work (int noutput_items, float *out = (float *) output_items[0]; int noi = noutput_items * d_vlen; - for (int i = 0; i < noi; i++){ - out[i] = in[i].real (); + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out[i] = in[i].real (); + } + } + else { + volk_32fc_deinterleave_real_32f_a(out, in, noi); } + return noutput_items; } @@ -121,6 +144,9 @@ gr_complex_to_imag::gr_complex_to_imag (unsigned int vlen) gr_make_io_signature (1, 1, sizeof (float) * vlen)), d_vlen(vlen) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); } int @@ -132,9 +158,15 @@ gr_complex_to_imag::work (int noutput_items, float *out = (float *) output_items[0]; int noi = noutput_items * d_vlen; - for (int i = 0; i < noi; i++){ - out[i] = in[i].imag (); + if(is_unaligned()) { + for (int i = 0; i < noi; i++){ + out[i] = in[i].imag (); + } + } + else { + volk_32fc_deinterleave_imag_32f_a(out, in, noi); } + return noutput_items; } @@ -152,6 +184,9 @@ gr_complex_to_mag::gr_complex_to_mag (unsigned int vlen) gr_make_io_signature (1, 1, sizeof (float) * vlen)), d_vlen(vlen) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); } int @@ -163,9 +198,9 @@ gr_complex_to_mag::work (int noutput_items, float *out = (float *) output_items[0]; int noi = noutput_items * d_vlen; - for (int i = 0; i < noi; i++){ - out[i] = std::abs (in[i]); - } + // turned out to be faster than aligned/unaligned switching + volk_32fc_magnitude_32f_u(out, in, noi); + return noutput_items; } @@ -183,6 +218,9 @@ gr_complex_to_mag_squared::gr_complex_to_mag_squared (unsigned int vlen) gr_make_io_signature (1, 1, sizeof (float) * vlen)), d_vlen(vlen) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); } int @@ -194,11 +232,13 @@ gr_complex_to_mag_squared::work (int noutput_items, float *out = (float *) output_items[0]; int noi = noutput_items * d_vlen; - for (int i = 0; i < noi; i++){ - const float __x = in[i].real(); - const float __y = in[i].imag(); - out[i] = __x * __x + __y * __y; + if(is_unaligned()) { + volk_32fc_magnitude_squared_32f_u(out, in, noi); + } + else { + volk_32fc_magnitude_squared_32f_a(out, in, noi); } + return noutput_items; } @@ -216,6 +256,9 @@ gr_complex_to_arg::gr_complex_to_arg (unsigned int vlen) gr_make_io_signature (1, 1, sizeof (float) * vlen)), d_vlen(vlen) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); } int @@ -227,9 +270,11 @@ gr_complex_to_arg::work (int noutput_items, float *out = (float *) output_items[0]; int noi = noutput_items * d_vlen; + // The fast_atan2f is faster than Volk for (int i = 0; i < noi; i++){ // out[i] = std::arg (in[i]); out[i] = gr_fast_atan2f(in[i]); } + return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.h b/gnuradio-core/src/lib/general/gr_complex_to_xxx.h index 166403259..232071323 100644 --- a/gnuradio-core/src/lib/general/gr_complex_to_xxx.h +++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.h @@ -109,10 +109,11 @@ class GR_CORE_API gr_complex_to_imag : public gr_sync_block */ class GR_CORE_API gr_complex_to_mag : public gr_sync_block { - friend GR_CORE_API gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen); + friend GR_CORE_API gr_complex_to_mag_sptr + gr_make_complex_to_mag (unsigned int vlen); gr_complex_to_mag (unsigned int vlen); - unsigned int d_vlen; + unsigned int d_vlen; public: virtual int work (int noutput_items, diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc index 59c3bae89..d2b20ffe6 100644 --- a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc +++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc @@ -28,6 +28,7 @@ #include <gr_conjugate_cc.h> #include <gr_io_signature.h> +#include <volk/volk.h> gr_conjugate_cc_sptr gr_make_conjugate_cc () @@ -40,6 +41,9 @@ gr_conjugate_cc::gr_conjugate_cc () gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature (1, 1, sizeof (gr_complex))) { + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(alignment_multiple); } int @@ -50,26 +54,11 @@ gr_conjugate_cc::work (int noutput_items, gr_complex *iptr = (gr_complex *) input_items[0]; gr_complex *optr = (gr_complex *) output_items[0]; - int size = noutput_items; - - while (size >= 8){ - 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; + if(is_unaligned()) { + volk_32fc_conjugate_32fc_u(optr, iptr, noutput_items); } - - while (size-- > 0) { - *optr = conj(*iptr); - iptr++; - optr++; + else { + volk_32fc_conjugate_32fc_a(optr, iptr, noutput_items); } return noutput_items; diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc index b06346f59..aedd461f8 100644 --- a/gnuradio-core/src/lib/general/gr_delay.cc +++ b/gnuradio-core/src/lib/general/gr_delay.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2010 Free Software Foundation, Inc. + * Copyright 2007,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -35,30 +35,95 @@ gr_make_delay (size_t itemsize, int delay) } gr_delay::gr_delay (size_t itemsize, int delay) - : gr_sync_block ("delay", - gr_make_io_signature (1, -1, itemsize), - gr_make_io_signature (1, -1, itemsize)), + : gr_block ("delay", + gr_make_io_signature (1, -1, itemsize), + gr_make_io_signature (1, -1, itemsize)), d_itemsize(itemsize) { set_delay(delay); + d_delta = 0; +} + +void +gr_delay::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + // make sure all inputs have noutput_items available + unsigned ninputs = ninput_items_required.size (); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = noutput_items; +} + +void +gr_delay::set_delay (int d) +{ + // only set a new delta if there is a change in the delay; this + // protects from quickly-repeated calls to this function that would + // end with d_delta=0. + if(d != delay()) { + gruel::scoped_lock l(d_mutex_delay); + int old = delay(); + set_history(d+1); + d_delta += delay() - old; + } } int -gr_delay::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +gr_delay::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + gruel::scoped_lock l(d_mutex_delay); assert(input_items.size() == output_items.size()); const char *iptr; char *optr; + int cons, ret; - for(size_t i = 0; i < input_items.size(); i++) { - iptr = (const char *) input_items[i]; - optr = (char *) output_items[i]; + // No change in delay; just memcpy ins to outs + if(d_delta == 0) { + for(size_t i = 0; i < input_items.size(); i++) { + iptr = (const char *) input_items[i]; + optr = (char *) output_items[i]; + std::memcpy(optr, iptr, noutput_items*d_itemsize); + } + cons = noutput_items; + ret = noutput_items; + } - memcpy(optr, iptr, noutput_items*d_itemsize); + // Skip over d_delta items on the input + else if(d_delta < 0) { + int n_to_copy, n_adj; + int delta = -d_delta; + n_to_copy = std::max(0, noutput_items-delta); + n_adj = std::min(delta, noutput_items); + for(size_t i = 0; i < input_items.size(); i++) { + iptr = (const char *) input_items[i]; + optr = (char *) output_items[i]; + std::memcpy(optr, iptr+delta*d_itemsize, n_to_copy*d_itemsize); + } + cons = noutput_items; + ret = n_to_copy; + delta -= n_adj; + d_delta = -delta; } - return noutput_items; + //produce but not consume (inserts zeros) + else { // d_delta > 0 + int n_from_input, n_padding; + n_from_input = std::max(0, noutput_items-d_delta); + n_padding = std::min(d_delta, noutput_items); + for(size_t i = 0; i < input_items.size(); i++) { + iptr = (const char *) input_items[i]; + optr = (char *) output_items[i]; + std::memset(optr, 0, n_padding*d_itemsize); + std::memcpy(optr, iptr, n_from_input*d_itemsize); + } + cons = n_from_input; + ret = noutput_items; + d_delta -= n_padding; + } + + consume_each(cons); + return ret; } diff --git a/gnuradio-core/src/lib/general/gr_delay.h b/gnuradio-core/src/lib/general/gr_delay.h index 14de9af1f..55f525c38 100644 --- a/gnuradio-core/src/lib/general/gr_delay.h +++ b/gnuradio-core/src/lib/general/gr_delay.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007 Free Software Foundation, Inc. + * Copyright 2007,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,7 +24,8 @@ #define INCLUDED_GR_DELAY_H #include <gr_core_api.h> -#include <gr_sync_block.h> +#include <gr_block.h> +#include <gruel/thread.h> class gr_delay; typedef boost::shared_ptr<gr_delay> gr_delay_sptr; @@ -35,21 +36,26 @@ GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay); * \brief delay the input by a certain number of samples * \ingroup misc_blk */ -class GR_CORE_API gr_delay : public gr_sync_block +class GR_CORE_API gr_delay : public gr_block { friend GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay); gr_delay (size_t itemsize, int delay); + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + size_t d_itemsize; + int d_delta; + gruel::mutex d_mutex_delay; public: int delay () const { return history()-1; } - void set_delay (int delay) { set_history(delay+1); } + void set_delay (int delay); - 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); }; #endif diff --git a/gnuradio-core/src/lib/general/gr_delay.i b/gnuradio-core/src/lib/general/gr_delay.i index a527d008f..2e62a222f 100644 --- a/gnuradio-core/src/lib/general/gr_delay.i +++ b/gnuradio-core/src/lib/general/gr_delay.i @@ -24,7 +24,7 @@ GR_SWIG_BLOCK_MAGIC(gr,delay) gr_delay_sptr gr_make_delay (size_t itemsize, int delay); -class gr_delay : public gr_sync_block +class gr_delay : public gr_block { private: gr_delay (size_t itemsize, int delay); diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.cc b/gnuradio-core/src/lib/general/gr_fft_vcc.cc index d07f6fa07..f744acb93 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc.cc +++ b/gnuradio-core/src/lib/general/gr_fft_vcc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007,2008 Free Software Foundation, Inc. + * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -32,9 +32,12 @@ #include <string.h> gr_fft_vcc_sptr -gr_make_fft_vcc (int fft_size, bool forward,const std::vector<float> &window, bool shift) +gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads) { - return gr_make_fft_vcc_fftw(fft_size, forward, window, shift); + return gr_make_fft_vcc_fftw(fft_size, forward, + window, shift, nthreads); } gr_fft_vcc::gr_fft_vcc (const std::string &name, @@ -62,3 +65,16 @@ gr_fft_vcc::set_window(const std::vector<float> &window) else return false; } + +void +gr_fft_vcc::set_nthreads(int n) +{ + throw std::runtime_error("gr_fft_vcc::set_nthreads not implemented."); +} + +int +gr_fft_vcc::nthreads() const +{ + throw std::runtime_error("gr_fft_vcc::nthreads not implemented."); + return 0; +} diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.h b/gnuradio-core/src/lib/general/gr_fft_vcc.h index a7c8e1162..ceabeb681 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc.h +++ b/gnuradio-core/src/lib/general/gr_fft_vcc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007,2008 Free Software Foundation, Inc. + * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,9 @@ class gr_fft_vcc; typedef boost::shared_ptr<gr_fft_vcc> gr_fft_vcc_sptr; GR_CORE_API gr_fft_vcc_sptr -gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); +gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift=false, int nthreads=1); /*! * \brief Compute forward or reverse FFT. complex vector in / complex vector out. @@ -42,7 +44,9 @@ class GR_CORE_API gr_fft_vcc : public gr_sync_block { protected: friend GR_CORE_API gr_fft_vcc_sptr - gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift); unsigned int d_fft_size; std::vector<float> d_window; @@ -55,6 +59,9 @@ protected: public: ~gr_fft_vcc (); + virtual void set_nthreads(int n); + virtual int nthreads() const; + bool set_window(const std::vector<float> &window); }; diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.i b/gnuradio-core/src/lib/general/gr_fft_vcc.i index f35316e70..26d8b89a3 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc.i +++ b/gnuradio-core/src/lib/general/gr_fft_vcc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007,2008,2010 Free Software Foundation, Inc. + * Copyright 2004,2007,2008,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,13 +23,19 @@ GR_SWIG_BLOCK_MAGIC(gr, fft_vcc) gr_fft_vcc_sptr -gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); +gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift=false, int nthreads=1); class gr_fft_vcc : public gr_sync_block { protected: - gr_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift); public: bool set_window(const std::vector<float> &window); + void set_nthreads(int n); + int nthreads() const; }; diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc index 8a6b2fe8a..a99beb965 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc +++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc @@ -31,16 +31,21 @@ #include <string.h> gr_fft_vcc_sptr -gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift) +gr_make_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads) { - return gnuradio::get_initial_sptr(new gr_fft_vcc_fftw (fft_size, forward, window, shift)); + return gnuradio::get_initial_sptr(new gr_fft_vcc_fftw + (fft_size, forward, window, + shift, nthreads)); } gr_fft_vcc_fftw::gr_fft_vcc_fftw (int fft_size, bool forward, - const std::vector<float> &window, bool shift) + const std::vector<float> &window, + bool shift, int nthreads) : gr_fft_vcc("fft_vcc_fftw", fft_size, forward, window, shift) { - d_fft = new gri_fft_complex (d_fft_size, forward); + d_fft = new gri_fft_complex (d_fft_size, forward, nthreads); } gr_fft_vcc_fftw::~gr_fft_vcc_fftw () @@ -48,6 +53,18 @@ gr_fft_vcc_fftw::~gr_fft_vcc_fftw () delete d_fft; } +void +gr_fft_vcc_fftw::set_nthreads(int n) +{ + d_fft->set_nthreads(n); +} + +int +gr_fft_vcc_fftw::nthreads() const +{ + return d_fft->nthreads(); +} + int gr_fft_vcc_fftw::work (int noutput_items, gr_vector_const_void_star &input_items, @@ -70,7 +87,7 @@ gr_fft_vcc_fftw::work (int noutput_items, if(!d_forward && d_shift){ unsigned int offset = (!d_forward && d_shift)?(d_fft_size/2):0; int fft_m_offset = d_fft_size - offset; - for (unsigned int i = 0; i < offset; i++) // apply window + for (int i = 0; i < offset; i++) // apply window dst[i+fft_m_offset] = in[i] * d_window[i]; for (unsigned int i = offset; i < d_fft_size; i++) // apply window dst[i-offset] = in[i] * d_window[i]; diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h index 8535d133c..82b7512d7 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h +++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h @@ -29,7 +29,9 @@ class gri_fft_complex; GR_CORE_API gr_fft_vcc_sptr -gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); +gr_make_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift=false, int nthreads=1); /*! * \brief Compute forward or reverse FFT. complex vector in / complex vector out. @@ -40,15 +42,22 @@ gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &wind class GR_CORE_API gr_fft_vcc_fftw : public gr_fft_vcc { friend GR_CORE_API gr_fft_vcc_sptr - gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_make_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads); gri_fft_complex *d_fft; - gr_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads=1); public: ~gr_fft_vcc_fftw (); + void set_nthreads(int n); + int nthreads() const; + 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_fft_vfc.cc b/gnuradio-core/src/lib/general/gr_fft_vfc.cc index 561c63740..5fbe732dc 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vfc.cc +++ b/gnuradio-core/src/lib/general/gr_fft_vfc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -40,12 +40,17 @@ gr_fft_vfc_sptr -gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window) +gr_make_fft_vfc (int fft_size, bool forward, + const std::vector<float> &window, + int nthreads) { - return gnuradio::get_initial_sptr(new gr_fft_vfc (fft_size, forward, window)); + return gnuradio::get_initial_sptr(new gr_fft_vfc (fft_size, forward, + window, nthreads)); } -gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window) +gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, + const std::vector<float> &window, + int nthreads) : gr_sync_block ("fft_vfc", gr_make_io_signature (1, 1, fft_size * sizeof (float)), gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))), @@ -56,7 +61,7 @@ gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &wi throw std::invalid_argument ("fft_vfc: forward must == true"); } - d_fft = new gri_fft_complex (d_fft_size, forward); + d_fft = new gri_fft_complex (d_fft_size, forward, nthreads); set_window(window); } @@ -66,6 +71,18 @@ gr_fft_vfc::~gr_fft_vfc () delete d_fft; } +void +gr_fft_vfc::set_nthreads(int n) +{ + d_fft->set_nthreads(n); +} + +int +gr_fft_vfc::nthreads() const +{ + return d_fft->nthreads(); +} + int gr_fft_vfc::work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.h b/gnuradio-core/src/lib/general/gr_fft_vfc.h index 6cf6b9037..84ae08f08 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vfc.h +++ b/gnuradio-core/src/lib/general/gr_fft_vfc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -32,7 +32,9 @@ class gr_fft_vfc; typedef boost::shared_ptr<gr_fft_vfc> gr_fft_vfc_sptr; GR_CORE_API gr_fft_vfc_sptr -gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); +gr_make_fft_vfc (int fft_size, bool forward, + const std::vector<float> &window, + int nthreads=1); /*! * \brief Compute forward FFT. float vector in / complex vector out. @@ -42,17 +44,24 @@ gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); class GR_CORE_API gr_fft_vfc : public gr_sync_block { friend GR_CORE_API gr_fft_vfc_sptr - gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); + gr_make_fft_vfc (int fft_size, bool forward, + const std::vector<float> &window, + int nthreads); unsigned int d_fft_size; std::vector<float> d_window; gri_fft_complex *d_fft; - gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); + gr_fft_vfc (int fft_size, bool forward, + const std::vector<float> &window, + int nthreads=1); public: ~gr_fft_vfc (); + void set_nthreads(int n); + int nthreads() const; + 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_fft_vfc.i b/gnuradio-core/src/lib/general/gr_fft_vfc.i index 149745b58..4783ae1fe 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vfc.i +++ b/gnuradio-core/src/lib/general/gr_fft_vfc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,14 +23,20 @@ GR_SWIG_BLOCK_MAGIC(gr, fft_vfc) gr_fft_vfc_sptr -gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window) +gr_make_fft_vfc (int fft_size, bool forward, + const std::vector<float> &window, + int nthreads=1) throw(std::exception); class gr_fft_vfc : public gr_sync_block { protected: - gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); + gr_fft_vfc (int fft_size, bool forward, + const std::vector<float> &window, + int nthreads=1); public: bool set_window(const std::vector<float> &window); + void set_nthreads(int n); + int nthreads() const; }; diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.cc b/gnuradio-core/src/lib/general/gr_float_to_char.cc index 88b9d276e..14635ff71 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_char.cc +++ b/gnuradio-core/src/lib/general/gr_float_to_char.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,19 +26,35 @@ #include <gr_float_to_char.h> #include <gr_io_signature.h> -#include <gri_float_to_char.h> +#include <volk/volk.h> gr_float_to_char_sptr -gr_make_float_to_char () +gr_make_float_to_char (size_t vlen, float scale) { - return gnuradio::get_initial_sptr(new gr_float_to_char ()); + return gnuradio::get_initial_sptr(new gr_float_to_char (vlen, scale)); } -gr_float_to_char::gr_float_to_char () +gr_float_to_char::gr_float_to_char (size_t vlen, float scale) : gr_sync_block ("gr_float_to_char", - gr_make_io_signature (1, 1, sizeof (float)), - gr_make_io_signature (1, 1, sizeof (char))) + gr_make_io_signature (1, 1, sizeof (float)*vlen), + gr_make_io_signature (1, 1, sizeof (char)*vlen)), + d_vlen(vlen), d_scale(scale) { + const int alignment_multiple = + volk_get_alignment() / sizeof(char); + set_alignment(alignment_multiple); +} + +float +gr_float_to_char::scale() const +{ + return d_scale; +} + +void +gr_float_to_char::set_scale(float scale) +{ + d_scale = scale; } int @@ -47,9 +63,14 @@ gr_float_to_char::work (int noutput_items, gr_vector_void_star &output_items) { const float *in = (const float *) input_items[0]; - char *out = (char *) output_items[0]; + int8_t *out = (int8_t *) output_items[0]; - gri_float_to_char (in, out, noutput_items); + if(is_unaligned()) { + volk_32f_s32f_convert_8i_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32f_s32f_convert_8i_a(out, in, d_scale, d_vlen*noutput_items); + } return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.h b/gnuradio-core/src/lib/general/gr_float_to_char.h index 434e2e9d0..c88645a18 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_char.h +++ b/gnuradio-core/src/lib/general/gr_float_to_char.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,7 @@ class gr_float_to_char; typedef boost::shared_ptr<gr_float_to_char> gr_float_to_char_sptr; GR_CORE_API gr_float_to_char_sptr -gr_make_float_to_char (); +gr_make_float_to_char (size_t vlen=1, float scale=1); /*! * \brief Convert stream of float to a stream of char @@ -39,10 +39,18 @@ gr_make_float_to_char (); class GR_CORE_API gr_float_to_char : public gr_sync_block { - friend GR_CORE_API gr_float_to_char_sptr gr_make_float_to_char (); - gr_float_to_char (); + private: + friend GR_CORE_API gr_float_to_char_sptr gr_make_float_to_char + (size_t vlen, float scale); + gr_float_to_char (size_t vlen, float scale); + + size_t d_vlen; + float d_scale; public: + float scale() const; + void set_scale(float scale); + virtual 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_float_to_char.i b/gnuradio-core/src/lib/general/gr_float_to_char.i index 05b206554..a1c88750f 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_char.i +++ b/gnuradio-core/src/lib/general/gr_float_to_char.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,9 +22,12 @@ GR_SWIG_BLOCK_MAGIC(gr,float_to_char) -gr_float_to_char_sptr gr_make_float_to_char (); +gr_float_to_char_sptr +gr_make_float_to_char (size_t vlen=1, float scale=1); class gr_float_to_char : public gr_sync_block { - gr_float_to_char (); +public: + float scale() const; + void set_scale(float scale); }; diff --git a/gnuradio-core/src/lib/general/gr_float_to_int.cc b/gnuradio-core/src/lib/general/gr_float_to_int.cc index 2349de8cb..b69591043 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_int.cc +++ b/gnuradio-core/src/lib/general/gr_float_to_int.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2011 Free Software Foundation, Inc. + * Copyright 2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -27,32 +27,63 @@ #include <gr_float_to_int.h> #include <gr_io_signature.h> #include <gri_float_to_int.h> +#include <volk/volk.h> gr_float_to_int_sptr -gr_make_float_to_int () +gr_make_float_to_int (size_t vlen, float scale) { - return gnuradio::get_initial_sptr(new gr_float_to_int ()); + return gnuradio::get_initial_sptr(new gr_float_to_int (vlen, scale)); } -gr_float_to_int::gr_float_to_int () +gr_float_to_int::gr_float_to_int (size_t vlen, float scale) : gr_sync_block ("gr_float_to_int", - gr_make_io_signature (1, 1, sizeof (float)), - gr_make_io_signature (1, 1, sizeof (int))) + gr_make_io_signature (1, 1, sizeof (float)*vlen), + gr_make_io_signature (1, 1, sizeof (int)*vlen)), + d_vlen(vlen), d_scale(scale) { + const int alignment_multiple = + volk_get_alignment() / sizeof(int); + set_alignment(alignment_multiple); } +float +gr_float_to_int::scale() const +{ + return d_scale; +} + +void +gr_float_to_int::set_scale(float scale) +{ + d_scale = scale; +} int gr_float_to_int::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + // Disable the Volk for now. There is a problem for large 32-bit ints that + // are not properly represented by the precisions of a single float, which + // can cause wrapping from large, positive numbers to negative. + // In gri_float_to_int, the value is first promoted to a 64-bit + // value, clipped, then converted to a float. +#if 0 + const float *in = (const float *) input_items[0]; + int32_t *out = (int32_t *) output_items[0]; + + if(is_unaligned()) { + volk_32f_s32f_convert_32i_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32f_s32f_convert_32i_a(out, in, d_scale, d_vlen*noutput_items); + } +#else const float *in = (const float *) input_items[0]; int *out = (int *) output_items[0]; - gri_float_to_int (in, out, noutput_items); + gri_float_to_int (in, out, d_scale, d_vlen*noutput_items); + +#endif return noutput_items; } - - - diff --git a/gnuradio-core/src/lib/general/gr_float_to_int.h b/gnuradio-core/src/lib/general/gr_float_to_int.h index 3324ed110..0b42c0aab 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_int.h +++ b/gnuradio-core/src/lib/general/gr_float_to_int.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2011 Free Software Foundation, Inc. + * Copyright 2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,7 @@ class gr_float_to_int; typedef boost::shared_ptr<gr_float_to_int> gr_float_to_int_sptr; GR_CORE_API gr_float_to_int_sptr -gr_make_float_to_int (); +gr_make_float_to_int (size_t vlen=1, float scale=1); /*! * \brief Convert stream of float to a stream of short @@ -39,10 +39,18 @@ gr_make_float_to_int (); class GR_CORE_API gr_float_to_int : public gr_sync_block { - friend GR_CORE_API gr_float_to_int_sptr gr_make_float_to_int (); - gr_float_to_int (); + private: + friend GR_CORE_API + gr_float_to_int_sptr gr_make_float_to_int (size_t vlen, float scale); + gr_float_to_int (size_t vlen, float scale); + + size_t d_vlen; + float d_scale; public: + float scale() const; + void set_scale(float scale); + virtual 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_float_to_int.i b/gnuradio-core/src/lib/general/gr_float_to_int.i index 4ab04cbf2..6e71f54a9 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_int.i +++ b/gnuradio-core/src/lib/general/gr_float_to_int.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2011 Free Software Foundation, Inc. + * Copyright 2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,9 +22,12 @@ GR_SWIG_BLOCK_MAGIC(gr,float_to_int) -gr_float_to_int_sptr gr_make_float_to_int (); +gr_float_to_int_sptr +gr_make_float_to_int (size_t vlen=1, float scale=1); class gr_float_to_int : public gr_sync_block { - gr_float_to_int (); +public: + float scale() const; + void set_scale(float scale); }; diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.cc b/gnuradio-core/src/lib/general/gr_float_to_short.cc index 084f76f9c..188bfdae3 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_short.cc +++ b/gnuradio-core/src/lib/general/gr_float_to_short.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,19 +26,35 @@ #include <gr_float_to_short.h> #include <gr_io_signature.h> -#include <gri_float_to_short.h> +#include <volk/volk.h> gr_float_to_short_sptr -gr_make_float_to_short () +gr_make_float_to_short (size_t vlen, float scale) { - return gnuradio::get_initial_sptr(new gr_float_to_short ()); + return gnuradio::get_initial_sptr(new gr_float_to_short (vlen, scale)); } -gr_float_to_short::gr_float_to_short () +gr_float_to_short::gr_float_to_short (size_t vlen, float scale) : gr_sync_block ("gr_float_to_short", - gr_make_io_signature (1, 1, sizeof (float)), - gr_make_io_signature (1, 1, sizeof (short))) + gr_make_io_signature (1, 1, sizeof (float)*vlen), + gr_make_io_signature (1, 1, sizeof (short)*vlen)), + d_vlen(vlen), d_scale(scale) { + const int alignment_multiple = + volk_get_alignment() / sizeof(short); + set_alignment(alignment_multiple); +} + +float +gr_float_to_short::scale() const +{ + return d_scale; +} + +void +gr_float_to_short::set_scale(float scale) +{ + d_scale = scale; } int @@ -49,8 +65,13 @@ gr_float_to_short::work (int noutput_items, const float *in = (const float *) input_items[0]; short *out = (short *) output_items[0]; - gri_float_to_short (in, out, noutput_items); - + if(is_unaligned()) { + volk_32f_s32f_convert_16i_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32f_s32f_convert_16i_a(out, in, d_scale, d_vlen*noutput_items); + } + return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.h b/gnuradio-core/src/lib/general/gr_float_to_short.h index 010d61141..93e441f41 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_short.h +++ b/gnuradio-core/src/lib/general/gr_float_to_short.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,7 @@ class gr_float_to_short; typedef boost::shared_ptr<gr_float_to_short> gr_float_to_short_sptr; GR_CORE_API gr_float_to_short_sptr -gr_make_float_to_short (); +gr_make_float_to_short (size_t vlen=1, float scale=1); /*! * \brief Convert stream of float to a stream of short @@ -39,10 +39,17 @@ gr_make_float_to_short (); class GR_CORE_API gr_float_to_short : public gr_sync_block { - friend GR_CORE_API gr_float_to_short_sptr gr_make_float_to_short (); - gr_float_to_short (); + friend GR_CORE_API + gr_float_to_short_sptr gr_make_float_to_short (size_t vlen, float scale); + gr_float_to_short (size_t vlen, float scale); + + size_t d_vlen; + float d_scale; public: + float scale() const; + void set_scale(float scale); + virtual 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_float_to_short.i b/gnuradio-core/src/lib/general/gr_float_to_short.i index ad059c453..072da5213 100644 --- a/gnuradio-core/src/lib/general/gr_float_to_short.i +++ b/gnuradio-core/src/lib/general/gr_float_to_short.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,9 +22,12 @@ GR_SWIG_BLOCK_MAGIC(gr,float_to_short) -gr_float_to_short_sptr gr_make_float_to_short (); +gr_float_to_short_sptr +gr_make_float_to_short (size_t vlen=1, float scale=1); class gr_float_to_short : public gr_sync_block { - gr_float_to_short (); +public: + float scale() const; + void set_scale(float scale); }; diff --git a/gnuradio-core/src/lib/general/gr_int_to_float.cc b/gnuradio-core/src/lib/general/gr_int_to_float.cc index 29ca22add..7ec15b1a8 100644 --- a/gnuradio-core/src/lib/general/gr_int_to_float.cc +++ b/gnuradio-core/src/lib/general/gr_int_to_float.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2011 Free Software Foundation, Inc. + * Copyright 2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,19 +26,23 @@ #include <gr_int_to_float.h> #include <gr_io_signature.h> -#include <gri_int_to_float.h> +#include <volk/volk.h> gr_int_to_float_sptr -gr_make_int_to_float () +gr_make_int_to_float (size_t vlen, float scale) { - return gnuradio::get_initial_sptr(new gr_int_to_float ()); + return gnuradio::get_initial_sptr(new gr_int_to_float (vlen, scale)); } -gr_int_to_float::gr_int_to_float () +gr_int_to_float::gr_int_to_float (size_t vlen, float scale) : gr_sync_block ("gr_int_to_float", - gr_make_io_signature (1, 1, sizeof (int32_t)), - gr_make_io_signature (1, 1, sizeof (float))) + gr_make_io_signature (1, 1, sizeof (int32_t)*vlen), + gr_make_io_signature (1, 1, sizeof (float)*vlen)), + d_vlen(vlen), d_scale(scale) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); } int @@ -48,9 +52,14 @@ gr_int_to_float::work (int noutput_items, { const int32_t *in = (const int32_t *) input_items[0]; float *out = (float *) output_items[0]; - - gri_int_to_float(in, out, noutput_items); + if(is_unaligned()) { + volk_32i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_32i_s32f_convert_32f_a(out, in, d_scale, d_vlen*noutput_items); + } + return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_int_to_float.h b/gnuradio-core/src/lib/general/gr_int_to_float.h index 9af381ba9..af6488a50 100644 --- a/gnuradio-core/src/lib/general/gr_int_to_float.h +++ b/gnuradio-core/src/lib/general/gr_int_to_float.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2011 Free Software Foundation, Inc. + * Copyright 2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,7 @@ class gr_int_to_float; typedef boost::shared_ptr<gr_int_to_float> gr_int_to_float_sptr; GR_CORE_API gr_int_to_float_sptr -gr_make_int_to_float (); +gr_make_int_to_float (size_t vlen=1, float scale=1); /*! * \brief Convert stream of int to a stream of float @@ -39,10 +39,18 @@ gr_make_int_to_float (); class GR_CORE_API gr_int_to_float : public gr_sync_block { - friend GR_CORE_API gr_int_to_float_sptr gr_make_int_to_float (); - gr_int_to_float (); + private: + friend GR_CORE_API gr_int_to_float_sptr + gr_make_int_to_float (size_t vlen, float scale); + gr_int_to_float (size_t vlen, float scale); + + size_t d_vlen; + float d_scale; public: + float scale() const; + void set_scale(float scale); + virtual 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_int_to_float.i b/gnuradio-core/src/lib/general/gr_int_to_float.i index 8cb9e35b5..c1f25e37b 100644 --- a/gnuradio-core/src/lib/general/gr_int_to_float.i +++ b/gnuradio-core/src/lib/general/gr_int_to_float.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2011 Free Software Foundation, Inc. + * Copyright 2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,9 +22,11 @@ GR_SWIG_BLOCK_MAGIC(gr,int_to_float) -gr_int_to_float_sptr gr_make_int_to_float (); +gr_int_to_float_sptr +gr_make_int_to_float (size_t vlen=1, float scale=1); class gr_int_to_float : public gr_sync_block { - gr_int_to_float (); + float scale() const; + void set_scale(float scale); }; diff --git a/gnuradio-core/src/lib/general/gr_multiply_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_cc.cc new file mode 100644 index 000000000..0d20e6257 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_cc.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_multiply_cc.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_multiply_cc_sptr +gr_make_multiply_cc (size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_multiply_cc (vlen)); +} + +gr_multiply_cc::gr_multiply_cc (size_t vlen) + : gr_sync_block ("gr_multiply_cc", + gr_make_io_signature (1, -1, sizeof (gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)), + d_vlen(vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(alignment_multiple); +} + +int +gr_multiply_cc::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]; + int noi = d_vlen*noutput_items; + + memcpy(out, input_items[0], noi*sizeof(gr_complex)); + if(is_unaligned()) { + for(size_t i = 1; i < input_items.size(); i++) + volk_32fc_x2_multiply_32fc_u(out, out, (gr_complex*)input_items[i], noi); + } + else { + for(size_t i = 1; i < input_items.size(); i++) + volk_32fc_x2_multiply_32fc_a(out, out, (gr_complex*)input_items[i], noi); + } + return noutput_items; +} + + + diff --git a/gnuradio-core/src/lib/general/gr_multiply_cc.h b/gnuradio-core/src/lib/general/gr_multiply_cc.h new file mode 100644 index 000000000..f80ec8b25 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_cc.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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_GR_MULTIPLY_CC_H +#define INCLUDED_GR_MULTIPLY_CC_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_multiply_cc; +typedef boost::shared_ptr<gr_multiply_cc> gr_multiply_cc_sptr; + +GR_CORE_API gr_multiply_cc_sptr +gr_make_multiply_cc (size_t vlen=1); + +/*! + * \brief Multiply streams of complex values + * \ingroup math_blk + */ + +class GR_CORE_API gr_multiply_cc : public gr_sync_block +{ + private: + friend GR_CORE_API gr_multiply_cc_sptr + gr_make_multiply_cc (size_t vlen); + gr_multiply_cc (size_t vlen); + + size_t d_vlen; + + public: + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_MULTIPLY_CC_H */ diff --git a/gnuradio-core/src/lib/general/gr_multiply_cc.i b/gnuradio-core/src/lib/general/gr_multiply_cc.i new file mode 100644 index 000000000..61768c390 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_cc.i @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,multiply_cc) + +gr_multiply_cc_sptr +gr_make_multiply_cc (size_t vlen=1); + +class gr_multiply_cc : public gr_sync_block +{ +public: + +}; diff --git a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc new file mode 100644 index 000000000..103d87b8b --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_multiply_conjugate_cc.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_multiply_conjugate_cc_sptr +gr_make_multiply_conjugate_cc (size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_multiply_conjugate_cc (vlen)); +} + +gr_multiply_conjugate_cc::gr_multiply_conjugate_cc (size_t vlen) + : gr_sync_block ("gr_multiply_conjugate_cc", + gr_make_io_signature (2, 2, sizeof (gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)), + d_vlen(vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(alignment_multiple); +} + +int +gr_multiply_conjugate_cc::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr_complex *in0 = (gr_complex *) input_items[0]; + gr_complex *in1 = (gr_complex *) input_items[1]; + gr_complex *out = (gr_complex *) output_items[0]; + int noi = d_vlen*noutput_items; + + if(is_unaligned()) { + volk_32fc_x2_multiply_conjugate_32fc_u(out, in0, in1, noi); + } + else { + volk_32fc_x2_multiply_conjugate_32fc_a(out, in0, in1, noi); + } + + return noutput_items; +} + + + diff --git a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.h b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.h new file mode 100644 index 000000000..eb032f31b --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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_GR_MULTIPLY_CONJUGATE_CC_H +#define INCLUDED_GR_MULTIPLY_CONJUGATE_CC_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_multiply_conjugate_cc; +typedef boost::shared_ptr<gr_multiply_conjugate_cc> +gr_multiply_conjugate_cc_sptr; + +GR_CORE_API gr_multiply_conjugate_cc_sptr +gr_make_multiply_conjugate_cc (size_t vlen=1); + +/*! + * \brief Multiplies a stream by the conjugate of the second stream + * \ingroup math_blk + */ + +class GR_CORE_API gr_multiply_conjugate_cc : public gr_sync_block +{ + private: + friend GR_CORE_API gr_multiply_conjugate_cc_sptr + gr_make_multiply_conjugate_cc (size_t vlen); + gr_multiply_conjugate_cc (size_t vlen); + + size_t d_vlen; + + public: + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_MULTIPLY_CONJUGATE_CC_H */ diff --git a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.i b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.i new file mode 100644 index 000000000..023410505 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.i @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,multiply_conjugate_cc) + +gr_multiply_conjugate_cc_sptr +gr_make_multiply_conjugate_cc (size_t vlen=1); + +class gr_multiply_conjugate_cc : public gr_sync_block +{ +public: + +}; diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc new file mode 100644 index 000000000..59521f54a --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc @@ -0,0 +1,80 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_multiply_const_cc.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_multiply_const_cc_sptr +gr_make_multiply_const_cc (gr_complex k, size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_multiply_const_cc (k, vlen)); +} + +gr_multiply_const_cc::gr_multiply_const_cc (gr_complex k, size_t vlen) + : gr_sync_block ("gr_multiply_const_cc", + gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen), + gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)), + d_k(k), d_vlen(vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(gr_complex); + set_alignment(alignment_multiple); +} + +gr_complex +gr_multiply_const_cc::k() const +{ + return d_k; +} + +void +gr_multiply_const_cc::set_k(gr_complex k) +{ + d_k = k; +} + +int +gr_multiply_const_cc::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]; + gr_complex *out = (gr_complex *) output_items[0]; + int noi = d_vlen*noutput_items; + + if(is_unaligned()) { + volk_32fc_s32fc_multiply_32fc_u(out, in, d_k, noi); + } + else { + volk_32fc_s32fc_multiply_32fc_a(out, in, d_k, noi); + } + + return noutput_items; +} + + + diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_cc.h b/gnuradio-core/src/lib/general/gr_multiply_const_cc.h new file mode 100644 index 000000000..1791d9160 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_const_cc.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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_GR_MULTIPLY_CONST_CC_H +#define INCLUDED_GR_MULTIPLY_CONST_CC_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_multiply_const_cc; +typedef boost::shared_ptr<gr_multiply_const_cc> gr_multiply_const_cc_sptr; + +GR_CORE_API gr_multiply_const_cc_sptr +gr_make_multiply_const_cc (gr_complex k, size_t vlen=1); + +/*! + * \brief Multiply stream of complex values with a constant \p k + * \ingroup math_blk + */ + +class GR_CORE_API gr_multiply_const_cc : public gr_sync_block +{ + private: + friend GR_CORE_API gr_multiply_const_cc_sptr + gr_make_multiply_const_cc (gr_complex k, size_t vlen); + gr_multiply_const_cc (gr_complex k, size_t vlen); + + gr_complex d_k; + size_t d_vlen; + + public: + gr_complex k() const; + void set_k(gr_complex k); + + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_MULTIPLY_CONST_CC_H */ diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_cc.i b/gnuradio-core/src/lib/general/gr_multiply_const_cc.i new file mode 100644 index 000000000..be8d32b31 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_const_cc.i @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,multiply_const_cc) + +gr_multiply_const_cc_sptr +gr_make_multiply_const_cc (gr_complex k, size_t vlen=1); + +class gr_multiply_const_cc : public gr_sync_block +{ +public: + gr_complex k() const; + void set_k(gr_complex k); +}; diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc b/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc new file mode 100644 index 000000000..8354cb27b --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc @@ -0,0 +1,80 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_multiply_const_ff.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_multiply_const_ff_sptr +gr_make_multiply_const_ff (float k, size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_multiply_const_ff (k, vlen)); +} + +gr_multiply_const_ff::gr_multiply_const_ff (float k, size_t vlen) + : gr_sync_block ("gr_multiply_const_ff", + gr_make_io_signature (1, 1, sizeof (float)*vlen), + gr_make_io_signature (1, 1, sizeof (float)*vlen)), + d_k(k), d_vlen(vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); +} + +float +gr_multiply_const_ff::k() const +{ + return d_k; +} + +void +gr_multiply_const_ff::set_k(float k) +{ + d_k = k; +} + +int +gr_multiply_const_ff::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + int noi = d_vlen*noutput_items; + + if(is_unaligned()) { + volk_32f_s32f_multiply_32f_u(out, in, d_k, noi); + } + else { + volk_32f_s32f_multiply_32f_a(out, in, d_k, noi); + } + + return noutput_items; +} + + + diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_ff.h b/gnuradio-core/src/lib/general/gr_multiply_const_ff.h new file mode 100644 index 000000000..ef42a92f4 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_const_ff.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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_GR_MULTIPLY_CONST_FF_H +#define INCLUDED_GR_MULTIPLY_CONST_FF_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_multiply_const_ff; +typedef boost::shared_ptr<gr_multiply_const_ff> gr_multiply_const_ff_sptr; + +GR_CORE_API gr_multiply_const_ff_sptr +gr_make_multiply_const_ff (float k, size_t vlen=1); + +/*! + * \brief Multiply stream of float values with a constant \p k + * \ingroup math_blk + */ + +class GR_CORE_API gr_multiply_const_ff : public gr_sync_block +{ + private: + friend GR_CORE_API gr_multiply_const_ff_sptr + gr_make_multiply_const_ff (float k, size_t vlen); + gr_multiply_const_ff (float k, size_t vlen); + + float d_k; + size_t d_vlen; + + public: + float k() const; + void set_k(float k); + + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_MULTIPLY_CONST_FF_H */ diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_ff.i b/gnuradio-core/src/lib/general/gr_multiply_const_ff.i new file mode 100644 index 000000000..0fd3b1225 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_const_ff.i @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,multiply_const_ff) + +gr_multiply_const_ff_sptr +gr_make_multiply_const_ff (float k, size_t vlen=1); + +class gr_multiply_const_ff : public gr_sync_block +{ +public: + float k() const; + void set_k(float k); +}; diff --git a/gnuradio-core/src/lib/general/gr_multiply_ff.cc b/gnuradio-core/src/lib/general/gr_multiply_ff.cc new file mode 100644 index 000000000..a7d34ce51 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_ff.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_multiply_ff.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_multiply_ff_sptr +gr_make_multiply_ff (size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_multiply_ff (vlen)); +} + +gr_multiply_ff::gr_multiply_ff (size_t vlen) + : gr_sync_block ("gr_multiply_ff", + gr_make_io_signature (1, -1, sizeof (float)*vlen), + gr_make_io_signature (1, 1, sizeof (float)*vlen)), + d_vlen(vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); +} + +int +gr_multiply_ff::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + float *out = (float *) output_items[0]; + int noi = d_vlen*noutput_items; + + memcpy(out, input_items[0], noi*sizeof(float)); + if(is_unaligned()) { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_multiply_32f_u(out, out, (const float*)input_items[i], noi); + } + else { + for(size_t i = 1; i < input_items.size(); i++) + volk_32f_x2_multiply_32f_a(out, out, (const float*)input_items[i], noi); + } + return noutput_items; +} + + + diff --git a/gnuradio-core/src/lib/general/gr_multiply_ff.h b/gnuradio-core/src/lib/general/gr_multiply_ff.h new file mode 100644 index 000000000..ae36cb1e0 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_ff.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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_GR_MULTIPLY_FF_H +#define INCLUDED_GR_MULTIPLY_FF_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_multiply_ff; +typedef boost::shared_ptr<gr_multiply_ff> gr_multiply_ff_sptr; + +GR_CORE_API gr_multiply_ff_sptr +gr_make_multiply_ff (size_t vlen=1); + +/*! + * \brief Multiply streams of complex values + * \ingroup math_blk + */ + +class GR_CORE_API gr_multiply_ff : public gr_sync_block +{ + private: + friend GR_CORE_API gr_multiply_ff_sptr + gr_make_multiply_ff (size_t vlen); + gr_multiply_ff (size_t vlen); + + size_t d_vlen; + + public: + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_MULTIPLY_FF_H */ diff --git a/gnuradio-core/src/lib/general/gr_multiply_ff.i b/gnuradio-core/src/lib/general/gr_multiply_ff.i new file mode 100644 index 000000000..0f06301f2 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_multiply_ff.i @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,multiply_ff) + +gr_multiply_ff_sptr +gr_make_multiply_ff (size_t vlen=1); + +class gr_multiply_ff : public gr_sync_block +{ +public: + +}; diff --git a/gnuradio-core/src/lib/general/gr_short_to_char.cc b/gnuradio-core/src/lib/general/gr_short_to_char.cc new file mode 100644 index 000000000..a3c096e6d --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_short_to_char.cc @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_short_to_char.h> +#include <gr_io_signature.h> +#include <volk/volk.h> + +gr_short_to_char_sptr +gr_make_short_to_char (size_t vlen) +{ + return gnuradio::get_initial_sptr(new gr_short_to_char (vlen)); +} + +gr_short_to_char::gr_short_to_char (size_t vlen) + : gr_sync_block ("gr_short_to_char", + gr_make_io_signature (1, 1, sizeof (short)*vlen), + gr_make_io_signature (1, 1, sizeof (char)*vlen)), + d_vlen(vlen) +{ + const int alignment_multiple = + volk_get_alignment() / sizeof(char); + set_alignment(alignment_multiple); +} + +int +gr_short_to_char::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const int16_t *in = (const int16_t *) input_items[0]; + int8_t *out = (int8_t *) output_items[0]; + + if(is_unaligned()) { + volk_16i_convert_8i_u(out, in, d_vlen*noutput_items); + } + else { + volk_16i_convert_8i_a(out, in, d_vlen*noutput_items); + } + + return noutput_items; +} + + + diff --git a/gnuradio-core/src/lib/general/gr_short_to_char.h b/gnuradio-core/src/lib/general/gr_short_to_char.h new file mode 100644 index 000000000..9682d86ec --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_short_to_char.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 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_GR_SHORT_TO_CHAR_H +#define INCLUDED_GR_SHORT_TO_CHAR_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> + +class gr_short_to_char; +typedef boost::shared_ptr<gr_short_to_char> gr_short_to_char_sptr; + +GR_CORE_API gr_short_to_char_sptr +gr_make_short_to_char (size_t vlen=1); + +/*! + * \brief Convert stream of short to a stream of float + * \ingroup converter_blk + */ + +class GR_CORE_API gr_short_to_char : public gr_sync_block +{ + private: + friend GR_CORE_API gr_short_to_char_sptr + gr_make_short_to_char (size_t vlen); + gr_short_to_char (size_t vlen); + + size_t d_vlen; + + public: + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_SHORT_TO_CHAR_H */ diff --git a/gnuradio-core/src/lib/general/gr_short_to_char.i b/gnuradio-core/src/lib/general/gr_short_to_char.i new file mode 100644 index 000000000..330a4fdda --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_short_to_char.i @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,short_to_char) + +gr_short_to_char_sptr +gr_make_short_to_char (size_t vlen=1); + +class gr_short_to_char : public gr_sync_block +{ + +}; diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.cc b/gnuradio-core/src/lib/general/gr_short_to_float.cc index 7b80953ac..94d376a27 100644 --- a/gnuradio-core/src/lib/general/gr_short_to_float.cc +++ b/gnuradio-core/src/lib/general/gr_short_to_float.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,19 +26,35 @@ #include <gr_short_to_float.h> #include <gr_io_signature.h> -#include <gri_short_to_float.h> +#include <volk/volk.h> gr_short_to_float_sptr -gr_make_short_to_float () +gr_make_short_to_float (size_t vlen, float scale) { - return gnuradio::get_initial_sptr(new gr_short_to_float ()); + return gnuradio::get_initial_sptr(new gr_short_to_float (vlen, scale)); } -gr_short_to_float::gr_short_to_float () +gr_short_to_float::gr_short_to_float (size_t vlen, float scale) : gr_sync_block ("gr_short_to_float", - gr_make_io_signature (1, 1, sizeof (short)), - gr_make_io_signature (1, 1, sizeof (float))) + gr_make_io_signature (1, 1, sizeof (short)*vlen), + gr_make_io_signature (1, 1, sizeof (float)*vlen)), + d_vlen(vlen), d_scale(scale) { + const int alignment_multiple = + volk_get_alignment() / sizeof(float); + set_alignment(alignment_multiple); +} + +float +gr_short_to_float::scale() const +{ + return d_scale; +} + +void +gr_short_to_float::set_scale(float scale) +{ + d_scale = scale; } int @@ -49,8 +65,12 @@ gr_short_to_float::work (int noutput_items, const short *in = (const short *) input_items[0]; float *out = (float *) output_items[0]; - gri_short_to_float (in, out, noutput_items); - + if(is_unaligned()) { + volk_16i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items); + } + else { + volk_16i_s32f_convert_32f_a(out, in, d_scale, d_vlen*noutput_items); + } return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.h b/gnuradio-core/src/lib/general/gr_short_to_float.h index b40c966ea..efdc81ecd 100644 --- a/gnuradio-core/src/lib/general/gr_short_to_float.h +++ b/gnuradio-core/src/lib/general/gr_short_to_float.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,7 @@ class gr_short_to_float; typedef boost::shared_ptr<gr_short_to_float> gr_short_to_float_sptr; GR_CORE_API gr_short_to_float_sptr -gr_make_short_to_float (); +gr_make_short_to_float (size_t vlen=1, float scale=1); /*! * \brief Convert stream of short to a stream of float @@ -39,10 +39,18 @@ gr_make_short_to_float (); class GR_CORE_API gr_short_to_float : public gr_sync_block { - friend GR_CORE_API gr_short_to_float_sptr gr_make_short_to_float (); - gr_short_to_float (); - + private: + friend GR_CORE_API gr_short_to_float_sptr + gr_make_short_to_float (size_t vlen, float scale); + gr_short_to_float (size_t vlen, float scale); + + size_t d_vlen; + float d_scale; + public: + float scale() const; + void set_scale(float scale); + virtual 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_short_to_float.i b/gnuradio-core/src/lib/general/gr_short_to_float.i index 56759df29..229618890 100644 --- a/gnuradio-core/src/lib/general/gr_short_to_float.i +++ b/gnuradio-core/src/lib/general/gr_short_to_float.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,9 +22,12 @@ GR_SWIG_BLOCK_MAGIC(gr,short_to_float) -gr_short_to_float_sptr gr_make_short_to_float (); +gr_short_to_float_sptr +gr_make_short_to_float (size_t vlen=1, float scale=1); class gr_short_to_float : public gr_sync_block { - gr_short_to_float (); +public: + float scale() const; + void set_scale(float scale); }; diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc index 0df1af25d..2edb5f5aa 100644 --- a/gnuradio-core/src/lib/general/gri_fft.cc +++ b/gnuradio-core/src/lib/general/gri_fft.cc @@ -47,6 +47,24 @@ static int my_fftw_read_char(void *f) { return fgetc((FILE *) f); } #include <boost/filesystem/path.hpp> namespace fs = boost::filesystem; +gr_complex * +gri_fft_malloc_complex(int size) +{ + return (gr_complex*)fftwf_malloc(sizeof(gr_complex)*size); +} + +float * +gri_fft_malloc_float(int size) +{ + return (float*)fftwf_malloc(sizeof(float)*size); +} + +void +gri_fft_free(void *b) +{ + fftwf_free(b); +} + boost::mutex & gri_fft_planner::mutex() { @@ -78,6 +96,22 @@ gri_fftw_import_wisdom () } static void +gri_fftw_config_threading (int nthreads) +{ + static int fftw_threads_inited = 0; + +#ifdef FFTW3F_THREADS + if (fftw_threads_inited == 0) + { + fftw_threads_inited = 1; + fftwf_init_threads(); + } + + fftwf_plan_with_nthreads(nthreads); +#endif +} + +static void gri_fftw_export_wisdom () { const char *filename = wisdom_filename (); @@ -94,7 +128,7 @@ gri_fftw_export_wisdom () // ---------------------------------------------------------------- -gri_fft_complex::gri_fft_complex (int fft_size, bool forward) +gri_fft_complex::gri_fft_complex (int fft_size, bool forward, int nthreads) { // Hold global mutex during plan construction and destruction. gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); @@ -115,7 +149,10 @@ gri_fft_complex::gri_fft_complex (int fft_size, bool forward) throw std::runtime_error ("fftwf_malloc"); } + d_nthreads = nthreads; + gri_fftw_config_threading (nthreads); gri_fftw_import_wisdom (); // load prior wisdom from disk + d_plan = fftwf_plan_dft_1d (fft_size, reinterpret_cast<fftwf_complex *>(d_inbuf), reinterpret_cast<fftwf_complex *>(d_outbuf), @@ -139,6 +176,18 @@ gri_fft_complex::~gri_fft_complex () fftwf_free (d_outbuf); } +void +gri_fft_complex::set_nthreads(int n) +{ + if (n <= 0) + throw std::out_of_range ("gri_fftw: invalid number of threads"); + d_nthreads = n; + +#ifdef FFTW3F_THREADS + fftwf_plan_with_nthreads(d_nthreads); +#endif +} + void gri_fft_complex::execute () { @@ -147,7 +196,7 @@ gri_fft_complex::execute () // ---------------------------------------------------------------- -gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) +gri_fft_real_fwd::gri_fft_real_fwd (int fft_size, int nthreads) { // Hold global mutex during plan construction and destruction. gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); @@ -168,7 +217,10 @@ gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) throw std::runtime_error ("fftwf_malloc"); } + d_nthreads = nthreads; + gri_fftw_config_threading (nthreads); gri_fftw_import_wisdom (); // load prior wisdom from disk + d_plan = fftwf_plan_dft_r2c_1d (fft_size, d_inbuf, reinterpret_cast<fftwf_complex *>(d_outbuf), @@ -191,6 +243,18 @@ gri_fft_real_fwd::~gri_fft_real_fwd () fftwf_free (d_outbuf); } +void +gri_fft_real_fwd::set_nthreads(int n) +{ + if (n <= 0) + throw std::out_of_range ("gri_fftw: invalid number of threads"); + d_nthreads = n; + +#ifdef FFTW3F_THREADS + fftwf_plan_with_nthreads(d_nthreads); +#endif +} + void gri_fft_real_fwd::execute () { @@ -199,7 +263,7 @@ gri_fft_real_fwd::execute () // ---------------------------------------------------------------- -gri_fft_real_rev::gri_fft_real_rev (int fft_size) +gri_fft_real_rev::gri_fft_real_rev (int fft_size, int nthreads) { // Hold global mutex during plan construction and destruction. gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); @@ -220,11 +284,13 @@ gri_fft_real_rev::gri_fft_real_rev (int fft_size) throw std::runtime_error ("fftwf_malloc"); } + d_nthreads = nthreads; + gri_fftw_config_threading (nthreads); + gri_fftw_import_wisdom (); // load prior wisdom from disk + // FIXME If there's ever a chance that the planning functions // will be called in multiple threads, we've got to ensure single // threaded access. They are not thread-safe. - - gri_fftw_import_wisdom (); // load prior wisdom from disk d_plan = fftwf_plan_dft_c2r_1d (fft_size, reinterpret_cast<fftwf_complex *>(d_inbuf), d_outbuf, @@ -244,6 +310,18 @@ gri_fft_real_rev::~gri_fft_real_rev () fftwf_free (d_outbuf); } +void +gri_fft_real_rev::set_nthreads(int n) +{ + if (n <= 0) + throw std::out_of_range ("gri_fftw: invalid number of threads"); + d_nthreads = n; + +#ifdef FFTW3F_THREADS + fftwf_plan_with_nthreads(d_nthreads); +#endif +} + void gri_fft_real_rev::execute () { diff --git a/gnuradio-core/src/lib/general/gri_fft.h b/gnuradio-core/src/lib/general/gri_fft.h index 91a82fb55..f77a18e52 100644 --- a/gnuradio-core/src/lib/general/gri_fft.h +++ b/gnuradio-core/src/lib/general/gri_fft.h @@ -30,6 +30,19 @@ #include <gr_complex.h> #include <boost/thread.hpp> +/*! \brief Helper function for allocating complex fft buffers + */ +gr_complex* gri_fft_malloc_complex(int size); + +/*! \brief Helper function for allocating float fft buffers + */ +float* gri_fft_malloc_float(int size); + +/*! \brief Helper function for freeing fft buffers + */ +void gri_fft_free(void *b); + + /*! * \brief Export reference to planner mutex for those apps that * want to use FFTW w/o using the gri_fftw* classes. @@ -49,12 +62,13 @@ public: */ class GR_CORE_API gri_fft_complex { int d_fft_size; + int d_nthreads; gr_complex *d_inbuf; gr_complex *d_outbuf; void *d_plan; public: - gri_fft_complex (int fft_size, bool forward = true); + gri_fft_complex (int fft_size, bool forward = true, int nthreads=1); virtual ~gri_fft_complex (); /* @@ -69,6 +83,16 @@ public: int outbuf_length () const { return d_fft_size; } /*! + * Set the number of threads to use for caclulation. + */ + void set_nthreads(int n); + + /*! + * Get the number of threads being used by FFTW + */ + int nthreads() const { return d_nthreads; } + + /*! * compute FFT. The input comes from inbuf, the output is placed in outbuf. */ void execute (); @@ -80,12 +104,13 @@ public: */ class GR_CORE_API gri_fft_real_fwd { int d_fft_size; + int d_nthreads; float *d_inbuf; gr_complex *d_outbuf; void *d_plan; public: - gri_fft_real_fwd (int fft_size); + gri_fft_real_fwd (int fft_size, int nthreads=1); virtual ~gri_fft_real_fwd (); /* @@ -100,6 +125,16 @@ public: int outbuf_length () const { return d_fft_size / 2 + 1; } /*! + * Set the number of threads to use for caclulation. + */ + void set_nthreads(int n); + + /*! + * Get the number of threads being used by FFTW + */ + int nthreads() const { return d_nthreads; } + + /*! * compute FFT. The input comes from inbuf, the output is placed in outbuf. */ void execute (); @@ -111,12 +146,13 @@ public: */ class GR_CORE_API gri_fft_real_rev { int d_fft_size; + int d_nthreads; gr_complex *d_inbuf; float *d_outbuf; void *d_plan; public: - gri_fft_real_rev (int fft_size); + gri_fft_real_rev (int fft_size, int nthreads=1); virtual ~gri_fft_real_rev (); /* @@ -131,6 +167,16 @@ public: int outbuf_length () const { return d_fft_size; } /*! + * Set the number of threads to use for caclulation. + */ + void set_nthreads(int n); + + /*! + * Get the number of threads being used by FFTW + */ + int nthreads() const { return d_nthreads; } + + /*! * compute FFT. The input comes from inbuf, the output is placed in outbuf. */ void execute (); diff --git a/gnuradio-core/src/lib/general/gri_float_to_int.cc b/gnuradio-core/src/lib/general/gri_float_to_int.cc index 5271e60e2..0b0b10dfe 100644 --- a/gnuradio-core/src/lib/general/gri_float_to_int.cc +++ b/gnuradio-core/src/lib/general/gri_float_to_int.cc @@ -34,10 +34,10 @@ static const int64_t MIN_INT = -2147483647; // -(2^31)-1 void -gri_float_to_int (const float *in, int *out, int nsamples) +gri_float_to_int (const float *in, int *out, float scale, int nsamples) { for (int i = 0; i < nsamples; i++){ - int64_t r = llrintf(in[i]); + int64_t r = llrintf(scale * in[i]); if (r < MIN_INT) r = MIN_INT; else if (r > MAX_INT) diff --git a/gnuradio-core/src/lib/general/gri_float_to_int.h b/gnuradio-core/src/lib/general/gri_float_to_int.h index a2f6ea877..d8b98efc1 100644 --- a/gnuradio-core/src/lib/general/gri_float_to_int.h +++ b/gnuradio-core/src/lib/general/gri_float_to_int.h @@ -28,6 +28,6 @@ /*! * convert array of floats to int with rounding and saturation. */ -GR_CORE_API void gri_float_to_int (const float *in, int *out, int nsamples); +GR_CORE_API void gri_float_to_int (const float *in, int *out, float scale, int nsamples); #endif /* INCLUDED_GRI_FLOAT_TO_INT_H */ diff --git a/gnuradio-core/src/lib/gengen/.gitignore b/gnuradio-core/src/lib/gengen/.gitignore index ecd4cb0d5..b91d2f197 100644 --- a/gnuradio-core/src/lib/gengen/.gitignore +++ b/gnuradio-core/src/lib/gengen/.gitignore @@ -124,9 +124,6 @@ /gr_add_const_vss.cc /gr_add_const_vss.h /gr_add_const_vss.i -/gr_add_ff.cc -/gr_add_ff.h -/gr_add_ff.i /gr_add_ii.cc /gr_add_ii.h /gr_add_ii.i @@ -202,15 +199,6 @@ /gr_max_ss.cc /gr_max_ss.h /gr_max_ss.i -/gr_multiply_cc.cc -/gr_multiply_cc.h -/gr_multiply_cc.i -/gr_multiply_const_cc.cc -/gr_multiply_const_cc.h -/gr_multiply_const_cc.i -/gr_multiply_const_ff.cc -/gr_multiply_const_ff.h -/gr_multiply_const_ff.i /gr_multiply_const_ii.cc /gr_multiply_const_ii.h /gr_multiply_const_ii.i @@ -229,9 +217,6 @@ /gr_multiply_const_vss.cc /gr_multiply_const_vss.h /gr_multiply_const_vss.i -/gr_multiply_ff.cc -/gr_multiply_ff.h -/gr_multiply_ff.i /gr_multiply_ii.cc /gr_multiply_ii.h /gr_multiply_ii.i diff --git a/gnuradio-core/src/lib/gengen/CMakeLists.txt b/gnuradio-core/src/lib/gengen/CMakeLists.txt index a7292f131..98b149e97 100644 --- a/gnuradio-core/src/lib/gengen/CMakeLists.txt +++ b/gnuradio-core/src/lib/gengen/CMakeLists.txt @@ -86,10 +86,10 @@ expand_h_cc_i(gr_noise_source_X s i f c) expand_h_cc_i(gr_sig_source_X s i f c) expand_h_cc_i(gr_add_const_XX ss ii ff cc sf) -expand_h_cc_i(gr_multiply_const_XX ss ii ff cc) -expand_h_cc_i(gr_add_XX ss ii ff cc) +expand_h_cc_i(gr_multiply_const_XX ss ii) +expand_h_cc_i(gr_add_XX ss ii cc) expand_h_cc_i(gr_sub_XX ss ii ff cc) -expand_h_cc_i(gr_multiply_XX ss ii ff cc) +expand_h_cc_i(gr_multiply_XX ss ii) expand_h_cc_i(gr_divide_XX ss ii ff cc) expand_h_cc_i(gr_mute_XX ss ii ff cc) expand_h_cc_i(gr_add_const_vXX ss ii ff cc) diff --git a/gnuradio-core/src/lib/gengen/Makefile.gen b/gnuradio-core/src/lib/gengen/Makefile.gen index 1c529803c..db260585f 100644 --- a/gnuradio-core/src/lib/gengen/Makefile.gen +++ b/gnuradio-core/src/lib/gengen/Makefile.gen @@ -12,7 +12,6 @@ GENERATED_H = \ gr_add_const_vff.h \ gr_add_const_vii.h \ gr_add_const_vss.h \ - gr_add_ff.h \ gr_add_ii.h \ gr_add_ss.h \ gr_and_bb.h \ @@ -45,16 +44,12 @@ GENERATED_H = \ gr_moving_average_ff.h \ gr_moving_average_ii.h \ gr_moving_average_ss.h \ - gr_multiply_cc.h \ - gr_multiply_const_cc.h \ - gr_multiply_const_ff.h \ gr_multiply_const_ii.h \ gr_multiply_const_ss.h \ gr_multiply_const_vcc.h \ gr_multiply_const_vff.h \ gr_multiply_const_vii.h \ gr_multiply_const_vss.h \ - gr_multiply_ff.h \ gr_multiply_ii.h \ gr_multiply_ss.h \ gr_mute_cc.h \ @@ -117,7 +112,6 @@ GENERATED_I = \ gr_add_const_vff.i \ gr_add_const_vii.i \ gr_add_const_vss.i \ - gr_add_ff.i \ gr_add_ii.i \ gr_add_ss.i \ gr_and_bb.i \ @@ -150,16 +144,12 @@ GENERATED_I = \ gr_moving_average_ff.i \ gr_moving_average_ii.i \ gr_moving_average_ss.i \ - gr_multiply_cc.i \ - gr_multiply_const_cc.i \ - gr_multiply_const_ff.i \ gr_multiply_const_ii.i \ gr_multiply_const_ss.i \ gr_multiply_const_vcc.i \ gr_multiply_const_vff.i \ gr_multiply_const_vii.i \ gr_multiply_const_vss.i \ - gr_multiply_ff.i \ gr_multiply_ii.i \ gr_multiply_ss.i \ gr_mute_cc.i \ @@ -222,7 +212,6 @@ GENERATED_CC = \ gr_add_const_vff.cc \ gr_add_const_vii.cc \ gr_add_const_vss.cc \ - gr_add_ff.cc \ gr_add_ii.cc \ gr_add_ss.cc \ gr_and_bb.cc \ @@ -255,16 +244,12 @@ GENERATED_CC = \ gr_moving_average_ff.cc \ gr_moving_average_ii.cc \ gr_moving_average_ss.cc \ - gr_multiply_cc.cc \ - gr_multiply_const_cc.cc \ - gr_multiply_const_ff.cc \ gr_multiply_const_ii.cc \ gr_multiply_const_ss.cc \ gr_multiply_const_vcc.cc \ gr_multiply_const_vff.cc \ gr_multiply_const_vii.cc \ gr_multiply_const_vss.cc \ - gr_multiply_ff.cc \ gr_multiply_ii.cc \ gr_multiply_ss.cc \ gr_mute_cc.cc \ diff --git a/gnuradio-core/src/lib/gengen/generate_common.py b/gnuradio-core/src/lib/gengen/generate_common.py index 9bd6bcc9c..6da2044e0 100755 --- a/gnuradio-core/src/lib/gengen/generate_common.py +++ b/gnuradio-core/src/lib/gengen/generate_common.py @@ -41,10 +41,7 @@ reg_signatures = ['ss', 'ii', 'ff', 'cc'] reg_roots = [ 'gr_add_const_XX', - 'gr_multiply_const_XX', - 'gr_add_XX', 'gr_sub_XX', - 'gr_multiply_XX', 'gr_divide_XX', 'gr_mute_XX', 'gr_add_const_vXX', @@ -66,7 +63,10 @@ others = ( ('gr_sample_and_hold_XX', ('bb','ss','ii','ff')), ('gr_argmax_XX', ('fs','is','ss')), ('gr_max_XX', ('ff','ii','ss')), - ('gr_peak_detector_XX', ('fb','ib','sb')) + ('gr_peak_detector_XX', ('fb','ib','sb')), + ('gr_multiply_XX', ('ss','ii')), + ('gr_multiply_const_XX', ('ss','ii')), + ('gr_add_XX', ('ss','cc','ii')) ) diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.cc b/gnuradio-core/src/lib/io/gr_oscope_guts.cc index 7bdc53ab0..8b0d1e632 100644 --- a/gnuradio-core/src/lib/io/gr_oscope_guts.cc +++ b/gnuradio-core/src/lib/io/gr_oscope_guts.cc @@ -31,23 +31,36 @@ #include <math.h> #include <assert.h> -static const int OUTPUT_RECORD_SIZE = 8192; // Must be power of 2 +/* + * Bad performance if it's large, and flaky triggering if it's too small + */ +static const int OUTPUT_RECORD_SIZE = 1024; // Must be power of 2 + +/* + * For (slow-updated) STRIPCHART triggering, we make the record size larger, since we + * potentially want to be able to "see" hours of data. This works as long as the + * update rates to a STRIPCHART are low, which they generally are--that's rather what + * a stripchart is all about! + */ +static const int SCHART_MULT = 8; + + static inline int -wrap_bi (int buffer_index) // wrap buffer index +wrap_bi (int buffer_index, int mx) // wrap buffer index { - return buffer_index & (OUTPUT_RECORD_SIZE - 1); + return buffer_index & (mx - 1); } static inline int -incr_bi (int buffer_index) // increment buffer index +incr_bi (int buffer_index, int mx) // increment buffer index { - return wrap_bi (buffer_index + 1); + return wrap_bi (buffer_index + 1, mx); } static inline int -decr_bi (int buffer_index) // decrement buffer index +decr_bi (int buffer_index, int mx) // decrement buffer index { - return wrap_bi (buffer_index - 1); + return wrap_bi (buffer_index - 1, mx); } gr_oscope_guts::gr_oscope_guts (double sample_rate, gr_msg_queue_sptr msgq) @@ -73,8 +86,8 @@ gr_oscope_guts::gr_oscope_guts (double sample_rate, gr_msg_queue_sptr msgq) d_buffer[i] = 0; for (int i = 0; i < MAX_CHANNELS; i++){ - d_buffer[i] = new float [OUTPUT_RECORD_SIZE]; - for (int j = 0; j < OUTPUT_RECORD_SIZE; j++) + d_buffer[i] = new float [OUTPUT_RECORD_SIZE*SCHART_MULT]; + for (int j = 0; j < OUTPUT_RECORD_SIZE*SCHART_MULT; j++) d_buffer[i][j] = 0.0; } @@ -132,13 +145,13 @@ gr_oscope_guts::process_sample (const float *channel_data) assert (0); } - d_obi = incr_bi (d_obi); + d_obi = incr_bi (d_obi, OUTPUT_RECORD_SIZE); } else { for (int i = 0; i < d_nchannels; i++) { - for (int j = OUTPUT_RECORD_SIZE-1; j > 0; j--) + for (int j = (OUTPUT_RECORD_SIZE*SCHART_MULT)-1; j > 0; j--) { d_buffer[i][j] = d_buffer[i][j-1]; } @@ -183,7 +196,10 @@ gr_oscope_guts::enter_post_trigger () bool gr_oscope_guts::found_trigger () { - float prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi)]; + int mx = d_trigger_mode == gr_TRIG_MODE_STRIPCHART ? OUTPUT_RECORD_SIZE*SCHART_MULT : + OUTPUT_RECORD_SIZE; + + float prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi, mx)]; float new_sample = d_buffer[d_trigger_channel][d_obi]; switch (d_trigger_mode){ @@ -224,6 +240,11 @@ gr_oscope_guts::found_trigger () void gr_oscope_guts::write_output_records () { + int mx; + + mx = d_trigger_mode == gr_TRIG_MODE_STRIPCHART ? + OUTPUT_RECORD_SIZE*SCHART_MULT : OUTPUT_RECORD_SIZE; + // if the output queue if full, drop the data like its hot. if (d_msgq->full_p()) return; @@ -231,17 +252,17 @@ gr_oscope_guts::write_output_records () gr_message_sptr msg = gr_make_message(0, // msg type d_nchannels, // arg1 for other side - OUTPUT_RECORD_SIZE, // arg2 for other side - ((d_nchannels * OUTPUT_RECORD_SIZE) + 1) * sizeof(float)); // sizeof payload + mx, // arg2 for other side + ((d_nchannels * mx) + 1) * sizeof(float)); // sizeof payload float *out = (float *)msg->msg(); // get pointer to raw message buffer for (int ch = 0; ch < d_nchannels; ch++){ // note that d_obi + 1 points at the oldest sample in the buffer - for (int i = 0; i < OUTPUT_RECORD_SIZE; i++){ - out[i] = d_buffer[ch][wrap_bi(d_obi + 1 + i)]; + for (int i = 0; i < mx; i++){ + out[i] = d_buffer[ch][wrap_bi(d_obi + 1 + i, mx)]; } - out += OUTPUT_RECORD_SIZE; + out += mx; } //Set the last sample as the trigger offset: // The non gl scope sink will not look at this last sample. @@ -405,5 +426,12 @@ gr_oscope_guts::get_trigger_level () const int gr_oscope_guts::get_samples_per_output_record () const { - return OUTPUT_RECORD_SIZE; + int mx; + + mx = OUTPUT_RECORD_SIZE; + if (d_trigger_mode == gr_TRIG_MODE_STRIPCHART) + { + mx = OUTPUT_RECORD_SIZE*SCHART_MULT; + } + return mx; } diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc index 9463869f5..78f77486b 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_block.cc @@ -34,6 +34,9 @@ gr_block::gr_block (const std::string &name, gr_io_signature_sptr output_signature) : gr_basic_block(name, input_signature, output_signature), d_output_multiple (1), + d_output_multiple_set(false), + d_unaligned(0), + d_is_unaligned(false), d_relative_rate (1.0), d_history(1), d_fixed_rate(false), @@ -75,10 +78,37 @@ gr_block::set_output_multiple (int multiple) if (multiple < 1) throw std::invalid_argument ("gr_block::set_output_multiple"); + d_output_multiple_set = true; d_output_multiple = multiple; } void +gr_block::set_alignment (int multiple) +{ + if (multiple < 1) + throw std::invalid_argument ("gr_block::set_alignment_multiple"); + + d_output_multiple = multiple; +} + +void +gr_block::set_unaligned (int na) +{ + // unaligned value must be less than 0 and it doesn't make sense + // that it's larger than the alignment value. + if ((na < 0) || (na > d_output_multiple)) + throw std::invalid_argument ("gr_block::set_unaligned"); + + d_unaligned = na; +} + +void +gr_block::set_is_unaligned (bool u) +{ + d_is_unaligned = u; +} + +void gr_block::set_relative_rate (double relative_rate) { if (relative_rate < 0.0) diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h index 86e0583e9..9171942e0 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.h +++ b/gnuradio-core/src/lib/runtime/gr_block.h @@ -152,8 +152,33 @@ class GR_CORE_API gr_block : public gr_basic_block { */ void set_output_multiple (int multiple); int output_multiple () const { return d_output_multiple; } + bool output_multiple_set () const { return d_output_multiple_set; } /*! + * \brief Constrains buffers to work on a set item alignment (for SIMD) + * + * set_alignment_multiple causes the scheduler to ensure that the noutput_items + * argument passed to forecast and general_work will be an integer multiple + * of \param multiple The default value is 1. + * + * This control is similar to the output_multiple setting, except + * that if the number of items passed to the block is less than the + * output_multiple, this value is ignored and the block can produce + * like normal. The d_unaligned value is set to the number of items + * the block is off by. In the next call to general_work, the + * noutput_items is set to d_unaligned or less until + * d_unaligned==0. The buffers are now aligned again and the aligned + * calls can be performed again. + */ + void set_alignment (int multiple); + int alignment () const { return d_output_multiple; } + + void set_unaligned (int na); + int unaligned () const { return d_unaligned; } + void set_is_unaligned (bool u); + bool is_unaligned () const { return d_is_unaligned; } + + /*! * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed. */ void consume (int which_input, int how_many_items); @@ -231,6 +256,9 @@ class GR_CORE_API gr_block : public gr_basic_block { private: int d_output_multiple; + bool d_output_multiple_set; + int d_unaligned; + bool d_is_unaligned; double d_relative_rate; // approx output_rate / input_rate gr_block_detail_sptr d_detail; // implementation details unsigned d_history; diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc index ef53baf78..86289695a 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_executor.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc @@ -183,6 +183,8 @@ gr_block_executor::run_one_iteration() int noutput_items; int max_items_avail; int max_noutput_items = d_max_noutput_items; + int new_alignment=0; + int alignment_state=-1; gr_block *m = d_block.get(); gr_block_detail *d = m->detail().get(); @@ -307,7 +309,11 @@ gr_block_executor::run_one_iteration() // try to work it forward starting with max_items_avail. // We want to try to consume all the input we've got. int reqd_noutput_items = m->fixed_rate_ninput_to_noutput(max_items_avail); - reqd_noutput_items = round_up(reqd_noutput_items, m->output_multiple()); + + // only test this if we specifically set the output_multiple + if(m->output_multiple_set()) + reqd_noutput_items = round_down(reqd_noutput_items, m->output_multiple()); + if (reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items) noutput_items = reqd_noutput_items; @@ -316,6 +322,41 @@ gr_block_executor::run_one_iteration() } noutput_items = std::min(noutput_items, max_noutput_items); + // Check if we're still unaligned; use up items until we're + // aligned again. Otherwise, make sure we set the alignment + // requirement. + if(!m->output_multiple_set()) { + if(m->is_unaligned()) { + // When unaligned, don't just set noutput_items to the remaining + // samples to meet alignment; this causes too much overhead in + // requiring a premature call back here. Set the maximum amount + // of samples to handle unalignment and get us back aligned. + if(noutput_items >= m->unaligned()) { + noutput_items = round_up(noutput_items, m->alignment()) \ + - (m->alignment() - m->unaligned()); + new_alignment = 0; + } + else { + new_alignment = m->unaligned() - noutput_items; + } + alignment_state = 0; + } + else if(noutput_items < m->alignment()) { + // if we don't have enough for an aligned call, keep track of + // misalignment, set unaligned flag, and proceed. + new_alignment = m->alignment() - noutput_items; + m->set_unaligned(new_alignment); + m->set_is_unaligned(true); + alignment_state = 1; + } + else { + // enough to round down to the nearest alignment and process. + noutput_items = round_down(noutput_items, m->alignment()); + m->set_is_unaligned(false); + alignment_state = 2; + } + } + // ask the block how much input they need to produce noutput_items m->forecast (noutput_items, d_ninput_items_required); @@ -354,6 +395,12 @@ gr_block_executor::run_one_iteration() goto were_done; } + // If we were made unaligned in this round but return here without + // processing; reset the unalignment claim before next entry. + if(alignment_state == 1) { + m->set_unaligned(0); + m->set_is_unaligned(false); + } return BLKD_IN; } @@ -379,6 +426,12 @@ gr_block_executor::run_one_iteration() LOG(*d_log << " general_work: noutput_items = " << noutput_items << " result = " << n << std::endl); + // Adjust number of unaligned items left to process + if(m->is_unaligned()) { + m->set_unaligned(new_alignment); + m->set_is_unaligned(m->unaligned() != 0); + } + if(!propagate_tags(m->tag_propagation_policy(), d, d_start_nitems_read, m->relative_rate(), d_returned_tags)) diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am index f5af80c78..9853766f9 100644 --- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am @@ -50,6 +50,7 @@ noinst_PYTHON = \ qa_bin_statistics.py \ qa_classify.py \ qa_complex_to_xxx.py \ + qa_conjugate.py \ qa_copy.py \ qa_delay.py \ qa_dc_blocker.py \ @@ -60,7 +61,9 @@ noinst_PYTHON = \ qa_fft.py \ qa_fft_filter.py \ qa_filter_delay_fc.py \ + qa_float_to_char.py \ qa_float_to_int.py \ + qa_float_to_short.py \ qa_fractional_interpolator.py \ qa_frequency_modulator.py \ qa_fsk_stuff.py \ @@ -77,6 +80,7 @@ noinst_PYTHON = \ qa_kludged_imports.py \ qa_max.py \ qa_message.py \ + qa_multiply_conjugate.py \ qa_mute.py \ qa_nlog10.py \ qa_noise.py \ diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py b/gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py index 8fb70fb3f..e3b20c3c3 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py @@ -78,6 +78,24 @@ class test_add_and_friends (gr_unittest.TestCase): op = gr.multiply_const_ii (5) self.help_ii ((src_data,), expected_result, op) + def test_mult_const_ff (self): + src_data = (-1, 0, 1, 2, 3) + expected_result = (-5, 0, 5, 10, 15) + op = gr.multiply_const_cc (5) + self.help_cc ((src_data,), expected_result, op) + + def test_mult_const_cc (self): + src_data = (-1-1j, 0+0j, 1+1j, 2+2j, 3+3j) + expected_result = (-5-5j, 0+0j, 5+5j, 10+10j, 15+15j) + op = gr.multiply_const_cc (5) + self.help_cc ((src_data,), expected_result, op) + + def test_mult_const_cc2 (self): + src_data = (-1-1j, 0+0j, 1+1j, 2+2j, 3+3j) + expected_result = (-3-7j, 0+0j, 3+7j, 6+14j, 9+21j) + op = gr.multiply_const_cc (5+2j) + self.help_cc ((src_data,), expected_result, op) + def test_add_ii (self): src1_data = (1, 2, 3, 4, 5) src2_data = (8, -3, 4, 8, 2) @@ -94,6 +112,22 @@ class test_add_and_friends (gr_unittest.TestCase): self.help_ii ((src1_data, src2_data), expected_result, op) + def test_mult_ff (self): + src1_data = (1, 2, 3, 4, 5) + src2_data = (8, -3, 4, 8, 2) + expected_result = (8, -6, 12, 32, 10) + op = gr.multiply_ff () + self.help_ff ((src1_data, src2_data), + expected_result, op) + + def test_mult_cc (self): + src1_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j) + src2_data = (8, -3, 4, 8, 2) + expected_result = (8+8j, -6-6j, 12+12j, 32+32j, 10+10j) + op = gr.multiply_cc () + self.help_cc ((src1_data, src2_data), + expected_result, op) + def test_sub_ii_1 (self): src1_data = (1, 2, 3, 4, 5) expected_result = (-1, -2, -3, -4, -5) diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py b/gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py index 76627247b..01679dc05 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py @@ -134,7 +134,7 @@ class test_complex_ops (gr_unittest.TestCase): self.tb.run () actual_result = dst.data () - self.assertFloatTuplesAlmostEqual (expected_result, actual_result, 5) + self.assertFloatTuplesAlmostEqual (expected_result, actual_result, 3) if __name__ == '__main__': diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_conjugate.py b/gnuradio-core/src/python/gnuradio/gr/qa_conjugate.py new file mode 100644 index 000000000..c07902a5a --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_conjugate.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# +# Copyright 2012 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 + +class test_conjugate (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_000 (self): + src_data = (-2-2j, -1-1j, -2+2j, -1+1j, + 2-2j, 1-1j, 2+2j, 1+1j, + 0+0j) + + exp_data = (-2+2j, -1+1j, -2-2j, -1-1j, + 2+2j, 1+1j, 2-2j, 1-1j, + 0-0j) + + src = gr.vector_source_c(src_data) + op = gr.conjugate_cc () + dst = gr.vector_sink_c () + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data () + self.assertEqual (exp_data, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_conjugate, "test_conjugate.xml") diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_delay.py b/gnuradio-core/src/python/gnuradio/gr/qa_delay.py index 7cad0ae72..114e50108 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_delay.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_delay.py @@ -50,7 +50,7 @@ class test_delay (gr_unittest.TestCase): delta_t = 10 tb = self.tb src_data = [float(x) for x in range(0, 100)] - expected_result = tuple(delta_t*[0.0] + src_data[0:-delta_t]) + expected_result = tuple(delta_t*[0.0] + src_data) src = gr.vector_source_f(src_data) op = gr.delay(gr.sizeof_float, delta_t) diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_fft.py b/gnuradio-core/src/python/gnuradio/gr/qa_fft.py index 98d80fbb0..e90eb2e7f 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_fft.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_fft.py @@ -152,6 +152,60 @@ class test_fft(gr_unittest.TestCase): #self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5) self.assert_fft_ok2(expected_result, result_data) + def test_003(self): + # Same test as above, only use 2 threads + + tb = gr.top_block() + fft_size = 32 + + tmp_data = ((4377+4516j), + (-1706.1268310546875+1638.4256591796875j), + (-915.2083740234375+660.69427490234375j), + (-660.370361328125+381.59600830078125j), + (-499.96044921875+238.41630554199219j), + (-462.26748657226562+152.88948059082031j), + (-377.98440551757812+77.5928955078125j), + (-346.85821533203125+47.152004241943359j), + (-295+20j), + (-286.33609008789062-22.257017135620117j), + (-271.52999877929688-33.081821441650391j), + (-224.6358642578125-67.019538879394531j), + (-244.24473571777344-91.524826049804688j), + (-203.09068298339844-108.54627227783203j), + (-198.45195007324219-115.90768432617188j), + (-182.97744750976562-128.12318420410156j), + (-167-180j), + (-130.33688354492188-173.83778381347656j), + (-141.19784545898438-190.28807067871094j), + (-111.09677124023438-214.48896789550781j), + (-70.039543151855469-242.41630554199219j), + (-68.960540771484375-228.30015563964844j), + (-53.049201965332031-291.47097778320312j), + (-28.695289611816406-317.64553833007812j), + (57-300j), + (45.301143646240234-335.69509887695312j), + (91.936195373535156-373.32437133789062j), + (172.09465026855469-439.275146484375j), + (242.24473571777344-504.47515869140625j), + (387.81732177734375-666.6788330078125j), + (689.48553466796875-918.2142333984375j), + (1646.539306640625-1694.1956787109375j)) + + src_data = tuple([x/fft_size for x in tmp_data]) + + expected_result = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)]) + + nthreads = 2 + + src = gr.vector_source_c(src_data) + s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size) + fft = gr.fft_vcc(fft_size, False, [], False, nthreads) + v2s = gr.vector_to_stream(gr.sizeof_gr_complex, fft_size) + dst = gr.vector_sink_c() + tb.connect(src, s2v, fft, v2s, dst) + tb.run() + result_data = dst.data() + self.assert_fft_ok2(expected_result, result_data) if __name__ == '__main__': gr_unittest.run(test_fft, "test_fft.xml") diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py b/gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py index 325495c1d..1e9fdb6a8 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py @@ -110,6 +110,23 @@ class test_fft_filter(gr_unittest.TestCase): def test_ccc_002(self): + # Test nthreads + tb = gr.top_block() + src_data = (0,1,2,3,4,5,6,7) + taps = (2,) + nthreads = 2 + expected_result = tuple([2 * complex(x) for x in (0,1,2,3,4,5,6,7)]) + src = gr.vector_source_c(src_data) + op = gr.fft_filter_ccc(1, taps, nthreads) + dst = gr.vector_sink_c() + tb.connect(src, op, dst) + tb.run() + result_data = dst.data() + #print 'expected:', expected_result + #print 'results: ', result_data + self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5) + + def test_ccc_003(self): tb = gr.top_block() src_data = (0,1,2,3,4,5,6,7) taps = (2,) @@ -124,6 +141,7 @@ class test_fft_filter(gr_unittest.TestCase): #print 'results: ', result_data self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5) + def test_ccc_004(self): random.seed(0) for i in xrange(25): @@ -167,6 +185,30 @@ class test_fft_filter(gr_unittest.TestCase): self.assert_fft_ok2(expected_result, result_data) + def test_ccc_006(self): + # Test decimating with nthreads=2 + random.seed(0) + nthreads = 2 + for i in xrange(25): + # sys.stderr.write("\n>>> Loop = %d\n" % (i,)) + dec = i + 1 + src_len = 4*1024 + src_data = make_random_complex_tuple(src_len) + ntaps = int(random.uniform(2, 100)) + taps = make_random_complex_tuple(ntaps) + expected_result = reference_filter_ccc(dec, taps, src_data) + + src = gr.vector_source_c(src_data) + op = gr.fft_filter_ccc(dec, taps, nthreads) + dst = gr.vector_sink_c() + tb = gr.top_block() + tb.connect(src, op, dst) + tb.run() + del tb + result_data = dst.data() + + self.assert_fft_ok2(expected_result, result_data) + # ---------------------------------------------------------------- # test _fff version # ---------------------------------------------------------------- @@ -202,7 +244,22 @@ class test_fft_filter(gr_unittest.TestCase): #print 'results: ', result_data self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5) - def xtest_fff_003(self): + def test_fff_003(self): + # Test 02 with nthreads + tb = gr.top_block() + src_data = (0,1,2,3,4,5,6,7) + taps = (2,) + nthreads = 2 + expected_result = tuple([2 * float(x) for x in (0,1,2,3,4,5,6,7)]) + src = gr.vector_source_f(src_data) + op = gr.fft_filter_fff(1, taps, nthreads) + dst = gr.vector_sink_f() + tb.connect(src, op, dst) + tb.run() + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5) + + def xtest_fff_004(self): random.seed(0) for i in xrange(25): sys.stderr.write("\n>>> Loop = %d\n" % (i,)) @@ -232,7 +289,7 @@ class test_fft_filter(gr_unittest.TestCase): actual.write(`x` + '\n') raise - def xtest_fff_004(self): + def xtest_fff_005(self): random.seed(0) for i in xrange(25): sys.stderr.write("\n>>> Loop = %d\n" % (i,)) @@ -252,7 +309,7 @@ class test_fft_filter(gr_unittest.TestCase): self.assert_fft_float_ok2(expected_result, result_data, abs_eps=2.0) - def xtest_fff_005(self): + def xtest_fff_006(self): random.seed(0) for i in xrange(25): sys.stderr.write("\n>>> Loop = %d\n" % (i,)) @@ -273,6 +330,29 @@ class test_fft_filter(gr_unittest.TestCase): self.assert_fft_float_ok2(expected_result, result_data) + def xtest_fff_007(self): + # test decimation with nthreads + random.seed(0) + nthreads = 2 + for i in xrange(25): + sys.stderr.write("\n>>> Loop = %d\n" % (i,)) + dec = i + 1 + src_len = 4*1024 + src_data = make_random_float_tuple(src_len) + ntaps = int(random.uniform(2, 100)) + taps = make_random_float_tuple(ntaps) + expected_result = reference_filter_fff(dec, taps, src_data) + + src = gr.vector_source_f(src_data) + op = gr.fft_filter_fff(dec, taps, nthreads) + dst = gr.vector_sink_f() + tb = gr.top_block() + tb.connect(src, op, dst) + tb.run() + result_data = dst.data() + + self.assert_fft_float_ok2(expected_result, result_data) + def test_fff_get0(self): random.seed(0) for i in xrange(25): diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_char.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_char.py new file mode 100755 index 000000000..ecdd36228 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_char.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# +# Copyright 2011,2012 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 +class test_float_to_char (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + + src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3) + expected_result = [0, 1, 2, 3, 4, 5, 255, 254, 253] + src = gr.vector_source_f(src_data) + op = gr.float_to_char() + dst = gr.vector_sink_b() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_002(self): + + src_data = ( 126.0, 127.0, 128.0) + expected_result = [ 126, 127, 127 ] + + src = gr.vector_source_f(src_data) + op = gr.float_to_char() + # Note: vector_sink_b returns uchar + dst = gr.vector_sink_b() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_003(self): + + scale = 2 + vlen = 3 + src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3) + expected_result = [0, 2, 4, 6, 8, 11, 254, 252, 250] + src = gr.vector_source_f(src_data) + s2v = gr.stream_to_vector(gr.sizeof_float, vlen) + op = gr.float_to_char(vlen, scale) + v2s = gr.vector_to_stream(gr.sizeof_char, vlen) + dst = gr.vector_sink_b() + + self.tb.connect(src, s2v, op, v2s, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_float_to_char, "test_float_to_char.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py index 3e0b847a2..977a8518d 100644..100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py @@ -33,7 +33,8 @@ class test_float_to_int (gr_unittest.TestCase): def test_001(self): src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5) - expected_result = [int(round(s)) for s in src_data] + expected_result = [0, 1, 2, 3, 4, 6, -1, -2, -3, -4, -6] + src = gr.vector_source_f(src_data) op = gr.float_to_int() dst = gr.vector_sink_i() @@ -60,6 +61,25 @@ class test_float_to_int (gr_unittest.TestCase): self.assertEqual(expected_result, result_data) + + def test_003(self): + + scale = 2 + vlen = 3 + src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3) + expected_result = [0, 2, 4, 7, 9, 11, -2, -4, -7,] + src = gr.vector_source_f(src_data) + s2v = gr.stream_to_vector(gr.sizeof_float, vlen) + op = gr.float_to_int(vlen, scale) + v2s = gr.vector_to_stream(gr.sizeof_int, vlen) + dst = gr.vector_sink_i() + + self.tb.connect(src, s2v, op, v2s, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + if __name__ == '__main__': gr_unittest.run(test_float_to_int, "test_float_to_int.xml") diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_short.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_short.py new file mode 100755 index 000000000..0d89a149c --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_short.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# Copyright 2011,2012 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 ctypes + +class test_float_to_short (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + + src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5) + expected_result = [0, 1, 2, 3, 4, 6, -1, -2, -3, -4, -6] + + src = gr.vector_source_f(src_data) + op = gr.float_to_short() + dst = gr.vector_sink_s() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_002(self): + + src_data = ( 32766, 32767, 32768, + -32767, -32768, -32769) + expected_result = [ 32766, 32767, 32767, + -32767, -32768, -32768 ] + + src = gr.vector_source_f(src_data) + op = gr.float_to_short() + dst = gr.vector_sink_s() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_003(self): + + scale = 2 + vlen = 3 + src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3) + expected_result = [0, 2, 4, 7, 9, 11, -2, -4, -7] + src = gr.vector_source_f(src_data) + s2v = gr.stream_to_vector(gr.sizeof_float, vlen) + op = gr.float_to_short(vlen, scale) + v2s = gr.vector_to_stream(gr.sizeof_short, vlen) + dst = gr.vector_sink_s() + + self.tb.connect(src, s2v, op, v2s, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_float_to_short, "test_float_to_short.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_uchar.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_uchar.py new file mode 100755 index 000000000..0d54f45f3 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_uchar.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# Copyright 2011 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 ctypes + +class test_float_to_uchar (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + + src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5) + expected_result = [0, 1, 2, 3, 4, 6, 0, 0, 0, 0, 0] + src = gr.vector_source_f(src_data) + op = gr.float_to_uchar() + dst = gr.vector_sink_b() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_002(self): + + src_data = ( 254.0, 255.0, 256.0) + expected_result = [ 254, 255, 255 ] + src = gr.vector_source_f(src_data) + op = gr.float_to_uchar() + dst = gr.vector_sink_b() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_float_to_uchar, "test_float_to_uchar.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py b/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py index edfc26409..530b2a5cc 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py @@ -44,6 +44,26 @@ class test_int_to_float (gr_unittest.TestCase): self.assertFloatTuplesAlmostEqual(expected_result, result_data) + def test_002(self): + + vlen = 3 + src_data = ( 65000, 65001, 65002, 65003, 65004, 65005, + -65001, -65002, -65003) + expected_result = [ 65000.0, 65001.0, 65002.0, + 65003.0, 65004.0, 65005.0, + -65001.0, -65002.0, -65003.0] + src = gr.vector_source_i(src_data) + s2v = gr.stream_to_vector(gr.sizeof_int, vlen) + op = gr.int_to_float(vlen) + v2s = gr.vector_to_stream(gr.sizeof_float, vlen) + dst = gr.vector_sink_f() + + self.tb.connect(src, s2v, op, v2s, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + if __name__ == '__main__': gr_unittest.run(test_int_to_float, "test_int_to_float.xml") diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_multiply_conjugate.py b/gnuradio-core/src/python/gnuradio/gr/qa_multiply_conjugate.py new file mode 100644 index 000000000..aaf3cc125 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_multiply_conjugate.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# +# Copyright 2012 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 + +class test_multiply_conjugate (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_000 (self): + src_data0 = (-2-2j, -1-1j, -2+2j, -1+1j, + 2-2j, 1-1j, 2+2j, 1+1j, + 0+0j) + src_data1 = (-3-3j, -4-4j, -3+3j, -4+4j, + 3-3j, 4-4j, 3+3j, 4+4j, + 0+0j) + + exp_data = (12+0j, 8+0j, 12+0j, 8+0j, + 12+0j, 8+0j, 12+0j, 8+0j, + 0+0j) + src0 = gr.vector_source_c(src_data0) + src1 = gr.vector_source_c(src_data1) + op = gr.multiply_conjugate_cc () + dst = gr.vector_sink_c () + + self.tb.connect(src0, (op,0)) + self.tb.connect(src1, (op,1)) + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data () + self.assertEqual (exp_data, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_multiply_conjugate, "test_multiply_conjugate.xml") diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_short_to_char.py b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_char.py new file mode 100755 index 000000000..6a95fa01d --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_char.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# +# Copyright 2011,2012 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 ctypes + +class test_short_to_char (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + + src_data = range(0, 32767, 32767/127) + src_data = [int(s) for s in src_data] + expected_result = range(0, 128) + src = gr.vector_source_s(src_data) + op = gr.short_to_char() + dst = gr.vector_sink_b() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_002(self): + + vlen = 3 + src_data = range(0, 32400, 32767/127) + src_data = [int(s) for s in src_data] + expected_result = range(0, 126) + src = gr.vector_source_s(src_data) + s2v = gr.stream_to_vector(gr.sizeof_short, vlen) + op = gr.short_to_char(vlen) + v2s = gr.vector_to_stream(gr.sizeof_char, vlen) + dst = gr.vector_sink_b() + + self.tb.connect(src, s2v, op, v2s, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_short_to_char, "test_short_to_char.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_short_to_float.py b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_float.py new file mode 100755 index 000000000..8f331b495 --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_float.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# Copyright 2011,2012 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 ctypes + +class test_short_to_float (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + + src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5) + expected_result = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, + -1.0, -2.0, -3.0, -4.0, -5.0] + + src = gr.vector_source_s(src_data) + op = gr.short_to_float() + dst = gr.vector_sink_f() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + + def test_002(self): + + vlen = 3 + src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3) + expected_result = [0.0, 1.0, 2.0, 3.0, 4.0, + 5.0, -1.0, -2.0, -3.0] + src = gr.vector_source_s(src_data) + s2v = gr.stream_to_vector(gr.sizeof_short, vlen) + op = gr.short_to_float(vlen) + v2s = gr.vector_to_stream(gr.sizeof_float, vlen) + dst = gr.vector_sink_f() + + self.tb.connect(src, s2v, op, v2s, dst) + self.tb.run() + result_data = list(dst.data()) + + self.assertEqual(expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_short_to_float, "test_short_to_float.xml") + |