diff options
Diffstat (limited to 'gnuradio-core/src/lib')
36 files changed, 2701 insertions, 15 deletions
diff --git a/gnuradio-core/src/lib/.gitignore b/gnuradio-core/src/lib/.gitignore new file mode 100644 index 000000000..e3bc1ee6a --- /dev/null +++ b/gnuradio-core/src/lib/.gitignore @@ -0,0 +1,9 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo +/gnuradio-config-info diff --git a/gnuradio-core/src/lib/filter/.gitignore b/gnuradio-core/src/lib/filter/.gitignore new file mode 100644 index 000000000..2d009f154 --- /dev/null +++ b/gnuradio-core/src/lib/filter/.gitignore @@ -0,0 +1,214 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo +/*.pyc +/generate-stamp +/# +/--- +/generate +/files: +/don't +/go +/in +/CVS +/--- +/GrFIRfilterCCC.cc +/GrFIRfilterCCC.h +/GrFIRfilterCCF.cc +/GrFIRfilterCCF.h +/GrFIRfilterFCC.cc +/GrFIRfilterFCC.h +/GrFIRfilterFFF.cc +/GrFIRfilterFFF.h +/GrFIRfilterFSF.cc +/GrFIRfilterFSF.h +/GrFIRfilterSCC.cc +/GrFIRfilterSCC.h +/GrFIRfilterSIS.cc +/GrFIRfilterSIS.h +/GrFreqXlatingFIRfilterCCC.cc +/GrFreqXlatingFIRfilterCCC.h +/GrFreqXlatingFIRfilterCCF.cc +/GrFreqXlatingFIRfilterCCF.h +/GrFreqXlatingFIRfilterFCC.cc +/GrFreqXlatingFIRfilterFCC.h +/GrFreqXlatingFIRfilterFCF.cc +/GrFreqXlatingFIRfilterFCF.h +/GrFreqXlatingFIRfilterSCC.cc +/GrFreqXlatingFIRfilterSCC.h +/GrFreqXlatingFIRfilterSCF.cc +/GrFreqXlatingFIRfilterSCF.h +/gr_fir_CCC.cc +/gr_fir_CCC.h +/gr_fir_CCC_generic.cc +/gr_fir_CCC_generic.h +/gr_fir_CCF.cc +/gr_fir_CCF.h +/gr_fir_CCF_generic.cc +/gr_fir_CCF_generic.h +/gr_fir_FCC.cc +/gr_fir_FCC.h +/gr_fir_FCC_generic.cc +/gr_fir_FCC_generic.h +/gr_fir_FFF.cc +/gr_fir_FFF.h +/gr_fir_FFF_generic.cc +/gr_fir_FFF_generic.h +/gr_fir_FSF.cc +/gr_fir_FSF.h +/gr_fir_FSF_generic.cc +/gr_fir_FSF_generic.h +/gr_fir_SCC.cc +/gr_fir_SCC.h +/gr_fir_SCC_generic.cc +/gr_fir_SCC_generic.h +/gr_fir_SIS.cc +/gr_fir_SIS.h +/gr_fir_SIS_generic.cc +/gr_fir_SIS_generic.h +/gr_fir_sysconfig.cc +/gr_fir_sysconfig.h +/gr_fir_sysconfig_generic.cc +/gr_fir_sysconfig_generic.h +/gr_fir_util.cc +/gr_fir_util.h +/GrFIRfilterCCC.i +/GrFIRfilterCCF.i +/GrFIRfilterFCC.i +/GrFIRfilterFFF.i +/GrFIRfilterFSF.i +/GrFIRfilterSCC.i +/GrFIRfilterSIS.i +/GrFreqXlatingFIRfilterCCC.i +/GrFreqXlatingFIRfilterCCF.i +/GrFreqXlatingFIRfilterFCC.i +/GrFreqXlatingFIRfilterFCF.i +/GrFreqXlatingFIRfilterSCC.i +/GrFreqXlatingFIRfilterSCF.i +/# +/--- +/end +/generated +/files +/--- +/filter_generated.i +/gr_fir_ccc.cc +/gr_fir_ccc.h +/gr_fir_ccc_generic.cc +/gr_fir_ccc_generic.h +/gr_fir_ccf.cc +/gr_fir_ccf.h +/gr_fir_ccf_generic.cc +/gr_fir_ccf_generic.h +/gr_fir_fcc.cc +/gr_fir_fcc.h +/gr_fir_fcc_generic.cc +/gr_fir_fcc_generic.h +/gr_fir_fff.cc +/gr_fir_fff.h +/gr_fir_fff_generic.cc +/gr_fir_fff_generic.h +/gr_fir_fsf.cc +/gr_fir_fsf.h +/gr_fir_fsf_generic.cc +/gr_fir_fsf_generic.h +/gr_fir_scc.cc +/gr_fir_scc.h +/gr_fir_scc_generic.cc +/gr_fir_scc_generic.h +/gr_fir_filter_ccc.cc +/gr_fir_filter_ccc.h +/gr_fir_filter_ccc.i +/gr_fir_filter_ccf.cc +/gr_fir_filter_ccf.h +/gr_fir_filter_ccf.i +/gr_fir_filter_fcc.cc +/gr_fir_filter_fcc.h +/gr_fir_filter_fcc.i +/gr_fir_filter_fff.cc +/gr_fir_filter_fff.h +/gr_fir_filter_fff.i +/gr_fir_filter_fsf.cc +/gr_fir_filter_fsf.h +/gr_fir_filter_fsf.i +/gr_fir_filter_scc.cc +/gr_fir_filter_scc.h +/gr_fir_filter_scc.i +/gr_freq_xlating_fir_filter_ccc.cc +/gr_freq_xlating_fir_filter_ccc.h +/gr_freq_xlating_fir_filter_ccc.i +/gr_freq_xlating_fir_filter_ccf.cc +/gr_freq_xlating_fir_filter_ccf.h +/gr_freq_xlating_fir_filter_ccf.i +/gr_freq_xlating_fir_filter_fcc.cc +/gr_freq_xlating_fir_filter_fcc.h +/gr_freq_xlating_fir_filter_fcc.i +/gr_freq_xlating_fir_filter_fcf.cc +/gr_freq_xlating_fir_filter_fcf.h +/gr_freq_xlating_fir_filter_fcf.i +/gr_freq_xlating_fir_filter_scc.cc +/gr_freq_xlating_fir_filter_scc.h +/gr_freq_xlating_fir_filter_scc.i +/gr_freq_xlating_fir_filter_scf.cc +/gr_freq_xlating_fir_filter_scf.h +/gr_freq_xlating_fir_filter_scf.i +/gr_interp_fir_filter_ccc.cc +/gr_interp_fir_filter_ccc.h +/gr_interp_fir_filter_ccc.i +/gr_interp_fir_filter_ccf.cc +/gr_interp_fir_filter_ccf.h +/gr_interp_fir_filter_ccf.i +/gr_interp_fir_filter_fcc.cc +/gr_interp_fir_filter_fcc.h +/gr_interp_fir_filter_fcc.i +/gr_interp_fir_filter_fff.cc +/gr_interp_fir_filter_fff.h +/gr_interp_fir_filter_fff.i +/gr_interp_fir_filter_fsf.cc +/gr_interp_fir_filter_fsf.h +/gr_interp_fir_filter_fsf.i +/gr_interp_fir_filter_scc.cc +/gr_interp_fir_filter_scc.h +/gr_interp_fir_filter_scc.i +/gr_rational_resampler_ccc.cc +/gr_rational_resampler_ccc.h +/gr_rational_resampler_ccc.i +/gr_rational_resampler_ccf.cc +/gr_rational_resampler_ccf.h +/gr_rational_resampler_ccf.i +/gr_rational_resampler_fcc.cc +/gr_rational_resampler_fcc.h +/gr_rational_resampler_fcc.i +/gr_rational_resampler_fff.cc +/gr_rational_resampler_fff.h +/gr_rational_resampler_fff.i +/gr_rational_resampler_fsf.cc +/gr_rational_resampler_fsf.h +/gr_rational_resampler_fsf.i +/gr_rational_resampler_scc.cc +/gr_rational_resampler_scc.h +/gr_rational_resampler_scc.i +/gr_rational_resampler_base_ccc.cc +/gr_rational_resampler_base_ccc.h +/gr_rational_resampler_base_ccc.i +/gr_rational_resampler_base_ccf.cc +/gr_rational_resampler_base_ccf.h +/gr_rational_resampler_base_ccf.i +/gr_rational_resampler_base_fcc.cc +/gr_rational_resampler_base_fcc.h +/gr_rational_resampler_base_fcc.i +/gr_rational_resampler_base_fff.cc +/gr_rational_resampler_base_fff.h +/gr_rational_resampler_base_fff.i +/gr_rational_resampler_base_fsf.cc +/gr_rational_resampler_base_fsf.h +/gr_rational_resampler_base_fsf.i +/gr_rational_resampler_base_scc.cc +/gr_rational_resampler_base_scc.h +/gr_rational_resampler_base_scc.i +/stamp-* diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index e230e88b5..838f69b92 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -201,7 +201,11 @@ libfilter_la_common_SOURCES = \ complex_dotprod_generic.cc \ ccomplex_dotprod_generic.cc \ float_dotprod_generic.c \ - short_dotprod_generic.c + short_dotprod_generic.c \ + gr_pfb_channelizer_ccf.cc \ + gr_pfb_decimator_ccf.cc \ + gr_pfb_interpolator_ccf.cc \ + gr_pfb_arb_resampler_ccf.cc libfilter_qa_la_common_SOURCES = \ qa_filter.cc \ @@ -276,7 +280,11 @@ grinclude_HEADERS = \ qa_filter.h \ short_dotprod_generic.h \ short_dotprod_x86.h \ - sse_debug.h + sse_debug.h \ + gr_pfb_channelizer_ccf.h \ + gr_pfb_decimator_ccf.h \ + gr_pfb_interpolator_ccf.h \ + gr_pfb_arb_resampler_ccf.h noinst_HEADERS = \ assembly.h \ @@ -327,6 +335,10 @@ swiginclude_HEADERS = \ gr_iir_filter_ffd.i \ gr_single_pole_iir_filter_ff.i \ gr_single_pole_iir_filter_cc.i \ + gr_pfb_channelizer_ccf.i \ + gr_pfb_decimator_ccf.i \ + gr_pfb_interpolator_ccf.i \ + gr_pfb_arb_resampler_ccf.i \ $(GENERATED_I) endif diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i index 7931a4d53..16b8005be 100644 --- a/gnuradio-core/src/lib/filter/filter.i +++ b/gnuradio-core/src/lib/filter/filter.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2005,2006,2007 Free Software Foundation, Inc. + * Copyright 2004,2005,2006,2007,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -32,6 +32,10 @@ #include <gr_fractional_interpolator_cc.h> #include <gr_goertzel_fc.h> #include <gr_cma_equalizer_cc.h> +#include <gr_pfb_channelizer_ccf.h> +#include <gr_pfb_decimator_ccf.h> +#include <gr_pfb_interpolator_ccf.h> +#include <gr_pfb_arb_resampler_ccf.h> %} %include "gr_iir_filter_ffd.i" @@ -45,5 +49,12 @@ %include "gr_fractional_interpolator_cc.i" %include "gr_goertzel_fc.i" %include "gr_cma_equalizer_cc.i" +%include "gr_pfb_channelizer_ccf.i" +%include "gr_pfb_decimator_ccf.i" +%include "gr_pfb_interpolator_ccf.i" +%include "gr_pfb_arb_resampler_ccf.i" +%include "gr_pfb_decimator_ccf.i" +%include "gr_pfb_interpolator_ccf.i" +%include "gr_pfb_arb_resampler_ccf.i" %include "filter_generated.i" diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc new file mode 100644 index 000000000..bfc4c0467 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc @@ -0,0 +1,196 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pfb_arb_resampler_ccf.h> +#include <gr_fir_ccf.h> +#include <gr_fir_util.h> +#include <gr_io_signature.h> + +gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate, + const std::vector<float> &taps, + unsigned int filter_size) +{ + return gr_pfb_arb_resampler_ccf_sptr (new gr_pfb_arb_resampler_ccf (rate, taps, + filter_size)); +} + + +gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, + const std::vector<float> &taps, + unsigned int filter_size) + : gr_block ("pfb_arb_resampler_ccf", + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex))), + d_updated (false) +{ + /* 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; + d_dec_rate = (unsigned int)floor(d_int_rate/rate); + d_flt_rate = (d_int_rate/rate) - d_dec_rate; + + // The accumulator keeps track of overflow to increment the stride correctly. + d_acc = 0; + + // Store the last filter between calls to work + d_last_filter = 0; + + d_filters = std::vector<gr_fir_ccf*>(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_ccf(vtaps); + } + + // Now, actually set the filters' taps + set_taps(taps); +} + +gr_pfb_arb_resampler_ccf::~gr_pfb_arb_resampler_ccf () +{ + for(unsigned int i = 0; i < d_int_rate; i++) { + delete d_filters[i]; + } +} + +void +gr_pfb_arb_resampler_ccf::set_taps (const std::vector<float> &taps) +{ + unsigned int i,j; + + unsigned int ntaps = taps.size(); + d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate); + + // Create d_numchan vectors to store each channel's taps + d_taps.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 = taps; + while((float)(tmp_taps.size()) < d_int_rate*d_taps_per_filter) { + tmp_taps.push_back(0.0); + } + + // Partition the filter + for(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 + d_taps[i] = std::vector<float>(d_taps_per_filter, 0); + for(j = 0; j < d_taps_per_filter; j++) { + d_taps[i][j] = tmp_taps[i + j*d_int_rate]; // add taps to channels in reverse order + } + + // Build a filter for each channel and add it's taps to it + d_filters[i]->set_taps(d_taps[i]); + } + + // Set the history to ensure enough input items for each filter + set_history (d_taps_per_filter); + + d_updated = true; +} + +void +gr_pfb_arb_resampler_ccf::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_ccf::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr_complex *in = (gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + if (d_updated) { + d_updated = false; + return 0; // history requirements may have changed. + } + + int i = 0, j, count = 0; + gr_complex o0, o1; + + // Restore the last filter position + j = d_last_filter; + + // produce output as long as we can and there are enough input samples + while((i < noutput_items) && (count < ninput_items[0]-1)) { + + // start j by wrapping around mod the number of channels + while((j < d_int_rate) && (i < noutput_items)) { + // Take the current filter output + o0 = d_filters[j]->filter(&in[count]); + + // Take the next filter output; wrap around to 0 if necessary + if(j+1 == d_int_rate) + // Use the sample of the next input item through the first filter + o1 = d_filters[0]->filter(&in[count+1]); + else { + // Use the sample from the current input item through the nex filter + o1 = d_filters[j+1]->filter(&in[count]); + } + + //out[i] = o0; // nearest-neighbor approach + out[i] = o0 + (o1 - o0)*d_acc; // linearly interpolate between samples + i++; + + // Accumulate the position in the stream for the interpolated point. + // If it goes above 1, roll around to zero and increment the stride + // length this time by the decimation rate plus 1 for the increment + // due to the acculated position. + 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 + count++; // we have fully consumed another input + j = j % d_int_rate; // roll filter around + } + } + + // Store the current filter position + d_last_filter = j; + + consume_each(count); + return i; +} diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h new file mode 100644 index 000000000..b79a89fe9 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h @@ -0,0 +1,158 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + + +#ifndef INCLUDED_GR_PFB_ARB_RESAMPLER_CCF_H +#define INCLUDED_GR_PFB_ARB_RESAMPLER_CCF_H + +#include <gr_block.h> + +class gr_pfb_arb_resampler_ccf; +typedef boost::shared_ptr<gr_pfb_arb_resampler_ccf> gr_pfb_arb_resampler_ccf_sptr; +gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate, + const std::vector<float> &taps, + unsigned int filter_size=32); + +class gr_fir_ccf; + +/*! + * \class gr_pfb_arb_resampler_ccf + * + * \brief Polyphase filterbank arbitrary resampler with + * gr_complex input, gr_complex 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_ccf : 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_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate, + const std::vector<float> &taps, + unsigned int filter_size); + + std::vector<gr_fir_ccf*> d_filters; + std::vector< std::vector<float> > d_taps; + 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; + 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_ccf (float rate, + const std::vector<float> &taps, + unsigned int filter_size); + +public: + ~gr_pfb_arb_resampler_ccf (); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the interpolated sampling rate. + */ + void set_taps (const std::vector<float> &taps); + + /*! + * Print all of the filterbank taps to screen. + */ + void print_taps(); + + 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_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i new file mode 100644 index 000000000..e365e0314 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i @@ -0,0 +1,41 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,pfb_arb_resampler_ccf); + +gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate, + const std::vector<float> &taps, + unsigned int filter_size=32); + +class gr_pfb_arb_resampler_ccf : public gr_block +{ + private: + gr_pfb_arb_resampler_ccf (float rate, + const std::vector<float> &taps, + unsigned int filter_size); + + public: + ~gr_pfb_arb_resampler_ccf (); + + void set_taps (const std::vector<float> &taps); + void print_taps(); +}; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc new file mode 100644 index 000000000..7be611e23 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc @@ -0,0 +1,150 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pfb_channelizer_ccf.h> +#include <gr_fir_ccf.h> +#include <gr_fir_util.h> +#include <gri_fft.h> +#include <gr_io_signature.h> + +gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, + const std::vector<float> &taps) +{ + return gr_pfb_channelizer_ccf_sptr (new gr_pfb_channelizer_ccf (numchans, taps)); +} + + +gr_pfb_channelizer_ccf::gr_pfb_channelizer_ccf (unsigned int numchans, + const std::vector<float> &taps) + : gr_sync_block ("pfb_channelizer_ccf", + gr_make_io_signature (numchans, numchans, sizeof(gr_complex)), + gr_make_io_signature (1, 1, numchans*sizeof(gr_complex))), + d_updated (false) +{ + d_numchans = numchans; + d_filters = std::vector<gr_fir_ccf*>(d_numchans); + + // Create an FIR filter for each channel and zero out the taps + std::vector<float> vtaps(0, d_numchans); + for(unsigned int i = 0; i < d_numchans; i++) { + d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps); + } + + // Now, actually set the filters' taps + set_taps(taps); + + // Create the FFT to handle the output de-spinning of the channels + d_fft = new gri_fft_complex (d_numchans, false); +} + +gr_pfb_channelizer_ccf::~gr_pfb_channelizer_ccf () +{ + for(unsigned int i = 0; i < d_numchans; i++) { + delete d_filters[i]; + } +} + +void +gr_pfb_channelizer_ccf::set_taps (const std::vector<float> &taps) +{ + unsigned int i,j; + + unsigned int ntaps = taps.size(); + d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans); + + // Create d_numchan vectors to store each channel's taps + d_taps.resize(d_numchans); + + // 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 = taps; + while((float)(tmp_taps.size()) < d_numchans*d_taps_per_filter) { + tmp_taps.push_back(0.0); + } + + // Partition the filter + for(i = 0; i < d_numchans; i++) { + // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out + d_taps[i] = std::vector<float>(d_taps_per_filter, 0); + for(j = 0; j < d_taps_per_filter; j++) { + d_taps[i][j] = tmp_taps[i + j*d_numchans]; // add taps to channels in reverse order + } + + // Build a filter for each channel and add it's taps to it + d_filters[i]->set_taps(d_taps[i]); + } + + // Set the history to ensure enough input items for each filter + set_history (d_taps_per_filter); + + d_updated = true; +} + +void +gr_pfb_channelizer_ccf::print_taps() +{ + unsigned int i, j; + for(i = 0; i < d_numchans; i++) { + printf("filter[%d]: [", i); + for(j = 0; j < d_taps_per_filter; j++) { + printf(" %.4e", d_taps[i][j]); + } + printf("]\n\n"); + } +} + + +int +gr_pfb_channelizer_ccf::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr_complex *in = (gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + if (d_updated) { + d_updated = false; + return 0; // history requirements may have changed. + } + + for(int i = 0; i < noutput_items; i++) { + // Move through filters from bottom to top + for(int j = d_numchans-1; j >= 0; j--) { + // Take in the items from the first input stream to d_numchans + in = (gr_complex*)input_items[d_numchans - 1 - j]; + + // Filter current input stream from bottom filter to top + d_fft->get_inbuf()[j] = d_filters[j]->filter(&in[i]); + } + + // despin through FFT + d_fft->execute(); + memcpy(&out[d_numchans*i], d_fft->get_outbuf(), d_numchans*sizeof(gr_complex)); + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h new file mode 100644 index 000000000..7d0a31c59 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + + +#ifndef INCLUDED_GR_PFB_CHANNELIZER_CCF_H +#define INCLUDED_GR_PFB_CHANNELIZER_CCF_H + +#include <gr_sync_block.h> + +class gr_pfb_channelizer_ccf; +typedef boost::shared_ptr<gr_pfb_channelizer_ccf> gr_pfb_channelizer_ccf_sptr; +gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, + const std::vector<float> &taps); + +class gr_fir_ccf; +class gri_fft_complex; + + +/*! + * \class gr_pfb_channelizer_ccf + * + * \brief Polyphase filterbank channelizer with + * gr_complex input, gr_complex output and float taps + * + * \ingroup filter_blk + * + * This block takes in complex inputs and channelizes it to <EM>M</EM> + * channels of equal bandwidth. Each of the resulting channels is + * decimated to the new rate that is the input sampling rate + * <EM>fs</EM> divided by the number of channels, <EM>M</EM>. + * + * The PFB channelizer code takes the taps generated above and builds + * a set of filters. The set contains <EM>M</EM> number of filters + * and each filter contains ceil(taps.size()/decim) number of taps. + * Each tap from the filter prototype is sequentially inserted into + * the next filter. When all of the input taps are used, the remaining + * filters in the filterbank are filled out with 0's to make sure each + * filter has the same number of taps. + * + * Each filter operates using the gr_fir filter classs of GNU Radio, + * which takes the input stream at <EM>i</EM> and performs the inner + * product calculation to <EM>i+(n-1)</EM> where <EM>n</EM> is the + * number of filter taps. To efficiently handle this in the GNU Radio + * structure, each filter input must come from its own input + * stream. So the channelizer must be provided with <EM>M</EM> streams + * where the input stream has been deinterleaved. This is most easily + * done using the gr_stream_to_streams block. + * + * The output is then produced as a vector, where index <EM>i</EM> in + * the vector is the next sample from the <EM>i</EM>th channel. This + * is most easily handled by sending the output to a + * gr_vector_to_streams block to handle the conversion and passing + * <EM>M</EM> streams out. + * + * The input and output formatting is done using a hier_block2 called + * pfb_channelizer_ccf. This can take in a single stream and outputs + * <EM>M</EM> streams based on the behavior described above. + * + * The filter's taps should be based on the input sampling rate. + * + * For example, using the GNU Radio's firdes utility to building + * filters, 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 unity. + * + * <B><EM>self._taps = gr.firdes.low_pass_2(1, fs, BW, TB, + * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The theory behind this block can be found in Chapter 6 of + * the following book. + * + * <B><EM>f. harris, Multirate Signal Processing for Communication + * Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004. + * + */ + +class gr_pfb_channelizer_ccf : public gr_sync_block +{ + private: + /*! + * Build the polyphase filterbank decimator. + * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM> + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + friend gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, + const std::vector<float> &taps); + + std::vector<gr_fir_ccf*> d_filters; + std::vector< std::vector<float> > d_taps; + gri_fft_complex *d_fft; + unsigned int d_numchans; + unsigned int d_taps_per_filter; + bool d_updated; + + /*! + * Build the polyphase filterbank decimator. + * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM> + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + gr_pfb_channelizer_ccf (unsigned int numchans, + const std::vector<float> &taps); + +public: + ~gr_pfb_channelizer_ccf (); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + void set_taps (const std::vector<float> &taps); + + /*! + * Print all of the filterbank taps to screen. + */ + void print_taps(); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i new file mode 100644 index 000000000..4bef90e22 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,pfb_channelizer_ccf); + +gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, + const std::vector<float> &taps); + +class gr_pfb_channelizer_ccf : public gr_sync_block +{ + private: + gr_pfb_channelizer_ccf (unsigned int numchans, + const std::vector<float> &taps); + + public: + ~gr_pfb_channelizer_ccf (); + + void set_taps (const std::vector<float> &taps); +}; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc new file mode 100644 index 000000000..b334f5878 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc @@ -0,0 +1,174 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pfb_decimator_ccf.h> +#include <gr_fir_ccf.h> +#include <gr_fir_util.h> +#include <gri_fft.h> +#include <gr_io_signature.h> +#include <gr_expj.h> + +gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim, + const std::vector<float> &taps, + unsigned int channel) +{ + return gr_pfb_decimator_ccf_sptr (new gr_pfb_decimator_ccf (decim, taps, channel)); +} + + +gr_pfb_decimator_ccf::gr_pfb_decimator_ccf (unsigned int decim, + const std::vector<float> &taps, + unsigned int channel) + : gr_sync_block ("pfb_decimator_ccf", + gr_make_io_signature (decim, decim, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex))), + d_updated (false) +{ + d_rate = decim; + d_filters = std::vector<gr_fir_ccf*>(d_rate); + d_chan = channel; + d_rotator = new gr_complex[d_rate]; + + // Create an FIR filter for each channel and zero out the taps + std::vector<float> vtaps(0, d_rate); + for(unsigned int i = 0; i < d_rate; i++) { + d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps); + d_rotator[i] = gr_expj(i*2*M_PI*d_chan/d_rate); + } + + // Now, actually set the filters' taps + set_taps(taps); + + // Create the FFT to handle the output de-spinning of the channels + d_fft = new gri_fft_complex (d_rate, false); +} + +gr_pfb_decimator_ccf::~gr_pfb_decimator_ccf () +{ + for(unsigned int i = 0; i < d_rate; i++) { + delete d_filters[i]; + } +} + +void +gr_pfb_decimator_ccf::set_taps (const std::vector<float> &taps) +{ + unsigned int i,j; + + unsigned int ntaps = taps.size(); + d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_rate); + + // Create d_numchan vectors to store each channel's taps + d_taps.resize(d_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 = taps; + while((float)(tmp_taps.size()) < d_rate*d_taps_per_filter) { + tmp_taps.push_back(0.0); + } + + // Partition the filter + for(i = 0; i < d_rate; i++) { + // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out + d_taps[i] = std::vector<float>(d_taps_per_filter, 0); + for(j = 0; j < d_taps_per_filter; j++) { + d_taps[i][j] = tmp_taps[i + j*d_rate]; // add taps to channels in reverse order + } + + // Build a filter for each channel and add it's taps to it + d_filters[i]->set_taps(d_taps[i]); + } + + // Set the history to ensure enough input items for each filter + set_history (d_taps_per_filter); + + d_updated = true; +} + +void +gr_pfb_decimator_ccf::print_taps() +{ + unsigned int i, j; + for(i = 0; i < d_rate; i++) { + printf("filter[%d]: [", i); + for(j = 0; j < d_taps_per_filter; j++) { + printf(" %.4e", d_taps[i][j]); + } + printf("]\n\n"); + } +} + +#define ROTATEFFT + +int +gr_pfb_decimator_ccf::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr_complex *in; + gr_complex *out = (gr_complex *) output_items[0]; + + if (d_updated) { + d_updated = false; + return 0; // history requirements may have changed. + } + + int i; + for(i = 0; i < noutput_items; i++) { + // Move through filters from bottom to top + out[i] = 0; + for(int j = d_rate-1; j >= 0; j--) { + // Take in the items from the first input stream to d_rate + in = (gr_complex*)input_items[d_rate - 1 - j]; + + // Filter current input stream from bottom filter to top + // The rotate them by expj(j*k*2pi/M) where M is the number of filters + // (the decimation rate) and k is the channel number to extract + + // This is the real math that goes on; we abuse the FFT to do this quickly + // for decimation rates > N where N is a small number (~5): + // out[i] += d_filters[j]->filter(&in[i])*gr_expj(j*d_chan*2*M_PI/d_rate); +#ifdef ROTATEFFT + d_fft->get_inbuf()[j] = d_filters[j]->filter(&in[i]); +#else + out[i] += d_filters[j]->filter(&in[i])*d_rotator[i]; +#endif + } + +#ifdef ROTATEFFT + // Perform the FFT to do the complex multiply despinning for all channels + d_fft->execute(); + + // Select only the desired channel out + out[i] = d_fft->get_outbuf()[d_chan]; +#endif + + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h new file mode 100644 index 000000000..83997c0c9 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h @@ -0,0 +1,148 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + + +#ifndef INCLUDED_GR_PFB_DECIMATOR_CCF_H +#define INCLUDED_GR_PFB_DECIMATOR_CCF_H + +#include <gr_sync_block.h> + +class gr_pfb_decimator_ccf; +typedef boost::shared_ptr<gr_pfb_decimator_ccf> gr_pfb_decimator_ccf_sptr; +gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim, + const std::vector<float> &taps, + unsigned int channel=0); + +class gr_fir_ccf; +class gri_fft_complex; + +/*! + * \class gr_pfb_decimator_ccf + * \brief Polyphase filterbank bandpass decimator with gr_complex + * input, gr_complex output and float taps + * + * \ingroup filter_blk + * + * This block takes in a signal stream and performs interger down- + * sampling (decimation) with a polyphase filterbank. The first input + * is the integer specifying how much to decimate by. The second + * input is a vector (Python list) of floating-point taps of the + * prototype filter. The third input specifies the channel to extract. + * By default, the zeroth channel is used, which is the baseband + * channel (first Nyquist zone). + * + * The <EM>channel</EM> parameter specifies which channel to use since + * this class is capable of bandpass decimation. Given a complex input + * stream at a sampling rate of <EM>fs</EM> and a decimation rate of + * <EM>decim</EM>, the input frequency domain is split into + * <EM>decim</EM> channels that represent the Nyquist zones. Using the + * polyphase filterbank, we can select any one of these channels to + * decimate. + * + * The output signal will be the basebanded and decimated signal from + * that channel. This concept is very similar to the PFB channelizer + * (see #gr_pfb_channelizer_ccf) where only a single channel is + * extracted at a time. + * + * The filter's taps should be based on the sampling rate before + * decimation. + * + * For example, using the GNU Radio's firdes utility to building + * filters, 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 unity. + * + * <B><EM>self._taps = gr.firdes.low_pass_2(1, fs, BW, TB, + * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The PFB decimator code takes the taps generated above and builds a + * set of filters. The set contains <EM>decim</EM> number of filters + * and each filter contains ceil(taps.size()/decim) number of taps. + * Each tap from the filter prototype is sequentially inserted into + * the next filter. When all of the input taps are used, the remaining + * filters in the filterbank are filled out with 0's to make sure each + * filter has the same number of taps. + * + * The theory behind this block can be found in Chapter 6 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_decimator_ccf : public gr_sync_block +{ + private: + /*! + * Build the polyphase filterbank decimator. + * \param decim (unsigned integer) Specifies the decimation rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + * \param channel (unsigned integer) Selects the channel to return [default=0]. + */ + friend gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim, + const std::vector<float> &taps, + unsigned int channel); + + std::vector<gr_fir_ccf*> d_filters; + std::vector< std::vector<float> > d_taps; + gri_fft_complex *d_fft; + unsigned int d_rate; + unsigned int d_chan; + unsigned int d_taps_per_filter; + bool d_updated; + gr_complex *d_rotator; + + /*! + * Build the polyphase filterbank decimator. + * \param decim (unsigned integer) Specifies the decimation rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + * \param channel (unsigned integer) Selects the channel to return [default=0]. + */ + gr_pfb_decimator_ccf (unsigned int decim, + const std::vector<float> &taps, + unsigned int channel); + +public: + ~gr_pfb_decimator_ccf (); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + void set_taps (const std::vector<float> &taps); + + /*! + * Print all of the filterbank taps to screen. + */ + void print_taps(); + + //void set_channel (unsigned int channel); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i new file mode 100644 index 000000000..c4215fce1 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i @@ -0,0 +1,41 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,pfb_decimator_ccf); + +gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim, + const std::vector<float> &taps, + unsigned int channel); + +class gr_pfb_decimator_ccf : public gr_sync_block +{ + private: + gr_pfb_decimator_ccf (unsigned int decim, + const std::vector<float> &taps, + unsigned int channel); + + public: + ~gr_pfb_decimator_ccf (); + + void set_taps (const std::vector<float> &taps); + //void set_channel (unsigned int channel); +}; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc new file mode 100644 index 000000000..d5eba885c --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc @@ -0,0 +1,142 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_pfb_interpolator_ccf.h> +#include <gr_fir_ccf.h> +#include <gr_fir_util.h> +#include <gr_io_signature.h> + +gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp, + const std::vector<float> &taps) +{ + return gr_pfb_interpolator_ccf_sptr (new gr_pfb_interpolator_ccf (interp, taps)); +} + + +gr_pfb_interpolator_ccf::gr_pfb_interpolator_ccf (unsigned int interp, + const std::vector<float> &taps) + : gr_sync_interpolator ("pfb_interpolator_ccf", + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex)), + interp), + d_updated (false) +{ + d_rate = interp; + d_filters = std::vector<gr_fir_ccf*>(d_rate); + + // Create an FIR filter for each channel and zero out the taps + std::vector<float> vtaps(0, d_rate); + for(unsigned int i = 0; i < d_rate; i++) { + d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps); + } + + // Now, actually set the filters' taps + set_taps(taps); +} + +gr_pfb_interpolator_ccf::~gr_pfb_interpolator_ccf () +{ + for(unsigned int i = 0; i < d_rate; i++) { + delete d_filters[i]; + } +} + +void +gr_pfb_interpolator_ccf::set_taps (const std::vector<float> &taps) +{ + unsigned int i,j; + + unsigned int ntaps = taps.size(); + d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_rate); + + // Create d_numchan vectors to store each channel's taps + //std::vector< std::vector<float> > vtaps(d_rate); + d_taps.resize(d_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 = taps; + while((float)(tmp_taps.size()) < d_rate*d_taps_per_filter) { + tmp_taps.push_back(0.0); + } + + // Partition the filter + for(i = 0; i < d_rate; i++) { + // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out + d_taps[i] = std::vector<float>(d_taps_per_filter, 0); + for(j = 0; j < d_taps_per_filter; j++) { + d_taps[i][j] = tmp_taps[i + j*d_rate]; // add taps to channels in reverse order + } + + // Build a filter for each channel and add it's taps to it + d_filters[i]->set_taps(d_taps[i]); + } + + // Set the history to ensure enough input items for each filter + set_history (d_taps_per_filter); + + d_updated = true; +} + +void +gr_pfb_interpolator_ccf::print_taps() +{ + unsigned int i, j; + for(i = 0; i < d_rate; i++) { + printf("filter[%d]: [", i); + for(j = 0; j < d_taps_per_filter; j++) { + printf(" %.4e", d_taps[i][j]); + } + printf("]\n\n"); + } +} + +int +gr_pfb_interpolator_ccf::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr_complex *in = (gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + if (d_updated) { + d_updated = false; + return 0; // history requirements may have changed. + } + + int i = 0, count = 0; + + while(i < noutput_items) { + for(int j = 0; j < d_rate; j++) { + out[i] = d_filters[j]->filter(&in[count]); + i++; + } + count++; + } + + return i; +} diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h new file mode 100644 index 000000000..50849d510 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h @@ -0,0 +1,129 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + + +#ifndef INCLUDED_GR_PFB_INTERPOLATOR_CCF_H +#define INCLUDED_GR_PFB_INTERPOLATOR_CCF_H + +#include <gr_sync_interpolator.h> + +class gr_pfb_interpolator_ccf; +typedef boost::shared_ptr<gr_pfb_interpolator_ccf> gr_pfb_interpolator_ccf_sptr; +gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp, + const std::vector<float> &taps); + +class gr_fir_ccf; + +/*! + * \class gr_pfb_interpolator_ccf + * \brief Polyphase filterbank interpolator with gr_complex input, + * gr_complex output and float taps + * + * \ingroup filter_blk + * + * This block takes in a signal stream and performs interger up- + * sampling (interpolation) with a polyphase filterbank. The first + * input is the integer specifying how much to interpolate by. The + * second input is a vector (Python list) of floating-point taps of + * the prototype filter. + * + * The filter's taps should be based on the interpolation rate + * specified. That is, the bandwidth specified is relative to the + * bandwidth after interpolation. + * + * For example, using the GNU Radio's firdes utility to building + * filters, 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, ATT, and the filter window function (a + * Blackman-harris window in this case). The first input is the gain, + * which is also specified as the interpolation rate so that the + * output levels are the same as the input (this creates an overall + * increase in power). + * + * <B><EM>self._taps = gr.firdes.low_pass_2(interp, interp*fs, BW, TB, + * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The PFB interpolator code takes the taps generated above and builds + * a set of filters. The set contains <EM>interp</EM> number of + * filters and each filter contains ceil(taps.size()/interp) number of + * taps. Each tap from the filter prototype is sequentially inserted + * into the next filter. When all of the input taps are used, the + * remaining filters in the filterbank are filled out with 0's to make + * sure each filter has the same number of taps. + * + * The theory behind this block can be found in Chapter 7.1 of the + * following book. + * + * <B><EM>f. harris, <EM>Multirate Signal Processing for Communication + * Systems</EM>," Upper Saddle River, NJ: Prentice Hall, + * Inc. 2004.</EM></B> + */ + +class gr_pfb_interpolator_ccf : public gr_sync_interpolator +{ + private: + /*! + * Build the polyphase filterbank interpolator. + * \param interp (unsigned integer) Specifies the interpolation rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the interpolated sampling rate. + */ + friend gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp, + const std::vector<float> &taps); + + std::vector<gr_fir_ccf*> d_filters; + std::vector< std::vector<float> > d_taps; + unsigned int d_rate; + unsigned int d_taps_per_filter; + bool d_updated; + + /*! + * Construct a Polyphase filterbank interpolator + * \param interp (unsigned integer) Specifies the interpolation rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the interpolated sampling rate. + */ + gr_pfb_interpolator_ccf (unsigned int interp, + const std::vector<float> &taps); + +public: + ~gr_pfb_interpolator_ccf (); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the interpolated sampling rate. + */ + void set_taps (const std::vector<float> &taps); + + /*! + * Print all of the filterbank taps to screen. + */ + void print_taps(); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i new file mode 100644 index 000000000..cf4302d45 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,pfb_interpolator_ccf); + +gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp, + const std::vector<float> &taps); + +class gr_pfb_interpolator_ccf : public gr_sync_interpolator +{ + private: + gr_pfb_interpolator_ccf (unsigned int interp, + const std::vector<float> &taps); + + public: + ~gr_pfb_interpolator_ccf (); + + void set_taps (const std::vector<float> &taps); + void print_taps(); +}; diff --git a/gnuradio-core/src/lib/g72x/.gitignore b/gnuradio-core/src/lib/g72x/.gitignore new file mode 100644 index 000000000..a02b6ff73 --- /dev/null +++ b/gnuradio-core/src/lib/g72x/.gitignore @@ -0,0 +1,8 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo diff --git a/gnuradio-core/src/lib/general/.gitignore b/gnuradio-core/src/lib/general/.gitignore new file mode 100644 index 000000000..4f3696f58 --- /dev/null +++ b/gnuradio-core/src/lib/general/.gitignore @@ -0,0 +1,323 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo +/*.pyc +/generate-stamp +/gr_constants.cc +/GrFIRfilterCCC.cc +/GrFIRfilterCCC.h +/GrFIRfilterCCF.cc +/GrFIRfilterCCF.h +/GrFIRfilterFCC.cc +/GrFIRfilterFCC.h +/GrFIRfilterFFF.cc +/GrFIRfilterFFF.h +/GrFIRfilterFSF.cc +/GrFIRfilterFSF.h +/GrFIRfilterSCC.cc +/GrFIRfilterSCC.h +/GrFIRfilterSIS.cc +/GrFIRfilterSIS.h +/GrFreqXlatingFIRfilterCCC.cc +/GrFreqXlatingFIRfilterCCC.h +/GrFreqXlatingFIRfilterCCF.cc +/GrFreqXlatingFIRfilterCCF.h +/GrFreqXlatingFIRfilterFCC.cc +/GrFreqXlatingFIRfilterFCC.h +/GrFreqXlatingFIRfilterFCF.cc +/GrFreqXlatingFIRfilterFCF.h +/GrFreqXlatingFIRfilterSCC.cc +/GrFreqXlatingFIRfilterSCC.h +/GrFreqXlatingFIRfilterSCF.cc +/GrFreqXlatingFIRfilterSCF.h +/gr_fir_CCC.cc +/gr_fir_CCC.h +/gr_fir_CCC_generic.cc +/gr_fir_CCC_generic.h +/gr_fir_CCF.cc +/gr_fir_CCF.h +/gr_fir_CCF_generic.cc +/gr_fir_CCF_generic.h +/gr_fir_FCC.cc +/gr_fir_FCC.h +/gr_fir_FCC_generic.cc +/gr_fir_FCC_generic.h +/gr_fir_FFF.cc +/gr_fir_FFF.h +/gr_fir_FFF_generic.cc +/gr_fir_FFF_generic.h +/gr_fir_FSF.cc +/gr_fir_FSF.h +/gr_fir_FSF_generic.cc +/gr_fir_FSF_generic.h +/gr_fir_SCC.cc +/gr_fir_SCC.h +/gr_fir_SCC_generic.cc +/gr_fir_SCC_generic.h +/gr_fir_SIS.cc +/gr_fir_SIS.h +/gr_fir_SIS_generic.cc +/gr_fir_SIS_generic.h +/gr_fir_sysconfig.cc +/gr_fir_sysconfig.h +/gr_fir_sysconfig_generic.cc +/gr_fir_sysconfig_generic.h +/gr_fir_util.cc +/gr_fir_util.h +/GrFIRfilterCCC.i +/GrFIRfilterCCF.i +/GrFIRfilterFCC.i +/GrFIRfilterFFF.i +/GrFIRfilterFSF.i +/GrFIRfilterSCC.i +/GrFIRfilterSIS.i +/GrFreqXlatingFIRfilterCCC.i +/GrFreqXlatingFIRfilterCCF.i +/GrFreqXlatingFIRfilterFCC.i +/GrFreqXlatingFIRfilterFCF.i +/GrFreqXlatingFIRfilterSCC.i +/GrFreqXlatingFIRfilterSCF.i +/# --- generated files --- +/gr_add_cc.cc +/gr_add_cc.h +/gr_add_cc.i +/gr_add_const_c.cc +/gr_add_const_c.h +/gr_add_const_c.i +/gr_add_const_cc.cc +/gr_add_const_cc.h +/gr_add_const_cc.i +/gr_add_const_f.cc +/gr_add_const_f.h +/gr_add_const_f.i +/gr_add_const_ff.cc +/gr_add_const_ff.h +/gr_add_const_ff.i +/gr_add_const_i.cc +/gr_add_const_i.h +/gr_add_const_i.i +/gr_add_const_ii.cc +/gr_add_const_ii.h +/gr_add_const_ii.i +/gr_add_const_s.cc +/gr_add_const_s.h +/gr_add_const_s.i +/gr_add_const_sf.cc +/gr_add_const_sf.h +/gr_add_const_sf.i +/gr_add_const_ss.cc +/gr_add_const_ss.h +/gr_add_const_ss.i +/gr_add_const_vcc.cc +/gr_add_const_vcc.h +/gr_add_const_vcc.i +/gr_add_const_vff.cc +/gr_add_const_vff.h +/gr_add_const_vff.i +/gr_add_const_vii.cc +/gr_add_const_vii.h +/gr_add_const_vii.i +/gr_add_const_vss.cc +/gr_add_const_vss.h +/gr_add_const_vss.i +/gr_add_ff.cc +/gr_add_ff.h +/gr_add_ff.i +/gr_add_ii.cc +/gr_add_ii.h +/gr_add_ii.i +/gr_add_ss.cc +/gr_add_ss.h +/gr_add_ss.i +/gr_add_vcc.cc +/gr_add_vcc.h +/gr_add_vcc.i +/gr_add_vff.cc +/gr_add_vff.h +/gr_add_vff.i +/gr_add_vii.cc +/gr_add_vii.h +/gr_add_vii.i +/gr_add_vss.cc +/gr_add_vss.h +/gr_add_vss.i +/gr_divide_cc.cc +/gr_divide_cc.h +/gr_divide_cc.i +/gr_divide_ff.cc +/gr_divide_ff.h +/gr_divide_ff.i +/gr_divide_ii.cc +/gr_divide_ii.h +/gr_divide_ii.i +/gr_divide_ss.cc +/gr_divide_ss.h +/gr_divide_ss.i +/gr_multiply_cc.cc +/gr_multiply_cc.h +/gr_multiply_cc.i +/gr_multiply_const_cc.cc +/gr_multiply_const_cc.h +/gr_multiply_const_cc.i +/gr_multiply_const_ff.cc +/gr_multiply_const_ff.h +/gr_multiply_const_ff.i +/gr_multiply_const_ii.cc +/gr_multiply_const_ii.h +/gr_multiply_const_ii.i +/gr_multiply_const_ss.cc +/gr_multiply_const_ss.h +/gr_multiply_const_ss.i +/gr_multiply_ff.cc +/gr_multiply_ff.h +/gr_multiply_ff.i +/gr_multiply_ii.cc +/gr_multiply_ii.h +/gr_multiply_ii.i +/gr_multiply_ss.cc +/gr_multiply_ss.h +/gr_multiply_ss.i +/gr_multiply_vcc.cc +/gr_multiply_vcc.h +/gr_multiply_vcc.i +/gr_multiply_vff.cc +/gr_multiply_vff.h +/gr_multiply_vff.i +/gr_multiply_vii.cc +/gr_multiply_vii.h +/gr_multiply_vii.i +/gr_multiply_vss.cc +/gr_multiply_vss.h +/gr_multiply_vss.i +/gr_multiply_const_vcc.cc +/gr_multiply_const_vcc.h +/gr_multiply_const_vcc.i +/gr_multiply_const_vff.cc +/gr_multiply_const_vff.h +/gr_multiply_const_vff.i +/gr_multiply_const_vii.cc +/gr_multiply_const_vii.h +/gr_multiply_const_vii.i +/gr_multiply_const_vss.cc +/gr_multiply_const_vss.h +/gr_multiply_const_vss.i +/gr_noise_source_c.cc +/gr_noise_source_c.h +/gr_noise_source_c.i +/gr_noise_source_f.cc +/gr_noise_source_f.h +/gr_noise_source_f.i +/gr_noise_source_i.cc +/gr_noise_source_i.h +/gr_noise_source_i.i +/gr_noise_source_s.cc +/gr_noise_source_s.h +/gr_noise_source_s.i +/gr_sig_source_c.cc +/gr_sig_source_c.h +/gr_sig_source_c.i +/gr_sig_source_f.cc +/gr_sig_source_f.h +/gr_sig_source_f.i +/gr_sig_source_i.cc +/gr_sig_source_i.h +/gr_sig_source_i.i +/gr_sig_source_s.cc +/gr_sig_source_s.h +/gr_sig_source_s.i +/gr_sub_cc.cc +/gr_sub_cc.h +/gr_sub_cc.i +/gr_sub_ff.cc +/gr_sub_ff.h +/gr_sub_ff.i +/gr_sub_ii.cc +/gr_sub_ii.h +/gr_sub_ii.i +/gr_sub_ss.cc +/gr_sub_ss.h +/gr_sub_ss.i +/gr_vector_sink_b.cc +/gr_vector_sink_b.h +/gr_vector_sink_b.i +/gr_vector_sink_c.cc +/gr_vector_sink_c.h +/gr_vector_sink_c.i +/gr_vector_sink_f.cc +/gr_vector_sink_f.h +/gr_vector_sink_f.i +/gr_vector_sink_i.cc +/gr_vector_sink_i.h +/gr_vector_sink_i.i +/gr_vector_sink_s.cc +/gr_vector_sink_s.h +/gr_vector_sink_s.i +/gr_vector_source_b.cc +/gr_vector_source_b.h +/gr_vector_source_b.i +/gr_vector_source_c.cc +/gr_vector_source_c.h +/gr_vector_source_c.i +/gr_vector_source_f.cc +/gr_vector_source_f.h +/gr_vector_source_f.i +/gr_vector_source_i.cc +/gr_vector_source_i.h +/gr_vector_source_i.i +/gr_vector_source_s.cc +/gr_vector_source_s.h +/gr_vector_source_s.i +/gr_mute_cc.cc +/gr_mute_cc.h +/gr_mute_cc.i +/gr_mute_ff.cc +/gr_mute_ff.h +/gr_mute_ff.i +/gr_mute_ii.cc +/gr_mute_ii.h +/gr_mute_ii.i +/gr_mute_ss.cc +/gr_mute_ss.h +/gr_mute_ss.i +/gr_chunks_to_symbols_bc.cc +/gr_chunks_to_symbols_bc.h +/gr_chunks_to_symbols_bc.i +/gr_chunks_to_symbols_bf.cc +/gr_chunks_to_symbols_bf.h +/gr_chunks_to_symbols_bf.i +/gr_chunks_to_symbols_ic.cc +/gr_chunks_to_symbols_ic.h +/gr_chunks_to_symbols_ic.i +/gr_chunks_to_symbols_if.cc +/gr_chunks_to_symbols_if.h +/gr_chunks_to_symbols_if.i +/gr_chunks_to_symbols_sc.cc +/gr_chunks_to_symbols_sc.h +/gr_chunks_to_symbols_sc.i +/gr_chunks_to_symbols_sf.cc +/gr_chunks_to_symbols_sf.h +/gr_chunks_to_symbols_sf.i +/gr_packed_to_unpacked_bb.cc +/gr_packed_to_unpacked_bb.h +/gr_packed_to_unpacked_bb.i +/gr_packed_to_unpacked_ii.cc +/gr_packed_to_unpacked_ii.h +/gr_packed_to_unpacked_ii.i +/gr_packed_to_unpacked_ss.cc +/gr_packed_to_unpacked_ss.h +/gr_packed_to_unpacked_ss.i +/gr_unpacked_to_packed_bb.cc +/gr_unpacked_to_packed_bb.h +/gr_unpacked_to_packed_bb.i +/gr_unpacked_to_packed_ii.cc +/gr_unpacked_to_packed_ii.h +/gr_unpacked_to_packed_ii.i +/gr_unpacked_to_packed_ss.cc +/gr_unpacked_to_packed_ss.h +/gr_unpacked_to_packed_ss.i +/# --- end generated files --- diff --git a/gnuradio-core/src/lib/gengen/.gitignore b/gnuradio-core/src/lib/gengen/.gitignore new file mode 100644 index 000000000..ecd4cb0d5 --- /dev/null +++ b/gnuradio-core/src/lib/gengen/.gitignore @@ -0,0 +1,418 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo +/*.pyc +/generate-stamp +/GrFIRfilterCCC.cc +/GrFIRfilterCCC.h +/GrFIRfilterCCF.cc +/GrFIRfilterCCF.h +/GrFIRfilterFCC.cc +/GrFIRfilterFCC.h +/GrFIRfilterFFF.cc +/GrFIRfilterFFF.h +/GrFIRfilterFSF.cc +/GrFIRfilterFSF.h +/GrFIRfilterSCC.cc +/GrFIRfilterSCC.h +/GrFIRfilterSIS.cc +/GrFIRfilterSIS.h +/GrFreqXlatingFIRfilterCCC.cc +/GrFreqXlatingFIRfilterCCC.h +/GrFreqXlatingFIRfilterCCF.cc +/GrFreqXlatingFIRfilterCCF.h +/GrFreqXlatingFIRfilterFCC.cc +/GrFreqXlatingFIRfilterFCC.h +/GrFreqXlatingFIRfilterFCF.cc +/GrFreqXlatingFIRfilterFCF.h +/GrFreqXlatingFIRfilterSCC.cc +/GrFreqXlatingFIRfilterSCC.h +/GrFreqXlatingFIRfilterSCF.cc +/GrFreqXlatingFIRfilterSCF.h +/gr_fir_CCC.cc +/gr_fir_CCC.h +/gr_fir_CCC_generic.cc +/gr_fir_CCC_generic.h +/gr_fir_CCF.cc +/gr_fir_CCF.h +/gr_fir_CCF_generic.cc +/gr_fir_CCF_generic.h +/gr_fir_FCC.cc +/gr_fir_FCC.h +/gr_fir_FCC_generic.cc +/gr_fir_FCC_generic.h +/gr_fir_FFF.cc +/gr_fir_FFF.h +/gr_fir_FFF_generic.cc +/gr_fir_FFF_generic.h +/gr_fir_FSF.cc +/gr_fir_FSF.h +/gr_fir_FSF_generic.cc +/gr_fir_FSF_generic.h +/gr_fir_SCC.cc +/gr_fir_SCC.h +/gr_fir_SCC_generic.cc +/gr_fir_SCC_generic.h +/gr_fir_SIS.cc +/gr_fir_SIS.h +/gr_fir_SIS_generic.cc +/gr_fir_SIS_generic.h +/gr_fir_sysconfig.cc +/gr_fir_sysconfig.h +/gr_fir_sysconfig_generic.cc +/gr_fir_sysconfig_generic.h +/gr_fir_util.cc +/gr_fir_util.h +/GrFIRfilterCCC.i +/GrFIRfilterCCF.i +/GrFIRfilterFCC.i +/GrFIRfilterFFF.i +/GrFIRfilterFSF.i +/GrFIRfilterSCC.i +/GrFIRfilterSIS.i +/GrFreqXlatingFIRfilterCCC.i +/GrFreqXlatingFIRfilterCCF.i +/GrFreqXlatingFIRfilterFCC.i +/GrFreqXlatingFIRfilterFCF.i +/GrFreqXlatingFIRfilterSCC.i +/GrFreqXlatingFIRfilterSCF.i +/# --- generated files --- +/gr_add_cc.cc +/gr_add_cc.h +/gr_add_cc.i +/gr_add_const_c.cc +/gr_add_const_cc.cc +/gr_add_const_cc.h +/gr_add_const_cc.i +/gr_add_const_c.h +/gr_add_const_c.i +/gr_add_const_f.cc +/gr_add_const_ff.cc +/gr_add_const_ff.h +/gr_add_const_ff.i +/gr_add_const_f.h +/gr_add_const_f.i +/gr_add_const_i.cc +/gr_add_const_i.h +/gr_add_const_i.i +/gr_add_const_ii.cc +/gr_add_const_ii.h +/gr_add_const_ii.i +/gr_add_const_s.cc +/gr_add_const_sf.cc +/gr_add_const_sf.h +/gr_add_const_sf.i +/gr_add_const_s.h +/gr_add_const_s.i +/gr_add_const_ss.cc +/gr_add_const_ss.h +/gr_add_const_ss.i +/gr_add_const_vcc.cc +/gr_add_const_vcc.h +/gr_add_const_vcc.i +/gr_add_const_vff.cc +/gr_add_const_vff.h +/gr_add_const_vff.i +/gr_add_const_vii.cc +/gr_add_const_vii.h +/gr_add_const_vii.i +/gr_add_const_vss.cc +/gr_add_const_vss.h +/gr_add_const_vss.i +/gr_add_ff.cc +/gr_add_ff.h +/gr_add_ff.i +/gr_add_ii.cc +/gr_add_ii.h +/gr_add_ii.i +/gr_add_ss.cc +/gr_add_ss.h +/gr_add_ss.i +/gr_and_bb.cc +/gr_and_bb.h +/gr_and_bb.i +/gr_and_ii.cc +/gr_and_ii.h +/gr_and_ii.i +/gr_and_ss.cc +/gr_and_ss.h +/gr_and_ss.i +/gr_argmax_fs.cc +/gr_argmax_fs.h +/gr_argmax_fs.i +/gr_argmax_is.cc +/gr_argmax_is.h +/gr_argmax_is.i +/gr_argmax_ss.cc +/gr_argmax_ss.h +/gr_argmax_ss.i +/gr_chunks_to_symbols_bc.cc +/gr_chunks_to_symbols_bc.h +/gr_chunks_to_symbols_bc.i +/gr_chunks_to_symbols_bf.cc +/gr_chunks_to_symbols_bf.h +/gr_chunks_to_symbols_bf.i +/gr_chunks_to_symbols_ic.cc +/gr_chunks_to_symbols_ic.h +/gr_chunks_to_symbols_ic.i +/gr_chunks_to_symbols_if.cc +/gr_chunks_to_symbols_if.h +/gr_chunks_to_symbols_if.i +/gr_chunks_to_symbols_sc.cc +/gr_chunks_to_symbols_sc.h +/gr_chunks_to_symbols_sc.i +/gr_chunks_to_symbols_sf.cc +/gr_chunks_to_symbols_sf.h +/gr_chunks_to_symbols_sf.i +/gr_divide_cc.cc +/gr_divide_cc.h +/gr_divide_cc.i +/gr_divide_ff.cc +/gr_divide_ff.h +/gr_divide_ff.i +/gr_divide_ii.cc +/gr_divide_ii.h +/gr_divide_ii.i +/gr_divide_ss.cc +/gr_divide_ss.h +/gr_divide_ss.i +/gr_integrate_cc.cc +/gr_integrate_cc.h +/gr_integrate_cc.i +/gr_integrate_ff.cc +/gr_integrate_ff.h +/gr_integrate_ff.i +/gr_integrate_ii.cc +/gr_integrate_ii.h +/gr_integrate_ii.i +/gr_integrate_ss.cc +/gr_integrate_ss.h +/gr_integrate_ss.i +/gr_max_ff.cc +/gr_max_ff.h +/gr_max_ff.i +/gr_max_ii.cc +/gr_max_ii.h +/gr_max_ii.i +/gr_max_ss.cc +/gr_max_ss.h +/gr_max_ss.i +/gr_multiply_cc.cc +/gr_multiply_cc.h +/gr_multiply_cc.i +/gr_multiply_const_cc.cc +/gr_multiply_const_cc.h +/gr_multiply_const_cc.i +/gr_multiply_const_ff.cc +/gr_multiply_const_ff.h +/gr_multiply_const_ff.i +/gr_multiply_const_ii.cc +/gr_multiply_const_ii.h +/gr_multiply_const_ii.i +/gr_multiply_const_ss.cc +/gr_multiply_const_ss.h +/gr_multiply_const_ss.i +/gr_multiply_const_vcc.cc +/gr_multiply_const_vcc.h +/gr_multiply_const_vcc.i +/gr_multiply_const_vff.cc +/gr_multiply_const_vff.h +/gr_multiply_const_vff.i +/gr_multiply_const_vii.cc +/gr_multiply_const_vii.h +/gr_multiply_const_vii.i +/gr_multiply_const_vss.cc +/gr_multiply_const_vss.h +/gr_multiply_const_vss.i +/gr_multiply_ff.cc +/gr_multiply_ff.h +/gr_multiply_ff.i +/gr_multiply_ii.cc +/gr_multiply_ii.h +/gr_multiply_ii.i +/gr_multiply_ss.cc +/gr_multiply_ss.h +/gr_multiply_ss.i +/gr_mute_cc.cc +/gr_mute_cc.h +/gr_mute_cc.i +/gr_mute_ff.cc +/gr_mute_ff.h +/gr_mute_ff.i +/gr_mute_ii.cc +/gr_mute_ii.h +/gr_mute_ii.i +/gr_mute_ss.cc +/gr_mute_ss.h +/gr_mute_ss.i +/gr_noise_source_c.cc +/gr_noise_source_c.h +/gr_noise_source_c.i +/gr_noise_source_f.cc +/gr_noise_source_f.h +/gr_noise_source_f.i +/gr_noise_source_i.cc +/gr_noise_source_i.h +/gr_noise_source_i.i +/gr_noise_source_s.cc +/gr_noise_source_s.h +/gr_noise_source_s.i +/gr_not_bb.cc +/gr_not_bb.h +/gr_not_bb.i +/gr_not_ii.cc +/gr_not_ii.h +/gr_not_ii.i +/gr_not_ss.cc +/gr_not_ss.h +/gr_not_ss.i +/gr_or_bb.cc +/gr_or_bb.h +/gr_or_bb.i +/gr_or_ii.cc +/gr_or_ii.h +/gr_or_ii.i +/gr_or_ss.cc +/gr_or_ss.h +/gr_or_ss.i +/gr_packed_to_unpacked_bb.cc +/gr_packed_to_unpacked_bb.h +/gr_packed_to_unpacked_bb.i +/gr_packed_to_unpacked_ii.cc +/gr_packed_to_unpacked_ii.h +/gr_packed_to_unpacked_ii.i +/gr_packed_to_unpacked_ss.cc +/gr_packed_to_unpacked_ss.h +/gr_packed_to_unpacked_ss.i +/gr_peak_detector_fb.cc +/gr_peak_detector_fb.h +/gr_peak_detector_fb.i +/gr_peak_detector_ff.cc +/gr_peak_detector_ff.h +/gr_peak_detector_ff.i +/gr_peak_detector_ib.cc +/gr_peak_detector_ib.h +/gr_peak_detector_ib.i +/gr_peak_detector_ii.cc +/gr_peak_detector_ii.h +/gr_peak_detector_ii.i +/gr_peak_detector_sb.cc +/gr_peak_detector_sb.h +/gr_peak_detector_sb.i +/gr_peak_detector_ss.cc +/gr_peak_detector_ss.h +/gr_peak_detector_ss.i +/gr_prefix.cc +/gr_sample_and_hold_bb.cc +/gr_sample_and_hold_bb.h +/gr_sample_and_hold_bb.i +/gr_sample_and_hold_ff.cc +/gr_sample_and_hold_ff.h +/gr_sample_and_hold_ff.i +/gr_sample_and_hold_ii.cc +/gr_sample_and_hold_ii.h +/gr_sample_and_hold_ii.i +/gr_sample_and_hold_ss.cc +/gr_sample_and_hold_ss.h +/gr_sample_and_hold_ss.i +/gr_sig_source_c.cc +/gr_sig_source_c.h +/gr_sig_source_c.i +/gr_sig_source_f.cc +/gr_sig_source_f.h +/gr_sig_source_f.i +/gr_sig_source_i.cc +/gr_sig_source_i.h +/gr_sig_source_i.i +/gr_sig_source_s.cc +/gr_sig_source_s.h +/gr_sig_source_s.i +/gr_sub_cc.cc +/gr_sub_cc.h +/gr_sub_cc.i +/gr_sub_ff.cc +/gr_sub_ff.h +/gr_sub_ff.i +/gr_sub_ii.cc +/gr_sub_ii.h +/gr_sub_ii.i +/gr_sub_ss.cc +/gr_sub_ss.h +/gr_sub_ss.i +/gr_unpacked_to_packed_bb.cc +/gr_unpacked_to_packed_bb.h +/gr_unpacked_to_packed_bb.i +/gr_unpacked_to_packed_ii.cc +/gr_unpacked_to_packed_ii.h +/gr_unpacked_to_packed_ii.i +/gr_unpacked_to_packed_ss.cc +/gr_unpacked_to_packed_ss.h +/gr_unpacked_to_packed_ss.i +/gr_vector_sink_b.cc +/gr_vector_sink_b.h +/gr_vector_sink_b.i +/gr_vector_sink_c.cc +/gr_vector_sink_c.h +/gr_vector_sink_c.i +/gr_vector_sink_f.cc +/gr_vector_sink_f.h +/gr_vector_sink_f.i +/gr_vector_sink_i.cc +/gr_vector_sink_i.h +/gr_vector_sink_i.i +/gr_vector_sink_s.cc +/gr_vector_sink_s.h +/gr_vector_sink_s.i +/gr_vector_source_b.cc +/gr_vector_source_b.h +/gr_vector_source_b.i +/gr_vector_source_c.cc +/gr_vector_source_c.h +/gr_vector_source_c.i +/gr_vector_source_f.cc +/gr_vector_source_f.h +/gr_vector_source_f.i +/gr_vector_source_i.cc +/gr_vector_source_i.h +/gr_vector_source_i.i +/gr_vector_source_s.cc +/gr_vector_source_s.h +/gr_vector_source_s.i +/gr_xor_bb.cc +/gr_xor_bb.h +/gr_xor_bb.i +/gr_xor_ii.cc +/gr_xor_ii.h +/gr_xor_ii.i +/gr_xor_ss.cc +/gr_xor_ss.h +/gr_xor_ss.i +/gr_moving_average_cc.cc +/gr_moving_average_cc.h +/gr_moving_average_cc.i +/gr_moving_average_ff.cc +/gr_moving_average_ff.h +/gr_moving_average_ff.i +/gr_moving_average_ss.cc +/gr_moving_average_ss.h +/gr_moving_average_ss.i +/gr_moving_average_ii.cc +/gr_moving_average_ii.h +/gr_moving_average_ii.i +/gr_and_const_bb.cc +/gr_and_const_ss.h +/gr_and_const_ss.i +/gr_and_const_ii.cc +/gr_and_const_bb.h +/gr_and_const_ss.cc +/gr_and_const_bb.i +/gr_and_const_ii.h +/gr_and_const_ii.i +/# --- end generated files --- +/stamp-* +/gengen_generated.i diff --git a/gnuradio-core/src/lib/hier/.gitignore b/gnuradio-core/src/lib/hier/.gitignore new file mode 100644 index 000000000..89a768d46 --- /dev/null +++ b/gnuradio-core/src/lib/hier/.gitignore @@ -0,0 +1,4 @@ +/Makefile +/Makefile.in +/.libs +/.deps diff --git a/gnuradio-core/src/lib/io/.gitignore b/gnuradio-core/src/lib/io/.gitignore new file mode 100644 index 000000000..a02b6ff73 --- /dev/null +++ b/gnuradio-core/src/lib/io/.gitignore @@ -0,0 +1,8 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo diff --git a/gnuradio-core/src/lib/missing/.gitignore b/gnuradio-core/src/lib/missing/.gitignore new file mode 100644 index 000000000..a02b6ff73 --- /dev/null +++ b/gnuradio-core/src/lib/missing/.gitignore @@ -0,0 +1,8 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo diff --git a/gnuradio-core/src/lib/reed-solomon/.gitignore b/gnuradio-core/src/lib/reed-solomon/.gitignore new file mode 100644 index 000000000..f137f5c67 --- /dev/null +++ b/gnuradio-core/src/lib/reed-solomon/.gitignore @@ -0,0 +1,9 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo +/rstest diff --git a/gnuradio-core/src/lib/runtime/.gitignore b/gnuradio-core/src/lib/runtime/.gitignore new file mode 100644 index 000000000..a02b6ff73 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/.gitignore @@ -0,0 +1,8 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am index 14ab464ad..b0e804277 100644 --- a/gnuradio-core/src/lib/runtime/Makefile.am +++ b/gnuradio-core/src/lib/runtime/Makefile.am @@ -44,6 +44,7 @@ libruntime_la_SOURCES = \ gr_io_signature.cc \ gr_local_sighandler.cc \ gr_message.cc \ + gr_msg_accepter.cc \ gr_msg_handler.cc \ gr_msg_queue.cc \ gr_pagesize.cc \ @@ -96,6 +97,7 @@ grinclude_HEADERS = \ gr_io_signature.h \ gr_local_sighandler.h \ gr_message.h \ + gr_msg_accepter.h \ gr_msg_handler.h \ gr_msg_queue.h \ gr_pagesize.h \ diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc index 71ccc0245..2fa1066cb 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc @@ -41,8 +41,7 @@ gr_basic_block_ncurrently_allocated() gr_basic_block::gr_basic_block(const std::string &name, gr_io_signature_sptr input_signature, gr_io_signature_sptr output_signature) - : gruel::msg_accepter_msgq(gruel::make_msg_queue(0)), - d_name(name), + : d_name(name), d_input_signature(input_signature), d_output_signature(output_signature), d_unique_id(s_next_id++), diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h index 27ec0fd89..b8797fdc6 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.h +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h @@ -26,7 +26,7 @@ #include <gr_runtime_types.h> #include <gr_sptr_magic.h> #include <boost/enable_shared_from_this.hpp> -#include <gruel/msg_accepter_msgq.h> +#include <gr_msg_accepter.h> #include <string> /*! @@ -40,7 +40,7 @@ * signal processing functions. */ -class gr_basic_block : gruel::msg_accepter_msgq, public boost::enable_shared_from_this<gr_basic_block> +class gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block> { protected: friend class gr_flowgraph; diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc index ae1ea2562..d33dfed84 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc @@ -106,3 +106,10 @@ gr_block_detail::produce_each (int how_many_items) for (int i = 0; i < noutputs (); i++) d_output[i]->update_write_pointer (how_many_items); } + + +void +gr_block_detail::_post(pmt::pmt_t msg) +{ + d_tpb.insert_tail(msg); +} diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h index 2856c402c..9d6358602 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h @@ -79,6 +79,12 @@ class gr_block_detail { void produce_each (int how_many_items); + /*! + * Accept msg, place in queue, arrange for thread to be awakened if it's not already. + */ + void _post(pmt::pmt_t msg); + + gr_tpb_detail d_tpb; // used by thread-per-block scheduler // ---------------------------------------------------------------------------- diff --git a/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc b/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc new file mode 100644 index 000000000..89876ae29 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gr_msg_accepter.h> +#include <gr_block.h> +#include <gr_block_detail.h> +#include <gr_hier_block2.h> +#include <stdexcept> + +using namespace pmt; + +gr_msg_accepter::gr_msg_accepter() +{ +} + +gr_msg_accepter::~gr_msg_accepter() +{ + // NOP, required as virtual destructor +} + +void +gr_msg_accepter::post(pmt_t msg) +{ + // Notify derived class, handled case by case + gr_block *p = dynamic_cast<gr_block *>(this); + if (p) { + p->detail()->_post(msg); + return; + } + gr_hier_block2 *p2 = dynamic_cast<gr_hier_block2 *>(this); + if (p2){ + // FIXME do the right thing + return; + } + + throw std::runtime_error("unknown derived class"); +} diff --git a/gnuradio-core/src/lib/runtime/gr_msg_accepter.h b/gnuradio-core/src/lib/runtime/gr_msg_accepter.h new file mode 100644 index 000000000..79a631f3a --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_msg_accepter.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GR_MSG_ACCEPTER_H +#define INCLUDED_GR_MSG_ACCEPTER_H + +#include <gruel/msg_accepter.h> +#include <gruel/pmt.h> + +/*! + * \brief Accepts messages and inserts them into a message queue, then notifies + * subclass gr_basic_block there is a message pending. + */ +class gr_msg_accepter : public gruel::msg_accepter +{ +public: + gr_msg_accepter(); + ~gr_msg_accepter(); + + void post(pmt::pmt_t msg); + +}; + +#endif /* INCLUDED_GR_MSG_ACCEPTER_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc index 02e8deed8..c6311ccaa 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -27,6 +27,8 @@ #include <gr_block_detail.h> #include <gr_buffer.h> +using namespace pmt; + /* * We assume that no worker threads are ever running when the * graph structure is being manipulated, thus it's safe for us to poke @@ -65,3 +67,44 @@ gr_tpb_detail::notify_neighbors(gr_block_detail *d) notify_downstream(d); notify_upstream(d); } + +void +gr_tpb_detail::insert_tail(pmt::pmt_t msg) +{ + gruel::scoped_lock guard(mutex); + + msg_queue.push_back(msg); + + // wake up thread if BLKD_IN or BLKD_OUT + input_cond.notify_one(); + output_cond.notify_one(); +} + +pmt_t +gr_tpb_detail::delete_head_nowait() +{ + gruel::scoped_lock guard(mutex); + + if (empty_p()) + return pmt_t(); + + pmt_t m(msg_queue.front()); + msg_queue.pop_front(); + + return m; +} + +/* + * Caller must already be holding the mutex + */ +pmt_t +gr_tpb_detail::delete_head_nowait_already_holding_mutex() +{ + if (empty_p()) + return pmt_t(); + + pmt_t m(msg_queue.front()); + msg_queue.pop_front(); + + return m; +} diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.h b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h index ab955240b..acfa264c7 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h @@ -22,6 +22,8 @@ #define INCLUDED_GR_TPB_DETAIL_H #include <gruel/thread.h> +#include <deque> +#include <gruel/pmt.h> class gr_block_detail; @@ -36,9 +38,12 @@ struct gr_tpb_detail { bool output_changed; gruel::condition_variable output_cond; - gr_tpb_detail() - : input_changed(false), output_changed(false) {} +private: + std::deque<pmt::pmt_t> msg_queue; +public: + gr_tpb_detail() + : input_changed(false), output_changed(false) { } //! Called by us to tell all our upstream blocks that their output may have changed. void notify_upstream(gr_block_detail *d); @@ -56,6 +61,23 @@ struct gr_tpb_detail { input_changed = false; output_changed = false; } + + //! is the queue empty? + bool empty_p() const { return msg_queue.empty(); } + + //| Acquires and release the mutex + void insert_tail(pmt::pmt_t msg); + + /*! + * \returns returns pmt at head of queue or pmt_t() if empty. + */ + pmt::pmt_t delete_head_nowait(); + + /*! + * \returns returns pmt at head of queue or pmt_t() if empty. + * Caller must already be holding the mutex + */ + pmt::pmt_t delete_head_nowait_already_holding_mutex(); private: diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc index 458b16d64..03eef17d9 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc +++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc @@ -24,17 +24,26 @@ #include <gr_tpb_thread_body.h> #include <iostream> #include <boost/thread.hpp> +#include <gruel/pmt.h> + +using namespace pmt; gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block) : d_exec(block) { // std::cerr << "gr_tpb_thread_body: " << block << std::endl; - gr_block_detail *d = block->detail().get(); + gr_block_detail *d = block->detail().get(); gr_block_executor::state s; + pmt_t msg; + while (1){ boost::this_thread::interruption_point(); + + // handle any queued up messages + while ((msg = d->d_tpb.delete_head_nowait())) + block->handle_msg(msg); d->d_tpb.clear_changed(); s = d_exec.run_one_iteration(); @@ -55,16 +64,39 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block) case gr_block_executor::BLKD_IN: // Wait for input. { gruel::scoped_lock guard(d->d_tpb.mutex); - while(!d->d_tpb.input_changed) - d->d_tpb.input_cond.wait(guard); + while (!d->d_tpb.input_changed){ + + // wait for input or message + while(!d->d_tpb.input_changed && d->d_tpb.empty_p()) + d->d_tpb.input_cond.wait(guard); + + // handle all pending messages + while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){ + guard.unlock(); // release lock while processing msg + block->handle_msg(msg); + guard.lock(); + } + } } break; + case gr_block_executor::BLKD_OUT: // Wait for output buffer space. { gruel::scoped_lock guard(d->d_tpb.mutex); - while(!d->d_tpb.output_changed) - d->d_tpb.output_cond.wait(guard); + while (!d->d_tpb.output_changed){ + + // wait for output room or message + while(!d->d_tpb.output_changed && d->d_tpb.empty_p()) + d->d_tpb.output_cond.wait(guard); + + // handle all pending messages + while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){ + guard.unlock(); // release lock while processing msg + block->handle_msg(msg); + guard.lock(); + } + } } break; diff --git a/gnuradio-core/src/lib/swig/.gitignore b/gnuradio-core/src/lib/swig/.gitignore new file mode 100644 index 000000000..9d7d01056 --- /dev/null +++ b/gnuradio-core/src/lib/swig/.gitignore @@ -0,0 +1,36 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo +/*.pyc +/swigrun.py +/swigrun_wrap.c +/Makefile.swigdeps.new +/gnuradio_swig_py_runtime.d +/gnuradio_swig_py_general.d +/gnuradio_swig_py_gengen.d +/gnuradio_swig_py_filter.d +/gnuradio_swig_py_io.d +/gnuradio_swig_bug_workaround.h +/gnuradio_swig_py_runtime.cc +/gnuradio_swig_py_runtime.h +/gnuradio_swig_py_runtime.py +/gnuradio_swig_py_general.cc +/gnuradio_swig_py_general.h +/gnuradio_swig_py_general.py +/gnuradio_swig_py_gengen.cc +/gnuradio_swig_py_gengen.h +/gnuradio_swig_py_gengen.py +/gnuradio_swig_py_filter.cc +/gnuradio_swig_py_filter.h +/gnuradio_swig_py_filter.py +/gnuradio_swig_py_io.cc +/gnuradio_swig_py_io.h +/gnuradio_swig_py_io.py +/gnuradio_swig_py_hier.cc +/gnuradio_swig_py_hier.h +/gnuradio_swig_py_hier.py diff --git a/gnuradio-core/src/lib/viterbi/.gitignore b/gnuradio-core/src/lib/viterbi/.gitignore new file mode 100644 index 000000000..85bb5cc04 --- /dev/null +++ b/gnuradio-core/src/lib/viterbi/.gitignore @@ -0,0 +1,6 @@ +/Makefile +/Makefile.in +/.libs +/.deps +/encode +/decode |