diff options
168 files changed, 5987 insertions, 12615 deletions
diff --git a/config/grc_gnuradio_examples.m4 b/config/grc_gnuradio_examples.m4 index f5d94318e..9a32e5ab9 100644 --- a/config/grc_gnuradio_examples.m4 +++ b/config/grc_gnuradio_examples.m4 @@ -28,20 +28,12 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[ gnuradio-examples/Makefile \ gnuradio-examples/python/Makefile \ gnuradio-examples/grc/Makefile \ - gnuradio-examples/python/apps/hf_explorer/Makefile \ - gnuradio-examples/python/apps/hf_radio/Makefile \ - gnuradio-examples/python/apps/Makefile \ - gnuradio-examples/python/digital/Makefile \ - gnuradio-examples/python/digital-bert/Makefile \ gnuradio-examples/python/mp-sched/Makefile \ - gnuradio-examples/python/multi-antenna/Makefile \ gnuradio-examples/python/multi_usrp/Makefile \ gnuradio-examples/python/network/Makefile \ gnuradio-examples/python/ofdm/Makefile \ gnuradio-examples/python/pfb/Makefile \ gnuradio-examples/python/tags/Makefile \ - gnuradio-examples/python/usrp/Makefile \ - gnuradio-examples/python/usrp2/Makefile \ gnuradio-examples/waveforms/Makefile \ ]) diff --git a/config/grc_gr_shd.m4 b/config/grc_gr_shd.m4 new file mode 100644 index 000000000..d09505fbf --- /dev/null +++ b/config/grc_gr_shd.m4 @@ -0,0 +1,59 @@ +dnl Copyright 2011 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. + +AC_DEFUN([GRC_GR_SHD],[ + GRC_ENABLE(gr-shd) + + dnl Dont do gr-shd if gnuradio-core skipped + GRC_CHECK_DEPENDENCY(gr-shd, gnuradio-core) + + if test $passed = yes; then + dnl Don't do gr-shd if the 'shd' package is not installed + PKG_CHECK_MODULES( + [SHD], [shd >= 3.1.0 shd < 3.2.0], [], + [passed=no; AC_MSG_RESULT([gr-shd requires libshd 3.1.x])] + ) + SHD_CPPFLAGS="${SHD_CPPFLAGS} -I\${abs_top_srcdir}/gr-shd/include" + AC_SUBST(SHD_CPPFLAGS) + AC_SUBST(SHD_LIBS) + + # Use this to tell the Makefile whether to define + # GR_HAVE_SHD for swig. + fi + + AM_CONDITIONAL([GR_DEFINE_HAVE_SHD],[test $passed = yes]) + + AC_CONFIG_FILES([ \ + gr-shd/gnuradio-shd.pc \ + gr-shd/Makefile \ + gr-shd/grc/Makefile \ + gr-shd/include/Makefile \ + gr-shd/lib/Makefile \ + gr-shd/swig/Makefile \ + gr-shd/swig/run_tests \ + gr-shd/swig/run_guile_tests \ + gr-shd/apps/Makefile \ + ]) + + GRC_BUILD_CONDITIONAL(gr-shd,[ + dnl run_tests is created from run_tests.in. Make it executable. + AC_CONFIG_COMMANDS([run_tests_shd], + [chmod +x gr-shd/swig/run_tests gr-shd/swig/run_guile_tests]) + ]) +]) diff --git a/config/grc_gr_uhd.m4 b/config/grc_gr_uhd.m4 index 111b0ae43..f2170166b 100644 --- a/config/grc_gr_uhd.m4 +++ b/config/grc_gr_uhd.m4 @@ -49,6 +49,10 @@ AC_DEFUN([GRC_GR_UHD],[ gr-uhd/swig/run_tests \ gr-uhd/swig/run_guile_tests \ gr-uhd/apps/Makefile \ + gr-uhd/apps/hf_explorer/Makefile \ + gr-uhd/apps/hf_radio/Makefile \ + gr-uhd/examples/Makefile \ + gr-uhd/examples/multi-antenna/Makefile \ ]) GRC_BUILD_CONDITIONAL(gr-uhd,[ diff --git a/configure.ac b/configure.ac index 28fac41d4..6e6d7018b 100644 --- a/configure.ac +++ b/configure.ac @@ -374,6 +374,7 @@ GRC_GR_UTILS dnl this must come after GRC_GR_WXGUI GRC_GNURADIO_EXAMPLES dnl must come after all GRC_GR_* GRC_GRC GRC_GR_UHD +GRC_GR_SHD GRC_DOCS dnl must be last # Each component is now either to be built, was skipped, will be diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index 48ec55a62..c314431bf 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -215,6 +215,7 @@ libfilter_la_common_SOURCES = \ gr_pfb_decimator_ccf.cc \ gr_pfb_interpolator_ccf.cc \ gr_pfb_arb_resampler_ccf.cc \ + gr_pfb_arb_resampler_fff.cc \ gr_pfb_clock_sync_ccf.cc \ gr_pfb_clock_sync_fff.cc \ gr_dc_blocker_cc.cc \ @@ -307,6 +308,7 @@ grinclude_HEADERS = \ gr_pfb_decimator_ccf.h \ gr_pfb_interpolator_ccf.h \ gr_pfb_arb_resampler_ccf.h \ + gr_pfb_arb_resampler_fff.h \ gr_pfb_clock_sync_ccf.h \ gr_pfb_clock_sync_fff.h \ gr_dc_blocker_cc.h \ @@ -374,6 +376,7 @@ swiginclude_HEADERS = \ gr_pfb_decimator_ccf.i \ gr_pfb_interpolator_ccf.i \ gr_pfb_arb_resampler_ccf.i \ + gr_pfb_arb_resampler_fff.i \ gr_pfb_clock_sync_ccf.i \ gr_pfb_clock_sync_fff.i \ gr_dc_blocker_cc.i \ diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i index 2af7fcc5c..8c3bb9eb6 100644 --- a/gnuradio-core/src/lib/filter/filter.i +++ b/gnuradio-core/src/lib/filter/filter.i @@ -36,6 +36,7 @@ #include <gr_pfb_decimator_ccf.h> #include <gr_pfb_interpolator_ccf.h> #include <gr_pfb_arb_resampler_ccf.h> +#include <gr_pfb_arb_resampler_fff.h> #include <gr_pfb_clock_sync_ccf.h> #include <gr_pfb_clock_sync_fff.h> #include <gr_dc_blocker_cc.h> @@ -57,6 +58,7 @@ %include "gr_pfb_decimator_ccf.i" %include "gr_pfb_interpolator_ccf.i" %include "gr_pfb_arb_resampler_ccf.i" +%include "gr_pfb_arb_resampler_fff.i" %include "gr_pfb_decimator_ccf.i" %include "gr_pfb_interpolator_ccf.i" %include "gr_pfb_arb_resampler_ccf.i" diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.cc b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.cc new file mode 100644 index 000000000..9035e67f4 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.cc @@ -0,0 +1,209 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009-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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pfb_arb_resampler_fff.h> +#include <gr_fir_fff.h> +#include <gr_fir_util.h> +#include <gr_io_signature.h> +#include <cstdio> + +gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate, + const std::vector<float> &taps, + unsigned int filter_size) +{ + return gnuradio::get_initial_sptr(new gr_pfb_arb_resampler_fff (rate, taps, + filter_size)); +} + + +gr_pfb_arb_resampler_fff::gr_pfb_arb_resampler_fff (float rate, + const std::vector<float> &taps, + unsigned int filter_size) + : gr_block ("pfb_arb_resampler_fff", + gr_make_io_signature (1, 1, sizeof(float)), + gr_make_io_signature (1, 1, sizeof(float))), + d_updated (false) +{ + d_acc = 0; // start accumulator at 0 + + /* The number of filters is specified by the user as the filter size; + this is also the interpolation rate of the filter. We use it and the + rate provided to determine the decimation rate. This acts as a + rational resampler. The flt_rate is calculated as the residual + between the integer decimation rate and the real decimation rate and + will be used to determine to interpolation point of the resampling + process. + */ + d_int_rate = filter_size; + set_rate(rate); + + // Store the last filter between calls to work + d_last_filter = 0; + + d_start_index = 0; + + d_filters = std::vector<gr_fir_fff*>(d_int_rate); + d_diff_filters = std::vector<gr_fir_fff*>(d_int_rate); + + // Create an FIR filter for each channel and zero out the taps + std::vector<float> vtaps(0, d_int_rate); + for(unsigned int i = 0; i < d_int_rate; i++) { + d_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps); + d_diff_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps); + } + + // Now, actually set the filters' taps + std::vector<float> dtaps; + create_diff_taps(taps, dtaps); + create_taps(taps, d_taps, d_filters); + create_taps(dtaps, d_dtaps, d_diff_filters); +} + +gr_pfb_arb_resampler_fff::~gr_pfb_arb_resampler_fff () +{ + for(unsigned int i = 0; i < d_int_rate; i++) { + delete d_filters[i]; + } +} + +void +gr_pfb_arb_resampler_fff::create_taps (const std::vector<float> &newtaps, + std::vector< std::vector<float> > &ourtaps, + std::vector<gr_fir_fff*> &ourfilter) +{ + unsigned int ntaps = newtaps.size(); + d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate); + + // Create d_numchan vectors to store each channel's taps + ourtaps.resize(d_int_rate); + + // Make a vector of the taps plus fill it out with 0's to fill + // each polyphase filter with exactly d_taps_per_filter + std::vector<float> tmp_taps; + tmp_taps = newtaps; + while((float)(tmp_taps.size()) < d_int_rate*d_taps_per_filter) { + tmp_taps.push_back(0.0); + } + + // Partition the filter + for(unsigned int i = 0; i < d_int_rate; i++) { + // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out + ourtaps[d_int_rate-1-i] = std::vector<float>(d_taps_per_filter, 0); + for(unsigned int j = 0; j < d_taps_per_filter; j++) { + ourtaps[d_int_rate - 1 - i][j] = tmp_taps[i + j*d_int_rate]; + } + + // Build a filter for each channel and add it's taps to it + ourfilter[i]->set_taps(ourtaps[d_int_rate-1-i]); + } + + // Set the history to ensure enough input items for each filter + set_history (d_taps_per_filter + 1); + + d_updated = true; +} + +void +gr_pfb_arb_resampler_fff::create_diff_taps(const std::vector<float> &newtaps, + std::vector<float> &difftaps) +{ + // Calculate the differential taps (derivative filter) by taking the difference + // between two taps. Duplicate the last one to make both filters the same length. + float tap; + difftaps.clear(); + for(unsigned int i = 0; i < newtaps.size()-1; i++) { + tap = newtaps[i+1] - newtaps[i]; + difftaps.push_back(tap); + } + difftaps.push_back(tap); +} + +void +gr_pfb_arb_resampler_fff::print_taps() +{ + unsigned int i, j; + for(i = 0; i < d_int_rate; i++) { + printf("filter[%d]: [", i); + for(j = 0; j < d_taps_per_filter; j++) { + printf(" %.4e", d_taps[i][j]); + } + printf("]\n"); + } +} + +int +gr_pfb_arb_resampler_fff::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + float *in = (float *) input_items[0]; + float *out = (float *) output_items[0]; + + if (d_updated) { + d_updated = false; + return 0; // history requirements may have changed. + } + + int i = 0, count = d_start_index; + unsigned int j; + float o0, o1; + + // Restore the last filter position + j = d_last_filter; + + // produce output as long as we can and there are enough input samples + int max_input = ninput_items[0]-(int)d_taps_per_filter; + while((i < noutput_items) && (count < max_input)) { + // start j by wrapping around mod the number of channels + while((j < d_int_rate) && (i < noutput_items)) { + // Take the current filter and derivative filter output + o0 = d_filters[j]->filter(&in[count]); + o1 = d_diff_filters[j]->filter(&in[count]); + + out[i] = o0 + o1*d_acc; // linearly interpolate between samples + i++; + + // Adjust accumulator and index into filterbank + d_acc += d_flt_rate; + j += d_dec_rate + (int)floor(d_acc); + d_acc = fmodf(d_acc, 1.0); + } + if(i < noutput_items) { // keep state for next entry + float ss = (int)(j / d_int_rate); // number of items to skip ahead by + count += ss; // we have fully consumed another input + j = j % d_int_rate; // roll filter around + } + } + + // Store the current filter position and start of next sample + d_last_filter = j; + d_start_index = std::max(0, count - ninput_items[0]); + + // consume all we've processed but no more than we can + consume_each(std::min(count, ninput_items[0])); + return i; +} diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.h b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.h new file mode 100644 index 000000000..541df8aa4 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.h @@ -0,0 +1,176 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009-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. + */ + + +#ifndef INCLUDED_GR_PFB_ARB_RESAMPLER_FFF_H +#define INCLUDED_GR_PFB_ARB_RESAMPLER_FFF_H + +#include <gr_block.h> + +class gr_pfb_arb_resampler_fff; +typedef boost::shared_ptr<gr_pfb_arb_resampler_fff> gr_pfb_arb_resampler_fff_sptr; +gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate, + const std::vector<float> &taps, + unsigned int filter_size=32); + +class gr_fir_fff; + +/*! + * \class gr_pfb_arb_resampler_fff + * + * \brief Polyphase filterbank arbitrary resampler with + * float input, float output and float taps + * + * \ingroup filter_blk + * + * This block takes in a signal stream and performs arbitrary + * resampling. The resampling rate can be any real + * number <EM>r</EM>. The resampling is done by constructing + * <EM>N</EM> filters where <EM>N</EM> is the interpolation rate. We + * then calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>. + * + * Using <EM>N</EM> and <EM>D</EM>, we can perform rational resampling + * where <EM>N/D</EM> is a rational number close to the input rate + * <EM>r</EM> where we have <EM>N</EM> filters and we cycle through + * them as a polyphase filterbank with a stride of <EM>D</EM> so that + * <EM>i+1 = (i + D) % N</EM>. + * + * To get the arbitrary rate, we want to interpolate between two + * points. For each value out, we take an output from the current + * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then + * linearly interpolate between the two based on the real resampling + * rate we want. + * + * The linear interpolation only provides us with an approximation to + * the real sampling rate specified. The error is a quantization error + * between the two filters we used as our interpolation points. To + * this end, the number of filters, <EM>N</EM>, used determines the + * quantization error; the larger <EM>N</EM>, the smaller the + * noise. You can design for a specified noise floor by setting the + * filter size (parameters <EM>filter_size</EM>). The size defaults to + * 32 filters, which is about as good as most implementations need. + * + * The trick with designing this filter is in how to specify the taps + * of the prototype filter. Like the PFB interpolator, the taps are + * specified using the interpolated filter rate. In this case, that + * rate is the input sample rate multiplied by the number of filters + * in the filterbank, which is also the interpolation rate. All other + * values should be relative to this rate. + * + * For example, for a 32-filter arbitrary resampler and using the + * GNU Radio's firdes utility to build the filter, we build a low-pass + * filter with a sampling rate of <EM>fs</EM>, a 3-dB bandwidth of + * <EM>BW</EM> and a transition bandwidth of <EM>TB</EM>. We can also + * specify the out-of-band attenuation to use, <EM>ATT</EM>, and the + * filter window function (a Blackman-harris window in this case). The + * first input is the gain of the filter, which we specify here as the + * interpolation rate (<EM>32</EM>). + * + * <B><EM>self._taps = gr.firdes.low_pass_2(32, 32*fs, BW, TB, + * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The theory behind this block can be found in Chapter 7.5 of + * the following book. + * + * <B><EM>f. harris, "Multirate Signal Processing for Communication + * Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B> + */ + +class gr_pfb_arb_resampler_fff : public gr_block +{ + private: + /*! + * Build the polyphase filterbank arbitray resampler. + * \param rate (float) Specifies the resampling rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the filter_size sampling rate. + * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly + related to quantization noise introduced during the resampling. + Defaults to 32 filters. + */ + friend gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate, + const std::vector<float> &taps, + unsigned int filter_size); + + std::vector<gr_fir_fff*> d_filters; + std::vector<gr_fir_fff*> d_diff_filters; + std::vector< std::vector<float> > d_taps; + std::vector< std::vector<float> > d_dtaps; + unsigned int d_int_rate; // the number of filters (interpolation rate) + unsigned int d_dec_rate; // the stride through the filters (decimation rate) + float d_flt_rate; // residual rate for the linear interpolation + float d_acc; + unsigned int d_last_filter; + int d_start_index; + unsigned int d_taps_per_filter; + bool d_updated; + + /*! + * Build the polyphase filterbank arbitray resampler. + * \param rate (float) Specifies the resampling rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the filter_size sampling rate. + * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly + related to quantization noise introduced during the resampling. + Defaults to 32 filters. + */ + gr_pfb_arb_resampler_fff (float rate, + const std::vector<float> &taps, + unsigned int filter_size); + + void create_diff_taps(const std::vector<float> &newtaps, + std::vector<float> &difftaps); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param newtaps (vector of floats) The prototype filter to populate the filterbank. + * The taps should be generated at the interpolated sampling rate. + * \param ourtaps (vector of floats) Reference to our internal member of holding the taps. + * \param ourfilter (vector of filters) Reference to our internal filter to set the taps for. + */ + void create_taps (const std::vector<float> &newtaps, + std::vector< std::vector<float> > &ourtaps, + std::vector<gr_fir_fff*> &ourfilter); + + +public: + ~gr_pfb_arb_resampler_fff (); + + // FIXME: See about a set_taps function during runtime. + + /*! + * Print all of the filterbank taps to screen. + */ + void print_taps(); + void set_rate (float rate) { + d_dec_rate = (unsigned int)floor(d_int_rate/rate); + d_flt_rate = (d_int_rate/rate) - d_dec_rate; + set_relative_rate(rate); + } + + 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/filter/gr_pfb_arb_resampler_fff.i b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.i new file mode 100644 index 000000000..8c1db22c3 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.i @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,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,pfb_arb_resampler_fff); + +gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate, + const std::vector<float> &taps, + unsigned int filter_size=32); + +class gr_pfb_arb_resampler_fff : public gr_block +{ + private: + gr_pfb_arb_resampler_fff (float rate, + const std::vector<float> &taps, + unsigned int filter_size); + + public: + ~gr_pfb_arb_resampler_fff (); + + //void set_taps (const std::vector<float> &taps); + void print_taps(); + void set_rate (float rate); +}; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc index a939609f3..633c5be07 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc @@ -187,6 +187,12 @@ gr_pfb_clock_sync_ccf::get_beta() const return d_beta; } +float +gr_pfb_clock_sync_ccf::get_clock_rate() const +{ + return d_rate_f; +} + /******************************************************************* *******************************************************************/ diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h index 0fd8ba35b..54ae889d7 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h @@ -315,6 +315,11 @@ public: */ float get_beta() const; + /*! + * \brief Returns the current clock rate + */ + float get_clock_rate() const; + /******************************************************************* *******************************************************************/ diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i index 78b9a6589..92ad1661a 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i @@ -63,5 +63,5 @@ class gr_pfb_clock_sync_ccf : public gr_block float get_damping_factor() const; float get_alpha() const; float get_beta() const; - + float get_clock_rate() const; }; diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py index 1910b5011..55870513a 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py @@ -88,7 +88,7 @@ class demod_20k0f3e_cf(fm_demod_cf): fm_demod_cf.__init__(self, channel_rate, audio_decim, 5000, # Deviation 3000, # Audio passband frequency - 4000) # Audio stopband frequency + 4500) # Audio stopband frequency class demod_200kf3e_cf(fm_demod_cf): """ diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py index 62f40582e..3aadf700b 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py @@ -73,3 +73,56 @@ class pfb_arb_resampler_ccf(gr.hier_block2): def set_rate(self, rate): self.pfb.set_rate(rate) + + +class pfb_arb_resampler_fff(gr.hier_block2): + ''' + Convenience wrapper for the polyphase filterbank arbitrary resampler. + + The block takes a single float stream in and outputs a single float + stream out. As such, it requires no extra glue to handle the input/output + streams. This block is provided to be consistent with the interface to the + other PFB block. + ''' + def __init__(self, rate, taps=None, flt_size=32, atten=100): + gr.hier_block2.__init__(self, "pfb_arb_resampler_fff", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + self._rate = rate + self._size = flt_size + + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.1 + #self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten) + made = False + while not made: + try: + self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + + self.pfb = gr.pfb_arb_resampler_fff(self._rate, self._taps, self._size) + #print "PFB has %d taps\n" % (len(self._taps),) + + self.connect(self, self.pfb) + self.connect(self.pfb, self) + + # Note -- set_taps not implemented in base class yet + def set_taps(self, taps): + self.pfb.set_taps(taps) + + def set_rate(self, rate): + self.pfb.set_rate(rate) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py index 858b9cde6..3a93a11d6 100755 --- a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py @@ -28,8 +28,9 @@ class wfm_rcv_fmdet(gr.hier_block2): """ Hierarchical block for demodulating a broadcast FM signal. - The input is the downconverted complex baseband signal (gr_complex). - The output is two streams of the demodulated audio (float) 0=Left, 1=Right. + The input is the downconverted complex baseband signal + (gr_complex). The output is two streams of the demodulated + audio (float) 0=Left, 1=Right. @param demod_rate: input sample rate of complex baseband input. @type demod_rate: float @@ -39,16 +40,15 @@ class wfm_rcv_fmdet(gr.hier_block2): gr.hier_block2.__init__(self, "wfm_rcv_fmdet", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(2, 2, gr.sizeof_float)) # Output signature - lowfreq = -125e3 - highfreq = 125e3 + lowfreq = -125e3/demod_rate + highfreq = 125e3/demod_rate audio_rate = demod_rate / audio_decimation - - # We assign to self so that outsiders can grab the demodulator + # We assign to self so that outsiders can grab the demodulator # if they need to. E.g., to plot its output. # # input: complex; output: float - + self.fm_demod = gr.fmdet_cf (demod_rate, lowfreq, highfreq, 0.05) # input: float; output: float @@ -62,25 +62,31 @@ class wfm_rcv_fmdet(gr.hier_block2): 15000 , width_of_transition_band, gr.firdes.WIN_HAMMING) + # input: float; output: float self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) if 1: - # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain - # We pick off the negative frequency half because we want to base band by it! - ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS + # Pick off the stereo carrier/2 with this filter. It + # attenuated 10 dB so apply 10 dB gain We pick off the + # negative frequency half because we want to base band by + # it! + ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO + ## DEEMPHASIS stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0, - demod_rate, - -19020, - -18980, - width_of_transition_band, - gr.firdes.WIN_HAMMING) + demod_rate, + -19020, + -18980, + width_of_transition_band, + gr.firdes.WIN_HAMMING) #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs) #print "stereo carrier filter ", stereo_carrier_filter_coeffs #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate - # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain + # Pick off the double side band suppressed carrier + # Left-Right audio. It is attenuated 10 dB so apply 10 dB + # gain stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0, demod_rate, @@ -90,101 +96,121 @@ class wfm_rcv_fmdet(gr.hier_block2): gr.firdes.WIN_HAMMING) #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs - # construct overlap add filter system from coefficients for stereo carrier - self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs) - - # carrier is twice the picked off carrier so arrange to do a commplex multiply + # construct overlap add filter system from coefficients + # for stereo carrier + self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, + stereo_carrier_filter_coeffs) + # carrier is twice the picked off carrier so arrange to do + # a commplex multiply self.stereo_carrier_generator = gr.multiply_cc(); # Pick off the rds signal - stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0, - demod_rate, - 57000 - 1500, - 57000 + 1500, - width_of_transition_band, - gr.firdes.WIN_HAMMING) + demod_rate, + 57000 - 1500, + 57000 + 1500, + width_of_transition_band, + gr.firdes.WIN_HAMMING) #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs # construct overlap add filter system from coefficients for stereo carrier - self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs) - - - - - - + self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation, + stereo_rds_filter_coeffs) self.rds_carrier_generator = gr.multiply_cc(); self.rds_signal_generator = gr.multiply_cc(); self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex); - - alpha = 5 * 0.25 * math.pi / (audio_rate) beta = alpha * alpha / 4.0 max_freq = -2.0*math.pi*18990/audio_rate; - min_freq = -2.0*math.pi*19010/audio_rate; + min_freq = -2.0*math.pi*19010/audio_rate; + self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta, + max_freq, + min_freq); + + #self.stereo_carrier_pll_recovery.squelch_enable(False) + ##pll_refout does not have squelch yet, so disabled for + #now - self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,max_freq,min_freq); - #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now - - - # set up mixer (multiplier) to get the L-R signal at baseband + # set up mixer (multiplier) to get the L-R signal at + # baseband self.stereo_basebander = gr.multiply_cc(); - # pick off the real component of the basebanded L-R signal. The imaginary SHOULD be zero + # pick off the real component of the basebanded L-R + # signal. The imaginary SHOULD be zero self.LmR_real = gr.complex_to_real(); self.Make_Left = gr.add_ff(); self.Make_Right = gr.sub_ff(); - self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs) + self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, + stereo_dsbsc_filter_coeffs) if 1: - # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier - self.connect (self, self.fm_demod,self.stereo_carrier_filter,self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0)) + # send the real signal to complex filter to pick off the + # carrier and then to one side of a multiplier + self.connect (self, self.fm_demod, self.stereo_carrier_filter, + self.stereo_carrier_pll_recovery, + (self.stereo_carrier_generator,0)) + # send the already filtered carrier to the otherside of the carrier + # the resulting signal from this multiplier is the carrier + # with correct phase but at -38000 Hz. self.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1)) - # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz. # send the new carrier to one side of the mixer (multiplier) self.connect (self.stereo_carrier_generator, (self.stereo_basebander,0)) + # send the demphasized audio to the DSBSC pick off filter, the complex # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier - self.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1)) # the result is BASEBANDED DSBSC with phase zero! + self.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1)) - # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer + # Pick off the real part since the imaginary is + # theoretically zero and then to one side of a summer self.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0)) - #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter + + #take the same real part of the DSBSC baseband signal and + #send it to negative side of a subtracter self.connect (self.LmR_real,(self.Make_Right,1)) - # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone + # Make rds carrier by taking the squared pilot tone and + # multiplying by pilot tone self.connect (self.stereo_basebander,(self.rds_carrier_generator,0)) self.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) - # take signal, filter off rds, send into mixer 0 channel + + # take signal, filter off rds, send into mixer 0 channel self.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0)) - # take rds_carrier_generator output and send into mixer 1 channel + + # take rds_carrier_generator output and send into mixer 1 + # channel self.connect (self.rds_carrier_generator,(self.rds_signal_generator,1)) - # send basebanded rds signal and send into "processor" which for now is a null sink + + # send basebanded rds signal and send into "processor" + # which for now is a null sink self.connect (self.rds_signal_generator,self_rds_signal_processor) if 1: - # pick off the audio, L+R that is what we used to have and send it to the summer + # pick off the audio, L+R that is what we used to have and + # send it to the summer self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1)) - # take the picked off L+R audio and send it to the PLUS side of the subtractor + + # take the picked off L+R audio and send it to the PLUS + # side of the subtractor self.connect(self.audio_filter,(self.Make_Right, 0)) + # The result of Make_Left gets (L+R) + (L-R) and results in 2*L # The result of Make_Right gets (L+R) - (L-R) and results in 2*R self.connect(self.Make_Left , self.deemph_Left, (self, 0)) self.connect(self.Make_Right, self.deemph_Right, (self, 1)) + # NOTE: mono support will require variable number of outputs in hier_block2s # See ticket:174 in Trac database #else: diff --git a/gnuradio-examples/python/Makefile.am b/gnuradio-examples/python/Makefile.am index 3f1977e74..a32f1fa86 100644 --- a/gnuradio-examples/python/Makefile.am +++ b/gnuradio-examples/python/Makefile.am @@ -22,15 +22,9 @@ include $(top_srcdir)/Makefile.common SUBDIRS = \ - apps \ - digital \ - digital-bert \ mp-sched \ - multi-antenna \ multi_usrp \ network \ ofdm \ pfb \ - tags \ - usrp \ - usrp2 + tags diff --git a/gnuradio-examples/python/apps/README b/gnuradio-examples/python/apps/README deleted file mode 100644 index b64b9d066..000000000 --- a/gnuradio-examples/python/apps/README +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2005 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. -# - -This directory servers as the parent directory for various and sundry -applications such as scanners, HF radios, etc. Each subdirectory -shall have a README file that includes a short description of what the -application does, and a list of hardware dependencies. E.g., requires -a USRP with an xyz daughterboard, connected to a footronics magic box. diff --git a/gnuradio-examples/python/apps/hf_explorer/README b/gnuradio-examples/python/apps/hf_explorer/README deleted file mode 100644 index 5f780b3d9..000000000 --- a/gnuradio-examples/python/apps/hf_explorer/README +++ /dev/null @@ -1,48 +0,0 @@ -hfx.py is meant to be a full-featured Long Wave / Medium Wave -and Short Wave (250kHz to 30Mhz) AM and Single Sideband receiver. -It uses the USRP with a Basic RX board, and will need an -antenna and some preamps, about 30db gain will work. See the -'Help' menu or hfx_help for more info. - ----------------------------------------------------------- - -hfx2.py is a major revision built about complex fir filter -coeffecients ability and cleaner python script. Inherits -most features from hfx.py - Powermate knob supported but -not required, tooltip frequency display, single click -tuning, AGC, record to disk, play from disk and record audio. -New feature is ability to tailor the audio passband with two -sliders over the spectrum display. The sliders almost align -with the actual frequency. Preset filter settings for LSB -(-3000 to 0kHz), USB (0 to +3000kHz), CW (-400 to -800Hz) -and AM (-5kHz from carrier to +5kHz). - -AM now switches in a synchronous PLL detector with the -carriers at 7.5kHz. The PLL carrier is displayed in the -bottom display and helps show where on the upper spectrum -the demodulated signal lies. Everything gets shifted up -7.5kHz in AM, center frequency, tooltips, etc. The target -AM carrier needs to be closely tuned in, it will have a -hollow sound untill it is locked, and then the PLL carrier -in the bottom display will jump up and remain relatively -constant. There is a slider "AM sync carrier" to play with -different levels to mix with the signal for demodulation. -The filter in AM is preset to 2500/12500 (7.5kHz +/- 5kHz) -and is handy for removing adjacent channel interference. -Change AM_SYNC_DISPLAY in script for whether to show AM -Sync carrier or not. -Run with "-h" for command line help with setting USRP -ddc center frequency, decimation, rf data record, playback -and audio data recording. - -There are some controls for controlling a varactor and -tuning an antenna - just ignore them unless you want -to build a voltage tuned antenna to track frequency. - -There is also code for Web based control of frequency and -volume - so I can tune the radio with an Ipaq from bed. -Disabled by default - it takes a web server, some -directories and scripts to use. - - - diff --git a/gnuradio-examples/python/apps/hf_radio/input.py b/gnuradio-examples/python/apps/hf_radio/input.py deleted file mode 100644 index 5984d8254..000000000 --- a/gnuradio-examples/python/apps/hf_radio/input.py +++ /dev/null @@ -1,46 +0,0 @@ -# Basic USRP setup and control. -# It's only ever been tried with a basic rx daughter card. -# -# Imagine that the gnuradio boilerplate is here. -# -# M. Revnell 2005-Dec - -from gnuradio import gr, gru, optfir -from gnuradio import usrp -from usrpm import usrp_dbid -import math - -# Put special knowlege of usrp here. - -class input: - def __init__( self, decim ): - self.freq = -2.5e6 - self.src = usrp.source_c( ) - self.subdev = usrp.pick_subdev( self.src, - (usrp_dbid.BASIC_RX, - usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO)) - - print self.subdev - - self.subdevice = usrp.selected_subdev( self.src, - self.subdev ) - - self.mux = usrp.determine_rx_mux_value( self.src, - self.subdev ) - self.decim = decim - - self.adc_rate = self.src.adc_rate() - self.usrp_rate = self.adc_rate / self.decim - self.src.set_decim_rate( self.decim ) - self.src.set_mux( self.mux ) - usrp.tune( self.src, 0, self.subdevice, self.freq ) - - def set_freq( self, x ): - r = usrp.tune( self.src, 0, self.subdevice, -x ) - if r: - self.freq = -x diff --git a/gnuradio-examples/python/apps/hf_radio/output.py b/gnuradio-examples/python/apps/hf_radio/output.py deleted file mode 100644 index dc9caf528..000000000 --- a/gnuradio-examples/python/apps/hf_radio/output.py +++ /dev/null @@ -1,17 +0,0 @@ -# Audio output with a volume control. -# -# M. Revnell 2005-Dec - -from gnuradio import gr, gru -from gnuradio import audio - -class output( gr.hier_block ): - def __init__( self, fg, rate ): - self.out = audio.sink( rate ) - self.vol = gr.multiply_const_ff( 0.1 ) - fg.connect( self.vol, self.out ) - gr.hier_block.__init__(self, fg, self.vol, None ) - - def set( self, val ): - self.vol.set_k( val ) - diff --git a/gnuradio-examples/python/apps/hf_radio/ssbagc.py b/gnuradio-examples/python/apps/hf_radio/ssbagc.py deleted file mode 100644 index fdf40bc6b..000000000 --- a/gnuradio-examples/python/apps/hf_radio/ssbagc.py +++ /dev/null @@ -1,48 +0,0 @@ -# post detection agc processing -# -# Imagine that the usual gnuradio copyright stuff is right here. -# -# This agc strategy is copied more or less verbatim from -# weaver_isb_am1_usrp3.py by cswiger. -# -# Thanks. -# -# Then modified in a variety of ways. -# -# There doesn't appear to be a way to hook multiple blocks to the -# input port when building a hier block like this. Thus the -# split below. -# -# Basic operation. -# Power is estimated by squaring the input. -# Low pass filter using a 1 pole iir. -# The time constant can be tweaked by changing the taps. -# Currently there is no implementation to change this while operating -# a potentially useful addition. -# The log block turns this into dB -# gain adjusts the agc authority. -# -# M. Revnell 2006-Jan - -from gnuradio import gr, gru - -class agc( gr.hier_block ): - def __init__( self, fg ): - self.split = gr.multiply_const_ff( 1 ) - self.sqr = gr.multiply_ff( ) - self.int0 = gr.iir_filter_ffd( [.004, 0], [0, .999] ) - self.offs = gr.add_const_ff( -30 ) - self.gain = gr.multiply_const_ff( 70 ) - self.log = gr.nlog10_ff( 10, 1 ) - self.agc = gr.divide_ff( ) - - fg.connect( self.split, ( self.agc, 0 ) ) - fg.connect( self.split, ( self.sqr, 0 ) ) - fg.connect( self.split, ( self.sqr, 1 ) ) - fg.connect( self.sqr, self.int0 ) - fg.connect( self.int0, self.log ) - fg.connect( self.log, self.offs ) - fg.connect( self.offs, self.gain ) - fg.connect( self.gain, ( self.agc, 1 ) ) - - gr.hier_block.__init__( self, fg, self.split, self.agc ) diff --git a/gnuradio-examples/python/digital-bert/README b/gnuradio-examples/python/digital-bert/README deleted file mode 100644 index 83f52f4f5..000000000 --- a/gnuradio-examples/python/digital-bert/README +++ /dev/null @@ -1,63 +0,0 @@ -BERT testing example scripts - - -benchmark_tx.py - -This sets up a BPSK transmitter that is modulated with a pseudorandom -sequence of bits. The PN code is generated by sending an all 1s -sequence through a 7-bit scrambler. The transmitter performs the BPSK -modulation, then passes the complex baseband waveform through a -root-raised-cosine filter and onto the USRP. - -The --sps parameter controls how many baseband samples per symbol -are created and passed through the RRC filter, prior to going to the -USRP over the USB for interpolation to the final DAC rate. - -The baseband bit rate is controlled by -r or --rate. This value, when -multiplied by the --sps parameter, must result in valid interpolation -rate for the USRP. For example, if the baseband rate is 250k bits/sec, -and the samples per symbol is 4, then the final rate is 1M samples/sec, -which results in an interpolation rate of 128. The valid interpolation -rates for the USRP are multiples of 4 between 16 and 512. - -Finally, the RRC excess bandwidth may be specified by --excess-bw. -(See ./benchmark_tx.py -h for additional parameters.) - - -benchmark_rx.py - -This sets up a BPSK receiver to demodulate the received waveform. It -accepts a similar set of parameters as the transmitter, except that one -specifies the USRP decimation rate desired. The resulting sample stream -rate must be an integral number of baseband symbols. For example, the -parameters corresponding to the above transmitter would be to use a -decimation rate of 8 (32 sps), 16 (16 sps), 32 (8 sps), 64, (4 sps), or -128 (2 sps). The lower the USRP decimation, the more CPU is required to -demodulate the signal, so not all valid decimation rates will work. - -The baseband signal from the USRP is first passed through an AGC to -establish an average power of 1.0. It is then passed through a matched -filter (another RRC), a Costas phase-locked loop, and a Mueller and -Muller bit timing recovery loop. The resulting constellation has an SNR -estimation probe attached, and is then sliced into a bit stream. - -The recovered bits are then passed through a 7-bit descrambler. If -there are no channel errors, the all 1s sequence is recovered. In the -event of a channel error, there will be a 0 in the bit stream for each -feedback tap in the descrambler. In this case, the CCSDS descrambler is -using 3 feedback taps. - -Finally, the signal is passed into a bit density measurement probe. The -channel BER is measured by dividing the 0s density by three. This -measurement is inaccurate at high BER rates (>10%) as the error 0s -begin to overlap. - -The benchmark script will, once per second, output the Costas loop -frequency offset, the recovered timing error, the estimated SNR, and the -average BER. - -NOTE: The particular SNR estimator used is inaccurate below about 7dB, -and will report erroneously high values even for random noise. - -There are a variety of Costas and M&M loop parameters one can adjust. -See ./benchmark_rx.py -h for the full set. diff --git a/gnuradio-examples/python/digital-bert/benchmark_rx.py b/gnuradio-examples/python/digital-bert/benchmark_rx.py deleted file mode 100755 index 1e00dbd76..000000000 --- a/gnuradio-examples/python/digital-bert/benchmark_rx.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 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, eng_notation, usrp -from optparse import OptionParser -from gnuradio.eng_option import eng_option -from receive_path import receive_path -import gnuradio.gr.gr_threading as _threading -import sys, time - -n2s = eng_notation.num_to_str - -class status_thread(_threading.Thread): - def __init__(self, tb): - _threading.Thread.__init__(self) - self.setDaemon(1) - self.tb = tb - self.done = False - self.start() - - def run(self): - while not self.done: - print "Freq. Offset: %5.0f Hz Timing Offset: %5.1f ppm Estimated SNR: %4.1f dB BER: %g" % ( - tb.frequency_offset(), tb.timing_offset()*1e6, tb.snr(), tb.ber()) - try: - time.sleep(1.0) - except KeyboardInterrupt: - self.done = True - -class rx_bpsk_block(gr.top_block): - def __init__(self, options): - - gr.top_block.__init__(self, "rx_mpsk") - - print "USRP decimation rate", options.decim_rate - - # Create a USRP source at desired board, sample rate, frequency, and gain - self._setup_usrp(options.which, - options.decim_rate, - options.rx_subdev_spec, - options.freq, - options.gain) - - # Create the BERT receiver - if_rate = self._usrp.adc_rate()/options.decim_rate - self._receiver = receive_path(if_rate, - options.rate, - options.excess_bw, - options.costas_alpha, - options.costas_beta, - options.costas_max, - options.mm_gain_mu, - options.mm_gain_omega, - options.mm_omega_limit) - - self.connect(self._usrp, self._receiver) - - - def _setup_usrp(self, which, decim, subdev_spec, freq, gain): - self._usrp = usrp.source_c(which=which, decim_rate=decim) - if subdev_spec is None: - subdev_spec = usrp.pick_rx_subdevice(self._usrp) - self._subdev = usrp.selected_subdev(self._usrp, subdev_spec) - mux = usrp.determine_rx_mux_value(self._usrp, subdev_spec) - self._usrp.set_mux(mux) - tr = self._usrp.tune(0, self._subdev, freq) - if not (tr): - print "Failed to tune to center frequency!" - else: - print "Center frequency:", n2s(freq) - if gain is None: - g = self._subdev.gain_range(); - gain = float(g[0]+g[1])/2.0 - self._subdev.set_gain(gain) - print "RX d'board:", self._subdev.side_and_name() - - def snr(self): - return self._receiver.snr() - - def mag(self): - return self._receiver.signal_mean() - - def var(self): - return self._receiver.noise_variance() - - def ber(self): - return self._receiver.ber() - - def frequency_offset(self): - return self._receiver.frequency_offset() - - def timing_offset(self): - return self._receiver.timing_offset() - -def get_options(): - parser = OptionParser(option_class=eng_option) - parser.add_option("-w", "--which", type="int", default=0, - help="select which USRP (0, 1, ...) (default is %default)", - metavar="NUM") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set Rx gain (default is mid-point)") - parser.add_option("-r", "--rate", type="eng_float", default=250e3, - help="Select modulation symbol rate (default=%default)") - parser.add_option("-d", "--decim-rate", type="int", default=8, - help="Select USRP decimation rate (default=%default)") - parser.add_option("", "--excess-bw", type="eng_float", default=0.35, - help="Select RRC excess bandwidth (default=%default)") - parser.add_option("", "--costas-alpha", type="eng_float", default=0.05, - help="set Costas loop 1st order gain, (default=%default)") - parser.add_option("", "--costas-beta", type="eng_float", default=0.00025, - help="set Costas loop 2nd order gain, (default=%default)") - parser.add_option("", "--costas-max", type="eng_float", default=0.05, - help="set Costas loop max freq (rad/sample) (default=%default)") - parser.add_option("", "--mm-gain-mu", type="eng_float", default=0.001, - help="set M&M loop 1st order gain, (default=%default)") - parser.add_option("", "--mm-gain-omega", type="eng_float", default=0.000001, - help="set M&M loop 2nd order gain, (default=%default)") - parser.add_option("", "--mm-omega-limit", type="eng_float", default=0.0001, - help="set M&M max timing error, (default=%default)") - - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - if options.freq == None: - print "You must supply a frequency with -f or --freq" - sys.exit(1) - - return (options, args) - - -if __name__ == "__main__": - (options, args) = get_options() - - tb = rx_bpsk_block(options) - - print "\n*** SNR estimator is inaccurate below about 7dB" - print "*** BER estimator is inaccurate above about 10%\n" - updater = status_thread(tb) - - try: - tb.run() - except KeyboardInterrupt: - updater.done = True - updater = None diff --git a/gnuradio-examples/python/digital-bert/benchmark_tx.py b/gnuradio-examples/python/digital-bert/benchmark_tx.py deleted file mode 100755 index 000f4bca2..000000000 --- a/gnuradio-examples/python/digital-bert/benchmark_tx.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 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, eng_notation, usrp -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from transmit_path import transmit_path -import sys - -_dac_rate = 128e6 - -n2s = eng_notation.num_to_str - -class tx_bpsk_block(gr.top_block): - def __init__(self, options): - gr.top_block.__init__(self, "tx_mpsk") - - self._transmitter = transmit_path(options.sps, - options.excess_bw, - options.amplitude) - - if_rate = options.rate*options.sps - interp = int(_dac_rate/if_rate) - - print "Modulation:", n2s(options.rate), "bits/sec" - print "TX IF rate:", n2s(if_rate), "samples/sec" - print "USRP interpolation:", interp - print "DAC amplitude:", options.amplitude - - self._setup_usrp(options.which, - interp, - options.tx_subdev_spec, - options.freq) - - self.connect(self._transmitter, self._usrp) - - - def _setup_usrp(self, which, interp, subdev_spec, freq): - self._usrp = usrp.sink_c(which=which, interp_rate=interp) - if subdev_spec is None: - subdev_spec = usrp.pick_tx_subdevice(self._usrp) - self._usrp.set_mux(usrp.determine_tx_mux_value(self._usrp, subdev_spec)) - self._subdev = usrp.selected_subdev(self._usrp, subdev_spec) - tr = usrp.tune(self._usrp, self._subdev.which(), self._subdev, freq) - if not (tr): - print "Failed to tune to center frequency!" - else: - print "Center frequency:", n2s(freq) - gain = float(self._subdev.gain_range()[1]) # Max TX gain - self._subdev.set_gain(gain) - self._subdev.set_enable(True) - print "TX d'board:", self._subdev.side_and_name() - - -def get_options(): - parser = OptionParser(option_class=eng_option) - parser.add_option("-w", "--which", type="int", default=0, - help="select which USRP (0, 1, ...) default is %default", - metavar="NUM") - parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, - help="select USRP Tx side A or B (default=first one with a daughterboard)") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-a", "--amplitude", type="eng_float", default=2000, - help="set Tx amplitude (0-32767) (default=%default)") - parser.add_option("-r", "--rate", type="eng_float", default=250e3, - help="Select modulation symbol rate (default=%default)") - parser.add_option("", "--sps", type="int", default=2, - help="Select samples per symbol (default=%default)") - parser.add_option("", "--excess-bw", type="eng_float", default=0.35, - help="Select RRC excess bandwidth (default=%default)") - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - if options.freq == None: - print "Must supply frequency as -f or --freq" - sys.exit(1) - - return (options, args) - -if __name__ == "__main__": - (options, args) = get_options() - - tb = tx_bpsk_block(options) - - try: - tb.run() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital-bert/receive_path.py b/gnuradio-examples/python/digital-bert/receive_path.py deleted file mode 100644 index e273923a4..000000000 --- a/gnuradio-examples/python/digital-bert/receive_path.py +++ /dev/null @@ -1,118 +0,0 @@ -# -# Copyright 2008 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, eng_notation -import math - -n2s = eng_notation.num_to_str - -class receive_path(gr.hier_block2): - def __init__(self, - if_rate, # Incoming sample rate - symbol_rate, # Original symbol rate - excess_bw, # RRC excess bandwidth, typically 0.35-0.5 - costas_alpha, # Costas loop 1st order gain, typically 0.01-0.2 - costas_beta, # Costas loop 2nd order gain, typically alpha^2/4.0 - costas_max, # Costas loop max frequency offset in radians/sample - mm_gain_mu, # M&M loop 1st order gain, typically 0.001-0.2 - mm_gain_omega, # M&M loop 2nd order gain, typically alpha^2/4.0 - mm_omega_limit, # M&M loop max timing error - ): - - gr.hier_block2.__init__(self, "receive_path", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(0, 0, 0)) # Output signature - - self._if_rate = if_rate - self._sps = int(self._if_rate/symbol_rate) - print "IF sample rate:", n2s(self._if_rate) - print "Symbol rate:", n2s(symbol_rate) - print "Samples/symbol:", self._sps - print "RRC bandwidth:", excess_bw - - # Create AGC to scale input to unity - self._agc = gr.agc_cc(1e-5, 1.0, 1.0, 1.0) - - # Create RRC with specified excess bandwidth - taps = gr.firdes.root_raised_cosine(1.0, # Gain - self._sps, # Sampling rate - 1.0, # Symbol rate - excess_bw, # Roll-off factor - 11*self._sps) # Number of taps - - self._rrc = gr.fir_filter_ccf(1, taps) - - # Create a Costas loop frequency/phase recovery block - - print "Costas alpha:", costas_alpha - print "Costas beta:", costas_beta - print "Costas max:", costas_max - - self._costas = gr.costas_loop_cc(costas_alpha, # PLL first order gain - costas_beta, # PLL second order gain - costas_max, # Max frequency offset rad/sample - -costas_max, # Min frequency offset rad/sample - 2) # BPSK - - # Create a M&M bit synchronization retiming block - mm_mu = 0.5 - mm_omega = self._sps - - print "MM gain mu:", mm_gain_mu - print "MM gain omega:", mm_gain_omega - print "MM omega limit:", mm_omega_limit - - self._mm = gr.clock_recovery_mm_cc(mm_omega, # Initial samples/symbol - mm_gain_omega, # Second order gain - mm_mu, # Initial symbol phase - mm_gain_mu, # First order gain - mm_omega_limit) # Maximum timing offset - - # Add an SNR probe on the demodulated constellation - self._snr_probe = gr.probe_mpsk_snr_c(10.0/symbol_rate) - self.connect(self._mm, self._snr_probe) - - # Slice the resulting constellation into bits. - # Get inphase channel and make decision about 0 - self._c2r = gr.complex_to_real() - self._slicer = gr.binary_slicer_fb() - - # Descramble BERT sequence. A channel error will create 3 incorrect bits - self._descrambler = gr.descrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit descrambler - - # Measure BER by the density of 0s in the stream - self._ber = gr.probe_density_b(1.0/symbol_rate) - - self.connect(self, self._agc, self._rrc, self._costas, self._mm, - self._c2r, self._slicer, self._descrambler, self._ber) - - def frequency_offset(self): - return self._costas.freq()*self._if_rate/(2*math.pi) - - def timing_offset(self): - return self._mm.omega()/self._sps-1.0 - - def snr(self): - return self._snr_probe.snr() - - def ber(self): - return (1.0-self._ber.density())/3.0 - diff --git a/gnuradio-examples/python/digital-bert/transmit_path.py b/gnuradio-examples/python/digital-bert/transmit_path.py deleted file mode 100644 index 96834b398..000000000 --- a/gnuradio-examples/python/digital-bert/transmit_path.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2008 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 -from math import pi, log10 -import cmath - -class transmit_path(gr.hier_block2): - """ - This transmits a BERT sequence of bits using filtered BPSK and - outputs the complex baseband waveform. - """ - def __init__(self, - sps, # Samples per symbol - excess_bw, # RRC filter excess bandwidth (typically 0.35-0.5) - amplitude # DAC output level, 0-32767, typically 2000-8000 - ): - - gr.hier_block2.__init__(self, "transmit_path", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - # Create BERT data bit stream - self._bits = gr.vector_source_b([1,], True) # Infinite stream of ones - self._scrambler = gr.scrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit scrambler - - # Map to constellation - self._constellation = [-1+0j, 1+0j] - self._mapper = gr.chunks_to_symbols_bc(self._constellation) - - # Create RRC with specified excess bandwidth - taps = gr.firdes.root_raised_cosine(sps*amplitude, # Gain - sps, # Sampling rate - 1.0, # Symbol rate - excess_bw, # Roll-off factor - 11*sps) # Number of taps - - self._rrc = gr.interp_fir_filter_ccf(sps, # Interpolation rate - taps) # FIR taps - - # Wire block inputs and outputs - self.connect(self._bits, self._scrambler, self._mapper, self._rrc, self) - diff --git a/gnuradio-examples/python/digital/benchmark_loopback.py b/gnuradio-examples/python/digital/benchmark_loopback.py deleted file mode 100755 index 47e4f2028..000000000 --- a/gnuradio-examples/python/digital/benchmark_loopback.py +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005, 2006, 2007, 2009 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, gru, modulation_utils -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random, time, struct, sys, math - -# from current dir -from transmit_path import transmit_path -from receive_path import receive_path - -class my_top_block(gr.top_block): - def __init__(self, mod_class, demod_class, rx_callback, options): - gr.top_block.__init__(self) - - channelon = True; - - SNR = 10.0**(options.snr/10.0) - frequency_offset = options.frequency_offset - - power_in_signal = abs(options.tx_amplitude)**2 - noise_power = power_in_signal/SNR - noise_voltage = math.sqrt(noise_power) - - # With new interface, sps does not get set by default, but - # in the loopback, we don't recalculate it; so just force it here - if(options.samples_per_symbol == None): - options.samples_per_symbol = 2 - - self.txpath = transmit_path(mod_class, options) - self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate) - self.rxpath = receive_path(demod_class, rx_callback, options) - - if channelon: - self.channel = gr.channel_model(noise_voltage, frequency_offset, 1.01) - - if options.discontinuous: - z = 20000*[0,] - self.zeros = gr.vector_source_c(z, True) - packet_size = 5*((4+8+4+1500+4) * 8) - self.mux = gr.stream_mux(gr.sizeof_gr_complex, [packet_size-0, int(9e5)]) - - # Connect components - self.connect(self.txpath, (self.mux,0)) - self.connect(self.zeros, (self.mux,1)) - self.connect(self.mux, self.channel, self.rxpath) - - else: - self.connect(self.txpath, self.channel, self.rxpath) - - else: - # Connect components - self.connect(self.txpath, self.throttle, self.rxpath) - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -def main(): - - global n_rcvd, n_right - - n_rcvd = 0 - n_right = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - # print payload[2:len(payload)] - - def send_pkt(payload='', eof=False): - return tb.txpath.send_pkt(payload, eof) - - - mods = modulation_utils.type_1_mods() - demods = modulation_utils.type_1_demods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - channel_grp = parser.add_option_group("Channel") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='dbpsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-s", "--size", type="eng_float", default=1500, - help="set packet size [default=%default]") - parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, - help="set megabytes to transmit [default=%default]") - parser.add_option("","--discontinuous", action="store_true", default=False, - help="enable discontinous transmission (bursts of 5 packets)") - - channel_grp.add_option("", "--sample-rate", type="eng_float", default=1e5, - help="set speed of channel/simulation rate to RATE [default=%default]") - channel_grp.add_option("", "--snr", type="eng_float", default=30, - help="set the SNR of the channel in dB [default=%default]") - channel_grp.add_option("", "--frequency-offset", type="eng_float", default=0, - help="set frequency offset introduced by channel [default=%default]") - channel_grp.add_option("", "--seed", action="store_true", default=False, - help="use a random seed for AWGN noise [default=%default]") - - transmit_path.add_options(parser, expert_grp) - receive_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - for demod in demods.values(): - demod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - # Create an instance of a hierarchical block - tb = my_top_block(mods[options.modulation], demods[options.modulation], rx_callback, options) - tb.start() - - # generate and send packets - nbytes = int(1e6 * options.megabytes) - n = 0 - pktno = 0 - pkt_size = int(options.size) - - while n < nbytes: - send_pkt(struct.pack('!H', pktno & 0xffff) + (pkt_size - 2) * chr(pktno & 0xff)) - n += pkt_size - pktno += 1 - - send_pkt(eof=True) - - tb.wait() - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_qt_loopback.py b/gnuradio-examples/python/digital/benchmark_qt_loopback.py deleted file mode 100755 index 0ae0e4e51..000000000 --- a/gnuradio-examples/python/digital/benchmark_qt_loopback.py +++ /dev/null @@ -1,470 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru, modulation_utils -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import random, time, struct, sys, os, math - -from threading import Thread - -# from current dir -from transmit_path import transmit_path -from receive_path import receive_path - -try: - from gnuradio.qtgui import qtgui - from PyQt4 import QtGui, QtCore - import sip -except ImportError: - print "Please install gr-qtgui." - sys.exit(1) - -try: - from qt_digital_window import Ui_DigitalWindow -except ImportError: - print "Error: could not find qt_digital_window.py:" - print "\t\"pyuic4 qt_digital_window.ui -o qt_digital_window.py\"" - sys.exit(1) - - -#print os.getpid() -#raw_input() - - -# //////////////////////////////////////////////////////////////////// -# Define the QT Interface and Control Dialog -# //////////////////////////////////////////////////////////////////// - - -class dialog_box(QtGui.QMainWindow): - def __init__(self, snkTx, snkRx, fg, parent=None): - - QtGui.QWidget.__init__(self, parent) - self.gui = Ui_DigitalWindow() - self.gui.setupUi(self) - - self.fg = fg - - self.set_sample_rate(self.fg.sample_rate()) - - self.set_snr(self.fg.snr()) - self.set_frequency(self.fg.frequency_offset()) - self.set_time_offset(self.fg.timing_offset()) - - self.set_gain_mu(self.fg.rx_timing_gain_alpha()) - self.set_alpha(self.fg.rx_alpha()) - - # Add the qtsnk widgets to the hlayout box - self.gui.sinkLayout.addWidget(snkTx) - self.gui.sinkLayout.addWidget(snkRx) - - - # Connect up some signals - self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"), - self.pauseFg) - - self.connect(self.gui.sampleRateEdit, QtCore.SIGNAL("editingFinished()"), - self.sampleRateEditText) - - self.connect(self.gui.snrEdit, QtCore.SIGNAL("editingFinished()"), - self.snrEditText) - self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"), - self.freqEditText) - self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"), - self.timeEditText) - - self.connect(self.gui.gainMuEdit, QtCore.SIGNAL("editingFinished()"), - self.gainMuEditText) - self.connect(self.gui.alphaEdit, QtCore.SIGNAL("editingFinished()"), - self.alphaEditText) - - # Build a timer to update the packet number and PER fields - self.update_delay = 250 # time between updating packet rate fields - self.pkt_timer = QtCore.QTimer(self) - self.connect(self.pkt_timer, QtCore.SIGNAL("timeout()"), - self.updatePacketInfo) - self.pkt_timer.start(self.update_delay) - - def pauseFg(self): - if(self.gui.pauseButton.text() == "Pause"): - self.fg.stop() - self.fg.wait() - self.gui.pauseButton.setText("Unpause") - else: - self.fg.start() - self.gui.pauseButton.setText("Pause") - - # Accessor functions for Gui to manipulate system parameters - def set_sample_rate(self, sr): - ssr = eng_notation.num_to_str(sr) - self.gui.sampleRateEdit.setText(QtCore.QString("%1").arg(ssr)) - - def sampleRateEditText(self): - try: - rate = self.gui.sampleRateEdit.text().toAscii() - srate = eng_notation.str_to_num(rate) - #self.fg.set_sample_rate(srate) - except RuntimeError: - pass - - - # Accessor functions for Gui to manipulate channel model - def set_snr(self, snr): - self.gui.snrEdit.setText(QtCore.QString("%1").arg(snr)) - - def set_frequency(self, fo): - self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo)) - - def set_time_offset(self, to): - self.gui.timeEdit.setText(QtCore.QString("%1").arg(to)) - - def snrEditText(self): - try: - snr = self.gui.snrEdit.text().toDouble()[0] - self.fg.set_snr(snr) - except RuntimeError: - pass - - def freqEditText(self): - try: - freq = self.gui.freqEdit.text().toDouble()[0] - self.fg.set_frequency_offset(freq) - except RuntimeError: - pass - - def timeEditText(self): - try: - to = self.gui.timeEdit.text().toDouble()[0] - self.fg.set_timing_offset(to) - except RuntimeError: - pass - - - # Accessor functions for Gui to manipulate receiver parameters - def set_gain_mu(self, gain): - self.gui.gainMuEdit.setText(QtCore.QString("%1").arg(gain)) - - def set_alpha(self, alpha): - self.gui.alphaEdit.setText(QtCore.QString("%1").arg(alpha)) - - def alphaEditText(self): - try: - alpha = self.gui.alphaEdit.text().toDouble()[0] - self.fg.set_rx_alpha(alpha) - except RuntimeError: - pass - - def gainMuEditText(self): - try: - gain = self.gui.gainMuEdit.text().toDouble()[0] - self.fg.set_rx_timing_gain_alpha(gain) - except RuntimeError: - pass - - # Accessor functions for packet error reporting - def updatePacketInfo(self): - # Pull these globals in from the main thread - global n_rcvd, n_right, pktno - - if(pktno > 0): - per = float(n_rcvd - n_right)/float(pktno) - else: - per = 0 - self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd)) - self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right)) - self.gui.perEdit.setText(QtCore.QString("%1").arg(per)) - - - -# //////////////////////////////////////////////////////////////////// -# Define the GNU Radio Top Block -# //////////////////////////////////////////////////////////////////// - - - -class my_top_block(gr.top_block): - def __init__(self, mod_class, demod_class, rx_callback, options): - gr.top_block.__init__(self) - - self._sample_rate = options.sample_rate - - if(options.samples_per_symbol is None): - options.samples_per_symbol = 2 - - channelon = True; - - self.gui_on = options.gui - - self._frequency_offset = options.frequency_offset - self._timing_offset = options.timing_offset - self._tx_amplitude = options.tx_amplitude - self._snr_dB = options.snr - - self._noise_voltage = self.get_noise_voltage(self._snr_dB) - - self.txpath = transmit_path(mod_class, options) - self.throttle = gr.throttle(gr.sizeof_gr_complex, self.sample_rate()) - self.rxpath = receive_path(demod_class, rx_callback, options) - - # FIXME: do better exposure to lower issues for control - self._timing_gain_alpha = self.rxpath.packet_receiver._demodulator._mm_gain_mu - self._alpha = self.rxpath.packet_receiver._demodulator._costas_alpha - - if channelon: - self.channel = gr.channel_model(self._noise_voltage, - self.frequency_offset(), - self.timing_offset()) - - if options.discontinuous: - z = 20000*[0,] - self.zeros = gr.vector_source_c(z, True) - packet_size = 5*((4+8+4+1500+4) * 8) - self.mux = gr.stream_mux(gr.sizeof_gr_complex, [packet_size-0, int(9e5)]) - - # Connect components - self.connect(self.txpath, self.throttle, (self.mux,0)) - self.connect(self.zeros, (self.mux,1)) - self.connect(self.mux, self.channel, self.rxpath) - - else: - self.connect(self.txpath, self.throttle, self.channel, self.rxpath) - - if self.gui_on: - self.qapp = QtGui.QApplication(sys.argv) - fftsize = 2048 - - self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - 0, self._sample_rate, - "Tx", True, True, False, True, True) - self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - 0, self._sample_rate, - "Rx", True, True, False, True, True) - - self.snk_tx.set_frequency_axis(-80, 0) - self.snk_rx.set_frequency_axis(-60, 20) - - # Connect to the QT sinks - # FIXME: make better exposure to receiver from rxpath - self.receiver = self.rxpath.packet_receiver._demodulator.receiver - self.receiver.set_alpha(2) - self.receiver.set_beta(0.02) - self.connect(self.channel, self.snk_tx) - self.connect(self.receiver, self.snk_rx) - - pyTxQt = self.snk_tx.pyqwidget() - pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget) - - pyRxQt = self.snk_rx.pyqwidget() - pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget) - - self.main_box = dialog_box(pyTx, pyRx, self) - self.main_box.show() - - else: - # Connect components - self.connect(self.txpath, self.throttle, self.rxpath) - - - - # System Parameters - def sample_rate(self): - return self._sample_rate - - def set_sample_rate(self, sr): - self._sample_rate = sr - #self.throttle.set_samples_per_second(self._sample_rate) - - # Channel Model Parameters - def snr(self): - return self._snr_dB - - def set_snr(self, snr): - self._snr_dB = snr - self._noise_voltage = self.get_noise_voltage(self._snr_dB) - self.channel.set_noise_voltage(self._noise_voltage) - - def get_noise_voltage(self, SNR): - snr = 10.0**(SNR/10.0) - power_in_signal = abs(self._tx_amplitude)**2 - noise_power = power_in_signal/snr - noise_voltage = math.sqrt(noise_power) - return noise_voltage - - def frequency_offset(self): - return self._frequency_offset * self.sample_rate() - - def set_frequency_offset(self, fo): - self._frequency_offset = fo / self.sample_rate() - self.channel.set_frequency_offset(self._frequency_offset) - - def timing_offset(self): - return self._timing_offset - - def set_timing_offset(self, to): - self._timing_offset = to - self.channel.set_timing_offset(self._timing_offset) - - - # Receiver Parameters - def rx_timing_gain_alpha(self): - return self._timing_gain_alpha - - def rx_timing_gain_beta(self): - return self._timing_gain_beta - - def set_rx_timing_gain_alpha(self, gain): - self._timing_gain_alpha = gain - self.receiver.set_gain_mu(self._timing_gain_alpha) - - def rx_alpha(self): - return self._alpha - - def rx_beta(self): - return self.beta - - def set_rx_alpha(self, alpha): - self._alpha = alpha - self.beta = .25 * self._alpha * self._alpha - self.receiver.set_alpha(self._alpha) - self.receiver.set_beta(self.beta) - - - -# ///////////////////////////////////////////////////////////////////////////// -# Thread to handle the packet sending procedure -# Operates in parallel with qApp.exec_() -# ///////////////////////////////////////////////////////////////////////////// - - - -class th_send(Thread): - def __init__(self, send_fnc, megs, sz): - Thread.__init__(self) - self.send = send_fnc - self.nbytes = int(1e6 * megs) - self.pkt_size = int(sz) - - def run(self): - # generate and send packets - n = 0 - pktno = 0 - - while n < self.nbytes: - self.send(struct.pack('!H', pktno & 0xffff) + - (self.pkt_size - 2) * chr(pktno & 0xff)) - n += self.pkt_size - pktno += 1 - - self.send(eof=True) - - def stop(self): - self.nbytes = 0 - - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - - - -def main(): - - global n_rcvd, n_right, pktno - - n_rcvd = 0 - n_right = 0 - pktno = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right, pktno - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - if not options.gui: - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - - def send_pkt(payload='', eof=False): - return tb.txpath.send_pkt(payload, eof) - - mods = modulation_utils.type_1_mods() - demods = modulation_utils.type_1_demods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - channel_grp = parser.add_option_group("Channel") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='dbpsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-s", "--size", type="eng_float", default=1500, - help="set packet size [default=%default]") - parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, - help="set megabytes to transmit [default=%default]") - parser.add_option("","--discontinuous", action="store_true", default=False, - help="enable discontinous transmission (bursts of 5 packets)") - parser.add_option("-G", "--gui", action="store_true", default=False, - help="Turn on the GUI [default=%default]") - - channel_grp.add_option("", "--sample-rate", type="eng_float", default=1e5, - help="set speed of channel/simulation rate to RATE [default=%default]") - channel_grp.add_option("", "--snr", type="eng_float", default=30, - help="set the SNR of the channel in dB [default=%default]") - channel_grp.add_option("", "--frequency-offset", type="eng_float", default=0, - help="set frequency offset introduced by channel [default=%default]") - channel_grp.add_option("", "--timing-offset", type="eng_float", default=1.0, - help="set timing offset introduced by channel [default=%default]") - channel_grp.add_option("", "--seed", action="store_true", default=False, - help="use a random seed for AWGN noise [default=%default]") - - transmit_path.add_options(parser, expert_grp) - receive_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - for demod in demods.values(): - demod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - # Create an instance of a hierarchical block - tb = my_top_block(mods[options.modulation], - demods[options.modulation], - rx_callback, options) - tb.start() - - packet_sender = th_send(send_pkt, options.megabytes, options.size) - packet_sender.start() - - if(options.gui): - tb.qapp.exec_() - packet_sender.stop() - else: - # Process until done; hack in to the join to stop on an interrupt - while(packet_sender.isAlive()): - try: - packet_sender.join(1) - except KeyboardInterrupt: - packet_sender.stop() - - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py deleted file mode 100755 index a36f4fbd4..000000000 --- a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py +++ /dev/null @@ -1,553 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 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, modulation_utils2 -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import struct, sys, math - -from threading import Thread - -# from current dir -from transmit_path import transmit_path -from receive_path import receive_path - -try: - from gnuradio.qtgui import qtgui - from PyQt4 import QtGui, QtCore - import sip -except ImportError: - print "Please install gr-qtgui." - sys.exit(1) - -try: - from qt_digital_window2 import Ui_DigitalWindow -except ImportError: - print "Error: could not find qt_digital_window2.py:" - print "\t\"pyuic4 qt_digital_window2.ui -o qt_digital_window2.py\"" - sys.exit(1) - - -#print os.getpid() -#raw_input() - - -# //////////////////////////////////////////////////////////////////// -# Define the QT Interface and Control Dialog -# //////////////////////////////////////////////////////////////////// - - -class dialog_box(QtGui.QMainWindow): - def __init__(self, snkTx, snkRx, fg, parent=None): - - QtGui.QWidget.__init__(self, parent) - self.gui = Ui_DigitalWindow() - self.gui.setupUi(self) - - self.fg = fg - - self.set_sample_rate(self.fg.sample_rate()) - - self.set_snr(self.fg.snr()) - self.set_frequency(self.fg.frequency_offset()) - self.set_time_offset(self.fg.timing_offset()) - - self.set_gain_clock(self.fg.rx_gain_clock()) - self.set_gain_phase(self.fg.rx_gain_phase()) - self.set_gain_freq(self.fg.rx_gain_freq()) - - # Add the qtsnk widgets to the hlayout box - self.gui.sinkLayout.addWidget(snkTx) - self.gui.sinkLayout.addWidget(snkRx) - - - # Connect up some signals - self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"), - self.pauseFg) - - self.connect(self.gui.sampleRateEdit, QtCore.SIGNAL("editingFinished()"), - self.sampleRateEditText) - - self.connect(self.gui.snrEdit, QtCore.SIGNAL("editingFinished()"), - self.snrEditText) - self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"), - self.freqEditText) - self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"), - self.timeEditText) - - self.connect(self.gui.gainClockEdit, QtCore.SIGNAL("editingFinished()"), - self.gainClockEditText) - self.connect(self.gui.gainPhaseEdit, QtCore.SIGNAL("editingFinished()"), - self.gainPhaseEditText) - self.connect(self.gui.gainFreqEdit, QtCore.SIGNAL("editingFinished()"), - self.gainFreqEditText) - - # Build a timer to update the packet number and PER fields - self.update_delay = 250 # time between updating packet rate fields - self.pkt_timer = QtCore.QTimer(self) - self.connect(self.pkt_timer, QtCore.SIGNAL("timeout()"), - self.updatePacketInfo) - self.pkt_timer.start(self.update_delay) - - def pauseFg(self): - if(self.gui.pauseButton.text() == "Pause"): - self.fg.stop() - self.fg.wait() - self.gui.pauseButton.setText("Unpause") - else: - self.fg.start() - self.gui.pauseButton.setText("Pause") - - # Accessor functions for Gui to manipulate system parameters - def set_sample_rate(self, sr): - ssr = eng_notation.num_to_str(sr) - self.gui.sampleRateEdit.setText(QtCore.QString("%1").arg(ssr)) - - def sampleRateEditText(self): - try: - rate = self.gui.sampleRateEdit.text().toAscii() - srate = eng_notation.str_to_num(rate) - #self.fg.set_sample_rate(srate) - except RuntimeError: - pass - - - # Accessor functions for Gui to manipulate channel model - def set_snr(self, snr): - self.gui.snrEdit.setText(QtCore.QString("%1").arg(snr)) - - def set_frequency(self, fo): - self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo)) - - def set_time_offset(self, to): - self.gui.timeEdit.setText(QtCore.QString("%1").arg(to)) - - def snrEditText(self): - try: - snr = self.gui.snrEdit.text().toDouble()[0] - self.fg.set_snr(snr) - except RuntimeError: - pass - - def freqEditText(self): - try: - freq = self.gui.freqEdit.text().toDouble()[0] - self.fg.set_frequency_offset(freq) - except RuntimeError: - pass - - def timeEditText(self): - try: - to = self.gui.timeEdit.text().toDouble()[0] - self.fg.set_timing_offset(to) - except RuntimeError: - pass - - - # Accessor functions for Gui to manipulate receiver parameters - def set_gain_clock(self, gain): - self.gui.gainClockEdit.setText(QtCore.QString("%1").arg(gain)) - - def set_gain_phase(self, gain_phase): - self.gui.gainPhaseEdit.setText(QtCore.QString("%1").arg(gain_phase)) - - def set_gain_freq(self, gain_freq): - self.gui.gainFreqEdit.setText(QtCore.QString("%1").arg(gain_freq)) - - - def set_alpha_time(self, alpha): - self.gui.alphaTimeEdit.setText(QtCore.QString("%1").arg(alpha)) - - def set_beta_time(self, beta): - self.gui.betaTimeEdit.setText(QtCore.QString("%1").arg(beta)) - - def set_alpha_phase(self, alpha): - self.gui.alphaPhaseEdit.setText(QtCore.QString("%1").arg(alpha)) - - def gainPhaseEditText(self): - try: - gain_phase = self.gui.gainPhaseEdit.text().toDouble()[0] - self.fg.set_rx_gain_phase(gain_phase) - except RuntimeError: - pass - - def gainClockEditText(self): - try: - gain = self.gui.gainClockEdit.text().toDouble()[0] - self.fg.set_rx_gain_clock(gain) - except RuntimeError: - pass - - def gainFreqEditText(self): - try: - gain = self.gui.gainFreqEdit.text().toDouble()[0] - self.fg.set_rx_gain_freq(gain) - except RuntimeError: - pass - - # Accessor functions for packet error reporting - def updatePacketInfo(self): - # Pull these globals in from the main thread - global n_rcvd, n_right, pktno - - if(pktno > 0): - per = float(n_rcvd - n_right)/float(pktno) - else: - per = 0 - self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd)) - self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right)) - self.gui.perEdit.setText(QtCore.QString("%1").arg(float(per), 0, 'e', 4)) - - - -# //////////////////////////////////////////////////////////////////// -# Define the GNU Radio Top Block -# //////////////////////////////////////////////////////////////////// - - - -class my_top_block(gr.top_block): - def __init__(self, mod_class, demod_class, rx_callback, options): - gr.top_block.__init__(self) - - self._sample_rate = options.sample_rate - - channelon = True; - - self.gui_on = options.gui - - self._frequency_offset = options.frequency_offset - self._timing_offset = options.timing_offset - self._tx_amplitude = options.tx_amplitude - self._snr_dB = options.snr - - self._noise_voltage = self.get_noise_voltage(self._snr_dB) - - # With new interface, sps does not get set by default, but - # in the loopback, we don't recalculate it; so just force it here - if(options.samples_per_symbol == None): - options.samples_per_symbol = 2 - - self.txpath = transmit_path(mod_class, options) - self.throttle = gr.throttle(gr.sizeof_gr_complex, self.sample_rate()) - self.rxpath = receive_path(demod_class, rx_callback, options) - - # FIXME: do better exposure to lower issues for control - self._gain_clock = self.rxpath.packet_receiver._demodulator._timing_alpha - self._gain_phase = self.rxpath.packet_receiver._demodulator._phase_alpha - self._gain_freq = self.rxpath.packet_receiver._demodulator._freq_alpha - - if channelon: - self.channel = gr.channel_model(self._noise_voltage, - self.frequency_offset(), - self.timing_offset()) - - if options.discontinuous: - z = 20000*[0,] - self.zeros = gr.vector_source_c(z, True) - packet_size = 5*((4+8+4+1500+4) * 8) - self.mux = gr.stream_mux(gr.sizeof_gr_complex, [packet_size-0, int(9e5)]) - - # Connect components - self.connect(self.txpath, self.throttle, (self.mux,0)) - self.connect(self.zeros, (self.mux,1)) - self.connect(self.mux, self.channel, self.rxpath) - - else: - self.connect(self.txpath, self.throttle, self.channel, self.rxpath) - - if self.gui_on: - self.qapp = QtGui.QApplication(sys.argv) - fftsize = 2048 - - self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - 0, 1, - "Tx", True, True, False, True, True) - self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - 0, 1, - "Rx", True, True, False, True, True) - - self.snk_tx.set_frequency_axis(-80, 0) - self.snk_rx.set_frequency_axis(-60, 20) - - self.freq_recov = self.rxpath.packet_receiver._demodulator.freq_recov - self.phase_recov = self.rxpath.packet_receiver._demodulator.phase_recov - self.time_recov = self.rxpath.packet_receiver._demodulator.time_recov - self.freq_recov.set_alpha(self._gain_freq) - self.freq_recov.set_beta(self._gain_freq/10.0) - self.phase_recov.set_alpha(self._gain_phase) - self.phase_recov.set_beta(0.25*self._gain_phase*self._gain_phase) - self.time_recov.set_alpha(self._gain_clock) - self.time_recov.set_beta(0.25*self._gain_clock*self._gain_clock) - - # Connect to the QT sinks - # FIXME: make better exposure to receiver from rxpath - self.connect(self.channel, self.snk_tx) - self.connect(self.phase_recov, self.snk_rx) - #self.connect(self.freq_recov, self.snk_rx) - - pyTxQt = self.snk_tx.pyqwidget() - pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget) - - pyRxQt = self.snk_rx.pyqwidget() - pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget) - - self.main_box = dialog_box(pyTx, pyRx, self) - self.main_box.show() - - else: - # Connect components - self.connect(self.txpath, self.throttle, self.rxpath) - - if options.verbose: - self._print_verbage() - - if options.log: - self._setup_logging() - - - - - # System Parameters - def sample_rate(self): - return self._sample_rate - - def set_sample_rate(self, sr): - self._sample_rate = sr - #self.throttle.set_samples_per_second(self._sample_rate) - - # Channel Model Parameters - def snr(self): - return self._snr_dB - - def set_snr(self, snr): - self._snr_dB = snr - self._noise_voltage = self.get_noise_voltage(self._snr_dB) - self.channel.set_noise_voltage(self._noise_voltage) - - def get_noise_voltage(self, SNR): - snr = 10.0**(SNR/10.0) - power_in_signal = abs(self._tx_amplitude)**2 - noise_power = power_in_signal/snr - noise_voltage = math.sqrt(noise_power) - return noise_voltage - - def frequency_offset(self): - return self._frequency_offset * self.sample_rate() - - def set_frequency_offset(self, fo): - self._frequency_offset = fo / self.sample_rate() - self.channel.set_frequency_offset(self._frequency_offset) - - def timing_offset(self): - return self._timing_offset - - def set_timing_offset(self, to): - self._timing_offset = to - self.channel.set_timing_offset(self._timing_offset) - - - # Receiver Parameters - def rx_gain_clock(self): - return self._gain_clock - - def rx_gain_clock_beta(self): - return self._gain_clock_beta - - def set_rx_gain_clock(self, gain): - self._gain_clock = gain - self._gain_clock_beta = .25 * self._gain_clock * self._gain_clock - self.rxpath.packet_receiver._demodulator.time_recov.set_alpha(self._gain_clock) - self.rxpath.packet_receiver._demodulator.time_recov.set_beta(self._gain_clock_beta) - - def rx_gain_phase(self): - return self._gain_phase - - def rx_gain_phase_beta(self): - return self._gain_phase_beta - - def set_rx_gain_phase(self, gain_phase): - self._gain_phase = gain_phase - self._gain_phase_beta = .25 * self._gain_phase * self._gain_phase - self.rxpath.packet_receiver._demodulator.phase_recov.set_alpha(self._gain_phase) - self.rxpath.packet_receiver._demodulator.phase_recov.set_beta(self._gain_phase_beta) - - - def rx_gain_freq(self): - return self._gain_freq - - def set_rx_gain_freq(self, gain_freq): - self._gain_freq = gain_freq - #self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq - self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq) - self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0) - #self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta) - - def _print_verbage(self): - print "\nChannel:" - print "SNR: %d" % self.snr() - print "Noise voltage: %.2e" % self.get_noise_voltage(self.snr()) - print "Frequency offset: %.2e" % self.frequency_offset() - print "Timing offset: %.2e" % self.timing_offset() - - def _setup_logging(self): - pass - -# ///////////////////////////////////////////////////////////////////////////// -# Thread to handle the packet sending procedure -# Operates in parallel with qApp.exec_() -# ///////////////////////////////////////////////////////////////////////////// - - - -class th_send(Thread): - def __init__(self, send_fnc, megs, sz): - Thread.__init__(self) - self.send = send_fnc - self.nbytes = int(1e6 * megs) - self.pkt_size = int(sz) - - def run(self): - # generate and send packets - n = 0 - pktno = 0 - - while n < self.nbytes: - self.send(struct.pack('!H', pktno & 0xffff) + - (self.pkt_size - 2) * chr(pktno & 0xff)) - n += self.pkt_size - pktno += 1 - - self.send(eof=True) - - def stop(self): - self.nbytes = 0 - - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - - - -def main(): - - global n_rcvd, n_right, pktno - - n_rcvd = 0 - n_right = 0 - pktno = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right, pktno - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - if not options.gui: - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - - def send_pkt(payload='', eof=False): - return tb.txpath.send_pkt(payload, eof) - - mods = modulation_utils2.type_1_mods() - demods = modulation_utils2.type_1_demods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - channel_grp = parser.add_option_group("Channel") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='psk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-s", "--size", type="eng_float", default=1500, - help="set packet size [default=%default]") - parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, - help="set megabytes to transmit [default=%default]") - parser.add_option("","--discontinuous", action="store_true", default=False, - help="enable discontinous transmission (bursts of 5 packets)") - parser.add_option("-G", "--gui", action="store_true", default=False, - help="Turn on the GUI [default=%default]") - - channel_grp.add_option("", "--sample-rate", type="eng_float", default=1e5, - help="set speed of channel/simulation rate to RATE [default=%default]") - channel_grp.add_option("", "--snr", type="eng_float", default=30, - help="set the SNR of the channel in dB [default=%default]") - channel_grp.add_option("", "--frequency-offset", type="eng_float", default=0, - help="set frequency offset introduced by channel [default=%default]") - channel_grp.add_option("", "--timing-offset", type="eng_float", default=1.0, - help="set timing offset introduced by channel [default=%default]") - channel_grp.add_option("", "--seed", action="store_true", default=False, - help="use a random seed for AWGN noise [default=%default]") - - transmit_path.add_options(parser, expert_grp) - receive_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - for demod in demods.values(): - demod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - # Create an instance of a hierarchical block - tb = my_top_block(mods[options.modulation], - demods[options.modulation], - rx_callback, options) - - tb.start() - - packet_sender = th_send(send_pkt, options.megabytes, options.size) - packet_sender.start() - - if(options.gui): - tb.qapp.exec_() - packet_sender.stop() - else: - # Process until done; hack in to the join to stop on an interrupt - while(packet_sender.isAlive()): - try: - packet_sender.join(1) - except KeyboardInterrupt: - packet_sender.stop() - - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_qt_rx.py b/gnuradio-examples/python/digital/benchmark_qt_rx.py deleted file mode 100755 index 0cbb68d23..000000000 --- a/gnuradio-examples/python/digital/benchmark_qt_rx.py +++ /dev/null @@ -1,443 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007,2009 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, gru, modulation_utils -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from gnuradio import usrp_options - -import random -import struct -import sys - -# from current dir -from receive_path import receive_path -from pick_bitrate import pick_rx_bitrate - -try: - from gnuradio.qtgui import qtgui - from PyQt4 import QtGui, QtCore - import sip -except ImportError: - print "Please install gr-qtgui." - sys.exit(1) - -try: - from qt_rx_window import Ui_DigitalWindow -except ImportError: - print "Error: could not find qt_rx_window.py:" - print "\tYou must first build this from qt_rx_window.ui with the following command:" - print "\t\"pyuic4 qt_rx_window.ui -o qt_rx_window.py\"" - sys.exit(1) - -#import os -#print os.getpid() -#raw_input('Attach and press enter: ') - -# //////////////////////////////////////////////////////////////////// -# Define the QT Interface and Control Dialog -# //////////////////////////////////////////////////////////////////// - - -class dialog_box(QtGui.QMainWindow): - def __init__(self, snkRxIn, snkRx, fg, parent=None): - - QtGui.QWidget.__init__(self, parent) - self.gui = Ui_DigitalWindow() - self.gui.setupUi(self) - - self.fg = fg - - self.set_frequency(self.fg.frequency()) - self.set_gain(self.fg.gain()) - self.set_decim(self.fg.decim()) - self.set_gain_mu(self.fg.rx_gain_mu()) - self.set_alpha(self.fg.rx_alpha()) - - # Add the qtsnk widgets to the hlayout box - self.gui.sinkLayout.addWidget(snkRxIn) - self.gui.sinkLayout.addWidget(snkRx) - - - # Connect up some signals - self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"), - self.freqEditText) - self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"), - self.gainEditText) - self.connect(self.gui.decimEdit, QtCore.SIGNAL("editingFinished()"), - self.decimEditText) - self.connect(self.gui.gainMuEdit, QtCore.SIGNAL("editingFinished()"), - self.gainMuEditText) - self.connect(self.gui.alphaEdit, QtCore.SIGNAL("editingFinished()"), - self.alphaEditText) - - # Build a timer to update the packet number and PER fields - self.update_delay = 250 # time between updating packet rate fields - self.pkt_timer = QtCore.QTimer(self) - self.connect(self.pkt_timer, QtCore.SIGNAL("timeout()"), - self.updatePacketInfo) - self.pkt_timer.start(self.update_delay) - - - # Accessor functions for Gui to manipulate receiver parameters - def set_frequency(self, fo): - self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo)) - - def set_gain(self, gain): - self.gui.gainEdit.setText(QtCore.QString("%1").arg(gain)) - - def set_decim(self, decim): - self.gui.decimEdit.setText(QtCore.QString("%1").arg(decim)) - - def set_gain_mu(self, gain): - self.gui.gainMuEdit.setText(QtCore.QString("%1").arg(gain)) - - def set_alpha(self, alpha): - self.gui.alphaEdit.setText(QtCore.QString("%1").arg(alpha)) - - def freqEditText(self): - try: - freq = self.gui.freqEdit.text().toDouble()[0] - self.fg.set_freq(freq) - except RuntimeError: - pass - - def gainEditText(self): - try: - gain = self.gui.gainEdit.text().toDouble()[0] - self.fg.set_gain(gain) - except RuntimeError: - pass - - def decimEditText(self): - try: - decim = self.gui.decimEdit.text().toInt()[0] - self.fg.set_decim(decim) - except RuntimeError: - pass - - def alphaEditText(self): - try: - alpha = self.gui.alphaEdit.text().toDouble()[0] - self.fg.set_rx_alpha(alpha) - except RuntimeError: - pass - - def gainMuEditText(self): - try: - gain = self.gui.gainMuEdit.text().toDouble()[0] - self.fg.set_rx_gain_mu(gain) - except RuntimeError: - pass - - - # Accessor function for packet error reporting - def updatePacketInfo(self): - # Pull these globals in from the main thread - global n_rcvd, n_right, pktno - - per = float(n_rcvd - n_right)/float(pktno) - self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd)) - self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right)) - self.gui.perEdit.setText(QtCore.QString("%1").arg(per)) - - - -# //////////////////////////////////////////////////////////////////// -# Define the GNU Radio Top Block -# //////////////////////////////////////////////////////////////////// - - -class my_top_block(gr.top_block): - def __init__(self, demodulator, rx_callback, options): - gr.top_block.__init__(self) - - self._rx_freq = options.rx_freq # receiver's center frequency - self._rx_gain = options.rx_gain # receiver's gain - self._rx_subdev_spec = options.rx_subdev_spec # daughterboard to use - self._decim = options.decim # Decimating rate for the USRP (prelim) - self._bitrate = options.bitrate - self._samples_per_symbol = options.samples_per_symbol - self._demod_class = demodulator - self.gui_on = options.gui - - if self._rx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n") - raise SystemExit - - # Set up USRP source - self._setup_usrp_source(options) - - # copy the final answers back into options for use by demodulator - options.samples_per_symbol = self._samples_per_symbol - options.bitrate = self._bitrate - options.decim = self._decim - - ok = self.set_freq(self._rx_freq) - if not ok: - print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(self._rx_freq)) - raise ValueError, eng_notation.num_to_str(self._rx_freq) - - self.set_gain(options.rx_gain) - - # Set up receive path - self.rxpath = receive_path(demodulator, rx_callback, options) - - # FIXME: do better exposure to lower issues for control - self._gain_mu = self.rxpath.packet_receiver._demodulator._mm_gain_mu - self._alpha = self.rxpath.packet_receiver._demodulator._costas_alpha - - self.connect(self.u, self.rxpath) - - if self.gui_on: - self.qapp = QtGui.QApplication(sys.argv) - fftsize = 2048 - - bw_in = self.u.adc_rate() / self.decim() - self.snk_rxin = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - self._rx_freq, bw_in, - "Received", True, True, False, True, True, False) - self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - 0, self._bitrate, - "Post-Synchronizer", True, True, False, True, True, False) - - self.snk_rxin.set_frequency_axis(-60, 60) - self.snk_rx.set_frequency_axis(-60, 20) - self.snk_rxin.set_time_domain_axis(-2000,2000) - - # Connect to the QT sinks - # FIXME: make better exposure to receiver from rxpath - self.receiver = self.rxpath.packet_receiver._demodulator.receiver - self.connect(self.u, self.snk_rxin) - self.connect(self.receiver, self.snk_rx) - - pyRxInQt = self.snk_rxin.pyqwidget() - pyRxIn = sip.wrapinstance(pyRxInQt, QtGui.QWidget) - - pyRxQt = self.snk_rx.pyqwidget() - pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget) - - self.main_box = dialog_box(pyRxIn, pyRx, self) - self.main_box.show() - - def _setup_usrp_source(self, options): - self.u = usrp_options.create_usrp_source(options) - adc_rate = self.u.adc_rate() - - self.u.set_decim(self._decim) - - (self._bitrate, self._samples_per_symbol, self._decim) = \ - pick_rx_bitrate(self._bitrate, self._demod_class.bits_per_symbol(), \ - self._samples_per_symbol, self._decim, adc_rate, \ - self.u.get_decim_rates()) - - self.u.set_decim(self._decim) - self.set_auto_tr(True) # enable Auto Transmit/Receive switching - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital up converter. - """ - return self.u.set_center_freq(target_freq) - - def set_gain(self, gain): - """ - Sets the analog gain in the USRP - """ - if gain is None: - r = self.u.gain_range() - gain = (r[0] + r[1])/2 # set gain to midpoint - self._rx_gain = gain - return self.u.set_gain(self._rx_gain) - - def set_auto_tr(self, enable): - return self.u.set_auto_tr(enable) - - def set_decim(self, decim): - self._decim = decim - self.u.set_decim(self._decim) - - if(self.gui_on): - bw_in = self.u.adc_rate() / self._decim - self._bitrate = bw_in / self._samples_per_symbol - self.snk_rxin.set_frequency_range(0, -bw_in/2.0, bw_in/2.0) - self.snk_rx.set_frequency_range(0, -self._bitrate/2.0, self._bitrate/2.0) - - def frequency(self): - return self._rx_freq - - def gain(self): - return self._rx_gain - - def decim(self): - return self._decim - - def rx_gain_mu(self): - return self._gain_mu - - def rx_gain_omega(self): - return self.gain_omega - - def set_rx_gain_mu(self, gain): - self._gain_mu = gain - self.gain_omega = .25 * self._gain_mu * self._gain_mu - self.receiver.set_gain_mu(self._gain_mu) - self.receiver.set_gain_omega(self.gain_omega) - - def rx_alpha(self): - return self._alpha - - def rx_beta(self): - return self.beta - - def set_rx_alpha(self, alpha): - self._alpha = alpha - self.beta = .25 * self._alpha * self._alpha - self.receiver.set_alpha(self._alpha) - self.receiver.set_beta(self.beta) - - def add_options(normal, expert): - """ - Adds usrp-specific options to the Options Parser - """ - add_freq_option(normal) - normal.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B") - normal.add_option("", "--rx-gain", type="eng_float", default=None, metavar="GAIN", - help="set receiver gain in dB [default=midpoint]. See also --show-rx-gain-range") - normal.add_option("", "--show-rx-gain-range", action="store_true", default=False, - help="print min and max Rx gain available on selected daughterboard") - normal.add_option("-v", "--verbose", action="store_true", default=False) - normal.add_option("-G", "--gui", action="store_true", default=False, - help="Turn on the GUI [default=%default]") - - expert.add_option("", "--rx-freq", type="eng_float", default=None, - help="set Rx frequency to FREQ [default=%default]", metavar="FREQ") - expert.add_option("-d", "--decim", type="intx", default=128, - help="set fpga decimation rate to DECIM [default=%default]") - expert.add_option("", "--snr", type="eng_float", default=30, - help="set the SNR of the channel in dB [default=%default]") - - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -global n_rcvd, n_right - -def main(): - global n_rcvd, n_right, pktno - - n_rcvd = 0 - n_right = 0 - pktno = 1 - - def rx_callback(ok, payload): - global n_rcvd, n_right, pktno - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - if not options.gui: - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - - demods = modulation_utils.type_1_demods() - - # Create Options Parser: - parser = OptionParser (option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), - default='dbpsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(demods.keys()),)) - - my_top_block.add_options(parser, expert_grp) - receive_path.add_options(parser, expert_grp) - usrp_options.add_rx_options(parser) - - for mod in demods.values(): - mod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help(sys.stderr) - sys.exit(1) - - if options.rx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - - # build the graph - tb = my_top_block(demods[options.modulation], rx_callback, options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: Failed to enable realtime scheduling." - - tb.start() # start flow graph - - if(options.gui): - tb.qapp.exec_() - else: - tb.wait() # wait for it to finish - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_qt_rx2.py b/gnuradio-examples/python/digital/benchmark_qt_rx2.py deleted file mode 100755 index 0c37f4c6a..000000000 --- a/gnuradio-examples/python/digital/benchmark_qt_rx2.py +++ /dev/null @@ -1,475 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 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, gru, modulation_utils2 -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from gnuradio import usrp_options - -import random -import struct -import sys - -# from current dir -from receive_path import receive_path -from pick_bitrate2 import pick_rx_bitrate - -try: - from gnuradio.qtgui import qtgui - from PyQt4 import QtGui, QtCore - import sip -except ImportError: - print "Please install gr-qtgui." - sys.exit(1) - -try: - from qt_rx_window2 import Ui_DigitalWindow -except ImportError: - print "Error: could not find qt_rx_window2.py:" - print "\tYou must first build this from qt_rx_window2.ui with the following command:" - print "\t\"pyuic4 qt_rx_window2.ui -o qt_rx_window2.py\"" - sys.exit(1) - -#import os -#print os.getpid() -#raw_input('Attach and press enter: ') - -# //////////////////////////////////////////////////////////////////// -# Define the QT Interface and Control Dialog -# //////////////////////////////////////////////////////////////////// - - -class dialog_box(QtGui.QMainWindow): - def __init__(self, snkRxIn, snkRx, fg, parent=None): - - QtGui.QWidget.__init__(self, parent) - self.gui = Ui_DigitalWindow() - self.gui.setupUi(self) - - self.fg = fg - - self.set_frequency(self.fg.frequency()) - self.set_gain(self.fg.gain()) - self.set_decim(self.fg.decim()) - self.set_gain_clock(self.fg.rx_gain_clock()) - self.set_gain_phase(self.fg.rx_gain_phase()) - self.set_gain_freq(self.fg.rx_gain_freq()) - - # Add the qtsnk widgets to the hlayout box - self.gui.sinkLayout.addWidget(snkRxIn) - self.gui.sinkLayout.addWidget(snkRx) - - - # Connect up some signals - self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"), - self.freqEditText) - self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"), - self.gainEditText) - self.connect(self.gui.decimEdit, QtCore.SIGNAL("editingFinished()"), - self.decimEditText) - self.connect(self.gui.gainClockEdit, QtCore.SIGNAL("editingFinished()"), - self.gainClockEditText) - self.connect(self.gui.gainPhaseEdit, QtCore.SIGNAL("editingFinished()"), - self.gainPhaseEditText) - self.connect(self.gui.gainFreqEdit, QtCore.SIGNAL("editingFinished()"), - self.gainFreqEditText) - - # Build a timer to update the packet number and PER fields - self.update_delay = 250 # time between updating packet rate fields - self.pkt_timer = QtCore.QTimer(self) - self.connect(self.pkt_timer, QtCore.SIGNAL("timeout()"), - self.updatePacketInfo) - self.pkt_timer.start(self.update_delay) - - - # Accessor functions for Gui to manipulate receiver parameters - def set_frequency(self, fo): - self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo)) - - def set_gain(self, gain): - self.gui.gainEdit.setText(QtCore.QString("%1").arg(gain)) - - def set_decim(self, decim): - self.gui.decimEdit.setText(QtCore.QString("%1").arg(decim)) - - def set_gain_clock(self, gain): - self.gui.gainClockEdit.setText(QtCore.QString("%1").arg(gain)) - - def set_gain_phase(self, gain_phase): - self.gui.gainPhaseEdit.setText(QtCore.QString("%1").arg(gain_phase)) - - def set_gain_freq(self, gain_freq): - self.gui.gainFreqEdit.setText(QtCore.QString("%1").arg(gain_freq)) - - def freqEditText(self): - try: - freq = self.gui.freqEdit.text().toDouble()[0] - self.fg.set_freq(freq) - except RuntimeError: - pass - - def gainEditText(self): - try: - gain = self.gui.gainEdit.text().toDouble()[0] - self.fg.set_gain(gain) - except RuntimeError: - pass - - def decimEditText(self): - try: - decim = self.gui.decimEdit.text().toInt()[0] - self.fg.set_decim(decim) - except RuntimeError: - pass - - def gainPhaseEditText(self): - try: - gain_phase = self.gui.gainPhaseEdit.text().toDouble()[0] - self.fg.set_rx_gain_phase(gain_phase) - except RuntimeError: - pass - - def gainClockEditText(self): - try: - gain = self.gui.gainClockEdit.text().toDouble()[0] - self.fg.set_rx_gain_clock(gain) - except RuntimeError: - pass - - def gainFreqEditText(self): - try: - gain = self.gui.gainFreqEdit.text().toDouble()[0] - self.fg.set_rx_gain_freq(gain) - except RuntimeError: - pass - - - # Accessor function for packet error reporting - def updatePacketInfo(self): - # Pull these globals in from the main thread - global n_rcvd, n_right, pktno - - per = float(n_rcvd - n_right)/float(pktno) - self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd)) - self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right)) - self.gui.perEdit.setText(QtCore.QString("%1").arg(per, 0, 'e', 4)) - - - -# //////////////////////////////////////////////////////////////////// -# Define the GNU Radio Top Block -# //////////////////////////////////////////////////////////////////// - - -class my_top_block(gr.top_block): - def __init__(self, demodulator, rx_callback, options): - gr.top_block.__init__(self) - - self._rx_freq = options.rx_freq # receiver's center frequency - self._rx_gain = options.rx_gain # receiver's gain - self._rx_subdev_spec = options.rx_subdev_spec # daughterboard to use - self._decim = options.decim # Decimating rate for the USRP (prelim) - self._bitrate = options.bitrate - self._samples_per_symbol = options.samples_per_symbol - self._demod_class = demodulator - self.gui_on = options.gui - - if self._rx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n") - raise SystemExit - - # Set up USRP source - self._setup_usrp_source(options) - - # copy the final answers back into options for use by demodulator - options.samples_per_symbol = self._samples_per_symbol - options.bitrate = self._bitrate - options.decim = self._decim - - ok = self.set_freq(self._rx_freq) - if not ok: - print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(self._rx_freq)) - raise ValueError, eng_notation.num_to_str(self._rx_freq) - - self.set_gain(options.rx_gain) - - # Set up receive path - self.rxpath = receive_path(demodulator, rx_callback, options) - - # FIXME: do better exposure to lower issues for control - self._gain_clock = self.rxpath.packet_receiver._demodulator._timing_alpha - self._gain_phase = self.rxpath.packet_receiver._demodulator._phase_alpha - self._gain_freq = self.rxpath.packet_receiver._demodulator._freq_alpha - - self.connect(self.u, self.rxpath) - - if self.gui_on: - self.qapp = QtGui.QApplication(sys.argv) - fftsize = 2048 - - bw_in = self.u.adc_rate() / self.decim() - self.snk_rxin = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - self._rx_freq, bw_in, - "Received", True, True, False, True, True, False) - self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - 0, self._bitrate, - "Post-Synchronizer", True, True, False, True, True, False) - - self.snk_rxin.set_frequency_axis(-140, 20) - self.snk_rx.set_frequency_axis(-80, 20) - self.snk_rxin.set_time_domain_axis(-2000,2000) - - # Connect to the QT sinks - # FIXME: make better exposure to receiver from rxpath - self.receiver = self.rxpath.packet_receiver._demodulator.phase_recov - #self.receiver = self.rxpath.packet_receiver._demodulator.freq_recov - self.connect(self.u, self.snk_rxin) - self.connect(self.receiver, self.snk_rx) - - pyRxInQt = self.snk_rxin.pyqwidget() - pyRxIn = sip.wrapinstance(pyRxInQt, QtGui.QWidget) - - pyRxQt = self.snk_rx.pyqwidget() - pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget) - - self.snk_freq = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - 0, self._bitrate, - "FLL", True, False, False, True, False, False) - - self.main_box = dialog_box(pyRxIn, pyRx, self) - self.main_box.show() - - def _setup_usrp_source(self, options): - self.u = usrp_options.create_usrp_source(options) - adc_rate = self.u.adc_rate() - - self.u.set_decim(self._decim) - - (self._bitrate, self._samples_per_symbol, self._decim) = \ - pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \ - options.samples_per_symbol, options.decim, \ - adc_rate, self.u.get_decim_rates()) - - self.u.set_decim(self._decim) - self.set_auto_tr(True) # enable Auto Transmit/Receive switching - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital up converter. - """ - return self.u.set_center_freq(target_freq) - - def set_gain(self, gain): - """ - Sets the analog gain in the USRP - """ - if gain is None: - r = self.u.gain_range() - gain = (r[0] + r[1])/2 # set gain to midpoint - self._rx_gain = gain - ret = self.u.set_gain(self._rx_gain) - return ret - - def set_auto_tr(self, enable): - return self.u.set_auto_tr(enable) - - def set_decim(self, decim): - self._decim = decim - self.u.set_decim(self._decim) - - if(self.gui_on): - bw_in = self.u.adc_rate() / self._decim - self._bitrate = bw_in / self._samples_per_symbol - self.snk_rxin.set_frequency_range(0, bw_in) - self.snk_rx.set_frequency_range(0, self._bitrate) - - def frequency(self): - return self._rx_freq - - def gain(self): - return self._rx_gain - - def decim(self): - return self._decim - - def rx_gain_clock(self): - return self._gain_clock - - def rx_gain_clock_beta(self): - return self._gain_clock_beta - - def set_rx_gain_clock(self, gain): - self._gain_clock = gain - self._gain_clock_beta = .25 * self._gain_clock * self._gain_clock - self.rxpath.packet_receiver._demodulator.time_recov.set_alpha(self._gain_clock) - self.rxpath.packet_receiver._demodulator.time_recov.set_beta(self._gain_clock_beta) - - def rx_gain_phase(self): - return self._gain_phase - - def rx_gain_phase_beta(self): - return self._gain_phase_beta - - def set_rx_gain_phase(self, gain_phase): - self._gain_phase = gain_phase - self._gain_phase_beta = .25 * self._gain_phase * self._gain_phase - self.rxpath.packet_receiver._demodulator.phase_recov.set_alpha(self._gain_phase) - self.rxpath.packet_receiver._demodulator.phase_recov.set_beta(self._gain_phase_beta) - - - def rx_gain_freq(self): - return self._gain_freq - - def set_rx_gain_freq(self, gain_freq): - self._gain_freq = gain_freq - #self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq - self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq) - self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0) - #self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta) - - - def add_options(normal, expert): - """ - Adds usrp-specific options to the Options Parser - """ - add_freq_option(normal) - normal.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B") - normal.add_option("", "--rx-gain", type="eng_float", default=None, metavar="GAIN", - help="set receiver gain in dB [default=midpoint]. See also --show-rx-gain-range") - normal.add_option("", "--show-rx-gain-range", action="store_true", default=False, - help="print min and max Rx gain available on selected daughterboard") - normal.add_option("-v", "--verbose", action="store_true", default=False) - normal.add_option("-G", "--gui", action="store_true", default=False, - help="Turn on the GUI [default=%default]") - - expert.add_option("", "--rx-freq", type="eng_float", default=None, - help="set Rx frequency to FREQ [default=%default]", metavar="FREQ") - expert.add_option("-d", "--decim", type="intx", default=128, - help="set fpga decimation rate to DECIM [default=%default]") - expert.add_option("", "--snr", type="eng_float", default=30, - help="set the SNR of the channel in dB [default=%default]") - - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") - - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -global n_rcvd, n_right - -def main(): - global n_rcvd, n_right, pktno - - n_rcvd = 0 - n_right = 0 - pktno = 1 - - def rx_callback(ok, payload): - global n_rcvd, n_right, pktno - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - if not options.gui: - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - - demods = modulation_utils2.type_1_demods() - - # Create Options Parser: - parser = OptionParser (option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), - default='dbpsk2', - help="Select modulation from: %s [default=%%default]" - % (', '.join(demods.keys()),)) - - my_top_block.add_options(parser, expert_grp) - receive_path.add_options(parser, expert_grp) - usrp_options.add_rx_options(parser) - - for mod in demods.values(): - mod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help(sys.stderr) - sys.exit(1) - - if options.rx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - - # build the graph - tb = my_top_block(demods[options.modulation], rx_callback, options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: Failed to enable realtime scheduling." - - tb.start() # start flow graph - - if(options.gui): - tb.qapp.exec_() - else: - tb.wait() # wait for it to finish - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_rx.py b/gnuradio-examples/python/digital/benchmark_rx.py deleted file mode 100755 index ccb0c8963..000000000 --- a/gnuradio-examples/python/digital/benchmark_rx.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007,2009 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, gru, modulation_utils -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random -import struct -import sys - -# from current dir -import usrp_receive_path - -#import os -#print os.getpid() -#raw_input('Attach and press enter: ') - -class my_top_block(gr.top_block): - def __init__(self, demodulator, rx_callback, options): - gr.top_block.__init__(self) - - # Set up receive path - self.rxpath = usrp_receive_path.usrp_receive_path(demodulator, rx_callback, options) - - self.connect(self.rxpath) - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -global n_rcvd, n_right - -def main(): - global n_rcvd, n_right - - n_rcvd = 0 - n_right = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - - demods = modulation_utils.type_1_demods() - - # Create Options Parser: - parser = OptionParser (option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), - default='gmsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(demods.keys()),)) - - usrp_receive_path.add_options(parser, expert_grp) - - for mod in demods.values(): - mod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help(sys.stderr) - sys.exit(1) - - if options.rx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - - # build the graph - tb = my_top_block(demods[options.modulation], rx_callback, options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: Failed to enable realtime scheduling." - - tb.start() # start flow graph - tb.wait() # wait for it to finish - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_rx2.py b/gnuradio-examples/python/digital/benchmark_rx2.py deleted file mode 100755 index fe422be83..000000000 --- a/gnuradio-examples/python/digital/benchmark_rx2.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 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, gru, modulation_utils2 -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random -import struct -import sys - -# from current dir -import usrp_receive_path2 - -#import os -#print os.getpid() -#raw_input('Attach and press enter: ') - -class my_top_block(gr.top_block): - def __init__(self, demodulator, rx_callback, options): - gr.top_block.__init__(self) - - # Set up receive path - self.rxpath = usrp_receive_path2.usrp_receive_path(demodulator, rx_callback, options) - - self.connect(self.rxpath) - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -global n_rcvd, n_right - -def main(): - global n_rcvd, n_right - - n_rcvd = 0 - n_right = 0 - - def rx_callback(ok, payload): - global n_rcvd, n_right - (pktno,) = struct.unpack('!H', payload[0:2]) - n_rcvd += 1 - if ok: - n_right += 1 - - print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( - ok, pktno, n_rcvd, n_right) - - - demods = modulation_utils2.type_1_demods() - - # Create Options Parser: - parser = OptionParser (option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), - default='dbpsk2', - help="Select modulation from: %s [default=%%default]" - % (', '.join(demods.keys()),)) - - usrp_receive_path2.add_options(parser, expert_grp) - - for mod in demods.values(): - mod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help(sys.stderr) - sys.exit(1) - - if options.rx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - - # build the graph - tb = my_top_block(demods[options.modulation], rx_callback, options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: Failed to enable realtime scheduling." - - tb.start() # start flow graph - tb.wait() # wait for it to finish - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_tx.py b/gnuradio-examples/python/digital/benchmark_tx.py deleted file mode 100755 index 73c4a3901..000000000 --- a/gnuradio-examples/python/digital/benchmark_tx.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007,2009 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, gru, modulation_utils -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random, time, struct, sys - -# from current dir -import usrp_transmit_path - -#import os -#print os.getpid() -#raw_input('Attach and press enter') - -class my_top_block(gr.top_block): - def __init__(self, modulator, options): - gr.top_block.__init__(self) - - self.txpath = usrp_transmit_path.usrp_transmit_path(modulator, options) - - self.connect(self.txpath) - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -def main(): - - def send_pkt(payload='', eof=False): - return tb.txpath.send_pkt(payload, eof) - - def rx_callback(ok, payload): - print "ok = %r, payload = '%s'" % (ok, payload) - - mods = modulation_utils.type_1_mods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='gmsk', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-s", "--size", type="eng_float", default=1500, - help="set packet size [default=%default]") - parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, - help="set megabytes to transmit [default=%default]") - parser.add_option("","--discontinuous", action="store_true", default=False, - help="enable discontinous transmission (bursts of 5 packets)") - parser.add_option("","--from-file", default=None, - help="use file for packet contents") - - usrp_transmit_path.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - if options.tx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - if options.from_file is not None: - source_file = open(options.from_file, 'r') - - # build the graph - tb = my_top_block(mods[options.modulation], options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - tb.start() # start flow graph - - # generate and send packets - nbytes = int(1e6 * options.megabytes) - n = 0 - pktno = 0 - pkt_size = int(options.size) - - while n < nbytes: - if options.from_file is None: - data = (pkt_size - 2) * chr(pktno & 0xff) - else: - data = source_file.read(pkt_size - 2) - if data == '': - break; - - payload = struct.pack('!H', pktno & 0xffff) + data - send_pkt(payload) - n += len(payload) - sys.stderr.write('.') - if options.discontinuous and pktno % 5 == 4: - time.sleep(1) - pktno += 1 - - send_pkt(eof=True) - - tb.wait() # wait for it to finish - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/benchmark_tx2.py b/gnuradio-examples/python/digital/benchmark_tx2.py deleted file mode 100755 index 6093dba61..000000000 --- a/gnuradio-examples/python/digital/benchmark_tx2.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 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, gru, modulation_utils2 -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -import random, time, struct, sys - -# from current dir -import usrp_transmit_path2 - -#import os -#print os.getpid() -#raw_input('Attach and press enter') - -class my_top_block(gr.top_block): - def __init__(self, modulator, options): - gr.top_block.__init__(self) - - self.txpath = usrp_transmit_path2.usrp_transmit_path(modulator, options) - - self.connect(self.txpath) - -# ///////////////////////////////////////////////////////////////////////////// -# main -# ///////////////////////////////////////////////////////////////////////////// - -def main(): - - def send_pkt(payload='', eof=False): - return tb.txpath.send_pkt(payload, eof) - - def rx_callback(ok, payload): - print "ok = %r, payload = '%s'" % (ok, payload) - - mods = modulation_utils2.type_1_mods() - - parser = OptionParser(option_class=eng_option, conflict_handler="resolve") - expert_grp = parser.add_option_group("Expert") - - parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='dbpsk2', - help="Select modulation from: %s [default=%%default]" - % (', '.join(mods.keys()),)) - - parser.add_option("-s", "--size", type="eng_float", default=1500, - help="set packet size [default=%default]") - parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, - help="set megabytes to transmit [default=%default]") - parser.add_option("","--discontinuous", action="store_true", default=False, - help="enable discontinous transmission (bursts of 5 packets)") - parser.add_option("","--from-file", default=None, - help="use file for packet contents") - - usrp_transmit_path2.add_options(parser, expert_grp) - - for mod in mods.values(): - mod.add_options(expert_grp) - - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - sys.exit(1) - - if options.tx_freq is None: - sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") - parser.print_help(sys.stderr) - sys.exit(1) - - if options.from_file is not None: - source_file = open(options.from_file, 'r') - - # build the graph - tb = my_top_block(mods[options.modulation], options) - - r = gr.enable_realtime_scheduling() - if r != gr.RT_OK: - print "Warning: failed to enable realtime scheduling" - - tb.start() # start flow graph - - # generate and send packets - nbytes = int(1e6 * options.megabytes) - n = 0 - pktno = 0 - pkt_size = int(options.size) - - while n < nbytes: - if options.from_file is None: - data = (pkt_size - 2) * chr(pktno & 0xff) - else: - data = source_file.read(pkt_size - 2) - if data == '': - break; - - payload = struct.pack('!H', pktno & 0xffff) + data - send_pkt(payload) - n += len(payload) - sys.stderr.write('.') - if options.discontinuous and pktno % 5 == 4: - time.sleep(1) - pktno += 1 - - send_pkt(eof=True) - - tb.wait() # wait for it to finish - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/digital/pick_bitrate.py b/gnuradio-examples/python/digital/pick_bitrate.py deleted file mode 100644 index ce1e021c5..000000000 --- a/gnuradio-examples/python/digital/pick_bitrate.py +++ /dev/null @@ -1,153 +0,0 @@ -# -# Copyright 2005,2006 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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 eng_notation - -_default_bitrate = 500e3 - -_valid_samples_per_symbol = (2,3,4,5,6,7) - -def _gen_tx_info(converter_rate, xrates): - results = [] - for samples_per_symbol in _valid_samples_per_symbol: - for interp in xrates: - bitrate = converter_rate / interp / samples_per_symbol - results.append((bitrate, samples_per_symbol, interp)) - results.sort() - return results - -def _gen_rx_info(converter_rate, xrates): - results = [] - for samples_per_symbol in _valid_samples_per_symbol: - for decim in xrates: - bitrate = converter_rate / decim / samples_per_symbol - results.append((bitrate, samples_per_symbol, decim)) - results.sort() - return results - -def _filter_info(info, samples_per_symbol, xrate): - if samples_per_symbol is not None: - info = [x for x in info if x[1] == samples_per_symbol] - if xrate is not None: - info = [x for x in info if x[2] == xrate] - return info - -def _pick_best(target_bitrate, bits_per_symbol, info): - """ - @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate) - """ - if len(info) == 0: - raise RuntimeError, "info is zero length!" - - if target_bitrate is None: # return the fastest one - return info[-1] - - # convert bit rate to symbol rate - target_symbolrate = target_bitrate / bits_per_symbol - - # Find the closest matching symbol rate. - # In the event of a tie, the one with the lowest samples_per_symbol wins. - # (We already sorted them, so the first one is the one we take) - - best = info[0] - best_delta = abs(target_symbolrate - best[0]) - for x in info[1:]: - delta = abs(target_symbolrate - x[0]) - if delta < best_delta: - best_delta = delta - best = x - - # convert symbol rate back to bit rate - return ((best[0] * bits_per_symbol),) + best[1:] - -def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - xrate, converter_rate, xrates, gen_info): - """ - @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate) - """ - if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1: - raise ValueError, "bits_per_symbol must be an int >= 1" - - if samples_per_symbol is not None and xrate is not None: # completely determined - return (float(converter_rate) / xrate / samples_per_symbol, - samples_per_symbol, xrate) - - if bitrate is None and samples_per_symbol is None and xrate is None: - bitrate = _default_bitrate - - # now we have a target bitrate and possibly an xrate or - # samples_per_symbol constraint, but not both of them. - - ret = _pick_best(bitrate, bits_per_symbol, - _filter_info(gen_info(converter_rate, xrates), samples_per_symbol, xrate)) - print "Actual Bitrate:", eng_notation.num_to_str(ret[0]) - return ret - -# --------------------------------------------------------------------------------------- - -def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - interp_rate, converter_rate, possible_interps): - """ - Given the 4 input parameters, return at configuration that matches - - @param bitrate: desired bitrate or None - @type bitrate: number or None - @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 - @type bits_per_symbol: integer >= 1 - @param samples_per_symbol: samples/baud (aka samples/symbol) - @type samples_per_symbol: number or None - @param interp_rate: USRP interpolation factor - @type interp_rate: integer or None - @param converter_rate: converter sample rate in Hz - @type converter_rate: number - @param possible_interps: a list of possible rates - @type possible_interps: a list of integers - - @returns tuple (bitrate, samples_per_symbol, interp_rate) - """ - print "Requested TX Bitrate:", bitrate and eng_notation.num_to_str(bitrate) or 'Auto', - return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - interp_rate, converter_rate, possible_interps, _gen_tx_info) - - -def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - decim_rate, converter_rate, possible_decims): - """ - Given the 4 input parameters, return at configuration that matches - - @param bitrate: desired bitrate or None - @type bitrate: number or None - @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 - @type bits_per_symbol: integer >= 1 - @param samples_per_symbol: samples/baud (aka samples/symbol) - @type samples_per_symbol: number or None - @param decim_rate: USRP decimation factor - @type decim_rate: integer or None - @param converter_rate: converter sample rate in Hz - @type converter_rate: number - @param possible_decims: a list of possible rates - @type possible_decims: a list of integers - - @returns tuple (bitrate, samples_per_symbol, decim_rate) - """ - print "Requested RX Bitrate:", bitrate and eng_notation.num_to_str(bitrate) or 'Auto' - return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - decim_rate, converter_rate, possible_decims, _gen_rx_info) diff --git a/gnuradio-examples/python/digital/pick_bitrate2.py b/gnuradio-examples/python/digital/pick_bitrate2.py deleted file mode 100644 index 92539560c..000000000 --- a/gnuradio-examples/python/digital/pick_bitrate2.py +++ /dev/null @@ -1,154 +0,0 @@ -# -# Copyright 2010 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 eng_notation - -_default_bitrate = 500e3 -_sps_min = 2 -_sps_max = 100 - -def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - xrate, converter_rate, xrates): - """ - @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate) - """ - - if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1: - raise ValueError, "bits_per_symbol must be an int >= 1" - - converter_rate = float(converter_rate) - bits_per_symbol = float(bits_per_symbol) - - # completely determined; if bitrate is specified, this overwrites it - if (samples_per_symbol is not None) and (xrate is not None): - bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol - - # If only SPS is given - if (bitrate is None) and (samples_per_symbol is not None) and (xrate is None): - xrate = max(xrates) - bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol - - # If only xrate is given, just set SPS to 2 and calculate bitrate - if (bitrate is None) and (samples_per_symbol is None) and (xrate is not None): - samples_per_symbol = 2.0 - bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol - - # If no parameters are give, use the default bit rate - if (bitrate is None) and (samples_per_symbol is None) and (xrate is None): - bitrate = _default_bitrate - - # If only bitrate is specified, return max xrate and appropriate - # samples per symbol (minimum of 2.0) to reach bit rate - if (samples_per_symbol is None) and (xrate is None): - xrates.sort() - for i in xrange(len(xrates)): - if((converter_rate / bits_per_symbol / xrates[i]) >= 2*bitrate): - rate = xrates[i] - else: - break - - try: - xrate = rate - except UnboundLocalError: - raise ValueError("Requested bitrate out of bounds") - - samples_per_symbol = converter_rate / bits_per_symbol / rate / bitrate - bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol - - # If bitrate and xrate are specified - if(samples_per_symbol is None): - samples_per_symbol = converter_rate / xrate / bits_per_symbol / bitrate - - # If bitrate and SPS are specified - if(xrate is None): - xrate = converter_rate / samples_per_symbol / bits_per_symbol / bitrate - if((xrate in xrates) == False): - # Find the closest avaiable rate larger than the calculated one - xrates.sort() - for x in xrates: - if(x > xrate): - xrate = x - break - if(xrate > max(xrates)): - xrate = max(xrates) - - bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol - print "Could not find suitable rate for specified SPS and Bitrate" - print "Using rate = %d for bitrate of %sbps" % \ - (xrate, (eng_notation.num_to_str(bitrate))) - - if((xrate in xrates) == False): - raise ValueError(("Invalid rate (rate = %d)" % xrate)) - if((samples_per_symbol < _sps_min) or (samples_per_symbol > _sps_max)): - raise ValueError(("Invalid samples per symbol (sps = %.2f). Must be in [%.0f, %.0f]." \ - % (samples_per_symbol, _sps_min, _sps_max))) - - return (bitrate, samples_per_symbol, int(xrate)) - - -def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - interp_rate, converter_rate, possible_interps): - """ - Given the 4 input parameters, return at configuration that matches - - @param bitrate: desired bitrate or None - @type bitrate: number or None - @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 - @type bits_per_symbol: integer >= 1 - @param samples_per_symbol: samples/baud (aka samples/symbol) - @type samples_per_symbol: number or None - @param interp_rate: USRP interpolation factor - @type interp_rate: integer or None - @param converter_rate: converter sample rate in Hz - @type converter_rate: number - @param possible_interps: a list of possible rates - @type possible_interps: a list of integers - - @returns tuple (bitrate, samples_per_symbol, interp_rate) - """ - - return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - interp_rate, converter_rate, possible_interps) - - -def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - decim_rate, converter_rate, possible_decims): - """ - Given the 4 input parameters, return at configuration that matches - - @param bitrate: desired bitrate or None - @type bitrate: number or None - @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 - @type bits_per_symbol: integer >= 1 - @param samples_per_symbol: samples/baud (aka samples/symbol) - @type samples_per_symbol: number or None - @param decim_rate: USRP decimation factor - @type decim_rate: integer or None - @param converter_rate: converter sample rate in Hz - @type converter_rate: number - @param possible_decims: a list of possible rates - @type possible_decims: a list of integers - - @returns tuple (bitrate, samples_per_symbol, decim_rate) - """ - - return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, - decim_rate, converter_rate, possible_decims) diff --git a/gnuradio-examples/python/digital/qt_digital_window.py b/gnuradio-examples/python/digital/qt_digital_window.py deleted file mode 100644 index b47ed0c2b..000000000 --- a/gnuradio-examples/python/digital/qt_digital_window.py +++ /dev/null @@ -1,239 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'qt_digital_window.ui' -# -# Created: Tue May 11 20:58:35 2010 -# by: PyQt4 UI code generator 4.6.1 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -class Ui_DigitalWindow(object): - def setupUi(self, DigitalWindow): - DigitalWindow.setObjectName("DigitalWindow") - DigitalWindow.resize(1059, 754) - self.centralwidget = QtGui.QWidget(DigitalWindow) - self.centralwidget.setObjectName("centralwidget") - self.verticalLayout_4 = QtGui.QVBoxLayout(self.centralwidget) - self.verticalLayout_4.setObjectName("verticalLayout_4") - self.sinkLayout = QtGui.QHBoxLayout() - self.sinkLayout.setObjectName("sinkLayout") - self.verticalLayout_4.addLayout(self.sinkLayout) - self.horizontalLayout = QtGui.QHBoxLayout() - self.horizontalLayout.setObjectName("horizontalLayout") - self.verticalLayout_2 = QtGui.QVBoxLayout() - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.sysBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sysBox.sizePolicy().hasHeightForWidth()) - self.sysBox.setSizePolicy(sizePolicy) - self.sysBox.setMinimumSize(QtCore.QSize(240, 60)) - self.sysBox.setMaximumSize(QtCore.QSize(240, 16777215)) - self.sysBox.setObjectName("sysBox") - self.formLayoutWidget = QtGui.QWidget(self.sysBox) - self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 211, 31)) - self.formLayoutWidget.setObjectName("formLayoutWidget") - self.formLayout = QtGui.QFormLayout(self.formLayoutWidget) - self.formLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout.setVerticalSpacing(20) - self.formLayout.setObjectName("formLayout") - self.sampleRateEdit = QtGui.QLineEdit(self.formLayoutWidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sampleRateEdit.sizePolicy().hasHeightForWidth()) - self.sampleRateEdit.setSizePolicy(sizePolicy) - self.sampleRateEdit.setMinimumSize(QtCore.QSize(60, 26)) - self.sampleRateEdit.setMaximumSize(QtCore.QSize(80, 26)) - self.sampleRateEdit.setObjectName("sampleRateEdit") - self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.sampleRateEdit) - self.sampleRateLabel = QtGui.QLabel(self.formLayoutWidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sampleRateLabel.sizePolicy().hasHeightForWidth()) - self.sampleRateLabel.setSizePolicy(sizePolicy) - self.sampleRateLabel.setMinimumSize(QtCore.QSize(0, 20)) - self.sampleRateLabel.setMaximumSize(QtCore.QSize(16777215, 20)) - self.sampleRateLabel.setObjectName("sampleRateLabel") - self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.sampleRateLabel) - self.verticalLayout_2.addWidget(self.sysBox) - spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) - self.verticalLayout_2.addItem(spacerItem) - self.horizontalLayout.addLayout(self.verticalLayout_2) - self.channelModeBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.channelModeBox.sizePolicy().hasHeightForWidth()) - self.channelModeBox.setSizePolicy(sizePolicy) - self.channelModeBox.setMinimumSize(QtCore.QSize(245, 130)) - self.channelModeBox.setMaximumSize(QtCore.QSize(245, 16777215)) - self.channelModeBox.setObjectName("channelModeBox") - self.formLayoutWidget_2 = QtGui.QWidget(self.channelModeBox) - self.formLayoutWidget_2.setGeometry(QtCore.QRect(10, 20, 221, 98)) - self.formLayoutWidget_2.setObjectName("formLayoutWidget_2") - self.formLayout_2 = QtGui.QFormLayout(self.formLayoutWidget_2) - self.formLayout_2.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout_2.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_2.setObjectName("formLayout_2") - self.snrLabel = QtGui.QLabel(self.formLayoutWidget_2) - self.snrLabel.setObjectName("snrLabel") - self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.snrLabel) - self.snrEdit = QtGui.QLineEdit(self.formLayoutWidget_2) - self.snrEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.snrEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.snrEdit.setObjectName("snrEdit") - self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.snrEdit) - self.freqLabel = QtGui.QLabel(self.formLayoutWidget_2) - self.freqLabel.setObjectName("freqLabel") - self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.freqLabel) - self.freqEdit = QtGui.QLineEdit(self.formLayoutWidget_2) - self.freqEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.freqEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.freqEdit.setObjectName("freqEdit") - self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.freqEdit) - self.timeLabel = QtGui.QLabel(self.formLayoutWidget_2) - self.timeLabel.setObjectName("timeLabel") - self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.timeLabel) - self.timeEdit = QtGui.QLineEdit(self.formLayoutWidget_2) - self.timeEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.timeEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.timeEdit.setObjectName("timeEdit") - self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.timeEdit) - self.horizontalLayout.addWidget(self.channelModeBox) - self.rxBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth()) - self.rxBox.setSizePolicy(sizePolicy) - self.rxBox.setMinimumSize(QtCore.QSize(220, 130)) - self.rxBox.setMaximumSize(QtCore.QSize(180, 16777215)) - self.rxBox.setObjectName("rxBox") - self.formLayoutWidget_3 = QtGui.QWidget(self.rxBox) - self.formLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 201, 101)) - self.formLayoutWidget_3.setObjectName("formLayoutWidget_3") - self.formLayout_3 = QtGui.QFormLayout(self.formLayoutWidget_3) - self.formLayout_3.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout_3.setObjectName("formLayout_3") - self.gainMuLabel = QtGui.QLabel(self.formLayoutWidget_3) - self.gainMuLabel.setObjectName("gainMuLabel") - self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.gainMuLabel) - self.alphaLabel = QtGui.QLabel(self.formLayoutWidget_3) - self.alphaLabel.setObjectName("alphaLabel") - self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.alphaLabel) - self.gainMuEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.gainMuEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.gainMuEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.gainMuEdit.setObjectName("gainMuEdit") - self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.gainMuEdit) - self.alphaEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.alphaEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.alphaEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.alphaEdit.setObjectName("alphaEdit") - self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.alphaEdit) - self.horizontalLayout.addWidget(self.rxBox) - self.rxBox_2 = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxBox_2.sizePolicy().hasHeightForWidth()) - self.rxBox_2.setSizePolicy(sizePolicy) - self.rxBox_2.setMinimumSize(QtCore.QSize(220, 125)) - self.rxBox_2.setMaximumSize(QtCore.QSize(265, 125)) - self.rxBox_2.setObjectName("rxBox_2") - self.formLayoutWidget_4 = QtGui.QWidget(self.rxBox_2) - self.formLayoutWidget_4.setGeometry(QtCore.QRect(10, 20, 201, 91)) - self.formLayoutWidget_4.setObjectName("formLayoutWidget_4") - self.formLayout_4 = QtGui.QFormLayout(self.formLayoutWidget_4) - self.formLayout_4.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout_4.setObjectName("formLayout_4") - self.pktsRcvdLabel = QtGui.QLabel(self.formLayoutWidget_4) - self.pktsRcvdLabel.setObjectName("pktsRcvdLabel") - self.formLayout_4.setWidget(0, QtGui.QFormLayout.LabelRole, self.pktsRcvdLabel) - self.pktsCorrectLabel = QtGui.QLabel(self.formLayoutWidget_4) - self.pktsCorrectLabel.setObjectName("pktsCorrectLabel") - self.formLayout_4.setWidget(1, QtGui.QFormLayout.LabelRole, self.pktsCorrectLabel) - self.perLabel = QtGui.QLabel(self.formLayoutWidget_4) - self.perLabel.setObjectName("perLabel") - self.formLayout_4.setWidget(2, QtGui.QFormLayout.LabelRole, self.perLabel) - self.pktsRcvdEdit = QtGui.QLineEdit(self.formLayoutWidget_4) - self.pktsRcvdEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.pktsRcvdEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.pktsRcvdEdit.setObjectName("pktsRcvdEdit") - self.formLayout_4.setWidget(0, QtGui.QFormLayout.FieldRole, self.pktsRcvdEdit) - self.pktsCorrectEdit = QtGui.QLineEdit(self.formLayoutWidget_4) - self.pktsCorrectEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.pktsCorrectEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.pktsCorrectEdit.setObjectName("pktsCorrectEdit") - self.formLayout_4.setWidget(1, QtGui.QFormLayout.FieldRole, self.pktsCorrectEdit) - self.perEdit = QtGui.QLineEdit(self.formLayoutWidget_4) - self.perEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.perEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.perEdit.setObjectName("perEdit") - self.formLayout_4.setWidget(2, QtGui.QFormLayout.FieldRole, self.perEdit) - self.horizontalLayout.addWidget(self.rxBox_2) - spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem1) - self.verticalLayout = QtGui.QVBoxLayout() - self.verticalLayout.setObjectName("verticalLayout") - self.pauseButton = QtGui.QPushButton(self.centralwidget) - self.pauseButton.setMinimumSize(QtCore.QSize(80, 0)) - self.pauseButton.setMaximumSize(QtCore.QSize(80, 16777215)) - self.pauseButton.setObjectName("pauseButton") - self.verticalLayout.addWidget(self.pauseButton) - spacerItem2 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) - self.verticalLayout.addItem(spacerItem2) - self.closeButton = QtGui.QPushButton(self.centralwidget) - self.closeButton.setMinimumSize(QtCore.QSize(80, 0)) - self.closeButton.setMaximumSize(QtCore.QSize(80, 16777215)) - self.closeButton.setObjectName("closeButton") - self.verticalLayout.addWidget(self.closeButton) - self.horizontalLayout.addLayout(self.verticalLayout) - self.verticalLayout_4.addLayout(self.horizontalLayout) - DigitalWindow.setCentralWidget(self.centralwidget) - self.menubar = QtGui.QMenuBar(DigitalWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1059, 23)) - self.menubar.setObjectName("menubar") - self.menuFile = QtGui.QMenu(self.menubar) - self.menuFile.setObjectName("menuFile") - DigitalWindow.setMenuBar(self.menubar) - self.statusbar = QtGui.QStatusBar(DigitalWindow) - self.statusbar.setObjectName("statusbar") - DigitalWindow.setStatusBar(self.statusbar) - self.actionExit = QtGui.QAction(DigitalWindow) - self.actionExit.setObjectName("actionExit") - self.menuFile.addAction(self.actionExit) - self.menubar.addAction(self.menuFile.menuAction()) - - self.retranslateUi(DigitalWindow) - QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close) - QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close) - QtCore.QMetaObject.connectSlotsByName(DigitalWindow) - DigitalWindow.setTabOrder(self.snrEdit, self.freqEdit) - DigitalWindow.setTabOrder(self.freqEdit, self.timeEdit) - - def retranslateUi(self, DigitalWindow): - DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) - self.sysBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "System Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.sampleRateLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Sample Rate (sps)", None, QtGui.QApplication.UnicodeUTF8)) - self.channelModeBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Channel Model Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.snrLabel.setText(QtGui.QApplication.translate("DigitalWindow", "SNR (dB)", None, QtGui.QApplication.UnicodeUTF8)) - self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency Offset (Hz)", None, QtGui.QApplication.UnicodeUTF8)) - self.timeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Timing Offset", None, QtGui.QApplication.UnicodeUTF8)) - self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.gainMuLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Gain mu", None, QtGui.QApplication.UnicodeUTF8)) - self.alphaLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha", None, QtGui.QApplication.UnicodeUTF8)) - self.rxBox_2.setTitle(QtGui.QApplication.translate("DigitalWindow", "Received Packet Info", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsRcvdLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Rcvd.", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsCorrectLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Correct", None, QtGui.QApplication.UnicodeUTF8)) - self.perLabel.setText(QtGui.QApplication.translate("DigitalWindow", "PER", None, QtGui.QApplication.UnicodeUTF8)) - self.pauseButton.setText(QtGui.QApplication.translate("DigitalWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8)) - self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8)) - self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8)) - self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8)) - diff --git a/gnuradio-examples/python/digital/qt_digital_window.ui b/gnuradio-examples/python/digital/qt_digital_window.ui deleted file mode 100644 index 4b3857d87..000000000 --- a/gnuradio-examples/python/digital/qt_digital_window.ui +++ /dev/null @@ -1,581 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>DigitalWindow</class> - <widget class="QMainWindow" name="DigitalWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1059</width> - <height>754</height> - </rect> - </property> - <property name="windowTitle"> - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <layout class="QHBoxLayout" name="sinkLayout"/> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QGroupBox" name="sysBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>240</width> - <height>60</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>240</width> - <height>16777215</height> - </size> - </property> - <property name="title"> - <string>System Parameters</string> - </property> - <widget class="QWidget" name="formLayoutWidget"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>211</width> - <height>31</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <property name="verticalSpacing"> - <number>20</number> - </property> - <item row="0" column="1"> - <widget class="QLineEdit" name="sampleRateEdit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>60</width> - <height>26</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>26</height> - </size> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="sampleRateLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>20</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>20</height> - </size> - </property> - <property name="text"> - <string>Sample Rate (sps)</string> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>60</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="channelModeBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>245</width> - <height>130</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>245</width> - <height>16777215</height> - </size> - </property> - <property name="title"> - <string>Channel Model Parameters</string> - </property> - <widget class="QWidget" name="formLayoutWidget_2"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>221</width> - <height>98</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout_2"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="snrLabel"> - <property name="text"> - <string>SNR (dB)</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="snrEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="freqLabel"> - <property name="text"> - <string>Frequency Offset (Hz)</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="freqEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="timeLabel"> - <property name="text"> - <string>Timing Offset</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="timeEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - </layout> - </widget> - <zorder>formLayoutWidget_2</zorder> - <zorder>sysBox</zorder> - </widget> - </item> - <item> - <widget class="QGroupBox" name="rxBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>220</width> - <height>130</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>180</width> - <height>16777215</height> - </size> - </property> - <property name="title"> - <string>Receiver Parameters</string> - </property> - <widget class="QWidget" name="formLayoutWidget_3"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>201</width> - <height>101</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout_3"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="gainMuLabel"> - <property name="text"> - <string>Gain mu</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="alphaLabel"> - <property name="text"> - <string>Alpha</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="gainMuEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="alphaEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <widget class="QGroupBox" name="rxBox_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>220</width> - <height>125</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>265</width> - <height>125</height> - </size> - </property> - <property name="title"> - <string>Received Packet Info</string> - </property> - <widget class="QWidget" name="formLayoutWidget_4"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>201</width> - <height>91</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout_4"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="pktsRcvdLabel"> - <property name="text"> - <string>Packets Rcvd.</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="pktsCorrectLabel"> - <property name="text"> - <string>Packets Correct</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="perLabel"> - <property name="text"> - <string>PER</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="pktsRcvdEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="pktsCorrectEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="perEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QPushButton" name="pauseButton"> - <property name="minimumSize"> - <size> - <width>80</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Pause</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>60</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="closeButton"> - <property name="minimumSize"> - <size> - <width>80</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1059</width> - <height>23</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>&File</string> - </property> - <addaction name="actionExit"/> - </widget> - <addaction name="menuFile"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionExit"> - <property name="text"> - <string>E&xit</string> - </property> - </action> - </widget> - <tabstops> - <tabstop>snrEdit</tabstop> - <tabstop>freqEdit</tabstop> - <tabstop>timeEdit</tabstop> - </tabstops> - <resources/> - <connections> - <connection> - <sender>closeButton</sender> - <signal>clicked()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>322</x> - <y>623</y> - </hint> - <hint type="destinationlabel"> - <x>66</x> - <y>561</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionExit</sender> - <signal>triggered()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>617</x> - <y>327</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/gnuradio-examples/python/digital/qt_digital_window2.py b/gnuradio-examples/python/digital/qt_digital_window2.py deleted file mode 100644 index 2d10e3a7f..000000000 --- a/gnuradio-examples/python/digital/qt_digital_window2.py +++ /dev/null @@ -1,248 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'qt_digital_window2.ui' -# -# Created: Tue May 11 20:55:10 2010 -# by: PyQt4 UI code generator 4.6.1 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -class Ui_DigitalWindow(object): - def setupUi(self, DigitalWindow): - DigitalWindow.setObjectName("DigitalWindow") - DigitalWindow.resize(1059, 751) - self.centralwidget = QtGui.QWidget(DigitalWindow) - self.centralwidget.setObjectName("centralwidget") - self.verticalLayout_3 = QtGui.QVBoxLayout(self.centralwidget) - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.sinkLayout = QtGui.QHBoxLayout() - self.sinkLayout.setObjectName("sinkLayout") - self.verticalLayout_3.addLayout(self.sinkLayout) - self.horizontalLayout = QtGui.QHBoxLayout() - self.horizontalLayout.setObjectName("horizontalLayout") - self.verticalLayout_2 = QtGui.QVBoxLayout() - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.sysBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sysBox.sizePolicy().hasHeightForWidth()) - self.sysBox.setSizePolicy(sizePolicy) - self.sysBox.setMinimumSize(QtCore.QSize(240, 60)) - self.sysBox.setMaximumSize(QtCore.QSize(240, 16777215)) - self.sysBox.setObjectName("sysBox") - self.formLayoutWidget = QtGui.QWidget(self.sysBox) - self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 211, 31)) - self.formLayoutWidget.setObjectName("formLayoutWidget") - self.formLayout = QtGui.QFormLayout(self.formLayoutWidget) - self.formLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout.setVerticalSpacing(20) - self.formLayout.setObjectName("formLayout") - self.sampleRateEdit = QtGui.QLineEdit(self.formLayoutWidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sampleRateEdit.sizePolicy().hasHeightForWidth()) - self.sampleRateEdit.setSizePolicy(sizePolicy) - self.sampleRateEdit.setMinimumSize(QtCore.QSize(60, 26)) - self.sampleRateEdit.setMaximumSize(QtCore.QSize(80, 26)) - self.sampleRateEdit.setObjectName("sampleRateEdit") - self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.sampleRateEdit) - self.sampleRateLabel = QtGui.QLabel(self.formLayoutWidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sampleRateLabel.sizePolicy().hasHeightForWidth()) - self.sampleRateLabel.setSizePolicy(sizePolicy) - self.sampleRateLabel.setMinimumSize(QtCore.QSize(0, 20)) - self.sampleRateLabel.setMaximumSize(QtCore.QSize(16777215, 20)) - self.sampleRateLabel.setObjectName("sampleRateLabel") - self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.sampleRateLabel) - self.verticalLayout_2.addWidget(self.sysBox) - spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) - self.verticalLayout_2.addItem(spacerItem) - self.horizontalLayout.addLayout(self.verticalLayout_2) - self.channelModeBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.channelModeBox.sizePolicy().hasHeightForWidth()) - self.channelModeBox.setSizePolicy(sizePolicy) - self.channelModeBox.setMinimumSize(QtCore.QSize(245, 130)) - self.channelModeBox.setMaximumSize(QtCore.QSize(245, 16777215)) - self.channelModeBox.setObjectName("channelModeBox") - self.formLayoutWidget_2 = QtGui.QWidget(self.channelModeBox) - self.formLayoutWidget_2.setGeometry(QtCore.QRect(10, 20, 221, 98)) - self.formLayoutWidget_2.setObjectName("formLayoutWidget_2") - self.formLayout_2 = QtGui.QFormLayout(self.formLayoutWidget_2) - self.formLayout_2.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout_2.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_2.setObjectName("formLayout_2") - self.snrLabel = QtGui.QLabel(self.formLayoutWidget_2) - self.snrLabel.setObjectName("snrLabel") - self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.snrLabel) - self.snrEdit = QtGui.QLineEdit(self.formLayoutWidget_2) - self.snrEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.snrEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.snrEdit.setObjectName("snrEdit") - self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.snrEdit) - self.freqLabel = QtGui.QLabel(self.formLayoutWidget_2) - self.freqLabel.setObjectName("freqLabel") - self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.freqLabel) - self.freqEdit = QtGui.QLineEdit(self.formLayoutWidget_2) - self.freqEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.freqEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.freqEdit.setObjectName("freqEdit") - self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.freqEdit) - self.timeLabel = QtGui.QLabel(self.formLayoutWidget_2) - self.timeLabel.setObjectName("timeLabel") - self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.timeLabel) - self.timeEdit = QtGui.QLineEdit(self.formLayoutWidget_2) - self.timeEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.timeEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.timeEdit.setObjectName("timeEdit") - self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.timeEdit) - self.horizontalLayout.addWidget(self.channelModeBox) - self.rxBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth()) - self.rxBox.setSizePolicy(sizePolicy) - self.rxBox.setMinimumSize(QtCore.QSize(220, 130)) - self.rxBox.setMaximumSize(QtCore.QSize(180, 16777215)) - self.rxBox.setObjectName("rxBox") - self.formLayoutWidget_3 = QtGui.QWidget(self.rxBox) - self.formLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 201, 101)) - self.formLayoutWidget_3.setObjectName("formLayoutWidget_3") - self.formLayout_3 = QtGui.QFormLayout(self.formLayoutWidget_3) - self.formLayout_3.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout_3.setObjectName("formLayout_3") - self.gainClockLabel = QtGui.QLabel(self.formLayoutWidget_3) - self.gainClockLabel.setObjectName("gainClockLabel") - self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.gainClockLabel) - self.gainPhaseLabel = QtGui.QLabel(self.formLayoutWidget_3) - self.gainPhaseLabel.setObjectName("gainPhaseLabel") - self.formLayout_3.setWidget(2, QtGui.QFormLayout.LabelRole, self.gainPhaseLabel) - self.gainClockEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.gainClockEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.gainClockEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.gainClockEdit.setObjectName("gainClockEdit") - self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.gainClockEdit) - self.gainFreqEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.gainFreqEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.gainFreqEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.gainFreqEdit.setObjectName("gainFreqEdit") - self.formLayout_3.setWidget(2, QtGui.QFormLayout.FieldRole, self.gainFreqEdit) - self.gainPhaseEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.gainPhaseEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.gainPhaseEdit.setObjectName("gainPhaseEdit") - self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.gainPhaseEdit) - self.gainPhaseLabel_2 = QtGui.QLabel(self.formLayoutWidget_3) - self.gainPhaseLabel_2.setObjectName("gainPhaseLabel_2") - self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.gainPhaseLabel_2) - self.horizontalLayout.addWidget(self.rxBox) - self.rxBox_2 = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxBox_2.sizePolicy().hasHeightForWidth()) - self.rxBox_2.setSizePolicy(sizePolicy) - self.rxBox_2.setMinimumSize(QtCore.QSize(220, 125)) - self.rxBox_2.setMaximumSize(QtCore.QSize(265, 125)) - self.rxBox_2.setObjectName("rxBox_2") - self.formLayoutWidget_4 = QtGui.QWidget(self.rxBox_2) - self.formLayoutWidget_4.setGeometry(QtCore.QRect(10, 20, 201, 91)) - self.formLayoutWidget_4.setObjectName("formLayoutWidget_4") - self.formLayout_4 = QtGui.QFormLayout(self.formLayoutWidget_4) - self.formLayout_4.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.formLayout_4.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_4.setObjectName("formLayout_4") - self.pktsRcvdLabel = QtGui.QLabel(self.formLayoutWidget_4) - self.pktsRcvdLabel.setObjectName("pktsRcvdLabel") - self.formLayout_4.setWidget(0, QtGui.QFormLayout.LabelRole, self.pktsRcvdLabel) - self.pktsRcvdEdit = QtGui.QLineEdit(self.formLayoutWidget_4) - self.pktsRcvdEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.pktsRcvdEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.pktsRcvdEdit.setObjectName("pktsRcvdEdit") - self.formLayout_4.setWidget(0, QtGui.QFormLayout.FieldRole, self.pktsRcvdEdit) - self.pktsCorrectLabel = QtGui.QLabel(self.formLayoutWidget_4) - self.pktsCorrectLabel.setObjectName("pktsCorrectLabel") - self.formLayout_4.setWidget(1, QtGui.QFormLayout.LabelRole, self.pktsCorrectLabel) - self.pktsCorrectEdit = QtGui.QLineEdit(self.formLayoutWidget_4) - self.pktsCorrectEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.pktsCorrectEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.pktsCorrectEdit.setObjectName("pktsCorrectEdit") - self.formLayout_4.setWidget(1, QtGui.QFormLayout.FieldRole, self.pktsCorrectEdit) - self.perLabel = QtGui.QLabel(self.formLayoutWidget_4) - self.perLabel.setObjectName("perLabel") - self.formLayout_4.setWidget(2, QtGui.QFormLayout.LabelRole, self.perLabel) - self.perEdit = QtGui.QLineEdit(self.formLayoutWidget_4) - self.perEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.perEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.perEdit.setObjectName("perEdit") - self.formLayout_4.setWidget(2, QtGui.QFormLayout.FieldRole, self.perEdit) - self.horizontalLayout.addWidget(self.rxBox_2) - spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem1) - self.verticalLayout = QtGui.QVBoxLayout() - self.verticalLayout.setObjectName("verticalLayout") - self.pauseButton = QtGui.QPushButton(self.centralwidget) - self.pauseButton.setMinimumSize(QtCore.QSize(80, 0)) - self.pauseButton.setMaximumSize(QtCore.QSize(80, 16777215)) - self.pauseButton.setObjectName("pauseButton") - self.verticalLayout.addWidget(self.pauseButton) - spacerItem2 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) - self.verticalLayout.addItem(spacerItem2) - self.closeButton = QtGui.QPushButton(self.centralwidget) - self.closeButton.setMinimumSize(QtCore.QSize(80, 0)) - self.closeButton.setMaximumSize(QtCore.QSize(80, 16777215)) - self.closeButton.setObjectName("closeButton") - self.verticalLayout.addWidget(self.closeButton) - self.horizontalLayout.addLayout(self.verticalLayout) - self.verticalLayout_3.addLayout(self.horizontalLayout) - DigitalWindow.setCentralWidget(self.centralwidget) - self.menubar = QtGui.QMenuBar(DigitalWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1059, 23)) - self.menubar.setObjectName("menubar") - self.menuFile = QtGui.QMenu(self.menubar) - self.menuFile.setObjectName("menuFile") - DigitalWindow.setMenuBar(self.menubar) - self.statusbar = QtGui.QStatusBar(DigitalWindow) - self.statusbar.setObjectName("statusbar") - DigitalWindow.setStatusBar(self.statusbar) - self.actionExit = QtGui.QAction(DigitalWindow) - self.actionExit.setObjectName("actionExit") - self.menuFile.addAction(self.actionExit) - self.menubar.addAction(self.menuFile.menuAction()) - - self.retranslateUi(DigitalWindow) - QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close) - QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close) - QtCore.QMetaObject.connectSlotsByName(DigitalWindow) - DigitalWindow.setTabOrder(self.snrEdit, self.freqEdit) - DigitalWindow.setTabOrder(self.freqEdit, self.timeEdit) - - def retranslateUi(self, DigitalWindow): - DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) - self.sysBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "System Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.sampleRateLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Sample Rate (sps)", None, QtGui.QApplication.UnicodeUTF8)) - self.channelModeBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Channel Model Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.snrLabel.setText(QtGui.QApplication.translate("DigitalWindow", "SNR (dB)", None, QtGui.QApplication.UnicodeUTF8)) - self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency Offset (Hz)", None, QtGui.QApplication.UnicodeUTF8)) - self.timeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Timing Offset", None, QtGui.QApplication.UnicodeUTF8)) - self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.gainClockLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Clock Loop Gain", None, QtGui.QApplication.UnicodeUTF8)) - self.gainPhaseLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Freq. Loop Gain", None, QtGui.QApplication.UnicodeUTF8)) - self.gainPhaseLabel_2.setText(QtGui.QApplication.translate("DigitalWindow", "Phase Loop Gain", None, QtGui.QApplication.UnicodeUTF8)) - self.rxBox_2.setTitle(QtGui.QApplication.translate("DigitalWindow", "Received Packet Info", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsRcvdLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Rcvd.", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsCorrectLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Correct", None, QtGui.QApplication.UnicodeUTF8)) - self.perLabel.setText(QtGui.QApplication.translate("DigitalWindow", "PER", None, QtGui.QApplication.UnicodeUTF8)) - self.pauseButton.setText(QtGui.QApplication.translate("DigitalWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8)) - self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8)) - self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8)) - self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8)) - diff --git a/gnuradio-examples/python/digital/qt_digital_window2.ui b/gnuradio-examples/python/digital/qt_digital_window2.ui deleted file mode 100644 index 544704668..000000000 --- a/gnuradio-examples/python/digital/qt_digital_window2.ui +++ /dev/null @@ -1,605 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>DigitalWindow</class> - <widget class="QMainWindow" name="DigitalWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1059</width> - <height>751</height> - </rect> - </property> - <property name="windowTitle"> - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <layout class="QHBoxLayout" name="sinkLayout"/> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QGroupBox" name="sysBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>240</width> - <height>60</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>240</width> - <height>16777215</height> - </size> - </property> - <property name="title"> - <string>System Parameters</string> - </property> - <widget class="QWidget" name="formLayoutWidget"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>211</width> - <height>31</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <property name="verticalSpacing"> - <number>20</number> - </property> - <item row="0" column="1"> - <widget class="QLineEdit" name="sampleRateEdit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>60</width> - <height>26</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>26</height> - </size> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="sampleRateLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>20</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>20</height> - </size> - </property> - <property name="text"> - <string>Sample Rate (sps)</string> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>60</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="channelModeBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>245</width> - <height>130</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>245</width> - <height>16777215</height> - </size> - </property> - <property name="title"> - <string>Channel Model Parameters</string> - </property> - <widget class="QWidget" name="formLayoutWidget_2"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>221</width> - <height>98</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout_2"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="snrLabel"> - <property name="text"> - <string>SNR (dB)</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="snrEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="freqLabel"> - <property name="text"> - <string>Frequency Offset (Hz)</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="freqEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="timeLabel"> - <property name="text"> - <string>Timing Offset</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="timeEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <widget class="QGroupBox" name="rxBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>220</width> - <height>130</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>180</width> - <height>16777215</height> - </size> - </property> - <property name="title"> - <string>Receiver Parameters</string> - </property> - <widget class="QWidget" name="formLayoutWidget_3"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>201</width> - <height>101</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout_3"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="gainClockLabel"> - <property name="text"> - <string>Clock Loop Gain</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="gainPhaseLabel"> - <property name="text"> - <string>Freq. Loop Gain</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="gainClockEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="gainFreqEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="gainPhaseEdit"> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="gainPhaseLabel_2"> - <property name="text"> - <string>Phase Loop Gain</string> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <widget class="QGroupBox" name="rxBox_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>220</width> - <height>125</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>265</width> - <height>125</height> - </size> - </property> - <property name="title"> - <string>Received Packet Info</string> - </property> - <widget class="QWidget" name="formLayoutWidget_4"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>201</width> - <height>91</height> - </rect> - </property> - <layout class="QFormLayout" name="formLayout_4"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="pktsRcvdLabel"> - <property name="text"> - <string>Packets Rcvd.</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="pktsRcvdEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="pktsCorrectLabel"> - <property name="text"> - <string>Packets Correct</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="pktsCorrectEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="perLabel"> - <property name="text"> - <string>PER</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="perEdit"> - <property name="minimumSize"> - <size> - <width>60</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - </layout> - <zorder>pktsRcvdLabel</zorder> - <zorder>pktsCorrectLabel</zorder> - <zorder>perLabel</zorder> - <zorder>pktsRcvdEdit</zorder> - <zorder>pktsCorrectEdit</zorder> - <zorder>perEdit</zorder> - </widget> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QPushButton" name="pauseButton"> - <property name="minimumSize"> - <size> - <width>80</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Pause</string> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>60</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="closeButton"> - <property name="minimumSize"> - <size> - <width>80</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1059</width> - <height>23</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>&File</string> - </property> - <addaction name="actionExit"/> - </widget> - <addaction name="menuFile"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionExit"> - <property name="text"> - <string>E&xit</string> - </property> - </action> - </widget> - <tabstops> - <tabstop>snrEdit</tabstop> - <tabstop>freqEdit</tabstop> - <tabstop>timeEdit</tabstop> - </tabstops> - <resources/> - <connections> - <connection> - <sender>closeButton</sender> - <signal>clicked()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>322</x> - <y>623</y> - </hint> - <hint type="destinationlabel"> - <x>66</x> - <y>561</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionExit</sender> - <signal>triggered()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>617</x> - <y>327</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/gnuradio-examples/python/digital/qt_rx_window.py b/gnuradio-examples/python/digital/qt_rx_window.py deleted file mode 100644 index e2488eb3d..000000000 --- a/gnuradio-examples/python/digital/qt_rx_window.py +++ /dev/null @@ -1,157 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'qt_rx_window.ui' -# -# Created: Tue May 11 21:03:07 2010 -# by: PyQt4 UI code generator 4.6.1 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -class Ui_DigitalWindow(object): - def setupUi(self, DigitalWindow): - DigitalWindow.setObjectName("DigitalWindow") - DigitalWindow.resize(999, 519) - self.centralwidget = QtGui.QWidget(DigitalWindow) - self.centralwidget.setObjectName("centralwidget") - self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget) - self.verticalLayout.setObjectName("verticalLayout") - self.sinkLayout = QtGui.QHBoxLayout() - self.sinkLayout.setObjectName("sinkLayout") - self.verticalLayout.addLayout(self.sinkLayout) - self.horizontalLayout = QtGui.QHBoxLayout() - self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.horizontalLayout.setObjectName("horizontalLayout") - self.rxBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth()) - self.rxBox.setSizePolicy(sizePolicy) - self.rxBox.setMinimumSize(QtCore.QSize(250, 190)) - self.rxBox.setMaximumSize(QtCore.QSize(250, 190)) - self.rxBox.setObjectName("rxBox") - self.gainMuEdit = QtGui.QLineEdit(self.rxBox) - self.gainMuEdit.setGeometry(QtCore.QRect(120, 120, 113, 23)) - self.gainMuEdit.setObjectName("gainMuEdit") - self.gainMuLabel = QtGui.QLabel(self.rxBox) - self.gainMuLabel.setGeometry(QtCore.QRect(10, 120, 111, 20)) - self.gainMuLabel.setObjectName("gainMuLabel") - self.alphaEdit = QtGui.QLineEdit(self.rxBox) - self.alphaEdit.setGeometry(QtCore.QRect(120, 150, 113, 23)) - self.alphaEdit.setObjectName("alphaEdit") - self.alphaLabel = QtGui.QLabel(self.rxBox) - self.alphaLabel.setGeometry(QtCore.QRect(10, 150, 111, 20)) - self.alphaLabel.setObjectName("alphaLabel") - self.gainLabel = QtGui.QLabel(self.rxBox) - self.gainLabel.setGeometry(QtCore.QRect(10, 60, 101, 17)) - self.gainLabel.setObjectName("gainLabel") - self.freqEdit = QtGui.QLineEdit(self.rxBox) - self.freqEdit.setGeometry(QtCore.QRect(120, 30, 113, 23)) - self.freqEdit.setObjectName("freqEdit") - self.freqLabel = QtGui.QLabel(self.rxBox) - self.freqLabel.setGeometry(QtCore.QRect(10, 30, 141, 17)) - self.freqLabel.setObjectName("freqLabel") - self.gainEdit = QtGui.QLineEdit(self.rxBox) - self.gainEdit.setGeometry(QtCore.QRect(120, 60, 113, 23)) - self.gainEdit.setObjectName("gainEdit") - self.decimLabel = QtGui.QLabel(self.rxBox) - self.decimLabel.setGeometry(QtCore.QRect(10, 90, 101, 17)) - self.decimLabel.setObjectName("decimLabel") - self.decimEdit = QtGui.QLineEdit(self.rxBox) - self.decimEdit.setGeometry(QtCore.QRect(120, 90, 113, 23)) - self.decimEdit.setObjectName("decimEdit") - self.horizontalLayout.addWidget(self.rxBox) - self.verticalLayout_3 = QtGui.QVBoxLayout() - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.rxPacketBox = QtGui.QGroupBox(self.centralwidget) - self.rxPacketBox.setEnabled(True) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxPacketBox.sizePolicy().hasHeightForWidth()) - self.rxPacketBox.setSizePolicy(sizePolicy) - self.rxPacketBox.setMinimumSize(QtCore.QSize(250, 130)) - self.rxPacketBox.setMaximumSize(QtCore.QSize(250, 130)) - font = QtGui.QFont() - font.setWeight(50) - font.setBold(False) - self.rxPacketBox.setFont(font) - self.rxPacketBox.setObjectName("rxPacketBox") - self.pktsRcvdEdit = QtGui.QLineEdit(self.rxPacketBox) - self.pktsRcvdEdit.setGeometry(QtCore.QRect(120, 30, 113, 23)) - self.pktsRcvdEdit.setObjectName("pktsRcvdEdit") - self.pktsRcvdLabel = QtGui.QLabel(self.rxPacketBox) - self.pktsRcvdLabel.setGeometry(QtCore.QRect(10, 30, 111, 20)) - self.pktsRcvdLabel.setObjectName("pktsRcvdLabel") - self.pktsCorrectEdit = QtGui.QLineEdit(self.rxPacketBox) - self.pktsCorrectEdit.setGeometry(QtCore.QRect(120, 60, 113, 23)) - self.pktsCorrectEdit.setObjectName("pktsCorrectEdit") - self.pktsCorrectLabel = QtGui.QLabel(self.rxPacketBox) - self.pktsCorrectLabel.setGeometry(QtCore.QRect(10, 60, 111, 20)) - self.pktsCorrectLabel.setObjectName("pktsCorrectLabel") - self.perLabel = QtGui.QLabel(self.rxPacketBox) - self.perLabel.setGeometry(QtCore.QRect(10, 90, 111, 20)) - self.perLabel.setObjectName("perLabel") - self.perEdit = QtGui.QLineEdit(self.rxPacketBox) - self.perEdit.setGeometry(QtCore.QRect(120, 90, 113, 23)) - self.perEdit.setObjectName("perEdit") - self.verticalLayout_3.addWidget(self.rxPacketBox) - spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) - self.verticalLayout_3.addItem(spacerItem) - self.horizontalLayout.addLayout(self.verticalLayout_3) - spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem1) - self.verticalLayout_5 = QtGui.QVBoxLayout() - self.verticalLayout_5.setObjectName("verticalLayout_5") - spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_5.addItem(spacerItem2) - self.closeButton = QtGui.QPushButton(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.closeButton.sizePolicy().hasHeightForWidth()) - self.closeButton.setSizePolicy(sizePolicy) - self.closeButton.setMinimumSize(QtCore.QSize(80, 30)) - self.closeButton.setMaximumSize(QtCore.QSize(80, 30)) - self.closeButton.setObjectName("closeButton") - self.verticalLayout_5.addWidget(self.closeButton) - self.horizontalLayout.addLayout(self.verticalLayout_5) - self.verticalLayout.addLayout(self.horizontalLayout) - DigitalWindow.setCentralWidget(self.centralwidget) - self.menubar = QtGui.QMenuBar(DigitalWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 999, 23)) - self.menubar.setObjectName("menubar") - self.menuFile = QtGui.QMenu(self.menubar) - self.menuFile.setObjectName("menuFile") - DigitalWindow.setMenuBar(self.menubar) - self.statusbar = QtGui.QStatusBar(DigitalWindow) - self.statusbar.setObjectName("statusbar") - DigitalWindow.setStatusBar(self.statusbar) - self.actionExit = QtGui.QAction(DigitalWindow) - self.actionExit.setObjectName("actionExit") - self.menuFile.addAction(self.actionExit) - self.menubar.addAction(self.menuFile.menuAction()) - - self.retranslateUi(DigitalWindow) - QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close) - QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close) - QtCore.QMetaObject.connectSlotsByName(DigitalWindow) - - def retranslateUi(self, DigitalWindow): - DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) - self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.gainMuLabel.setText(QtGui.QApplication.translate("DigitalWindow", "mu\'s gain", None, QtGui.QApplication.UnicodeUTF8)) - self.alphaLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha", None, QtGui.QApplication.UnicodeUTF8)) - self.gainLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Gain (dB)", None, QtGui.QApplication.UnicodeUTF8)) - self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency (Hz)", None, QtGui.QApplication.UnicodeUTF8)) - self.decimLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Decimation", None, QtGui.QApplication.UnicodeUTF8)) - self.rxPacketBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Received Packet Info", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsRcvdLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Rcvd.", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsCorrectLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Correct", None, QtGui.QApplication.UnicodeUTF8)) - self.perLabel.setText(QtGui.QApplication.translate("DigitalWindow", "PER", None, QtGui.QApplication.UnicodeUTF8)) - self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8)) - self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8)) - self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8)) - diff --git a/gnuradio-examples/python/digital/qt_rx_window.ui b/gnuradio-examples/python/digital/qt_rx_window.ui deleted file mode 100644 index f5a074876..000000000 --- a/gnuradio-examples/python/digital/qt_rx_window.ui +++ /dev/null @@ -1,407 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>DigitalWindow</class> - <widget class="QMainWindow" name="DigitalWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>999</width> - <height>519</height> - </rect> - </property> - <property name="windowTitle"> - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="sinkLayout"/> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <item> - <widget class="QGroupBox" name="rxBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>250</width> - <height>190</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>250</width> - <height>190</height> - </size> - </property> - <property name="title"> - <string>Receiver Parameters</string> - </property> - <widget class="QLineEdit" name="gainMuEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>120</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="gainMuLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>120</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>mu's gain</string> - </property> - </widget> - <widget class="QLineEdit" name="alphaEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>150</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="alphaLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>150</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>Alpha</string> - </property> - </widget> - <widget class="QLabel" name="gainLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>60</y> - <width>101</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>Gain (dB)</string> - </property> - </widget> - <widget class="QLineEdit" name="freqEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>30</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="freqLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>30</y> - <width>141</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>Frequency (Hz)</string> - </property> - </widget> - <widget class="QLineEdit" name="gainEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>60</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="decimLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>90</y> - <width>101</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>Decimation</string> - </property> - </widget> - <widget class="QLineEdit" name="decimEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>90</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - </widget> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QGroupBox" name="rxPacketBox"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>250</width> - <height>130</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>250</width> - <height>130</height> - </size> - </property> - <property name="font"> - <font> - <weight>50</weight> - <bold>false</bold> - </font> - </property> - <property name="title"> - <string>Received Packet Info</string> - </property> - <widget class="QLineEdit" name="pktsRcvdEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>30</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="pktsRcvdLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>30</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>Packets Rcvd.</string> - </property> - </widget> - <widget class="QLineEdit" name="pktsCorrectEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>60</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="pktsCorrectLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>60</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>Packets Correct</string> - </property> - </widget> - <widget class="QLabel" name="perLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>90</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>PER</string> - </property> - </widget> - <widget class="QLineEdit" name="perEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>90</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - </widget> - </item> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>60</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="closeButton"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>80</width> - <height>30</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>30</height> - </size> - </property> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>999</width> - <height>23</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>&File</string> - </property> - <addaction name="actionExit"/> - </widget> - <addaction name="menuFile"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionExit"> - <property name="text"> - <string>E&xit</string> - </property> - </action> - </widget> - <resources/> - <connections> - <connection> - <sender>actionExit</sender> - <signal>triggered()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>617</x> - <y>327</y> - </hint> - </hints> - </connection> - <connection> - <sender>closeButton</sender> - <signal>clicked()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>960</x> - <y>694</y> - </hint> - <hint type="destinationlabel"> - <x>66</x> - <y>561</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/gnuradio-examples/python/digital/qt_rx_window2.py b/gnuradio-examples/python/digital/qt_rx_window2.py deleted file mode 100644 index 2fd719ce1..000000000 --- a/gnuradio-examples/python/digital/qt_rx_window2.py +++ /dev/null @@ -1,166 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'qt_rx_window2.ui' -# -# Created: Tue May 11 21:01:39 2010 -# by: PyQt4 UI code generator 4.6.1 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -class Ui_DigitalWindow(object): - def setupUi(self, DigitalWindow): - DigitalWindow.setObjectName("DigitalWindow") - DigitalWindow.resize(1000, 523) - self.centralwidget = QtGui.QWidget(DigitalWindow) - self.centralwidget.setObjectName("centralwidget") - self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget) - self.verticalLayout.setObjectName("verticalLayout") - self.sinkLayout = QtGui.QHBoxLayout() - self.sinkLayout.setObjectName("sinkLayout") - self.verticalLayout.addLayout(self.sinkLayout) - self.horizontalLayout = QtGui.QHBoxLayout() - self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize) - self.horizontalLayout.setObjectName("horizontalLayout") - self.rxBox = QtGui.QGroupBox(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth()) - self.rxBox.setSizePolicy(sizePolicy) - self.rxBox.setMinimumSize(QtCore.QSize(250, 190)) - self.rxBox.setMaximumSize(QtCore.QSize(250, 250)) - self.rxBox.setObjectName("rxBox") - self.formLayout = QtGui.QFormLayout(self.rxBox) - self.formLayout.setObjectName("formLayout") - self.freqLabel = QtGui.QLabel(self.rxBox) - self.freqLabel.setObjectName("freqLabel") - self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.freqLabel) - self.freqEdit = QtGui.QLineEdit(self.rxBox) - self.freqEdit.setObjectName("freqEdit") - self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.freqEdit) - self.gainLabel = QtGui.QLabel(self.rxBox) - self.gainLabel.setObjectName("gainLabel") - self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.gainLabel) - self.gainEdit = QtGui.QLineEdit(self.rxBox) - self.gainEdit.setObjectName("gainEdit") - self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.gainEdit) - self.decimLabel = QtGui.QLabel(self.rxBox) - self.decimLabel.setObjectName("decimLabel") - self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.decimLabel) - self.decimEdit = QtGui.QLineEdit(self.rxBox) - self.decimEdit.setObjectName("decimEdit") - self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.decimEdit) - self.gainClockLabel = QtGui.QLabel(self.rxBox) - self.gainClockLabel.setObjectName("gainClockLabel") - self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.gainClockLabel) - self.gainClockEdit = QtGui.QLineEdit(self.rxBox) - self.gainClockEdit.setObjectName("gainClockEdit") - self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.gainClockEdit) - self.gainPhaseLabel = QtGui.QLabel(self.rxBox) - self.gainPhaseLabel.setObjectName("gainPhaseLabel") - self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.gainPhaseLabel) - self.gainPhaseEdit = QtGui.QLineEdit(self.rxBox) - self.gainPhaseEdit.setObjectName("gainPhaseEdit") - self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.gainPhaseEdit) - self.gainFreqEdit = QtGui.QLineEdit(self.rxBox) - self.gainFreqEdit.setObjectName("gainFreqEdit") - self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.gainFreqEdit) - self.gainFreqLabel = QtGui.QLabel(self.rxBox) - self.gainFreqLabel.setObjectName("gainFreqLabel") - self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.gainFreqLabel) - self.horizontalLayout.addWidget(self.rxBox) - self.verticalLayout_3 = QtGui.QVBoxLayout() - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.rxPacketBox = QtGui.QGroupBox(self.centralwidget) - self.rxPacketBox.setEnabled(True) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rxPacketBox.sizePolicy().hasHeightForWidth()) - self.rxPacketBox.setSizePolicy(sizePolicy) - self.rxPacketBox.setMinimumSize(QtCore.QSize(250, 130)) - self.rxPacketBox.setMaximumSize(QtCore.QSize(250, 130)) - font = QtGui.QFont() - font.setWeight(50) - font.setBold(False) - self.rxPacketBox.setFont(font) - self.rxPacketBox.setObjectName("rxPacketBox") - self.pktsRcvdEdit = QtGui.QLineEdit(self.rxPacketBox) - self.pktsRcvdEdit.setGeometry(QtCore.QRect(120, 30, 113, 23)) - self.pktsRcvdEdit.setObjectName("pktsRcvdEdit") - self.pktsRcvdLabel = QtGui.QLabel(self.rxPacketBox) - self.pktsRcvdLabel.setGeometry(QtCore.QRect(10, 30, 111, 20)) - self.pktsRcvdLabel.setObjectName("pktsRcvdLabel") - self.pktsCorrectEdit = QtGui.QLineEdit(self.rxPacketBox) - self.pktsCorrectEdit.setGeometry(QtCore.QRect(120, 60, 113, 23)) - self.pktsCorrectEdit.setObjectName("pktsCorrectEdit") - self.pktsCorrectLabel = QtGui.QLabel(self.rxPacketBox) - self.pktsCorrectLabel.setGeometry(QtCore.QRect(10, 60, 111, 20)) - self.pktsCorrectLabel.setObjectName("pktsCorrectLabel") - self.perLabel = QtGui.QLabel(self.rxPacketBox) - self.perLabel.setGeometry(QtCore.QRect(10, 90, 111, 20)) - self.perLabel.setObjectName("perLabel") - self.perEdit = QtGui.QLineEdit(self.rxPacketBox) - self.perEdit.setGeometry(QtCore.QRect(120, 90, 113, 23)) - self.perEdit.setObjectName("perEdit") - self.verticalLayout_3.addWidget(self.rxPacketBox) - spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) - self.verticalLayout_3.addItem(spacerItem) - self.horizontalLayout.addLayout(self.verticalLayout_3) - spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem1) - self.verticalLayout_5 = QtGui.QVBoxLayout() - self.verticalLayout_5.setObjectName("verticalLayout_5") - spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_5.addItem(spacerItem2) - self.closeButton = QtGui.QPushButton(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.closeButton.sizePolicy().hasHeightForWidth()) - self.closeButton.setSizePolicy(sizePolicy) - self.closeButton.setMinimumSize(QtCore.QSize(80, 30)) - self.closeButton.setMaximumSize(QtCore.QSize(80, 30)) - self.closeButton.setObjectName("closeButton") - self.verticalLayout_5.addWidget(self.closeButton) - self.horizontalLayout.addLayout(self.verticalLayout_5) - self.verticalLayout.addLayout(self.horizontalLayout) - DigitalWindow.setCentralWidget(self.centralwidget) - self.menubar = QtGui.QMenuBar(DigitalWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 23)) - self.menubar.setObjectName("menubar") - self.menuFile = QtGui.QMenu(self.menubar) - self.menuFile.setObjectName("menuFile") - DigitalWindow.setMenuBar(self.menubar) - self.statusbar = QtGui.QStatusBar(DigitalWindow) - self.statusbar.setObjectName("statusbar") - DigitalWindow.setStatusBar(self.statusbar) - self.actionExit = QtGui.QAction(DigitalWindow) - self.actionExit.setObjectName("actionExit") - self.menuFile.addAction(self.actionExit) - self.menubar.addAction(self.menuFile.menuAction()) - - self.retranslateUi(DigitalWindow) - QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close) - QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close) - QtCore.QMetaObject.connectSlotsByName(DigitalWindow) - - def retranslateUi(self, DigitalWindow): - DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) - self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency (Hz)", None, QtGui.QApplication.UnicodeUTF8)) - self.gainLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Gain (dB)", None, QtGui.QApplication.UnicodeUTF8)) - self.decimLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Decimation", None, QtGui.QApplication.UnicodeUTF8)) - self.gainClockLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Clock Loop Gain", None, QtGui.QApplication.UnicodeUTF8)) - self.gainPhaseLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Phase Loop Gain", None, QtGui.QApplication.UnicodeUTF8)) - self.gainFreqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Freq. Loop Gain", None, QtGui.QApplication.UnicodeUTF8)) - self.rxPacketBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Received Packet Info", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsRcvdLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Rcvd.", None, QtGui.QApplication.UnicodeUTF8)) - self.pktsCorrectLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Correct", None, QtGui.QApplication.UnicodeUTF8)) - self.perLabel.setText(QtGui.QApplication.translate("DigitalWindow", "PER", None, QtGui.QApplication.UnicodeUTF8)) - self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8)) - self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8)) - self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8)) - diff --git a/gnuradio-examples/python/digital/qt_rx_window2.ui b/gnuradio-examples/python/digital/qt_rx_window2.ui deleted file mode 100644 index 745af8fb8..000000000 --- a/gnuradio-examples/python/digital/qt_rx_window2.ui +++ /dev/null @@ -1,354 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>DigitalWindow</class> - <widget class="QMainWindow" name="DigitalWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1000</width> - <height>523</height> - </rect> - </property> - <property name="windowTitle"> - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="sinkLayout"/> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="sizeConstraint"> - <enum>QLayout::SetFixedSize</enum> - </property> - <item> - <widget class="QGroupBox" name="rxBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>250</width> - <height>190</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>250</width> - <height>250</height> - </size> - </property> - <property name="title"> - <string>Receiver Parameters</string> - </property> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="freqLabel"> - <property name="text"> - <string>Frequency (Hz)</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="freqEdit"/> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="gainLabel"> - <property name="text"> - <string>Gain (dB)</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="gainEdit"/> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="decimLabel"> - <property name="text"> - <string>Decimation</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="decimEdit"/> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="gainClockLabel"> - <property name="text"> - <string>Clock Loop Gain</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLineEdit" name="gainClockEdit"/> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="gainPhaseLabel"> - <property name="text"> - <string>Phase Loop Gain</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QLineEdit" name="gainPhaseEdit"/> - </item> - <item row="5" column="1"> - <widget class="QLineEdit" name="gainFreqEdit"/> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="gainFreqLabel"> - <property name="text"> - <string>Freq. Loop Gain</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QGroupBox" name="rxPacketBox"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>250</width> - <height>130</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>250</width> - <height>130</height> - </size> - </property> - <property name="font"> - <font> - <weight>50</weight> - <bold>false</bold> - </font> - </property> - <property name="title"> - <string>Received Packet Info</string> - </property> - <widget class="QLineEdit" name="pktsRcvdEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>30</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="pktsRcvdLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>30</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>Packets Rcvd.</string> - </property> - </widget> - <widget class="QLineEdit" name="pktsCorrectEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>60</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="pktsCorrectLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>60</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>Packets Correct</string> - </property> - </widget> - <widget class="QLabel" name="perLabel"> - <property name="geometry"> - <rect> - <x>10</x> - <y>90</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>PER</string> - </property> - </widget> - <widget class="QLineEdit" name="perEdit"> - <property name="geometry"> - <rect> - <x>120</x> - <y>90</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - </widget> - </item> - <item> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>60</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="closeButton"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>80</width> - <height>30</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>30</height> - </size> - </property> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QMenuBar" name="menubar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>1000</width> - <height>23</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>&File</string> - </property> - <addaction name="actionExit"/> - </widget> - <addaction name="menuFile"/> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <action name="actionExit"> - <property name="text"> - <string>E&xit</string> - </property> - </action> - </widget> - <resources/> - <connections> - <connection> - <sender>actionExit</sender> - <signal>triggered()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>617</x> - <y>327</y> - </hint> - </hints> - </connection> - <connection> - <sender>closeButton</sender> - <signal>clicked()</signal> - <receiver>DigitalWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>960</x> - <y>694</y> - </hint> - <hint type="destinationlabel"> - <x>66</x> - <y>561</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/gnuradio-examples/python/digital/receive_path.py b/gnuradio-examples/python/digital/receive_path.py deleted file mode 100644 index 0024d6941..000000000 --- a/gnuradio-examples/python/digital/receive_path.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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, gru, blks2 -from gnuradio import eng_notation -import copy -import sys - -# ///////////////////////////////////////////////////////////////////////////// -# receive path -# ///////////////////////////////////////////////////////////////////////////// - -class receive_path(gr.hier_block2): - def __init__(self, demod_class, rx_callback, options): - gr.hier_block2.__init__(self, "receive_path", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(0, 0, 0)) # Output signature - - - options = copy.copy(options) # make a copy so we can destructively modify - - self._verbose = options.verbose - self._bitrate = options.bitrate # desired bit rate - self._samples_per_symbol = options.samples_per_symbol # desired samples/symbol - - self._rx_callback = rx_callback # this callback is fired when there's a packet available - self._demod_class = demod_class # the demodulator_class we're using - - # Get demod_kwargs - demod_kwargs = self._demod_class.extract_kwargs_from_options(options) - - # Design filter to get actual channel we want - sw_decim = 1 - chan_coeffs = gr.firdes.low_pass (1.0, # gain - sw_decim * self._samples_per_symbol, # sampling rate - 1.0, # midpoint of trans. band - 0.5, # width of trans. band - gr.firdes.WIN_HANN) # filter type - self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs) - - # receiver - self.packet_receiver = \ - blks2.demod_pkts(self._demod_class(**demod_kwargs), - access_code=None, - callback=self._rx_callback, - threshold=-1) - - # Carrier Sensing Blocks - alpha = 0.001 - thresh = 30 # in dB, will have to adjust - self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha) - - # Display some information about the setup - if self._verbose: - self._print_verbage() - - # connect block input to channel filter - self.connect(self, self.channel_filter) - - # connect the channel input filter to the carrier power detector - self.connect(self.channel_filter, self.probe) - - # connect channel filter to the packet receiver - self.connect(self.channel_filter, self.packet_receiver) - - def bitrate(self): - return self._bitrate - - def samples_per_symbol(self): - return self._samples_per_symbol - - def carrier_sensed(self): - """ - Return True if we think carrier is present. - """ - #return self.probe.level() > X - return self.probe.unmuted() - - def carrier_threshold(self): - """ - Return current setting in dB. - """ - return self.probe.threshold() - - def set_carrier_threshold(self, threshold_in_db): - """ - Set carrier threshold. - - @param threshold_in_db: set detection threshold - @type threshold_in_db: float (dB) - """ - self.probe.set_threshold(threshold_in_db) - - - def add_options(normal, expert): - """ - Adds receiver-specific options to the Options Parser - """ - if not normal.has_option("--bitrate"): - normal.add_option("-r", "--bitrate", type="eng_float", default=100e3, - help="specify bitrate [default=%default].") - normal.add_option("-v", "--verbose", action="store_true", default=False) - expert.add_option("-S", "--samples-per-symbol", type="float", default=None, - help="set samples/symbol [default=%default]") - expert.add_option("", "--log", action="store_true", default=False, - help="Log all parts of flow graph to files (CAUTION: lots of data)") - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - - def _print_verbage(self): - """ - Prints information about the receive path - """ - print "\nReceive Path:" - print "modulation: %s" % (self._demod_class.__name__) - print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %.4f" % (self._samples_per_symbol) diff --git a/gnuradio-examples/python/digital/simple.py b/gnuradio-examples/python/digital/simple.py deleted file mode 100644 index 6d340db36..000000000 --- a/gnuradio-examples/python/digital/simple.py +++ /dev/null @@ -1,64 +0,0 @@ - -from gnuradio import gr, blks2, packet_utils - -# Some constants -TX_AMPLITUDE = 0.25 -SAMPLE_RATE = 1e5 -# NOISE_VOLTAGE = 0.01 -NOISE_VOLTAGE = 0.01 -# FREQUENCY_OFFSET = 0 -FREQUENCY_OFFSET = 0.01 -TIMING_OFFSET = 1.0 -SAMPLES_PER_SYMBOL = 2 -GAIN = 1.0 -SW_DECIM = 1 -BAND_MIDPOINT = 1.0 -BAND_WIDTH = 0.5 - -# Modulation/Demodulation methods -modulator = blks2.dbpsk2_mod() -demodulator = blks2.dbpsk2_demod() - -#Transmission Blocks -packet_transmitter = blks2.mod_pkts(modulator, access_code=None, msgq_limit=4, - pad_for_usrp=True) -amp = gr.multiply_const_cc(TX_AMPLITUDE) -throttle = gr.throttle(gr.sizeof_gr_complex, SAMPLE_RATE) -# Channel -channel = gr.channel_model(NOISE_VOLTAGE, FREQUENCY_OFFSET, TIMING_OFFSET) -# Receiver Blocks -chan_coeffs = gr.firdes.low_pass(GAIN, SW_DECIM * SAMPLES_PER_SYMBOL, - BAND_MIDPOINT, BAND_WIDTH, gr.firdes.WIN_HANN) -channel_filter = gr.fft_filter_ccc(SW_DECIM, chan_coeffs) -packet_receiver = blks2.demod_pkts(demodulator, access_code=None, callback=None, - threshold=-1) -# Put it all together and start it up (although nothing will be done -# until we send some packets). -tb = gr.top_block() -tb.connect(packet_transmitter, amp, throttle, channel, channel_filter, - packet_receiver) -tb.start() - -# The queue into which recieved packets are placed -pkq = packet_receiver._rcvd_pktq - -# The function to create a packet and place it in a queue to be sent. -sender = packet_transmitter.send_pkt - -# Some some packets (The second will not be recieved because it gets cut off -# before it can finish. I think this occurs during modulation.) -sender('hello there I wonder how long this needs to be before I start to see any errors.') -sender('world') -sender(eof=True) - -# Wait for all the packets to get sent and received. -tb.wait() - -# Check how many messages have been received and print them. -cnt = pkq.count() -print('There are %s messages' % cnt) -for a in range(0, cnt): - msg = pkq.delete_head() - ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1())) - print("Message %s is %s" % (a, payload)) - diff --git a/gnuradio-examples/python/digital/simple_qam.py b/gnuradio-examples/python/digital/simple_qam.py deleted file mode 100644 index 947d7faad..000000000 --- a/gnuradio-examples/python/digital/simple_qam.py +++ /dev/null @@ -1,76 +0,0 @@ - -from gnuradio import gr, blks2, packet_utils - -# Some constants -NOISE_VOLTAGE = 0.1 -FREQUENCY_OFFSET = 0.0000 -TIMING_OFFSET = 1.0 -SAMPLES_PER_SYMBOL = 2 -GAIN = 1.0 -SW_DECIM = 1 -BAND_MIDPOINT = 1.0 -BAND_WIDTH = 0.5 -FREQ_ALPHA = 0.005 -EXCESS_BW = 0.35 - -# Modulation/Demodulation methods -modulator = blks2.qam_mod(16, SAMPLES_PER_SYMBOL) -demodulator = blks2.qam_demod(16, SAMPLES_PER_SYMBOL, freq_alpha=FREQ_ALPHA) - -#Transmission Blocks -packet_transmitter = blks2.mod_pkts(modulator, access_code=None, msgq_limit=4, - pad_for_usrp=True) -# Channel -channel = gr.channel_model(NOISE_VOLTAGE, FREQUENCY_OFFSET, TIMING_OFFSET) -# Receiver Blocks -chan_coeffs = gr.firdes.low_pass(GAIN, SW_DECIM * SAMPLES_PER_SYMBOL, - BAND_MIDPOINT, BAND_WIDTH, gr.firdes.WIN_HANN) -channel_filter = gr.fft_filter_ccc(SW_DECIM, chan_coeffs) -packet_receiver = blks2.demod_pkts(demodulator, access_code=None, callback=None, - threshold=-1) -# Put it all together and start it up (although nothing will be done -# until we send some packets). -tb = gr.top_block() -tb.connect(packet_transmitter, channel, channel_filter, - packet_receiver) -tb.start() - -# The queue into which recieved packets are placed -pkq = packet_receiver._rcvd_pktq - -# The function to create a packet and place it in a queue to be sent. -sender = packet_transmitter.send_pkt - -# Some some packets (The second will not be recieved because it gets cut off -# before it can finish. I think this occurs during modulation.) - -# Send some large messages to start off with to let things lock. -for i in range(0, int(20.0/SAMPLES_PER_SYMBOL)): - sender('a'*4000) - -sender('hello1') -sender('hello2') -sender('hello3') -sender('hello4') -sender('hello5') -sender('hello6') -sender('hello7') -sender('hello8') -sender('hello9') -sender('hello10') -sender('hello11') -sender('hello12') -sender('world') -sender(eof=True) - -# Wait for all the packets to get sent and received. -tb.wait() - -# Check how many messages have been received and print them. -cnt = pkq.count() -print('There are %s messages' % cnt) -for a in range(0, cnt): - msg = pkq.delete_head() - ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1())) - print("Message %s is %s" % (a, payload)) - diff --git a/gnuradio-examples/python/digital/transmit_path.py b/gnuradio-examples/python/digital/transmit_path.py deleted file mode 100644 index 86ebf75c3..000000000 --- a/gnuradio-examples/python/digital/transmit_path.py +++ /dev/null @@ -1,118 +0,0 @@ -# -# Copyright 2005, 2006, 2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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, gru, blks2 -from gnuradio import eng_notation - -import copy -import sys - -# ///////////////////////////////////////////////////////////////////////////// -# transmit path -# ///////////////////////////////////////////////////////////////////////////// - -class transmit_path(gr.hier_block2): - def __init__(self, modulator_class, options): - ''' - See below for what options should hold - ''' - gr.hier_block2.__init__(self, "transmit_path", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - options = copy.copy(options) # make a copy so we can destructively modify - - self._verbose = options.verbose - self._tx_amplitude = options.tx_amplitude # digital amplitude sent to USRP - self._bitrate = options.bitrate # desired bit rate - self._samples_per_symbol = options.samples_per_symbol # desired samples/baud - - self._modulator_class = modulator_class # the modulator_class we are using - - # Get mod_kwargs - mod_kwargs = self._modulator_class.extract_kwargs_from_options(options) - - # transmitter - modulator = self._modulator_class(**mod_kwargs) - self.packet_transmitter = \ - blks2.mod_pkts(modulator, - access_code=None, - msgq_limit=4, - pad_for_usrp=True) - - self.amp = gr.multiply_const_cc(1) - self.set_tx_amplitude(self._tx_amplitude) - - # Display some information about the setup - if self._verbose: - self._print_verbage() - - # Connect components in the flowgraph - self.connect(self.packet_transmitter, self.amp, self) - - def set_tx_amplitude(self, ampl): - """ - Sets the transmit amplitude sent to the USRP in volts - @param: ampl 0 <= ampl < 1. - """ - self._tx_amplitude = max(0.0, min(ampl, 1)) - self.amp.set_k(self._tx_amplitude) - - def send_pkt(self, payload='', eof=False): - """ - Calls the transmitter method to send a packet - """ - return self.packet_transmitter.send_pkt(payload, eof) - - def bitrate(self): - return self._bitrate - - def samples_per_symbol(self): - return self._samples_per_symbol - - def add_options(normal, expert): - """ - Adds transmitter-specific options to the Options Parser - """ - if not normal.has_option('--bitrate'): - normal.add_option("-r", "--bitrate", type="eng_float", default=100e3, - help="specify bitrate [default=%default].") - normal.add_option("", "--tx-amplitude", type="eng_float", default=0.250, metavar="AMPL", - help="set transmitter digital amplitude: 0 <= AMPL < 1 [default=%default]") - normal.add_option("-v", "--verbose", action="store_true", default=False) - - expert.add_option("-S", "--samples-per-symbol", type="float", default=None, - help="set samples/symbol [default=%default]") - expert.add_option("", "--log", action="store_true", default=False, - help="Log all parts of flow graph to file (CAUTION: lots of data)") - - # Make a static method to call before instantiation - add_options = staticmethod(add_options) - - def _print_verbage(self): - """ - Prints information about the transmit path - """ - print "Tx amplitude %s" % (self._tx_amplitude) - print "modulation: %s" % (self._modulator_class.__name__) - print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %.4f" % (self._samples_per_symbol) - diff --git a/gnuradio-examples/python/digital/usrp_receive_path.py b/gnuradio-examples/python/digital/usrp_receive_path.py deleted file mode 100644 index a8f16e28a..000000000 --- a/gnuradio-examples/python/digital/usrp_receive_path.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright 2009 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 -from gnuradio import usrp_options -import receive_path -from pick_bitrate import pick_rx_bitrate -from gnuradio import eng_notation - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") - -def add_options(parser, expert): - add_freq_option(parser) - usrp_options.add_rx_options(parser) - receive_path.receive_path.add_options(parser, expert) - expert.add_option("", "--rx-freq", type="eng_float", default=None, - help="set Rx frequency to FREQ [default=%default]", metavar="FREQ") - parser.add_option("-v", "--verbose", action="store_true", default=False) - -class usrp_receive_path(gr.hier_block2): - - def __init__(self, demod_class, rx_callback, options): - ''' - See below for what options should hold - ''' - gr.hier_block2.__init__(self, "usrp_receive_path", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(0, 0, 0)) # Output signature - if options.rx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n") - raise SystemExit - - #setup usrp - self._demod_class = demod_class - self._setup_usrp_source(options) - - rx_path = receive_path.receive_path(demod_class, rx_callback, options) - for attr in dir(rx_path): #forward the methods - if not attr.startswith('_') and not hasattr(self, attr): - setattr(self, attr, getattr(rx_path, attr)) - - #connect - self.connect(self.u, rx_path) - - def _setup_usrp_source(self, options): - self.u = usrp_options.create_usrp_source(options) - adc_rate = self.u.adc_rate() - self.rs_rate = options.bitrate - - (self._bitrate, self._samples_per_symbol, self._decim) = \ - pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \ - options.samples_per_symbol, options.decim, - adc_rate, self.u.get_decim_rates()) - - if options.verbose: - print 'USRP Source:', self.u - print 'Decimation: ', self._decim - - options.samples_per_symbol = self._samples_per_symbol - options.decim = self._decim - - self.u.set_decim(self._decim) - - if not self.u.set_center_freq(options.rx_freq): - print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.rx_freq)) - raise ValueError, eng_notation.num_to_str(options.rx_freq) diff --git a/gnuradio-examples/python/digital/usrp_receive_path2.py b/gnuradio-examples/python/digital/usrp_receive_path2.py deleted file mode 100644 index d20017204..000000000 --- a/gnuradio-examples/python/digital/usrp_receive_path2.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright 2010 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 -from gnuradio import usrp_options -import receive_path -from pick_bitrate2 import pick_rx_bitrate -from gnuradio import eng_notation - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") - -def add_options(parser, expert): - add_freq_option(parser) - usrp_options.add_rx_options(parser) - receive_path.receive_path.add_options(parser, expert) - expert.add_option("", "--rx-freq", type="eng_float", default=None, - help="set Rx frequency to FREQ [default=%default]", metavar="FREQ") - parser.add_option("-v", "--verbose", action="store_true", default=False) - -class usrp_receive_path(gr.hier_block2): - - def __init__(self, demod_class, rx_callback, options): - ''' - See below for what options should hold - ''' - gr.hier_block2.__init__(self, "usrp_receive_path", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(0, 0, 0)) # Output signature - if options.rx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n") - raise SystemExit - - #setup usrp - self._demod_class = demod_class - self._setup_usrp_source(options) - - rx_path = receive_path.receive_path(demod_class, rx_callback, options) - for attr in dir(rx_path): #forward the methods - if not attr.startswith('_') and not hasattr(self, attr): - setattr(self, attr, getattr(rx_path, attr)) - - #connect - self.connect(self.u, rx_path) - - def _setup_usrp_source(self, options): - self.u = usrp_options.create_usrp_source(options) - adc_rate = self.u.adc_rate() - self.rs_rate = options.bitrate - - (self._bitrate, self._samples_per_symbol, self._decim) = \ - pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \ - options.samples_per_symbol, options.decim, - adc_rate, self.u.get_decim_rates()) - - if options.verbose: - print 'USRP Source:', self.u - print 'Decimation: ', self._decim - - options.samples_per_symbol = self._samples_per_symbol - options.decim = self._decim - - self.u.set_decim(self._decim) - - if not self.u.set_center_freq(options.rx_freq): - print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.rx_freq)) - raise ValueError, eng_notation.num_to_str(options.rx_freq) diff --git a/gnuradio-examples/python/digital/usrp_transmit_path.py b/gnuradio-examples/python/digital/usrp_transmit_path.py deleted file mode 100644 index f0f467599..000000000 --- a/gnuradio-examples/python/digital/usrp_transmit_path.py +++ /dev/null @@ -1,101 +0,0 @@ -# -# Copyright 2009 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 -from gnuradio import usrp_options -import transmit_path -from pick_bitrate import pick_tx_bitrate -from gnuradio import eng_notation - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") - -def add_options(parser, expert): - add_freq_option(parser) - usrp_options.add_tx_options(parser) - transmit_path.transmit_path.add_options(parser, expert) - expert.add_option("", "--tx-freq", type="eng_float", default=None, - help="set transmit frequency to FREQ [default=%default]", metavar="FREQ") - parser.add_option("-v", "--verbose", action="store_true", default=False) - -class usrp_transmit_path(gr.hier_block2): - def __init__(self, modulator_class, options): - ''' - See below for what options should hold - ''' - gr.hier_block2.__init__(self, "usrp_transmit_path", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(0, 0, 0)) # Output signature - if options.tx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n") - raise SystemExit - - #setup usrp - self._modulator_class = modulator_class - self._setup_usrp_sink(options) - - tx_path = transmit_path.transmit_path(modulator_class, options) - for attr in dir(tx_path): #forward the methods - if not attr.startswith('_') and not hasattr(self, attr): - setattr(self, attr, getattr(tx_path, attr)) - - #connect - self.connect(tx_path, self.u) - - def _setup_usrp_sink(self, options): - """ - Creates a USRP sink, determines the settings for best bitrate, - and attaches to the transmitter's subdevice. - """ - self.u = usrp_options.create_usrp_sink(options) - dac_rate = self.u.dac_rate() - self.rs_rate = options.bitrate # Store requested bit rate - - (self._bitrate, self._samples_per_symbol, self._interp) = \ - pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), - options.samples_per_symbol, options.interp, - dac_rate, self.u.get_interp_rates()) - - options.interp = self._interp - options.samples_per_symbol = self._samples_per_symbol - options.bitrate = self._bitrate - - if options.verbose: - print 'USRP Sink:', self.u - print "Interpolation Rate: ", self._interp - - self.u.set_interp(self._interp) - self.u.set_auto_tr(True) - - if not self.u.set_center_freq(options.tx_freq): - print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.tx_freq)) - raise ValueError, eng_notation.num_to_str(options.tx_freq) diff --git a/gnuradio-examples/python/digital/usrp_transmit_path2.py b/gnuradio-examples/python/digital/usrp_transmit_path2.py deleted file mode 100644 index 54930e5a0..000000000 --- a/gnuradio-examples/python/digital/usrp_transmit_path2.py +++ /dev/null @@ -1,101 +0,0 @@ -# -# Copyright 2010 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 -from gnuradio import usrp_options -import transmit_path -from pick_bitrate2 import pick_tx_bitrate -from gnuradio import eng_notation - -def add_freq_option(parser): - """ - Hackery that has the -f / --freq option set both tx_freq and rx_freq - """ - def freq_callback(option, opt_str, value, parser): - parser.values.rx_freq = value - parser.values.tx_freq = value - - if not parser.has_option('--freq'): - parser.add_option('-f', '--freq', type="eng_float", - action="callback", callback=freq_callback, - help="set Tx and/or Rx frequency to FREQ [default=%default]", - metavar="FREQ") - -def add_options(parser, expert): - add_freq_option(parser) - usrp_options.add_tx_options(parser) - transmit_path.transmit_path.add_options(parser, expert) - expert.add_option("", "--tx-freq", type="eng_float", default=None, - help="set transmit frequency to FREQ [default=%default]", metavar="FREQ") - parser.add_option("-v", "--verbose", action="store_true", default=False) - -class usrp_transmit_path(gr.hier_block2): - def __init__(self, modulator_class, options): - ''' - See below for what options should hold - ''' - gr.hier_block2.__init__(self, "usrp_transmit_path", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(0, 0, 0)) # Output signature - if options.tx_freq is None: - sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n") - raise SystemExit - - #setup usrp - self._modulator_class = modulator_class - self._setup_usrp_sink(options) - - tx_path = transmit_path.transmit_path(modulator_class, options) - for attr in dir(tx_path): #forward the methods - if not attr.startswith('_') and not hasattr(self, attr): - setattr(self, attr, getattr(tx_path, attr)) - - #connect - self.connect(tx_path, self.u) - - def _setup_usrp_sink(self, options): - """ - Creates a USRP sink, determines the settings for best bitrate, - and attaches to the transmitter's subdevice. - """ - self.u = usrp_options.create_usrp_sink(options) - dac_rate = self.u.dac_rate() - self.rs_rate = options.bitrate # Store requested bit rate - - (self._bitrate, self._samples_per_symbol, self._interp) = \ - pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), - options.samples_per_symbol, options.interp, - dac_rate, self.u.get_interp_rates()) - - options.interp = self._interp - options.samples_per_symbol = self._samples_per_symbol - options.bitrate = self._bitrate - - if options.verbose: - print 'USRP Sink:', self.u - print "Interpolation Rate: ", self._interp - - self.u.set_interp(self._interp) - self.u.set_auto_tr(True) - - if not self.u.set_center_freq(options.tx_freq): - print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.tx_freq)) - raise ValueError, eng_notation.num_to_str(options.tx_freq) diff --git a/gnuradio-examples/python/multi-antenna/.gitignore b/gnuradio-examples/python/multi-antenna/.gitignore deleted file mode 100644 index ff40c06f3..000000000 --- a/gnuradio-examples/python/multi-antenna/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/*.pyc -/*.pyo -/*.dat diff --git a/gnuradio-examples/python/multi-antenna/multi_fft.py b/gnuradio-examples/python/multi-antenna/multi_fft.py deleted file mode 100755 index 544445860..000000000 --- a/gnuradio-examples/python/multi-antenna/multi_fft.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru, eng_notation -from gnuradio import usrp -from gnuradio.eng_option import eng_option -from gnuradio import eng_notation -from gnuradio import optfir -from optparse import OptionParser -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider -import wx -from usrpm import usrp_dbid -import time -import os.path -import sys - -# required FPGA that can do 4 rx channels. - - -class my_graph(stdgui2.std_top_block): - - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser (option_class=eng_option) - #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), - # help="select USRP Rx side A or B (default=A)") - parser.add_option("-d", "--decim", type="int", default=128, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, - help="set frequency to FREQ [default=%default])", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=20, - help="set gain in dB [default=%default]") - parser.add_option("-F", "--filter", action="store_true", default=True, - help="Enable channel filter") - (options, args) = parser.parse_args() - - if len(args) != 0: - parser.print_help() - raise SystemExit - - nchan = 4 - - if options.filter: - sw_decim = 4 - else: - sw_decim = 1 - - self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf") - if self.u.nddcs() < nchan: - sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( - nchan, self.u.nddcs())) - raise SystemExit - - if not self.u.set_nchannels(nchan): - sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,)) - raise SystemExit - - input_rate = self.u.adc_freq() / self.u.decim_rate() - print "USB data rate = %s" % (eng_notation.num_to_str(input_rate),) - print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),) - - self.subdev = self.u.db(0) + self.u.db(1) - - if (len (self.subdev) < 4 or - self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or - self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX): - sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') - sys.exit(1) - - self.u.set_mux(gru.hexint(0xf3f2f1f0)) - - # deinterleave four channels from FPGA - di = gr.deinterleave(gr.sizeof_gr_complex) - - self.connect(self.u, di) - - - - # taps for channel filter - chan_filt_coeffs = optfir.low_pass (1, # gain - input_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - - for i in range(nchan): - scope = fftsink2.fft_sink_c(panel, sample_rate=input_rate/sw_decim, - title="Input %d" % (i,), - ref_level=80, y_per_div=20) - vbox.Add(scope.win, 10, wx.EXPAND) - - if options.filter: - chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) - self.connect((di, i), chan_filt, scope) - else: - self.connect((di, i), scope) - - - self.set_gain(options.gain) - self.set_freq(options.freq) - - def set_gain(self, gain): - for i in range(len(self.subdev)): - self.subdev[i].set_gain(gain) - - def set_freq(self, target_freq): - ok = True - for i in range(len(self.subdev)): - r = usrp.tune(self.u, i, self.subdev[i], target_freq) - if not r: - ok = False - print "set_freq: failed to set subdev[%d] freq to %f" % ( - i, target_freq) - - return ok - - -def main (): - app = stdgui2.stdapp(my_graph, "Multi Scope", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/usrp/.gitignore b/gnuradio-examples/python/usrp/.gitignore deleted file mode 100644 index c400497f5..000000000 --- a/gnuradio-examples/python/usrp/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/*.pyc -/*.pyo diff --git a/gnuradio-examples/python/usrp/Makefile.am b/gnuradio-examples/python/usrp/Makefile.am deleted file mode 100644 index 0ede005a0..000000000 --- a/gnuradio-examples/python/usrp/Makefile.am +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright 2004,2005,2009 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -include $(top_srcdir)/Makefile.common - -ourdatadir = $(exampledir)/usrp - -dist_ourdata_SCRIPTS = \ - fm_tx_2_daughterboards.py \ - fm_tx4.py \ - max_power.py \ - test_dft_analysis.py \ - test_dft_synth.py \ - usrp_benchmark_usb.py \ - usrp_nbfm_ptt.py \ - usrp_nbfm_rcv.py \ - usrp_spectrum_sense.py \ - usrp_test_loop_lfsr.py \ - usrp_tv_rcv_nogui.py \ - usrp_tv_rcv.py \ - usrp_wfm_rcv.py \ - usrp_wfm_rcv_nogui.py \ - usrp_wfm_rcv_fmdet.py \ - usrp_wfm_rcv_pll.py \ - usrp_wfm_rcv_sca.py \ - usrp_wfm_rcv2_nogui.py \ - usrp_wxapt_rcv.py \ - usrp_am_mw_rcv.py diff --git a/gnuradio-examples/python/usrp/max_power.py b/gnuradio-examples/python/usrp/max_power.py deleted file mode 100755 index 91005e530..000000000 --- a/gnuradio-examples/python/usrp/max_power.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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. -# - -""" -Setup USRP for maximum power consumption. -""" - - -from gnuradio import gr -from gnuradio import usrp -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -def ramp_source (): - period = 2**16 - src = gr.vector_source_s (range (-period/2, period/2, 1), True) - return src - -def build_block (tx_enable, rx_enable): - max_usb_rate = 8e6 # 8 MS/sec - dac_freq = 128e6 - adc_freq = 64e6 - - tx_nchan = 2 - tx_mux = 0x0000ba98 - tx_interp = int (dac_freq / (max_usb_rate/2 * tx_nchan)) # 16 - - rx_nchan = 2 - rx_mux = 0x00003210 - rx_decim = int ((adc_freq * rx_nchan) / (max_usb_rate/2)) # 32 - - tb = gr.top_block () - - if tx_enable: - tx_src0 = gr.sig_source_c (dac_freq/tx_interp, gr.GR_CONST_WAVE, 0, 16e3, 0) - usrp_tx = usrp.sink_c (0, tx_interp, tx_nchan, tx_mux) - usrp_tx.set_tx_freq (0, 10e6) - usrp_tx.set_tx_freq (1, 9e6) - tb.connect (tx_src0, usrp_tx) - - if rx_enable: - usrp_rx = usrp.source_c (0, rx_decim, rx_nchan, rx_mux) - usrp_rx.set_rx_freq (0, 5.5e6) - usrp_rx.set_rx_freq (1, 6.5e6) - rx_dst0 = gr.null_sink (gr.sizeof_gr_complex) - tb.connect (usrp_rx, rx_dst0) - - return tb - -def main (): - parser = OptionParser (option_class=eng_option) - parser.add_option ("-t", action="store_true", dest="tx_enable", - default=False, help="enable Tx path") - parser.add_option ("-r", action="store_true", dest="rx_enable", - default=False, help="enable Rx path") - (options, args) = parser.parse_args () - tb = build_block (options.tx_enable, options.rx_enable) - - tb.start () - raw_input ('Press Enter to quit: ') - tb.stop () - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/usrp/test_dft_analysis.py b/gnuradio-examples/python/usrp/test_dft_analysis.py deleted file mode 100755 index 49db6bf2a..000000000 --- a/gnuradio-examples/python/usrp/test_dft_analysis.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru, blks2 -from gnuradio.wxgui import stdgui2, fftsink2, slider -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import wx - -class test_graph (stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - parser = OptionParser (option_class=eng_option) - (options, args) = parser.parse_args () - - sample_rate = 16e3 - mpoints = 4 - ampl = 1000 - freq = 0 - - lo_freq = 1e6 - lo_ampl = 1 - - vbox.Add(slider.slider(panel, - -sample_rate/2, sample_rate/2, - self.set_lo_freq), 0, wx.ALIGN_CENTER) - - - src = gr.sig_source_c(sample_rate, gr.GR_CONST_WAVE, - freq, ampl, 0) - - self.lo = gr.sig_source_c(sample_rate, gr.GR_SIN_WAVE, - lo_freq, lo_ampl, 0) - - mixer = gr.multiply_cc() - self.connect(src, (mixer, 0)) - self.connect(self.lo, (mixer, 1)) - - # We add these throttle blocks so that this demo doesn't - # suck down all the CPU available. Normally you wouldn't use these. - thr = gr.throttle(gr.sizeof_gr_complex, sample_rate) - - taps = gr.firdes.low_pass(1, # gain - 1, # rate - 1.0/mpoints * 0.4, # cutoff - 1.0/mpoints * 0.1, # trans width - gr.firdes.WIN_HANN) - print len(taps) - analysis = blks2.analysis_filterbank(mpoints, taps) - - self.connect(mixer, thr) - self.connect(thr, analysis) - - for i in range(mpoints): - fft = fftsink2.fft_sink_c(frame, fft_size=128, - sample_rate=sample_rate/mpoints, - fft_rate=5, - title="Ch %d" % (i,)) - self.connect((analysis, i), fft) - vbox.Add(fft.win, 1, wx.EXPAND) - - def set_lo_freq(self, freq): - self.lo.set_frequency(freq) - - - -def main (): - app = stdgui2.stdapp (test_graph, "Test DFT filterbank") - app.MainLoop () - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/usrp/test_dft_synth.py b/gnuradio-examples/python/usrp/test_dft_synth.py deleted file mode 100755 index 99b1c4923..000000000 --- a/gnuradio-examples/python/usrp/test_dft_synth.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gru, blks2 -from gnuradio.wxgui import stdgui2, fftsink2 -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import wx -import random - - -def make_random_complex_tuple(L, gain=1): - result = [] - for x in range(L): - result.append(gain * complex(random.gauss(0, 1),random.gauss(0, 1))) - - return tuple(result) - -def random_noise_c(gain=1): - src = gr.vector_source_c(make_random_complex_tuple(32*1024, gain), True) - return src - - -class test_graph (stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - parser = OptionParser (option_class=eng_option) - (options, args) = parser.parse_args () - - sample_rate = 16e6 - mpoints = 16 - ampl = 1000 - - enable = mpoints/2 * [1, 0] - enable[0] = 1 - - taps = gr.firdes.low_pass(1, # gain - 1, # rate - 1.0/mpoints * 0.4, # cutoff - 1.0/mpoints * 0.1, # trans width - gr.firdes.WIN_HANN) - - synth = blks2.synthesis_filterbank(mpoints, taps) - - null_source = gr.null_source(gr.sizeof_gr_complex) - - if 1: - for i in range(mpoints): - s = gr.sig_source_c(sample_rate/mpoints, gr.GR_SIN_WAVE, - 300e3, ampl * enable[i], 0) - self.connect(s, (synth, i)) - - else: - for i in range(mpoints): - if i == 1: - #s = gr.sig_source_c(sample_rate/mpoints, gr.GR_SIN_WAVE, - # 300e3, ampl * enable[i], 0) - s = random_noise_c(ampl) - self.connect(s, (synth, i)) - else: - self.connect(null_source, (synth, i)) - - - # We add these throttle blocks so that this demo doesn't - # suck down all the CPU available. Normally you wouldn't use these. - thr = gr.throttle(gr.sizeof_gr_complex, sample_rate) - fft = fftsink2.fft_sink_c(frame, fft_size=1024,sample_rate=sample_rate) - vbox.Add(fft.win, 1, wx.EXPAND) - - self.connect(synth, thr, fft) - - -def main (): - app = stdgui2.stdapp (test_graph, "Test DFT filterbank") - app.MainLoop () - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/usrp/usrp_benchmark_usb.py b/gnuradio-examples/python/usrp/usrp_benchmark_usb.py deleted file mode 100755 index 4ea84f764..000000000 --- a/gnuradio-examples/python/usrp/usrp_benchmark_usb.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005 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. -# - -""" -Benchmark the USB/USRP throughput. Finds the maximum full-duplex speed -the USRP/USB combination can sustain without errors. - -This program does not currently give reliable results. Sorry about that... -""" - -from gnuradio import gr -from gnuradio import usrp -from gnuradio import eng_notation - -import sys - -def run_test (usb_throughput, verbose): - # usb_throughput is in bytes/sec. - # - # Returns True or False - - nsec = 1 - stream_length = int (usb_throughput/2 * nsec) # length of stream to examine - - adc_freq = 64e6 - dac_freq = 128e6 - sizeof_sample = 2 * gr.sizeof_short - - usb_throughput_in_samples = usb_throughput / sizeof_sample - - # allocate usb throughput 50/50 between Tx and Rx - - tx_interp = int (dac_freq) / int (usb_throughput_in_samples / 2) - rx_decim = int (adc_freq) / int (usb_throughput_in_samples / 2) - - # print "tx_interp =", tx_interp, "rx_decim =", rx_decim - assert (tx_interp == 2 * rx_decim) - - tb = gr.top_block () - - # Build the Tx pipeline - data_src = gr.lfsr_32k_source_s () - src_head = gr.head (gr.sizeof_short, int (stream_length * 2)) - usrp_tx = usrp.sink_s (0, tx_interp) - tb.connect (data_src, src_head, usrp_tx) - - # and the Rx pipeline - usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) - head = gr.head (gr.sizeof_short, stream_length) - check = gr.check_lfsr_32k_s () - tb.connect (usrp_rx, head, check) - - tb.run () - - ntotal = check.ntotal () - nright = check.nright () - runlength = check.runlength () - - if verbose: - print "usb_throughput =", eng_notation.num_to_str (usb_throughput) - print "ntotal =", ntotal - print "nright =", nright - print "runlength =", runlength - print "delta =", ntotal - runlength - - return runlength >= stream_length - 80000 - -def main (): - verbose = True - best_rate = 0 - usb_rate = [ 2e6, 4e6, 8e6, 16e6, 32e6 ] - #usb_rate = [ 32e6, 32e6, 32e6, 32e6, 32e6 ] - # usb_rate.reverse () - for rate in usb_rate: - sys.stdout.write ("Testing %sB/sec... " % (eng_notation.num_to_str (rate))) - sys.stdout.flush () - ok = run_test (rate, verbose) - if ok: - best_rate = max (best_rate, rate) - sys.stdout.write ("OK\n") - else: - sys.stdout.write ("FAILED\n") - - print "Max USB/USRP throughput = %sB/sec" % (eng_notation.num_to_str (best_rate),) - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/usrp/usrp_test_loop_lfsr.py b/gnuradio-examples/python/usrp/usrp_test_loop_lfsr.py deleted file mode 100755 index 696c1a24c..000000000 --- a/gnuradio-examples/python/usrp/usrp_test_loop_lfsr.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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. -# - -""" -Digital loopback (Tx to Rx) for the USRP Rev1. -""" - -from gnuradio import gr -from gnuradio import usrp - - -def build_graph (): - tx_interp = 32 # tx should be twice rx - rx_decim = 16 - - tb = gr.top_block () - - data_src = gr.lfsr_32k_source_s () - - # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98) - usrp_tx = usrp.sink_s (0, tx_interp) - - tb.connect (data_src, usrp_tx) - - usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) - - sink = gr.check_lfsr_32k_s () - tb.connect (usrp_rx, sink) - - # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat") - # tb.connect (usrp_rx, file_sink) - - return tb - -def main (): - tb = build_graph () - try: - tb.run() - except KeyboardInterrupt: - pass - -if __name__ == '__main__': - main () diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py deleted file mode 100755 index edfbc3657..000000000 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks2 -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from usrpm import usrp_dbid -import sys -import math - -def calc_dxc_freq(target_freq, baseband_freq, fs): - dxc_temp = (target_freq - baseband_freq) % fs - - if dxc_temp < fs/2.0: - dxc_freq = - dxc_temp - inverted = False - else: - dxc_freq = fs - dxc_temp - inverted = True - - return (dxc_freq, inverted) - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) - - -class wfm_rx_block (gr.top_block): - - def __init__(self): - gr.top_block.__init__(self) - - parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") - parser.add_option("", "--f1", type="eng_float", default=100.7e6, - help="set 1st station frequency to FREQ", metavar="FREQ") - parser.add_option("", "--f2", type="eng_float", default=102.5e6, - help="set 2nd station freq to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=40, - help="set gain in dB (default is midpoint)") - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - if abs(options.f1) < 1e6: - options.f1 *= 1e6 - - if abs(options.f2) < 1e6: - options.f2 *= 1e6 - - if abs(options.f1 - options.f2) > 5.5e6: - print "Sorry, two stations must be within 5.5MHz of each other" - raise SystemExit - - f = (options.f1, options.f2) - - self.vol = .1 - self.state = "FREQ" - - # build graph - - self.u = usrp.source_c(0, nchan=2) # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 200 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 320 kS/s - chanfilt_decim = 1 - demod_rate = usrp_rate / chanfilt_decim - audio_decimation = 10 - audio_rate = demod_rate / audio_decimation # 32 kHz - - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - mv = usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec) - mv |= (mv << 8) & 0xff00 # both DDC inputs setup same way - self.u.set_mux(mv) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) - - - # deinterleave two channels from FPGA - di = gr.deinterleave(gr.sizeof_gr_complex) - - # wire up the head of the chain - self.connect(self.u, di) - - # sound card as final sink - audio_sink = audio.sink(int(audio_rate), options.audio_output) - - # taps for channel filter - chan_filt_coeffs = optfir.low_pass (1, # gain - usrp_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - - mid_freq = (f[0] + f[1]) / 2 - # set front end PLL to middle frequency - tune_result = self.subdev.set_freq(mid_freq) - - for n in range(2): - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - guts = blks2.wfm_rcv (demod_rate, audio_decimation) - volume_control = gr.multiply_const_ff(self.vol) - self.connect((di, n), chan_filt) - self.connect(chan_filt, guts, volume_control) - self.connect(volume_control, (audio_sink, n)) - dxc_freq, inverted = calc_dxc_freq(f[n], tune_result.baseband_freq, - self.u.converter_rate()) - self.u.set_rx_freq(n, dxc_freq) - - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - - # set initial values - self.set_gain(options.gain) - - - def set_vol (self, vol): - self.vol = vol - self.volume_control.set_k(self.vol) - - - def set_gain(self, gain): - self.subdev.set_gain(gain) - - def __del__(self): - # Avoid weak-reference error - del self.subdev - -if __name__ == '__main__': - tb = wfm_rx_block() - try: - tb.run() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py deleted file mode 100755 index 217f207c5..000000000 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks2 -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from usrpm import usrp_dbid -import sys -import math - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) - - -class wfm_rx_block (gr.top_block): - - def __init__(self): - gr.top_block.__init__(self) - - parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") - parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - self.vol = .1 - self.state = "FREQ" - self.freq = 0 - - # build graph - - self.u = usrp.source_c() # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 200 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 320 kS/s - chanfilt_decim = 1 - demod_rate = usrp_rate / chanfilt_decim - audio_decimation = 10 - audio_rate = demod_rate / audio_decimation # 32 kHz - - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) - - - chan_filt_coeffs = optfir.low_pass (1, # gain - usrp_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - - self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) - - self.volume_control = gr.multiply_const_ff(self.vol) - - # sound card as final sink - audio_sink = audio.sink(int(audio_rate), - options.audio_output, - False) # ok_to_block - - # now wire it all together - self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink) - - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - if abs(options.freq) < 1e6: - options.freq *= 1e6 - - # set initial values - - self.set_gain(options.gain) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - def set_vol (self, vol): - self.vol = vol - self.volume_control.set_k(self.vol) - self.update_status_bar () - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = self.u.tune(0, self.subdev, target_freq) - - if r: - self.freq = target_freq - self.update_status_bar() - self._set_status_msg("OK", 0) - return True - - self._set_status_msg("Failed", 0) - return False - - def set_gain(self, gain): - self.subdev.set_gain(gain) - - def update_status_bar (self): - msg = "Freq: %s Volume:%f Setting:%s" % ( - eng_notation.num_to_str(self.freq), self.vol, self.state) - self._set_status_msg(msg, 1) - - def _set_status_msg(self, msg, which=0): - print msg - - -if __name__ == '__main__': - tb = wfm_rx_block() - try: - tb.run() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/usrp2/qt_wfm_interface.py b/gnuradio-examples/python/usrp2/qt_wfm_interface.py deleted file mode 100644 index 4c4367ed0..000000000 --- a/gnuradio-examples/python/usrp2/qt_wfm_interface.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'qt_wfm_interface.ui' -# -# Created: Thu Jun 18 23:41:03 2009 -# by: PyQt4 UI code generator 4.4.3 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -class Ui_InterfaceWindow(object): - def setupUi(self, InterfaceWindow): - InterfaceWindow.setObjectName("InterfaceWindow") - InterfaceWindow.resize(909, 711) - self.centralwidget = QtGui.QWidget(InterfaceWindow) - self.centralwidget.setObjectName("centralwidget") - self.closeButton = QtGui.QPushButton(self.centralwidget) - self.closeButton.setGeometry(QtCore.QRect(790, 580, 101, 31)) - self.closeButton.setObjectName("closeButton") - self.sinkFrame = QtGui.QFrame(self.centralwidget) - self.sinkFrame.setGeometry(QtCore.QRect(10, 10, 891, 501)) - self.sinkFrame.setFrameShape(QtGui.QFrame.StyledPanel) - self.sinkFrame.setFrameShadow(QtGui.QFrame.Raised) - self.sinkFrame.setObjectName("sinkFrame") - self.horizontalLayoutWidget = QtGui.QWidget(self.sinkFrame) - self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 871, 481)) - self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") - self.sinkLayout = QtGui.QHBoxLayout(self.horizontalLayoutWidget) - self.sinkLayout.setObjectName("sinkLayout") - self.channelModeBox = QtGui.QGroupBox(self.centralwidget) - self.channelModeBox.setGeometry(QtCore.QRect(10, 520, 261, 131)) - self.channelModeBox.setObjectName("channelModeBox") - self.bandwidthabel = QtGui.QLabel(self.channelModeBox) - self.bandwidthabel.setGeometry(QtCore.QRect(10, 90, 101, 17)) - self.bandwidthabel.setObjectName("bandwidthabel") - self.bandwidthEdit = QtGui.QLineEdit(self.channelModeBox) - self.bandwidthEdit.setGeometry(QtCore.QRect(130, 90, 113, 23)) - self.bandwidthEdit.setObjectName("bandwidthEdit") - self.gainEdit = QtGui.QLineEdit(self.channelModeBox) - self.gainEdit.setGeometry(QtCore.QRect(130, 60, 113, 23)) - self.gainEdit.setObjectName("gainEdit") - self.gainLabel = QtGui.QLabel(self.channelModeBox) - self.gainLabel.setGeometry(QtCore.QRect(10, 60, 111, 20)) - self.gainLabel.setObjectName("gainLabel") - self.freqEdit = QtGui.QLineEdit(self.channelModeBox) - self.freqEdit.setGeometry(QtCore.QRect(130, 30, 113, 23)) - self.freqEdit.setObjectName("freqEdit") - self.freqLabel = QtGui.QLabel(self.channelModeBox) - self.freqLabel.setGeometry(QtCore.QRect(10, 30, 111, 17)) - self.freqLabel.setObjectName("freqLabel") - self.pauseButton = QtGui.QPushButton(self.centralwidget) - self.pauseButton.setGeometry(QtCore.QRect(790, 520, 101, 31)) - self.pauseButton.setObjectName("pauseButton") - self.fmBox = QtGui.QGroupBox(self.centralwidget) - self.fmBox.setGeometry(QtCore.QRect(290, 520, 251, 131)) - self.fmBox.setObjectName("fmBox") - self.volumeEdit = QtGui.QLineEdit(self.fmBox) - self.volumeEdit.setGeometry(QtCore.QRect(130, 20, 113, 23)) - self.volumeEdit.setObjectName("volumeEdit") - self.volumeLabel = QtGui.QLabel(self.fmBox) - self.volumeLabel.setGeometry(QtCore.QRect(10, 20, 111, 17)) - self.volumeLabel.setObjectName("volumeLabel") - InterfaceWindow.setCentralWidget(self.centralwidget) - self.menubar = QtGui.QMenuBar(InterfaceWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 909, 24)) - self.menubar.setObjectName("menubar") - self.menuFile = QtGui.QMenu(self.menubar) - self.menuFile.setObjectName("menuFile") - InterfaceWindow.setMenuBar(self.menubar) - self.statusbar = QtGui.QStatusBar(InterfaceWindow) - self.statusbar.setObjectName("statusbar") - InterfaceWindow.setStatusBar(self.statusbar) - self.actionExit = QtGui.QAction(InterfaceWindow) - self.actionExit.setObjectName("actionExit") - self.menuFile.addAction(self.actionExit) - self.menubar.addAction(self.menuFile.menuAction()) - - self.retranslateUi(InterfaceWindow) - QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), InterfaceWindow.close) - QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), InterfaceWindow.close) - QtCore.QMetaObject.connectSlotsByName(InterfaceWindow) - InterfaceWindow.setTabOrder(self.closeButton, self.gainEdit) - InterfaceWindow.setTabOrder(self.gainEdit, self.freqEdit) - InterfaceWindow.setTabOrder(self.freqEdit, self.bandwidthEdit) - - def retranslateUi(self, InterfaceWindow): - InterfaceWindow.setWindowTitle(QtGui.QApplication.translate("InterfaceWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) - self.closeButton.setText(QtGui.QApplication.translate("InterfaceWindow", "Close", None, QtGui.QApplication.UnicodeUTF8)) - self.channelModeBox.setTitle(QtGui.QApplication.translate("InterfaceWindow", "USRP Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.bandwidthabel.setText(QtGui.QApplication.translate("InterfaceWindow", "Bandwidth (Hz)", None, QtGui.QApplication.UnicodeUTF8)) - self.gainLabel.setText(QtGui.QApplication.translate("InterfaceWindow", "Gain (dB)", None, QtGui.QApplication.UnicodeUTF8)) - self.freqLabel.setText(QtGui.QApplication.translate("InterfaceWindow", "Frequency", None, QtGui.QApplication.UnicodeUTF8)) - self.pauseButton.setText(QtGui.QApplication.translate("InterfaceWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8)) - self.fmBox.setTitle(QtGui.QApplication.translate("InterfaceWindow", "FM Tuner Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.volumeLabel.setText(QtGui.QApplication.translate("InterfaceWindow", "Volume", None, QtGui.QApplication.UnicodeUTF8)) - self.menuFile.setTitle(QtGui.QApplication.translate("InterfaceWindow", "&File", None, QtGui.QApplication.UnicodeUTF8)) - self.actionExit.setText(QtGui.QApplication.translate("InterfaceWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8)) - diff --git a/gnuradio-examples/python/usrp2/qt_wfm_interface.ui b/gnuradio-examples/python/usrp2/qt_wfm_interface.ui deleted file mode 100644 index 16902d9f4..000000000 --- a/gnuradio-examples/python/usrp2/qt_wfm_interface.ui +++ /dev/null @@ -1,253 +0,0 @@ -<ui version="4.0" > - <class>InterfaceWindow</class> - <widget class="QMainWindow" name="InterfaceWindow" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>909</width> - <height>711</height> - </rect> - </property> - <property name="windowTitle" > - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralwidget" > - <widget class="QPushButton" name="closeButton" > - <property name="geometry" > - <rect> - <x>790</x> - <y>580</y> - <width>101</width> - <height>31</height> - </rect> - </property> - <property name="text" > - <string>Close</string> - </property> - </widget> - <widget class="QFrame" name="sinkFrame" > - <property name="geometry" > - <rect> - <x>10</x> - <y>10</y> - <width>891</width> - <height>501</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Raised</enum> - </property> - <widget class="QWidget" name="horizontalLayoutWidget" > - <property name="geometry" > - <rect> - <x>10</x> - <y>10</y> - <width>871</width> - <height>481</height> - </rect> - </property> - <layout class="QHBoxLayout" name="sinkLayout" /> - </widget> - </widget> - <widget class="QGroupBox" name="channelModeBox" > - <property name="geometry" > - <rect> - <x>10</x> - <y>520</y> - <width>261</width> - <height>131</height> - </rect> - </property> - <property name="title" > - <string>USRP Parameters</string> - </property> - <widget class="QLabel" name="bandwidthabel" > - <property name="geometry" > - <rect> - <x>10</x> - <y>90</y> - <width>101</width> - <height>17</height> - </rect> - </property> - <property name="text" > - <string>Bandwidth (Hz)</string> - </property> - </widget> - <widget class="QLineEdit" name="bandwidthEdit" > - <property name="geometry" > - <rect> - <x>130</x> - <y>90</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLineEdit" name="gainEdit" > - <property name="geometry" > - <rect> - <x>130</x> - <y>60</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="gainLabel" > - <property name="geometry" > - <rect> - <x>10</x> - <y>60</y> - <width>111</width> - <height>20</height> - </rect> - </property> - <property name="text" > - <string>Gain (dB)</string> - </property> - </widget> - <widget class="QLineEdit" name="freqEdit" > - <property name="geometry" > - <rect> - <x>130</x> - <y>30</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="freqLabel" > - <property name="geometry" > - <rect> - <x>10</x> - <y>30</y> - <width>111</width> - <height>17</height> - </rect> - </property> - <property name="text" > - <string>Frequency</string> - </property> - </widget> - </widget> - <widget class="QPushButton" name="pauseButton" > - <property name="geometry" > - <rect> - <x>790</x> - <y>520</y> - <width>101</width> - <height>31</height> - </rect> - </property> - <property name="text" > - <string>Pause</string> - </property> - </widget> - <widget class="QGroupBox" name="fmBox" > - <property name="geometry" > - <rect> - <x>290</x> - <y>520</y> - <width>251</width> - <height>131</height> - </rect> - </property> - <property name="title" > - <string>FM Tuner Parameters</string> - </property> - <widget class="QLineEdit" name="volumeEdit" > - <property name="geometry" > - <rect> - <x>130</x> - <y>20</y> - <width>113</width> - <height>23</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="volumeLabel" > - <property name="geometry" > - <rect> - <x>10</x> - <y>20</y> - <width>111</width> - <height>17</height> - </rect> - </property> - <property name="text" > - <string>Volume</string> - </property> - </widget> - </widget> - </widget> - <widget class="QMenuBar" name="menubar" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>909</width> - <height>24</height> - </rect> - </property> - <widget class="QMenu" name="menuFile" > - <property name="title" > - <string>&File</string> - </property> - <addaction name="actionExit" /> - </widget> - <addaction name="menuFile" /> - </widget> - <widget class="QStatusBar" name="statusbar" /> - <action name="actionExit" > - <property name="text" > - <string>E&xit</string> - </property> - </action> - </widget> - <tabstops> - <tabstop>closeButton</tabstop> - <tabstop>gainEdit</tabstop> - <tabstop>freqEdit</tabstop> - <tabstop>bandwidthEdit</tabstop> - </tabstops> - <resources/> - <connections> - <connection> - <sender>closeButton</sender> - <signal>clicked()</signal> - <receiver>InterfaceWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel" > - <x>322</x> - <y>623</y> - </hint> - <hint type="destinationlabel" > - <x>66</x> - <y>561</y> - </hint> - </hints> - </connection> - <connection> - <sender>actionExit</sender> - <signal>triggered()</signal> - <receiver>InterfaceWindow</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel" > - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel" > - <x>617</x> - <y>327</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/gnuradio-examples/python/usrp2/usrp2_wfm_qt.py b/gnuradio-examples/python/usrp2/usrp2_wfm_qt.py deleted file mode 100755 index 0c7476921..000000000 --- a/gnuradio-examples/python/usrp2/usrp2_wfm_qt.py +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007,2008,2009 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, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp2 -from gnuradio import blks2 -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import sys -import math - - -try: - from gnuradio.qtgui import qtgui - from PyQt4 import QtGui, QtCore - import sip -except ImportError: - print "Please install gr-qtgui." - sys.exit(1) - -try: - from qt_wfm_interface import Ui_InterfaceWindow -except ImportError: - print "Error: could not find qt_wfm_interface.py:" - print "\tPlease run: \"pyuic4 qt_wfm_interface.ui -o qt_wfm_interface.py\"" - sys.exit(1) - -print "This program is not in a proper working state. Comment this out if you want to play." -sys.exit(1) - - -# //////////////////////////////////////////////////////////////////// -# Define the QT Interface and Control Dialog -# //////////////////////////////////////////////////////////////////// - - -class dialog_box(QtGui.QMainWindow): - def __init__(self, snk_usrp, snk_vol, fg, parent=None): - - QtGui.QWidget.__init__(self, parent) - self.gui = Ui_InterfaceWindow() - self.gui.setupUi(self) - - self.fg = fg - - # Set USRP parameters - self.set_bw(self.fg.usrp_bw()) - self.set_freq(self.fg.freq()) - self.set_gain(self.fg.gain()) - self.set_volume(self.fg.volume()) - - # Add the qtsnk widgets to the hlayout box - self.gui.sinkLayout.addWidget(snk_usrp) - self.gui.sinkLayout.addWidget(snk_vol) - - - # Connect up some signals - self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"), - self.pauseFg) - - self.connect(self.gui.bandwidthEdit, QtCore.SIGNAL("editingFinished()"), - self.bwEditText) - self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"), - self.freqEditText) - self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"), - self.gainEditText) - - self.connect(self.gui.volumeEdit, QtCore.SIGNAL("editingFinished()"), - self.volumeEditText) - - - def pauseFg(self): - if(self.gui.pauseButton.text() == "Pause"): - self.fg.stop() - self.fg.wait() - self.gui.pauseButton.setText("Unpause") - else: - self.fg.start() - self.gui.pauseButton.setText("Pause") - - - # Accessor functions for Gui to manipulate USRP - def set_bw(self, bw): - self.gui.bandwidthEdit.setText(QtCore.QString("%1").arg(bw)) - - def set_freq(self, freq): - self.gui.freqEdit.setText(QtCore.QString("%1").arg(freq)) - - def set_gain(self, gain): - self.gui.gainEdit.setText(QtCore.QString("%1").arg(gain)) - - def set_volume(self, vol): - self.gui.volumeEdit.setText(QtCore.QString("%1").arg(vol)) - - def bwEditText(self): - try: - bw = self.gui.bandwidthEdit.text().toDouble()[0] - self.fg.set_usrp_bw(bw) - except RuntimeError: - pass - - def freqEditText(self): - try: - freq = self.gui.freqEdit.text().toDouble()[0] - self.fg.set_freq(freq) - except RuntimeError: - pass - - def gainEditText(self): - try: - gain = self.gui.gainEdit.text().toDouble()[0] - self.fg.set_gain(gain) - except RuntimeError: - pass - - def volumeEditText(self): - try: - vol = self.gui.volumeEdit.text().toDouble()[0] - self.fg.set_volume(vol) - except RuntimeError: - pass - - - - -# //////////////////////////////////////////////////////////////////// -# Define the GNU Radio Top Block -# //////////////////////////////////////////////////////////////////// - - -class wfm_rx_block (gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - parser = OptionParser(option_class=eng_option) - parser.add_option("-e", "--interface", type="string", default="eth0", - help="select Ethernet interface, default is eth0") - parser.add_option("-m", "--mac-addr", type="string", default="", - help="select USRP by MAC address, default is auto-select") - #parser.add_option("-A", "--antenna", default=None, - # help="select Rx Antenna (only on RFX-series boards)") - parser.add_option("-f", "--freq", type="eng_float", default=100.1, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-V", "--volume", type="eng_float", default=None, - help="set volume (default is midpoint)") - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - self._volume = options.volume - self._usrp_freq = options.freq - self._usrp_gain = options.gain - self._audio_rate = int(32e3) - - # build graph - - self.u = usrp2.source_32fc(options.interface, options.mac_addr) - - # calculate decimation values to get USRP BW at 320 kHz - self.calculate_usrp_bw(320e3) - - self.set_decim(self._usrp_decim) - - #FIXME: need named constants and text descriptions available to (gr-)usrp2 even - #when usrp(1) module is not built. A usrp_common module, perhaps? - dbid = self.u.daughterboard_id() - print "Using RX d'board 0x%04X" % (dbid,) - #if not (dbid == 0x0001 or #usrp_dbid.BASIC_RX - # dbid == 0x0003 or #usrp_dbid.TV_RX - # dbid == 0x000c or #usrp_dbid.TV_RX_REV_2 - # dbid == 0x0040 or #usrp_dbid.TV_RX_REV_3 - # dbid == 0x0043 or #usrp_dbid.TV_RX_MIMO - # dbid == 0x0044 or #usrp_dbid.TV_RX_REV_2_MIMO - # dbid == 0x0045 ): #usrp_dbid.TV_RX_REV_3_MIMO - # print "This daughterboard does not cover the required frequency range" - # print "for this application. Please use a BasicRX or TVRX daughterboard." - # raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.") - - chan_filt_coeffs = optfir.low_pass (1, # gain - self._usrp_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (self._chanfilt_decim, chan_filt_coeffs) - - self.guts = blks2.wfm_rcv (self._demod_rate, self._audio_decim) - - self.volume_control = gr.multiply_const_ff(1) - - # sound card as final sink - #audio_sink = audio.sink (int (audio_rate), - # options.audio_output, - # False) # ok_to_block - audio_sink = audio.sink (self._audio_rate, - options.audio_output) - - - if self._usrp_gain is None: - # if no gain was specified, use the mid-point in dB - g = self.u.gain_range() - print "Gain range: ", g - self._usrp_gain = float(g[0]+g[1])/2 - - if self._volume is None: - g = self.volume_range() - self._volume = float(g[0]+g[1])/2 - - if abs(self._usrp_freq) < 1e6: - self._usrp_freq *= 1e6 - - # set initial values - self.set_gain(self._usrp_gain) - self.set_volume(self._volume) - if not(self.set_freq(self._usrp_freq)): - print ("Failed to set initial frequency") - - - # Define a GUI sink to display the received signal - self.qapp = QtGui.QApplication(sys.argv) - fftsize = 2048 - - self.usrp_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - -self._usrp_rate/2.0, self._usrp_rate/2.0, - "Received Signal", True, True, False, True, False, - use_openGL=False) - self.usrp_rx2 = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - -self._usrp_rate/2.0, self._usrp_rate/2.0, - "Received Signal", True, True, False, True, False) - - # now wire it all together - self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink) - self.connect (self.u, self.usrp_rx) - self.connect (self.volume_control, self.usrp_rx2) - - usrp_rx_widget = sip.wrapinstance(self.usrp_rx.pyqwidget(), QtGui.QWidget) - usrp_rx2_widget = sip.wrapinstance(self.usrp_rx2.pyqwidget(), QtGui.QWidget) - - self.main_box = dialog_box(usrp_rx_widget, usrp_rx2_widget, self) - self.main_box.show() - - - def calculate_usrp_bw(self, bw): - """ - Calculate the different decimation rates that make the USRP BW equal to the - input bandwidth parameter 'bw' and the audio bandwidth equal to the system- - wide bandwidth 'self._audio_rate' - """ - - adc_rate = self.u.adc_rate() - d_usrp = int(adc_rate/bw) - bw_real = adc_rate / float(d_usrp) - - d_chan = 1 - demod_rate = bw_real / d_chan - - d_audio = int(bw_real / self._audio_rate) - audio_rate = demod_rate / d_audio - - self._usrp_decim = d_usrp - self._chanfilt_decim = d_chan - self._audio_decim = d_audio - self._demod_rate = demod_rate - self._usrp_rate = bw_real - - print "USRP Decimation: ", self._usrp_decim - print "USRP Bandwidth: ", bw_real - print "Audio Decimation: ", self._audio_decim - print "Audio Bandwidth: ", audio_rate - - def set_volume (self, vol): - g = self.volume_range() - self._volume = max(g[0], min(g[1], vol)) - self.volume_control.set_k(10**(self._volume/10)) - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = self.u.set_center_freq(target_freq) - if r: - self._usrp_freq = target_freq - return True - return False - - def set_usrp_bw(self, bw): - self.calculate_usrp_bw(bw) - - def set_gain(self, gain): - self._usrp_gain = gain - self.u.set_gain(gain) - - def set_decim(self, decim): - self._usrp_decim = int(decim) - self.u.set_decim(self._usrp_decim) - - def volume(self): - return self._volume - - def freq(self): - return self._usrp_freq - - def usrp_bw(self): - return self._usrp_rate - - def gain(self): - return self._usrp_gain - - def decim(self): - return self._usrp_decim - - def volume_range(self): - return (-20.0, 0.0, 0.5) - - -if __name__ == '__main__': - tb = wfm_rx_block() - tb.start() - tb.qapp.exec_() - diff --git a/gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py b/gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py deleted file mode 100755 index 2b94c458e..000000000 --- a/gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py +++ /dev/null @@ -1,289 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2005,2006,2007,2008,2009 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, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp2 -from gnuradio import blks2 -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import slider, powermate -from gnuradio.wxgui import stdgui2, fftsink2, form -from optparse import OptionParser -import sys -import math -import wx - -class wfm_rx_block (stdgui2.std_top_block): - def __init__(self,frame,panel,vbox,argv): - stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) - - parser = OptionParser(option_class=eng_option) - parser.add_option("-e", "--interface", type="string", default="eth0", - help="select Ethernet interface, default is eth0") - parser.add_option("-m", "--mac-addr", type="string", default="", - help="select USRP by MAC address, default is auto-select") - #parser.add_option("-A", "--antenna", default=None, - # help="select Rx Antenna (only on RFX-series boards)") - parser.add_option("-f", "--freq", type="eng_float", default=100.1, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-V", "--volume", type="eng_float", default=None, - help="set volume (default is midpoint)") - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - self.frame = frame - self.panel = panel - - self.vol = 0 - self.state = "FREQ" - self.freq = 0 - - # build graph - - self.u = usrp2.source_32fc(options.interface, options.mac_addr) - - adc_rate = self.u.adc_rate() # 100 MS/s - usrp_decim = 312 - self.u.set_decim(usrp_decim) - usrp_rate = adc_rate / usrp_decim # ~320 kS/s - chanfilt_decim = 1 - demod_rate = usrp_rate / chanfilt_decim - audio_decimation = 10 - audio_rate = demod_rate / audio_decimation # ~32 kHz - - #FIXME: need named constants and text descriptions available to (gr-)usrp2 even - #when usrp(1) module is not built. A usrp_common module, perhaps? - dbid = self.u.daughterboard_id() - print "Using RX d'board 0x%04X" % (dbid,) - if not (dbid == 0x0001 or #usrp_dbid.BASIC_RX - dbid == 0x0003 or #usrp_dbid.TV_RX - dbid == 0x000c or #usrp_dbid.TV_RX_REV_2 - dbid == 0x0040 or #usrp_dbid.TV_RX_REV_3 - dbid == 0x0043 or #usrp_dbid.TV_RX_MIMO - dbid == 0x0044 or #usrp_dbid.TV_RX_REV_2_MIMO - dbid == 0x0045 or #usrp_dbid.TV_RX_REV_3_MIMO - dbid == 0x0053 ): #usrp_dbid.WBX - print "This daughterboard does not cover the required frequency range" - print "for this application. Please use a BasicRX or TVRX daughterboard." - raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.") - - chan_filt_coeffs = optfir.low_pass (1, # gain - usrp_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - - self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) - - self.volume_control = gr.multiply_const_ff(self.vol) - - # sound card as final sink - audio_sink = audio.sink (int (audio_rate), - options.audio_output, - False) # ok_to_block - - # now wire it all together - self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink) - - self._build_gui(vbox, usrp_rate, demod_rate, audio_rate) - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.u.gain_range() - options.gain = float(g[0]+g[1])/2 - - if options.volume is None: - g = self.volume_range() - options.volume = float(g[0]+g[1])/2 - - if abs(options.freq) < 1e6: - options.freq *= 1e6 - - # set initial values - - self.set_gain(options.gain) - self.set_vol(options.volume) - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - - def _set_status_msg(self, msg, which=0): - self.frame.GetStatusBar().SetStatusText(msg, which) - - - def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - - if 1: - self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP2", - fft_size=512, sample_rate=usrp_rate, - ref_scale=1.0, ref_level=0, y_divs=12) - self.connect (self.u, self.src_fft) - vbox.Add (self.src_fft.win, 4, wx.EXPAND) - - if 1: - post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Demod", - fft_size=1024, sample_rate=usrp_rate, - y_per_div=10, ref_level=0) - self.connect (self.guts.fm_demod, post_filt_fft) - vbox.Add (post_filt_fft.win, 4, wx.EXPAND) - - if 0: - post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post Deemph", - fft_size=512, sample_rate=audio_rate, - y_per_div=10, ref_level=-20) - self.connect (self.guts.deemph, post_deemph_fft) - vbox.Add (post_deemph_fft.win, 4, wx.EXPAND) - - - # control area form at bottom - self.myform = myform = form.form() - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - hbox.Add((5,0), 0) - myform['freq_slider'] = \ - form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, - range=(87.9e6, 108.1e6, 0.1e6), - callback=self.set_freq) - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['volume'] = \ - form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", - weight=3, range=self.volume_range(), - callback=self.set_vol) - hbox.Add((5,0), 1) - - myform['gain'] = \ - form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.u.gain_range(), - callback=self.set_gain) - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - try: - self.knob = powermate.powermate(self.frame) - self.rot = 0 - powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate) - powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button) - except: - pass - #print "FYI: No Powermate or Contour Knob found" - - - def on_rotate (self, event): - self.rot += event.delta - if (self.state == "FREQ"): - if self.rot >= 3: - self.set_freq(self.freq + .1e6) - self.rot -= 3 - elif self.rot <=-3: - self.set_freq(self.freq - .1e6) - self.rot += 3 - else: - step = self.volume_range()[2] - if self.rot >= 3: - self.set_vol(self.vol + step) - self.rot -= 3 - elif self.rot <=-3: - self.set_vol(self.vol - step) - self.rot += 3 - - def on_button (self, event): - if event.value == 0: # button up - return - self.rot = 0 - if self.state == "FREQ": - self.state = "VOL" - else: - self.state = "FREQ" - self.update_status_bar () - - - def set_vol (self, vol): - g = self.volume_range() - self.vol = max(g[0], min(g[1], vol)) - self.volume_control.set_k(10**(self.vol/10)) - self.myform['volume'].set_value(self.vol) - self.update_status_bar () - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = self.u.set_center_freq(target_freq) - if r: - self.freq = target_freq - self.myform['freq'].set_value(target_freq) # update displayed value - self.myform['freq_slider'].set_value(target_freq) # update displayed value - self.update_status_bar() - self._set_status_msg("OK", 0) - return True - - self._set_status_msg("Failed", 0) - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.u.set_gain(gain) - - def update_status_bar (self): - msg = "Volume:%r Setting:%s" % (self.vol, self.state) - self._set_status_msg(msg, 1) - self.src_fft.set_baseband_freq(self.freq) - - def volume_range(self): - return (-20.0, 0.0, 0.5) - - -if __name__ == '__main__': - app = stdgui2.stdapp (wfm_rx_block, "USRP2 WFM RX") - app.MainLoop () diff --git a/gr-audio/lib/alsa/audio_alsa_sink.cc b/gr-audio/lib/alsa/audio_alsa_sink.cc index 5fd197ec7..0bda42470 100644 --- a/gr-audio/lib/alsa/audio_alsa_sink.cc +++ b/gr-audio/lib/alsa/audio_alsa_sink.cc @@ -326,7 +326,7 @@ audio_alsa_sink::work_s16 (int noutput_items, gr_vector_void_star &output_items) { typedef gr_int16 sample_t; // the type of samples we're creating - static const int NBITS = 16; // # of bits in a sample + static const float scale_factor = std::pow(2.0f, 16-1) - 1; unsigned int nchan = input_items.size (); const float **in = (const float **) &input_items[0]; @@ -343,7 +343,7 @@ audio_alsa_sink::work_s16 (int noutput_items, bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ for (unsigned int chan = 0; chan < nchan; chan++){ - buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1)); + buf[bi++] = (sample_t) (in[chan][i] * scale_factor); } } @@ -368,7 +368,7 @@ audio_alsa_sink::work_s32 (int noutput_items, gr_vector_void_star &output_items) { typedef gr_int32 sample_t; // the type of samples we're creating - static const int NBITS = 32; // # of bits in a sample + static const float scale_factor = std::pow(2.0f, 32-1) - 1; unsigned int nchan = input_items.size (); const float **in = (const float **) &input_items[0]; @@ -385,7 +385,7 @@ audio_alsa_sink::work_s32 (int noutput_items, bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ for (unsigned int chan = 0; chan < nchan; chan++){ - buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1)); + buf[bi++] = (sample_t) (in[chan][i] * scale_factor); } } @@ -410,7 +410,7 @@ audio_alsa_sink::work_s16_1x2 (int noutput_items, gr_vector_void_star &output_items) { typedef gr_int16 sample_t; // the type of samples we're creating - static const int NBITS = 16; // # of bits in a sample + static const float scale_factor = std::pow(2.0f, 16-1) - 1; assert (input_items.size () == 1); static const unsigned int nchan = 2; @@ -427,7 +427,7 @@ audio_alsa_sink::work_s16_1x2 (int noutput_items, // process one period of data bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ - sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1)); + sample_t t = (sample_t) (in[0][i] * scale_factor); buf[bi++] = t; buf[bi++] = t; } @@ -452,7 +452,7 @@ audio_alsa_sink::work_s32_1x2 (int noutput_items, gr_vector_void_star &output_items) { typedef gr_int32 sample_t; // the type of samples we're creating - static const int NBITS = 32; // # of bits in a sample + static const float scale_factor = std::pow(2.0f, 32-1) - 1; assert (input_items.size () == 1); static unsigned int nchan = 2; @@ -469,7 +469,7 @@ audio_alsa_sink::work_s32_1x2 (int noutput_items, // process one period of data bi = 0; for (unsigned int i = 0; i < d_period_size; i++){ - sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1)); + sample_t t = (sample_t) (in[0][i] * scale_factor); buf[bi++] = t; buf[bi++] = t; } diff --git a/gr-digital/examples/Makefile.am b/gr-digital/examples/Makefile.am index 4f745f3a9..dc8aba6ca 100644 --- a/gr-digital/examples/Makefile.am +++ b/gr-digital/examples/Makefile.am @@ -37,6 +37,8 @@ dist_ourdata_SCRIPTS = \ tx_voice.py \ rx_voice.py \ run_length.py \ - gen_whitener.py - + gen_whitener.py \ + digital_bert_rx.py \ + digital_bert_tx.py \ + tunnel.py diff --git a/gnuradio-examples/python/digital/README b/gr-digital/examples/README index 904a64895..1c50ad69b 100644 --- a/gnuradio-examples/python/digital/README +++ b/gr-digital/examples/README @@ -82,3 +82,72 @@ useful as a diagnostic tool when experimenting with line coding or whitening algorithms. + +********************************************************************** +********************************************************************** + + +BERT testing example scripts + +benchmark_tx.py + +This sets up a BPSK transmitter that is modulated with a pseudorandom +sequence of bits. The PN code is generated by sending an all 1s +sequence through a 7-bit scrambler. The transmitter performs the BPSK +modulation, then passes the complex baseband waveform through a +root-raised-cosine filter and onto the USRP. + +The --sps parameter controls how many baseband samples per symbol +are created and passed through the RRC filter, prior to going to the +USRP over the USB for interpolation to the final DAC rate. + +The baseband bit rate is controlled by -r or --rate. This value, when +multiplied by the --sps parameter, must result in valid interpolation +rate for the USRP. For example, if the baseband rate is 250k bits/sec, +and the samples per symbol is 4, then the final rate is 1M samples/sec, +which results in an interpolation rate of 128. The valid interpolation +rates for the USRP are multiples of 4 between 16 and 512. + +Finally, the RRC excess bandwidth may be specified by --excess-bw. +(See ./benchmark_tx.py -h for additional parameters.) + + +benchmark_rx.py + +This sets up a BPSK receiver to demodulate the received waveform. It +accepts a similar set of parameters as the transmitter, except that one +specifies the USRP decimation rate desired. The resulting sample stream +rate must be an integral number of baseband symbols. For example, the +parameters corresponding to the above transmitter would be to use a +decimation rate of 8 (32 sps), 16 (16 sps), 32 (8 sps), 64, (4 sps), or +128 (2 sps). The lower the USRP decimation, the more CPU is required to +demodulate the signal, so not all valid decimation rates will work. + +The baseband signal from the USRP is first passed through an AGC to +establish an average power of 1.0. It is then passed through a matched +filter (another RRC), a Costas phase-locked loop, and a Mueller and +Muller bit timing recovery loop. The resulting constellation has an SNR +estimation probe attached, and is then sliced into a bit stream. + +The recovered bits are then passed through a 7-bit descrambler. If +there are no channel errors, the all 1s sequence is recovered. In the +event of a channel error, there will be a 0 in the bit stream for each +feedback tap in the descrambler. In this case, the CCSDS descrambler is +using 3 feedback taps. + +Finally, the signal is passed into a bit density measurement probe. The +channel BER is measured by dividing the 0s density by three. This +measurement is inaccurate at high BER rates (>10%) as the error 0s +begin to overlap. + +The benchmark script will, once per second, output the Costas loop +frequency offset, the recovered timing error, the estimated SNR, and the +average BER. + +NOTE: The particular SNR estimator used is inaccurate below about 7dB, +and will report erroneously high values even for random noise. + +There are a variety of Costas and M&M loop parameters one can adjust. +See ./benchmark_rx.py -h for the full set. + + diff --git a/gr-digital/examples/benchmark_rx.py b/gr-digital/examples/benchmark_rx.py index 7eb4fb9b4..c586cc8fe 100755 --- a/gr-digital/examples/benchmark_rx.py +++ b/gr-digital/examples/benchmark_rx.py @@ -44,7 +44,7 @@ class my_top_block(gr.top_block): def __init__(self, demodulator, rx_callback, options): gr.top_block.__init__(self) - if(options.tx_freq is not None): + if(options.rx_freq is not None): self.source = uhd_receiver(options.address, options.bitrate, options.samples_per_symbol, options.rx_freq, options.rx_gain, diff --git a/gr-digital/examples/digital_bert_rx.py b/gr-digital/examples/digital_bert_rx.py new file mode 100755 index 000000000..9ee1f5ee8 --- /dev/null +++ b/gr-digital/examples/digital_bert_rx.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +# +# Copyright 2008,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, eng_notation +from optparse import OptionParser +from gnuradio.eng_option import eng_option +import gnuradio.gr.gr_threading as _threading +import sys, time, math + +from gnuradio import digital + +# from current dir +from uhd_interface import uhd_receiver + +n2s = eng_notation.num_to_str + +class status_thread(_threading.Thread): + def __init__(self, tb): + _threading.Thread.__init__(self) + self.setDaemon(1) + self.tb = tb + self.done = False + self.start() + + def run(self): + while not self.done: + print "Freq. Offset: {0:5.0f} Hz Timing Offset: {1:10.1f} ppm Estimated SNR: {2:4.1f} dB BER: {3:g}".format( + tb.frequency_offset(), tb.timing_offset()*1e6, tb.snr(), tb.ber()) + try: + time.sleep(1.0) + except KeyboardInterrupt: + self.done = True + + + +class bert_receiver(gr.hier_block2): + def __init__(self, bitrate, + constellation, samples_per_symbol, + differential, excess_bw, gray_coded, + freq_bw, timing_bw, phase_bw, + verbose, log): + + gr.hier_block2.__init__(self, "bert_receive", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(0, 0, 0)) # Output signature + + self._bitrate = bitrate + + self._demod = digital.generic_demod(constellation, samples_per_symbol, + differential, excess_bw, gray_coded, + freq_bw, timing_bw, phase_bw, + verbose, log) + + self._symbol_rate = self._bitrate * self._demod.bits_per_symbol() + self._sample_rate = self._symbol_rate * samples_per_symbol + + # Add an SNR probe on the demodulated constellation + self._snr_probe = gr.probe_mpsk_snr_c(10.0/self._symbol_rate) + self.connect(self._demod.time_recov, self._snr_probe) + + # Descramble BERT sequence. A channel error will create 3 incorrect bits + self._descrambler = gr.descrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit descrambler + + # Measure BER by the density of 0s in the stream + self._ber = gr.probe_density_b(1.0/self._symbol_rate) + + self.connect(self, self._demod, self._descrambler, self._ber) + + def frequency_offset(self): + return self._demod.freq_recov.get_frequency()*self._sample_rate/(2*math.pi) + + def timing_offset(self): + return self._demod.time_recov.get_clock_rate() + + def snr(self): + return self._snr_probe.snr() + + def ber(self): + return (1.0-self._ber.density())/3.0 + + + +class rx_psk_block(gr.top_block): + def __init__(self, demod, options): + + gr.top_block.__init__(self, "rx_mpsk") + + self._demodulator_class = demod + + # Get demod_kwargs + demod_kwargs = self._demodulator_class.extract_kwargs_from_options(options) + + # demodulator + self._demodulator = self._demodulator_class(**demod_kwargs) + + if(options.rx_freq is not None): + self._source = uhd_receiver(options.address, options.bitrate, + options.samples_per_symbol, + options.rx_freq, options.rx_gain, + options.antenna, options.verbose) + options.samples_per_symbol = self._source._sps + + elif(options.from_file is not None): + self._source = gr.file_source(gr.sizeof_gr_complex, options.from_file) + else: + self._source = gr.null_source(gr.sizeof_gr_complex) + + # Create the BERT receiver + self._receiver = bert_receiver(options.bitrate, + self._demodulator._constellation, + options.samples_per_symbol, + options.differential, + options.excess_bw, + gray_coded=True, + freq_bw=options.freq_bw, + timing_bw=options.timing_bw, + phase_bw=options.phase_bw, + verbose=options.verbose, + log=options.log) + + self.connect(self._source, self._receiver) + + def snr(self): + return self._receiver.snr() + + def mag(self): + return self._receiver.signal_mean() + + def var(self): + return self._receiver.noise_variance() + + def ber(self): + return self._receiver.ber() + + def frequency_offset(self): + return self._receiver.frequency_offset() + + def timing_offset(self): + return self._receiver.timing_offset() + + +def get_options(demods): + parser = OptionParser(option_class=eng_option, conflict_handler="resolve") + parser.add_option("","--from-file", default=None, + help="input file of samples to demod") + parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), + default='psk', + help="Select modulation from: %s [default=%%default]" + % (', '.join(demods.keys()),)) + parser.add_option("-r", "--bitrate", type="eng_float", default=250e3, + help="Select modulation bit rate (default=%default)") + parser.add_option("-S", "--samples-per-symbol", type="float", default=2, + help="set samples/symbol [default=%default]") + if not parser.has_option("--verbose"): + parser.add_option("-v", "--verbose", action="store_true", default=False) + if not parser.has_option("--log"): + parser.add_option("", "--log", action="store_true", default=False, + help="Log all parts of flow graph to files (CAUTION: lots of data)") + + uhd_receiver.add_options(parser) + + demods = digital.modulation_utils2.type_1_demods() + for mod in demods.values(): + mod.add_options(parser) + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + + return (options, args) + + +if __name__ == "__main__": + demods = digital.modulation_utils2.type_1_demods() + + (options, args) = get_options(demods) + + demod = demods[options.modulation] + tb = rx_psk_block(demod, options) + + print "\n*** SNR estimator is inaccurate below about 7dB" + print "*** BER estimator is inaccurate above about 10%\n" + updater = status_thread(tb) + + try: + tb.run() + except KeyboardInterrupt: + updater.done = True + updater = None diff --git a/gr-digital/examples/digital_bert_tx.py b/gr-digital/examples/digital_bert_tx.py new file mode 100755 index 000000000..6b544c7f7 --- /dev/null +++ b/gr-digital/examples/digital_bert_tx.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# +# Copyright 2008,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, eng_notation +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import sys + +from gnuradio import digital + +# from current dir +from uhd_interface import uhd_transmitter + +n2s = eng_notation.num_to_str + +class bert_transmit(gr.hier_block2): + def __init__(self, constellation, samples_per_symbol, + differential, excess_bw, gray_coded, + verbose, log): + + gr.hier_block2.__init__(self, "bert_transmit", + gr.io_signature(0, 0, 0), # Output signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Input signature + + # Create BERT data bit stream + self._bits = gr.vector_source_b([1,], True) # Infinite stream of ones + self._scrambler = gr.scrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit scrambler + + self._mod = digital.generic_mod(constellation, samples_per_symbol, + differential, excess_bw, gray_coded, + verbose, log) + + self._pack = gr.unpacked_to_packed_bb(self._mod.bits_per_symbol(), gr.GR_MSB_FIRST) + + self.connect(self._bits, self._scrambler, self._pack, self._mod, self) + + +class tx_psk_block(gr.top_block): + def __init__(self, mod, options): + gr.top_block.__init__(self, "tx_mpsk") + + self._modulator_class = mod + + # Get mod_kwargs + mod_kwargs = self._modulator_class.extract_kwargs_from_options(options) + + # transmitter + self._modulator = self._modulator_class(**mod_kwargs) + + if(options.tx_freq is not None): + self._sink = uhd_transmitter(options.address, options.bitrate, + options.samples_per_symbol, + options.tx_freq, options.tx_gain, + options.antenna, options.verbose) + options.samples_per_symbol = self._sink._sps + + elif(options.to_file is not None): + self._sink = gr.file_sink(gr.sizeof_gr_complex, options.to_file) + else: + self._sink = gr.null_sink(gr.sizeof_gr_complex) + + + self._transmitter = bert_transmit(self._modulator._constellation, + options.samples_per_symbol, + options.differential, + options.excess_bw, + gray_coded=True, + verbose=options.verbose, + log=options.log) + + self.connect(self._transmitter, self._sink) + + +def get_options(mods): + parser = OptionParser(option_class=eng_option, conflict_handler="resolve") + parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), + default='psk', + help="Select modulation from: %s [default=%%default]" + % (', '.join(mods.keys()),)) + parser.add_option("", "--amplitude", type="eng_float", default=0.2, + help="set Tx amplitude (0-1) (default=%default)") + parser.add_option("-r", "--bitrate", type="eng_float", default=250e3, + help="Select modulation bit rate (default=%default)") + parser.add_option("-S", "--samples-per-symbol", type="float", default=2, + help="set samples/symbol [default=%default]") + parser.add_option("","--to-file", default=None, + help="Output file for modulated samples") + if not parser.has_option("--verbose"): + parser.add_option("-v", "--verbose", action="store_true", default=False) + if not parser.has_option("--log"): + parser.add_option("", "--log", action="store_true", default=False) + + uhd_transmitter.add_options(parser) + + for mod in mods.values(): + mod.add_options(parser) + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + + return (options, args) + +if __name__ == "__main__": + mods = digital.modulation_utils2.type_1_mods() + + (options, args) = get_options(mods) + + mod = mods[options.modulation] + tb = tx_psk_block(mod, options) + + try: + tb.run() + except KeyboardInterrupt: + pass diff --git a/gr-digital/examples/rx_voice.py b/gr-digital/examples/rx_voice.py index d29d64ed6..b58704e16 100755 --- a/gr-digital/examples/rx_voice.py +++ b/gr-digital/examples/rx_voice.py @@ -20,17 +20,13 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr -from gnuradio import uhd -from gnuradio import audio +from gnuradio import gr, blks2, audio, uhd from gnuradio import eng_notation from gnuradio.eng_option import eng_option from optparse import OptionParser -from gnuradio.vocoder import gsm_full_rate - -# From gr-digital from gnuradio import digital +from gnuradio import vocoder import random import struct @@ -38,6 +34,7 @@ import sys # from current dir from receive_path import receive_path +from uhd_interface import uhd_receiver #import os #print os.getpid() @@ -50,9 +47,9 @@ class audio_tx(gr.hier_block2): gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - sample_rate = 8000 + self.sample_rate = sample_rate = 8000 self.packet_src = gr.message_source(33) - voice_decoder = gsm_full_rate.decode_ps() + voice_decoder = vocoder.gsm_fr_decode_ps() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) audio_sink = audio.sink(sample_rate, audio_output_dev) @@ -68,10 +65,25 @@ class my_top_block(gr.top_block): self.rxpath = receive_path(demod_class, rx_callback, options) self.audio_tx = audio_tx(options.audio_output) - if(options.from_file is not None): + if(options.rx_freq is not None): + self.source = uhd_receiver(options.address, options.bitrate, + options.samples_per_symbol, + options.rx_freq, options.rx_gain, + options.antenna, options.verbose) + options.samples_per_symbol = self.source._sps + + audio_rate = self.audio_tx.sample_rate + usrp_rate = self.source.get_sample_rate() + rrate = audio_rate / usrp_rate + self.resampler = blks2.pfb_arb_resampler_ccf(rrate) + + self.connect(self.source, self.resampler, self.rxpath) + + elif(options.from_file is not None): self.thr = gr.throttle(gr.sizeof_gr_complex, options.bitrate) self.source = gr.file_source(gr.sizeof_gr_complex, options.from_file) self.connect(self.source, self.thr, self.rxpath) + else: self.thr = gr.throttle(gr.sizeof_gr_complex, 1e6) self.source = gr.null_source(gr.sizeof_gr_complex) @@ -117,6 +129,7 @@ def main(): parser.add_option("","--from-file", default=None, help="input file of samples to demod") receive_path.add_options(parser, expert_grp) + uhd_receiver.add_options(parser) for mod in demods.values(): mod.add_options(expert_grp) diff --git a/gnuradio-examples/python/digital/tunnel.py b/gr-digital/examples/tunnel.py index b0af721da..d25594df5 100755 --- a/gnuradio-examples/python/digital/tunnel.py +++ b/gr-digital/examples/tunnel.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2009 Free Software Foundation, Inc. +# Copyright 2005,2006,2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,45 +21,45 @@ # -# ///////////////////////////////////////////////////////////////////////////// +# //////////////////////////////////////////////////////////////////// # -# This code sets up up a virtual ethernet interface (typically gr0), -# and relays packets between the interface and the GNU Radio PHY+MAC +# This code sets up up a virtual ethernet interface (typically +# gr0), and relays packets between the interface and the GNU Radio +# PHY+MAC # # What this means in plain language, is that if you've got a couple # of USRPs on different machines, and if you run this code on those -# machines, you can talk between them using normal TCP/IP networking. +# machines, you can talk between them using normal TCP/IP +# networking. # -# ///////////////////////////////////////////////////////////////////////////// +# //////////////////////////////////////////////////////////////////// -from gnuradio import gr, gru, modulation_utils -from gnuradio import usrp +from gnuradio import gr, digital, uhd from gnuradio import eng_notation from gnuradio.eng_option import eng_option from optparse import OptionParser -import random -import time -import struct -import sys -import os - # from current dir -import usrp_transmit_path -import usrp_receive_path +from receive_path import receive_path +from transmit_path import transmit_path +from uhd_interface import uhd_transmitter +from uhd_interface import uhd_receiver + +import os, sys +import random, time, struct #print os.getpid() #raw_input('Attach and press enter') - -# ///////////////////////////////////////////////////////////////////////////// +# //////////////////////////////////////////////////////////////////// # -# Use the Universal TUN/TAP device driver to move packets to/from kernel +# Use the Universal TUN/TAP device driver to move packets to/from +# kernel # # See /usr/src/linux/Documentation/networking/tuntap.txt # -# ///////////////////////////////////////////////////////////////////////////// +# //////////////////////////////////////////////////////////////////// # Linux specific... # TUNSETIFF ifr flags from <linux/tun_if.h> @@ -81,9 +81,9 @@ def open_tun_interface(tun_device_filename): return (tun, ifname) -# ///////////////////////////////////////////////////////////////////////////// -# the flow graph -# ///////////////////////////////////////////////////////////////////////////// +# //////////////////////////////////////////////////////////////////// +# the flow graph +# //////////////////////////////////////////////////////////////////// class my_top_block(gr.top_block): @@ -91,10 +91,23 @@ class my_top_block(gr.top_block): rx_callback, options): gr.top_block.__init__(self) - self.txpath = usrp_transmit_path.usrp_transmit_path(mod_class, options) - self.rxpath = usrp_receive_path.usrp_receive_path(demod_class, rx_callback, options) - self.connect(self.txpath) - self.connect(self.rxpath) + + self.source = uhd_receiver(options.address, options.bitrate, + options.samples_per_symbol, + options.rx_freq, options.rx_gain, + options.antenna, options.verbose) + + self.sink = uhd_transmitter(options.address, options.bitrate, + options.samples_per_symbol, + options.tx_freq, options.tx_gain, + options.antenna, options.verbose) + + options.samples_per_symbol = self.source._sps + + self.txpath = transmit_path(mod_class, options) + self.rxpath = receive_path(demod_class, rx_callback, options) + self.connect(self.txpath, self.sink) + self.connect(self.source, self.rxpath) def send_pkt(self, payload='', eof=False): return self.txpath.send_pkt(payload, eof) @@ -106,21 +119,22 @@ class my_top_block(gr.top_block): return self.rxpath.carrier_sensed() -# ///////////////////////////////////////////////////////////////////////////// +# //////////////////////////////////////////////////////////////////// # Carrier Sense MAC -# ///////////////////////////////////////////////////////////////////////////// +# //////////////////////////////////////////////////////////////////// class cs_mac(object): """ Prototype carrier sense MAC - Reads packets from the TUN/TAP interface, and sends them to the PHY. - Receives packets from the PHY via phy_rx_callback, and sends them - into the TUN/TAP interface. + Reads packets from the TUN/TAP interface, and sends them to the + PHY. Receives packets from the PHY via phy_rx_callback, and sends + them into the TUN/TAP interface. - Of course, we're not restricted to getting packets via TUN/TAP, this - is just an example. + Of course, we're not restricted to getting packets via TUN/TAP, + this is just an example. """ + def __init__(self, tun_fd, verbose=False): self.tun_fd = tun_fd # file descriptor for TUN/TAP interface self.verbose = verbose @@ -175,28 +189,28 @@ class cs_mac(object): def main(): - mods = modulation_utils.type_1_mods() - demods = modulation_utils.type_1_demods() + mods = digital.modulation_utils2.type_1_mods() + demods = digital.modulation_utils2.type_1_demods() parser = OptionParser (option_class=eng_option, conflict_handler="resolve") expert_grp = parser.add_option_group("Expert") - expert_grp.add_option("", "--rx-freq", type="eng_float", default=None, - help="set Rx frequency to FREQ [default=%default]", metavar="FREQ") - expert_grp.add_option("", "--tx-freq", type="eng_float", default=None, - help="set transmit frequency to FREQ [default=%default]", metavar="FREQ") parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), default='gmsk', help="Select modulation from: %s [default=%%default]" % (', '.join(mods.keys()),)) + parser.add_option("-s", "--size", type="eng_float", default=1500, + help="set packet size [default=%default]") parser.add_option("-v","--verbose", action="store_true", default=False) expert_grp.add_option("-c", "--carrier-threshold", type="eng_float", default=30, help="set carrier detect threshold (dB) [default=%default]") expert_grp.add_option("","--tun-device-filename", default="/dev/net/tun", help="path to tun device file [default=%default]") - usrp_transmit_path.add_options(parser, expert_grp) - usrp_receive_path.add_options(parser, expert_grp) + transmit_path.add_options(parser, expert_grp) + receive_path.add_options(parser, expert_grp) + uhd_receiver.add_options(parser) + uhd_transmitter.add_options(parser) for mod in mods.values(): mod.add_options(expert_grp) @@ -220,25 +234,9 @@ def main(): realtime = False print "Note: failed to enable realtime scheduling" - - # If the user hasn't set the fusb_* parameters on the command line, - # pick some values that will reduce latency. - - if options.fusb_block_size == 0 and options.fusb_nblocks == 0: - if realtime: # be more aggressive - options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'rt_nblocks', 16) - else: - options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) - - #print "fusb_block_size =", options.fusb_block_size - #print "fusb_nblocks =", options.fusb_nblocks - # instantiate the MAC mac = cs_mac(tun_fd, verbose=True) - # build the graph (PHY) tb = my_top_block(mods[options.modulation], demods[options.modulation], @@ -256,8 +254,6 @@ def main(): print "freq: %s" % (eng_notation.num_to_str(options.tx_freq)) print "bitrate: %sb/sec" % (eng_notation.num_to_str(tb.txpath.bitrate()),) print "samples/symbol: %3d" % (tb.txpath.samples_per_symbol(),) - #print "interp: %3d" % (tb.txpath.interp(),) - #print "decim: %3d" % (tb.rxpath.decim(),) tb.rxpath.set_carrier_threshold(options.carrier_threshold) print "Carrier sense threshold:", options.carrier_threshold, "dB" diff --git a/gr-digital/examples/tx_voice.py b/gr-digital/examples/tx_voice.py index f4f2c3a86..eabb5e3c3 100755 --- a/gr-digital/examples/tx_voice.py +++ b/gr-digital/examples/tx_voice.py @@ -20,17 +20,13 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr -from gnuradio import uhd -from gnuradio import audio +from gnuradio import gr, blks2, audio, uhd from gnuradio import eng_notation from gnuradio.eng_option import eng_option from optparse import OptionParser -from gnuradio.vocoder import gsm_full_rate - -# From gr-digital from gnuradio import digital +from gnuradio import vocoder import random import time @@ -39,6 +35,7 @@ import sys # from current dir from transmit_path import transmit_path +from uhd_interface import uhd_transmitter #import os #print os.getpid() @@ -50,11 +47,11 @@ class audio_rx(gr.hier_block2): gr.hier_block2.__init__(self, "audio_rx", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - sample_rate = 8000 + self.sample_rate = sample_rate = 8000 src = audio.source(sample_rate, audio_input_dev) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short() - voice_coder = gsm_full_rate.encode_sp() + voice_coder = vocoder.gsm_fr_encode_sp() self.packets_from_encoder = gr.msg_queue() packet_sink = gr.message_sink(33, self.packets_from_encoder, False) self.connect(src, src_scale, f2s, voice_coder, packet_sink) @@ -70,13 +67,27 @@ class my_top_block(gr.top_block): self.txpath = transmit_path(modulator_class, options) self.audio_rx = audio_rx(options.audio_input) - if(options.to_file is not None): + if(options.tx_freq is not None): + self.sink = uhd_transmitter(options.address, options.bitrate, + options.samples_per_symbol, + options.tx_freq, options.tx_gain, + options.antenna, options.verbose) + options.samples_per_symbol = self.sink._sps + audio_rate = self.audio_rx.sample_rate + usrp_rate = self.sink.get_sample_rate() + rrate = usrp_rate / audio_rate + + elif(options.to_file is not None): self.sink = gr.file_sink(gr.sizeof_gr_complex, options.to_file) + rrate = 1 else: self.sink = gr.null_sink(gr.sizeof_gr_complex) + rrate = 1 + self.resampler = blks2.pfb_arb_resampler_ccf(rrate) + self.connect(self.audio_rx) - self.connect(self.txpath, self.sink) + self.connect(self.txpath, self.resampler, self.sink) # ///////////////////////////////////////////////////////////////////////////// @@ -106,7 +117,9 @@ def main(): help="pcm input device name. E.g., hw:0,0 or /dev/dsp") parser.add_option("","--to-file", default=None, help="Output file for modulated samples") + transmit_path.add_options(parser, expert_grp) + uhd_transmitter.add_options(parser) for mod in mods.values(): mod.add_options(expert_grp) diff --git a/gr-digital/examples/uhd_interface.py b/gr-digital/examples/uhd_interface.py index 3e2162ba3..8420f3eec 100644 --- a/gr-digital/examples/uhd_interface.py +++ b/gr-digital/examples/uhd_interface.py @@ -90,6 +90,9 @@ class uhd_interface: return (actual_samp_rate, actual_sps) + def get_sample_rate(self): + return self.u.get_samp_rate() + def set_gain(self, gain=None): if gain is None: # if no gain was specified, use the mid-point in dB @@ -197,7 +200,8 @@ class uhd_receiver(uhd_interface, gr.hier_block2): metavar="FREQ") parser.add_option("", "--rx-gain", type="eng_float", default=None, help="set receive gain in dB (default is midpoint)") - parser.add_option("-v", "--verbose", action="store_true", default=False) + if not parser.has_option("--verbose"): + parser.add_option("-v", "--verbose", action="store_true", default=False) # Make a static method to call before instantiation add_options = staticmethod(add_options) diff --git a/gr-digital/python/Makefile.am b/gr-digital/python/Makefile.am index a33e4963d..cd98fe2d4 100644 --- a/gr-digital/python/Makefile.am +++ b/gr-digital/python/Makefile.am @@ -53,7 +53,6 @@ digital_PYTHON = \ crc.py \ generic_mod_demod.py \ gmsk.py \ - modulation_utils.py \ modulation_utils2.py \ packet_utils.py \ pkt.py \ diff --git a/gr-digital/python/d8psk.py b/gr-digital/python/d8psk.py deleted file mode 100644 index 46290faed..000000000 --- a/gr-digital/python/d8psk.py +++ /dev/null @@ -1,372 +0,0 @@ -# -# Copyright 2005,2006,2007,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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential 8PSK modulation and demodulation. -""" - -from gnuradio import gr, modulation_utils2 -from math import pi, sqrt -import digital_swig, psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 3 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_freq_alpha = 0.010 -_def_phase_damping = 0.4 -_def_phase_natfreq = 0.25 -_def_timing_alpha = 0.100 -_def_timing_beta = 0.010 -_def_timing_max_dev = 1.5 - -# ///////////////////////////////////////////////////////////////////////////// -# D8PSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class d8psk_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered differential 8PSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Log modulation data to files? - @type log: bool - """ - - gr.hier_block2.__init__(self, "d8psk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - nfilts = 32 - ntaps = 11 * int(nfilts * self._samples_per_symbol) # make nfilts filters of ntaps each - self.rrc_taps = gr.firdes.root_raised_cosine( - nfilts, # gain - nfilts, # sampling rate based on 32 filters in resampler - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - def add_options(parser): - """ - Adds 8PSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options(d8psk_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# D8PSK demodulator -# -# Differentially coherent detection of differentially encoded 8psk -# ///////////////////////////////////////////////////////////////////////////// - -class d8psk_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - freq_alpha=_def_freq_alpha, - phase_damping=_def_phase_damping, - phase_natfreq=_def_phase_natfreq, - timing_alpha=_def_timing_alpha, - timing_max_dev=_def_timing_max_dev, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log, - sync_out=False): - """ - Hierarchical block for RRC-filtered DQPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param freq_alpha: loop filter gain for frequency recovery - @type freq_alpha: float - @param phase_damping: loop filter damping factor for phase/fine frequency recovery - @type phase_damping: float - @param phase_natfreq: loop filter natural frequency for phase/fine frequency recovery - @type phase_natfreq: float - @param timing_alpha: timing loop alpha gain - @type timing_alpha: float - @param timing_max: timing loop maximum rate deviations - @type timing_max: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - if sync_out: io_sig_out = gr.io_signaturev(2, 2, (gr.sizeof_char, gr.sizeof_gr_complex)) - else: io_sig_out = gr.io_signature(1, 1, gr.sizeof_char) - - gr.hier_block2.__init__(self, "d8psk_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - io_sig_out) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._freq_alpha = freq_alpha - self._freq_beta = 0.25*self._freq_alpha**2 - self._phase_damping = phase_damping - self._phase_natfreq = phase_natfreq - self._timing_alpha = timing_alpha - self._timing_beta = _def_timing_beta - self._timing_max_dev=timing_max_dev - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 2.0) - - # Frequency correction - self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw, - 11*int(self._samples_per_symbol), - self._freq_alpha, self._freq_beta) - - # symbol timing recovery with RRC data filter - nfilts = 32 - ntaps = 11 * int(samples_per_symbol*nfilts) - taps = gr.firdes.root_raised_cosine(1.41*nfilts, nfilts, - 1.0/float(self._samples_per_symbol), - self._excess_bw, ntaps) - self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, - self._timing_alpha, - taps, nfilts, nfilts/2, self._timing_max_dev) - self.time_recov.set_beta(self._timing_beta) - - # Perform phase / fine frequency correction - self.phase_recov = digital_swig.costas_loop_cc(self._phase_damping, - self._phase_natfreq, - arity) - - # Perform Differential decoding on the constellation - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = cmath.exp(1j*cmath.pi/8.0) - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.agc, - self.freq_recov, self.time_recov, self.phase_recov, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - if sync_out: self.connect(self.phase_recov, (self, 1)) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "FLL gain: %.2f" % self._freq_alpha - print "Timing alpha gain: %.2f" % self._timing_alpha - print "Timing beta gain: %.2f" % self._timing_beta - print "Timing max dev: %.2f" % self._timing_max_dev - print "Phase damping fact: %.2e" % self._phase_damping - print "Phase natural freq: %.2e" % self._phase_natfreq - - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.freq_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat")) - self.connect(self.time_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat")) - self.connect(self.phase_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds D8PSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha, - help="set frequency lock loop alpha gain value [default=%default] (PSK)") - parser.add_option("", "--phase-natfreq", type="float", default=_def_phase_natfreq, - help="set natural frequency of phase tracking loop [default=%default] (PSK)") - parser.add_option("", "--phase-damping", type="float", default=_def_phase_damping, - help="set damping factor of phase tracking loop [default=%default] (PSK)") - parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha, - help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta, - help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev, - help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options( - d8psk_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -modulation_utils2.add_type_1_mod('d8psk', d8psk_mod) -modulation_utils2.add_type_1_demod('d8psk', d8psk_demod) diff --git a/gr-digital/python/dbpsk.py b/gr-digital/python/dbpsk.py deleted file mode 100644 index 9e065263f..000000000 --- a/gr-digital/python/dbpsk.py +++ /dev/null @@ -1,372 +0,0 @@ -# -# Copyright 2009,2010,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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential BPSK modulation and demodulation. -""" - -from gnuradio import gr, modulation_utils2 -from math import pi, sqrt, ceil -import digital_swig, psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_freq_alpha = 0.010 -_def_phase_damping = 0.4 -_def_phase_natfreq = 0.25 -_def_timing_alpha = 0.100 -_def_timing_beta = 0.010 -_def_timing_max_dev = 1.5 - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered differential BPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Log modulation data to files? - @type log: bool - """ - - gr.hier_block2.__init__(self, "dbpsk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if self._samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol) - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - - self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity]) - - # pulse shaping filter - nfilts = 32 - ntaps = nfilts * 11 * int(self._samples_per_symbol) # make nfilts filters of ntaps each - self.rrc_taps = gr.firdes.root_raised_cosine( - nfilts, # gain - nfilts, # sampling rate based on 32 filters in resampler - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) - - # Connect - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # static method that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def add_options(parser): - """ - Adds DBPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default]") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=True, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options(dbpsk_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK demodulator -# -# Differentially coherent detection of differentially encoded BPSK -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - freq_alpha=_def_freq_alpha, - phase_damping=_def_phase_damping, - phase_natfreq=_def_phase_natfreq, - timing_alpha=_def_timing_alpha, - timing_max_dev=_def_timing_max_dev, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log, - sync_out=False): - """ - Hierarchical block for RRC-filtered differential BPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param freq_alpha: loop filter gain for frequency recovery - @type freq_alpha: float - @param phase_damping: loop filter damping factor for phase/fine frequency recovery - @type phase_damping: float - @param phase_natfreq: loop filter natural frequency for phase/fine frequency recovery - @type phase_natfreq: float - @param timing_alpha: loop alpha gain for timing recovery - @type timing_alpha: float - @param timing_max: timing loop maximum rate deviations - @type timing_max: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Print modualtion data to files? - @type log: bool - @param sync_out: Output a sync signal on :1? - @type sync_out: bool - """ - if sync_out: io_sig_out = gr.io_signaturev(2, 2, (gr.sizeof_char, gr.sizeof_gr_complex)) - else: io_sig_out = gr.io_signature(1, 1, gr.sizeof_char) - - gr.hier_block2.__init__(self, "dbpsk_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - io_sig_out) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._freq_alpha = freq_alpha - self._freq_beta = 0.10*self._freq_alpha - self._phase_damping = phase_damping - self._phase_natfreq = phase_natfreq - self._timing_alpha = timing_alpha - self._timing_beta = _def_timing_beta - self._timing_max_dev=timing_max_dev - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "samples_per_symbol must be >= 2, is %r" % (samples_per_symbol,) - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 1.0) - - # Frequency correction - self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw, - 11*int(self._samples_per_symbol), - self._freq_alpha, self._freq_beta) - - # symbol timing recovery with RRC data filter - nfilts = 32 - ntaps = 11 * int(self._samples_per_symbol*nfilts) - taps = gr.firdes.root_raised_cosine(nfilts, nfilts, - 1.0/float(self._samples_per_symbol), - self._excess_bw, ntaps) - self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, - self._timing_alpha, - taps, nfilts, nfilts/2, self._timing_max_dev) - self.time_recov.set_beta(self._timing_beta) - - # Perform phase / fine frequency correction - self.phase_recov = digital_swig.costas_loop_cc(self._phase_damping, - self._phase_natfreq, - arity) - - # Do differential decoding based on phase change of symbols - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - const = digital_swig.constellation_bpsk() - self.slicer = digital_swig.constellation_decoder_cb(const.base()) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.agc, - self.freq_recov, self.time_recov, self.phase_recov, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - if sync_out: self.connect(self.phase_recov, (self, 1)) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "FLL gain: %.2e" % self._freq_alpha - print "Timing alpha gain: %.2e" % self._timing_alpha - print "Timing beta gain: %.2e" % self._timing_beta - print "Timing max dev: %.2f" % self._timing_max_dev - print "Phase damping fact: %.2e" % self._phase_damping - print "Phase natural freq: %.2e" % self._phase_natfreq - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.freq_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat")) - self.connect(self.time_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat")) - self.connect(self.phase_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds DBPSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha, - help="set frequency lock loop alpha gain value [default=%default] (PSK)") - parser.add_option("", "--phase-natfreq", type="float", default=_def_phase_natfreq, - help="set natural frequency of phase tracking loop [default=%default] (PSK)") - parser.add_option("", "--phase-damping", type="float", default=_def_phase_damping, - help="set damping factor of phase tracking loop [default=%default] (PSK)") - parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha, - help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta, - help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev, - help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options( - dbpsk_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - -# -# Add these to the mod/demod registry -# -modulation_utils2.add_type_1_mod('dbpsk', dbpsk_mod) -modulation_utils2.add_type_1_demod('dbpsk', dbpsk_demod) diff --git a/gr-digital/python/dqpsk.py b/gr-digital/python/dqpsk.py deleted file mode 100644 index 5e17d24bc..000000000 --- a/gr-digital/python/dqpsk.py +++ /dev/null @@ -1,376 +0,0 @@ -# -# Copyright 2009,2010,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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential QPSK modulation and demodulation. -""" - -from gnuradio import gr, modulation_utils2 -from math import pi, sqrt -import digital_swig, psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_freq_alpha = 0.010 -_def_phase_damping = 0.4 -_def_phase_natfreq = 0.25 -_def_timing_alpha = 0.100 -_def_timing_beta = 0.010 -_def_timing_max_dev = 1.5 - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "dqpsk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, ("sbp must be >= 2, is %f" % samples_per_symbol) - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = .707 + .707j - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - nfilts = 32 - ntaps = 11 * int(nfilts * self._samples_per_symbol) # make nfilts filters of ntaps each - self.rrc_taps = gr.firdes.root_raised_cosine( - nfilts, # gain - nfilts, # sampling rate based on 32 filters in resampler - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - def add_options(parser): - """ - Adds QPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options(dqpsk_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK demodulator -# -# Differentially coherent detection of differentially encoded qpsk -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - freq_alpha=_def_freq_alpha, - phase_damping=_def_phase_damping, - phase_natfreq=_def_phase_natfreq, - timing_alpha=_def_timing_alpha, - timing_max_dev=_def_timing_max_dev, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log, - sync_out=False): - """ - Hierarchical block for RRC-filtered DQPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param freq_alpha: loop filter gain for frequency recovery - @type freq_alpha: float - @param phase_damping: loop filter damping factor for phase/fine frequency recovery - @type phase_damping: float - @param phase_natfreq: loop filter natural frequency for phase/fine frequency recovery - @type phase_natfreq: float - @param timing_alpha: timing loop alpha gain - @type timing_alpha: float - @param timing_max: timing loop maximum rate deviations - @type timing_max: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Print modualtion data to files? - @type log: bool - @param sync_out: Output a sync signal on :1? - @type sync_out: bool - """ - if sync_out: io_sig_out = gr.io_signaturev(2, 2, (gr.sizeof_char, gr.sizeof_gr_complex)) - else: io_sig_out = gr.io_signature(1, 1, gr.sizeof_char) - - gr.hier_block2.__init__(self, "dqpsk_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - io_sig_out) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._freq_alpha = freq_alpha - self._freq_beta = 0.25*self._freq_alpha**2 - self._phase_damping = phase_damping - self._phase_natfreq = phase_natfreq - self._timing_alpha = timing_alpha - self._timing_beta = _def_timing_beta - self._timing_max_dev=timing_max_dev - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 2.0) - - # Frequency correction - self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw, - 11*int(self._samples_per_symbol), - self._freq_alpha, self._freq_beta) - - - # symbol timing recovery with RRC data filter - nfilts = 32 - ntaps = 11 * int(samples_per_symbol*nfilts) - taps = gr.firdes.root_raised_cosine(nfilts, nfilts, - 1.0/float(self._samples_per_symbol), - self._excess_bw, ntaps) - self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, - self._timing_alpha, - taps, nfilts, nfilts/2, self._timing_max_dev) - self.time_recov.set_beta(self._timing_beta) - - - # Perform phase / fine frequency correction - self.phase_recov = digital_swig.costas_loop_cc(self._phase_damping, - self._phase_natfreq, - arity) - - # Perform Differential decoding on the constellation - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.agc, - self.freq_recov, self.time_recov, self.phase_recov, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - if sync_out: self.connect(self.phase_recov, (self, 1)) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "FLL gain: %.2f" % self._freq_alpha - print "Timing alpha gain: %.2f" % self._timing_alpha - print "Timing beta gain: %.2f" % self._timing_beta - print "Timing max dev: %.2f" % self._timing_max_dev - print "Phase damping fact: %.2e" % self._phase_damping - print "Phase natural freq: %.2e" % self._phase_natfreq - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.freq_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat")) - self.connect(self.time_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat")) - self.connect(self.phase_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds DQPSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha, - help="set frequency lock loop alpha gain value [default=%default] (PSK)") - parser.add_option("", "--phase-natfreq", type="float", default=_def_phase_natfreq, - help="set natural frequency of phase tracking loop [default=%default] (PSK)") - parser.add_option("", "--phase-damping", type="float", default=_def_phase_damping, - help="set damping factor of phase tracking loop [default=%default] (PSK)") - parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha, - help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta, - help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev, - help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options( - dqpsk_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -modulation_utils2.add_type_1_mod('dqpsk', dqpsk_mod) -modulation_utils2.add_type_1_demod('dqpsk', dqpsk_demod) diff --git a/gr-digital/python/generic_mod_demod.py b/gr-digital/python/generic_mod_demod.py index dc69fc0b5..dec96e455 100644 --- a/gr-digital/python/generic_mod_demod.py +++ b/gr-digital/python/generic_mod_demod.py @@ -76,8 +76,8 @@ def add_common_options(parser): class generic_mod(gr.hier_block2): def __init__(self, constellation, - differential=_def_differential, samples_per_symbol=_def_samples_per_symbol, + differential=_def_differential, excess_bw=_def_excess_bw, gray_coded=True, verbose=_def_verbose, diff --git a/gr-digital/python/gmsk.py b/gr-digital/python/gmsk.py index ba122821e..c7a50f422 100644 --- a/gr-digital/python/gmsk.py +++ b/gr-digital/python/gmsk.py @@ -78,8 +78,10 @@ class gmsk_mod(gr.hier_block2): self._samples_per_symbol = samples_per_symbol self._bt = bt - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % \ + self._differential = False # make consistant with other modulators + + if samples_per_symbol < 2: + raise TypeError, ("samples_per_symbol must >= 2, is %r" % \ (samples_per_symbol,)) ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once @@ -94,12 +96,12 @@ class gmsk_mod(gr.hier_block2): 1, # gain samples_per_symbol, # symbol_rate bt, # bandwidth * symbol time - ntaps # number of taps + int(ntaps) # number of taps ) - self.sqwave = (1,) * samples_per_symbol # rectangular window + self.sqwave = (1,) * int(samples_per_symbol) # rectangular window self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) - self.gaussian_filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) + self.gaussian_filter = gr.pfb_arb_resampler_fff(samples_per_symbol, self.taps) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) @@ -192,6 +194,8 @@ class gmsk_demod(gr.hier_block2): self._bt = bt self._timing_bw = timing_bw self._timing_max_dev= _def_timing_max_dev + + self._differential = False # make consistant with other modulators if samples_per_symbol < 2: raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol @@ -234,7 +238,7 @@ class gmsk_demod(gr.hier_block2): def _print_verbage(self): print "bits per symbol: %d" % self.bits_per_symbol() - print "Bandwidth-Time Prod: %f" % self._bw + print "Bandwidth-Time Prod: %f" % self._bt print "Timing bandwidth: %.2e" % self._timing_bw @@ -253,6 +257,8 @@ class gmsk_demod(gr.hier_block2): """ parser.add_option("", "--timing-bw", type="float", default=_def_timing_bw, help="set timing symbol sync loop gain lock-in bandwidth [default=%default]") + parser.add_option("", "--bt", type="float", default=_def_bt, + help="set bandwidth-time product [default=%default] (GMSK)") add_options=staticmethod(add_options) def extract_kwargs_from_options(options): diff --git a/gr-digital/python/modulation_utils.py b/gr-digital/python/modulation_utils.py deleted file mode 100644 index 71ba77389..000000000 --- a/gr-digital/python/modulation_utils.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright 2006 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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 this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -""" -Miscellaneous utilities for managing mods and demods, as well as other items -useful in dealing with generalized handling of different modulations and demods. -""" - -import inspect - - -# Type 1 modulators accept a stream of bytes on their input and produce complex baseband output -_type_1_modulators = {} - -def type_1_mods(): - return _type_1_modulators - -def add_type_1_mod(name, mod_class): - _type_1_modulators[name] = mod_class - - -# Type 1 demodulators accept complex baseband input and produce a stream of bits, packed -# 1 bit / byte as their output. Their output is completely unambiguous. There is no need -# to resolve phase or polarity ambiguities. -_type_1_demodulators = {} - -def type_1_demods(): - return _type_1_demodulators - -def add_type_1_demod(name, demod_class): - _type_1_demodulators[name] = demod_class - - -def extract_kwargs_from_options(function, excluded_args, options): - """ - Given a function, a list of excluded arguments and the result of - parsing command line options, create a dictionary of key word - arguments suitable for passing to the function. The dictionary - will be populated with key/value pairs where the keys are those - that are common to the function's argument list (minus the - excluded_args) and the attributes in options. The values are the - corresponding values from options unless that value is None. - In that case, the corresponding dictionary entry is not populated. - - (This allows different modulations that have the same parameter - names, but different default values to coexist. The downside is - that --help in the option parser will list the default as None, - but in that case the default provided in the __init__ argument - list will be used since there is no kwargs entry.) - - @param function: the function whose parameter list will be examined - @param excluded_args: function arguments that are NOT to be added to the dictionary - @type excluded_args: sequence of strings - @param options: result of command argument parsing - @type options: optparse.Values - """ - # Try this in C++ ;) - args, varargs, varkw, defaults = inspect.getargspec(function) - d = {} - for kw in [a for a in args if a not in excluded_args]: - if hasattr(options, kw): - if getattr(options, kw) is not None: - d[kw] = getattr(options, kw) - return d diff --git a/gnuradio-examples/python/usrp2/.gitignore b/gr-shd/.gitignore index b336cc7ce..a37fc0c1a 100644 --- a/gnuradio-examples/python/usrp2/.gitignore +++ b/gr-shd/.gitignore @@ -1,2 +1,3 @@ /Makefile /Makefile.in +/*.pc diff --git a/gnuradio-examples/python/digital-bert/Makefile.am b/gr-shd/Makefile.am index eac013f09..2331831e0 100644 --- a/gnuradio-examples/python/digital-bert/Makefile.am +++ b/gr-shd/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2008,2009 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -17,17 +17,15 @@ # along with GNU Radio; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, # Boston, MA 02110-1301, USA. -# +# include $(top_srcdir)/Makefile.common -ourdatadir = $(exampledir)/digital-bert +SUBDIRS = include lib apps -dist_ourdata_DATA = \ - README \ - receive_path.py \ - transmit_path.py +if PYTHON +SUBDIRS += swig grc +endif -dist_ourdata_SCRIPTS = \ - benchmark_rx.py \ - benchmark_tx.py
\ No newline at end of file +pkgconfigdir = $(libdir)/pkgconfig +dist_pkgconfig_DATA = gnuradio-shd.pc diff --git a/gr-shd/apps/.gitignore b/gr-shd/apps/.gitignore new file mode 100644 index 000000000..22a4e7292 --- /dev/null +++ b/gr-shd/apps/.gitignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in + diff --git a/gnuradio-examples/python/usrp2/Makefile.am b/gr-shd/apps/Makefile.am index cca813349..16837f575 100644 --- a/gnuradio-examples/python/usrp2/Makefile.am +++ b/gr-shd/apps/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2005,2009 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,12 +21,12 @@ include $(top_srcdir)/Makefile.common -ourdatadir = $(exampledir)/usrp2 -dist_ourdata_DATA = \ - qt_wfm_interface.ui \ - qt_wfm_interface.py +EXTRA_DIST += \ + $(bin_SCRIPTS) +ourpythondir = $(grpythondir) + +bin_SCRIPTS = \ + shd_fft.py \ + shd_rx_cfile.py -dist_ourdata_SCRIPTS = \ - usrp2_wfm_qt.py \ - usrp2_wfm_rcv.py diff --git a/gr-utils/src/python/usrp2_fft.py b/gr-shd/apps/shd_fft.py index 4276e389a..81e84d383 100755 --- a/gr-utils/src/python/usrp2_fft.py +++ b/gr-shd/apps/shd_fft.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005,2007,2008,2010 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,11 @@ # from gnuradio import gr, gru -from gnuradio import usrp2 +from gnuradio import shd from gnuradio import eng_notation from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider +from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2 +from gnuradio.wxgui import scopesink2, form, slider from optparse import OptionParser import wx import sys @@ -38,14 +39,13 @@ class app_top_block(stdgui2.std_top_block): self.panel = panel parser = OptionParser(option_class=eng_option) - parser.add_option("-e", "--interface", type="string", default="eth0", - help="select Ethernet interface, default is eth0") - parser.add_option("-m", "--mac-addr", type="string", default="", - help="select USRP by MAC address, default is auto-select") - #parser.add_option("-A", "--antenna", default=None, - # help="select Rx Antenna (only on RFX-series boards)") - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") + parser.add_option("-a", "--address", type="string", + default="type=xmini", + help="Address of SHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate (bandwidth) [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, @@ -67,16 +67,21 @@ class app_top_block(stdgui2.std_top_block): self.options = options self.show_debug_info = True - self.u = usrp2.source_32fc(options.interface, options.mac_addr) - self.u.set_decim(options.decim) - - input_rate = self.u.adc_rate() / self.u.decim() - + self.src = shd.smini_source(device_addr=options.address, + io_type=shd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + self.src.set_samp_rate(options.samp_rate) + input_rate = self.src.get_samp_rate() + if options.waterfall: self.scope = \ - waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate) + waterfallsink2.waterfall_sink_c (panel, fft_size=1024, + sample_rate=input_rate) + self.frame.SetMinSize((800, 420)) elif options.oscilloscope: self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) + self.frame.SetMinSize((800, 600)) else: self.scope = fftsink2.fft_sink_c (panel, fft_size=options.fft_size, @@ -85,40 +90,46 @@ class app_top_block(stdgui2.std_top_block): ref_level=20.0, y_divs = 12, avg_alpha=options.avg_alpha) + self.frame.SetMinSize((800, 420)) - self.connect(self.u, self.scope) + self.connect(self.src, self.scope) self._build_gui(vbox) self._setup_events() + # set initial values if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.u.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.src.get_gain_range() + options.gain = float(g.start()+g.stop())/2 if options.freq is None: # if no freq was specified, use the mid-point - r = self.u.freq_range() - options.freq = float(r[0]+r[1])/2 + r = self.src.get_freq_range() + options.freq = float(r.start()+r.stop())/2 self.set_gain(options.gain) - #if options.antenna is not None: - # print "Selecting antenna %s" % (options.antenna,) - # self.subdev.select_rx_antenna(options.antenna) + if(options.antenna): + self.src.set_antenna(options.antenna, 0) if self.show_debug_info: - self.myform['decim'].set_value(self.u.decim()) + self.myform['samprate'].set_value(self.src.get_samp_rate()) self.myform['fs@gbe'].set_value(input_rate) - self.myform['dbname'].set_value("0x%04X" % (self.u.daughterboard_id(),)) # FIXME: add text name self.myform['baseband'].set_value(0) self.myform['ddc'].set_value(0) if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") + print "Center Freq: ", self.src.get_center_freq() + print "Freq Range: ", self.src.get_freq_range() + print "Gain: ", self.src.get_gain() + print "Gain Names: ", self.src.get_gain_names() + print "Gain Range: ", self.src.get_gain_range() + def _set_status_msg(self, msg): self.frame.GetStatusBar().SetStatusText(msg, 0) @@ -135,17 +146,20 @@ class app_top_block(stdgui2.std_top_block): hbox.Add((5,0), 0, 0) myform['freq'] = form.float_field( parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) + callback=myform.check_input_and_call(_form_set_freq, + self._set_status_msg)) hbox.Add((5,0), 0, 0) - g = self.u.gain_range() + g = self.src.get_gain_range() # some configurations don't have gain control - if g[1] > g[0]: - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) + if g.stop() > g.start(): + myform['gain'] = form.slider_field(parent=self.panel, + sizer=hbox, label="Gain", + weight=3, + min=int(g.start()), + max=int(g.stop()), + callback=self.set_gain) hbox.Add((5,0), 0, 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -158,8 +172,8 @@ class app_top_block(stdgui2.std_top_block): # FIXME figure out how to have this be a subpanel that is always # created, but has its visibility controlled by foo.Show(True/False) - def _form_set_decim(kv): - return self.set_decim(kv['decim']) + def _form_set_samp_rate(kv): + return self.set_samp_rate(kv['samprate']) if not(self.show_debug_info): return @@ -168,25 +182,19 @@ class app_top_block(stdgui2.std_top_block): vbox = vbox_arg myform = self.myform - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) + hbox.Add((5,0), 0) + myform['samprate'] = form.float_field( + parent=panel, sizer=hbox, label="Sample Rate", + callback=myform.check_input_and_call(_form_set_samp_rate, + self._set_status_msg)) hbox.Add((5,0), 1) myform['fs@gbe'] = form.static_float_field( parent=panel, sizer=hbox, label="Fs@GbE") hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) myform['baseband'] = form.static_float_field( parent=panel, sizer=hbox, label="Analog BB") @@ -196,7 +204,6 @@ class app_top_block(stdgui2.std_top_block): hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) - def set_freq(self, target_freq): """ @@ -210,13 +217,13 @@ class app_top_block(stdgui2.std_top_block): the result of that operation and our target_frequency to determine the value for the digital down converter. """ - r = self.u.set_center_freq(target_freq) - + r = self.src.set_center_freq(target_freq, 0) + if r: self.myform['freq'].set_value(target_freq) # update displayed value if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) + self.myform['baseband'].set_value(r.actual_rf_freq) + self.myform['ddc'].set_value(r.actual_dsp_freq) if not self.options.oscilloscope: self.scope.set_baseband_freq(target_freq) return True @@ -226,18 +233,18 @@ class app_top_block(stdgui2.std_top_block): def set_gain(self, gain): if self.myform.has_key('gain'): self.myform['gain'].set_value(gain) # update displayed value - self.u.set_gain(gain) + self.src.set_gain(gain, 0) - def set_decim(self, decim): - ok = self.u.set_decim(decim) - if not ok: - print "set_decim failed" - input_rate = self.u.adc_rate() / self.u.decim() + def set_samp_rate(self, samp_rate): + ok = self.src.set_samp_rate(samp_rate) + input_rate = self.src.get_samp_rate() self.scope.set_sample_rate(input_rate) if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim()) + self.myform['samprate'].set_value(self.src.get_samp_rate()) self.myform['fs@gbe'].set_value(input_rate) - return ok + + # shd set_samp_rate never fails; always falls back to closest requested. + return True def _setup_events(self): if not self.options.waterfall and not self.options.oscilloscope: @@ -266,7 +273,7 @@ class app_top_block(stdgui2.std_top_block): def main (): - app = stdgui2.stdapp(app_top_block, "USRP2 FFT", nstatus=1) + app = stdgui2.stdapp(app_top_block, "SHD FFT", nstatus=1) app.MainLoop() if __name__ == '__main__': diff --git a/gr-shd/apps/shd_rx_cfile.py b/gr-shd/apps/shd_rx_cfile.py new file mode 100755 index 000000000..007bc809f --- /dev/null +++ b/gr-shd/apps/shd_rx_cfile.py @@ -0,0 +1,152 @@ +#!/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. +# + +""" +Read samples from a SHD device and write to file formatted as binary +outputs single precision complex float values or complex short values +(interleaved 16 bit signed short integers). +""" + +from gnuradio import gr, eng_notation +from gnuradio import shd +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import sys + +n2s = eng_notation.num_to_str + +class rx_cfile_block(gr.top_block): + + def __init__(self, options, filename): + gr.top_block.__init__(self) + + # Create a SHD device source + if options.output_shorts: + self._src = shd.smini_source(device_addr=options.address, + io_type=shd.io_type.COMPLEX_INT16, + num_channels=1) + self._sink = gr.file_sink(gr.sizeof_short*2, filename) + else: + self._src = shd.smini_source(device_addr=options.address, + io_type=shd.io_type.COMPLEX_FLOAT32, + num_channels=1) + self._sink = gr.file_sink(gr.sizeof_gr_complex, filename) + + # Set receiver sample rate + self._src.set_samp_rate(options.samp_rate) + + # Set receive daughterboard gain + if options.gain is None: + g = self._src.get_gain_range() + options.gain = float(g.start()+g.stop())/2 + print "Using mid-point gain of", \ + options.gain, "(", g.start(), "-", g.stop(), ")" + self._src.set_gain(options.gain) + + # Set the antenna + if(options.antenna): + self._src.set_antenna(options.antenna, 0) + + # Set frequency (tune request takes lo_offset) + if(options.lo_offset is not None): + treq = shd.tune_request(options.freq, options.lo_offset) + else: + treq = shd.tune_request(options.freq) + tr = self._src.set_center_freq(treq) + if tr == None: + sys.stderr.write('Failed to set center frequency\n') + raise SystemExit, 1 + + # Create head block if needed and wire it up + if options.nsamples is None: + self.connect(self._src, self._sink) + else: + if options.output_shorts: + self._head = gr.head(gr.sizeof_short*2, + int(options.nsamples)) + else: + self._head = gr.head(gr.sizeof_gr_complex, + int(options.nsamples)) + + self.connect(self._src, self._head, self._sink) + + input_rate = self._src.get_samp_rate() + + if options.verbose: + print "Address:", options.address + print "Rx gain:", options.gain + print "Rx baseband frequency:", n2s(tr.actual_rf_freq) + print "Rx DDC frequency:", n2s(tr.actual_dsp_freq) + print "Rx Sample Rate:", n2s(input_rate) + if options.nsamples is None: + print "Receiving samples until Ctrl-C" + else: + print "Receving", n2s(options.nsamples), "samples" + if options.output_shorts: + print "Writing 16-bit complex shorts" + else: + print "Writing 32-bit complex floats" + print "Output filename:", filename + +def get_options(): + usage="%prog: [options] output_filename" + parser = OptionParser(option_class=eng_option, usage=usage) + parser.add_option("-a", "--address", type="string", default="type=xmini", + help="Address of SHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate (bandwidth) [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + parser.add_option( "-s","--output-shorts", action="store_true", default=False, + help="output interleaved shorts instead of complex floats") + parser.add_option("-N", "--nsamples", type="eng_float", default=None, + help="number of samples to collect [default=+inf]") + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="verbose output") + parser.add_option("", "--lo-offset", type="eng_float", default=None, + help="set daughterboard LO offset to OFFSET [default=hw default]") + + (options, args) = parser.parse_args () + if len(args) != 1: + parser.print_help() + raise SystemExit, 1 + + if options.freq is None: + parser.print_help() + sys.stderr.write('You must specify the frequency with -f FREQ\n'); + raise SystemExit, 1 + + return (options, args[0]) + + +if __name__ == '__main__': + (options, filename) = get_options() + tb = rx_cfile_block(options, filename) + + try: + tb.run() + except KeyboardInterrupt: + pass diff --git a/gr-shd/apps/shd_siggen.py b/gr-shd/apps/shd_siggen.py new file mode 100755 index 000000000..112eeea15 --- /dev/null +++ b/gr-shd/apps/shd_siggen.py @@ -0,0 +1,120 @@ +#!/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. +# + +""" +Read samples from a SHD device and write to file formatted as binary +outputs single precision complex float values or complex short values +(interleaved 16 bit signed short integers). +""" + +from gnuradio import gr, eng_notation +from gnuradio import shd +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import sys + +n2s = eng_notation.num_to_str + +class shd_siggen(gr.top_block): + + def __init__(self, options): + gr.top_block.__init__(self) + + self._src = gr.sig_source_c(options.samp_rate, gr.GR_SIN_WAVE, + 200, 1) + + self._snk = shd.smini_sink(device_addr=options.address, + io_type=shd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + # Set receiver sample rate + self._snk.set_samp_rate(options.samp_rate) + + # Set receive daughterboard gain + if options.gain is None: + g = self._snk.get_gain_range() + options.gain = float(g.start()+g.stop())/2 + print "Using mid-point gain of", \ + options.gain, "(", g.start(), "-", g.stop(), ")" + self._snk.set_gain(options.gain) + + # Set the antenna + if(options.antenna): + self._snk.set_antenna(options.antenna, 0) + + # Set frequency (tune request takes lo_offset) + if(options.lo_offset is not None): + treq = shd.tune_request(options.freq, options.lo_offset) + else: + treq = shd.tune_request(options.freq) + tr = self._snk.set_center_freq(treq) + if tr == None: + sys.stderr.write('Failed to set center frequency\n') + raise SystemExit, 1 + + # Create head block if needed and wire it up + self.connect(self._src, self._snk) + input_rate = self._snk.get_samp_rate() + + if options.verbose: + print "Address:", options.address + print "Rx gain:", options.gain + print "Rx baseband frequency:", n2s(tr.actual_rf_freq) + print "Rx DDC frequency:", n2s(tr.actual_dsp_freq) + print "Rx Sample Rate:", n2s(input_rate) + +def get_options(): + usage="%prog: [options]" + parser = OptionParser(option_class=eng_option, usage=usage) + parser.add_option("-a", "--address", type="string", default="type=xmini", + help="Address of SHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate (bandwidth) [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + parser.add_option("-v", "--verbose", action="store_true", default=False, + help="verbose output") + parser.add_option("", "--lo-offset", type="eng_float", default=None, + help="set daughterboard LO offset to OFFSET [default=hw default]") + + (options, args) = parser.parse_args () + + if options.freq is None: + parser.print_help() + sys.stderr.write('You must specify the frequency with -f FREQ\n'); + raise SystemExit, 1 + + return (options) + + +if __name__ == '__main__': + options = get_options() + tb = shd_siggen(options) + + try: + tb.run() + except KeyboardInterrupt: + pass diff --git a/gr-shd/gnuradio-shd.pc.in b/gr-shd/gnuradio-shd.pc.in new file mode 100644 index 000000000..cff0dcf00 --- /dev/null +++ b/gr-shd/gnuradio-shd.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gnuradio-shd +Description: GNU Radio blocks for the Symplex Hardware Driver (SHD) +Requires: gnuradio-core +Version: @LIBVER@ +Libs: -L${libdir} -lgnuradio-shd +Cflags: -I${includedir} diff --git a/gr-shd/grc/.gitignore b/gr-shd/grc/.gitignore new file mode 100644 index 000000000..2c261c55b --- /dev/null +++ b/gr-shd/grc/.gitignore @@ -0,0 +1,3 @@ +/shd_smini*.xml +/Makefile +/Makefile.in diff --git a/gr-shd/grc/Makefile.am b/gr-shd/grc/Makefile.am new file mode 100644 index 000000000..c44ad1b4e --- /dev/null +++ b/gr-shd/grc/Makefile.am @@ -0,0 +1,43 @@ +# +# 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. +# + +include $(top_srcdir)/Makefile.common + +grcblocksdir = $(grc_blocksdir) + +generated_shd_smini_blocks = \ + shd_smini_source.xml \ + shd_smini_sink.xml + +BUILT_SOURCES += $(generated_shd_smini_blocks) + +dist_grcblocks_DATA = \ + shd_block_tree.xml \ + $(BUILT_SOURCES) + +######################################################################## +# Rules for generating the source and sink xml wrappers +######################################################################## +EXTRA_DIST += $(srcdir)/gen_shd_smini_blocks.py + +$(generated_shd_smini_blocks): $(srcdir)/gen_shd_smini_blocks.py + @echo "generating $@..." + $(PYTHON) $< $@ diff --git a/gr-shd/grc/gen_shd_smini_blocks.py b/gr-shd/grc/gen_shd_smini_blocks.py new file mode 100644 index 000000000..652b6cf51 --- /dev/null +++ b/gr-shd/grc/gen_shd_smini_blocks.py @@ -0,0 +1,297 @@ +""" +Copyright 2011 Free Software Foundation, Inc. + +This file is part of GNU Radio + +GNU Radio Companion is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +GNU Radio Companion is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +""" + +MAIN_TMPL = """\ +<?xml version="1.0"?> +<block> + <name>SHD: SMINI $sourk.title()</name> + <key>shd_smini_$(sourk)</key> + <import>from gnuradio import shd</import> + <make>shd.smini_$(sourk)( + device_addr=\$dev_addr, + io_type=shd.io_type.\$type.type, + num_channels=\$nchan, +) +\#if \$clock_rate() +self.\$(id).set_clock_rate(\$clock_rate, shd.ALL_MBOARDS) +\#end if +#for $m in range($max_mboards) +######################################################################## +\#if \$num_mboards() > $m and \$ref_source$(m)() == 'external' +self.\$(id).set_clock_config(shd.clock_config.external(), $m) +\#end if +######################################################################## +\#if \$num_mboards() > $m and \$ref_source$(m)() == 'internal' +self.\$(id).set_clock_config(shd.clock_config.internal(), $m) +\#end if +######################################################################## +\#if \$num_mboards() > $m and \$ref_source$(m)() == 'mimo' +_config = shd.clock_config() +_config.ref_source = shd.clock_config.REF_MIMO +_config.pps_source = shd.clock_config.PPS_MIMO +self.\$(id).set_clock_config(_config, $m) +\#end if +######################################################################## +\#if \$num_mboards() > $m and \$sd_spec$(m)() +self.\$(id).set_subdev_spec(\$sd_spec$(m), $m) +\#end if +######################################################################## +#end for +\#if \$sync() +self.\$(id).set_time_unknown_pps(shd.time_spec()) +\#end if +self.\$(id).set_samp_rate(\$samp_rate) +#for $n in range($max_nchan) +\#if \$nchan() > $n +self.\$(id).set_center_freq(\$center_freq$(n), $n) +self.\$(id).set_gain(\$gain$(n), $n) +\#end if +#end for +</make> + <callback>set_samp_rate(\$samp_rate)</callback> + #for $n in range($max_nchan) + <callback>set_center_freq(\$center_freq$(n), $n)</callback> + <callback>set_gain(\$gain$(n), $n)</callback> + #end for + <param> + <name>$(direction.title())put Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>type:COMPLEX_FLOAT32</opt> + <opt>vlen:1</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>type:COMPLEX_INT16</opt> + <opt>vlen:2</opt> + </option> + </param> + <param> + <name>Device Addr</name> + <key>dev_addr</key> + <value></value> + <type>string</type> + <hide> + \#if \$dev_addr() + none + \#else + part + \#end if + </hide> + </param> + <param> + <name>Sync</name> + <key>sync</key> + <value></value> + <type>enum</type> + <hide>\#if \$sync() then 'none' else 'part'#</hide> + <option> + <name>unknown PPS</name> + <key>sync</key> + </option> + <option> + <name>don't sync</name> + <key></key> + </option> + </param> + <param> + <name>Clock Rate (Hz)</name> + <key>clock_rate</key> + <value>0.0</value> + <type>real</type> + <hide>\#if \$clock_rate() then 'none' else 'part'#</hide> + <option> + <name>Default</name> + <key>0.0</key> + </option> + </param> + <param> + <name>Num Mboards</name> + <key>num_mboards</key> + <value>1</value> + <type>int</type> + <hide>part</hide> + #for $m in range(1, $max_mboards+1) + <option> + <name>$(m)</name> + <key>$m</key> + </option> + #end for + </param> + #for $m in range($max_mboards) + <param> + <name>Mb$(m): Ref Source</name> + <key>ref_source$(m)</key> + <value></value> + <type>enum</type> + <hide> + \#if not \$num_mboards() > $m + all + \#elif \$ref_source$(m)() + none + \#else + part + \#end if + </hide> + <option><name>Default</name><key></key></option> + <option><name>Internal</name><key>internal</key></option> + <option><name>External</name><key>external</key></option> + <option><name>MIMO Cable</name><key>mimo</key></option> + </param> + <param> + <name>Mb$(m): Subdev Spec</name> + <key>sd_spec$(m)</key> + <value></value> + <type>string</type> + <hide> + \#if not \$num_mboards() > $m + all + \#elif \$sd_spec$(m)() + none + \#else + part + \#end if + </hide> + </param> + #end for + <param> + <name>Num Channels</name> + <key>nchan</key> + <value>1</value> + <type>int</type> + #for $n in range(1, $max_nchan+1) + <option> + <name>$(n)</name> + <key>$n</key> + </option> + #end for + </param> + <param> + <name>Samp Rate (Sps)</name> + <key>samp_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + $params + <check>$max_nchan >= \$nchan</check> + <check>\$nchan > 0</check> + <check>$max_mboards >= \$num_mboards</check> + <check>\$num_mboards > 0</check> + <check>\$nchan >= \$num_mboards</check> + <$sourk> + <name>$direction</name> + <type>\$type</type> + <vlen>\$type.vlen</vlen> + <nports>\$nchan</nports> + </$sourk> + <doc> +The SHD SMINI $sourk.title() Block: + +Device Address: +The device address is a delimited string used to locate SHD devices on your system. \\ +If left blank, the first SHD device found will be used. \\ +Use the device address to specify a specific device or list of devices. +SMINI1 Example: serial=12345678 +SMINI2 Example: type=xmini + +Num Motherboards: +Selects the number of SMINI motherboards in this device configuration. + +Reference Source: +Where the motherboard should sync its time and clock references. +If source and sink blocks reference the same device, +it is only necessary to set the reference source on one of the blocks. + +Subdevice specification: +Each motherboard should have its own subdevice specification \\ +and all subdevice specifications should be the same length. \\ +Select the subdevice or subdevices for each channel using a markup string. \\ +The markup string consists of a list of dboard_slot:subdev_name pairs (one pair per channel). \\ +If left blank, the SHD will try to select the first subdevice on your system. \\ +See the application notes for further details. +Single channel example: :AB +Dual channel example: :A :B + +Num Channels: +Selects the total number of channels in this multi-SMINI configuration. +Ex: 4 motherboards with 2 channels per board = 8 channels total + +Sample rate: +The sample rate is the number of samples per second input by this block. \\ +The SHD device driver will try its best to match the requested sample rate. \\ +If the requested rate is not possible, the SHD block will print an error at runtime. + +Center frequency: +The center frequency is the overall frequency of the RF chain. \\ +For greater control of how the SHD tunes elements in the RF chain, \\ +pass a tune_request object rather than a simple target frequency. +Tuning with an LO offset example: shd.tune_request(freq, lo_off) + + </doc> +</block> +""" + +PARAMS_TMPL = """ + <param> + <name>Ch$(n): Center Freq (Hz)</name> + <key>center_freq$(n)</key> + <value>0</value> + <type>real</type> + <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide> + </param> + <param> + <name>Ch$(n): Gain (dB)</name> + <key>gain$(n)</key> + <value>0</value> + <type>real</type> + <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide> + </param> +""" + +def parse_tmpl(_tmpl, **kwargs): + from Cheetah import Template + return str(Template.Template(_tmpl, kwargs)) + +max_num_mboards = 8 +max_num_channels = max_num_mboards*4 + +if __name__ == '__main__': + import sys + for file in sys.argv[1:]: + if 'source' in file: + sourk = 'source' + direction = 'out' + elif 'sink' in file: + sourk = 'sink' + direction = 'in' + else: raise Exception, 'is %s a source or sink?'%file + + params = ''.join([parse_tmpl(PARAMS_TMPL, n=n) for n in range(max_num_channels)]) + open(file, 'w').write(parse_tmpl(MAIN_TMPL, + max_nchan=max_num_channels, + max_mboards=max_num_mboards, + params=params, + sourk=sourk, + direction=direction, + )) diff --git a/gr-shd/grc/shd_block_tree.xml b/gr-shd/grc/shd_block_tree.xml new file mode 100644 index 000000000..5d9786f67 --- /dev/null +++ b/gr-shd/grc/shd_block_tree.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Block Tree for shd blocks. +################################################### + --> +<cat> + <name></name> <!-- Blank for Root Name --> + <cat> + <name>SHD</name> + <block>shd_smini_source</block> + <block>shd_smini_sink</block> + </cat> +</cat> diff --git a/gnuradio-examples/python/apps/.gitignore b/gr-shd/include/.gitignore index b336cc7ce..b336cc7ce 100644 --- a/gnuradio-examples/python/apps/.gitignore +++ b/gr-shd/include/.gitignore diff --git a/gnuradio-examples/python/apps/Makefile.am b/gr-shd/include/Makefile.am index 50fe75151..2cb1597df 100644 --- a/gnuradio-examples/python/apps/Makefile.am +++ b/gr-shd/include/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2006 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -17,10 +17,11 @@ # along with GNU Radio; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, # Boston, MA 02110-1301, USA. -# +# include $(top_srcdir)/Makefile.common -SUBDIRS = hf_explorer hf_radio -EXTRA_DIST += README - +grinclude_HEADERS = \ + gr_shd_api.h \ + gr_shd_smini_source.h \ + gr_shd_smini_sink.h
\ No newline at end of file diff --git a/gr-shd/include/gr_shd_api.h b/gr-shd/include/gr_shd_api.h new file mode 100644 index 000000000..e6773c3f3 --- /dev/null +++ b/gr-shd/include/gr_shd_api.h @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#ifndef INCLUDED_GR_SHD_API_H +#define INCLUDED_GR_SHD_API_H + +#include <shd/config.hpp> + +#ifdef gnuradio_shd_EXPORTS +# define GR_SHD_API SHD_EXPORT +#else +# define GR_SHD_API SHD_IMPORT +#endif + +#endif /* INCLUDED_GR_SHD_API_H */ diff --git a/gr-shd/include/gr_shd_smini_sink.h b/gr-shd/include/gr_shd_smini_sink.h new file mode 100644 index 000000000..938958687 --- /dev/null +++ b/gr-shd/include/gr_shd_smini_sink.h @@ -0,0 +1,282 @@ +/* + * 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. + */ + +#ifndef INCLUDED_GR_SHD_SMINI_SINK_H +#define INCLUDED_GR_SHD_SMINI_SINK_H + +#include <gr_shd_api.h> +#include <gr_sync_block.h> +#include <shd/xmini/multi_xmini.hpp> + +class shd_smini_sink; + +GR_SHD_API boost::shared_ptr<shd_smini_sink> shd_make_smini_sink( + const shd::device_addr_t &device_addr, + const shd::io_type_t &io_type, + size_t num_channels +); + +class GR_SHD_API shd_smini_sink : virtual public gr_sync_block +{ + public: + + /*! + * Set the subdevice specification. + * \param spec the subdev spec markup string + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_subdev_spec(const std::string &spec, size_t mboard = 0) = 0; + + /*! + * Set the sample rate for the smini device. + * \param rate a new rate in Sps + */ + virtual void set_samp_rate(double rate) = 0; + + /*! + * Get the sample rate for the smini device. + * This is the actual sample rate and may differ from the rate set. + * \return the actual rate in Sps + */ + virtual double get_samp_rate(void) = 0; + + /*! + * Tune the smini device to the desired center frequency. + * \param tune_request the tune request instructions + * \param chan the channel index 0 to N-1 + * \return a tune result with the actual frequencies + */ + virtual shd::tune_result_t set_center_freq( + const shd::tune_request_t tune_request, size_t chan = 0 + ) = 0; + + /*! + * Tune the smini device to the desired center frequency. + * This is a wrapper around set center freq so that in this case, + * the user can pass a single frequency in the call through swig. + * \param freq the desired frequency in Hz + * \param chan the channel index 0 to N-1 + * \return a tune result with the actual frequencies + */ + shd::tune_result_t set_center_freq(double freq, size_t chan = 0){ + return set_center_freq(shd::tune_request_t(freq), chan); + } + + /*! + * Get the center frequency. + * \param chan the channel index 0 to N-1 + * \return the frequency in Hz + */ + virtual double get_center_freq(size_t chan = 0) = 0; + + /*! + * Get the tunable frequency range. + * \param chan the channel index 0 to N-1 + * \return the frequency range in Hz + */ + virtual shd::freq_range_t get_freq_range(size_t chan = 0) = 0; + + /*! + * Set the gain for the dboard. + * \param gain the gain in dB + * \param chan the channel index 0 to N-1 + */ + virtual void set_gain(double gain, size_t chan = 0) = 0; + + /*! + * Set the named gain on the dboard. + * \param gain the gain in dB + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + */ + virtual void set_gain(double gain, const std::string &name, + size_t chan = 0) = 0; + + /*! + * Get the actual dboard gain setting. + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain(size_t chan = 0) = 0; + + /*! + * Get the actual dboard gain setting of named stage. + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain(const std::string &name, + size_t chan = 0) = 0; + + /*! + * Get the actual dboard gain setting of named stage. + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual std::vector<std::string> get_gain_names(size_t chan = 0) = 0; + + /*! + * Get the settable gain range. + * \param chan the channel index 0 to N-1 + * \return the gain range in dB + */ + virtual shd::gain_range_t get_gain_range(size_t chan = 0) = 0; + + /*! + * Get the settable gain range. + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the gain range in dB + */ + virtual shd::gain_range_t get_gain_range(const std::string &name, + size_t chan = 0) = 0; + + /*! + * Set the antenna to use. + * \param ant the antenna string + * \param chan the channel index 0 to N-1 + */ + virtual void set_antenna(const std::string &ant, + size_t chan = 0) = 0; + + /*! + * Get the antenna in use. + * \param chan the channel index 0 to N-1 + * \return the antenna string + */ + virtual std::string get_antenna(size_t chan = 0) = 0; + + /*! + * Get a list of possible antennas. + * \param chan the channel index 0 to N-1 + * \return a vector of antenna strings + */ + virtual std::vector<std::string> get_antennas(size_t chan = 0) = 0; + + /*! + * Set the subdevice bandpass filter. + * \param chan the channel index 0 to N-1 + * \param bandwidth the filter bandwidth in Hz + */ + virtual void set_bandwidth(double bandwidth, size_t chan = 0) = 0; + + /*! + * Get a daughterboard sensor value. + * \param name the name of the sensor + * \param chan the channel index 0 to N-1 + * \return a sensor value object + */ + virtual shd::sensor_value_t get_dboard_sensor(const std::string &name, + size_t chan = 0) = 0; + + /*! + * Get a list of possible daughterboard sensor names. + * \param chan the channel index 0 to N-1 + * \return a vector of sensor names + */ + virtual std::vector<std::string> get_dboard_sensor_names(size_t chan = 0) = 0; + + /*! + * Get a motherboard sensor value. + * \param name the name of the sensor + * \param mboard the motherboard index 0 to M-1 + * \return a sensor value object + */ + virtual shd::sensor_value_t get_mboard_sensor(const std::string &name, + size_t mboard = 0) = 0; + + /*! + * Get a list of possible motherboard sensor names. + * \param mboard the motherboard index 0 to M-1 + * \return a vector of sensor names + */ + virtual std::vector<std::string> get_mboard_sensor_names(size_t mboard = 0) = 0; + + /*! + * Set the clock configuration. + * \param clock_config the new configuration + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_clock_config(const shd::clock_config_t &clock_config, + size_t mboard = 0) = 0; + + /*! + * Get the master clock rate. + * \param mboard the motherboard index 0 to M-1 + * \return the clock rate in Hz + */ + virtual double get_clock_rate(size_t mboard = 0) = 0; + + /*! + * Set the master clock rate. + * \param rate the new rate in Hz + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_clock_rate(double rate, size_t mboard = 0) = 0; + + /*! + * Get the current time registers. + * \param mboard the motherboard index 0 to M-1 + * \return the current smini time + */ + virtual shd::time_spec_t get_time_now(size_t mboard = 0) = 0; + + /*! + * Get the time when the last pps pulse occured. + * \param mboard the motherboard index 0 to M-1 + * \return the current smini time + */ + virtual shd::time_spec_t get_time_last_pps(size_t mboard = 0) = 0; + + /*! + * Sets the time registers immediately. + * \param time_spec the new time + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_time_now(const shd::time_spec_t &time_spec, + size_t mboard = 0) = 0; + + /*! + * Set the time registers at the next pps. + * \param time_spec the new time + */ + virtual void set_time_next_pps(const shd::time_spec_t &time_spec) = 0; + + /*! + * Sync the time registers with an unknown pps edge. + * \param time_spec the new time + */ + virtual void set_time_unknown_pps(const shd::time_spec_t &time_spec) = 0; + + /*! + * Get access to the underlying shd dboard iface object. + * \return the dboard_iface object + */ + virtual shd::xmini::dboard_iface::sptr get_dboard_iface(size_t chan = 0) = 0; + + /*! + * Get access to the underlying shd device object. + * \return the multi smini device object + */ + virtual shd::xmini::multi_xmini::sptr get_device(void) = 0; +}; + +#endif /* INCLUDED_GR_SHD_SMINI_SINK_H */ diff --git a/gr-shd/include/gr_shd_smini_source.h b/gr-shd/include/gr_shd_smini_source.h new file mode 100644 index 000000000..3e3dbf427 --- /dev/null +++ b/gr-shd/include/gr_shd_smini_source.h @@ -0,0 +1,286 @@ +/* + * 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. + */ + +#ifndef INCLUDED_GR_SHD_SMINI_SOURCE_H +#define INCLUDED_GR_SHD_SMINI_SOURCE_H + +#include <gr_shd_api.h> +#include <gr_sync_block.h> +#include <shd/xmini/multi_xmini.hpp> + +class shd_smini_source; + +GR_SHD_API boost::shared_ptr<shd_smini_source> shd_make_smini_source( + const shd::device_addr_t &device_addr, + const shd::io_type_t &io_type, + size_t num_channels +); + +class GR_SHD_API shd_smini_source : virtual public gr_sync_block +{ + public: + + /*! + * Set the subdevice specification. + * \param spec the subdev spec markup string + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_subdev_spec(const std::string &spec, + size_t mboard = 0) = 0; + + /*! + * Set the sample rate for the smini device. + * \param rate a new rate in Sps + */ + virtual void set_samp_rate(double rate) = 0; + + /*! + * Get the sample rate for the smini device. + * This is the actual sample rate and may differ from the rate set. + * \return the actual rate in Sps + */ + virtual double get_samp_rate(void) = 0; + + /*! + * Tune the smini device to the desired center frequency. + * \param tune_request the tune request instructions + * \param chan the channel index 0 to N-1 + * \return a tune result with the actual frequencies + */ + virtual shd::tune_result_t set_center_freq( + const shd::tune_request_t tune_request, + size_t chan = 0 + ) = 0; + + /*! + * Tune the smini device to the desired center frequency. + * This is a wrapper around set center freq so that in this case, + * the user can pass a single frequency in the call through swig. + * \param freq the desired frequency in Hz + * \param chan the channel index 0 to N-1 + * \return a tune result with the actual frequencies + */ + shd::tune_result_t set_center_freq(double freq, size_t chan = 0){ + return set_center_freq(shd::tune_request_t(freq), chan); + } + + /*! + * Get the center frequency. + * \param chan the channel index 0 to N-1 + * \return the frequency in Hz + */ + virtual double get_center_freq(size_t chan = 0) = 0; + + /*! + * Get the tunable frequency range. + * \param chan the channel index 0 to N-1 + * \return the frequency range in Hz + */ + virtual shd::freq_range_t get_freq_range(size_t chan = 0) = 0; + + /*! + * Set the gain for the dboard. + * \param gain the gain in dB + * \param chan the channel index 0 to N-1 + */ + virtual void set_gain(double gain, size_t chan = 0) = 0; + + /*! + * Set the named gain on the dboard. + * \param gain the gain in dB + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + */ + virtual void set_gain(double gain, const std::string &name, + size_t chan = 0) = 0; + + /*! + * Get the actual dboard gain setting. + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain(size_t chan = 0) = 0; + + /*! + * Get the actual dboard gain setting of named stage. + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain(const std::string &name, + size_t chan = 0) = 0; + + /*! + * Get the actual dboard gain setting of named stage. + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual std::vector<std::string> get_gain_names(size_t chan = 0) = 0; + + /*! + * Get the settable gain range. + * \param chan the channel index 0 to N-1 + * \return the gain range in dB + */ + virtual shd::gain_range_t get_gain_range(size_t chan = 0) = 0; + + /*! + * Get the settable gain range. + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the gain range in dB + */ + virtual shd::gain_range_t get_gain_range(const std::string &name, + size_t chan = 0) = 0; + + /*! + * Set the antenna to use. + * \param ant the antenna string + * \param chan the channel index 0 to N-1 + */ + virtual void set_antenna(const std::string &ant, + size_t chan = 0) = 0; + + /*! + * Get the antenna in use. + * \param chan the channel index 0 to N-1 + * \return the antenna string + */ + virtual std::string get_antenna(size_t chan = 0) = 0; + + /*! + * Get a list of possible antennas. + * \param chan the channel index 0 to N-1 + * \return a vector of antenna strings + */ + virtual std::vector<std::string> get_antennas(size_t chan = 0) = 0; + + /*! + * Set the subdevice bandpass filter. + * \param bandwidth the filter bandwidth in Hz + * \param chan the channel index 0 to N-1 + */ + virtual void set_bandwidth(double bandwidth, + size_t chan = 0) = 0; + + /*! + * Get a daughterboard sensor value. + * \param name the name of the sensor + * \param chan the channel index 0 to N-1 + * \return a sensor value object + */ + virtual shd::sensor_value_t get_dboard_sensor(const std::string &name, + size_t chan = 0) = 0; + + /*! + * Get a list of possible daughterboard sensor names. + * \param chan the channel index 0 to N-1 + * \return a vector of sensor names + */ + virtual std::vector<std::string> get_dboard_sensor_names(size_t chan = 0) = 0; + + /*! + * Get a motherboard sensor value. + * \param name the name of the sensor + * \param mboard the motherboard index 0 to M-1 + * \return a sensor value object + */ + virtual shd::sensor_value_t get_mboard_sensor(const std::string &name, + size_t mboard = 0) = 0; + + /*! + * Get a list of possible motherboard sensor names. + * \param mboard the motherboard index 0 to M-1 + * \return a vector of sensor names + */ + virtual std::vector<std::string> get_mboard_sensor_names(size_t mboard = 0) = 0; + + /*! + * Set the clock configuration. + * \param clock_config the new configuration + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_clock_config(const shd::clock_config_t &clock_config, + size_t mboard = 0) = 0; + + /*! + * Get the master clock rate. + * \param mboard the motherboard index 0 to M-1 + * \return the clock rate in Hz + */ + virtual double get_clock_rate(size_t mboard = 0) = 0; + + /*! + * Set the master clock rate. + * \param rate the new rate in Hz + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_clock_rate(double rate, + size_t mboard = 0) = 0; + + /*! + * Get the current time registers. + * \param mboard the motherboard index 0 to M-1 + * \return the current smini time + */ + virtual shd::time_spec_t get_time_now(size_t mboard = 0) = 0; + + /*! + * Get the time when the last pps pulse occured. + * \param mboard the motherboard index 0 to M-1 + * \return the current smini time + */ + virtual shd::time_spec_t get_time_last_pps(size_t mboard = 0) = 0; + + /*! + * Sets the time registers immediately. + * \param time_spec the new time + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_time_now(const shd::time_spec_t &time_spec, + size_t mboard = 0) = 0; + + /*! + * Set the time registers at the next pps. + * \param time_spec the new time + */ + virtual void set_time_next_pps(const shd::time_spec_t &time_spec) = 0; + + /*! + * Sync the time registers with an unknown pps edge. + * \param time_spec the new time + */ + virtual void set_time_unknown_pps(const shd::time_spec_t &time_spec) = 0; + + /*! + * Get access to the underlying shd dboard iface object. + * \return the dboard_iface object + */ + virtual shd::xmini::dboard_iface::sptr get_dboard_iface(size_t chan = 0) = 0; + + /*! + * Get access to the underlying shd device object. + * \return the multi smini device object + */ + virtual shd::xmini::multi_xmini::sptr get_device(void) = 0; +}; + +#endif /* INCLUDED_GR_SHD_SMINI_SOURCE_H */ diff --git a/gnuradio-examples/python/digital-bert/.gitignore b/gr-shd/lib/.gitignore index b336cc7ce..b336cc7ce 100644 --- a/gnuradio-examples/python/digital-bert/.gitignore +++ b/gr-shd/lib/.gitignore diff --git a/gr-shd/lib/Makefile.am b/gr-shd/lib/Makefile.am new file mode 100644 index 000000000..7a887aebf --- /dev/null +++ b/gr-shd/lib/Makefile.am @@ -0,0 +1,42 @@ +# +# 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. +# + +include $(top_srcdir)/Makefile.common + +AM_CPPFLAGS = \ + $(STD_DEFINES_AND_INCLUDES) \ + $(WITH_INCLUDES) \ + $(SHD_CPPFLAGS) \ + -Dgnuradio_shd_EXPORTS + +lib_LTLIBRARIES = libgnuradio-shd.la + +libgnuradio_shd_la_SOURCES = \ + gr_shd_smini_source.cc \ + gr_shd_smini_sink.cc + +libgnuradio_shd_la_LIBADD = \ + $(GNURADIO_CORE_LA) \ + $(SHD_LIBS) + +libgnuradio_shd_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) + +noinst_HEADERS = diff --git a/gr-shd/lib/gr_shd_smini_sink.cc b/gr-shd/lib/gr_shd_smini_sink.cc new file mode 100644 index 000000000..c9fb222d0 --- /dev/null +++ b/gr-shd/lib/gr_shd_smini_sink.cc @@ -0,0 +1,276 @@ +/* + * 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. + */ + +#include <gr_shd_smini_sink.h> +#include <gr_io_signature.h> +#include <stdexcept> + +/********************************************************************* + * SHD Multi SMINI Sink Impl + ********************************************************************/ +class shd_smini_sink_impl : public shd_smini_sink +{ +public: + shd_smini_sink_impl(const shd::device_addr_t &device_addr, + const shd::io_type_t &io_type, + size_t num_channels): + gr_sync_block("gr shd smini sink", + gr_make_io_signature(num_channels, num_channels, io_type.size), + gr_make_io_signature(0, 0, 0)), + _type(io_type), + _nchan(num_channels), + _has_time_spec(_nchan > 1) + { + _dev = shd::xmini::multi_xmini::make(device_addr); + } + + void set_subdev_spec(const std::string &spec, + size_t mboard) + { + return _dev->set_tx_subdev_spec(spec, mboard); + } + + void set_samp_rate(double rate){ + _dev->set_tx_rate(rate); + _sample_rate = this->get_samp_rate(); + } + + double get_samp_rate(void){ + return _dev->get_tx_rate(); + } + + shd::tune_result_t set_center_freq( + const shd::tune_request_t tune_request, size_t chan) + { + return _dev->set_tx_freq(tune_request, chan); + } + + double get_center_freq(size_t chan) + { + return _dev->get_tx_freq(chan); + } + + shd::freq_range_t get_freq_range(size_t chan) + { + return _dev->get_tx_freq_range(chan); + } + + void set_gain(double gain, size_t chan) + { + return _dev->set_tx_gain(gain, chan); + } + + void set_gain(double gain, const std::string &name, + size_t chan) + { + return _dev->set_tx_gain(gain, name, chan); + } + + double get_gain(size_t chan){ + return _dev->get_tx_gain(chan); + } + + double get_gain(const std::string &name, size_t chan) + { + return _dev->get_tx_gain(name, chan); + } + + std::vector<std::string> get_gain_names(size_t chan) + { + return _dev->get_tx_gain_names(chan); + } + + shd::gain_range_t get_gain_range(size_t chan) + { + return _dev->get_tx_gain_range(chan); + } + + shd::gain_range_t get_gain_range(const std::string &name, + size_t chan) + { + return _dev->get_tx_gain_range(name, chan); + } + + void set_antenna(const std::string &ant, size_t chan) + { + return _dev->set_tx_antenna(ant, chan); + } + + std::string get_antenna(size_t chan) + { + return _dev->get_tx_antenna(chan); + } + + std::vector<std::string> get_antennas(size_t chan) + { + return _dev->get_tx_antennas(chan); + } + + void set_bandwidth(double bandwidth, size_t chan) + { + return _dev->set_tx_bandwidth(bandwidth, chan); + } + + shd::sensor_value_t get_dboard_sensor(const std::string &name, + size_t chan) + { + return _dev->get_tx_sensor(name, chan); + } + + std::vector<std::string> get_dboard_sensor_names(size_t chan) + { + return _dev->get_tx_sensor_names(chan); + } + + shd::sensor_value_t get_mboard_sensor(const std::string &name, + size_t mboard) + { + return _dev->get_mboard_sensor(name, mboard); + } + + std::vector<std::string> get_mboard_sensor_names(size_t mboard) + { + return _dev->get_mboard_sensor_names(mboard); + } + + void set_clock_config(const shd::clock_config_t &clock_config, + size_t mboard) + { + return _dev->set_clock_config(clock_config, mboard); + } + + double get_clock_rate(size_t mboard) + { + return _dev->get_master_clock_rate(mboard); + } + + void set_clock_rate(double rate, size_t mboard) + { + return _dev->set_master_clock_rate(rate, mboard); + } + + shd::time_spec_t get_time_now(size_t mboard = 0) + { + return _dev->get_time_now(mboard); + } + + shd::time_spec_t get_time_last_pps(size_t mboard) + { + return _dev->get_time_last_pps(mboard); + } + + void set_time_now(const shd::time_spec_t &time_spec, + size_t mboard) + { + return _dev->set_time_now(time_spec, mboard); + } + + void set_time_next_pps(const shd::time_spec_t &time_spec) + { + return _dev->set_time_next_pps(time_spec); + } + + void set_time_unknown_pps(const shd::time_spec_t &time_spec) + { + return _dev->set_time_unknown_pps(time_spec); + } + + shd::xmini::dboard_iface::sptr get_dboard_iface(size_t chan) + { + return _dev->get_tx_dboard_iface(chan); + } + + shd::xmini::multi_xmini::sptr get_device(void) + { + return _dev; + } + + /******************************************************************* + * Work + ******************************************************************/ + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + //send a mid-burst packet with time spec + _metadata.start_of_burst = false; + _metadata.end_of_burst = false; + _metadata.has_time_spec = _has_time_spec; + + size_t num_sent = _dev->get_device()->send( + input_items, noutput_items, _metadata, + _type, shd::device::SEND_MODE_FULL_BUFF, 1.0); + + //increment the timespec by the number of samples sent + _metadata.time_spec += shd::time_spec_t(0, num_sent, _sample_rate); + return num_sent; + } + + //Send an empty start-of-burst packet to begin streaming. + //Set at a time in the near future to avoid late packets. + bool start(void) + { + _metadata.start_of_burst = true; + _metadata.end_of_burst = false; + _metadata.has_time_spec = _has_time_spec; + _metadata.time_spec = get_time_now() + shd::time_spec_t(0.01); + + _dev->get_device()->send( + gr_vector_const_void_star(_nchan), 0, _metadata, + _type, shd::device::SEND_MODE_ONE_PACKET, 1.0); + return true; + } + + //Send an empty end-of-burst packet to end streaming. + //Ending the burst avoids an underflow error on stop. + bool stop(void) + { + _metadata.start_of_burst = false; + _metadata.end_of_burst = true; + _metadata.has_time_spec = false; + + _dev->get_device()->send( + gr_vector_const_void_star(_nchan), 0, _metadata, + _type, shd::device::SEND_MODE_ONE_PACKET, 1.0); + return true; + } + +protected: + shd::xmini::multi_xmini::sptr _dev; + const shd::io_type_t _type; + size_t _nchan; + bool _has_time_spec; + shd::tx_metadata_t _metadata; + double _sample_rate; +}; + +/********************************************************************* + * Make SHD Multi SMINI Sink + ********************************************************************/ + +boost::shared_ptr<shd_smini_sink> shd_make_smini_sink( + const shd::device_addr_t &device_addr, + const shd::io_type_t &io_type, + size_t num_channels) +{ + return boost::shared_ptr<shd_smini_sink>( + new shd_smini_sink_impl(device_addr, io_type, num_channels)); +} diff --git a/gr-shd/lib/gr_shd_smini_source.cc b/gr-shd/lib/gr_shd_smini_source.cc new file mode 100644 index 000000000..caf98f311 --- /dev/null +++ b/gr-shd/lib/gr_shd_smini_source.cc @@ -0,0 +1,299 @@ +/* + * 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. + */ + +#include <gr_shd_smini_source.h> +#include <gr_io_signature.h> +#include <stdexcept> +#include <iostream> +#include <boost/format.hpp> + +/********************************************************************* + * SHD Multi S-MINI Source Impl + ********************************************************************/ +class shd_smini_source_impl : public shd_smini_source +{ +public: + shd_smini_source_impl( + const shd::device_addr_t &device_addr, + const shd::io_type_t &io_type, + size_t num_channels + ): + gr_sync_block( + "gr shd smini source", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(num_channels, num_channels, io_type.size) + ), + _type(io_type), + _nchan(num_channels), + _stream_now(_nchan == 1), + _tmp_buffs(_nchan) + { + _dev = shd::xmini::multi_xmini::make(device_addr); + } + + void set_subdev_spec(const std::string &spec, size_t mboard) + { + return _dev->set_rx_subdev_spec(spec, mboard); + } + + void set_samp_rate(double rate) + { + _dev->set_rx_rate(rate); + } + + double get_samp_rate(void) + { + return _dev->get_rx_rate(); + } + + shd::tune_result_t set_center_freq( + const shd::tune_request_t tune_request, size_t chan) + { + return _dev->set_rx_freq(tune_request, chan); + } + + double get_center_freq(size_t chan) + { + return _dev->get_rx_freq(chan); + } + + shd::freq_range_t get_freq_range(size_t chan) + { + return _dev->get_rx_freq_range(chan); + } + + void set_gain(double gain, size_t chan) + { + return _dev->set_rx_gain(gain, chan); + } + + void set_gain(double gain, const std::string &name, + size_t chan) + { + return _dev->set_rx_gain(gain, name, chan); + } + + double get_gain(size_t chan) + { + return _dev->get_rx_gain(chan); + } + + double get_gain(const std::string &name, size_t chan) + { + return _dev->get_rx_gain(name, chan); + } + + std::vector<std::string> get_gain_names(size_t chan) + { + return _dev->get_rx_gain_names(chan); + } + + shd::gain_range_t get_gain_range(size_t chan) + { + return _dev->get_rx_gain_range(chan); + } + + shd::gain_range_t get_gain_range(const std::string &name, + size_t chan) + { + return _dev->get_rx_gain_range(name, chan); + } + + void set_antenna(const std::string &ant, size_t chan) + { + return _dev->set_rx_antenna(ant, chan); + } + + std::string get_antenna(size_t chan) + { + return _dev->get_rx_antenna(chan); + } + + std::vector<std::string> get_antennas(size_t chan) + { + return _dev->get_rx_antennas(chan); + } + + void set_bandwidth(double bandwidth, size_t chan) + { + return _dev->set_rx_bandwidth(bandwidth, chan); + } + + shd::sensor_value_t get_dboard_sensor(const std::string &name, + size_t chan) + { + return _dev->get_rx_sensor(name, chan); + } + + std::vector<std::string> get_dboard_sensor_names(size_t chan) + { + return _dev->get_rx_sensor_names(chan); + } + + shd::sensor_value_t get_mboard_sensor(const std::string &name, + size_t mboard) + { + return _dev->get_mboard_sensor(name, mboard); + } + + std::vector<std::string> get_mboard_sensor_names(size_t mboard) + { + return _dev->get_mboard_sensor_names(mboard); + } + + void set_clock_config(const shd::clock_config_t &clock_config, + size_t mboard) + { + return _dev->set_clock_config(clock_config, mboard); + } + + double get_clock_rate(size_t mboard) + { + return _dev->get_master_clock_rate(mboard); + } + + void set_clock_rate(double rate, size_t mboard) + { + return _dev->set_master_clock_rate(rate, mboard); + } + + shd::time_spec_t get_time_now(size_t mboard = 0) + { + return _dev->get_time_now(mboard); + } + + shd::time_spec_t get_time_last_pps(size_t mboard) + { + return _dev->get_time_last_pps(mboard); + } + + void set_time_now(const shd::time_spec_t &time_spec, + size_t mboard) + { + return _dev->set_time_now(time_spec, mboard); + } + + void set_time_next_pps(const shd::time_spec_t &time_spec) + { + return _dev->set_time_next_pps(time_spec); + } + + void set_time_unknown_pps(const shd::time_spec_t &time_spec) + { + return _dev->set_time_unknown_pps(time_spec); + } + + shd::xmini::dboard_iface::sptr get_dboard_iface(size_t chan) + { + return _dev->get_rx_dboard_iface(chan); + } + + shd::xmini::multi_xmini::sptr get_device(void) + { + return _dev; + } + + /******************************************************************* + * Work + ******************************************************************/ + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + //In order to allow for low-latency: + //We receive all available packets without timeout. + //This call can timeout under regular operation... + size_t num_samps = _dev->get_device()->recv( + output_items, noutput_items, _metadata, + _type, shd::device::RECV_MODE_FULL_BUFF, 0.0); + + //If receive resulted in a timeout condition: + //We now receive a single packet with a large timeout. + if(_metadata.error_code == shd::rx_metadata_t::ERROR_CODE_TIMEOUT) { + num_samps = _dev->get_device()->recv( + output_items, noutput_items, _metadata, + _type, shd::device::RECV_MODE_ONE_PACKET, 1.0); + } + + //handle possible errors conditions + switch(_metadata.error_code) { + case shd::rx_metadata_t::ERROR_CODE_NONE: + //TODO insert tag for time stamp + break; + + case shd::rx_metadata_t::ERROR_CODE_TIMEOUT: + //Assume that the user called stop() on the flow graph. + //However, a timeout can occur under error conditions. + return WORK_DONE; + + case shd::rx_metadata_t::ERROR_CODE_OVERFLOW: + //ignore overflows and try work again + //TODO insert tag for overflow + return work(noutput_items, input_items, output_items); + + default: + std::cout << boost::format("SHD source block got error code 0x%x" + ) % _metadata.error_code << std::endl; + return num_samps; + } + + return num_samps; + } + + bool start(void) + { + //setup a stream command that starts streaming slightly in the future + static const double reasonable_delay = 0.1; //order of magnitude over RTT + shd::stream_cmd_t stream_cmd(shd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + stream_cmd.stream_now = _stream_now; + stream_cmd.time_spec = get_time_now() + shd::time_spec_t(reasonable_delay); + _dev->issue_stream_cmd(stream_cmd); + return true; + } + + bool stop(void) + { + _dev->issue_stream_cmd(shd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + return true; + } + +private: + shd::xmini::multi_xmini::sptr _dev; + const shd::io_type_t _type; + size_t _nchan; + bool _stream_now; + gr_vector_void_star _tmp_buffs; + shd::rx_metadata_t _metadata; +}; + + +/********************************************************************* + * Make SHD Multi SMINI Source + ********************************************************************/ + +boost::shared_ptr<shd_smini_source> shd_make_smini_source( + const shd::device_addr_t &device_addr, + const shd::io_type_t &io_type, + size_t num_channels) +{ + return boost::shared_ptr<shd_smini_source>( + new shd_smini_source_impl(device_addr, io_type, num_channels)); +} diff --git a/gr-shd/swig/.gitignore b/gr-shd/swig/.gitignore new file mode 100644 index 000000000..23ae38f9b --- /dev/null +++ b/gr-shd/swig/.gitignore @@ -0,0 +1,8 @@ +/shd_swig.cc +/shd_swig.py +/Makefile +/Makefile.in +/guile +/python +/run_guile_tests +/run_tests diff --git a/gr-shd/swig/Makefile.am b/gr-shd/swig/Makefile.am new file mode 100644 index 000000000..3e155ba41 --- /dev/null +++ b/gr-shd/swig/Makefile.am @@ -0,0 +1,82 @@ +# +# 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. +# + +include $(top_srcdir)/Makefile.common +include $(top_srcdir)/Makefile.swig + +TESTS = +EXTRA_DIST += run_tests.in run_guile_tests.in $(nobase_guile_DATA) +DISTCLEANFILES += run_tests run_guile_tests + +noinst_PYTHON = qa_shd.py +noinst_GUILE = shd.test + +AM_CPPFLAGS = \ + $(STD_DEFINES_AND_INCLUDES) \ + $(PYTHON_CPPFLAGS) \ + $(SHD_CPPFLAGS) \ + $(WITH_INCLUDES) + +shd_swig_swig_args = $(SHD_CPPFLAGS) + +if GUILE +nobase_guile_DATA = \ + gnuradio/shd.scm +endif + +# ---------------------------------------------------------------- +# The SWIG library + +TOP_SWIG_IFILES = \ + shd_swig.i + +# Install so that they end up available as: +# import gnuradio.shd +# This ends up at: +# ${prefix}/lib/python${python_version}/site-packages/gnuradio/shd +shd_swig_pythondir_category = \ + gnuradio/shd + +# additional libraries for linking with the SWIG-generated library +shd_swig_la_swig_libadd = \ + $(top_builddir)/gr-shd/lib/libgnuradio-shd.la + +# additional Python files to be installed along with the SWIG-generated one +shd_swig_python = \ + __init__.py + +# additional SWIG files to be installed +shd_swig_swiginclude_headers = + +shd_swig_swig_args = $(SHD_CPPFLAGS) + +## If SHD was installed, defined GR_HAVE_SHD for swigging headers +if GR_DEFINE_HAVE_SHD + shd_swig_swig_args += -DGR_HAVE_SHD +endif + +if PYTHON +TESTS += run_tests +endif + +if GUILE +TESTS += run_guile_tests +endif diff --git a/gr-shd/swig/Makefile.swig.gen b/gr-shd/swig/Makefile.swig.gen new file mode 100644 index 000000000..ebe843bbe --- /dev/null +++ b/gr-shd/swig/Makefile.swig.gen @@ -0,0 +1,145 @@ +# -*- Makefile -*- +# +# Copyright 2009 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. +# + +# Makefile.swig.gen for shd_swig.i + +## Default install locations for these files: +## +## Default location for the Python directory is: +## ${prefix}/lib/python${python_version}/site-packages/[category]/shd_swig +## Default location for the Python exec directory is: +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/shd_swig +## +## The following can be overloaded to change the install location, but +## this has to be done in the including Makefile.am -before- +## Makefile.swig is included. + +shd_swig_pythondir_category ?= gnuradio/shd_swig +shd_swig_pylibdir_category ?= $(shd_swig_pythondir_category) +shd_swig_pythondir = $(pythondir)/$(shd_swig_pythondir_category) +shd_swig_pylibdir = $(pyexecdir)/$(shd_swig_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +shd_swig_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/shd_swig +# FIXME: determince whether these should be installed with gnuradio. +shd_swig_scmdir = $(guiledir) + +## SWIG headers are always installed into the same directory. + +shd_swig_swigincludedir = $(swigincludedir) + +## This is a template file for a "generated" Makefile addition (in +## this case, "Makefile.swig.gen"). By including the top-level +## Makefile.swig, this file will be used to generate the SWIG +## dependencies. Assign the variable TOP_SWIG_FILES to be the list of +## SWIG .i files to generated wrappings for; there can be more than 1 +## so long as the names are unique (no sorting is done on the +## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i +## file will generate .cc, .py, and possibly .h files -- meaning that +## all of these files will have the same base name (that provided for +## the SWIG .i file). +## +## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the +## right thing. For more info, see < +## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > + +## Other cleaned files: dependency files generated by SWIG or this Makefile + +MOSTLYCLEANFILES += $(DEPDIR)/*.S* + +## Various SWIG variables. These can be overloaded in the including +## Makefile.am by setting the variable value there, then including +## Makefile.swig . + +shd_swig_swiginclude_HEADERS = \ + shd_swig.i \ + $(shd_swig_swiginclude_headers) + +if PYTHON +shd_swig_pylib_LTLIBRARIES = \ + _shd_swig.la + +_shd_swig_la_SOURCES = \ + python/shd_swig.cc \ + $(shd_swig_la_swig_sources) + +shd_swig_python_PYTHON = \ + shd_swig.py \ + $(shd_swig_python) + +_shd_swig_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(shd_swig_la_swig_libadd) + +_shd_swig_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(shd_swig_la_swig_ldflags) + +_shd_swig_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(shd_swig_la_swig_cxxflags) + +python/shd_swig.cc: shd_swig.py +shd_swig.py: shd_swig.i + +# Include the python dependencies for this file +-include python/shd_swig.d + +endif # end of if python + +if GUILE + +shd_swig_scmlib_LTLIBRARIES = \ + libguile-gnuradio-shd_swig.la +libguile_gnuradio_shd_swig_la_SOURCES = \ + guile/shd_swig.cc \ + $(shd_swig_la_swig_sources) +nobase_shd_swig_scm_DATA = \ + gnuradio/shd_swig.scm \ + gnuradio/shd_swig-primitive.scm +libguile_gnuradio_shd_swig_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(shd_swig_la_swig_libadd) +libguile_gnuradio_shd_swig_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(shd_swig_la_swig_ldflags) +libguile_gnuradio_shd_swig_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(shd_swig_la_swig_cxxflags) + +guile/shd_swig.cc: gnuradio/shd_swig.scm +gnuradio/shd_swig.scm: shd_swig.i +gnuradio/shd_swig-primitive.scm: gnuradio/shd_swig.scm + +# Include the guile dependencies for this file +-include guile/shd_swig.d + +endif # end of GUILE + + diff --git a/gr-shd/swig/__init__.py b/gr-shd/swig/__init__.py new file mode 100644 index 000000000..17589625c --- /dev/null +++ b/gr-shd/swig/__init__.py @@ -0,0 +1,88 @@ +# +# 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. +# + +######################################################################## +# Prepare shd swig module to make it more pythonic +######################################################################## +def _prepare_shd_swig(): + import shd_swig + + #some useful typedefs for the user + setattr(shd_swig, 'freq_range_t', shd_swig.meta_range_t) + setattr(shd_swig, 'gain_range_t', shd_swig.meta_range_t) + + #Make the python tune request object inherit from float + #so that it can be passed in GRC as a frequency parameter. + #The type checking in GRC will accept the tune request. + class tune_request_t(shd_swig.tune_request_t, float): + def __new__(self, *args): return float.__new__(self) + def __float__(self): return self.target_freq + setattr(shd_swig, 'tune_request_t', tune_request_t) + + #Make the python tune request object inherit from string + #so that it can be passed in GRC as a string parameter. + #The type checking in GRC will accept the device address. + #Define the set/get item special methods for dict access. + class device_addr_t(shd_swig.device_addr_t, str): + def __new__(self, *args): return str.__new__(self) + def __getitem__(self, key): return self.get(key) + def __setitem__(self, key, val): self.set(key, val) + setattr(shd_swig, 'device_addr_t', device_addr_t) + + #handle general things on all shd_swig attributes + #Install the __str__ and __repr__ handlers if applicable + #Create aliases for shd swig attributes to avoid the "_t" + for attr in dir(shd_swig): + myobj = getattr(shd_swig, attr) + if hasattr(myobj, 'to_string'): myobj.__repr__ = lambda o: o.to_string().strip() + if hasattr(myobj, 'to_pp_string'): myobj.__str__ = lambda o: o.to_pp_string().strip() + if hasattr(myobj, 'to_bool'): myobj.__nonzero__ = lambda o: o.to_bool() + if hasattr(myobj, 'to_int'): myobj.__int__ = lambda o: o.to_int() + if hasattr(myobj, 'to_real'): myobj.__float__ = lambda o: o.to_real() + if attr.endswith('_t'): setattr(shd_swig, attr[:-2], myobj) + + #Cast constructor args (FIXME swig handle overloads?) + for attr in ('smini_source', 'smini_sink'): + def constructor_factory(old_constructor): + def constructor_interceptor(*args, **kwargs): + args = list(args) + kwargs = dict(kwargs) + for index, key, cast in ( + (0, 'device_addr', device_addr), + (1, 'io_type', io_type), + ): + if len(args) > index: args[index] = cast(args[index]) + if kwargs.has_key(key): kwargs[key] = cast(kwargs[key]) + return old_constructor(*args, **kwargs) + return constructor_interceptor + setattr(shd_swig, attr, constructor_factory(getattr(shd_swig, attr))) + + #Aliases for deprecated constructors + setattr(shd_swig, 'single_smini_source', shd_swig.smini_source) + setattr(shd_swig, 'single_smini_sink', shd_swig.smini_sink) + setattr(shd_swig, 'multi_smini_source', shd_swig.smini_source) + setattr(shd_swig, 'multi_smini_sink', shd_swig.smini_sink) + +######################################################################## +# Initialize this module with the contents of shd swig +######################################################################## +_prepare_shd_swig() +from shd_swig import * diff --git a/gr-shd/swig/gnuradio/.gitignore b/gr-shd/swig/gnuradio/.gitignore new file mode 100644 index 000000000..adf5c3727 --- /dev/null +++ b/gr-shd/swig/gnuradio/.gitignore @@ -0,0 +1,2 @@ +shd_swig-primitive.scm +shd_swig.scm diff --git a/gr-shd/swig/gnuradio/shd.scm b/gr-shd/swig/gnuradio/shd.scm new file mode 100644 index 000000000..91af98dd8 --- /dev/null +++ b/gr-shd/swig/gnuradio/shd.scm @@ -0,0 +1,27 @@ +;;; +;;; 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; Semi bogus module that just reexports the shd_swig module + +(define-module (gnuradio shd) + #:use-module (gnuradio export-safely) + #:use-module (gnuradio shd_swig) + #:duplicates (merge-generics replace check)) + +(re-export-all '(gnuradio shd_swig)) diff --git a/gr-shd/swig/qa_shd.py b/gr-shd/swig/qa_shd.py new file mode 100755 index 000000000..538de918c --- /dev/null +++ b/gr-shd/swig/qa_shd.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# +# Copyright 2005,2008,2010 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 shd_swig + +class test_shd(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_000_nop (self): + """Just see if we can import the module... + They may not have a SHD device connected, etc. Don't try to run anything""" + pass + +if __name__ == '__main__': + gr_unittest.run(test_shd, "test_shd.xml") diff --git a/gr-shd/swig/run_guile_tests.in b/gr-shd/swig/run_guile_tests.in new file mode 100644 index 000000000..5d08b0dd5 --- /dev/null +++ b/gr-shd/swig/run_guile_tests.in @@ -0,0 +1,14 @@ +#!/bin/sh + +. @top_builddir@/setup_guile_test_env + +# 1st argument is absolute path to hand coded guile source directory +# 2nd argument is absolute path to component C++ shared library build directory +# 3nd argument is absolute path to component SWIG build directory + +add_local_paths \ + @srcdir@ \ + @abs_builddir@ \ + @abs_builddir@ + +@GUILE@ -e main -c '(use-modules (gnuradio test-suite guile-test))' -t @srcdir@ diff --git a/gr-shd/swig/run_tests.in b/gr-shd/swig/run_tests.in new file mode 100644 index 000000000..580296374 --- /dev/null +++ b/gr-shd/swig/run_tests.in @@ -0,0 +1,10 @@ +#!/bin/sh + +# 1st parameter is absolute path to component source directory +# 2nd parameter is absolute path to component build directory +# 3rd parameter is path to Python QA directory + +@top_builddir@/run_tests.sh \ + @abs_top_srcdir@/gr-shd \ + @abs_top_builddir@/gr-shd \ + @srcdir@ diff --git a/gr-shd/swig/shd.test b/gr-shd/swig/shd.test new file mode 100644 index 000000000..7b118a081 --- /dev/null +++ b/gr-shd/swig/shd.test @@ -0,0 +1,37 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file, where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(define-module (test-module) + #:use-module (oop goops) + #:use-module (gnuradio core) + #:use-module (gnuradio test-suite lib) + #:duplicates (merge-generics replace check)) + +;;; Just see if we can import the module... +;;; They may not have a SHD device attached, powered up etc. + +(use-modules (gnuradio shd)) diff --git a/gr-shd/swig/shd_swig.i b/gr-shd/swig/shd_swig.i new file mode 100644 index 000000000..217b2f1af --- /dev/null +++ b/gr-shd/swig/shd_swig.i @@ -0,0 +1,135 @@ +/* -*- 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. + */ + +// Defined during configure; avoids trying to locate +// header files if SHD was not installed. +#ifdef GR_HAVE_SHD + +#define GR_SHD_API + +//////////////////////////////////////////////////////////////////////// +// Language independent exception handler +//////////////////////////////////////////////////////////////////////// +%include exception.i + +%exception { + try { + $action + } + catch(std::exception &e) { + SWIG_exception(SWIG_RuntimeError, e.what()); + } + catch(...) { + SWIG_exception(SWIG_RuntimeError, "Unknown exception"); + } + +} + +//////////////////////////////////////////////////////////////////////// +// standard includes +//////////////////////////////////////////////////////////////////////// +%include "gnuradio.i" + +//////////////////////////////////////////////////////////////////////// +// block headers +//////////////////////////////////////////////////////////////////////// +%{ +#include <gr_shd_smini_source.h> +#include <gr_shd_smini_sink.h> +%} + +//////////////////////////////////////////////////////////////////////// +// used types +//////////////////////////////////////////////////////////////////////// +%template(string_vector_t) std::vector<std::string>; + +%include <shd/config.hpp> + +%include <shd/utils/pimpl.hpp> + +%ignore shd::dict::operator[]; //ignore warnings about %extend +%include <shd/types/dict.hpp> +%template(string_string_dict_t) shd::dict<std::string, std::string>; //define after dict + +%include <shd/types/device_addr.hpp> + +%include <shd/types/io_type.hpp> + +%template(range_vector_t) std::vector<shd::range_t>; //define before range +%include <shd/types/ranges.hpp> + +%include <shd/types/tune_request.hpp> + +%include <shd/types/tune_result.hpp> + +%include <shd/types/io_type.hpp> + +%include <shd/types/time_spec.hpp> + +%include <shd/types/clock_config.hpp> + +%include <shd/types/metadata.hpp> + +%ignore shd::device::register_device; //causes compile to choke in MSVC +%include <shd/device.hpp> +%template(device_addr_vector_t) std::vector<shd::device_addr_t>; + +%include <shd/types/sensors.hpp> + +//////////////////////////////////////////////////////////////////////// +// swig dboard_iface for python access +//////////////////////////////////////////////////////////////////////// +%include stdint.i +%include <shd/types/serial.hpp> +%template(byte_vector_t) std::vector<uint8_t>; +%include <shd/xmini/dboard_iface.hpp> + +%template(dboard_iface_sptr) boost::shared_ptr<shd::xmini::dboard_iface>; + +//////////////////////////////////////////////////////////////////////// +// block magic +//////////////////////////////////////////////////////////////////////// +GR_SWIG_BLOCK_MAGIC(shd,smini_source) +%include <gr_shd_smini_source.h> + +GR_SWIG_BLOCK_MAGIC(shd,smini_sink) +%include <gr_shd_smini_sink.h> + +//////////////////////////////////////////////////////////////////////// +// helpful constants +//////////////////////////////////////////////////////////////////////// +%{ +static const size_t ALL_MBOARDS = shd::xmini::multi_xmini::ALL_MBOARDS; +%} +static const size_t ALL_MBOARDS; + +#if SWIGGUILE +%scheme %{ +(load-extension-global "libguile-gnuradio-shd_swig" "scm_init_gnuradio_shd_swig_module") +%} + +%goops %{ +(use-modules (gnuradio gnuradio_core_runtime)) +%} +#endif /* SWIGGUILE */ + +#endif /* GR_HAVE_SHD */ diff --git a/gr-uhd/Makefile.am b/gr-uhd/Makefile.am index ea16c863c..c81a1a049 100644 --- a/gr-uhd/Makefile.am +++ b/gr-uhd/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = include lib apps +SUBDIRS = include lib apps examples if PYTHON SUBDIRS += swig grc diff --git a/gr-uhd/apps/Makefile.am b/gr-uhd/apps/Makefile.am index 9bb9b6cdd..c30a143c2 100644 --- a/gr-uhd/apps/Makefile.am +++ b/gr-uhd/apps/Makefile.am @@ -24,9 +24,13 @@ include $(top_srcdir)/Makefile.common EXTRA_DIST += \ $(bin_SCRIPTS) +SUBDIRS = hf_explorer hf_radio + ourpythondir = $(grpythondir) bin_SCRIPTS = \ - uhd_fft.py \ - uhd_rx_cfile.py - + uhd_fft.py \ + uhd_rx_cfile.py \ + uhd_siggen.py \ + uhd_siggen_gui.py \ + uhd_rx_nogui.py diff --git a/gnuradio-examples/python/apps/hf_explorer/.gitignore b/gr-uhd/apps/hf_explorer/.gitignore index b6950912c..b6950912c 100644 --- a/gnuradio-examples/python/apps/hf_explorer/.gitignore +++ b/gr-uhd/apps/hf_explorer/.gitignore diff --git a/gnuradio-examples/python/apps/hf_explorer/Makefile.am b/gr-uhd/apps/hf_explorer/Makefile.am index 88ad52128..c8e7ecb25 100644 --- a/gnuradio-examples/python/apps/hf_explorer/Makefile.am +++ b/gr-uhd/apps/hf_explorer/Makefile.am @@ -28,4 +28,4 @@ dist_ourdata_DATA = \ hfx_help dist_ourdata_SCRIPTS = \ - hfx2.py + hfx.py diff --git a/gr-uhd/apps/hf_explorer/README b/gr-uhd/apps/hf_explorer/README new file mode 100644 index 000000000..57f45ceba --- /dev/null +++ b/gr-uhd/apps/hf_explorer/README @@ -0,0 +1,42 @@ +hfx.py is meant to be a full-featured Long Wave / Medium Wave +and Short Wave (250kHz to 30Mhz) AM and Single Sideband receiver. +It uses the USRP with a Basic RX board, and will need an +antenna and some preamps, about 30db gain will work. See the +'Help' menu or hfx_help for more info. + +---------------------------------------------------------- + +Powermate knob supported but not required, tooltip frequency display, +single click tuning, AGC, record to disk, play from disk and record +audio. Ability to tailor the audio passband with two sliders over the +spectrum display. The sliders almost align with the actual +frequency. Preset filter settings for LSB (-3000 to 0kHz), USB (0 to ++3000kHz), CW (-400 to -800Hz) and AM (-5kHz from carrier to +5kHz). + +AM now switches in a synchronous PLL detector with the carriers at +7.5kHz. The PLL carrier is displayed in the bottom display and helps +show where on the upper spectrum the demodulated signal +lies. Everything gets shifted up 7.5kHz in AM, center frequency, +tooltips, etc. The target AM carrier needs to be closely tuned in, it +will have a hollow sound untill it is locked, and then the PLL carrier +in the bottom display will jump up and remain relatively +constant. There is a slider "AM sync carrier" to play with different +levels to mix with the signal for demodulation. The filter in AM is +preset to 2500/12500 (7.5kHz +/- 5kHz) and is handy for removing +adjacent channel interference. Change AM_SYNC_DISPLAY in script for +whether to show AM Sync carrier or not. + +Run with "-h" for command line help with setting USRP ddc center +frequency, decimation, rf data record, playback and audio data +recording. + +There are some controls for controlling a varactor and tuning an +antenna - just ignore them unless you want to build a voltage tuned +antenna to track frequency. + +There is also code for Web based control of frequency and volume - so +I can tune the radio with an Ipaq from bed. Disabled by default - it +takes a web server, some directories and scripts to use. + + + diff --git a/gnuradio-examples/python/apps/hf_explorer/hfx2.py b/gr-uhd/apps/hf_explorer/hfx.py index 00a3b9047..687adf82b 100755 --- a/gnuradio-examples/python/apps/hf_explorer/hfx2.py +++ b/gr-uhd/apps/hf_explorer/hfx.py @@ -1,8 +1,7 @@ #!/usr/bin/env python -# -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.4 on Tue Mar 14 10:16:06 2006 # -# Copyright 2006 Free Software Foundation, Inc. +# Copyright 2006,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -81,10 +80,13 @@ AM_SYNC_DISPLAY = False import os, wx, sys, math import wx.lib.evtmgr as em from gnuradio.wxgui import powermate, fftsink2 -from gnuradio import gr, audio, eng_notation, usrp, gru +from gnuradio import gr, audio, eng_notation from gnuradio.eng_option import eng_option +from gnuradio import uhd from optparse import OptionParser +n2s = eng_notation.num_to_str + ID_BUTTON_1 = wx.NewId() # LSB button ID_BUTTON_2 = wx.NewId() # USB ID_BUTTON_3 = wx.NewId() # AM @@ -111,20 +113,6 @@ ID_SLIDER_7 = wx.NewId() # AT control voltage output ID_EXIT = wx.NewId() # Menu Exit -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db(1, 0).dbid() >= 0: - return (1, 0) - return (0, 0) - - class MyFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ @@ -135,7 +123,8 @@ class MyFrame(wx.Frame): self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() - self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) + self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", + "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end @@ -145,9 +134,11 @@ class MyFrame(wx.Frame): self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") - self.slider_1 = wx.Slider(self, ID_SLIDER_1, 0, -15799, 15799, style=wx.SL_HORIZONTAL|wx.SL_LABELS) + self.slider_fcutoff_hi = wx.Slider(self, ID_SLIDER_1, 0, -15798, 15799, + style=wx.SL_HORIZONTAL|wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") - self.slider_2 = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15799, style=wx.SL_HORIZONTAL|wx.SL_LABELS) + self.slider_fcutoff_lo = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15798, + style=wx.SL_HORIZONTAL|wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") @@ -169,9 +160,11 @@ class MyFrame(wx.Frame): self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") - self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL|wx.SL_LABELS) + self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, + style=wx.SL_HORIZONTAL|wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") - self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL|wx.SL_LABELS) + self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, + style=wx.SL_HORIZONTAL|wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") @@ -184,26 +177,30 @@ class MyFrame(wx.Frame): # end wxGlade parser = OptionParser (option_class=eng_option) + parser.add_option("", "--address", type="string", default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") parser.add_option ("-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ") + parser.add_option ("-s", "--samp-rate", type="eng_float", default=256e3, + help="set sample rate (bandwidth) [default=%default]") parser.add_option ("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option ("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option ("-i", "--input_file", default="", help="radio input file", metavar="FILE") - parser.add_option ("-d", "--decim", type="int", default=250, - help="USRP decimation") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, help="select USRP Rx side A or B (default=first one with a daughterboard)") + parser.add_option ("-O", "--audio-output", type="string", default="", + help="audio output device name. E.g., hw:0,0, /dev/dsp, or pulse") + (options, args) = parser.parse_args () self.usrp_center = options.ddc_freq - usb_rate = 64e6 / options.decim - self.slider_range = usb_rate * 0.9375 + input_rate = options.samp_rate + self.slider_range = input_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range/2) self.f_hi = self.usrp_center + (self.slider_range/2) self.af_sample_rate = 32000 - fir_decim = long (usb_rate / self.af_sample_rate) + fir_decim = long (input_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] @@ -215,7 +212,7 @@ class MyFrame(wx.Frame): self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo - self.f_slider_scale = 10000/options.decim + self.f_slider_scale = 10000 self.spin_ctrl_1.SetRange(self.f_lo,self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) @@ -245,40 +242,40 @@ class MyFrame(wx.Frame): else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: - self.src = usrp.source_s(decim_rate=options.decim) - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.src) - self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec) - self.src.tune(0, self.subdev, self.usrp_center) - self.tune_offset = 0 # -self.usrp_center - self.src.rx_freq(0) + self.src = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + self.src.set_samp_rate(input_rate) + input_rate = self.src.get_samp_rate() + + self.src.set_center_freq(self.usrp_center, 0) + self.tune_offset = 0 else: self.src = gr.file_source (gr.sizeof_short,options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band + # convert rf data in interleaved short int form to complex + s2ss = gr.stream_to_streams(gr.sizeof_short,2) + s2f1 = gr.short_to_float() + s2f2 = gr.short_to_float() + src_f2c = gr.float_to_complex() + self.tb.connect(self.src,s2ss) + self.tb.connect((s2ss,0),s2f1) + self.tb.connect((s2ss,1),s2f2) + self.tb.connect(s2f1,(src_f2c,0)) + self.tb.connect(s2f2,(src_f2c,1)) + # save radio data to a file if SAVE_RADIO_TO_FILE: - file = gr.file_sink(gr.sizeof_short, options.radio_file) - self.tb.connect (self.src, file) + radio_file = gr.file_sink(gr.sizeof_short, options.radio_file) + self.tb.connect (self.src, radio_file) # 2nd DDC xlate_taps = gr.firdes.low_pass ( \ - 1.0, usb_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING ) + 1.0, input_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING ) self.xlate = gr.freq_xlating_fir_filter_ccf ( \ - fir_decim, xlate_taps, self.tune_offset, usb_rate ) - - # convert rf data in interleaved short int form to complex - s2ss = gr.stream_to_streams(gr.sizeof_short,2) - s2f1 = gr.short_to_float() - s2f2 = gr.short_to_float() - src_f2c = gr.float_to_complex() - self.tb.connect(self.src,s2ss) - self.tb.connect((s2ss,0),s2f1) - self.tb.connect((s2ss,1),s2f2) - self.tb.connect(s2f1,(src_f2c,0)) - self.tb.connect(s2f2,(src_f2c,1)) - + fir_decim, xlate_taps, self.tune_offset, input_rate ) # Complex Audio filter audio_coeffs = gr.firdes.complex_band_pass ( @@ -288,17 +285,22 @@ class MyFrame(wx.Frame): 0, # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window - self.slider_1.SetValue(0) - self.slider_2.SetValue(-3000) + self.slider_fcutoff_hi.SetValue(0) + self.slider_fcutoff_lo.SetValue(-3000) - self.audio_filter = gr.fir_filter_ccc ( 1, audio_coeffs) + self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display - self.fft = fftsink2.fft_sink_c (self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240)) + self.fft = fftsink2.fft_sink_c(self.panel_2, fft_size=512, + sample_rate=self.af_sample_rate, + average=True, size=(640,240)) # AM Sync carrier if AM_SYNC_DISPLAY: - self.fft2 = fftsink.fft_sink_c (self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240)) + self.fft2 = fftsink.fft_sink_c(self.tb, self.panel_9, + y_per_div=20, fft_size=512, + sample_rate=self.af_sample_rate, + average=True, size=(640,240)) c2f = gr.complex_to_float() @@ -307,7 +309,8 @@ class MyFrame(wx.Frame): # the following frequencies turn out to be in radians/sample # gr.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X - pll = gr.pll_refout_cc(.5,.0625,(2.*math.pi*7.5e3/self.af_sample_rate),(2.*math.pi*6.5e3/self.af_sample_rate)) + pll = gr.pll_refout_cc(.5,.0625,(2.*math.pi*7.5e3/self.af_sample_rate), + (2.*math.pi*6.5e3/self.af_sample_rate)) self.pll_carrier_scale = gr.multiply_const_cc(complex(10,0)) am_det = gr.multiply_cc() # these are for converting +7.5kHz to -7.5kHz @@ -327,7 +330,7 @@ class MyFrame(wx.Frame): 100, # transition gr.firdes.WIN_HAMMING) # window - self.pll_carrier_filter = gr.fir_filter_ccc ( 1, pll_carrier_coeffs) + self.pll_carrier_filter = gr.fir_filter_ccc (1, pll_carrier_coeffs) self.sel_sb = gr.multiply_const_ff(1) combine = gr.add_ff() @@ -338,20 +341,29 @@ class MyFrame(wx.Frame): offset = gr.add_const_ff(1) agc = gr.divide_ff() - self.scale = gr.multiply_const_ff(0.00001) - dst = audio.sink(long(self.af_sample_rate)) + dst = audio.sink(long(self.af_sample_rate), + options.audio_output) + + + if self.PLAY_FROM_USRP: + self.tb.connect(self.src, self.xlate, self.fft) + else: + self.tb.connect(src_f2c, self.xlate, self.fft) - self.tb.connect(src_f2c,self.xlate,self.fft) self.tb.connect(self.xlate,self.audio_filter,self.sel_am,(am_det,0)) - self.tb.connect(self.sel_am,pll,self.pll_carrier_scale,self.pll_carrier_filter,c2f3) + self.tb.connect(self.sel_am,pll,self.pll_carrier_scale, + self.pll_carrier_filter,c2f3) self.tb.connect((c2f3,0),phaser1,(f2c,0)) self.tb.connect((c2f3,1),phaser2,(f2c,1)) self.tb.connect(f2c,(am_det,1)) self.tb.connect(am_det,c2f2,(combine,0)) - self.tb.connect(self.audio_filter,c2f,self.sel_sb,(combine,1)) + self.tb.connect(self.audio_filter,c2f, + self.sel_sb,(combine,1)) + if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter,self.fft2) + self.tb.connect(combine,self.scale) self.tb.connect(self.scale,(sqr1,0)) self.tb.connect(self.scale,(sqr1,1)) @@ -368,9 +380,9 @@ class MyFrame(wx.Frame): self.tb.start() # for mouse position reporting on fft display - em.eventManager.Register(self.Mouse, wx.EVT_MOTION, self.fft.win) + self.fft.win.Bind(wx.EVT_LEFT_UP, self.Mouse) # and left click to re-tune - em.eventManager.Register(self.Click, wx.EVT_LEFT_DOWN, self.fft.win) + self.fft.win.Bind(wx.EVT_LEFT_DOWN, self.Click) # start a timer to check for web commands if WEB_CONTROL: @@ -403,9 +415,9 @@ class MyFrame(wx.Frame): def __set_properties(self): # begin wxGlade: MyFrame.__set_properties - self.SetTitle("HF Explorer 2") - self.slider_1.SetMinSize((450, 38)) - self.slider_2.SetMinSize((450, 38)) + self.SetTitle("HF Explorer") + self.slider_fcutoff_hi.SetMinSize((450, 38)) + self.slider_fcutoff_lo.SetMinSize((450, 38)) self.panel_2.SetMinSize((640, 240)) self.button_7.SetValue(1) self.slider_3.SetMinSize((450, 19)) @@ -434,11 +446,14 @@ class MyFrame(wx.Frame): sizer_2.Add(self.button_4, 0, wx.ADJUST_MINSIZE, 0) grid_sizer_1.Add(sizer_2, 1, wx.EXPAND, 0) grid_sizer_1.Add(self.button_5, 0, wx.ADJUST_MINSIZE, 0) - grid_sizer_1.Add(self.slider_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + grid_sizer_1.Add(self.slider_fcutoff_hi, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) grid_sizer_1.Add(self.button_6, 0, wx.ADJUST_MINSIZE, 0) - grid_sizer_1.Add(self.slider_2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + grid_sizer_1.Add(self.slider_fcutoff_lo, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) sizer_6.Add(self.panel_5, 1, wx.EXPAND, 0) - sizer_6.Add(self.label_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + sizer_6.Add(self.label_1, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) sizer_6.Add(self.text_ctrl_1, 0, wx.ADJUST_MINSIZE, 0) sizer_6.Add(self.panel_6, 1, wx.EXPAND, 0) sizer_6.Add(self.panel_7, 1, wx.EXPAND, 0) @@ -461,9 +476,11 @@ class MyFrame(wx.Frame): grid_sizer_1.Add(sizer_5, 1, wx.EXPAND, 0) grid_sizer_1.Add(self.panel_8, 1, wx.EXPAND, 0) grid_sizer_1.Add(self.panel_9, 1, wx.EXPAND, 0) - grid_sizer_1.Add(self.label_3, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) + grid_sizer_1.Add(self.label_3, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) grid_sizer_1.Add(self.slider_6, 0, wx.ADJUST_MINSIZE, 0) - grid_sizer_1.Add(self.label_4, 0, wx.ALIGN_BOTTOM|wx.ADJUST_MINSIZE, 0) + grid_sizer_1.Add(self.label_4, 0, + wx.ALIGN_BOTTOM|wx.ADJUST_MINSIZE, 0) grid_sizer_1.Add(self.slider_7, 0, wx.ADJUST_MINSIZE, 0) grid_sizer_1.Add(self.panel_10, 1, wx.EXPAND, 0) sizer_7.Add(self.button_12, 0, wx.ADJUST_MINSIZE, 0) @@ -488,14 +505,14 @@ class MyFrame(wx.Frame): # Powermate being turned def on_rotate(self, event): if self.active_button == 5: - self.slider_1.SetValue(self.slider_1.GetValue()+event.delta) - if self.slider_2.GetValue() > (self.slider_1.GetValue() - 200) : - self.slider_2.SetValue(self.slider_1.GetValue() - 200) + self.slider_fcutoff_hi.SetValue(self.slider_fcutoff_hi.GetValue()+event.delta) + if self.slider_fcutoff_lo.GetValue() > (self.slider_fcutoff_hi.GetValue() - 200) : + self.slider_fcutoff_lo.SetValue(self.slider_fcutoff_hi.GetValue() - 200) self.filter() if self.active_button == 6: - self.slider_2.SetValue(self.slider_2.GetValue()+event.delta) - if self.slider_1.GetValue() < (self.slider_2.GetValue() + 200) : - self.slider_1.SetValue(self.slider_2.GetValue() + 200) + self.slider_fcutoff_lo.SetValue(self.slider_fcutoff_lo.GetValue()+event.delta) + if self.slider_fcutoff_hi.GetValue() < (self.slider_fcutoff_lo.GetValue() + 200) : + self.slider_fcutoff_hi.SetValue(self.slider_fcutoff_lo.GetValue() + 200) self.filter() if self.active_button == 7: new = max(0, min(6000, self.slider_3.GetValue() + event.delta)) @@ -581,14 +598,14 @@ class MyFrame(wx.Frame): # Make sure filter settings are legal def set_filter(self, event): slider = event.GetId() - slider1 = self.slider_1.GetValue() - slider2 = self.slider_2.GetValue() + slider1 = self.slider_fcutoff_hi.GetValue() + slider2 = self.slider_fcutoff_lo.GetValue() if slider == ID_SLIDER_1: - if slider2 > (self.slider_1.GetValue() - 200) : - self.slider_2.SetValue(slider1 - 200) + if slider2 > (self.slider_fcutoff_hi.GetValue() - 200) : + self.slider_fcutoff_lo.SetValue(slider1 - 200) elif slider == ID_SLIDER_2: - if slider1 < (self.slider_2.GetValue() + 200) : - self.slider_1.SetValue(slider2 + 200) + if slider1 < (self.slider_fcutoff_lo.GetValue() + 200) : + self.slider_fcutoff_hi.SetValue(slider2 + 200) self.filter() # Calculate taps and apply @@ -596,8 +613,8 @@ class MyFrame(wx.Frame): audio_coeffs = gr.firdes.complex_band_pass ( 1.0, # gain self.af_sample_rate, # sample rate - self.slider_2.GetValue(), # low cutoff - self.slider_1.GetValue(), # high cutoff + self.slider_fcutoff_lo.GetValue(), # low cutoff + self.slider_fcutoff_hi.GetValue(), # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window self.audio_filter.set_taps(audio_coeffs) @@ -607,8 +624,8 @@ class MyFrame(wx.Frame): self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset)) self.sel_sb.set_k(1) self.sel_am.set_k(0) - self.slider_1.SetValue(0) - self.slider_2.SetValue(-3000) + self.slider_fcutoff_hi.SetValue(0) + self.slider_fcutoff_lo.SetValue(-3000) self.filter() def set_usb(self, event): @@ -616,8 +633,8 @@ class MyFrame(wx.Frame): self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset)) self.sel_sb.set_k(1) self.sel_am.set_k(0) - self.slider_1.SetValue(3000) - self.slider_2.SetValue(0) + self.slider_fcutoff_hi.SetValue(3000) + self.slider_fcutoff_lo.SetValue(0) self.filter() def set_am(self, event): @@ -625,8 +642,8 @@ class MyFrame(wx.Frame): self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset - 7.5e3)) self.sel_sb.set_k(0) self.sel_am.set_k(1) - self.slider_1.SetValue(12500) - self.slider_2.SetValue(2500) + self.slider_fcutoff_hi.SetValue(12500) + self.slider_fcutoff_lo.SetValue(2500) self.filter() def set_cw(self, event): @@ -635,8 +652,8 @@ class MyFrame(wx.Frame): self.AM_mode = False self.sel_sb.set_k(1) self.sel_am.set_k(0) - self.slider_1.SetValue(-400) - self.slider_2.SetValue(-800) + self.slider_fcutoff_hi.SetValue(-400) + self.slider_fcutoff_lo.SetValue(-800) self.filter() def set_volume(self, event): @@ -644,7 +661,7 @@ class MyFrame(wx.Frame): def set_pga(self,event): if self.PLAY_FROM_USRP: - self.subdev.set_gain(self.slider_5.GetValue()) + self.src.set_gain(self.slider_5.GetValue()) def slide_tune(self, event): self.frequency = (self.f_slider_scale * self.slider_3.GetValue()) + self.f_slider_offset @@ -731,8 +748,11 @@ class MyFrame(wx.Frame): # Slider to set loop antenna capacitance def antenna_tune(self, evt): if self.PLAY_FROM_USRP: - self.src.write_aux_dac(0,3,self.slider_7.GetValue()) - + dev = self.src.get_dboard_iface() + dev.write_aux_dac(uhd.dboard_iface.UNIT_RX, + uhd.dboard_iface.AUX_DAC_C, + float(self.slider_7.GetValue())) + # Timer events - check for web commands def OnUpdate(self): cmds = os.listdir("/var/www/cgi-bin/commands/") @@ -791,11 +811,13 @@ class UpdateTimer(wx.Timer): class MyApp(wx.App): def OnInit(self): - frame = MyFrame(None, -1, "HF Explorer 2") + frame = MyFrame(None, -1, "HF Explorer") frame.Show(True) self.SetTopWindow(frame) return True -app = MyApp(0) -app.MainLoop() + +if __name__ == "__main__": + app = MyApp(0) + app.MainLoop() diff --git a/gnuradio-examples/python/apps/hf_explorer/hfx_help b/gr-uhd/apps/hf_explorer/hfx_help index 9a52dd2bb..9a52dd2bb 100644 --- a/gnuradio-examples/python/apps/hf_explorer/hfx_help +++ b/gr-uhd/apps/hf_explorer/hfx_help diff --git a/gnuradio-examples/python/apps/hf_radio/.gitignore b/gr-uhd/apps/hf_radio/.gitignore index b6950912c..b6950912c 100644 --- a/gnuradio-examples/python/apps/hf_radio/.gitignore +++ b/gr-uhd/apps/hf_radio/.gitignore diff --git a/gnuradio-examples/python/apps/hf_radio/Makefile.am b/gr-uhd/apps/hf_radio/Makefile.am index e514076f6..e514076f6 100644 --- a/gnuradio-examples/python/apps/hf_radio/Makefile.am +++ b/gr-uhd/apps/hf_radio/Makefile.am diff --git a/gnuradio-examples/python/apps/hf_radio/README.TXT b/gr-uhd/apps/hf_radio/README.TXT index 7c7edf5e0..7c7edf5e0 100644 --- a/gnuradio-examples/python/apps/hf_radio/README.TXT +++ b/gr-uhd/apps/hf_radio/README.TXT diff --git a/gnuradio-examples/python/apps/hf_radio/hfir.sci b/gr-uhd/apps/hf_radio/hfir.sci index a2d5e2a62..a2d5e2a62 100644 --- a/gnuradio-examples/python/apps/hf_radio/hfir.sci +++ b/gr-uhd/apps/hf_radio/hfir.sci diff --git a/gr-uhd/apps/hf_radio/input.py b/gr-uhd/apps/hf_radio/input.py new file mode 100644 index 000000000..2626ddfb5 --- /dev/null +++ b/gr-uhd/apps/hf_radio/input.py @@ -0,0 +1,78 @@ +# 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. +# + +# Basic USRP setup and control. +# It's only ever been tried with a basic rx daughter card. +# +# Imagine that the gnuradio boilerplate is here. +# +# M. Revnell 2005-Dec + +from gnuradio import gr +from gnuradio import uhd + +class uhd_input(gr.hier_block2): + def __init__( self, address, samp_rate): + gr.hier_block2.__init__(self, "uhd_input", + gr.io_signature(0,0,0), + gr.io_signature(1,1,gr.sizeof_gr_complex)) + + self.src = uhd.usrp_source(device_addr=address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + self.src.set_samp_rate(samp_rate) + self.usrp_rate = self.src.get_samp_rate() + + self.connect(self.src, self) + + def set_freq(self, target_freq): + """ + Set the center frequency. + + @param target_freq: frequency in Hz + @type: bool + """ + r = self.src.set_center_freq(target_freq, 0) + + if r: + self.freq = target_freq + return True + else: + return False + + def get_freq(self): + return self.src.get_center_freq(0) + + def set_gain(self, gain): + self.gain = gain + self.src.set_gain(gain, 0) + + def add_options(parser): + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + add_options = staticmethod(add_options) diff --git a/gr-uhd/apps/hf_radio/output.py b/gr-uhd/apps/hf_radio/output.py new file mode 100644 index 000000000..8ee7dc54c --- /dev/null +++ b/gr-uhd/apps/hf_radio/output.py @@ -0,0 +1,42 @@ +# 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. +# + + +# Audio output with a volume control. +# +# M. Revnell 2005-Dec + +from gnuradio import gr, gru +from gnuradio import audio + +class output( gr.hier_block2 ): + def __init__( self, rate, device ): + gr.hier_block2.__init__(self, "output", + gr.io_signature(1,1,gr.sizeof_float), + gr.io_signature(0,0,0)) + + self.vol = gr.multiply_const_ff( 0.1 ) + self.out = audio.sink( int(rate), device ) + + self.connect( self, self.vol, self.out ) + + def set( self, val ): + self.vol.set_k( val ) + diff --git a/gnuradio-examples/python/apps/hf_radio/radio.py b/gr-uhd/apps/hf_radio/radio.py index 9f444b916..32e26c7eb 100755 --- a/gnuradio-examples/python/apps/hf_radio/radio.py +++ b/gr-uhd/apps/hf_radio/radio.py @@ -1,11 +1,29 @@ #!/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. +# # GUI interactions and high level connections handled here. # # Interacts with classes defined by wxGlade in ui.py. # -# The usual gnuradio copyright boilerplate incorperated here by reference. -# # M. Revnell 2006-Jan from threading import * @@ -15,11 +33,11 @@ import time from gnuradio import gr, gru, eng_notation, optfir from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks -from gnuradio.wxgui import fftsink -from gnuradio.wxgui import waterfallsink -from gnuradio.wxgui import scopesink +from gnuradio import uhd +from gnuradio import blks2 +from gnuradio.wxgui import fftsink2 +from gnuradio.wxgui import waterfallsink2 +from gnuradio.wxgui import scopesink2 from input import * from output import * @@ -28,35 +46,36 @@ from ssbagc import * from ui import * from math import log10 -class graph( gr.hier_block ): - def __init__( self, fg ): - self.graph = fg - self.fe_decim = 250 - self.src = input( self.fe_decim ) - self.adc_rate = self.src.adc_rate - self.fe_rate = self.adc_rate / self.fe_decim +class radio_top_block( gr.top_block ): + def __init__( self ): + gr.top_block.__init__(self, "radio_top_block") + + self.address = "addr=192.168.11.2" + self.samp_rate = 256e3 + self.freq = -2.5e6 + self.gain = 0 + self.src = uhd_input( self.address, + self.samp_rate) + self.src.set_freq(self.freq) + self.src.set_gain(self.gain) + + self.fe_rate = self.src.usrp_rate self.filter_decim = 1 self.audio_decim = 16 self.demod_rate = self.fe_rate / self.filter_decim self.audio_rate = self.demod_rate / self.audio_decim + self.audio_dev = "pulse" - self.demod = ssb_demod( fg, self.demod_rate, self.audio_rate ) - self.agc = agc( fg ) - #self.agc = gr.agc_ff() - self.out = output( fg, self.audio_rate ) + self.demod = ssb_demod( self.demod_rate, self.audio_rate ) + self.agc = agc() + self.out = output( self.audio_rate, self.audio_dev ) - fg.connect( self.src.src, - self.demod, - self.agc, - self.out ) - - gr.hier_block.__init__( self, fg, None, None ) + self.connect( self.src, self.demod, self.agc, self.out ) def tune( self, freq ): fe_target = -freq self.src.set_freq( fe_target ) - fe_freq = self.src.src.rx_freq( 0 ) - demod_cf = fe_target - fe_freq + demod_cf = fe_target - self.src.get_freq() self.demod.tune( demod_cf ) class radio_frame( ui_frame ): @@ -88,35 +107,30 @@ class radio_frame( ui_frame ): agc_ref = self.block.agc.offs.k() self.agc_ref.SetValue( str( agc_ref ) ) self.agc_ref_s.SetValue( 5 ) - - self.fespectrum = fftsink.fft_sink_c( - self.block.graph, + + self.fespectrum = fftsink2.fft_sink_c( self.fe_panel, fft_size=512, sample_rate = block.fe_rate, - baseband_freq = 0, - average = False, - size = ( 680, 140 ) ) + ref_scale = 1.0, + ref_level = 20.0, + y_divs = 12, + avg_alpha = 0.1) - self.ifspectrum = fftsink.fft_sink_c( - self.block.graph, + self.ifspectrum = fftsink2.fft_sink_c( self.if_panel, fft_size=512, sample_rate = block.audio_rate, - baseband_freq = 0, - average = False, - size = ( 680, 140 ) ) - - em.eventManager.Register( self.fe_mouse, - wx.EVT_MOTION, - self.fespectrum.win ) + ref_scale = 1.0, + ref_level = 20.0, + y_divs = 12, + avg_alpha = 0.1) - em.eventManager.Register( self.fe_click, - wx.EVT_LEFT_DOWN, - self.fespectrum.win ) + self.fespectrum.win.Bind( wx.EVT_MOTION, self.fe_mouse) + self.fespectrum.win.Bind( wx.EVT_LEFT_DOWN, self.fe_click) - block.graph.connect( block.src.src, self.fespectrum ) - block.graph.connect( block.demod.xlate, self.ifspectrum ) + block.connect( block.src.src, self.fespectrum ) + block.connect( block.demod.xlate, self.ifspectrum ) def agc_ref_up( self, event ): self.agc_ref_s.SetValue( 5 ) @@ -232,7 +246,7 @@ class radio_frame( ui_frame ): self.tune( self.freq_disp.GetValue() - 1e6 ) def event_pga( self, event ): - self.block.src.src.set_pga( 0, self.pga.GetValue()) + self.block.src.set_gain(self.pga.GetValue()) def event_vol( self, event ): self.block.out.set( self.volume.GetValue()/20.0 ) @@ -267,38 +281,39 @@ class radio_frame( ui_frame ): class radio( wx.App ): def OnInit( self ): - self.graph = gr.flow_graph() - self.block = graph( self.graph ) - self.frame = radio_frame( self.block, None, -1, "Title" ) + self.block = radio_top_block() + self.frame = radio_frame( self.block, None, -1, "HF Receiver" ) self.frame.Show( True ) self.SetTopWindow( self.frame ) + self.block.start() return True -a=radio( 0 ) - -l=gr.probe_signal_f() -#l=gr.probe_avg_mag_sqrd_f(1,.001) -a.graph.connect(a.block.agc.offs,l ) -#a.graph.connect(a.block.demod,l) - -def main_function(): - global a - a.MainLoop() - - def rssi_function(): - global a - global l - while 1: - level = l.level() - wx.CallAfter( a.frame.setrssi, level ) - time.sleep( .1 ) - -thread1 = Thread( target = main_function ) -thread2 = Thread( target = rssi_function ) - -thread1.start() -thread2.start() - -a.graph.start() + global radio_obj + global sig_probe + + go = True + while go: + try: + level = sig_probe.level() + wx.CallAfter( radio_obj.frame.setrssi, level ) + time.sleep( .1 ) + except: + go = False + +def main(): + global radio_obj, sig_probe + + radio_obj = radio( 0 ) + sig_probe = gr.probe_signal_f() + radio_obj.block.connect(radio_obj.block.agc.offs, sig_probe) + + thread2 = Thread( target = rssi_function ) + thread2.start() + + radio_obj.MainLoop() + + +if __name__ == "__main__": + main() diff --git a/gnuradio-examples/python/apps/hf_radio/radio.xml b/gr-uhd/apps/hf_radio/radio.xml index 81daa19b0..81daa19b0 100644 --- a/gnuradio-examples/python/apps/hf_radio/radio.xml +++ b/gr-uhd/apps/hf_radio/radio.xml diff --git a/gnuradio-examples/python/apps/hf_radio/ssb_taps b/gr-uhd/apps/hf_radio/ssb_taps index 0ef3bbf26..0ef3bbf26 100644 --- a/gnuradio-examples/python/apps/hf_radio/ssb_taps +++ b/gr-uhd/apps/hf_radio/ssb_taps diff --git a/gr-uhd/apps/hf_radio/ssbagc.py b/gr-uhd/apps/hf_radio/ssbagc.py new file mode 100644 index 000000000..494712863 --- /dev/null +++ b/gr-uhd/apps/hf_radio/ssbagc.py @@ -0,0 +1,70 @@ +# 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. + + +# post detection agc processing +# +# This agc strategy is copied more or less verbatim from +# weaver_isb_am1_usrp3.py by cswiger. +# +# Thanks. +# +# Then modified in a variety of ways. +# +# There doesn't appear to be a way to hook multiple blocks to the +# input port when building a hier block like this. Thus the +# split below. +# +# Basic operation. +# Power is estimated by squaring the input. +# Low pass filter using a 1 pole iir. +# The time constant can be tweaked by changing the taps. +# Currently there is no implementation to change this while operating +# a potentially useful addition. +# The log block turns this into dB +# gain adjusts the agc authority. +# +# M. Revnell 2006-Jan + +from gnuradio import gr + +class agc( gr.hier_block2 ): + def __init__( self ): + gr.hier_block2.__init__(self, "agc", + gr.io_signature(1,1,gr.sizeof_float), + gr.io_signature(1,1,gr.sizeof_float)) + + self.split = gr.multiply_const_ff( 1 ) + self.sqr = gr.multiply_ff( ) + self.int0 = gr.iir_filter_ffd( [.004, 0], [0, .999] ) + self.offs = gr.add_const_ff( -30 ) + self.gain = gr.multiply_const_ff( 70 ) + self.log = gr.nlog10_ff( 10, 1 ) + self.agc = gr.divide_ff( ) + + self.connect(self, self.split) + self.connect(self.split, (self.agc, 0)) + self.connect(self.split, (self.sqr, 0)) + self.connect(self.split, (self.sqr, 1)) + self.connect(self.sqr, self.int0) + self.connect(self.int0, self.log) + self.connect(self.log, self.offs) + self.connect(self.offs, self.gain) + self.connect(self.gain, (self.agc, 1)) + self.connect(self.agc, self) diff --git a/gnuradio-examples/python/apps/hf_radio/ssbdemod.py b/gr-uhd/apps/hf_radio/ssbdemod.py index c73567b66..072d317a2 100644 --- a/gnuradio-examples/python/apps/hf_radio/ssbdemod.py +++ b/gr-uhd/apps/hf_radio/ssbdemod.py @@ -1,8 +1,26 @@ +# 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. +# + # This tries to push the hilbert transform for ssb demod back into the # freq. xlating filter. # -# The usual gnuradio copyright notice is hereby included by reference. -# # The starting point for this was weaver_isb_am1_usrp3.py. # # The tap coefficients for freq_xlating_fir_filter_ccf were generated @@ -13,16 +31,17 @@ # They were generated using Scilab which I am already familiar with. # M. Revnell Jan 06 -from gnuradio import gr, gru -from gnuradio import audio -from gnuradio import usrp +from gnuradio import gr -class ssb_demod( gr.hier_block ): - def __init__( self, fg, if_rate, af_rate ): +class ssb_demod( gr.hier_block2 ): + def __init__( self, if_rate, af_rate ): + gr.hier_block2.__init__(self, "ssb_demod", + gr.io_signature(1,1,gr.sizeof_gr_complex), + gr.io_signature(1,1,gr.sizeof_float)) - self.if_rate = if_rate - self.af_rate = af_rate - self.if_decim = if_rate / af_rate + self.if_rate = int(if_rate) + self.af_rate = int(af_rate) + self.if_decim = int(if_rate / af_rate) self.sideband = 1 self.xlate_taps = ([complex(v) for v in file('ssb_taps').readlines()]) @@ -51,17 +70,17 @@ class ssb_demod( gr.hier_block ): self.mixer = gr.add_ff() self.am_det = gr.complex_to_mag() - fg.connect( self.xlate, self.split ) - fg.connect( ( self.split,0 ), ( self.sum,0 ) ) - fg.connect( ( self.split,1 ), ( self.sum,1 ) ) - fg.connect( self.sum, self.sb_sel ) - fg.connect( self.xlate, self.am_det ) - fg.connect( self.sb_sel, ( self.mixer, 0 ) ) - fg.connect( self.am_det, self.am_sel ) - fg.connect( self.am_sel, ( self.mixer, 1 ) ) - fg.connect( self.mixer, self.lpf ) - - gr.hier_block.__init__( self, fg, self.xlate, self.lpf ) + self.connect(self, self.xlate) + self.connect(self.xlate, self.split) + self.connect((self.split, 0), (self.sum, 0)) + self.connect((self.split, 1), (self.sum, 1)) + self.connect(self.sum, self.sb_sel) + self.connect(self.xlate, self.am_det) + self.connect(self.sb_sel, (self.mixer, 0)) + self.connect(self.am_det, self.am_sel) + self.connect(self.am_sel, (self.mixer, 1)) + self.connect(self.mixer, self.lpf) + self.connect(self.lpf, self) def upper_sb( self ): self.xlate.set_taps([v.conjugate() for v in self.xlate_taps]) diff --git a/gnuradio-examples/python/apps/hf_radio/startup.py b/gr-uhd/apps/hf_radio/startup.py index 093369b57..093369b57 100644 --- a/gnuradio-examples/python/apps/hf_radio/startup.py +++ b/gr-uhd/apps/hf_radio/startup.py diff --git a/gnuradio-examples/python/apps/hf_radio/ui.py b/gr-uhd/apps/hf_radio/ui.py index 71b73c128..551a30415 100755 --- a/gnuradio-examples/python/apps/hf_radio/ui.py +++ b/gr-uhd/apps/hf_radio/ui.py @@ -1,4 +1,25 @@ #!/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. +# + # -*- coding: UTF-8 -*- # generated by wxGlade 0.4 on Mon Jan 2 19:02:03 2006 diff --git a/gr-uhd/apps/uhd_fft.py b/gr-uhd/apps/uhd_fft.py index 87952ef3a..0f0c274e8 100755 --- a/gr-uhd/apps/uhd_fft.py +++ b/gr-uhd/apps/uhd_fft.py @@ -20,16 +20,23 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru +from gnuradio import gr from gnuradio import uhd from gnuradio import eng_notation from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider from optparse import OptionParser -import wx + import sys import numpy +try: + from gnuradio.wxgui import stdgui2, form, slider + from gnuradio.wxgui import fftsink2, waterfallsink2, scopesink2 + import wx +except ImportError: + sys.stderr.write("Error importing GNU Radio's wxgui. Please make sure gr-wxgui is installed.\n") + sys.exit(1) + class app_top_block(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) @@ -38,7 +45,8 @@ class app_top_block(stdgui2.std_top_block): self.panel = panel parser = OptionParser(option_class=eng_option) - parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", help="Address of UHD device, [default=%default]") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") @@ -74,7 +82,8 @@ class app_top_block(stdgui2.std_top_block): if options.waterfall: self.scope = \ - waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate) + waterfallsink2.waterfall_sink_c (panel, fft_size=1024, + sample_rate=input_rate) self.frame.SetMinSize((800, 420)) elif options.oscilloscope: self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) @@ -114,9 +123,8 @@ class app_top_block(stdgui2.std_top_block): if self.show_debug_info: self.myform['samprate'].set_value(self.u.get_samp_rate()) - self.myform['fs@gbe'].set_value(input_rate) - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) + self.myform['rffreq'].set_value(0) + self.myform['dspfreq'].set_value(0) if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") @@ -137,14 +145,16 @@ class app_top_block(stdgui2.std_top_block): hbox.Add((5,0), 0, 0) myform['freq'] = form.float_field( parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) + callback=myform.check_input_and_call(_form_set_freq, + self._set_status_msg)) hbox.Add((5,0), 0, 0) g = self.u.get_gain_range() # some configurations don't have gain control if g.stop() > g.start(): - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", + myform['gain'] = form.slider_field(parent=self.panel, + sizer=hbox, label="Gain", weight=3, min=int(g.start()), max=int(g.stop()), callback=self.set_gain) @@ -175,19 +185,16 @@ class app_top_block(stdgui2.std_top_block): hbox.Add((5,0), 0) myform['samprate'] = form.float_field( parent=panel, sizer=hbox, label="Sample Rate", - callback=myform.check_input_and_call(_form_set_samp_rate, self._set_status_msg)) + callback=myform.check_input_and_call(_form_set_samp_rate, + self._set_status_msg)) hbox.Add((5,0), 1) - myform['fs@gbe'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@GbE") + myform['rffreq'] = form.static_float_field( + parent=panel, sizer=hbox, label="RF Freq.") hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") + myform['dspfreq'] = form.static_float_field( + parent=panel, sizer=hbox, label="DSP Freq.") hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -198,19 +205,13 @@ class app_top_block(stdgui2.std_top_block): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. """ r = self.u.set_center_freq(target_freq, 0) if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.actual_rf_freq) - self.myform['ddc'].set_value(r.actual_dsp_freq) + self.myform['freq'].set_value(self.u.get_center_freq()) + self.myform['rffreq'].set_value(r.actual_rf_freq) + self.myform['dspfreq'].set_value(r.actual_dsp_freq) if not self.options.oscilloscope: self.scope.set_baseband_freq(target_freq) return True @@ -228,7 +229,6 @@ class app_top_block(stdgui2.std_top_block): self.scope.set_sample_rate(input_rate) if self.show_debug_info: # update displayed values self.myform['samprate'].set_value(self.u.get_samp_rate()) - self.myform['fs@gbe'].set_value(input_rate) # uhd set_samp_rate never fails; always falls back to closest requested. return True diff --git a/gr-utils/src/python/usrp_rx_nogui.py b/gr-uhd/apps/uhd_rx_nogui.py index a5d792c8b..6f860b820 100755 --- a/gr-utils/src/python/usrp_rx_nogui.py +++ b/gr-uhd/apps/uhd_rx_nogui.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2006,2007 Free Software Foundation, Inc. +# Copyright 2006,2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,7 +20,8 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, usrp, optfir, audio, eng_notation, blks2 +from gnuradio import gr, gru, uhd, optfir, audio, blks2 +from gnuradio import eng_notation from gnuradio.eng_option import eng_option from optparse import OptionParser import sys @@ -66,75 +67,79 @@ Please see fm_demod.py and am_demod.py for details of the demodulation blocks. """ -# (usrp_decim, channel_decim, audio_decim, channel_pass, channel_stop, demod) +# (device_rate, channel_rate, audio_rate, channel_pass, channel_stop, demod) demod_params = { - 'AM' : (250, 16, 1, 5000, 8000, blks2.demod_10k0a3e_cf), - 'FM' : (250, 8, 4, 8000, 9000, blks2.demod_20k0f3e_cf), - 'WFM' : (250, 1, 8, 90000, 100000, blks2.demod_200kf3e_cf) + 'AM' : (256e3, 16e3, 16e3, 5000, 8000, blks2.demod_10k0a3e_cf), + 'FM' : (256e3, 32e3, 8e3, 8000, 9000, blks2.demod_20k0f3e_cf), + 'WFM' : (320e3, 320e3, 32e3, 80000, 115000, blks2.demod_200kf3e_cf) } -class usrp_src(gr.hier_block2): +class uhd_src(gr.hier_block2): """ - Create a USRP source object supplying complex floats. + Create a UHD source object supplying complex floats. Selects user supplied subdevice or chooses first available one. Calibration value is the offset from the tuned frequency to the actual frequency. """ - def __init__(self, subdev_spec, decim, gain=None, calibration=0.0): - gr.hier_block2.__init__(self, "usrp_src", + def __init__(self, address, samp_rate, gain=None, calibration=0.0): + gr.hier_block2.__init__(self, "uhd_src", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - self._decim = decim - self._src = usrp.source_c() - if subdev_spec is None: - subdev_spec = usrp.pick_rx_subdevice(self._src) - self._subdev = usrp.selected_subdev(self._src, subdev_spec) - self._src.set_mux(usrp.determine_rx_mux_value(self._src, subdev_spec)) - self._src.set_decim_rate(self._decim) - + self._src = uhd.usrp_source(device_addr=address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + self._src.set_samp_rate(samp_rate) + dev_rate = self._src.get_samp_rate() + self._samp_rate = samp_rate + + # Resampler to get to exactly samp_rate no matter what dev_rate is + self._rrate = samp_rate / dev_rate + self._resamp = blks2.pfb_arb_resampler_ccf(self._rrate) + # If no gain specified, set to midrange if gain is None: - g = self._subdev.gain_range() - gain = (g[0]+g[1])/2.0 - - self._subdev.set_gain(gain) + g = self._src.get_gain_range() + gain = (g.start()+g.stop())/2.0 + print "Using gain: ", gain + self._src.set_gain(gain) + self._cal = calibration - self.connect(self._src, self) + self.connect(self._src, self._resamp, self) def tune(self, freq): - result = usrp.tune(self._src, 0, self._subdev, freq+self._cal) - # TODO: deal with residual + r = self._src.set_center_freq(freq+self._cal, 0) def rate(self): - return self._src.adc_rate()/self._decim - + return self._samp_rate + class app_top_block(gr.top_block): def __init__(self, options): gr.top_block.__init__(self) self.options = options - (usrp_decim, channel_decim, audio_decim, + (dev_rate, channel_rate, audio_rate, channel_pass, channel_stop, demod) = demod_params[options.modulation] - USRP = usrp_src(options.rx_subdev_spec, # Daugherboard spec - usrp_decim, # IF decimation ratio - options.gain, # Receiver gain - options.calibration) # Frequency offset - USRP.tune(options.frequency) + DEV = uhd_src(options.address, # UHD device address + dev_rate, # device sample rate + options.gain, # Receiver gain + options.calibration) # Frequency offset + DEV.tune(options.frequency) - if_rate = USRP.rate() - channel_rate = if_rate // channel_decim - audio_rate = channel_rate // audio_decim + if_rate = DEV.rate() + channel_decim = int(if_rate // channel_rate) + audio_decim = int(channel_rate // audio_rate) - CHAN_taps = optfir.low_pass(1.0, # Filter gain - if_rate, # Sample rate - channel_pass, # One sided modulation bandwidth - channel_stop, # One sided channel bandwidth - 0.1, # Passband ripple - 60) # Stopband attenuation + CHAN_taps = optfir.low_pass(1.0, # Filter gain + if_rate, # Sample rate + channel_pass, # One sided modulation bandwidth + channel_stop, # One sided channel bandwidth + 0.1, # Passband ripple + 60) # Stopband attenuation CHAN = gr.freq_xlating_fir_filter_ccf(channel_decim, # Decimation rate CHAN_taps, # Filter taps @@ -143,7 +148,7 @@ class app_top_block(gr.top_block): RFSQL = gr.pwr_squelch_cc(options.rf_squelch, # Power threshold 125.0/channel_rate, # Time constant - channel_rate/20, # 50ms rise/fall + int(channel_rate/20), # 50ms rise/fall False) # Zero, not gate output AGC = gr.agc_cc(1.0/channel_rate, # Time constant @@ -154,7 +159,8 @@ class app_top_block(gr.top_block): DEMOD = demod(channel_rate, audio_decim) # From RF to audio - self.connect(USRP, CHAN, RFSQL, AGC, DEMOD) + #self.connect(DEV, CHAN, RFSQL, AGC, DEMOD) + self.connect(DEV, CHAN, DEMOD) # Optionally add CTCSS and RSAMP if needed tail = DEMOD @@ -172,37 +178,51 @@ class app_top_block(gr.top_block): self.connect(tail, RSAMP) tail = RSAMP - # Send to default audio output - AUDIO = audio.sink(options.output_rate, "") + # Send to audio output device + AUDIO = audio.sink(int(options.output_rate), + options.audio_output) self.connect(tail, AUDIO) def main(): parser = OptionParser(option_class=eng_option) - parser.add_option("-f", "--frequency", type="eng_float", default=None, - help="set receive frequency to Hz", metavar="Hz") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", - help="select USRP Rx side A or B", metavar="SUBDEV") - parser.add_option("-c", "--calibration", type="eng_float", default=0.0, - help="set frequency offset to Hz", metavar="Hz") - parser.add_option("-g", "--gain", type="int", default=None, - help="set RF gain", metavar="dB") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate [default=%default]") + parser.add_option("-f", "--frequency", type="eng_float", + default=None, metavar="Hz", + help="set receive frequency to Hz [default=%default]") + parser.add_option("-c", "--calibration", type="eng_float", + default=0.0, metavar="Hz", + help="set frequency offset to Hz [default=%default]") + parser.add_option("-g", "--gain", type="int", + metavar="dB", default=None, + help="set RF gain [default is midpoint]") parser.add_option("-m", "--modulation", type="choice", choices=('AM','FM','WFM'), - help="set modulation type (AM,FM)", metavar="TYPE") - parser.add_option("-o", "--output-rate", type="int", default=32000, - help="set audio output rate to RATE", metavar="RATE") - parser.add_option("-r", "--rf-squelch", type="eng_float", default=-50.0, - help="set RF squelch to dB", metavar="dB") + metavar="TYPE", default=None, + help="set modulation type (AM,FM) [default=%default]") + parser.add_option("-o", "--output-rate", type="eng_float", + default=32000, metavar="RATE", + help="set audio output rate to RATE [default=%default]") + parser.add_option("-r", "--rf-squelch", type="eng_float", + default=-50.0, metavar="dB", + help="set RF squelch to dB [default=%default]") parser.add_option("-p", "--ctcss", type="float", - help="set CTCSS squelch to FREQ", metavar="FREQ") + default=None, metavar="FREQ", + help="set CTCSS squelch to FREQ [default=%default]") + parser.add_option("-O", "--audio-output", type="string", default="", + help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") (options, args) = parser.parse_args() if options.frequency is None: - print "Must supply receive frequency with -f" + sys.stderr.write("Must supply receive frequency with -f.\n") sys.exit(1) - if options.frequency < 1e6: - options.frequency *= 1e6 - + if options.modulation is None: + sys.stderr.write("Must supply a modulation type (AM, FM, WFM).\n") + sys.exit(1) + tb = app_top_block(options) try: tb.run() diff --git a/gr-utils/src/python/usrp_siggen.py b/gr-uhd/apps/uhd_siggen.py index da83da770..921ba44b5 100755 --- a/gr-utils/src/python/usrp_siggen.py +++ b/gr-uhd/apps/uhd_siggen.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2008,2009 Free Software Foundation, Inc. +# Copyright 2008,2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -23,12 +23,10 @@ DESC_KEY = 'desc' SAMP_RATE_KEY = 'samp_rate' LINK_RATE_KEY = 'link_rate' -DAC_RATE_KEY = 'dac_rate' -INTERP_KEY = 'interp' GAIN_KEY = 'gain' TX_FREQ_KEY = 'tx_freq' -DDC_FREQ_KEY = 'ddc_freq' -BB_FREQ_KEY = 'bb_freq' +DSP_FREQ_KEY = 'dsp_freq' +RF_FREQ_KEY = 'rf_freq' AMPLITUDE_KEY = 'amplitude' AMPL_RANGE_KEY = 'ampl_range' WAVEFORM_FREQ_KEY = 'waveform_freq' @@ -40,10 +38,9 @@ TYPE_KEY = 'type' def setter(ps, key, val): ps[key] = val -from gnuradio import gr, eng_notation +from gnuradio import gr, uhd, eng_notation from gnuradio.gr.pubsub import pubsub from gnuradio.eng_option import eng_option -from gnuradio import usrp_options from optparse import OptionParser import sys import math @@ -66,40 +63,48 @@ class top_block(gr.top_block, pubsub): gr.top_block.__init__(self) pubsub.__init__(self) self._verbose = options.verbose + #initialize values from options self._setup_usrpx(options) - self.subscribe(INTERP_KEY, lambda i: setter(self, SAMP_RATE_KEY, self[DAC_RATE_KEY]/i)) - self.subscribe(SAMP_RATE_KEY, lambda e: setter(self, LINK_RATE_KEY, e*32)) - self[INTERP_KEY] = options.interp or 16 + self[SAMP_RATE_KEY] = options.samp_rate self[TX_FREQ_KEY] = options.tx_freq self[AMPLITUDE_KEY] = options.amplitude self[WAVEFORM_FREQ_KEY] = options.waveform_freq self[WAVEFORM_OFFSET_KEY] = options.offset self[WAVEFORM2_FREQ_KEY] = options.waveform2_freq - self[BB_FREQ_KEY] = 0 - self[DDC_FREQ_KEY] = 0 + self[DSP_FREQ_KEY] = 0 + self[RF_FREQ_KEY] = 0 + #subscribe set methods - self.subscribe(INTERP_KEY, self.set_interp) + self.subscribe(SAMP_RATE_KEY, self.set_samp_rate) self.subscribe(GAIN_KEY, self.set_gain) self.subscribe(TX_FREQ_KEY, self.set_freq) self.subscribe(AMPLITUDE_KEY, self.set_amplitude) self.subscribe(WAVEFORM_FREQ_KEY, self.set_waveform_freq) self.subscribe(WAVEFORM2_FREQ_KEY, self.set_waveform2_freq) self.subscribe(TYPE_KEY, self.set_waveform) + #force update on pubsub keys - for key in (INTERP_KEY, GAIN_KEY, TX_FREQ_KEY, - AMPLITUDE_KEY, WAVEFORM_FREQ_KEY, WAVEFORM_OFFSET_KEY, WAVEFORM2_FREQ_KEY): + for key in (SAMP_RATE_KEY, GAIN_KEY, TX_FREQ_KEY, + AMPLITUDE_KEY, WAVEFORM_FREQ_KEY, + WAVEFORM_OFFSET_KEY, WAVEFORM2_FREQ_KEY): self[key] = self[key] self[TYPE_KEY] = options.type #set type last def _setup_usrpx(self, options): - self._u = usrp_options.create_usrp_sink(options) + self._u = uhd.usrp_sink(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + self._u.set_samp_rate(options.samp_rate) + if(options.antenna): + self._u.set_antenna(options.antenna) + self.publish(DESC_KEY, lambda: str(self._u)) - self.publish(DAC_RATE_KEY, self._u.dac_rate) - self.publish(FREQ_RANGE_KEY, self._u.freq_range) - self.publish(GAIN_RANGE_KEY, self._u.gain_range) - self.publish(GAIN_KEY, self._u.gain) - if self._verbose: print str(self._u) + self.publish(FREQ_RANGE_KEY, self._u.get_freq_range) + self.publish(GAIN_RANGE_KEY, self._u.get_gain_range) + self.publish(GAIN_KEY, self._u.get_gain) + if self._verbose: + print str(self._u) def _set_tx_amplitude(self, ampl): """ @@ -107,16 +112,13 @@ class top_block(gr.top_block, pubsub): @param ampl the amplitude or None for automatic """ ampl_range = self[AMPL_RANGE_KEY] - if ampl is None: ampl = (ampl_range[1] - ampl_range[0])*0.15 + ampl_range[0] + if ampl is None: + ampl = (ampl_range[1] - ampl_range[0])*0.15 + ampl_range[0] self[AMPLITUDE_KEY] = max(ampl_range[0], min(ampl, ampl_range[1])) - def set_interp(self, interp): - if not self._u.set_interp(interp): - raise RuntimeError("Failed to set interpolation rate %i" % (interp,)) - - if self._verbose: - print "USRP interpolation rate:", interp - print "USRP IF bandwidth: %sHz" % (n2s(self[SAMP_RATE_KEY]),) + def set_samp_rate(self, sr): + self._u.set_samp_rate(sr) + sr = self._u.get_samp_rate() if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE): self._src.set_sampling_freq(self[SAMP_RATE_KEY]) @@ -129,7 +131,9 @@ class top_block(gr.top_block, pubsub): else: return True # Waveform not yet set - if self._verbose: print "Set interpolation rate to:", interp + if self._verbose: + print "Set sample rate to:", sr + return True def set_gain(self, gain): @@ -158,14 +162,14 @@ class top_block(gr.top_block, pubsub): fs = "%sHz" % (n2s(target_freq),) if tr is not None: self._freq = target_freq - self[DDC_FREQ_KEY] = tr.dxc_freq - self[BB_FREQ_KEY] = tr.baseband_freq + self[DSP_FREQ_KEY] = tr.actual_dsp_freq + self[RF_FREQ_KEY] = tr.actual_rf_freq if self._verbose: - print "Set center frequency to", fs - print "Tx baseband frequency: %sHz" % (n2s(tr.baseband_freq),) - print "Tx DDC frequency: %sHz" % (n2s(tr.dxc_freq),) - print "Tx residual frequency: %sHz" % (n2s(tr.residual_freq),) - elif self._verbose: print "Failed to set freq." + print "Set center frequency to", self._u.get_center_freq() + print "Tx RF frequency: %sHz" % (n2s(tr.actual_rf_freq),) + print "Tx DSP frequency: %sHz" % (n2s(tr.actual_dsp_freq),) + elif self._verbose: + print "Failed to set freq." return tr def set_waveform_freq(self, freq): @@ -254,7 +258,8 @@ class top_block(gr.top_block, pubsub): def set_amplitude(self, amplitude): if amplitude < 0.0 or amplitude > 1.0: - if self._verbose: print "Amplitude out of range:", amplitude + if self._verbose: + print "Amplitude out of range:", amplitude return False if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE, gr.GR_GAUSSIAN, gr.GR_UNIFORM): @@ -267,22 +272,33 @@ class top_block(gr.top_block, pubsub): else: return True # Waveform not yet set - if self._verbose: print "Set amplitude to:", amplitude + if self._verbose: + print "Set amplitude to:", amplitude return True def get_options(): usage="%prog: [options]" parser = OptionParser(option_class=eng_option, usage=usage) - usrp_options.add_tx_options(parser) + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate (bandwidth) [default=%default]") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") parser.add_option("-f", "--tx-freq", type="eng_float", default=None, - help="Set carrier frequency to FREQ [default=mid-point]", metavar="FREQ") + help="Set carrier frequency to FREQ [default=mid-point]", + metavar="FREQ") parser.add_option("-x", "--waveform-freq", type="eng_float", default=0, help="Set baseband waveform frequency to FREQ [default=%default]") parser.add_option("-y", "--waveform2-freq", type="eng_float", default=None, help="Set 2nd waveform frequency to FREQ [default=%default]") parser.add_option("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE, - help="Generate a carrier modulated by a complex sine wave", default=gr.GR_SIN_WAVE) + help="Generate a carrier modulated by a complex sine wave", + default=gr.GR_SIN_WAVE) parser.add_option("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, help="Generate a constant carrier") parser.add_option("--offset", type="eng_float", default=0, @@ -295,8 +311,9 @@ def get_options(): help="Generate Two Tone signal for IMD testing") parser.add_option("--sweep", dest="type", action="store_const", const="sweep", help="Generate a swept sine wave") - parser.add_option("-A", "--amplitude", type="eng_float", default=0.15, - help="Set output amplitude to AMPL (0.0-1.0) [default=%default]", metavar="AMPL") + parser.add_option("", "--amplitude", type="eng_float", default=0.15, + help="Set output amplitude to AMPL (0.0-1.0) [default=%default]", + metavar="AMPL") parser.add_option("-v", "--verbose", action="store_true", default=False, help="Use verbose console output [default=%default]") @@ -304,7 +321,8 @@ def get_options(): return (options, args) -# If this script is executed, the following runs. If it is imported, the below does not run. +# If this script is executed, the following runs. If it is imported, +# the below does not run. def main(): if gr.enable_realtime_scheduling() != gr.RT_OK: print "Note: failed to enable realtime scheduling, continuing" @@ -328,4 +346,5 @@ def main(): # which will call the decontructor on usrp and stop transmit. # Whats odd is that grc works fine with tb in the __main__, # perhaps its because the try/except clauses around tb. -if __name__ == "__main__": main() +if __name__ == "__main__": + main() diff --git a/gr-utils/src/python/usrp_siggen_gui.py b/gr-uhd/apps/uhd_siggen_gui.py index 47d47bdb3..2ef6ea40f 100755 --- a/gr-utils/src/python/usrp_siggen_gui.py +++ b/gr-uhd/apps/uhd_siggen_gui.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2009 Free Software Foundation, Inc. +# Copyright 2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -24,7 +24,7 @@ import wx from gnuradio import gr from gnuradio.gr.pubsub import pubsub from gnuradio.wxgui import gui, forms -import usrp_siggen +import uhd_siggen import sys, math class app_gui(pubsub): @@ -62,14 +62,14 @@ class app_gui(pubsub): sweep_bb_hbox.ShowItems(type == 'sweep') tone_bb_hbox.ShowItems(type == '2tone') self.vbox.Layout() - self.tb.subscribe(usrp_siggen.TYPE_KEY, set_type) + self.tb.subscribe(uhd_siggen.TYPE_KEY, set_type) #create sine forms sine_bb_hbox.AddSpacer(10) forms.text_box( parent=self.panel, sizer=sine_bb_hbox, label='Frequency (Hz)', ps=self.tb, - key=usrp_siggen.WAVEFORM_FREQ_KEY, + key=uhd_siggen.WAVEFORM_FREQ_KEY, converter=forms.float_converter(), ) sine_bb_hbox.AddStretchSpacer() @@ -79,7 +79,7 @@ class app_gui(pubsub): parent=self.panel, sizer=sweep_bb_hbox, label='Sweep Width (Hz)', ps=self.tb, - key=usrp_siggen.WAVEFORM_FREQ_KEY, + key=uhd_siggen.WAVEFORM_FREQ_KEY, converter=forms.float_converter(), ) sweep_bb_hbox.AddStretchSpacer() @@ -87,7 +87,7 @@ class app_gui(pubsub): parent=self.panel, sizer=sweep_bb_hbox, label='Sweep Rate (Hz)', ps=self.tb, - key=usrp_siggen.WAVEFORM2_FREQ_KEY, + key=uhd_siggen.WAVEFORM2_FREQ_KEY, converter=forms.float_converter(), ) sweep_bb_hbox.AddStretchSpacer() @@ -97,7 +97,7 @@ class app_gui(pubsub): parent=self.panel, sizer=tone_bb_hbox, label='Tone 1 (Hz)', ps=self.tb, - key=usrp_siggen.WAVEFORM_FREQ_KEY, + key=uhd_siggen.WAVEFORM_FREQ_KEY, converter=forms.float_converter(), ) tone_bb_hbox.AddStretchSpacer() @@ -105,27 +105,31 @@ class app_gui(pubsub): parent=self.panel, sizer=tone_bb_hbox, label='Tone 2 (Hz)', ps=self.tb, - key=usrp_siggen.WAVEFORM2_FREQ_KEY, + key=uhd_siggen.WAVEFORM2_FREQ_KEY, converter=forms.float_converter(), ) tone_bb_hbox.AddStretchSpacer() forms.radio_buttons( parent=self.panel, sizer=bb_vbox, - choices=usrp_siggen.waveforms.keys(), - labels=usrp_siggen.waveforms.values(), + choices=uhd_siggen.waveforms.keys(), + labels=uhd_siggen.waveforms.values(), ps=self.tb, - key=usrp_siggen.TYPE_KEY, + key=uhd_siggen.TYPE_KEY, style=wx.NO_BORDER | wx.RA_HORIZONTAL, ) bb_vbox.AddSpacer(10) bb_vbox.Add(sine_bb_hbox, 0, wx.EXPAND) bb_vbox.Add(sweep_bb_hbox, 0, wx.EXPAND) bb_vbox.Add(tone_bb_hbox, 0, wx.EXPAND) - set_type(self.tb[usrp_siggen.TYPE_KEY]) + set_type(self.tb[uhd_siggen.TYPE_KEY]) + ################################################## # Frequency controls ################################################## - fc_vbox = forms.static_box_sizer(parent=self.panel, label="Center Frequency", orient=wx.VERTICAL, bold=True) + fc_vbox = forms.static_box_sizer(parent=self.panel, + label="Center Frequency", + orient=wx.VERTICAL, + bold=True) fc_vbox.AddSpacer(5) # First row of frequency controls (center frequency) freq_hbox = wx.BoxSizer(wx.HORIZONTAL) @@ -145,42 +149,47 @@ class app_gui(pubsub): proportion=1, converter=forms.float_converter(), ps=self.tb, - key=usrp_siggen.TX_FREQ_KEY, + key=uhd_siggen.TX_FREQ_KEY, ) freq_hbox.AddSpacer(10) + forms.slider( parent=self.panel, sizer=freq_hbox, proportion=2, ps=self.tb, - key=usrp_siggen.TX_FREQ_KEY, - minimum=self.tb[usrp_siggen.FREQ_RANGE_KEY][0], - maximum=self.tb[usrp_siggen.FREQ_RANGE_KEY][1], + key=uhd_siggen.TX_FREQ_KEY, + minimum=self.tb[uhd_siggen.FREQ_RANGE_KEY].start(), + maximum=self.tb[uhd_siggen.FREQ_RANGE_KEY].stop(), num_steps=100, ) freq_hbox.AddSpacer(5) tr_hbox.AddSpacer(5) forms.static_text( parent=self.panel, sizer=tr_hbox, - label='Daughterboard (Hz)', + label='RF Frequency', ps=self.tb, - key=usrp_siggen.BB_FREQ_KEY, + key=uhd_siggen.RF_FREQ_KEY, converter=forms.float_converter(), proportion=1, ) tr_hbox.AddSpacer(10) forms.static_text( parent=self.panel, sizer=tr_hbox, - label='USRP DDC (Hz)', + label='DSP Frequency', ps=self.tb, - key=usrp_siggen.DDC_FREQ_KEY, + key=uhd_siggen.DSP_FREQ_KEY, converter=forms.float_converter(), proportion=1, ) tr_hbox.AddSpacer(5) + ################################################## # Amplitude controls ################################################## - amp_hbox = forms.static_box_sizer(parent=self.panel, label="Amplitude", orient=wx.VERTICAL, bold=True) + amp_hbox = forms.static_box_sizer(parent=self.panel, + label="Amplitude", + orient=wx.VERTICAL, + bold=True) amp_hbox.AddSpacer(5) # First row of amp controls (ampl) lvl_hbox = wx.BoxSizer(wx.HORIZONTAL) @@ -199,7 +208,7 @@ class app_gui(pubsub): proportion=1, converter=forms.float_converter(), ps=self.tb, - key=usrp_siggen.AMPLITUDE_KEY, + key=uhd_siggen.AMPLITUDE_KEY, label="Level (0.0-1.0)", ) lvl_hbox.AddSpacer(10) @@ -207,21 +216,21 @@ class app_gui(pubsub): parent=self.panel, sizer=lvl_hbox, proportion=2, ps=self.tb, - key=usrp_siggen.AMPLITUDE_KEY, + key=uhd_siggen.AMPLITUDE_KEY, min_exp=-6, max_exp=0, base=10, num_steps=100, ) lvl_hbox.AddSpacer(5) - if self.tb[usrp_siggen.GAIN_RANGE_KEY][0] < self.tb[usrp_siggen.GAIN_RANGE_KEY][1]: + if self.tb[uhd_siggen.GAIN_RANGE_KEY].start() < self.tb[uhd_siggen.GAIN_RANGE_KEY].stop(): gain_hbox.AddSpacer(5) forms.text_box( parent=self.panel, sizer=gain_hbox, proportion=1, converter=forms.float_converter(), ps=self.tb, - key=usrp_siggen.GAIN_KEY, + key=uhd_siggen.GAIN_KEY, label="TX Gain (dB)", ) gain_hbox.AddSpacer(10) @@ -229,48 +238,40 @@ class app_gui(pubsub): parent=self.panel, sizer=gain_hbox, proportion=2, ps=self.tb, - key=usrp_siggen.GAIN_KEY, - minimum=self.tb[usrp_siggen.GAIN_RANGE_KEY][0], - maximum=self.tb[usrp_siggen.GAIN_RANGE_KEY][1], - step_size=self.tb[usrp_siggen.GAIN_RANGE_KEY][2], + key=uhd_siggen.GAIN_KEY, + minimum=self.tb[uhd_siggen.GAIN_RANGE_KEY].start(), + maximum=self.tb[uhd_siggen.GAIN_RANGE_KEY].stop(), + step_size=self.tb[uhd_siggen.GAIN_RANGE_KEY].step(), ) gain_hbox.AddSpacer(5) + ################################################## # Sample Rate controls ################################################## - sam_hbox = forms.static_box_sizer(parent=self.panel, label="Sample Rate", orient=wx.HORIZONTAL, bold=True) + sam_hbox = forms.static_box_sizer(parent=self.panel, + label="Sample Rate", + orient=wx.HORIZONTAL, + bold=True) self.vbox.Add(sam_hbox, 0, wx.EXPAND) self.vbox.AddSpacer(10) self.vbox.AddStretchSpacer() - sam_hbox.AddSpacer(5) - forms.text_box( - parent=self.panel, sizer=sam_hbox, - converter=forms.int_converter(), - ps=self.tb, - key=usrp_siggen.INTERP_KEY, - label="Interpolation", - ) sam_hbox.AddStretchSpacer(20) forms.static_text( parent=self.panel, sizer=sam_hbox, label='Sample Rate (sps)', ps=self.tb, - key=usrp_siggen.SAMP_RATE_KEY, + key=uhd_siggen.SAMP_RATE_KEY, converter=forms.float_converter(), ) sam_hbox.AddStretchSpacer(20) - forms.static_text( - parent=self.panel, sizer=sam_hbox, - label='Link Rate (bits/sec)', - ps=self.tb, - key=usrp_siggen.LINK_RATE_KEY, - converter=forms.float_converter(), - ) - sam_hbox.AddSpacer(5) + ################################################## - # USRP status + # UHD status ################################################## - u2_hbox = forms.static_box_sizer(parent=self.panel, label="USRP Status", orient=wx.HORIZONTAL, bold=True) + u2_hbox = forms.static_box_sizer(parent=self.panel, + label="UHD Status", + orient=wx.HORIZONTAL, + bold=True) self.vbox.Add(u2_hbox, 0, wx.EXPAND) self.vbox.AddSpacer(10) self.vbox.AddStretchSpacer() @@ -278,7 +279,7 @@ class app_gui(pubsub): forms.static_text( parent=self.panel, sizer=u2_hbox, ps=self.tb, - key=usrp_siggen.DESC_KEY, + key=uhd_siggen.DESC_KEY, converter=forms.str_converter(), ) self.vbox.AddSpacer(5) @@ -287,17 +288,17 @@ class app_gui(pubsub): def main(): try: # Get command line parameters - (options, args) = usrp_siggen.get_options() + (options, args) = uhd_siggen.get_options() # Create the top block using these - tb = usrp_siggen.top_block(options, args) + tb = uhd_siggen.top_block(options, args) # Create the GUI application app = gui.app(top_block=tb, # Constructed top block gui=app_gui, # User interface class options=options, # Command line options args=args, # Command line args - title="USRP Signal Generator", # Top window title + title="UHD Signal Generator", # Top window title nstatus=1, # Number of status lines start=True, # Whether to start flowgraph realtime=True) # Whether to set realtime priority @@ -309,9 +310,9 @@ def main(): print e sys.exit(1) -# Make sure to create the top block (tb) within a function: -# That code in main will allow tb to go out of scope on return, -# which will call the decontructor on usrp and stop transmit. -# Whats odd is that grc works fine with tb in the __main__, -# perhaps its because the try/except clauses around tb. +# Make sure to create the top block (tb) within a function: That code +# in main will allow tb to go out of scope on return, which will call +# the decontructor on uhd device and stop transmit. Whats odd is that +# grc works fine with tb in the __main__, perhaps its because the +# try/except clauses around tb. if __name__ == "__main__": main() diff --git a/gr-uhd/examples/.gitignore b/gr-uhd/examples/.gitignore new file mode 100644 index 000000000..ad8a13c08 --- /dev/null +++ b/gr-uhd/examples/.gitignore @@ -0,0 +1,5 @@ +/Makefile +/Makefile.in +*.dat +*.32f +*.32fc diff --git a/gnuradio-examples/python/digital/Makefile.am b/gr-uhd/examples/Makefile.am index f9d129400..b10b48928 100644 --- a/gnuradio-examples/python/digital/Makefile.am +++ b/gr-uhd/examples/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2009 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,24 +21,24 @@ include $(top_srcdir)/Makefile.common -ourdatadir = $(exampledir)/digital +SUBDIRS = multi-antenna -dist_ourdata_DATA = \ - README \ - pick_bitrate.py \ - qt_digital_window.ui \ - qt_digital_window.py \ - qt_rx_window.ui \ - qt_rx_window.py \ - receive_path.py \ - transmit_path.py \ - usrp_receive_path.py \ - usrp_transmit_path.py +ourdatadir = $(exampledir)/uhd dist_ourdata_SCRIPTS = \ - benchmark_loopback.py \ - benchmark_rx.py \ - benchmark_tx.py \ - benchmark_qt_rx.py \ - benchmark_qt_loopback.py\ - tunnel.py
\ No newline at end of file + fm_tx4.py \ + fm_tx_2_daughterboards.py \ + max_power.py \ + usrp_am_mw_rcv.py \ + usrp_nbfm_ptt.py \ + usrp_nbfm_rcv.py \ + usrp_spectrum_sense.py \ + usrp_tv_rcv_nogui.py \ + usrp_tv_rcv.py \ + usrp_wfm_rcv2_nogui.py \ + usrp_wfm_rcv_fmdet.py \ + usrp_wfm_rcv_nogui.py \ + usrp_wfm_rcv_pll.py \ + usrp_wfm_rcv.py \ + usrp_wfm_rcv_sca.py \ + usrp_wxapt_rcv.py diff --git a/gnuradio-examples/python/usrp/fm_tx4.py b/gr-uhd/examples/fm_tx4.py index a51668dde..9b39752c1 100755 --- a/gnuradio-examples/python/usrp/fm_tx4.py +++ b/gr-uhd/examples/fm_tx4.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -33,8 +33,7 @@ audio_to_file.py """ from gnuradio import gr, eng_notation -from gnuradio import usrp -from gnuradio import audio +from gnuradio import uhd from gnuradio import blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser @@ -43,7 +42,6 @@ import math import sys from gnuradio.wxgui import stdgui2, fftsink2 -#from gnuradio import tx_debug_gui import wx @@ -54,10 +52,17 @@ class pipeline(gr.hier_block2): def __init__(self, filename, lo_freq, audio_rate, if_rate): gr.hier_block2.__init__(self, "pipeline", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - src = gr.file_source (gr.sizeof_float, filename, True) + gr.io_signature(0, 0, 0), + gr.io_signature(1, 1, gr.sizeof_gr_complex)) + + try: + src = gr.file_source (gr.sizeof_float, filename, True) + except RuntimeError: + sys.stderr.write(("\nError: Could not open file '%s'\n\n" % \ + filename)) + sys.exit(1) + + print audio_rate, if_rate fmtx = blks2.nbfm_tx (audio_rate, if_rate, max_dev=5e3, tau=75e-6) # Local oscillator @@ -78,10 +83,17 @@ class fm_tx_block(stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) parser = OptionParser (option_class=eng_option) - parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, - help="select USRP Tx side A or B") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=400e3, + help="set sample rate (bandwidth) [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set Tx frequency to FREQ [required]", metavar="FREQ") + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") parser.add_option("-n", "--nchannels", type="int", default=4, help="number of Tx channels [1,4]") #parser.add_option("","--debug", action="store_true", default=False, @@ -104,57 +116,54 @@ class fm_tx_block(stdgui2.std_top_block): # ---------------------------------------------------------------- # Set up constants and parameters - self.u = usrp.sink_c () # the USRP sink (consumes samples) + self.u = uhd.usrp_sink(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + self.usrp_rate = options.samp_rate + self.u.set_samp_rate(self.usrp_rate) + self.usrp_rate = self.u.get_samp_rate() - self.dac_rate = self.u.dac_rate() # 128 MS/s - self.usrp_interp = 400 - self.u.set_interp_rate(self.usrp_interp) - self.usrp_rate = self.dac_rate / self.usrp_interp # 320 kS/s self.sw_interp = 10 self.audio_rate = self.usrp_rate / self.sw_interp # 32 kS/s - # determine the daughterboard subdevice we're using - if options.tx_subdev_spec is None: - options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u) + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2 - m = usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec) - #print "mux = %#04x" % (m,) - self.u.set_mux(m) - self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec) - print "Using TX d'board %s" % (self.subdev.side_and_name(),) + self.set_gain(options.gain) + self.set_freq(options.freq) - self.subdev.set_gain(self.subdev.gain_range()[1]) # set max Tx gain - if not self.set_freq(options.freq): - freq_range = self.subdev.freq_range() - print "Failed to set frequency to %s. Daughterboard supports %s to %s" % ( - eng_notation.num_to_str(options.freq), - eng_notation.num_to_str(freq_range[0]), - eng_notation.num_to_str(freq_range[1])) - raise SystemExit - self.subdev.set_enable(True) # enable transmitter + if(options.antenna): + self.u.set_antenna(options.antenna, 0) - sum = gr.add_cc () + self.sum = gr.add_cc () # Instantiate N NBFM channels step = 25e3 - offset = (0 * step, 1 * step, -1 * step, 2 * step, -2 * step, 3 * step, -3 * step) + offset = (0 * step, 1 * step, -1 * step, + 2 * step, -2 * step, 3 * step, -3 * step) + for i in range (options.nchannels): t = pipeline("audio-%d.dat" % (i % 4), offset[i], self.audio_rate, self.usrp_rate) - self.connect(t, (sum, i)) + self.connect(t, (self.sum, i)) - gain = gr.multiply_const_cc (4000.0 / options.nchannels) + self.gain = gr.multiply_const_cc (1.0 / options.nchannels) # connect it all - self.connect (sum, gain) - self.connect (gain, self.u) + self.connect (self.sum, self.gain) + self.connect (self.gain, self.u) # plot an FFT to verify we are sending what we want if 1: post_mod = fftsink2.fft_sink_c(panel, title="Post Modulation", - fft_size=512, sample_rate=self.usrp_rate, - y_per_div=20, ref_level=40) - self.connect (sum, post_mod) + fft_size=512, + sample_rate=self.usrp_rate, + y_per_div=20, + ref_level=40) + self.connect (self.gain, post_mod) vbox.Add (post_mod.win, 1, wx.EXPAND) @@ -177,18 +186,17 @@ class fm_tx_block(stdgui2.std_top_block): any residual_freq to the s/w freq translater. """ - r = self.u.tune(self.subdev.which(), self.subdev, target_freq) + r = self.u.set_center_freq(target_freq, 0) if r: - print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq) - print "r.dxc_freq =", eng_notation.num_to_str(r.dxc_freq) - print "r.residual_freq =", eng_notation.num_to_str(r.residual_freq) - print "r.inverted =", r.inverted - - # Could use residual_freq in s/w freq translator + print "Frequency =", eng_notation.num_to_str(self.u.get_center_freq()) return True return False + def set_gain(self, gain): + self.u.set_gain(gain, 0) + + def main (): app = stdgui2.stdapp(fm_tx_block, "Multichannel FM Tx", nstatus=1) app.MainLoop () diff --git a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py b/gr-uhd/examples/fm_tx_2_daughterboards.py index 15fdf2831..36d237616 100755 --- a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py +++ b/gr-uhd/examples/fm_tx_2_daughterboards.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -30,14 +30,10 @@ Side A is 600 Hz tone. Side B is 350 + 440 Hz tones. """ -from gnuradio import gr +from gnuradio import gr, uhd, blks2 from gnuradio.eng_notation import num_to_str, str_to_num -from gnuradio import usrp -from gnuradio import audio -from gnuradio import blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser -from usrpm import usrp_dbid import math import sys @@ -90,8 +86,17 @@ class my_top_block(gr.top_block): def __init__(self): gr.top_block.__init__(self) - usage="%prog: [options] side-A-tx-freq side-B-tx-freq" + usage="%prog: [options] tx-freq0 tx-freq1" parser = OptionParser (option_class=eng_option, usage=usage) + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=320e3, + help="set sample rate [default=%default]") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") (options, args) = parser.parse_args () if len(args) != 2: @@ -104,32 +109,45 @@ class my_top_block(gr.top_block): # ---------------------------------------------------------------- # Set up USRP to transmit on both daughterboards - self.u = usrp.sink_c(nchan=2) # say we want two channels + d = uhd.device_find(uhd.device_addr(options.address)) + uhd_type = d[0].get('type') - self.dac_rate = self.u.dac_rate() # 128 MS/s - self.usrp_interp = 400 - self.u.set_interp_rate(self.usrp_interp) - self.usrp_rate = self.dac_rate / self.usrp_interp # 320 kS/s + self.u = uhd.usrp_sink(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=2) - # we're using both daughterboard slots, thus subdev is a 2-tuple - self.subdev = (self.u.db(0, 0), self.u.db(1, 0)) - print "Using TX d'board %s" % (self.subdev[0].side_and_name(),) - print "Using TX d'board %s" % (self.subdev[1].side_and_name(),) - - # set up the Tx mux so that - # channel 0 goes to Slot A I&Q and channel 1 to Slot B I&Q - self.u.set_mux(0xba98) + # Set up USRP system based on type + if(uhd_type == "usrp"): + self.u.set_subdev_spec("A:0 B:0") + tr0 = uhd.tune_request(freq0) + tr1 = uhd.tune_request(freq1) - self.subdev[0].set_gain(self.subdev[0].gain_range()[1]) # set max Tx gain - self.subdev[1].set_gain(self.subdev[1].gain_range()[1]) # set max Tx gain + else: + if abs(freq0 - freq1) > 5.5e6: + sys.stderr.write("\nError: When not using two separate d'boards, frequencies must bewithin 5.5MHz of each other.\n") + raise SystemExit + + self.u.set_subdev_spec("A:0 A:0") + + mid_freq = (freq0 + freq1)/2.0 + tr0 = uhd.tune_request(freq0, rf_freq=mid_freq, + rf_freq_policy=uhd.tune_request.POLICY_MANUAL) + + tr1 = uhd.tune_request(freq1, rf_freq=mid_freq, + rf_freq_policy=uhd.tune_request.POLICY_MANUAL) + + # Use the tune requests to tune each channel + self.set_freq(tr0, 0) + self.set_freq(tr1, 1) + + self.usrp_rate = options.samp_rate - self.set_freq(0, freq0) - self.set_freq(1, freq1) - self.subdev[0].set_enable(True) # enable transmitter - self.subdev[1].set_enable(True) # enable transmitter + self.u.set_samp_rate(self.usrp_rate) + dev_rate = self.u.get_samp_rate() # ---------------------------------------------------------------- - # build two signal sources, interleave them, amplify and connect them to usrp + # build two signal sources, interleave them, amplify and + # connect them to usrp sig0 = example_signal_0(self.usrp_rate) sig1 = example_signal_1(self.usrp_rate) @@ -138,43 +156,45 @@ class my_top_block(gr.top_block): self.connect(sig0, (intl, 0)) self.connect(sig1, (intl, 1)) - # apply some gain - if_gain = 10000 - ifamp = gr.multiply_const_cc(if_gain) - + # Correct for any difference in requested and actual rates + rrate = self.usrp_rate / dev_rate + resamp = blks2.pfb_arb_resampler_ccf(rrate) + # and wire them up - self.connect(intl, ifamp, self.u) - + self.connect(intl, resamp, self.u) + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 + + self.set_gain(options.gain, 0) + self.set_gain(options.gain, 1) - def set_freq(self, side, target_freq): + def set_freq(self, target_freq, chan): """ Set the center frequency we're interested in. @param side: 0 = side A, 1 = side B @param target_freq: frequency in Hz @rtype: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital up converter. """ - print "Tuning side %s to %sHz" % (("A", "B")[side], num_to_str(target_freq)) - r = self.u.tune(self.subdev[side].which(), self.subdev[side], target_freq) + print "Tuning channel %s to %sHz" % \ + (chan, num_to_str(target_freq)) + + r = self.u.set_center_freq(target_freq, chan) + if r: - print " r.baseband_freq =", num_to_str(r.baseband_freq) - print " r.dxc_freq =", num_to_str(r.dxc_freq) - print " r.residual_freq =", num_to_str(r.residual_freq) - print " r.inverted =", r.inverted - print " OK" return True else: - print " Failed!" + print " Set Frequency Failed!" return False + def set_gain(self, gain, chan): + self.u.set_gain(gain, chan) if __name__ == '__main__': try: diff --git a/gr-uhd/examples/max_power.py b/gr-uhd/examples/max_power.py new file mode 100755 index 000000000..44d3beeee --- /dev/null +++ b/gr-uhd/examples/max_power.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,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. +# + +""" +Setup USRP for maximum power consumption. +""" + + +from gnuradio import gr +from gnuradio import uhd +from gnuradio.eng_option import eng_option +from optparse import OptionParser + +from gnuradio import eng_notation + +n2s = eng_notation.num_to_str + +# Set this to a huge number; UHD will adjust to the +# maximum the USRP xxxx device can handle +MAX_RATE = 1000e6 + +class build_block(gr.top_block): + def __init__(self, address, tx_enable, rx_enable): + gr.top_block.__init__(self) + + d = uhd.device_find(uhd.device_addr(address)) + uhd_type = d[0].get('type') + + print "\nFound '%s' at address '%s'" % \ + (uhd_type, address) + + # Test the type of USRP; if it's a USRP (v1), it has + # 2 channels; otherwise, it has 1 channel + if uhd_type == "usrp": + tx_nchan = 2 + rx_nchan = 2 + else: + tx_nchan = 1 + rx_nchan = 1 + + if tx_enable: + print "\nTRANSMIT CHAIN" + self.u_tx = uhd.usrp_sink(device_addr=address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=tx_nchan) + self.u_tx.set_samp_rate(MAX_RATE) + + self.tx_src0 = gr.sig_source_c(self.u_tx.get_samp_rate(), + gr.GR_CONST_WAVE, + 0, 1.0, 0) + + # Get dboard gain range and select maximum + tx_gain_range = self.u_tx.get_gain_range() + tx_gain = tx_gain_range.stop() + + # Get dboard freq range and select midpoint + tx_freq_range = self.u_tx.get_freq_range() + tx_freq_mid = (tx_freq_range.start() + tx_freq_range.stop())/2.0 + + for i in xrange(tx_nchan): + self.u_tx.set_center_freq (tx_freq_mid + i*1e6, i) + self.u_tx.set_gain(tx_gain, i) + + print "\nTx Sample Rate: %ssps" % (n2s(self.u_tx.get_samp_rate())) + for i in xrange(tx_nchan): + print "Tx Channel %d: " % (i) + print "\tFrequency = %sHz" % \ + (n2s(self.u_tx.get_center_freq(i))) + print "\tGain = %f dB" % (self.u_tx.get_gain(i)) + print "" + + self.connect (self.tx_src0, self.u_tx) + + if rx_enable: + print "\nRECEIVE CHAIN" + self.u_rx = uhd.usrp_source(device_addr=address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=rx_nchan) + self.rx_dst0 = gr.null_sink (gr.sizeof_gr_complex) + + self.u_rx.set_samp_rate(MAX_RATE) + + # Get dboard gain range and select maximum + rx_gain_range = self.u_rx.get_gain_range() + rx_gain = rx_gain_range.stop() + + # Get dboard freq range and select midpoint + rx_freq_range = self.u_rx.get_freq_range() + rx_freq_mid = (rx_freq_range.start() + rx_freq_range.stop())/2.0 + + for i in xrange(tx_nchan): + self.u_rx.set_center_freq (rx_freq_mid + i*1e6, i) + self.u_rx.set_gain(rx_gain, i) + + print "\nRx Sample Rate: %ssps" % (n2s(self.u_rx.get_samp_rate())) + for i in xrange(rx_nchan): + print "Rx Channel %d: " % (i) + print "\tFrequency = %sHz" % \ + (n2s(self.u_rx.get_center_freq(i))) + print "\tGain = %f dB" % (self.u_rx.get_gain(i)) + print "" + + self.connect (self.u_rx, self.rx_dst0) + +def main (): + parser = OptionParser (option_class=eng_option) + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-t", action="store_true", dest="tx_enable", + default=False, help="enable Tx path") + parser.add_option("-r", action="store_true", dest="rx_enable", + default=False, help="enable Rx path") + (options, args) = parser.parse_args () + + tb = build_block (options.address, options.tx_enable, options.rx_enable) + + tb.start () + raw_input ('Press Enter to quit: ') + tb.stop () + +if __name__ == '__main__': + main () diff --git a/gnuradio-examples/python/digital/.gitignore b/gr-uhd/examples/multi-antenna/.gitignore index ff40c06f3..ff40c06f3 100644 --- a/gnuradio-examples/python/digital/.gitignore +++ b/gr-uhd/examples/multi-antenna/.gitignore diff --git a/gnuradio-examples/python/multi-antenna/Makefile.am b/gr-uhd/examples/multi-antenna/Makefile.am index 0cb944589..0cb944589 100644 --- a/gnuradio-examples/python/multi-antenna/Makefile.am +++ b/gr-uhd/examples/multi-antenna/Makefile.am diff --git a/gr-uhd/examples/multi-antenna/multi_fft.py b/gr-uhd/examples/multi-antenna/multi_fft.py new file mode 100755 index 000000000..d4c878c84 --- /dev/null +++ b/gr-uhd/examples/multi-antenna/multi_fft.py @@ -0,0 +1,152 @@ +#!/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, eng_notation +from gnuradio import uhd +from gnuradio.eng_option import eng_option +from gnuradio import eng_notation +from gnuradio import optfir +from optparse import OptionParser +from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2 +from gnuradio.wxgui import scopesink2, form, slider +import wx +import time +import os.path +import sys + +# required FPGA that can do 4 rx channels. + +class my_graph(stdgui2.std_top_block): + + def __init__(self, frame, panel, vbox, argv): + stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) + + self.frame = frame + self.panel = panel + + parser = OptionParser (option_class=eng_option) + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate (bandwidth) [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + parser.add_option("-F", "--filter", action="store_true", default=True, + help="Enable channel filter") + parser.add_option("-N", "--nchans", type="int", default=1, + help="set number of channels (default=%default)") + (options, args) = parser.parse_args() + + if len(args) != 0: + parser.print_help() + raise SystemExit + + self.nchans = options.nchans + + if options.filter: + sw_decim = 4 + else: + sw_decim = 1 + + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=self.nchans) + self.u.set_samp_rate(options.samp_rate) + input_rate = self.u.get_samp_rate() + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2 + + if options.freq is None: + # if no freq was specified, use the mid-point + r = self.u.get_freq_range() + options.freq = float(r.start()+r.stop())/2 + + self.set_gain(options.gain) + self.set_freq(options.freq) + + #if self.u.nddcs() < nchan: + # sys.stderr.write('This code requires an FPGA build with %d DDCs. This FPGA has only %d.\n' % ( + # nchan, self.u.nddcs())) + # raise SystemExit + + #if (len (self.subdev) < 4 or + # self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX or + # self.u.db(0, 0).dbid() != usrp_dbid.BASIC_RX): + # sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n') + # sys.exit(1) + + # deinterleave four channels from FPGA + di = gr.deinterleave(gr.sizeof_gr_complex) + + self.connect(self.u, di) + + # taps for channel filter + chan_filt_coeffs = optfir.low_pass (1, # gain + input_rate, # sampling rate + 80e3, # passband cutoff + 115e3, # stopband cutoff + 0.1, # passband ripple + 60) # stopband attenuation + #print len(chan_filt_coeffs) + + for i in range(self.nchans): + scope = fftsink2.fft_sink_c(panel, sample_rate=input_rate/sw_decim, + title="Input %d" % (i,), + ref_level=80, y_per_div=20) + vbox.Add(scope.win, 10, wx.EXPAND) + + if options.filter: + chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs) + self.connect((di, i), chan_filt, scope) + else: + self.connect((di, i), scope) + + def set_gain(self, gain): + for i in range(self.nchans): + self.u.set_gain(gain, i) + + + def set_freq(self, target_freq): + for i in range(self.nchans): + r = self.u.set_center_freq(target_freq, 0) + + if r: + return True + else: + print "set_freq: failed to set subdev[%d] freq to %f" % \ + (i, target_freq) + return False + +def main (): + app = stdgui2.stdapp(my_graph, "Multi Scope", nstatus=1) + app.MainLoop() + +if __name__ == '__main__': + main () diff --git a/gnuradio-examples/python/multi-antenna/multi_file.py b/gr-uhd/examples/multi-antenna/multi_file.py index 87d9085e3..87d9085e3 100755 --- a/gnuradio-examples/python/multi-antenna/multi_file.py +++ b/gr-uhd/examples/multi-antenna/multi_file.py diff --git a/gnuradio-examples/python/multi-antenna/multi_scope.py b/gr-uhd/examples/multi-antenna/multi_scope.py index d1e28ad18..d1e28ad18 100755 --- a/gnuradio-examples/python/multi-antenna/multi_scope.py +++ b/gr-uhd/examples/multi-antenna/multi_scope.py diff --git a/gnuradio-examples/python/usrp/usrp_am_mw_rcv.py b/gr-uhd/examples/usrp_am_mw_rcv.py index 60f6c5825..130bdcf56 100755 --- a/gnuradio-examples/python/usrp/usrp_am_mw_rcv.py +++ b/gr-uhd/examples/usrp_am_mw_rcv.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,9 +20,9 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, eng_notation, optfir +from gnuradio import gr, eng_notation, optfir from gnuradio import audio -from gnuradio import usrp +from gnuradio import uhd from gnuradio import blks2 from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate @@ -33,30 +33,18 @@ import sys import math import wx -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: BASIC_RX,TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.BASIC_RX, - usrp_dbid.LF_RX, - usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO)) - - class wfm_rx_block (stdgui2.std_top_block): - def __init__(self,frame,panel,vbox,argv): - stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) + def __init__(self, frame, panel, vbox, argv): + stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate (bandwidth) [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=1008.0e3, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-I", "--use-if-freq", action="store_true", default=False, @@ -86,77 +74,72 @@ class wfm_rx_block (stdgui2.std_top_block): self.freq = 0 # build graph + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + usrp_rate = 256e3 + demod_rate = 64e3 + audio_rate = 32e3 + chanfilt_decim = int(usrp_rate // demod_rate) + audio_decim = int(demod_rate // audio_rate) + + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() - #TODO: add an AGC after the channel filter and before the AM_demod + # Resample signal to exactly self.usrp_rate + # FIXME: make one of the follow-on filters an arb resampler + rrate = usrp_rate / dev_rate + self.resamp = blks2.pfb_arb_resampler_ccf(rrate) - self.u = usrp.source_c() # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 250 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 256 kS/s - chanfilt_decim = 4 - demod_rate = usrp_rate / chanfilt_decim # 64 kHz - audio_decimation = 2 - audio_rate = demod_rate / audio_decimation # 32 kHz - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) - - - chan_filt_coeffs = optfir.low_pass (1, # gain - usrp_rate, # sampling rate - 8e3, # passband cutoff - 12e3, # stopband cutoff - 1.0, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - self.chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) + chan_filt_coeffs = gr.firdes.low_pass_2 (1, # gain + usrp_rate, # sampling rate + 8e3, # passband cutoff + 4e3, # transition bw + 60) # stopband attenuation + if self.use_IF: # Turn If to baseband and filter. - self.chan_filt = gr.freq_xlating_fir_filter_ccf (chanfilt_decim, chan_filt_coeffs, self.IF_freq, usrp_rate) + self.chan_filt = gr.freq_xlating_fir_filter_ccf (chanfilt_decim, + chan_filt_coeffs, + self.IF_freq, + usrp_rate) else: self.chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - self.am_demod = gr.complex_to_mag() + self.agc = gr.agc_cc(0.1, 1, 1, 100000) + self.am_demod = gr.complex_to_mag() self.volume_control = gr.multiply_const_ff(self.vol) - audio_filt_coeffs = optfir.low_pass (1, # gain - demod_rate, # sampling rate - 8e3, # passband cutoff - 10e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - self.audio_filt=gr.fir_filter_fff(audio_decimation,audio_filt_coeffs) + audio_filt_coeffs = gr.firdes.low_pass_2 (1, # gain + demod_rate, # sampling rate + 8e3, # passband cutoff + 2e3, # transition bw + 60) # stopband attenuation + self.audio_filt=gr.fir_filter_fff(audio_decim, audio_filt_coeffs) + # sound card as final sink - audio_sink = audio.sink (int (audio_rate), - options.audio_output, - False) # ok_to_block + self.audio_sink = audio.sink (int (audio_rate), + options.audio_output, + False) # ok_to_block # now wire it all together - self.connect (self.u, self.chan_filt, self.am_demod, self.audio_filt, self.volume_control, audio_sink) + self.connect (self.u, self.resamp, self.chan_filt, self.agc, + self.am_demod, self.audio_filt, + self.volume_control, self.audio_sink) self._build_gui(vbox, usrp_rate, demod_rate, audio_rate) if options.gain is None: - g = self.subdev.gain_range() + g = self.u.get_gain_range() if True: - # if no gain was specified, use the maximum gain available - # (usefull for Basic_RX which is relatively deaf and the most probable board to be used for AM) - # TODO: check db type to decide on default gain. - options.gain = float(g[1]) - else: - # if no gain was specified, use the mid-point in dB - options.gain = float(g[0]+g[1])/2 - + # if no gain was specified, use the mid gain + options.gain = (g.start() + g.stop())/2.0 + options.gain = g.stop() if options.volume is None: - g = self.volume_range() - options.volume = float(g[0]*3+g[1])/4 + v = self.volume_range() + options.volume = float(v[0]*3+v[1])/4.0 if abs(options.freq) < 1e3: options.freq *= 1e3 @@ -168,6 +151,8 @@ class wfm_rx_block (stdgui2.std_top_block): if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") + if(options.antenna): + self.u.set_antenna(options.antenna, 0) def _set_status_msg(self, msg, which=0): self.frame.GetStatusBar().SetStatusText(msg, which) @@ -179,7 +164,7 @@ class wfm_rx_block (stdgui2.std_top_block): return self.set_freq(kv['freq']) - if 1: + if 0: self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate, ref_scale=32768.0, ref_level=0.0, y_divs=12) @@ -233,9 +218,10 @@ class wfm_rx_block (stdgui2.std_top_block): callback=self.set_vol) hbox.Add((5,0), 1) + g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -291,14 +277,8 @@ class wfm_rx_block (stdgui2.std_top_block): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. """ - r = usrp.tune(self.u, 0, self.subdev, target_freq + self.IF_freq) - #TODO: check if db is inverting the spectrum or not to decide if we should do + self.IF_freq or - self.IF_freq + r = self.u.set_center_freq(target_freq + self.IF_freq, 0) if r: self.freq = target_freq @@ -313,7 +293,7 @@ class wfm_rx_block (stdgui2.std_top_block): def set_gain(self, gain): self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) + self.u.set_gain(gain) def update_status_bar (self): msg = "Volume:%r Setting:%s" % (self.vol, self.state) diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py b/gr-uhd/examples/usrp_nbfm_ptt.py index 3ce1e0c49..af3b132f4 100755 --- a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py +++ b/gr-uhd/examples/usrp_nbfm_ptt.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2007 Free Software Foundation, Inc. +# Copyright 2005,2007.2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -25,10 +25,7 @@ import sys import wx from optparse import OptionParser -from gnuradio import gr, gru, eng_notation -from gnuradio import usrp -from gnuradio import audio -from gnuradio import blks2 +from gnuradio import gr, audio, blks2, uhd from gnuradio.eng_option import eng_option from gnuradio.wxgui import stdgui2, fftsink2, scopesink2, slider, form from usrpm import usrp_dbid @@ -51,14 +48,17 @@ class ptt_block(stdgui2.std_top_block): self.space_bar_pressed = False parser = OptionParser (option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B") - parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, - help="select USRP Tx side A or B") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") parser.add_option ("-f", "--freq", type="eng_float", default=442.1e6, help="set Tx and Rx frequency to FREQ", metavar="FREQ") parser.add_option ("-g", "--rx-gain", type="eng_float", default=None, help="set rx gain [default=midpoint in dB]") + parser.add_option ("", "--tx-gain", type="eng_float", default=None, + help="set tx gain [default=midpoint in dB]") parser.add_option("-I", "--audio-input", type="string", default="", help="pcm input device name. E.g., hw:0,0 or /dev/dsp") parser.add_option("-O", "--audio-output", type="string", default="", @@ -73,8 +73,10 @@ class ptt_block(stdgui2.std_top_block): if options.freq < 1e6: options.freq *= 1e6 - self.txpath = transmit_path(options.tx_subdev_spec, options.audio_input) - self.rxpath = receive_path(options.rx_subdev_spec, options.rx_gain, options.audio_output) + self.txpath = transmit_path(options.address, options.tx_gain, + options.audio_input) + self.rxpath = receive_path(options.address, options.rx_gain, + options.audio_output) self.connect(self.txpath) self.connect(self.rxpath) @@ -152,10 +154,10 @@ class ptt_block(stdgui2.std_top_block): vbox.Add (rx_fft.win, 1, wx.EXPAND) if 1 and not(no_gui): - rx_fft = fftsink2.fft_sink_c(panel, title="Post s/w DDC", + rx_fft = fftsink2.fft_sink_c(panel, title="Post s/w Resampler", fft_size=512, sample_rate=self.rxpath.quad_rate, ref_level=80, y_per_div=20) - self.connect (self.rxpath.ddc, rx_fft) + self.connect (self.rxpath.resamp, rx_fft) vbox.Add (rx_fft.win, 1, wx.EXPAND) if 0 and not(no_gui): @@ -199,10 +201,12 @@ class ptt_block(stdgui2.std_top_block): form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch", weight=3, range=self.rxpath.squelch_range(), callback=self.set_squelch) + + g = self.rxpath.u.get_gain_range() hbox.Add((5,0), 0) myform['rx_gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Rx Gain", - weight=3, range=self.rxpath.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_rx_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -269,19 +273,20 @@ class ptt_block(stdgui2.std_top_block): # //////////////////////////////////////////////////////////////////////// class transmit_path(gr.hier_block2): - def __init__(self, subdev_spec, audio_input): + def __init__(self, address, gain, audio_input): gr.hier_block2.__init__(self, "transmit_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - self.u = usrp.sink_c () + self.u = uhd.usrp_sink(device_addr=address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + self.if_rate = 320e3 + self.audio_rate = 32e3 - dac_rate = self.u.dac_rate(); - self.if_rate = 320e3 # 320 kS/s - self.usrp_interp = int(dac_rate // self.if_rate) - self.u.set_interp_rate(self.usrp_interp) - self.sw_interp = 10 - self.audio_rate = self.if_rate // self.sw_interp # 32 kS/s + self.u.set_samp_rate(self.if_rate) + dev_rate = self.u.get_samp_rate() self.audio_gain = 10 self.normal_gain = 32000 @@ -289,16 +294,16 @@ class transmit_path(gr.hier_block2): self.audio = audio.source(int(self.audio_rate), audio_input) self.audio_amp = gr.multiply_const_ff(self.audio_gain) - lpf = gr.firdes.low_pass (1, # gain - self.audio_rate, # sampling rate + lpf = gr.firdes.low_pass (1, # gain + self.audio_rate, # sampling rate 3800, # low pass cutoff freq 300, # width of trans. band gr.firdes.WIN_HANN) # filter type - hpf = gr.firdes.high_pass (1, # gain - self.audio_rate, # sampling rate - 325, # low pass cutoff freq - 50, # width of trans. band + hpf = gr.firdes.high_pass (1, # gain + self.audio_rate, # sampling rate + 325, # low pass cutoff freq + 50, # width of trans. band gr.firdes.WIN_HANN) # filter type audio_taps = convolve(array(lpf),array(hpf)) @@ -311,18 +316,21 @@ class transmit_path(gr.hier_block2): self.fmtx = blks2.nbfm_tx(self.audio_rate, self.if_rate) self.amp = gr.multiply_const_cc (self.normal_gain) - # determine the daughterboard subdevice we're using - if subdev_spec is None: - subdev_spec = usrp.pick_tx_subdevice(self.u) - self.u.set_mux(usrp.determine_tx_mux_value(self.u, subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, subdev_spec) - print "TX using", self.subdev.name() + rrate = dev_rate / self.if_rate + self.resamp = blks2.pfb_arb_resampler_ccf(rrate) self.connect(self.audio, self.audio_amp, self.audio_filt, - (self.add_pl,0), self.fmtx, self.amp, self.u) + (self.add_pl,0), self.fmtx, self.amp, + self.resamp, self.u) + + if gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.get_gain_range() + gain = float(g.start() + g.stop())/2.0 - self.set_gain(self.subdev.gain_range()[1]) # set max Tx gain + self.set_gain(gain) + self.set_enable(False) def set_freq(self, target_freq): """ @@ -330,26 +338,17 @@ class transmit_path(gr.hier_block2): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital up converter. Finally, we feed - any residual_freq to the s/w freq translater. """ - r = self.u.tune(self.subdev.which(), self.subdev, target_freq) + r = self.u.set_center_freq(target_freq) if r: - # Use residual_freq in s/w freq translator return True - return False def set_gain(self, gain): self.gain = gain - self.subdev.set_gain(gain) + self.u.set_gain(gain) def set_enable(self, enable): - self.subdev.set_enable(enable) # set H/W Tx enable if enable: self.amp.set_k (self.normal_gain) else: @@ -362,64 +361,53 @@ class transmit_path(gr.hier_block2): # //////////////////////////////////////////////////////////////////////// class receive_path(gr.hier_block2): - def __init__(self, subdev_spec, gain, audio_output): + def __init__(self, address, gain, audio_output): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - self.u = usrp.source_c () - adc_rate = self.u.adc_rate() - - self.if_rate = 256e3 # 256 kS/s - usrp_decim = int(adc_rate // self.if_rate) - if_decim = 4 - self.u.set_decim_rate(usrp_decim) - self.quad_rate = self.if_rate // if_decim # 64 kS/s - audio_decim = 2 - audio_rate = self.quad_rate // audio_decim # 32 kS/s + self.u = uhd.usrp_source(device_addr=address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) - if subdev_spec is None: - subdev_spec = usrp.pick_rx_subdevice(self.u) - self.subdev = usrp.selected_subdev(self.u, subdev_spec) - print "RX using", self.subdev.name() + self.if_rate = 256e3 + self.quad_rate = 64e3 + self.audio_rate = 32e3 - self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec)) + self.u.set_samp_rate(self.if_rate) + dev_rate = self.u.get_samp_rate() # Create filter to get actual channel we want - chan_coeffs = gr.firdes.low_pass (1.0, # gain - self.if_rate, # sampling rate + nfilts = 32 + chan_coeffs = gr.firdes.low_pass (nfilts, # gain + nfilts*dev_rate, # sampling rate 13e3, # low pass cutoff freq 4e3, # width of trans. band gr.firdes.WIN_HANN) # filter type - print "len(rx_chan_coeffs) =", len(chan_coeffs) - - # Decimating Channel filter with frequency translation - # complex in and out, float taps - self.ddc = gr.freq_xlating_fir_filter_ccf(if_decim, # decimation rate - chan_coeffs, # taps - 0, # frequency translation amount - self.if_rate) # input sample rate + rrate = self.quad_rate / dev_rate + self.resamp = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) # instantiate the guts of the single channel receiver - self.fmrx = blks2.nbfm_rx(audio_rate, self.quad_rate) + self.fmrx = blks2.nbfm_rx(self.audio_rate, self.quad_rate) # standard squelch block - self.squelch = blks2.standard_squelch(audio_rate) + self.squelch = blks2.standard_squelch(self.audio_rate) # audio gain / mute block self._audio_gain = gr.multiply_const_ff(1.0) # sound card as final sink - audio_sink = audio.sink (int(audio_rate), audio_output) + audio_sink = audio.sink (int(self.audio_rate), audio_output) # now wire it all together - self.connect (self.u, self.ddc, self.fmrx, self.squelch, self._audio_gain, audio_sink) + self.connect (self.u, self.resamp, self.fmrx, self.squelch, + self._audio_gain, audio_sink) if gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + gain = float(g.start() + g.stop())/2.0 self.enabled = True self.set_gain(gain) @@ -463,26 +451,15 @@ class receive_path(gr.hier_block2): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter in the - FPGA. Finally, we feed any residual_freq to the s/w freq - translator. """ - r = self.u.tune(0, self.subdev, target_freq) + r = self.u.set_center_freq(target_freq) if r: - # Use residual_freq in s/w freq translater - # print "residual_freq =", r.residual_freq - self.ddc.set_center_freq(-r.residual_freq) return True - return False def set_gain(self, gain): self.gain = gain - self.subdev.set_gain(gain) + self.u.set_gain(gain) # //////////////////////////////////////////////////////////////////////// diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py b/gr-uhd/examples/usrp_nbfm_rcv.py index 4c66fc970..2dc69423c 100755 --- a/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py +++ b/gr-uhd/examples/usrp_nbfm_rcv.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2007 Free Software Foundation, Inc. +# Copyright 2005,2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,20 +20,15 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks2 +from gnuradio import gr, audio, blks2, uhd from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser -from usrpm import usrp_dbid import sys import math import wx - #//////////////////////////////////////////////////////////////////////// # Control Stuff #//////////////////////////////////////////////////////////////////////// @@ -43,8 +38,11 @@ class my_top_block (stdgui2.std_top_block): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=146.585e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, @@ -70,7 +68,8 @@ class my_top_block (stdgui2.std_top_block): self.freq = 0 self.freq_step = 25e3 - self.rxpath = receive_path(options.rx_subdev_spec, options.gain, options.audio_output) + self.rxpath = receive_path(options.address, options.antenna, + options.gain, options.audio_output) self.connect(self.rxpath) self._build_gui(vbox, options.no_gui) @@ -99,34 +98,47 @@ class my_top_block (stdgui2.std_top_block): self.src_fft = None - if 1 and not(no_gui): - self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", - fft_size=512, sample_rate=self.rxpath.if_rate, - ref_scale=32768.0, ref_level=0, y_per_div=10, y_divs=12) + if 0 and not(no_gui): + self.src_fft = fftsink2.fft_sink_c(self.panel, + title="Data from USRP", + fft_size=512, + sample_rate=self.rxpath.if_rate, + ref_scale=32768.0, + ref_level=0, + y_per_div=10, + y_divs=12) self.connect (self.rxpath.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 1 and not(no_gui): - rx_fft = fftsink2.fft_sink_c(self.panel, title="Post s/w DDC", - fft_size=512, sample_rate=self.rxpath.quad_rate, - ref_level=80, y_per_div=20) - self.connect (self.rxpath.ddc, rx_fft) + rx_fft = fftsink2.fft_sink_c(self.panel, + title="Post s/w Resampling", + fft_size=512, + sample_rate=self.rxpath.quad_rate, + ref_level=80, + y_per_div=20) + self.connect (self.rxpath.resamp, rx_fft) vbox.Add (rx_fft.win, 4, wx.EXPAND) if 1 and not(no_gui): - post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post Deemph", - fft_size=512, sample_rate=self.rxpath.audio_rate, - y_per_div=10, ref_level=-40) + post_deemph_fft = fftsink2.fft_sink_f(self.panel, + title="Post Deemph", + fft_size=512, + sample_rate=self.rxpath.audio_rate, + y_per_div=10, + ref_level=-40) self.connect (self.rxpath.fmrx.deemph, post_deemph_fft) vbox.Add (post_deemph_fft.win, 4, wx.EXPAND) if 0: - post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Filter", - fft_size=512, sample_rate=audio_rate, - y_per_div=10, ref_level=-40) + post_filt_fft = fftsink2.fft_sink_f(self.panel, + title="Post Filter", + fft_size=512, + sample_rate=audio_rate, + y_per_div=10, + ref_level=-40) self.connect (self.guts.audio_filter, post_filt) vbox.Add (fft_win4, 4, wx.EXPAND) - # control area form at bottom self.myform = myform = form.form() @@ -134,7 +146,8 @@ class my_top_block (stdgui2.std_top_block): hbox.Add((5,0), 0) myform['freq'] = form.float_field( parent=self.panel, sizer=hbox, label="Freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) + callback=myform.check_input_and_call(_form_set_freq, + self._set_status_msg)) #hbox.Add((5,0), 0) #myform['freq_slider'] = \ @@ -157,10 +170,11 @@ class my_top_block (stdgui2.std_top_block): form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch", weight=3, range=self.rxpath.squelch_range(), callback=self.set_squelch) + g = self.rxpath.u.get_gain_range() hbox.Add((5,0), 0) myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.rxpath.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -246,45 +260,31 @@ class my_top_block (stdgui2.std_top_block): USE_SIMPLE_SQUELCH = False class receive_path(gr.hier_block2): - def __init__(self, subdev_spec, gain, audio_output): + def __init__(self, address, antenna, gain, audio_output): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature - self.u = usrp.source_c () - adc_rate = self.u.adc_rate() + self.u = uhd.usrp_source(device_addr=address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) - self.if_rate = 256e3 # 256 kS/s - usrp_decim = int(adc_rate // self.if_rate) - if_decim = 4 - self.u.set_decim_rate(usrp_decim) - self.quad_rate = self.if_rate // if_decim # 64 kS/s - audio_decim = 2 - self.audio_rate = self.quad_rate // audio_decim # 32 kS/s + self.if_rate = 256e3 + self.quad_rate = 64e3 + self.audio_rate = 32e3 - - if subdev_spec is None: - subdev_spec = usrp.pick_rx_subdevice(self.u) - self.subdev = usrp.selected_subdev(self.u, subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec)) + self.u.set_samp_rate(self.if_rate) + dev_rate = self.u.get_samp_rate() # Create filter to get actual channel we want - chan_coeffs = gr.firdes.low_pass (1.0, # gain - self.if_rate, # sampling rate - 8e3, # low pass cutoff freq - 2e3, # width of trans. band - gr.firdes.WIN_HANN) # filter type - - print "len(rx_chan_coeffs) =", len(chan_coeffs) - - # Decimating Channel filter with frequency translation - # complex in and out, float taps - self.ddc = gr.freq_xlating_fir_filter_ccf(if_decim, # decimation rate - chan_coeffs, # taps - 0, # frequency translation amount - self.if_rate) # input sample rate + nfilts = 32 + chan_coeffs = gr.firdes.low_pass (nfilts, # gain + nfilts*dev_rate, # sampling rate + 8e3, # low pass cutoff freq + 2e3, # width of trans. band + gr.firdes.WIN_HANN) # filter type + rrate = self.quad_rate / dev_rate + self.resamp = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) if USE_SIMPLE_SQUELCH: self.squelch = gr.simple_squelch_cc(20) @@ -302,24 +302,28 @@ class receive_path(gr.hier_block2): # now wire it all together if USE_SIMPLE_SQUELCH: - self.connect (self.u, self.ddc, self.squelch, self.fmrx, + self.connect (self.u, self.resamp, self.squelch, self.fmrx, self._audio_gain, audio_sink) else: - self.connect (self.u, self.ddc, self.fmrx, self.squelch, + self.connect (self.u, self.resamp, self.fmrx, self.squelch, self._audio_gain, audio_sink) if gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + gain = float(g.start()+g.stop())/2 self.set_gain(gain) v = self.volume_range() self.set_volume((v[0]+v[1])/2) + s = self.squelch_range() self.set_squelch((s[0]+s[1])/2) + if(antenna): + self.u.set_antenna(antenna, 0) + def volume_range(self): return (-20.0, 0.0, 0.5) @@ -351,27 +355,16 @@ class receive_path(gr.hier_block2): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter in the - FPGA. Finally, we feed any residual_freq to the s/w freq - translator. """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) + r = self.u.set_center_freq(target_freq) if r: - # Use residual_freq in s/w freq translater - # print "residual_freq =", r.residual_freq - self.ddc.set_center_freq(-r.residual_freq) return True - return False def set_gain(self, gain): self.gain = gain - self.subdev.set_gain(gain) + self.u.set_gain(gain) # //////////////////////////////////////////////////////////////////////// diff --git a/gnuradio-examples/python/usrp/usrp_spectrum_sense.py b/gr-uhd/examples/usrp_spectrum_sense.py index 90adf1671..e89745b3b 100755 --- a/gnuradio-examples/python/usrp/usrp_spectrum_sense.py +++ b/gr-uhd/examples/usrp_spectrum_sense.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2007 Free Software Foundation, Inc. +# Copyright 2005,2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,16 +20,16 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, eng_notation, optfir, window +from gnuradio import gr, eng_notation, window from gnuradio import audio -from gnuradio import usrp +from gnuradio import uhd from gnuradio.eng_option import eng_option from optparse import OptionParser -from usrpm import usrp_dbid import sys import math import struct +sys.stderr.write("Warning: this is known to have issues on some machines+Python version combinations to seg fault due to the callback in bin_statitics. If you figure out why, we'd love to hear about it!\n") class tune(gr.feval_dd): """ @@ -41,17 +41,20 @@ class tune(gr.feval_dd): def eval(self, ignore): """ - This method is called from gr.bin_statistics_f when it wants to change - the center frequency. This method tunes the front end to the new center - frequency, and returns the new frequency as its result. + This method is called from gr.bin_statistics_f when it wants + to change the center frequency. This method tunes the front + end to the new center frequency, and returns the new frequency + as its result. """ + try: - # We use this try block so that if something goes wrong from here - # down, at least we'll have a prayer of knowing what went wrong. - # Without this, you get a very mysterious: + # We use this try block so that if something goes wrong + # from here down, at least we'll have a prayer of knowing + # what went wrong. Without this, you get a very + # mysterious: # - # terminate called after throwing an instance of 'Swig::DirectorMethodException' - # Aborted + # terminate called after throwing an instance of + # 'Swig::DirectorMethodException' Aborted # # message on stderr. Not exactly helpful ;) @@ -68,7 +71,7 @@ class parse_msg(object): self.vlen = int(msg.arg2()) assert(msg.length() == self.vlen * gr.sizeof_float) - # FIXME consider using Numarray or NumPy vector + # FIXME consider using NumPy array t = msg.to_string() self.raw_data = t self.data = struct.unpack('%df' % (self.vlen,), t) @@ -81,24 +84,25 @@ class my_top_block(gr.top_block): usage = "usage: %prog [options] min_freq max_freq" parser = OptionParser(option_class=eng_option, usage=usage) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0,0), - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate [default=%default]") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") - parser.add_option("", "--tune-delay", type="eng_float", default=1e-3, metavar="SECS", + parser.add_option("", "--tune-delay", type="eng_float", + default=1e-3, metavar="SECS", help="time to delay (in seconds) after changing frequency [default=%default]") - parser.add_option("", "--dwell-delay", type="eng_float", default=10e-3, metavar="SECS", + parser.add_option("", "--dwell-delay", type="eng_float", + default=10e-3, metavar="SECS", help="time to dwell (in seconds) at a given frequncy [default=%default]") parser.add_option("-F", "--fft-size", type="int", default=256, help="specify number of FFT bins [default=%default]") - parser.add_option("-d", "--decim", type="intx", default=16, - help="set decimation to DECIM [default=%default]") parser.add_option("", "--real-time", action="store_true", default=False, help="Attempt to enable real-time scheduling") - parser.add_option("-B", "--fusb-block-size", type="int", default=0, - help="specify fast usb block size [default=%default]") - parser.add_option("-N", "--fusb-nblocks", type="int", default=0, - help="specify number of fast usb blocks [default=%default]") (options, args) = parser.parse_args() if len(args) != 2: @@ -109,11 +113,11 @@ class my_top_block(gr.top_block): self.max_freq = eng_notation.str_to_num(args[1]) if self.min_freq > self.max_freq: - self.min_freq, self.max_freq = self.max_freq, self.min_freq # swap them + # swap them + self.min_freq, self.max_freq = self.max_freq, self.min_freq self.fft_size = options.fft_size - if not options.real_time: realtime = False else: @@ -125,36 +129,14 @@ class my_top_block(gr.top_block): realtime = False print "Note: failed to enable realtime scheduling" - # If the user hasn't set the fusb_* parameters on the command line, - # pick some values that will reduce latency. - - if 1: - if options.fusb_block_size == 0 and options.fusb_nblocks == 0: - if realtime: # be more aggressive - options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'rt_nblocks', 16) - else: - options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) - options.fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) - - #print "fusb_block_size =", options.fusb_block_size - #print "fusb_nblocks =", options.fusb_nblocks - # build graph - - self.u = usrp.source_c(fusb_block_size=options.fusb_block_size, - fusb_nblocks=options.fusb_nblocks) - - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = options.decim - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + usrp_rate = options.samp_rate + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) @@ -186,7 +168,8 @@ class my_top_block(gr.top_block): self.msgq = gr.msg_queue(16) self._tune_callback = tune(self) # hang on to this to keep it from being GC'd stats = gr.bin_statistics_f(self.fft_size, self.msgq, - self._tune_callback, tune_delay, dwell_delay) + self._tune_callback, tune_delay, + dwell_delay) # FIXME leave out the log10 until we speed it up #self.connect(self.u, s2v, fft, c2mag, log, stats) @@ -194,8 +177,8 @@ class my_top_block(gr.top_block): if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 self.set_gain(options.gain) print "gain =", options.gain @@ -209,6 +192,7 @@ class my_top_block(gr.top_block): if not self.set_freq(target_freq): print "Failed to set frequency to", target_freq + sys.exit(1) return target_freq @@ -219,17 +203,15 @@ class my_top_block(gr.top_block): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. """ - return self.u.tune(0, self.subdev, target_freq) + r = self.u.set_center_freq(target_freq) + if r: + return True + return False def set_gain(self, gain): - self.subdev.set_gain(gain) + self.u.set_gain(gain) def main_loop(tb): @@ -254,7 +236,7 @@ def main_loop(tb): if __name__ == '__main__': tb = my_top_block() try: - tb.start() # start executing flow graph in another thread... + tb.start() main_loop(tb) except KeyboardInterrupt: diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv.py b/gr-uhd/examples/usrp_tv_rcv.py index 4e13a83ab..a68867365 100755 --- a/gnuradio-examples/python/usrp/usrp_tv_rcv.py +++ b/gr-uhd/examples/usrp_tv_rcv.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,51 +22,38 @@ """ Realtime capture and display of analog Tv stations. + Can also use a file as source or sink -When you use an output file you can show the results frame-by-frame using ImageMagick -When you want to use the realtime sdl display window you must first install gr-video-sdl (is in gnuradio cvs). -When you use a file source, in stead of the usrp, make sure you capture interleaved shorts. -(Use usrp_rx_file.py, or use usrp_rx_cfile.py --output-shorts if you have a recent enough usrp_rx_cfile.py) -There is no synchronisation yet. The sync blocks are in development but not yet in cvs. +When you use an output file you can show the results frame-by-frame +using ImageMagick + +When you want to use the realtime sdl display window you must first +install gr-video-sdl. + +When you use a file source, instead of the usrp, make sure you +capture interleaved shorts. (Use usrp_rx_file.py, or use +usrp_rx_cfile.py --output-shorts if you have a recent enough +usrp_rx_cfile.py) + +There is no synchronisation yet. The sync blocks are in development +but not yet in cvs. """ -from gnuradio import gr, gru, eng_notation, optfir + +from gnuradio import gr try: from gnuradio import video_sdl except: print "FYI: gr-video-sdl is not installed" print "realtime SDL video output window will not be available" -from gnuradio import usrp +from gnuradio import uhd from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser -from usrpm import usrp_dbid import sys -import math import wx -# To debug, insert this in your test code... -#import os -#print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),) -#raw_input ('Press Enter to continue: ') -# remainder of your test code follows... - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) - class tv_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): @@ -74,11 +61,14 @@ class tv_rx_block (stdgui2.std_top_block): usage="%prog: [options] [input_filename]. \n If you don't specify an input filename the usrp will be used as source\n " \ "Make sure your input capture file containes interleaved shorts not complex floats" - parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") - parser.add_option("-d", "--decim", type="int", default=64, - help="set fgpa decimation rate to DECIM [default=%default]") + parser=OptionParser(option_class=eng_option, usage=usage) + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate") parser.add_option("-f", "--freq", type="eng_float", default=519.25e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, @@ -87,8 +77,6 @@ class tv_rx_block (stdgui2.std_top_block): help="set contrast (default is 1.0)") parser.add_option("-b", "--brightness", type="eng_float", default=0.0, help="set brightness (default is 0)") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") parser.add_option("-p", "--pal", action="store_true", default=False, help="PAL video format (this is the default)") parser.add_option("-n", "--ntsc", action="store_true", default=False, @@ -97,8 +85,10 @@ class tv_rx_block (stdgui2.std_top_block): help="For example out_raw_uchar.gray. If you don't specify an output filename you will get a video_sink_sdl realtime output window. You then need to have gr-video-sdl installed)") parser.add_option("-r", "--repeat", action="store_false", default=True, help="repeat file in a loop") - parser.add_option("-N", "--no-hb", action="store_true", default=False, - help="don't use halfband filter in usrp") + parser.add_option("", "--freq-min", type="eng_float", default=50.25e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=900.25e6, + help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() if not ((len(args) == 1) or (len(args) == 0)): @@ -118,68 +108,70 @@ class tv_rx_block (stdgui2.std_top_block): self.state = "FREQ" self.freq = 0 - # build graph + self.tv_freq_min = options.freq_min + self.tv_freq_max = options.freq_max + # build graph self.u=None - usrp_decim = options.decim # 32 - if not (options.out_filename=="sdl"): options.repeat=False + usrp_rate = options.samp_rate + if not ((filename is None) or (filename=="usrp")): - self.filesource = gr.file_source(gr.sizeof_short,filename,options.repeat) # file is data source + # file is data source + self.filesource = gr.file_source(gr.sizeof_short,filename,options.repeat) self.istoc = gr.interleaved_short_to_complex() self.connect(self.filesource,self.istoc) - adc_rate=64e6 self.src=self.istoc + options.gain=0.0 self.gain=0.0 - else: - if options.no_hb or (options.decim<8): - self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths - else: - self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default) - self.u = usrp.source_c(0,fpga_filename=self.fpga_filename) # usrp is data source - if options.width_8: - sample_width = 8 - sample_shift = 8 - format = self.u.make_format(sample_width, sample_shift) - r = self.u.set_format(format) - adc_rate = self.u.adc_rate() # 64 MS/s - self.u.set_decim_rate(usrp_decim) - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) + + else: # use a UHD device + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() + if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 + self.src=self.u - usrp_rate = adc_rate / usrp_decim # 320 kS/s + self.gain = options.gain f2uc=gr.float_to_uchar() + # sdl window as final sink if not (options.pal or options.ntsc): options.pal=True #set default to PAL + if options.pal: lines_per_frame=625.0 frames_per_sec=25.0 show_width=768 + elif options.ntsc: lines_per_frame=525.0 frames_per_sec=29.97002997 show_width=640 + width=int(usrp_rate/(lines_per_frame*frames_per_sec)) height=int(lines_per_frame) if (options.out_filename=="sdl"): - #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now) + #Here comes the tv screen, you have to build and install + #gr-video-sdl for this (subproject of gnuradio, only in cvs + #for now) try: - video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height) + video_sink = video_sdl.sink_uc ( frames_per_sec, width, height, 0, + show_width, height) except: print "gr-video-sdl is not installed" print "realtime \"sdl\" video output window is not available" @@ -188,7 +180,8 @@ class tv_rx_block (stdgui2.std_top_block): else: print "You can use the imagemagick display tool to show the resulting imagesequence" print "use the following line to show the demodulated TV-signal:" - print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" + options.out_filename + print "display -depth 8 -size " +str(width)+ "x" + str(height) \ + + " gray:" + options.out_filename print "(Use the spacebar to advance to next frames)" options.repeat=False file_sink=gr.file_sink(gr.sizeof_char, options.out_filename) @@ -204,11 +197,23 @@ class tv_rx_block (stdgui2.std_top_block): process_type='do_no_sync' if process_type=='do_no_sync': - self.connect (self.src, self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst) + self.connect (self.src, self.agc,self.am_demod, + self.invert_and_scale, self.set_blacklevel, + f2uc,self.dst) elif process_type=='do_tv_sync_adv': - #defaults: gr.tv_sync_adv (double sampling_freq, unsigned int tv_format,bool output_active_video_only=false, bool do_invert=false, double wanted_black_level=0.0, double wanted_white_level=255.0, double avg_alpha=0.1, double initial_gain=1.0, double initial_offset=0.0,bool debug=false) - self.tv_sync_adv=gr.tv_sync_adv(usrp_rate,0,False,False,0.0,255.0,0.01,1.0,0.0,False) #note, this block is not yet in cvs - self.connect (self.src, self.am_demod,self.invert_and_scale,self.tv_sync_adv,s2f,f2uc,self.dst) + #defaults: gr.tv_sync_adv (double sampling_freq, unsigned + #int tv_format,bool output_active_video_only=false, bool + #do_invert=false, double wanted_black_level=0.0, double + #wanted_white_level=255.0, double avg_alpha=0.1, double + #initial_gain=1.0, double initial_offset=0.0,bool + #debug=false) + + #note, this block is not yet in cvs + self.tv_sync_adv=gr.tv_sync_adv(usrp_rate, 0, False, False, + 0.0, 255.0, 0.01, 1.0, 0.0, False) + self.connect (self.src, self.am_demod, self.invert_and_scale, + self.tv_sync_adv, s2f, f2uc, self.dst) + elif process_type=='do_nullsink': #self.connect (self.src, self.am_demod,self.invert_and_scale,f2uc,video_sink) c2r=gr.complex_to_real() @@ -221,18 +226,30 @@ class tv_rx_block (stdgui2.std_top_block): debug=False video_alpha=0.3 #0.1 corr_alpha=0.3 - tv_corr=gr.tv_correlator_ff(frame_size,nframes, search_window, video_alpha, corr_alpha,debug) #Note: this block is not yet in cvs + + #Note: this block is not yet in cvs + tv_corr=gr.tv_correlator_ff(frame_size,nframes, search_window, + video_alpha, corr_alpha,debug) shift=gr.add_const_ff(-0.7) - self.connect (self.src, self.agc,self.am_demod,tv_corr,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst) #self.agc, + + self.connect (self.src, self.agc, self.am_demod, tv_corr, + self.invert_and_scale, self.set_blacklevel, + f2uc, self.dst) else: # process_type=='do_test_image': - src_vertical_bars = gr.sig_source_f (usrp_rate, gr.GR_SIN_WAVE, 10.0 *usrp_rate/320, 255,128) - self.connect(src_vertical_bars,f2uc,self.dst) + src_vertical_bars = gr.sig_source_f (usrp_rate, gr.GR_SIN_WAVE, + 10.0 *usrp_rate/320, 255,128) + self.connect(src_vertical_bars, f2uc, self.dst) self._build_gui(vbox, usrp_rate, usrp_rate, usrp_rate) + - - if abs(options.freq) < 1e6: - options.freq *= 1e6 + frange = self.u.get_freq_range() + if(frange.start() > self.tv_freq_max or frange.stop() < self.tv_freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + if(options.freq < self.tv_freq_min or options.freq > self.tv_freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) # set initial values self.set_gain(options.gain) @@ -286,7 +303,7 @@ class tv_rx_block (stdgui2.std_top_block): hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, - range=(50.25e6, 900.25e6, 0.25e6), + range=(self.tv_freq_min, self.tv_freq_max, 0.25e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -307,9 +324,10 @@ class tv_rx_block (stdgui2.std_top_block): hbox.Add((5,0), 0) if not (self.u is None): + g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -387,7 +405,7 @@ class tv_rx_block (stdgui2.std_top_block): determine the value for the digital down converter. """ if not (self.u is None): - r = usrp.tune(self.u, 0, self.subdev, target_freq) + r = self.u.set_center_freq(target_freq) if r: self.freq = target_freq self.myform['freq'].set_value(target_freq) # update displayed value @@ -400,17 +418,17 @@ class tv_rx_block (stdgui2.std_top_block): return False def set_gain(self, gain): - if not (self.u is None): - self.gain=gain - self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) - self.update_status_bar() - + if not (self.u is None): + self.gain=gain + self.myform['gain'].set_value(gain) # update displayed value + self.u.set_gain(gain) + self.update_status_bar() + def update_status_bar (self): - msg = "Setting:%s Contrast:%r Brightness:%r Gain: %r" % (self.state, self.contrast,self.brightness,self.gain) - self._set_status_msg(msg, 1) + msg = "Setting:%s Contrast:%r Brightness:%r Gain: %r" % \ + (self.state, self.contrast,self.brightness,self.gain) + self._set_status_msg(msg, 1) #self.src_fft.set_baseband_freq(self.freq) - if __name__ == '__main__': diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py b/gr-uhd/examples/usrp_tv_rcv_nogui.py index e6a8de1be..a44e20d39 100755 --- a/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py +++ b/gr-uhd/examples/usrp_tv_rcv_nogui.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,17 +22,21 @@ """ Reads from a file and generates PAL TV pictures in black and white -which can be displayed using ImageMagick or realtime using gr-video-sdl -(To capture the input file Use usrp_rx_file.py, or use usrp_rx_cfile.py --output-shorts if you have a recent enough usrp_rx_cfile.py) -Can also use usrp directly as capture source, but then you need a higher decimation factor (64) -and thus get a lower horizontal resulution. -There is no synchronisation yet. The sync blocks are in development but not yet in cvs. +which can be displayed using ImageMagick or realtime using +gr-video-sdl (To capture the input file Use usrp_rx_file.py, or use +usrp_rx_cfile.py --output-shorts if you have a recent enough +usrp_rx_cfile.py) + +Can also use usrp directly as capture source, but then you need a +higher decimation factor (64) and thus get a lower horizontal +resulution. There is no synchronisation yet. The sync blocks are in +development but not yet in cvs. """ from gnuradio import gr, eng_notation from gnuradio import audio -from gnuradio import usrp +from gnuradio import uhd from gnuradio.eng_option import eng_option from optparse import OptionParser import sys @@ -49,24 +53,31 @@ class my_top_block(gr.top_block): def __init__(self): gr.top_block.__init__(self) - usage="%prog: [options] output_filename. \n Special output_filename \"sdl\" will use video_sink_sdl as realtime output window. " \ - "You then need to have gr-video-sdl installed. \n" \ - "Make sure your input capture file containes interleaved shorts not complex floats" + usage=("%prog: [options] output_filename.\nSpecial output_filename" + \ + "\"sdl\" will use video_sink_sdl as realtime output window. " + \ + "You then need to have gr-video-sdl installed.\n" +\ + "Make sure your input capture file containes interleaved " + \ + "shorts not complex floats") parser = OptionParser(option_class=eng_option, usage=usage) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0), - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate") parser.add_option("-c", "--contrast", type="eng_float", default=1.0, help="set contrast (default is 1.0)") parser.add_option("-b", "--brightness", type="eng_float", default=0.0, help="set brightness (default is 0)") - parser.add_option("-d", "--decim", type="int", default=8, - help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-i", "--in-filename", type="string", default=None, - help="Use input file as source. samples must be interleaved shorts \n " + - "Use usrp_rx_file.py or usrp_rx_cfile.py --output-shorts. \n" - "Special name \"usrp\" results in realtime capturing and processing using usrp. \n" + - "You then probably need a decimation factor of 64 or higher.") - parser.add_option("-f", "--freq", type="eng_float", default=None, + help="Use input file as source. samples must be " + \ + "interleaved shorts \n Use usrp_rx_file.py or " + \ + "usrp_rx_cfile.py --output-shorts.\n Special " + \ + "name \"usrp\" results in realtime capturing " + \ + "and processing using usrp.\n" + \ + "You then probably need a decimation factor of 64 or higher.") + parser.add_option("-f", "--freq", type="eng_float", default=519.25e6, help="set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") @@ -76,12 +87,12 @@ class my_top_block(gr.top_block): help="NTSC video format") parser.add_option("-r", "--repeat", action="store_false", default=True, help="repeat in_file in a loop") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") parser.add_option("-N", "--nframes", type="eng_float", default=None, help="number of frames to collect [default=+inf]") - parser.add_option( "--no-hb", action="store_true", default=False, - help="don't use halfband filter in usrp") + parser.add_option("", "--freq-min", type="eng_float", default=50.25e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=900.25e6, + help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args () if not (len(args) == 1): parser.print_help() @@ -90,6 +101,9 @@ class my_top_block(gr.top_block): filename = args[0] + self.tv_freq_min = options.freq_min + self.tv_freq_max = options.freq_max + if options.in_filename is None: parser.print_help() sys.stderr.write('You must specify the input -i FILENAME or -i usrp\n'); @@ -98,61 +112,51 @@ class my_top_block(gr.top_block): if not (filename=="sdl"): options.repeat=False + input_rate = options.samp_rate + print "video sample rate %s" % (eng_notation.num_to_str(input_rate)) + if not (options.in_filename=="usrp"): - self.filesource = gr.file_source(gr.sizeof_short,options.in_filename,options.repeat) # file is data source, capture with usr_rx_csfile.py + # file is data source, capture with usr_rx_csfile.py + self.filesource = gr.file_source(gr.sizeof_short, + options.in_filename, + options.repeat) self.istoc = gr.interleaved_short_to_complex() self.connect(self.filesource,self.istoc) - self.adc_rate=64e6 self.src=self.istoc else: if options.freq is None: parser.print_help() sys.stderr.write('You must specify the frequency with -f FREQ\n'); raise SystemExit, 1 - if abs(options.freq) < 1e6: - options.freq *= 1e6 - if options.no_hb or (options.decim<8): - self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths - else: - self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default) # build the graph - self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename) + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + self.u.set_samp_rate(input_rate) + dev_rate = self.u.get_samp_rate() + self.src=self.u - if options.width_8: - sample_width = 8 - sample_shift = 8 - format = self.u.make_format(sample_width, sample_shift) - r = self.u.set_format(format) - self.adc_rate=self.u.adc_freq() - if options.rx_subdev_spec is None: - options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u) - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - # determine the daughterboard subdevice we're using - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - self.subdev.set_gain(options.gain) + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 + self.u.set_gain(options.gain) - r = self.u.tune(0, self.subdev, options.freq) + r = self.u.set_center_freq(options.freq) if not r: sys.stderr.write('Failed to set frequency\n') raise SystemExit, 1 - input_rate = self.adc_rate / options.decim - print "video sample rate %s" % (eng_notation.num_to_str(input_rate)) - - self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7 + self.agc = gr.agc_cc(1e-7,1.0,1.0) #1e-7 self.am_demod = gr.complex_to_mag () - self.set_blacklevel=gr.add_const_ff(options.brightness +255.0) + self.set_blacklevel = gr.add_const_ff(options.brightness +255.0) self.invert_and_scale = gr.multiply_const_ff (-options.contrast *128.0*255.0/(200.0)) - self.f2uc=gr.float_to_uchar() + self.f2uc = gr.float_to_uchar() - # sdl window as final sink + # sdl window as final sink if not (options.pal or options.ntsc): options.pal=True #set default to PAL if options.pal: @@ -167,9 +171,12 @@ class my_top_block(gr.top_block): height=int(lines_per_frame) if filename=="sdl": - #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now) + #Here comes the tv screen, you have to build and install + #gr-video-sdl for this (subproject of gnuradio, only in cvs + #for now) try: - video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height) + video_sink = video_sdl.sink_uc(frames_per_sec, width, height, 0, + show_width,height) except: print "gr-video-sdl is not installed" print "realtime \"sdl\" video output window is not available" @@ -189,9 +196,9 @@ class my_top_block(gr.top_block): self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes*width*height)) self.connect(self.src, self.head, self.agc) - self.connect (self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,self.f2uc,self.dst) + self.connect (self.agc, self.am_demod, self.invert_and_scale, + self.set_blacklevel, self.f2uc, self.dst) - if __name__ == '__main__': try: my_top_block().run() diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv.py b/gr-uhd/examples/usrp_wfm_rcv.py index fba2a1210..7b35fbbe4 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv.py +++ b/gr-uhd/examples/usrp_wfm_rcv.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc. +# Copyright 2005-2007,2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,42 +20,25 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks2 +from gnuradio import gr, optfir, audio, blks2, uhd from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser -from usrpm import usrp_dbid import sys -import math import wx -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) - class wfm_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=40, @@ -64,6 +47,10 @@ class wfm_rx_block (stdgui2.std_top_block): help="set volume (default is midpoint)") parser.add_option("-O", "--audio-output", type="string", default="", help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") + parser.add_option("", "--freq-min", type="eng_float", default=87.9e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=108.1e6, + help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() if len(args) != 0: @@ -77,72 +64,64 @@ class wfm_rx_block (stdgui2.std_top_block): self.state = "FREQ" self.freq = 0 + self.fm_freq_min = options.freq_min + self.fm_freq_max = options.freq_max + # build graph - - self.u = usrp.source_c() # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 200 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 320 kS/s - chanfilt_decim = 1 - demod_rate = usrp_rate / chanfilt_decim - audio_decimation = 10 - audio_rate = demod_rate / audio_decimation # 32 kHz - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) - dbid = self.subdev.dbid() - if not (dbid == usrp_dbid.BASIC_RX or - dbid == usrp_dbid.TV_RX or - dbid == usrp_dbid.TV_RX_REV_2 or - dbid == usrp_dbid.TV_RX_REV_3 or - dbid == usrp_dbid.TV_RX_MIMO or - dbid == usrp_dbid.TV_RX_REV_2_MIMO or - dbid == usrp_dbid.TV_RX_REV_3_MIMO -): - print "This daughterboard does not cover the required frequency range" - print "for this application. Please use a BasicRX or TVRX daughterboard." - raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.") - - chan_filt_coeffs = optfir.low_pass (1, # gain - usrp_rate, # sampling rate - 80e3, # passband cutoff - 115e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - - self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + usrp_rate = 320e3 + demod_rate = 320e3 + audio_rate = 32e3 + audio_decim = int(demod_rate / audio_rate) + + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() + + nfilts = 32 + chan_coeffs = optfir.low_pass (nfilts, # gain + nfilts*usrp_rate, # sampling rate + 80e3, # passband cutoff + 115e3, # stopband cutoff + 0.1, # passband ripple + 60) # stopband attenuation + rrate = usrp_rate / dev_rate + self.chan_filt = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) + + self.guts = blks2.wfm_rcv (demod_rate, audio_decim) self.volume_control = gr.multiply_const_ff(self.vol) # sound card as final sink - audio_sink = audio.sink (int (audio_rate), - options.audio_output, - False) # ok_to_block + self.audio_sink = audio.sink (int (audio_rate), + options.audio_output, + False) # ok_to_block # now wire it all together - self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink) + self.connect (self.u, self.chan_filt, self.guts, + self.volume_control, self.audio_sink) self._build_gui(vbox, usrp_rate, demod_rate, audio_rate) if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2 if options.volume is None: g = self.volume_range() options.volume = float(g[0]+g[1])/2 + + frange = self.u.get_freq_range() + if(frange.start() > self.fm_freq_max or frange.stop() < self.fm_freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + if(options.freq < self.fm_freq_min or options.freq > self.fm_freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) - if abs(options.freq) < 1e6: - options.freq *= 1e6 # set initial values @@ -196,7 +175,7 @@ class wfm_rx_block (stdgui2.std_top_block): hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, - range=(87.9e6, 108.1e6, 0.1e6), + range=(self.fm_freq_min, self.fm_freq_max, 0.1e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -210,9 +189,10 @@ class wfm_rx_block (stdgui2.std_top_block): callback=self.set_vol) hbox.Add((5,0), 1) + g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -268,14 +248,9 @@ class wfm_rx_block (stdgui2.std_top_block): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) - + + r = self.u.set_center_freq(target_freq) if r: self.freq = target_freq self.myform['freq'].set_value(target_freq) # update displayed value @@ -289,7 +264,7 @@ class wfm_rx_block (stdgui2.std_top_block): def set_gain(self, gain): self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) + self.u.set_gain(gain) def update_status_bar (self): msg = "Volume:%r Setting:%s" % (self.vol, self.state) diff --git a/gr-uhd/examples/usrp_wfm_rcv2_nogui.py b/gr-uhd/examples/usrp_wfm_rcv2_nogui.py new file mode 100755 index 000000000..013a6864f --- /dev/null +++ b/gr-uhd/examples/usrp_wfm_rcv2_nogui.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python +# +# Copyright 2005-2007,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, optfir, audio, blks2, uhd +from gnuradio.eng_option import eng_option +from optparse import OptionParser +from usrpm import usrp_dbid +import sys +import math + +class wfm_rx_block (gr.top_block): + + def __init__(self): + gr.top_block.__init__(self) + + parser=OptionParser(option_class=eng_option) + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("", "--f1", type="eng_float", default=100.7e6, + help="set 1st station frequency to FREQ", metavar="FREQ") + parser.add_option("", "--f2", type="eng_float", default=102.5e6, + help="set 2nd station freq to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=40, + help="set gain in dB (default is midpoint)") + parser.add_option("-O", "--audio-output", type="string", default="", + help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") + parser.add_option("", "--freq-min", type="eng_float", default=87.9e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=108.1e6, + help="Set a maximum frequency [default=%default]") + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + + if abs(options.f1 - options.f2) > 5.5e6: + print "Sorry, two stations must be within 5.5MHz of each other" + raise SystemExit + + f = (options.f1, options.f2) + + self.vol = .1 + self.state = "FREQ" + + self.fm_freq_min = options.freq_min + self.fm_freq_max = options.freq_max + + # build graph + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=2) + + # Set front end channel mapping + self.u.set_subdev_spec("A:0 A:0") + + usrp_rate = 320e3 + demod_rate = 320e3 + audio_rate = 32e3 + audio_decim = int(demod_rate / audio_rate) + + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() + + # Make sure dboard can suppor the required frequencies + frange = self.u.get_freq_range() + if(frange.start() > self.fm_freq_max or frange.stop() < self.fm_freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + + # sound card as final sink + self.audio_sink = audio.sink(int(audio_rate), options.audio_output) + + # taps for channel filter + nfilts = 32 + chan_coeffs = optfir.low_pass (nfilts, # gain + nfilts*usrp_rate, # sampling rate + 80e3, # passband cutoff + 115e3, # stopband cutoff + 0.1, # passband ripple + 60) # stopband attenuation + rrate = usrp_rate / dev_rate + + # set front end PLL to middle frequency + mid_freq = (f[0] + f[1]) / 2.0 + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 + + for n in range(2): + chan_filt = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) + guts = blks2.wfm_rcv (demod_rate, audio_decim) + volume_control = gr.multiply_const_ff(self.vol) + + #self.connect((self.di, n), chan_filt) + self.connect((self.u, n), chan_filt) + self.connect(chan_filt, guts, volume_control) + self.connect(volume_control, (self.audio_sink, n)) + + # Test the the requested frequencies are in range + if(f[n] < self.fm_freq_min or f[n] > self.fm_freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) + + # Tune each channel by setting the RF freq to mid_freq and the + # DDC freq to f[n]. + tr = uhd.tune_request(f[n], rf_freq=mid_freq, + rf_freq_policy=uhd.tune_request.POLICY_MANUAL) + self.u.set_center_freq(tr, n) + + # Set gain for each channel + self.set_gain(options.gain, n) + + def set_vol (self, vol): + self.vol = vol + self.volume_control.set_k(self.vol) + + + def set_gain(self, gain, n): + self.u.set_gain(gain, n) + +if __name__ == '__main__': + tb = wfm_rx_block() + try: + tb.run() + except KeyboardInterrupt: + pass diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_fmdet.py b/gr-uhd/examples/usrp_wfm_rcv_fmdet.py index 30744ee01..53ad6edbf 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv_fmdet.py +++ b/gr-uhd/examples/usrp_wfm_rcv_fmdet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,41 +20,28 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks2 +from gnuradio import gr, optfir, audio, blks2, uhd from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate from gnuradio.wxgui import stdgui2, fftsink2, form, scopesink2 from optparse import OptionParser -from usrpm import usrp_dbid import sys -import math import wx -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) +import os +print os.getpid() +raw_input() class wfm_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=65, @@ -65,6 +52,10 @@ class wfm_rx_block (stdgui2.std_top_block): help="set volume (default is midpoint)") parser.add_option("-O", "--audio-output", type="string", default="", help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") + parser.add_option("", "--freq-min", type="eng_float", default=87.9e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=108.1e6, + help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() @@ -79,55 +70,52 @@ class wfm_rx_block (stdgui2.std_top_block): self.state = "FREQ" self.freq = 0 - # build graph - - self.u = usrp.source_c() # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 200 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 320 kS/s - chanfilt_decim = 1 - demod_rate = usrp_rate / chanfilt_decim - audio_decimation = 10 - audio_rate = 3*demod_rate / audio_decimation/2 # 48 kHz - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) + self.fm_freq_min = options.freq_min + self.fm_freq_max = options.freq_max - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) + # build graph + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + usrp_rate = 320e3 + demod_rate = 320e3 + audio_rate = 48e3 + audio_decim = 10 - chan_filt_coeffs = gr.firdes.low_pass_2 (1, # gain - usrp_rate, # sampling rate - 90e3, # passband cutoff - 30e3, # transition bandwidth - 70, # stopband attenuation - gr.firdes.WIN_BLACKMAN) - print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() - self.rchan_sample = blks2.rational_resampler_fff(3,2) - self.lchan_sample = blks2.rational_resampler_fff(3,2) + nfilts = 32 + chan_coeffs = gr.firdes.low_pass_2(10*nfilts, # gain + nfilts*usrp_rate, # sampling rate + 90e3, # passband cutoff + 30e3, # transition bw + 70) # stopband attenuation + rrate = usrp_rate / dev_rate + self.chan_filt = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) + self.guts = blks2.wfm_rcv_fmdet (demod_rate, audio_decim) - #self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) - self.guts = blks2.wfm_rcv_fmdet (demod_rate, audio_decimation) + chan_rate = audio_rate / (demod_rate/audio_decim) + self.rchan_filt = blks2.pfb_arb_resampler_fff(chan_rate) + self.lchan_filt = blks2.pfb_arb_resampler_fff(chan_rate) # FIXME rework {add,multiply}_const_* to handle multiple streams self.volume_control_l = gr.multiply_const_ff(self.vol) self.volume_control_r = gr.multiply_const_ff(self.vol) # sound card as final sink - audio_sink = audio.sink (int (audio_rate), - options.audio_output, - False) # ok_to_block + self.audio_sink = audio.sink (int (audio_rate), + options.audio_output, + False) # ok_to_block # now wire it all together - self.connect (self.u, chan_filt, self.guts) - self.connect((self.guts, 0), self.lchan_sample,self.volume_control_l,(audio_sink,0)) - self.connect((self.guts, 1), self.rchan_sample,self.volume_control_r,(audio_sink,1)) + self.connect (self.u, self.chan_filt, self.guts) + self.connect((self.guts, 0), self.lchan_filt, + self.volume_control_l, (self.audio_sink,0)) + self.connect((self.guts, 1), self.rchan_filt, + self.volume_control_r, (self.audio_sink,1)) try: self.guts.stereo_carrier_pll_recovery.squelch_enable(True) @@ -139,8 +127,8 @@ class wfm_rx_block (stdgui2.std_top_block): if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 if options.volume is None: g = self.volume_range() @@ -149,8 +137,15 @@ class wfm_rx_block (stdgui2.std_top_block): if abs(options.freq) < 1e6: options.freq *= 1e6 - # set initial values + frange = self.u.get_freq_range() + if(frange.start() > self.fm_freq_max or frange.stop() < self.fm_freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + if(options.freq < self.fm_freq_min or options.freq > self.fm_freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) + # set initial values self.set_gain(options.gain) self.set_vol(options.volume) try: @@ -232,7 +227,7 @@ class wfm_rx_block (stdgui2.std_top_block): hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, - range=(87.9e6, 108.1e6, 0.1e6), + range=(self.fm_freq_min, self.fm_freq_max, 0.1e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -246,9 +241,10 @@ class wfm_rx_block (stdgui2.std_top_block): callback=self.set_vol) hbox.Add((5,0), 1) + g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) @@ -311,20 +307,17 @@ class wfm_rx_block (stdgui2.std_top_block): except: print "FYI: This implementation of the stereo_carrier_pll_recovery has no squelch implementation yet" + def set_freq(self, target_freq): """ Set the center frequency we're interested in. @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) + r = self.u.set_center_freq(target_freq) + if r: self.freq = target_freq self.myform['freq'].set_value(target_freq) # update displayed value @@ -335,10 +328,10 @@ class wfm_rx_block (stdgui2.std_top_block): self._set_status_msg("Failed", 0) return False - + def set_gain(self, gain): self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) + self.u.set_gain(gain) def update_status_bar (self): msg = "Volume:%r Setting:%s" % (self.vol, self.state) diff --git a/gr-uhd/examples/usrp_wfm_rcv_nogui.py b/gr-uhd/examples/usrp_wfm_rcv_nogui.py new file mode 100755 index 000000000..ffeda4493 --- /dev/null +++ b/gr-uhd/examples/usrp_wfm_rcv_nogui.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +# +# Copyright 2005-2007,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, optfir, audio, blks2, uhd +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import sys + +class wfm_rx_block (gr.top_block): + + def __init__(self): + gr.top_block.__init__(self) + + parser=OptionParser(option_class=eng_option) + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + parser.add_option("-V", "--volume", type="eng_float", default=None, + help="set volume (default is midpoint)") + parser.add_option("-O", "--audio-output", type="string", default="", + help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") + parser.add_option("", "--freq-min", type="eng_float", default=87.9e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=108.1e6, + help="Set a maximum frequency [default=%default]") + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + + self.state = "FREQ" + self.freq = 0 + + self.fm_freq_min = options.freq_min + self.fm_freq_max = options.freq_max + + # build graph + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + usrp_rate = 320e3 + demod_rate = 320e3 + audio_rate = 32e3 + audio_decim = int(demod_rate / audio_rate) + + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() + + nfilts = 32 + chan_coeffs = optfir.low_pass (nfilts, # gain + nfilts*usrp_rate, # sampling rate + 80e3, # passband cutoff + 115e3, # stopband cutoff + 0.1, # passband ripple + 60) # stopband attenuation + rrate = usrp_rate / dev_rate + self.chan_filt = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) + + self.guts = blks2.wfm_rcv (demod_rate, audio_decim) + + self.volume_control = gr.multiply_const_ff(1) + + # sound card as final sink + self.audio_sink = audio.sink(int(audio_rate), + options.audio_output, + False) # ok_to_block + + # now wire it all together + self.connect (self.u, self.chan_filt, self.guts, + self.volume_control, self.audio_sink) + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 + + if options.volume is None: + g = self.volume_range() + options.volume = float(g[0]+g[1])/2 + + frange = self.u.get_freq_range() + if(frange.start() > self.fm_freq_max or frange.stop() < self.fm_freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + if(options.freq < self.fm_freq_min or options.freq > self.fm_freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) + + # set initial values + self.set_gain(options.gain) + self.set_vol(options.volume) + if not(self.set_freq(options.freq)): + self._set_status_msg("Failed to set initial frequency") + + def set_vol (self, vol): + g = self.volume_range() + self.vol = max(g[0], min(g[1], vol)) + self.volume_control.set_k(10**(self.vol/10)) + self.update_status_bar () + + def set_freq(self, target_freq): + """ + Set the center frequency we're interested in. + + @param target_freq: frequency in Hz + @rypte: bool + """ + + r = self.u.set_center_freq(target_freq) + + if r: + self.freq = target_freq + self.update_status_bar() + self._set_status_msg("OK", 0) + return True + + self._set_status_msg("Failed", 0) + return False + + def set_gain(self, gain): + self.u.set_gain(gain) + + def update_status_bar (self): + msg = "Freq: %s Volume:%f Setting:%s" % ( + eng_notation.num_to_str(self.freq), self.vol, self.state) + self._set_status_msg(msg, 1) + + def _set_status_msg(self, msg, which=0): + print msg + + def volume_range(self): + return (-20.0, 0.0, 0.5) + + +if __name__ == '__main__': + tb = wfm_rx_block() + try: + tb.run() + except KeyboardInterrupt: + pass diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py b/gr-uhd/examples/usrp_wfm_rcv_pll.py index 0d52ed7ee..2cb4e4068 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py +++ b/gr-uhd/examples/usrp_wfm_rcv_pll.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,41 +20,25 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks2 +from gnuradio import gr, optfir, audio, blks2, uhd +from gnuradio import eng_notation from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate from gnuradio.wxgui import stdgui2, fftsink2, form, scopesink2 from optparse import OptionParser -from usrpm import usrp_dbid import sys -import math import wx -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) - class wfm_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=65, @@ -65,7 +49,10 @@ class wfm_rx_block (stdgui2.std_top_block): help="set volume (default is midpoint)") parser.add_option("-O", "--audio-output", type="string", default="", help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") - + parser.add_option("", "--freq-min", type="eng_float", default=87.9e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=108.1e6, + help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() if len(args) != 0: @@ -79,55 +66,53 @@ class wfm_rx_block (stdgui2.std_top_block): self.state = "FREQ" self.freq = 0 + self.fm_freq_min = options.freq_min + self.fm_freq_max = options.freq_max + # build graph + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + usrp_rate = 320e3 + demod_rate = 320e3 + audio_rate = 48e3 + audio_decim = 10 + + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() + + nfilts = 32 + chan_coeffs = gr.firdes.low_pass_2 (nfilts, # gain + nfilts*usrp_rate, # sampling rate + 90e3, # passband cutoff + 30e3, # stopband cutoff + 70) # stopband attenuation + rrate = usrp_rate / dev_rate + self.chan_filt = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) - self.u = usrp.source_c() # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 200 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 320 kS/s - chanfilt_decim = 1 - demod_rate = usrp_rate / chanfilt_decim - audio_decimation = 10 - audio_rate = 3*demod_rate / audio_decimation/2 # 48 kHz - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - - - chan_filt_coeffs = gr.firdes.low_pass_2 (1, # gain - usrp_rate, # sampling rate - 90e3, # passband cutoff - 30e3, # transition bandwidth - 70, # stopband attenuation - gr.firdes.WIN_BLACKMAN) - print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) - self.rchan_sample = blks2.rational_resampler_fff(3,2) - self.lchan_sample = blks2.rational_resampler_fff(3,2) + self.guts = blks2.wfm_rcv_pll (demod_rate, audio_decim) - - #self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) - self.guts = blks2.wfm_rcv_pll (demod_rate, audio_decimation) + chan_rate = audio_rate / (demod_rate/audio_decim) + self.rchan_filt = blks2.pfb_arb_resampler_fff(chan_rate) + self.lchan_filt = blks2.pfb_arb_resampler_fff(chan_rate) # FIXME rework {add,multiply}_const_* to handle multiple streams self.volume_control_l = gr.multiply_const_ff(self.vol) self.volume_control_r = gr.multiply_const_ff(self.vol) # sound card as final sink - audio_sink = audio.sink (int (audio_rate), - options.audio_output, - False) # ok_to_block + self.audio_sink = audio.sink (int (audio_rate), + options.audio_output, + False) # ok_to_block # now wire it all together - self.connect (self.u, chan_filt, self.guts) - self.connect((self.guts, 0), self.lchan_sample,self.volume_control_l,(audio_sink,0)) - self.connect((self.guts, 1), self.rchan_sample,self.volume_control_r,(audio_sink,1)) + self.connect (self.u, self.chan_filt, self.guts) + self.connect((self.guts, 0), self.lchan_filt, + self.volume_control_l, (self.audio_sink,0)) + self.connect((self.guts, 1), self.rchan_filt, + self.volume_control_r, (self.audio_sink,1)) try: self.guts.stereo_carrier_pll_recovery.squelch_enable(True) @@ -139,18 +124,22 @@ class wfm_rx_block (stdgui2.std_top_block): if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 if options.volume is None: g = self.volume_range() options.volume = float(g[0]+g[1])/2 - if abs(options.freq) < 1e6: - options.freq *= 1e6 + frange = self.u.get_freq_range() + if(frange.start() > self.fm_freq_max or frange.stop() < self.fm_freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + if(options.freq < self.fm_freq_min or options.freq > self.fm_freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) # set initial values - self.set_gain(options.gain) self.set_vol(options.volume) try: @@ -232,7 +221,7 @@ class wfm_rx_block (stdgui2.std_top_block): hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, - range=(87.9e6, 108.1e6, 0.1e6), + range=(self.fm_freq_min, self.fm_freq_max, 0.1e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -246,9 +235,10 @@ class wfm_rx_block (stdgui2.std_top_block): callback=self.set_vol) hbox.Add((5,0), 1) + g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) @@ -317,14 +307,10 @@ class wfm_rx_block (stdgui2.std_top_block): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) + r = self.u.set_center_freq(target_freq) + if r: self.freq = target_freq self.myform['freq'].set_value(target_freq) # update displayed value @@ -335,10 +321,10 @@ class wfm_rx_block (stdgui2.std_top_block): self._set_status_msg("Failed", 0) return False - + def set_gain(self, gain): self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) + self.u.set_gain(gain) def update_status_bar (self): msg = "Volume:%r Setting:%s" % (self.vol, self.state) diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_sca.py b/gr-uhd/examples/usrp_wfm_rcv_sca.py index 39547b3ae..1c6154871 100755 --- a/gnuradio-examples/python/usrp/usrp_wfm_rcv_sca.py +++ b/gr-uhd/examples/usrp_wfm_rcv_sca.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2006,2007 Free Software Foundation, Inc. +# Copyright 2006,2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -50,42 +50,25 @@ OFDM. """ -from gnuradio import gr, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio.blks2impl.fm_emph import fm_deemph +from gnuradio import gr, optfir, audio, blks2, uhd from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser -from usrpm import usrp_dbid import sys import math import wx -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) - - class wfm_rx_sca_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=40, @@ -94,6 +77,10 @@ class wfm_rx_sca_block (stdgui2.std_top_block): help="set volume (default is midpoint)") parser.add_option("-O", "--audio-output", type="string", default="", help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") + parser.add_option("", "--freq-min", type="eng_float", default=87.9e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=108.1e6, + help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() if len(args) != 0: @@ -107,58 +94,57 @@ class wfm_rx_sca_block (stdgui2.std_top_block): self.state = "FREQ" self.freq = 0 + self.fm_freq_min = options.freq_min + self.fm_freq_max = options.freq_max + # build graph - self.u = usrp.source_c() # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 200 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 320 kS/s - chanfilt_decim = 1 - demod_rate = usrp_rate / chanfilt_decim - sca_chanfilt_decim = 5 - sca_demod_rate = demod_rate / sca_chanfilt_decim #64 kHz - audio_decimation = 2 - audio_rate = sca_demod_rate / audio_decimation # 32 kHz - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) - - #Create filter to get main FM Channel we want - chan_filt_coeffs = optfir.low_pass (1, # gain - usrp_rate, # sampling rate - 100e3, # passband cutoff - 140e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + + usrp_rate = 320e3 + demod_rate = 320e3 + audio_rate = 32e3 + sca_demod_rate = 64e3 + audio_decim = int(demod_rate / audio_rate) + sca_chanfilt_decim = int(demod_rate / sca_demod_rate) + + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() + + nfilts = 32 + chan_coeffs = optfir.low_pass (nfilts, # gain + nfilts*usrp_rate, # sampling rate + 100e3, # passband cutoff + 140e3, # stopband cutoff + 0.1, # passband ripple + 60) # stopband attenuation + rrate = usrp_rate / dev_rate + self.chan_filt = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) #Create demodulator block for Main FM Channel max_dev = 75e3 fm_demod_gain = demod_rate/(2*math.pi*max_dev) self.fm_demod = gr.quadrature_demod_cf (fm_demod_gain) - # Note - deemphasis is not applied to the Main FM Channel as main audio is not decoded + # Note - deemphasis is not applied to the Main FM Channel as + # main audio is not decoded - # SCA Devation is 10% of carrier but some references say 20% if mono with one SCA (6 KHz seems typical) + # SCA Devation is 10% of carrier but some references say 20% + # if mono with one SCA (6 KHz seems typical) max_sca_dev = 6e3 # Create filter to get SCA channel we want sca_chan_coeffs = gr.firdes.low_pass (1.0, # gain - demod_rate, # sampling rate - max_sca_dev, # low pass cutoff freq - max_sca_dev/3, # width of trans. band - gr.firdes.WIN_HANN) # filter type + demod_rate, # sampling rate + max_sca_dev, # cutoff freq + max_sca_dev/3, # trans. band + gr.firdes.WIN_HANN) # filter type - self.ddc = gr.freq_xlating_fir_filter_fcf(sca_chanfilt_decim, # decimation rate + self.ddc = gr.freq_xlating_fir_filter_fcf(sca_chanfilt_decim, # decim rate sca_chan_coeffs, # taps - 0, # frequency translation amount (Gets set by the UI) + 0, # freq translation amount (Gets set by the UI) demod_rate) # input sample rate #Create demodulator block for SCA Channel @@ -168,46 +154,55 @@ class wfm_rx_sca_block (stdgui2.std_top_block): # SCA analog audio is bandwidth limited to 5 KHz max_sca_audio_freq = 5.0e3 + # SCA analog deephasis is 150 uS (75 uS may be used) sca_tau = 150e-6 # compute FIR filter taps for SCA audio filter - audio_coeffs = gr.firdes.low_pass (1.0, # gain - sca_demod_rate, # sampling rate - max_sca_audio_freq, # low pass cutoff freq - max_sca_audio_freq/2.5, # width of trans. band + audio_coeffs = gr.firdes.low_pass (1.0, # gain + sca_demod_rate, # sampling rate + max_sca_audio_freq, # cutoff freq + max_sca_audio_freq/2.5, # trans. band gr.firdes.WIN_HAMMING) # input: float; output: float - self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) + self.audio_filter = gr.fir_filter_fff (audio_decim, audio_coeffs) # Create deemphasis block that is applied after SCA demodulation - self.deemph = fm_deemph (audio_rate, sca_tau) + self.deemph = blks2.fm_deemph (audio_rate, sca_tau) self.volume_control = gr.multiply_const_ff(self.vol) # sound card as final sink - audio_sink = audio.sink (int (audio_rate), - options.audio_output, - False) # ok_to_block + self.audio_sink = audio.sink (int (audio_rate), + options.audio_output, + False) # ok_to_block # now wire it all together - self.connect (self.u, chan_filt, self.fm_demod, self.ddc, self.fm_demod_sca) - self.connect (self.fm_demod_sca, self.audio_filter, self.deemph, self.volume_control, audio_sink) + self.connect (self.u, self.chan_filt, self.fm_demod, + self.ddc, self.fm_demod_sca) + self.connect (self.fm_demod_sca, self.audio_filter, + self.deemph, self.volume_control, + self.audio_sink) self._build_gui(vbox, usrp_rate, demod_rate, sca_demod_rate, audio_rate) if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2 if options.volume is None: g = self.volume_range() options.volume = float(g[0]+g[1])/2 - if abs(options.freq) < 1e6: - options.freq *= 1e6 + frange = self.u.get_freq_range() + if(frange.start() > self.fm_freq_max or frange.stop() < self.fm_freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + if(options.freq < self.fm_freq_min or options.freq > self.fm_freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) # set initial values @@ -271,7 +266,7 @@ class wfm_rx_sca_block (stdgui2.std_top_block): hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, - range=(87.9e6, 108.1e6, 0.1e6), + range=(self.fm_freq_min, self.fm_freq_max, 0.1e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -299,9 +294,10 @@ class wfm_rx_sca_block (stdgui2.std_top_block): callback=self.set_vol) hbox.Add((5,0), 1) + g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.subdev.gain_range(), + weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -363,8 +359,7 @@ class wfm_rx_sca_block (stdgui2.std_top_block): the result of that operation and our target_frequency to determine the value for the digital down converter. """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) - + r = self.u.set_center_freq(target_freq) if r: self.freq = target_freq self.myform['freq'].set_value(target_freq) # update displayed value @@ -372,7 +367,6 @@ class wfm_rx_sca_block (stdgui2.std_top_block): self.update_status_bar() self._set_status_msg("OK", 0) return True - self._set_status_msg("Failed", 0) return False @@ -387,7 +381,7 @@ class wfm_rx_sca_block (stdgui2.std_top_block): def set_gain(self, gain): self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) + self.u.set_gain(gain) def update_status_bar (self): msg = "Volume:%r Setting:%s" % (self.vol, self.state) diff --git a/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py b/gr-uhd/examples/usrp_wxapt_rcv.py index b356702a6..5b44398d1 100755 --- a/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py +++ b/gr-uhd/examples/usrp_wxapt_rcv.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2005-2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,42 +20,25 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, eng_notation, optfir -from gnuradio import audio -from gnuradio import usrp -from gnuradio import blks2 +from gnuradio import gr, audio, blks2, uhd from gnuradio.eng_option import eng_option from gnuradio.wxgui import slider, powermate from gnuradio.wxgui import stdgui2, fftsink2, form from optparse import OptionParser -from usrpm import usrp_dbid import sys -import math import wx -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A. - - @return a subdev_spec - """ - return usrp.pick_subdev(u, (usrp_dbid.TV_RX, - usrp_dbid.TV_RX_REV_2, - usrp_dbid.TV_RX_REV_3, - usrp_dbid.TV_RX_MIMO, - usrp_dbid.TV_RX_REV_2_MIMO, - usrp_dbid.TV_RX_REV_3_MIMO, - usrp_dbid.BASIC_RX)) - class wxapt_rx_block (stdgui2.std_top_block): def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) parser=OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=A)") + parser.add_option("-a", "--address", type="string", + default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") parser.add_option("-f", "--freq", type="eng_float", default=137.5e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, @@ -64,6 +47,10 @@ class wxapt_rx_block (stdgui2.std_top_block): help="set volume (default is midpoint)") parser.add_option("-O", "--audio-output", type="string", default="", help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp") + parser.add_option("", "--freq-min", type="eng_float", default=137e6, + help="Set a minimum frequency [default=%default]") + parser.add_option("", "--freq-max", type="eng_float", default=138e6, + help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() if len(args) != 0: @@ -77,62 +64,62 @@ class wxapt_rx_block (stdgui2.std_top_block): self.state = "FREQ" self.freq = 0 - # build graph - - self.u = usrp.source_c() # usrp is data source - - adc_rate = self.u.adc_rate() # 64 MS/s - usrp_decim = 200 - self.u.set_decim_rate(usrp_decim) - usrp_rate = adc_rate / usrp_decim # 320 kS/s - chanfilt_decim = 4 - demod_rate = usrp_rate / chanfilt_decim - audio_decimation = 10 - audio_rate = demod_rate / audio_decimation # 32 kHz + self.freq_min = options.freq_min + self.freq_max = options.freq_max - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) + # build graph + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - print "Using RX d'board %s" % (self.subdev.side_and_name(),) + usrp_rate = 320e3 + demod_rate = 320e3 + audio_rate = 32e3 + audio_decim = int(demod_rate / audio_rate) + self.u.set_samp_rate(usrp_rate) + dev_rate = self.u.get_samp_rate() - chan_filt_coeffs = optfir.low_pass (1, # gain - usrp_rate, # sampling rate - 40e3, # passband cutoff - 60e3, # stopband cutoff - 0.1, # passband ripple - 60) # stopband attenuation - #print len(chan_filt_coeffs) - chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs) + nfilts = 32 + chan_coeffs = gr.firdes.low_pass_2 (nfilts, # gain + nfilts*usrp_rate, # sampling rate + 40e3, # passband cutoff + 20e3, # transition bw + 60) # stopband attenuation + rrate = usrp_rate / dev_rate + self.chan_filt = blks2.pfb_arb_resampler_ccf(rrate, chan_coeffs, nfilts) - self.guts = blks2.wfm_rcv (demod_rate, audio_decimation) + self.guts = blks2.wfm_rcv (demod_rate, audio_decim) self.volume_control = gr.multiply_const_ff(self.vol) # sound card as final sink - audio_sink = audio.sink (int (audio_rate), options.audio_output) + self.audio_sink = audio.sink (int (audio_rate), options.audio_output) # now wire it all together - self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink) + self.connect (self.u, self.chan_filt, self.guts, + self.volume_control, self.audio_sink) self._build_gui(vbox, usrp_rate, demod_rate, audio_rate) if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2.0 if options.volume is None: g = self.volume_range() options.volume = float(g[0]+g[1])/2 - - if abs(options.freq) < 1e6: - options.freq *= 1e6 - # set initial values + frange = self.u.get_freq_range() + if(frange.start() > self.freq_max or frange.stop() < self.freq_min): + sys.stderr.write("Radio does not support required frequency range.\n") + sys.exit(1) + if(options.freq < self.freq_min or options.freq > self.freq_max): + sys.stderr.write("Requested frequency is outside of required frequency range.\n") + sys.exit(1) + # set initial values self.set_gain(options.gain) self.set_vol(options.volume) if not(self.set_freq(options.freq)): @@ -183,7 +170,7 @@ class wxapt_rx_block (stdgui2.std_top_block): hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, - range=(137.0e6, 138.0e6, 0.0005e6), + range=(self.freq_min, self.freq_max, 0.0005e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -197,9 +184,10 @@ class wxapt_rx_block (stdgui2.std_top_block): callback=self.set_vol) hbox.Add((5,0), 1) + g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, range=self.subdev.gain_range(), + weight=3, range=(g.start(), g.start(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) @@ -255,14 +243,10 @@ class wxapt_rx_block (stdgui2.std_top_block): @param target_freq: frequency in Hz @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) - + + r = self.u.set_center_freq(target_freq) + if r: self.freq = target_freq self.myform['freq'].set_value(target_freq) # update displayed value @@ -276,7 +260,7 @@ class wxapt_rx_block (stdgui2.std_top_block): def set_gain(self, gain): self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) + self.u.set_gain(gain) def update_status_bar (self): msg = "Volume:%r Setting:%s" % (self.vol, self.state) diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i index 93bf5bfbe..f8381ae64 100644 --- a/gr-uhd/swig/uhd_swig.i +++ b/gr-uhd/swig/uhd_swig.i @@ -26,6 +26,9 @@ #define GR_UHD_API +//suppress 319. No access specifier given for base class name (ignored). +#pragma SWIG nowarn=319 + //////////////////////////////////////////////////////////////////////// // standard includes //////////////////////////////////////////////////////////////////////// @@ -72,8 +75,6 @@ %include <uhd/types/metadata.hpp> -%ignore uhd::device::register_device; //causes compile to choke in MSVC -%include <uhd/device.hpp> %template(device_addr_vector_t) std::vector<uhd::device_addr_t>; %include <uhd/types/sensors.hpp> diff --git a/gr-utils/src/python/Makefile.am b/gr-utils/src/python/Makefile.am index b422bfd05..11fb038f6 100644 --- a/gr-utils/src/python/Makefile.am +++ b/gr-utils/src/python/Makefile.am @@ -49,10 +49,4 @@ bin_SCRIPTS = \ gr_plot_iq.py \ gr_plot_short.py \ gr_plot_qt.py \ - gr_filter_design.py \ - usrp_fft.py \ - usrp_oscope.py \ - usrp_rx_nogui.py \ - usrp_siggen.py \ - usrp_siggen_gui.py \ - usrp2_fft.py + gr_filter_design.py diff --git a/gr-utils/src/python/usrp_fft.py b/gr-utils/src/python/usrp_fft.py deleted file mode 100755 index eda9bd57c..000000000 --- a/gr-utils/src/python/usrp_fft.py +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2007,2008,2010 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, gru -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider -from optparse import OptionParser -import wx -import sys -import numpy - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db(1, 0).dbid() >= 0: - return (1, 0) - return (0, 0) - - -class app_top_block(stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser(option_class=eng_option) - parser.add_option("-w", "--which", type="int", default=0, - help="select which USRP (0, 1, ...) default is %default", - metavar="NUM") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-A", "--antenna", default=None, - help="select Rx Antenna (only on RFX-series boards)") - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB [default is midpoint]") - parser.add_option("-W", "--waterfall", action="store_true", default=False, - help="Enable waterfall display") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") - parser.add_option( "--no-hb", action="store_true", default=False, - help="don't use halfband filter in usrp") - parser.add_option("-S", "--oscilloscope", action="store_true", default=False, - help="Enable oscilloscope display") - parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1, - help="Set fftsink averaging factor, [default=%default]") - parser.add_option("", "--ref-scale", type="eng_float", default=13490.0, - help="Set dBFS=0dB input value, [default=%default]") - parser.add_option("", "--fft-size", type="int", default=1024, - help="Set FFT frame size, [default=%default]"); - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - self.options = options - self.show_debug_info = True - - # build the graph - if options.no_hb or (options.decim<8): - #Min decimation of this firmware is 4. - #contains 4 Rx paths without halfbands and 0 tx paths. - self.fpga_filename="std_4rx_0tx.rbf" - self.u = usrp.source_c(which=options.which, decim_rate=options.decim, fpga_filename=self.fpga_filename) - else: - #Min decimation of standard firmware is 8. - #standard fpga firmware "std_2rxhb_2tx.rbf" - #contains 2 Rx paths with halfband filters and 2 tx paths (the default) - self.u = usrp.source_c(which=options.which, decim_rate=options.decim) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - - if options.width_8: - width = 8 - shift = 8 - format = self.u.make_format(width, shift) - print "format =", hex(format) - r = self.u.set_format(format) - print "set_format =", r - - # determine the daughterboard subdevice we're using - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - - input_rate = self.u.adc_freq() / self.u.decim_rate() - - if options.waterfall: - self.scope = \ - waterfallsink2.waterfall_sink_c (panel, fft_size=options.fft_size, sample_rate=input_rate) - elif options.oscilloscope: - self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) - else: - self.scope = fftsink2.fft_sink_c (panel, fft_size=options.fft_size, sample_rate=input_rate, - ref_scale=options.ref_scale, ref_level=0.0, y_divs = 10, - avg_alpha=options.avg_alpha) - - self.connect(self.u, self.scope) - - self._build_gui(vbox) - self._setup_events() - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - if options.freq is None: - # if no freq was specified, use the mid-point - r = self.subdev.freq_range() - options.freq = float(r[0]+r[1])/2 - - self.set_gain(options.gain) - - if options.antenna is not None: - print "Selecting antenna %s" % (options.antenna,) - self.subdev.select_rx_antenna(options.antenna) - - if self.show_debug_info: - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - self.myform['dbname'].set_value(self.subdev.name()) - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - hbox.Add((5,0), 0, 0) - g = self.subdev.gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - def _form_set_decim(kv): - return self.set_decim(kv['decim']) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) - - hbox.Add((5,0), 1) - myform['fs@usb'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@USB") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = self.u.tune(0, self.subdev, target_freq) - - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - if not self.options.oscilloscope: - self.scope.set_baseband_freq(target_freq) - return True - - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) - - def set_decim(self, decim): - ok = self.u.set_decim_rate(decim) - if not ok: - print "set_decim failed" - input_rate = self.u.adc_freq() / self.u.decim_rate() - self.scope.set_sample_rate(input_rate) - if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - return ok - - def _setup_events(self): - if not self.options.waterfall and not self.options.oscilloscope: - self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick) - - def evt_left_dclick(self, event): - (ux, uy) = self.scope.win.GetXY(event) - if event.CmdDown(): - # Re-center on maximum power - points = self.scope.win._points - if self.scope.win.peak_hold: - if self.scope.win.peak_vals is not None: - ind = numpy.argmax(self.scope.win.peak_vals) - else: - ind = int(points.shape()[0]/2) - else: - ind = numpy.argmax(points[:,1]) - (freq, pwr) = points[ind] - target_freq = freq/self.scope.win._scale_factor - print ind, freq, pwr - self.set_freq(target_freq) - else: - # Re-center on clicked frequency - target_freq = ux/self.scope.win._scale_factor - self.set_freq(target_freq) - - -def main (): - app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-utils/src/python/usrp_oscope.py b/gr-utils/src/python/usrp_oscope.py deleted file mode 100755 index 9921e9873..000000000 --- a/gr-utils/src/python/usrp_oscope.py +++ /dev/null @@ -1,349 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2006,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 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. -# - -# print "Loading revised usrp_oscope with additional options for scopesink..." - -from gnuradio import gr, gru -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, scopesink2, form, slider -from optparse import OptionParser -import wx -import sys -from usrpm import usrp_dbid - - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db(1, 0).dbid() >= 0: - return (1, 0) - return (0, 0) - - -class app_top_block(stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") - parser.add_option( "--no-hb", action="store_true", default=False, - help="don't use halfband filter in usrp") - parser.add_option("-C", "--basic-complex", action="store_true", default=False, - help="Use both inputs of a basicRX or LFRX as a single Complex input channel") - parser.add_option("-D", "--basic-dualchan", action="store_true", default=False, - help="Use both inputs of a basicRX or LFRX as seperate Real input channels") - parser.add_option("-n", "--frame-decim", type="int", default=1, - help="set oscope frame decimation factor to n [default=1]") - parser.add_option("-v", "--v-scale", type="eng_float", default=1000, - help="set oscope initial V/div to SCALE [default=%default]") - parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6, - help="set oscope initial s/div to SCALE [default=50us]") - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - self.show_debug_info = True - - # build the graph - if options.basic_dualchan: - self.num_inputs=2 - else: - self.num_inputs=1 - if options.no_hb or (options.decim<8): - #Min decimation of this firmware is 4. - #contains 4 Rx paths without halfbands and 0 tx paths. - self.fpga_filename="std_4rx_0tx.rbf" - self.u = usrp.source_c(nchan=self.num_inputs,decim_rate=options.decim, fpga_filename=self.fpga_filename) - else: - #Min decimation of standard firmware is 8. - #standard fpga firmware "std_2rxhb_2tx.rbf" - #contains 2 Rx paths with halfband filters and 2 tx paths (the default) - self.u = usrp.source_c(nchan=self.num_inputs,decim_rate=options.decim) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - if options.width_8: - width = 8 - shift = 8 - format = self.u.make_format(width, shift) - #print "format =", hex(format) - r = self.u.set_format(format) - #print "set_format =", r - - # determine the daughterboard subdevice we're using - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - if (options.basic_complex or options.basic_dualchan ): - if ((self.subdev.dbid()==usrp_dbid.BASIC_RX) or (self.subdev.dbid()==usrp_dbid.LF_RX)): - side = options.rx_subdev_spec[0] # side A = 0, side B = 1 - if options.basic_complex: - #force Basic_RX and LF_RX in complex mode (use both I and Q channel) - print "Receiver daughterboard forced in complex mode. Both inputs will combined to form a single complex channel." - self.dualchan=False - if side==0: - self.u.set_mux(0x00000010) #enable adc 0 and 1 to form a single complex input on side A - else: #side ==1 - self.u.set_mux(0x00000032) #enable adc 3 and 2 to form a single complex input on side B - elif options.basic_dualchan: - #force Basic_RX and LF_RX in dualchan mode (use input A for channel 0 and input B for channel 1) - print "Receiver daughterboard forced in dualchannel mode. Each input will be used to form a seperate channel." - self.dualchan=True - if side==0: - self.u.set_mux(gru.hexint(0xf0f0f1f0)) #enable adc 0, side A to form a real input on channel 0 and adc1,side A to form a real input on channel 1 - else: #side ==1 - self.u.set_mux(0xf0f0f3f2) #enable adc 2, side B to form a real input on channel 0 and adc3,side B to form a real input on channel 1 - else: - sys.stderr.write('options basic_dualchan or basic_complex is only supported for Basic Rx or LFRX at the moment\n') - sys.exit(1) - else: - self.dualchan=False - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - - input_rate = self.u.adc_freq() / self.u.decim_rate() - - self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, - frame_decim=options.frame_decim, - v_scale=options.v_scale, - t_scale=options.t_scale, - num_inputs=self.num_inputs) - if self.dualchan: - # deinterleave two channels from FPGA - self.di = gr.deinterleave(gr.sizeof_gr_complex) - self.connect(self.u,self.di) - self.connect((self.di,0),(self.scope,0)) - self.connect((self.di,1),(self.scope,1)) - else: - self.connect(self.u, self.scope) - - self._build_gui(vbox) - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - if options.freq is None: - if ((self.subdev.dbid()==usrp_dbid.BASIC_RX) or (self.subdev.dbid()==usrp_dbid.LF_RX)): - #for Basic RX and LFRX if no freq is specified you probably want 0.0 Hz and not 45 GHz - options.freq=0.0 - else: - # if no freq was specified, use the mid-point - r = self.subdev.freq_range() - options.freq = float(r[0]+r[1])/2 - - self.set_gain(options.gain) - - if self.show_debug_info: - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - self.myform['dbname'].set_value(self.subdev.name()) - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) - if self.num_inputs==2: - self.myform['baseband2'].set_value(0) - self.myform['ddc2'].set_value(0) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - if self.num_inputs==2: - if not(self.set_freq2(options.freq)): - self._set_status_msg("Failed to set initial frequency for channel 2") - - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - def _form_set_freq2(kv): - return self.set_freq2(kv['freq2']) - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - if self.num_inputs==2: - myform['freq2'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq2", weight=1, - callback=myform.check_input_and_call(_form_set_freq2, self._set_status_msg)) - hbox.Add((5,0), 0, 0) - g = self.subdev.gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - def _form_set_decim(kv): - return self.set_decim(kv['decim']) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) - - hbox.Add((5,0), 1) - myform['fs@usb'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@USB") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - if self.num_inputs==2: - hbox.Add((1,0), 1) - myform['baseband2'] = form.static_float_field( - parent=panel, sizer=hbox, label="BB2") - hbox.Add((1,0), 1) - myform['ddc2'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC2") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) - - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - return True - - return False - - def set_freq2(self, target_freq): - """ - Set the center frequency of we're interested in for the second channel. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = usrp.tune(self.u, 1, self.subdev, target_freq) - - if r: - self.myform['freq2'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband2'].set_value(r.baseband_freq) - self.myform['ddc2'].set_value(r.dxc_freq) - return True - - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) - - def set_decim(self, decim): - ok = self.u.set_decim_rate(decim) - if not ok: - print "set_decim failed" - input_rate = self.u.adc_freq() / self.u.decim_rate() - self.scope.set_sample_rate(input_rate) - if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - return ok - -def main (): - app = stdgui2.stdapp(app_top_block, "USRP O'scope", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () |