diff options
20 files changed, 2134 insertions, 1137 deletions
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 index d4b14c594..48eb849ab 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc @@ -47,6 +47,8 @@ gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, gr_make_io_signature (1, 1, sizeof(gr_complex))), 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 @@ -131,23 +133,15 @@ void gr_pfb_arb_resampler_ccf::create_diff_taps(const std::vector<float> &newtaps, std::vector<float> &difftaps) { - float maxtap = 1e-20; + // 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(); - difftaps.push_back(0); //newtaps[0]); - for(unsigned int i = 1; i < newtaps.size()-1; i++) { - float tap = newtaps[i+1] - newtaps[i-1]; + for(unsigned int i = 0; i < newtaps.size()-1; i++) { + tap = newtaps[i+1] - newtaps[i]; difftaps.push_back(tap); - if(tap > maxtap) { - maxtap = tap; - } - } - difftaps.push_back(0);//-newtaps[newtaps.size()-1]); - - // Scale the differential taps; helps scale error term to better update state - // FIXME: should this be scaled this way or use the same gain as the taps? - for(unsigned int i = 0; i < difftaps.size(); i++) { - difftaps[i] /= maxtap; } + difftaps.push_back(tap); } void @@ -188,14 +182,17 @@ gr_pfb_arb_resampler_ccf::general_work (int noutput_items, // start j by wrapping around mod the number of channels while((j < d_int_rate) && (i < noutput_items)) { - // Take the current filter output + // 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_flt_rate; // linearly interpolate between samples + out[i] = o0 + o1*d_acc; // linearly interpolate between samples i++; - - j += d_dec_rate; + + // 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 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 index 531e9726f..b99ad286b 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h @@ -118,6 +118,7 @@ class gr_pfb_arb_resampler_ccf : public gr_block 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; diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc index 0f3d85c83..030e45ddf 100644 --- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc +++ b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc @@ -53,11 +53,13 @@ gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float ro } +static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)}; +static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int)); gr_fll_band_edge_cc::gr_fll_band_edge_cc (float samps_per_sym, float rolloff, int filter_size, float alpha, float beta) : gr_sync_block ("fll_band_edge_cc", gr_make_io_signature (1, 1, sizeof(gr_complex)), - gr_make_io_signature (1, 1, sizeof(gr_complex))), + gr_make_io_signaturev (1, 4, iosig)), d_alpha(alpha), d_beta(beta), d_updated (false) { // base this on the number of samples per symbol @@ -67,6 +69,29 @@ gr_fll_band_edge_cc::gr_fll_band_edge_cc (float samps_per_sym, float rolloff, d_freq = 0; d_phase = 0; + set_alpha(alpha); + + design_filter(samps_per_sym, rolloff, filter_size); +} + +gr_fll_band_edge_cc::~gr_fll_band_edge_cc () +{ + delete d_filter_lower; + delete d_filter_upper; +} + +void +gr_fll_band_edge_cc::set_alpha(float alpha) +{ + float eta = sqrt(2.0)/2.0; + float theta = alpha; + d_alpha = (4*eta*theta) / (1.0 + 2.0*eta*theta + theta*theta); + d_beta = (4*theta*theta) / (1.0 + 2.0*eta*theta + theta*theta); +} + +void +gr_fll_band_edge_cc::design_filter(float samps_per_sym, float rolloff, int filter_size) +{ int M = rint(filter_size / samps_per_sym); float power = 0; std::vector<float> bb_taps; @@ -81,11 +106,11 @@ gr_fll_band_edge_cc::gr_fll_band_edge_cc (float samps_per_sym, float rolloff, int N = (bb_taps.size() - 1.0)/2.0; std::vector<gr_complex> taps_lower; std::vector<gr_complex> taps_upper; - for(int i = 0; i < bb_taps.size(); i++) { + for(unsigned int i = 0; i < bb_taps.size(); i++) { float tap = bb_taps[i] / power; - float k = (-N + i)/(2.0*samps_per_sym); //rng = scipy.arange(-nn2, nn2+1) / (2*spb); - + float k = (-N + (int)i)/(2.0*samps_per_sym); + gr_complex t1 = tap * gr_expj(-2*M_PI*(1+rolloff)*k); gr_complex t2 = tap * gr_expj(2*M_PI*(1+rolloff)*k); @@ -97,61 +122,32 @@ gr_fll_band_edge_cc::gr_fll_band_edge_cc (float samps_per_sym, float rolloff, d_filter_upper = gr_fir_util::create_gr_fir_ccc(vtaps); d_filter_lower = gr_fir_util::create_gr_fir_ccc(vtaps); - set_taps_lower(taps_lower); - set_taps_upper(taps_upper); -} - -gr_fll_band_edge_cc::~gr_fll_band_edge_cc () -{ -} - -void -gr_fll_band_edge_cc::set_taps_lower (const std::vector<gr_complex> &taps) -{ - unsigned int i; - - for(i = 0; i < taps.size(); i++) { - d_taps_lower.push_back(taps[i]); - } - - d_filter_lower->set_taps(d_taps_lower); - - // Set the history to ensure enough input items for each filter - set_history(d_taps_lower.size()+1); + d_filter_lower->set_taps(taps_lower); + d_filter_upper->set_taps(taps_upper); d_updated = true; -} - -void -gr_fll_band_edge_cc::set_taps_upper (const std::vector<gr_complex> &taps) -{ - unsigned int i; - - for(i = 0; i < taps.size(); i++) { - d_taps_upper.push_back(taps[i]); - } - - d_filter_upper->set_taps(d_taps_upper); // Set the history to ensure enough input items for each filter - set_history(d_taps_upper.size()+1); + set_history(filter_size+1); - d_updated = true; } void gr_fll_band_edge_cc::print_taps() { unsigned int i; + std::vector<gr_complex> taps_upper = d_filter_upper->get_taps(); + std::vector<gr_complex> taps_lower = d_filter_lower->get_taps(); + printf("Upper Band-edge: ["); - for(i = 0; i < d_taps_upper.size(); i++) { - printf(" %.4e + %.4ej,", d_taps_upper[i].real(), d_taps_upper[i].imag()); + for(i = 0; i < taps_upper.size(); i++) { + printf(" %.4e + %.4ej,", taps_upper[i].real(), taps_upper[i].imag()); } printf("]\n\n"); printf("Lower Band-edge: ["); - for(i = 0; i < d_taps_lower.size(); i++) { - printf(" %.4e + %.4ej,", d_taps_lower[i].real(), d_taps_lower[i].imag()); + for(i = 0; i < taps_lower.size(); i++) { + printf(" %.4e + %.4ej,", taps_lower[i].real(), taps_lower[i].imag()); } printf("]\n\n"); } @@ -164,6 +160,13 @@ gr_fll_band_edge_cc::work (int noutput_items, const gr_complex *in = (const gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; + float *frq, *phs, *err; + if(output_items.size() > 2) { + frq = (float *) output_items[1]; + phs = (float *) output_items[2]; + err = (float *) output_items[3]; + } + if (d_updated) { d_updated = false; return 0; // history requirements may have changed. @@ -180,21 +183,28 @@ gr_fll_band_edge_cc::work (int noutput_items, out_upper = norm(d_filter_upper->filter(&out[i])); out_lower = norm(d_filter_lower->filter(&out[i])); error = out_lower - out_upper; - d_error = 0.1*error + 0.9*d_error; // average error + d_error = 0.01*error + 0.99*d_error; // average error - d_freq = d_freq + d_beta * error; - d_phase = d_phase + d_freq + d_alpha * error; + d_freq = d_freq + d_beta * d_error; + d_phase = d_phase + d_freq + d_alpha * d_error; if(d_phase > M_PI) d_phase -= M_TWOPI; else if(d_phase < -M_PI) d_phase += M_TWOPI; - + if (d_freq > d_max_freq) d_freq = d_max_freq; else if (d_freq < d_min_freq) d_freq = d_min_freq; + + if(output_items.size() > 2) { + frq[i] = d_freq; + phs[i] = d_phase; + err[i] = d_error; + } } + return noutput_items; } diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h index 86e69df16..09baf7fde 100644 --- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h +++ b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h @@ -39,6 +39,26 @@ class gri_fft_complex; * \brief Frequency Lock Loop using band-edge filters * * \ingroup general + * + * The frequency lock loop derives a band-edge filter that covers the upper and lower bandwidths + * of a digitally-modulated signal. The bandwidth range is determined by the excess bandwidth + * (e.g., rolloff factor) of the modulated signal. The placement in frequency of the band-edges + * is determined by the oversampling ratio (number of samples per symbol) and the excess bandwidth. + * The size of the filters should be fairly large so as to average over a number of symbols. + * The FLL works by calculating the power in both the upper and lower bands and comparing them. The + * difference in power between the filters is proportional to the frequency offset. + * + * In theory, the band-edge filter is the derivative of the matched filter in frequency, + * (H_be(f) = \frac{H(f)}{df}. In practice, this comes down to a quarter sine wave at the point + * of the matched filter's rolloff (if it's a raised-cosine, the derivative of a cosine is a sine). + * Extend this sine by another quarter wave to make a half wave around the band-edges is equivalent + * in time to the sum of two sinc functions. The baseband filter fot the band edges is therefore + * derived from this sum of sincs. The band edge filters are then just the baseband signal + * modulated to the correct place in frequency. All of these calculations are done in the + * 'design_filter' function. + * + * Note: We use FIR filters here because the filters have to have a flat phase response over the + * entire frequency range to allow their comparisons to be valid. */ class gr_fll_band_edge_cc : public gr_sync_block @@ -46,7 +66,11 @@ class gr_fll_band_edge_cc : public gr_sync_block private: /*! * Build the FLL - * \param taps (vector/list of gr_complex) The taps of the band-edge filter + * \param samps_per_sym (float) Number of samples per symbol of signal + * \param rolloff (float) Rolloff factor of signal + * \param filter_size (int) Size (in taps) of the filter + * \param alpha (float) Loop gain 1 + * \param beta (float) Loop gain 2 */ friend gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff, int filter_size, float alpha, float beta); @@ -58,8 +82,6 @@ class gr_fll_band_edge_cc : public gr_sync_block gr_fir_ccc* d_filter_upper; gr_fir_ccc* d_filter_lower; - std::vector<gr_complex> d_taps_upper; - std::vector<gr_complex> d_taps_lower; bool d_updated; float d_error; float d_freq; @@ -76,17 +98,19 @@ public: ~gr_fll_band_edge_cc (); /*! - * Resets the filter taps with the new prototype filter - * \param taps (vector/list of gr_complex) The band-edge filter + * Design the band-edge filter based on the number of samples per symbol, + * filter rolloff factor, and the filter size + * \param samps_per_sym (float) Number of samples per symbol of signal + * \param rolloff (float) Rolloff factor of signal + * \param filter_size (int) Size (in taps) of the filter */ - void set_taps_lower (const std::vector<gr_complex> &taps); - void set_taps_upper (const std::vector<gr_complex> &taps); + void design_filter(float samps_per_sym, float rolloff, int filter_size); /*! * Set the alpha gainvalue * \param alpha (float) new gain value */ - void set_alpha(float alpha) { d_alpha = alpha; } + void set_alpha(float alpha); /*! * Set the beta gain value diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i index 545bad4f6..c9c792c8a 100644 --- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i +++ b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i @@ -36,5 +36,6 @@ class gr_fll_band_edge_cc : public gr_sync_block void set_alpha (float alpha); void set_beta (float beta); + void design_filter(float samps_per_sym, float rolloff, int filter_size); void print_taps(); }; diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py index cd9a207c8..e9fb3df89 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py @@ -26,7 +26,7 @@ differential BPSK modulation and demodulation. """ from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt +from math import pi, sqrt, ceil import psk import cmath from pprint import pprint @@ -38,6 +38,7 @@ _def_gray_code = True _def_verbose = False _def_log = False +_def_freq_alpha = 4e-3 _def_costas_alpha = 0.1 _def_timing_alpha = 0.100 _def_timing_beta = 0.010 @@ -85,8 +86,6 @@ class dbpsk2_mod(gr.hier_block2): if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2: raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol) - ntaps = 11 * self._samples_per_symbol - arity = pow(2,self.bits_per_symbol()) # turn bytes into k-bit vectors @@ -103,15 +102,15 @@ class dbpsk2_mod(gr.hier_block2): self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity]) # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (samples_per_symbol since we're - # interpolating by samples_per_symbol) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) + nfilts = 32 + ntaps = nfilts * 11 * 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.interp_fir_filter_ccf(self._samples_per_symbol, - self.rrc_taps) + 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, @@ -182,6 +181,7 @@ class dbpsk2_demod(gr.hier_block2): def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, + freq_alpha=_def_freq_alpha, costas_alpha=_def_costas_alpha, timing_alpha=_def_timing_alpha, timing_max_dev=_def_timing_max_dev, @@ -199,9 +199,11 @@ class dbpsk2_demod(gr.hier_block2): @type samples_per_symbol: float @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float - @param costas_alpha: loop filter gain + @param freq_alpha: loop filter gain for frequency recovery + @type freq_alpha: float + @param costas_alpha: loop filter gain for phase/fine frequency recovery @type costas_alpha: float - @param timing_alpha: timing loop alpha gain + @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 @@ -223,6 +225,8 @@ class dbpsk2_demod(gr.hier_block2): 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._costas_alpha = costas_alpha self._timing_alpha = timing_alpha self._timing_beta = _def_timing_beta @@ -238,24 +242,32 @@ class dbpsk2_demod(gr.hier_block2): 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._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha # Allow a frequency swing of +/- half of the sample rate fmin = -0.5 fmax = 0.5 - self.clock_recov = gr.costas_loop_cc(self._costas_alpha, + self.phase_recov = gr.costas_loop_cc(self._costas_alpha, self._costas_beta, fmax, fmin, arity) - # symbol timing recovery with RRC data filter - nfilts = 32 - ntaps = 11 * 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) - # Do differential decoding based on phase change of symbols self.diffdec = gr.diff_phasor_cc() @@ -280,8 +292,7 @@ class dbpsk2_demod(gr.hier_block2): # Connect self.connect(self, self.agc, - self.clock_recov, - self.time_recov, + 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.time_recov, (self, 1)) @@ -297,6 +308,7 @@ class dbpsk2_demod(gr.hier_block2): 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 "Costas Loop alpha: %.2f" % self._costas_alpha print "Costas Loop beta: %.2f" % self._costas_beta print "Timing alpha gain: %.2f" % self._timing_alpha @@ -333,6 +345,8 @@ class dbpsk2_demod(gr.hier_block2): 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("", "--costas-alpha", type="float", default=None, help="set Costas loop alpha value [default=%default] (PSK)") parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha, diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py index fd1e9f0ef..9fae6acca 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py @@ -38,6 +38,7 @@ _def_gray_code = True _def_verbose = False _def_log = False +_def_freq_alpha = 4e-3 _def_costas_alpha = 0.01 _def_timing_alpha = 0.100 _def_timing_beta = 0.010 @@ -105,14 +106,15 @@ class dqpsk2_mod(gr.hier_block2): self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) + nfilts = 32 + ntaps = nfilts * 11 * 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.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) + self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) if verbose: self._print_verbage() @@ -182,6 +184,7 @@ class dqpsk2_demod(gr.hier_block2): def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, + freq_alpha=_def_freq_alpha, costas_alpha=_def_costas_alpha, timing_alpha=_def_timing_alpha, timing_max_dev=_def_timing_max_dev, @@ -199,6 +202,8 @@ class dqpsk2_demod(gr.hier_block2): @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 costas_alpha: loop filter gain @type costas_alphas: float @param timing_alpha: timing loop alpha gain @@ -223,6 +228,8 @@ class dqpsk2_demod(gr.hier_block2): 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._costas_alpha = costas_alpha self._timing_alpha = timing_alpha self._timing_beta = _def_timing_beta @@ -238,24 +245,35 @@ class dqpsk2_demod(gr.hier_block2): self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) #self.agc = gr.feedforward_agc_cc(16, 2.0) - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - # Allow a frequency swing of +/- half of the sample rate - fmin = -0.5 - fmax = 0.5 + # 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) - self.clock_recov = gr.costas_loop_cc(self._costas_alpha, - self._costas_beta, - fmax, fmin, arity) # symbol timing recovery with RRC data filter nfilts = 32 - ntaps = 11 * samples_per_symbol*nfilts - taps = gr.firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(self._samples_per_symbol), self._excess_bw, ntaps) + 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._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha + # Allow a frequency swing of +/- half of the sample rate + fmin = -0.5 + fmax = 0.5 + + self.phase_recov = gr.costas_loop_cc(self._costas_alpha, + self._costas_beta, + fmax, fmin, arity) + + # Perform Differential decoding on the constellation self.diffdec = gr.diff_phasor_cc() @@ -280,8 +298,7 @@ class dqpsk2_demod(gr.hier_block2): # Connect self.connect(self, self.agc, - self.clock_recov, - self.time_recov, + 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.time_recov, (self, 1)) @@ -297,6 +314,7 @@ class dqpsk2_demod(gr.hier_block2): 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 "Costas Loop alpha: %.2e" % self._costas_alpha print "Costas Loop beta: %.2e" % self._costas_beta print "Timing alpha gain: %.2f" % self._timing_alpha @@ -333,6 +351,8 @@ class dqpsk2_demod(gr.hier_block2): 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("", "--costas-alpha", type="float", default=_def_costas_alpha, help="set Costas loop alpha value [default=%default] (PSK)") parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha, diff --git a/gnuradio-examples/grc/Makefile.am b/gnuradio-examples/grc/Makefile.am index f8a26bace..118ecd593 100644 --- a/gnuradio-examples/grc/Makefile.am +++ b/gnuradio-examples/grc/Makefile.am @@ -31,7 +31,9 @@ dist_audiodata_DATA = \ demoddatadir = $(grc_examples_prefix)/demod dist_demoddata_DATA = \ demod/mpsk_demod.grc \ - demod/pam_timing.grc + demod/pam_timing.grc \ + demod/pam_sync.grc \ + demod/digital_freq_lock.grc simpledatadir = $(grc_examples_prefix)/simple dist_simpledata_DATA = \ diff --git a/gnuradio-examples/grc/demod/digital_freq_lock.grc b/gnuradio-examples/grc/demod/digital_freq_lock.grc index a7324a070..37ee8123e 100644 --- a/gnuradio-examples/grc/demod/digital_freq_lock.grc +++ b/gnuradio-examples/grc/demod/digital_freq_lock.grc @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Tue Dec 15 22:45:39 2009</timestamp> + <timestamp>Fri Jan 29 18:10:00 2010</timestamp> <block> <key>options</key> <param> @@ -911,45 +911,6 @@ </param> </block> <block> - <key>gr_channel_model</key> - <param> - <key>id</key> - <value>gr_channel_model_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>noise_voltage</key> - <value>noise_amp</value> - </param> - <param> - <key>freq_offset</key> - <value>freq_offset</value> - </param> - <param> - <key>epsilon</key> - <value>1.0</value> - </param> - <param> - <key>taps</key> - <value>1.0</value> - </param> - <param> - <key>seed</key> - <value>42</value> - </param> - <param> - <key>_coordinate</key> - <value>(346, 491)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>variable</key> <param> <key>id</key> @@ -1222,6 +1183,45 @@ <value>0</value> </param> </block> + <block> + <key>gr_channel_model</key> + <param> + <key>id</key> + <value>gr_channel_model_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>noise_voltage</key> + <value>noise_amp</value> + </param> + <param> + <key>freq_offset</key> + <value>freq_offset</value> + </param> + <param> + <key>epsilon</key> + <value>1.0</value> + </param> + <param> + <key>taps</key> + <value>1.0</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(618, 376)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> <connection> <source_block_id>random_source_x_0</source_block_id> <sink_block_id>gr_uchar_to_float_0</sink_block_id> diff --git a/gnuradio-examples/grc/demod/pam_sync.grc b/gnuradio-examples/grc/demod/pam_sync.grc index fc1186894..80a7aef0c 100644 --- a/gnuradio-examples/grc/demod/pam_sync.grc +++ b/gnuradio-examples/grc/demod/pam_sync.grc @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Tue Dec 15 23:06:57 2009</timestamp> + <timestamp>Mon Feb 1 18:58:32 2010</timestamp> <block> <key>options</key> <param> @@ -367,29 +367,6 @@ </param> </block> <block> - <key>gr_float_to_complex</key> - <param> - <key>id</key> - <value>gr_float_to_complex_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>vlen</key> - <value>1</value> - </param> - <param> - <key>_coordinate</key> - <value>(590, 184)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>variable</key> <param> <key>id</key> @@ -526,60 +503,6 @@ <key>variable</key> <param> <key>id</key> - <value>spb_gen</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>value</key> - <value>4</value> - </param> - <param> - <key>_coordinate</key> - <value>(119, 841)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> - <key>gr_multiply_const_vxx</key> - <param> - <key>id</key> - <value>gr_multiply_const_vxx_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>const</key> - <value>sig_amp</value> - </param> - <param> - <key>vlen</key> - <value>1</value> - </param> - <param> - <key>_coordinate</key> - <value>(1096, 197)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> - <key>variable</key> - <param> - <key>id</key> <value>pam_amp</value> </param> <param> @@ -646,80 +569,6 @@ </param> </block> <block> - <key>root_raised_cosine_filter</key> - <param> - <key>id</key> - <value>root_raised_cosine_filter_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>interp_fir_filter_ccf</value> - </param> - <param> - <key>decim</key> - <value>1</value> - </param> - <param> - <key>interp</key> - <value>spb_gen</value> - </param> - <param> - <key>gain</key> - <value>2*spb_gen</value> - </param> - <param> - <key>samp_rate</key> - <value>1.0</value> - </param> - <param> - <key>sym_rate</key> - <value>1./spb_gen</value> - </param> - <param> - <key>alpha</key> - <value>rolloff</value> - </param> - <param> - <key>ntaps</key> - <value>11*spb_gen</value> - </param> - <param> - <key>_coordinate</key> - <value>(834, 157)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> - <key>variable</key> - <param> - <key>id</key> - <value>spb</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>value</key> - <value>4.0</value> - </param> - <param> - <key>_coordinate</key> - <value>(32, 842)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>gr_throttle</key> <param> <key>id</key> @@ -1081,57 +930,6 @@ </param> </block> <block> - <key>gr_pfb_clock_sync_xxx</key> - <param> - <key>id</key> - <value>gr_pfb_clock_sync_xxx_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>ccf</value> - </param> - <param> - <key>sps</key> - <value>spb</value> - </param> - <param> - <key>alpha</key> - <value>time_alpha</value> - </param> - <param> - <key>beta</key> - <value>time_beta</value> - </param> - <param> - <key>taps</key> - <value>rrctaps</value> - </param> - <param> - <key>filter_size</key> - <value>nfilts</value> - </param> - <param> - <key>init_phase</key> - <value>16</value> - </param> - <param> - <key>max_dev</key> - <value>1.5</value> - </param> - <param> - <key>_coordinate</key> - <value>(655, 527)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>gr_costas_loop_cc</key> <param> <key>id</key> @@ -1238,37 +1036,6 @@ </param> </block> <block> - <key>blks2_pfb_arb_resampler_ccf</key> - <param> - <key>id</key> - <value>blks2_pfb_arb_resampler_ccf_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>rate</key> - <value>float(spb)/float(spb_gen)</value> - </param> - <param> - <key>taps</key> - <value>firdes.low_pass(128, 128, 0.45, 0.1)</value> - </param> - <param> - <key>size</key> - <value>128</value> - </param> - <param> - <key>_coordinate</key> - <value>(596, 326)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>variable</key> <param> <key>id</key> @@ -1292,49 +1059,6 @@ </param> </block> <block> - <key>gr_fll_band_edge_cc</key> - <param> - <key>id</key> - <value>gr_fll_band_edge_cc_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>cc</value> - </param> - <param> - <key>samps_per_sym</key> - <value>spb_gen</value> - </param> - <param> - <key>rolloff</key> - <value>rolloff</value> - </param> - <param> - <key>filter_size</key> - <value>44</value> - </param> - <param> - <key>alpha</key> - <value>freq_alpha</value> - </param> - <param> - <key>beta</key> - <value>freq_beta</value> - </param> - <param> - <key>_coordinate</key> - <value>(429, 543)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>notebook</key> <param> <key>id</key> @@ -1547,45 +1271,6 @@ </param> </block> <block> - <key>gr_channel_model</key> - <param> - <key>id</key> - <value>gr_channel_model_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>noise_voltage</key> - <value>noise_amp</value> - </param> - <param> - <key>freq_offset</key> - <value>freq_offset</value> - </param> - <param> - <key>epsilon</key> - <value>interpratio</value> - </param> - <param> - <key>taps</key> - <value>1.0</value> - </param> - <param> - <key>seed</key> - <value>42</value> - </param> - <param> - <key>_coordinate</key> - <value>(60, 443)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>virtual_sink</key> <param> <key>id</key> @@ -1688,7 +1373,248 @@ </param> <param> <key>_coordinate</key> - <value>(655, 686)</value> + <value>(663, 687)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_pfb_clock_sync_xxx</key> + <param> + <key>id</key> + <value>gr_pfb_clock_sync_xxx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>ccf</value> + </param> + <param> + <key>sps</key> + <value>spb</value> + </param> + <param> + <key>alpha</key> + <value>time_alpha</value> + </param> + <param> + <key>beta</key> + <value>time_beta</value> + </param> + <param> + <key>taps</key> + <value>rrctaps</value> + </param> + <param> + <key>filter_size</key> + <value>nfilts</value> + </param> + <param> + <key>init_phase</key> + <value>16</value> + </param> + <param> + <key>max_dev</key> + <value>1.5</value> + </param> + <param> + <key>_coordinate</key> + <value>(662, 527)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_float_to_complex</key> + <param> + <key>id</key> + <value>gr_float_to_complex_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(592, 184)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_channel_model</key> + <param> + <key>id</key> + <value>gr_channel_model_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>noise_voltage</key> + <value>noise_amp</value> + </param> + <param> + <key>freq_offset</key> + <value>freq_offset</value> + </param> + <param> + <key>epsilon</key> + <value>interpratio</value> + </param> + <param> + <key>taps</key> + <value>1.0</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(60, 443)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_multiply_const_vxx</key> + <param> + <key>id</key> + <value>gr_multiply_const_vxx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>const</key> + <value>sig_amp</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(670, 322)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blks2_pfb_arb_resampler_ccf</key> + <param> + <key>id</key> + <value>blks2_pfb_arb_resampler_ccf_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>rate</key> + <value>spb</value> + </param> + <param> + <key>taps</key> + <value>firdes.root_raised_cosine(32, 32, 1.0, 0.35, 44*32)</value> + </param> + <param> + <key>size</key> + <value>32</value> + </param> + <param> + <key>_coordinate</key> + <value>(778, 180)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_fll_band_edge_cc</key> + <param> + <key>id</key> + <value>gr_fll_band_edge_cc_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>cc</value> + </param> + <param> + <key>samps_per_sym</key> + <value>spb</value> + </param> + <param> + <key>rolloff</key> + <value>rolloff</value> + </param> + <param> + <key>filter_size</key> + <value>44</value> + </param> + <param> + <key>alpha</key> + <value>freq_alpha</value> + </param> + <param> + <key>beta</key> + <value>freq_beta</value> + </param> + <param> + <key>_coordinate</key> + <value>(429, 528)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>spb</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>4.0</value> + </param> + <param> + <key>_coordinate</key> + <value>(40, 829)</value> </param> <param> <key>_rotation</key> @@ -1720,12 +1646,6 @@ <sink_key>0</sink_key> </connection> <connection> - <source_block_id>blks2_pfb_arb_resampler_ccf_0</source_block_id> - <sink_block_id>gr_channel_model_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> <source_block_id>gr_channel_model_0</source_block_id> <sink_block_id>gr_throttle_0</sink_block_id> <source_key>0</source_key> @@ -1744,24 +1664,6 @@ <sink_key>1</sink_key> </connection> <connection> - <source_block_id>gr_float_to_complex_0</source_block_id> - <sink_block_id>root_raised_cosine_filter_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> - <source_block_id>root_raised_cosine_filter_0</source_block_id> - <sink_block_id>gr_multiply_const_vxx_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> - <source_block_id>gr_multiply_const_vxx_0</source_block_id> - <sink_block_id>blks2_pfb_arb_resampler_ccf_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> <source_block_id>gr_uchar_to_float_0</source_block_id> <sink_block_id>gr_add_xx_0</sink_block_id> <source_key>0</source_key> @@ -1821,4 +1723,22 @@ <source_key>0</source_key> <sink_key>0</sink_key> </connection> + <connection> + <source_block_id>gr_float_to_complex_0</source_block_id> + <sink_block_id>blks2_pfb_arb_resampler_ccf_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blks2_pfb_arb_resampler_ccf_0</source_block_id> + <sink_block_id>gr_multiply_const_vxx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_multiply_const_vxx_0</source_block_id> + <sink_block_id>gr_channel_model_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> </flow_graph> diff --git a/gnuradio-examples/grc/demod/pam_timing.grc b/gnuradio-examples/grc/demod/pam_timing.grc index 149e4c706..02130f481 100644 --- a/gnuradio-examples/grc/demod/pam_timing.grc +++ b/gnuradio-examples/grc/demod/pam_timing.grc @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Sat Oct 31 10:26:48 2009</timestamp> + <timestamp>Mon Feb 1 18:54:46 2010</timestamp> <block> <key>options</key> <param> @@ -173,29 +173,6 @@ </param> </block> <block> - <key>variable</key> - <param> - <key>id</key> - <value>rrctaps</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>value</key> - <value>firdes.root_raised_cosine(nfilts,1.0,1.0/(spb*nfilts), .35, int(11*spb*nfilts))</value> - </param> - <param> - <key>_coordinate</key> - <value>(513, 679)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>random_source_x</key> <param> <key>id</key> @@ -328,45 +305,6 @@ </param> </block> <block> - <key>gr_channel_model</key> - <param> - <key>id</key> - <value>gr_channel_model_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>noise_voltage</key> - <value>noise_amp</value> - </param> - <param> - <key>freq_offset</key> - <value>freq_offset</value> - </param> - <param> - <key>epsilon</key> - <value>interpratio</value> - </param> - <param> - <key>taps</key> - <value>1.0</value> - </param> - <param> - <key>seed</key> - <value>42</value> - </param> - <param> - <key>_coordinate</key> - <value>(59, 543)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>notebook</key> <param> <key>id</key> @@ -402,73 +340,6 @@ </param> </block> <block> - <key>wxgui_scopesink2</key> - <param> - <key>id</key> - <value>wxgui_scopesink2_0_0_1</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>title</key> - <value>Error</value> - </param> - <param> - <key>samp_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>v_scale</key> - <value>.5</value> - </param> - <param> - <key>v_offset</key> - <value>0</value> - </param> - <param> - <key>t_scale</key> - <value>0</value> - </param> - <param> - <key>ac_couple</key> - <value>False</value> - </param> - <param> - <key>xy_mode</key> - <value>False</value> - </param> - <param> - <key>num_inputs</key> - <value>1</value> - </param> - <param> - <key>win_size</key> - <value></value> - </param> - <param> - <key>grid_pos</key> - <value></value> - </param> - <param> - <key>notebook</key> - <value>notebook_0,3</value> - </param> - <param> - <key>_coordinate</key> - <value>(1115, 358)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>gr_add_xx</key> <param> <key>id</key> @@ -531,29 +402,6 @@ </param> </block> <block> - <key>gr_float_to_complex</key> - <param> - <key>id</key> - <value>gr_float_to_complex_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>vlen</key> - <value>1</value> - </param> - <param> - <key>_coordinate</key> - <value>(590, 184)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>variable</key> <param> <key>id</key> @@ -687,29 +535,6 @@ </param> </block> <block> - <key>variable</key> - <param> - <key>id</key> - <value>spb_gen</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>value</key> - <value>4</value> - </param> - <param> - <key>_coordinate</key> - <value>(119, 841)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>variable_slider</key> <param> <key>id</key> @@ -820,50 +645,45 @@ </param> </block> <block> - <key>root_raised_cosine_filter</key> + <key>variable</key> <param> <key>id</key> - <value>root_raised_cosine_filter_0</value> + <value>pam_amp</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>interp_fir_filter_ccf</value> - </param> - <param> - <key>decim</key> - <value>1</value> - </param> - <param> - <key>interp</key> - <value>spb_gen</value> + <key>value</key> + <value>2</value> </param> <param> - <key>gain</key> - <value>2*spb_gen</value> + <key>_coordinate</key> + <value>(223, 9)</value> </param> <param> - <key>samp_rate</key> - <value>1.0</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>variable</key> <param> - <key>sym_rate</key> - <value>1./spb_gen</value> + <key>id</key> + <value>sig_amp</value> </param> <param> - <key>alpha</key> - <value>0.35</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>ntaps</key> - <value>11*spb_gen</value> + <key>value</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(834, 157)</value> + <value>(315, 9)</value> </param> <param> <key>_rotation</key> @@ -871,30 +691,66 @@ </param> </block> <block> - <key>blks2_pfb_arb_resampler_ccf</key> + <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>blks2_pfb_arb_resampler_ccf_0</value> + <value>wxgui_scopesink2_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>rate</key> - <value>float(spb)/float(spb_gen)</value> + <key>type</key> + <value>complex</value> </param> <param> - <key>taps</key> - <value>firdes.low_pass(128, 128, 0.45, 0.1)</value> + <key>title</key> + <value>Scope Plot</value> </param> <param> - <key>size</key> - <value>128</value> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> </param> <param> <key>_coordinate</key> - <value>(617, 374)</value> + <value>(1116, 500)</value> </param> <param> <key>_rotation</key> @@ -902,10 +758,10 @@ </param> </block> <block> - <key>gr_multiply_const_vxx</key> + <key>gr_throttle</key> <param> <key>id</key> - <value>gr_multiply_const_vxx_0</value> + <value>gr_throttle_0</value> </param> <param> <key>_enabled</key> @@ -916,8 +772,8 @@ <value>complex</value> </param> <param> - <key>const</key> - <value>sig_amp</value> + <key>samples_per_second</key> + <value>samp_rate</value> </param> <param> <key>vlen</key> @@ -925,7 +781,7 @@ </param> <param> <key>_coordinate</key> - <value>(1096, 197)</value> + <value>(290, 575)</value> </param> <param> <key>_rotation</key> @@ -933,68 +789,66 @@ </param> </block> <block> - <key>variable</key> + <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>pam_amp</value> + <value>wxgui_scopesink2_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>2</value> + <key>type</key> + <value>float</value> </param> <param> - <key>_coordinate</key> - <value>(223, 9)</value> + <key>title</key> + <value>Error</value> </param> <param> - <key>_rotation</key> - <value>0</value> + <key>samp_rate</key> + <value>samp_rate</value> </param> - </block> - <block> - <key>variable</key> <param> - <key>id</key> - <value>spb</value> + <key>v_scale</key> + <value>3</value> </param> <param> - <key>_enabled</key> - <value>True</value> + <key>v_offset</key> + <value>0</value> </param> <param> - <key>value</key> - <value>4.1</value> + <key>t_scale</key> + <value>0</value> </param> <param> - <key>_coordinate</key> - <value>(32, 842)</value> + <key>ac_couple</key> + <value>False</value> </param> <param> - <key>_rotation</key> - <value>0</value> + <key>xy_mode</key> + <value>False</value> </param> - </block> - <block> - <key>variable</key> <param> - <key>id</key> - <value>sig_amp</value> + <key>num_inputs</key> + <value>1</value> </param> <param> - <key>_enabled</key> - <value>True</value> + <key>win_size</key> + <value></value> </param> <param> - <key>value</key> - <value>1</value> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value>notebook_0,0</value> </param> <param> <key>_coordinate</key> - <value>(315, 9)</value> + <value>(1110, 651)</value> </param> <param> <key>_rotation</key> @@ -1005,7 +859,7 @@ <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>wxgui_scopesink2_0</value> + <value>wxgui_scopesink2_0_0_0</value> </param> <param> <key>_enabled</key> @@ -1013,7 +867,7 @@ </param> <param> <key>type</key> - <value>complex</value> + <value>float</value> </param> <param> <key>title</key> @@ -1025,7 +879,7 @@ </param> <param> <key>v_scale</key> - <value>0</value> + <value>9</value> </param> <param> <key>v_offset</key> @@ -1057,11 +911,11 @@ </param> <param> <key>notebook</key> - <value></value> + <value>notebook_0,1</value> </param> <param> <key>_coordinate</key> - <value>(1116, 500)</value> + <value>(1112, 881)</value> </param> <param> <key>_rotation</key> @@ -1069,10 +923,33 @@ </param> </block> <block> - <key>gr_throttle</key> + <key>variable</key> <param> <key>id</key> - <value>gr_throttle_0</value> + <value>rrctaps</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>firdes.root_raised_cosine(nfilts,1.0,1.0/(spb*nfilts), .35, int(11*spb*nfilts))</value> + </param> + <param> + <key>_coordinate</key> + <value>(513, 679)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_pfb_clock_sync_xxx</key> + <param> + <key>id</key> + <value>gr_pfb_clock_sync_xxx_0</value> </param> <param> <key>_enabled</key> @@ -1080,19 +957,39 @@ </param> <param> <key>type</key> - <value>complex</value> + <value>ccf</value> </param> <param> - <key>samples_per_second</key> - <value>samp_rate</value> + <key>sps</key> + <value>spb</value> </param> <param> - <key>vlen</key> - <value>1</value> + <key>alpha</key> + <value>alpha</value> + </param> + <param> + <key>beta</key> + <value>beta</value> + </param> + <param> + <key>taps</key> + <value>rrctaps</value> + </param> + <param> + <key>filter_size</key> + <value>nfilts</value> + </param> + <param> + <key>init_phase</key> + <value>16</value> + </param> + <param> + <key>max_dev</key> + <value>1.5</value> </param> <param> <key>_coordinate</key> - <value>(290, 575)</value> + <value>(512, 527)</value> </param> <param> <key>_rotation</key> @@ -1103,7 +1000,7 @@ <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>wxgui_scopesink2_0_0</value> + <value>wxgui_scopesink2_0_0_0_0</value> </param> <param> <key>_enabled</key> @@ -1115,7 +1012,7 @@ </param> <param> <key>title</key> - <value>Error</value> + <value>Scope Plot</value> </param> <param> <key>samp_rate</key> @@ -1123,7 +1020,7 @@ </param> <param> <key>v_scale</key> - <value>3</value> + <value>1.25</value> </param> <param> <key>v_offset</key> @@ -1155,11 +1052,11 @@ </param> <param> <key>notebook</key> - <value>notebook_0,0</value> + <value>notebook_0,2</value> </param> <param> <key>_coordinate</key> - <value>(1110, 651)</value> + <value>(1111, 767)</value> </param> <param> <key>_rotation</key> @@ -1170,7 +1067,7 @@ <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>wxgui_scopesink2_0_0_0_0</value> + <value>wxgui_scopesink2_0_0_1</value> </param> <param> <key>_enabled</key> @@ -1178,11 +1075,11 @@ </param> <param> <key>type</key> - <value>float</value> + <value>complex</value> </param> <param> <key>title</key> - <value>Scope Plot</value> + <value>Error</value> </param> <param> <key>samp_rate</key> @@ -1190,7 +1087,7 @@ </param> <param> <key>v_scale</key> - <value>1.25</value> + <value>.5</value> </param> <param> <key>v_offset</key> @@ -1222,11 +1119,11 @@ </param> <param> <key>notebook</key> - <value>notebook_0,2</value> + <value>notebook_0,3</value> </param> <param> <key>_coordinate</key> - <value>(1111, 767)</value> + <value>(1115, 358)</value> </param> <param> <key>_rotation</key> @@ -1234,50 +1131,53 @@ </param> </block> <block> - <key>gr_pfb_clock_sync_xxx</key> + <key>gr_float_to_complex</key> <param> <key>id</key> - <value>gr_pfb_clock_sync_xxx_0</value> + <value>gr_float_to_complex_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>ccf</value> + <key>vlen</key> + <value>1</value> </param> <param> - <key>sps</key> - <value>spb</value> + <key>_coordinate</key> + <value>(590, 184)</value> </param> <param> - <key>alpha</key> - <value>alpha</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>blks2_pfb_arb_resampler_ccf</key> <param> - <key>beta</key> - <value>beta</value> + <key>id</key> + <value>blks2_pfb_arb_resampler_ccf_0</value> </param> <param> - <key>taps</key> - <value>rrctaps</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>filter_size</key> - <value>nfilts</value> + <key>rate</key> + <value>spb</value> </param> <param> - <key>init_phase</key> - <value>16</value> + <key>taps</key> + <value>firdes.root_raised_cosine(32, 32, 1.0, 0.35, 44*32)</value> </param> <param> - <key>max_dev</key> - <value>1.5</value> + <key>size</key> + <value>32</value> </param> <param> <key>_coordinate</key> - <value>(512, 527)</value> + <value>(816, 181)</value> </param> <param> <key>_rotation</key> @@ -1285,66 +1185,92 @@ </param> </block> <block> - <key>wxgui_scopesink2</key> + <key>gr_channel_model</key> <param> <key>id</key> - <value>wxgui_scopesink2_0_0_0</value> + <value>gr_channel_model_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>float</value> + <key>noise_voltage</key> + <value>noise_amp</value> </param> <param> - <key>title</key> - <value>Scope Plot</value> + <key>freq_offset</key> + <value>freq_offset</value> </param> <param> - <key>samp_rate</key> - <value>samp_rate</value> + <key>epsilon</key> + <value>interpratio</value> </param> <param> - <key>v_scale</key> - <value>9</value> + <key>taps</key> + <value>1.0</value> </param> <param> - <key>v_offset</key> - <value>0</value> + <key>seed</key> + <value>42</value> </param> <param> - <key>t_scale</key> + <key>_coordinate</key> + <value>(59, 543)</value> + </param> + <param> + <key>_rotation</key> <value>0</value> </param> + </block> + <block> + <key>gr_multiply_const_vxx</key> <param> - <key>ac_couple</key> - <value>False</value> + <key>id</key> + <value>gr_multiply_const_vxx_0</value> </param> <param> - <key>xy_mode</key> - <value>False</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>num_inputs</key> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>const</key> + <value>sig_amp</value> + </param> + <param> + <key>vlen</key> <value>1</value> </param> <param> - <key>win_size</key> - <value></value> + <key>_coordinate</key> + <value>(714, 382)</value> </param> <param> - <key>grid_pos</key> - <value></value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>variable</key> <param> - <key>notebook</key> - <value>notebook_0,1</value> + <key>id</key> + <value>spb</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>4.2563</value> </param> <param> <key>_coordinate</key> - <value>(1112, 881)</value> + <value>(42, 840)</value> </param> <param> <key>_rotation</key> @@ -1388,18 +1314,6 @@ <sink_key>0</sink_key> </connection> <connection> - <source_block_id>blks2_pfb_arb_resampler_ccf_0</source_block_id> - <sink_block_id>gr_channel_model_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> - <source_block_id>blks2_pfb_arb_resampler_ccf_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0_0_1</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> <source_block_id>gr_channel_model_0</source_block_id> <sink_block_id>gr_throttle_0</sink_block_id> <source_key>0</source_key> @@ -1418,51 +1332,57 @@ <sink_key>1</sink_key> </connection> <connection> - <source_block_id>gr_float_to_complex_0</source_block_id> - <sink_block_id>root_raised_cosine_filter_0</sink_block_id> + <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>root_raised_cosine_filter_0</source_block_id> - <sink_block_id>gr_multiply_const_vxx_0</sink_block_id> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_pfb_clock_sync_xxx_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gr_multiply_const_vxx_0</source_block_id> - <sink_block_id>blks2_pfb_arb_resampler_ccf_0</sink_block_id> - <source_key>0</source_key> + <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id> + <sink_block_id>wxgui_scopesink2_0_0</sink_block_id> + <source_key>1</source_key> <sink_key>0</sink_key> </connection> <connection> <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0</sink_block_id> - <source_key>0</source_key> + <sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id> + <source_key>3</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gr_throttle_0</source_block_id> - <sink_block_id>gr_pfb_clock_sync_xxx_0</sink_block_id> + <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id> + <sink_block_id>wxgui_scopesink2_0_0_0_0</sink_block_id> + <source_key>2</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_multiply_const_vxx_0</source_block_id> + <sink_block_id>wxgui_scopesink2_0_0_1</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0_0</sink_block_id> - <source_key>1</source_key> + <source_block_id>gr_float_to_complex_0</source_block_id> + <sink_block_id>blks2_pfb_arb_resampler_ccf_0</sink_block_id> + <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0_0_0_0</sink_block_id> - <source_key>2</source_key> + <source_block_id>blks2_pfb_arb_resampler_ccf_0</source_block_id> + <sink_block_id>gr_multiply_const_vxx_0</sink_block_id> + <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gr_pfb_clock_sync_xxx_0</source_block_id> - <sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id> - <source_key>3</source_key> + <source_block_id>gr_multiply_const_vxx_0</source_block_id> + <sink_block_id>gr_channel_model_0</sink_block_id> + <source_key>0</source_key> <sink_key>0</sink_key> </connection> </flow_graph> diff --git a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py index 101dd68d6..1cb95198e 100755 --- a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py +++ b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py @@ -52,9 +52,9 @@ class dialog_box(QtGui.QMainWindow): self.set_frequency(self.fg.frequency_offset()) self.set_time_offset(self.fg.timing_offset()) - self.set_alpha_time(self.fg.rx_timing_gain_alpha()) - self.set_beta_time(self.fg.rx_timing_gain_beta()) - self.set_alpha_freq(self.fg.rx_freq_gain_alpha()) + 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) @@ -75,12 +75,12 @@ class dialog_box(QtGui.QMainWindow): self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"), self.timeEditText) - self.connect(self.gui.alphaTimeEdit, QtCore.SIGNAL("editingFinished()"), - self.alphaTimeEditText) - self.connect(self.gui.betaTimeEdit, QtCore.SIGNAL("editingFinished()"), - self.betaTimeEditText) - self.connect(self.gui.alphaFreqEdit, QtCore.SIGNAL("editingFinished()"), - self.alphaFreqEditText) + 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 @@ -145,33 +145,43 @@ class dialog_box(QtGui.QMainWindow): # 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_freq(self, alpha): - self.gui.alphaFreqEdit.setText(QtCore.QString("%1").arg(alpha)) + def set_alpha_phase(self, alpha): + self.gui.alphaPhaseEdit.setText(QtCore.QString("%1").arg(alpha)) - def alphaFreqEditText(self): + def gainPhaseEditText(self): try: - alpha = self.gui.alphaFreqEdit.text().toDouble()[0] - self.fg.set_rx_freq_gain_alpha(alpha) + gain_phase = self.gui.gainPhaseEdit.text().toDouble()[0] + self.fg.set_rx_gain_phase(gain_phase) except RuntimeError: pass - def alphaTimeEditText(self): + def gainClockEditText(self): try: - alpha = self.gui.alphaTimeEdit.text().toDouble()[0] - self.fg.set_rx_timing_gain_alpha(alpha) + gain = self.gui.gainClockEdit.text().toDouble()[0] + self.fg.set_rx_gain_clock(gain) except RuntimeError: pass - def betaTimeEditText(self): + def gainFreqEditText(self): try: - beta = self.gui.betaTimeEdit.text().toDouble()[0] - self.fg.set_rx_timing_gain_beta(beta) + gain = self.gui.gainFreqEdit.text().toDouble()[0] + self.fg.set_rx_gain_freq(gain) except RuntimeError: pass @@ -186,7 +196,7 @@ class dialog_box(QtGui.QMainWindow): 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)) + self.gui.perEdit.setText(QtCore.QString("%1").arg(float(per), 0, 'e', 4)) @@ -218,9 +228,9 @@ class my_top_block(gr.top_block): 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._timing_alpha - self._timing_gain_beta = self.rxpath.packet_receiver._demodulator._timing_beta - self._freq_gain_alpha = self.rxpath.packet_receiver._demodulator._costas_alpha + self._gain_clock = self.rxpath.packet_receiver._demodulator._timing_alpha + self._gain_phase = self.rxpath.packet_receiver._demodulator._costas_alpha + self._gain_freq = self.rxpath.packet_receiver._demodulator._freq_alpha if channelon: self.channel = gr.channel_model(self._noise_voltage, @@ -254,17 +264,21 @@ class my_top_block(gr.top_block): 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.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.freq_recov = self.rxpath.packet_receiver._demodulator.clock_recov - self.time_recov = self.rxpath.packet_receiver._demodulator.time_recov - self.freq_recov.set_alpha(self._freq_gain_alpha) - self.freq_recov.set_beta(0.25*self._freq_gain_alpha*self._freq_gain_alpha) - self.time_recov.set_alpha(self._timing_gain_alpha) - self.time_recov.set_beta(self._timing_gain_beta) self.connect(self.channel, self.snk_tx) - self.connect(self.time_recov, self.snk_rx) + 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) @@ -321,32 +335,39 @@ class my_top_block(gr.top_block): # Receiver Parameters - def rx_timing_gain_alpha(self): - return self._timing_gain_alpha + def rx_gain_clock(self): + return self._gain_clock - 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.time_recov.set_alpha(self._timing_gain_alpha) + def rx_gain_clock_beta(self): + return self._gain_clock_beta - def set_rx_timing_gain_beta(self, gain): - self._timing_gain_beta = gain - self.time_recov.set_beta(self._timing_gain_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_freq_gain_alpha(self): - return self._freq_gain_alpha + def rx_gain_phase(self): + return self._gain_phase - def rx_freq_gain_beta(self): - return self._freq_gain_beta + def rx_gain_phase_beta(self): + return self._gain_phase_beta - def set_rx_freq_gain_alpha(self, alpha): - self._freq_gain_alpha = alpha - self._freq_gain_beta = .25 * self._freq_gain_alpha * self._freq_gain_alpha - self.freq_recov.set_alpha(self._freq_gain_alpha) - self.freq_recov.set_beta(self._freq_gain_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_fre_beta) # ///////////////////////////////////////////////////////////////////////////// diff --git a/gnuradio-examples/python/digital/benchmark_qt_rx2.py b/gnuradio-examples/python/digital/benchmark_qt_rx2.py new file mode 100755 index 000000000..cabbecb6f --- /dev/null +++ b/gnuradio-examples/python/digital/benchmark_qt_rx2.py @@ -0,0 +1,474 @@ +#!/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_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._costas_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(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 + 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_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_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/qt_digital_window2.py b/gnuradio-examples/python/digital/qt_digital_window2.py index f111e3772..98745dfe8 100644 --- a/gnuradio-examples/python/digital/qt_digital_window2.py +++ b/gnuradio-examples/python/digital/qt_digital_window2.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'qt_digital_window.ui' +# Form implementation generated from reading ui file 'qt_digital_window2.ui' # -# Created: Mon Oct 12 12:10:54 2009 +# Created: Sat Jan 2 16:42:30 2010 # by: PyQt4 UI code generator 4.4.3 # # WARNING! All changes made in this file will be lost! @@ -17,48 +17,6 @@ class Ui_DigitalWindow(object): self.centralwidget.setObjectName("centralwidget") self.gridLayout = QtGui.QGridLayout(self.centralwidget) self.gridLayout.setObjectName("gridLayout") - 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.gridLayout.addLayout(self.verticalLayout_2, 2, 0, 1, 1) self.verticalLayout_5 = QtGui.QVBoxLayout() self.verticalLayout_5.setObjectName("verticalLayout_5") self.sinkFrame = QtGui.QFrame(self.centralwidget) @@ -119,6 +77,21 @@ class Ui_DigitalWindow(object): self.timeEdit.setObjectName("timeEdit") self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.timeEdit) self.gridLayout.addWidget(self.channelModeBox, 2, 1, 1, 1) + 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) + spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) + self.verticalLayout.addItem(spacerItem) + 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.gridLayout.addLayout(self.verticalLayout, 2, 5, 1, 1) self.rxBox_2 = QtGui.QGroupBox(self.centralwidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -162,21 +135,48 @@ class Ui_DigitalWindow(object): self.gridLayout.addWidget(self.rxBox_2, 2, 3, 1, 1) spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem1, 2, 4, 1, 1) - 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) + 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) 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.gridLayout.addLayout(self.verticalLayout, 2, 5, 1, 1) + self.verticalLayout_2.addItem(spacerItem2) + self.gridLayout.addLayout(self.verticalLayout_2, 2, 0, 1, 1) self.rxBox = QtGui.QGroupBox(self.centralwidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -187,34 +187,34 @@ class Ui_DigitalWindow(object): 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, 10, 161, 101)) + self.formLayoutWidget_3.setGeometry(QtCore.QRect(10, 10, 164, 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.alphaTimeLabel = QtGui.QLabel(self.formLayoutWidget_3) - self.alphaTimeLabel.setObjectName("alphaTimeLabel") - self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.alphaTimeLabel) - self.alphaFreqLabel = QtGui.QLabel(self.formLayoutWidget_3) - self.alphaFreqLabel.setObjectName("alphaFreqLabel") - self.formLayout_3.setWidget(2, QtGui.QFormLayout.LabelRole, self.alphaFreqLabel) - self.alphaTimeEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.alphaTimeEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.alphaTimeEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.alphaTimeEdit.setObjectName("alphaTimeEdit") - self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.alphaTimeEdit) - self.alphaFreqEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.alphaFreqEdit.setMinimumSize(QtCore.QSize(60, 0)) - self.alphaFreqEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.alphaFreqEdit.setObjectName("alphaFreqEdit") - self.formLayout_3.setWidget(2, QtGui.QFormLayout.FieldRole, self.alphaFreqEdit) - self.betaTimeEdit = QtGui.QLineEdit(self.formLayoutWidget_3) - self.betaTimeEdit.setMaximumSize(QtCore.QSize(80, 16777215)) - self.betaTimeEdit.setObjectName("betaTimeEdit") - self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.betaTimeEdit) - self.betaTimeLabel = QtGui.QLabel(self.formLayoutWidget_3) - self.betaTimeLabel.setObjectName("betaTimeLabel") - self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.betaTimeLabel) + 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.gridLayout.addWidget(self.rxBox, 2, 2, 1, 1) DigitalWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(DigitalWindow) @@ -240,22 +240,22 @@ class Ui_DigitalWindow(object): 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.pauseButton.setText(QtGui.QApplication.translate("DigitalWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8)) + self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", 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.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.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8)) - self.alphaTimeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha: time", None, QtGui.QApplication.UnicodeUTF8)) - self.alphaFreqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha: freq", None, QtGui.QApplication.UnicodeUTF8)) - self.betaTimeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Beta: time", 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.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 index dc20ed798..4e87ff058 100644 --- a/gnuradio-examples/python/digital/qt_digital_window2.ui +++ b/gnuradio-examples/python/digital/qt_digital_window2.ui @@ -14,116 +14,6 @@ </property> <widget class="QWidget" name="centralwidget" > <layout class="QGridLayout" name="gridLayout" > - <item row="2" column="0" > - <layout class="QVBoxLayout" name="verticalLayout_2" > - <item> - <widget class="QGroupBox" name="sysBox" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="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 vsizetype="Fixed" hsizetype="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 vsizetype="Fixed" hsizetype="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 row="0" column="0" colspan="6" > <layout class="QVBoxLayout" name="verticalLayout_5" > <item> @@ -265,10 +155,66 @@ </item> </layout> </widget> - <zorder>formLayoutWidget_2</zorder> - <zorder>rxBox</zorder> </widget> </item> + <item row="2" column="5" > + <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> <item row="2" column="3" > <widget class="QGroupBox" name="rxBox_2" > <property name="sizePolicy" > @@ -384,7 +330,6 @@ <zorder>pktsRcvdEdit</zorder> <zorder>pktsCorrectEdit</zorder> <zorder>perEdit</zorder> - <zorder>rxBox</zorder> </widget> </widget> </item> @@ -401,29 +346,100 @@ </property> </spacer> </item> - <item row="2" column="5" > - <layout class="QVBoxLayout" name="verticalLayout" > + <item row="2" column="0" > + <layout class="QVBoxLayout" name="verticalLayout_2" > <item> - <widget class="QPushButton" name="pauseButton" > + <widget class="QGroupBox" name="sysBox" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="minimumSize" > <size> - <width>80</width> - <height>0</height> + <width>240</width> + <height>60</height> </size> </property> <property name="maximumSize" > <size> - <width>80</width> + <width>240</width> <height>16777215</height> </size> </property> - <property name="text" > - <string>Pause</string> + <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 vsizetype="Fixed" hsizetype="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 vsizetype="Fixed" hsizetype="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" > + <spacer name="verticalSpacer_2" > <property name="orientation" > <enum>Qt::Vertical</enum> </property> @@ -438,25 +454,6 @@ </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> <item row="2" column="2" > @@ -487,7 +484,7 @@ <rect> <x>10</x> <y>10</y> - <width>161</width> + <width>164</width> <height>101</height> </rect> </property> @@ -496,21 +493,21 @@ <enum>QLayout::SetFixedSize</enum> </property> <item row="0" column="0" > - <widget class="QLabel" name="alphaTimeLabel" > + <widget class="QLabel" name="gainClockLabel" > <property name="text" > - <string>Alpha: time</string> + <string>Clock Loop Gain</string> </property> </widget> </item> <item row="2" column="0" > - <widget class="QLabel" name="alphaFreqLabel" > + <widget class="QLabel" name="gainPhaseLabel" > <property name="text" > - <string>Alpha: freq</string> + <string>Freq. Loop Gain</string> </property> </widget> </item> <item row="0" column="1" > - <widget class="QLineEdit" name="alphaTimeEdit" > + <widget class="QLineEdit" name="gainClockEdit" > <property name="minimumSize" > <size> <width>60</width> @@ -526,7 +523,7 @@ </widget> </item> <item row="2" column="1" > - <widget class="QLineEdit" name="alphaFreqEdit" > + <widget class="QLineEdit" name="gainFreqEdit" > <property name="minimumSize" > <size> <width>60</width> @@ -542,7 +539,7 @@ </widget> </item> <item row="1" column="1" > - <widget class="QLineEdit" name="betaTimeEdit" > + <widget class="QLineEdit" name="gainPhaseEdit" > <property name="maximumSize" > <size> <width>80</width> @@ -552,9 +549,9 @@ </widget> </item> <item row="1" column="0" > - <widget class="QLabel" name="betaTimeLabel" > + <widget class="QLabel" name="gainPhaseLabel_2" > <property name="text" > - <string>Beta: time</string> + <string>Phase Loop Gain</string> </property> </widget> </item> diff --git a/gnuradio-examples/python/digital/qt_rx_window2.py b/gnuradio-examples/python/digital/qt_rx_window2.py new file mode 100644 index 000000000..14c961ab2 --- /dev/null +++ b/gnuradio-examples/python/digital/qt_rx_window2.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'qt_rx_window2.ui' +# +# Created: Sat Jan 2 12:54:51 2010 +# 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_DigitalWindow(object): + def setupUi(self, DigitalWindow): + DigitalWindow.setObjectName("DigitalWindow") + DigitalWindow.resize(1000, 816) + self.centralwidget = QtGui.QWidget(DigitalWindow) + self.centralwidget.setObjectName("centralwidget") + self.gridLayout = QtGui.QGridLayout(self.centralwidget) + self.gridLayout.setObjectName("gridLayout") + 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.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1) + self.sinkFrame = QtGui.QFrame(self.centralwidget) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(1) + sizePolicy.setHeightForWidth(self.sinkFrame.sizePolicy().hasHeightForWidth()) + self.sinkFrame.setSizePolicy(sizePolicy) + self.sinkFrame.setMinimumSize(QtCore.QSize(800, 500)) + self.sinkFrame.setFrameShape(QtGui.QFrame.StyledPanel) + self.sinkFrame.setFrameShadow(QtGui.QFrame.Raised) + self.sinkFrame.setObjectName("sinkFrame") + self.horizontalLayout_2 = QtGui.QHBoxLayout(self.sinkFrame) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.sinkLayout = QtGui.QHBoxLayout() + self.sinkLayout.setObjectName("sinkLayout") + self.horizontalLayout_2.addLayout(self.sinkLayout) + self.gridLayout.addWidget(self.sinkFrame, 0, 0, 1, 1) + DigitalWindow.setCentralWidget(self.centralwidget) + self.menubar = QtGui.QMenuBar(DigitalWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 24)) + 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 new file mode 100644 index 000000000..5a83471b8 --- /dev/null +++ b/gnuradio-examples/python/digital/qt_rx_window2.ui @@ -0,0 +1,379 @@ +<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>816</height> + </rect> + </property> + <property name="windowTitle" > + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget" > + <layout class="QGridLayout" name="gridLayout" > + <item row="1" column="0" > + <layout class="QHBoxLayout" name="horizontalLayout" > + <property name="sizeConstraint" > + <enum>QLayout::SetFixedSize</enum> + </property> + <item> + <widget class="QGroupBox" name="rxBox" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="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 vsizetype="Fixed" hsizetype="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 vsizetype="Fixed" hsizetype="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> + <item row="0" column="0" > + <widget class="QFrame" name="sinkFrame" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="minimumSize" > + <size> + <width>800</width> + <height>500</height> + </size> + </property> + <property name="frameShape" > + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow" > + <enum>QFrame::Raised</enum> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2" > + <item> + <layout class="QHBoxLayout" name="sinkLayout" /> + </item> + </layout> + </widget> + </item> + </layout> + <zorder>sinkFrame</zorder> + <zorder>verticalSpacer</zorder> + </widget> + <widget class="QMenuBar" name="menubar" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>1000</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> + <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/usrp_receive_path.py b/gnuradio-examples/python/digital/usrp_receive_path.py index e28eb0a8c..517825cc1 100644 --- a/gnuradio-examples/python/digital/usrp_receive_path.py +++ b/gnuradio-examples/python/digital/usrp_receive_path.py @@ -63,15 +63,22 @@ class usrp_receive_path(gr.hier_block2): 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)) + #setup usrp self._demod_class = demod_class self._setup_usrp_source(options) + + # Set up resampler based on rate determined by _setup_usrp_source + rs_taps = gr.firdes.low_pass_2(32, 32, 0.45, 0.1, 60) + self.resampler = gr.pfb_arb_resampler_ccf(self.rs_rate, rs_taps) + #connect - self.connect(self.u, rx_path) + self.connect(self.u, self.resampler, 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 if options.verbose: print 'USRP Source:', self.u (self._bitrate, self._samples_per_symbol, self._decim) = \ @@ -79,6 +86,11 @@ class usrp_receive_path(gr.hier_block2): options.samples_per_symbol, options.decim, adc_rate, \ self.u.get_decim_rates()) + # Calculate resampler rate based on requested and actual rates + self.rs_rate = 1.0 /(self._bitrate / self.rs_rate) + + print "Resampling by %f to get bitrate of %ssps" % ( self.rs_rate, eng_notation.num_to_str(self._bitrate/self.rs_rate)) + self.u.set_decim(self._decim) if not self.u.set_center_freq(options.rx_freq): diff --git a/gnuradio-examples/python/digital/usrp_transmit_path.py b/gnuradio-examples/python/digital/usrp_transmit_path.py index ad9f741a6..ee63dcd2b 100644 --- a/gnuradio-examples/python/digital/usrp_transmit_path.py +++ b/gnuradio-examples/python/digital/usrp_transmit_path.py @@ -62,12 +62,18 @@ class usrp_transmit_path(gr.hier_block2): 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)) + #setup usrp self._modulator_class = modulator_class self._setup_usrp_sink(options) - #connect - self.connect(tx_path, self.u) + # Set up resampler based on rate determined by _setup_usrp_sink + rs_taps = gr.firdes.low_pass_2(32, 32, 0.45, 0.1, 60) + self.resampler = gr.pfb_arb_resampler_ccf(self.rs_rate, rs_taps) + + #connect + self.connect(tx_path, self.resampler, self.u) + def _setup_usrp_sink(self, options): """ Creates a USRP sink, determines the settings for best bitrate, @@ -75,6 +81,7 @@ class usrp_transmit_path(gr.hier_block2): """ self.u = usrp_options.create_usrp_sink(options) dac_rate = self.u.dac_rate() + self.rs_rate = options.bitrate # Store requested bit rate if options.verbose: print 'USRP Sink:', self.u (self._bitrate, self._samples_per_symbol, self._interp) = \ @@ -82,6 +89,10 @@ class usrp_transmit_path(gr.hier_block2): options.samples_per_symbol, options.interp, dac_rate, \ self.u.get_interp_rates()) + # Calculate resampler rate based on requested and actual rates + self.rs_rate = self._bitrate / self.rs_rate + print "Resampling by %f to get bitrate of %ssps" % (self.rs_rate, eng_notation.num_to_str(self._bitrate/self.rs_rate)) + self.u.set_interp(self._interp) self.u.set_auto_tr(True) diff --git a/grc/blocks/gr_fll_band_edge_cc.xml b/grc/blocks/gr_fll_band_edge_cc.xml index 41c760cbb..5a13ac49b 100644 --- a/grc/blocks/gr_fll_band_edge_cc.xml +++ b/grc/blocks/gr_fll_band_edge_cc.xml @@ -58,4 +58,19 @@ <name>out</name> <type>$type.output</type> </source> + <source> + <name>freq</name> + <type>float</type> + <optional>1</optional> + </source> + <source> + <name>phase</name> + <type>float</type> + <optional>1</optional> + </source> + <source> + <name>error</name> + <type>float</type> + <optional>1</optional> + </source> </block> |