Merge branch 'master' of git@gnuradio.org:gnuradio
authorTom <trondeau@vt.edu>
Tue, 2 Feb 2010 00:45:39 +0000 (19:45 -0500)
committerTom <trondeau@vt.edu>
Tue, 2 Feb 2010 00:45:39 +0000 (19:45 -0500)
20 files changed:
gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc
gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h
gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc
gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h
gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i
gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
gnuradio-examples/grc/Makefile.am
gnuradio-examples/grc/demod/digital_freq_lock.grc
gnuradio-examples/grc/demod/pam_sync.grc
gnuradio-examples/grc/demod/pam_timing.grc
gnuradio-examples/python/digital/benchmark_qt_loopback2.py
gnuradio-examples/python/digital/benchmark_qt_rx2.py [new file with mode: 0755]
gnuradio-examples/python/digital/qt_digital_window2.py
gnuradio-examples/python/digital/qt_digital_window2.ui
gnuradio-examples/python/digital/qt_rx_window2.py [new file with mode: 0644]
gnuradio-examples/python/digital/qt_rx_window2.ui [new file with mode: 0644]
gnuradio-examples/python/digital/usrp_receive_path.py
gnuradio-examples/python/digital/usrp_transmit_path.py
grc/blocks/gr_fll_band_edge_cc.xml

index d4b14c5945d1470561176be5cc700f4a6b105600..48eb849ab1f32ca54bdd47c003ce8674edbc8e28 100644 (file)
@@ -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
index 531e9726f347c64f78991749e0393ee9bdd5e7d2..b99ad286b888588991af8109cc1dbd17dc5ca192 100644 (file)
@@ -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;
index 0f3d85c83f5e2936ed5b097ec1c57cc3194c43a3..030e45ddfb803f1b724540774ab9247792a0a923 100644 (file)
@@ -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;
 }
index 86e69df16305f76f031c668e8db0b4446e5a0d9f..09baf7fde88b65dd0de45d6689988d1877a3983f 100644 (file)
@@ -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
index 545bad4f61c28b6b92257786867aabbfd937fa3c..c9c792c8a6f802d7ff5abf1cef32d0c05816164d 100644 (file)
@@ -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();
 };
index cd9a207c876cd51d1caa01b1d54d42247cccd6c0..e9fb3df89874266518b2a7025fbc020a20362a39 100644 (file)
@@ -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,
index fd1e9f0efcfb38aab9529513403cd3e55118c4c7..9fae6accac07c14cf5aff158d8b6f2dde0bbbd22 100644 (file)
@@ -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,
index f8a26bacea60519eb4dc9372b09595f5e45f2882..118ecd593133f0ae152d3c4e82a6ae08e4f84225 100644 (file)
@@ -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 = \
index a7324a070a3de16ed0d0decdf810c4550f48846a..37ee8123eb084e212510c5768769e79584ba61a3 100644 (file)
@@ -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>
       <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>(346, 491)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
   <block>
     <key>variable</key>
     <param>
       <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>
index fc1186894027892b4db07eed7befd01b58e3fb2a..80a7aef0c668c1a67ea67cc7dd1d67c9b48c5222 100644 (file)
@@ -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>
       <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>(590, 184)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
   <block>
     <key>variable</key>
     <param>
       <value>180</value>
     </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>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>
       <value>0</value>
     </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>
       <value>180</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>(655, 527)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
   <block>
     <key>gr_costas_loop_cc</key>
     <param>
       <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>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>
       <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_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>
     </param>
   </block>
   <block>
-    <key>gr_channel_model</key>
+    <key>virtual_sink</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>
-      <value>virtual_sink_0</value>
+      <value>virtual_sink_0</value>
     </param>
     <param>
       <key>_enabled</key>
     </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>
     <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_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>
     <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>
     <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>
index 149e4c706843154ab35ce55fc78af2464c2f383e..02130f4815f9886fbdec89d67e2f8ed5b0385fc2 100644 (file)
@@ -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>
       <value>0</value>
     </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>
       <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>(59, 543)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
   <block>
     <key>notebook</key>
     <param>
       <value>0</value>
     </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>
       <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>(590, 184)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
   <block>
     <key>variable</key>
     <param>
       <value>180</value>
     </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>
     </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>
     </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>_coordinate</key>
-      <value>(617, 374)</value>
+      <key>v_scale</key>
+      <value>0</value>
     </param>
     <param>
-      <key>_rotation</key>
+      <key>v_offset</key>
       <value>0</value>
     </param>
-  </block>
-  <block>
-    <key>gr_multiply_const_vxx</key>
     <param>
-      <key>id</key>
-      <value>gr_multiply_const_vxx_0</value>
+      <key>t_scale</key>
+      <value>0</value>
     </param>
     <param>
-      <key>_enabled</key>
-      <value>True</value>
+      <key>ac_couple</key>
+      <value>False</value>
     </param>
     <param>
-      <key>type</key>
-      <value>complex</value>
+      <key>xy_mode</key>
+      <value>False</value>
     </param>
     <param>
-      <key>const</key>
-      <value>sig_amp</value>
+      <key>num_inputs</key>
+      <value>1</value>
     </param>
     <param>
-      <key>vlen</key>
-      <value>1</value>
+      <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>(1096, 197)</value>
+      <value>(1116, 500)</value>
     </param>
     <param>
       <key>_rotation</key>
     </param>
   </block>
   <block>
-    <key>variable</key>
+    <key>gr_throttle</key>
     <param>
       <key>id</key>
-      <value>pam_amp</value>
+      <value>gr_throttle_0</value>
     </param>
     <param>
       <key>_enabled</key>
       <value>True</value>
     </param>
     <param>
-      <key>value</key>
-      <value>2</value>
-    </param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
     <param>
       <key>_coordinate</key>
-      <value>(223, 9)</value>
+      <value>(290, 575)</value>
     </param>
     <param>
       <key>_rotation</key>
     </param>
   </block>
   <block>
-    <key>variable</key>
+    <key>wxgui_scopesink2</key>
     <param>
       <key>id</key>
-      <value>spb</value>
+      <value>wxgui_scopesink2_0_0</value>
     </param>
     <param>
       <key>_enabled</key>
       <value>True</value>
     </param>
     <param>
-      <key>value</key>
-      <value>4.1</value>
+      <key>type</key>
+      <value>float</value>
     </param>
     <param>
-      <key>_coordinate</key>
-      <value>(32, 842)</value>
+      <key>title</key>
+      <value>Error</value>
     </param>
     <param>
-      <key>_rotation</key>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>3</value>
+    </param>
+    <param>
+      <key>v_offset</key>
       <value>0</value>
     </param>
-  </block>
-  <block>
-    <key>variable</key>
     <param>
-      <key>id</key>
-      <value>sig_amp</value>
+      <key>t_scale</key>
+      <value>0</value>
     </param>
     <param>
-      <key>_enabled</key>
-      <value>True</value>
+      <key>ac_couple</key>
+      <value>False</value>
     </param>
     <param>
-      <key>value</key>
+      <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,0</value>
+    </param>
     <param>
       <key>_coordinate</key>
-      <value>(315, 9)</value>
+      <value>(1110, 651)</value>
     </param>
     <param>
       <key>_rotation</key>
     <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>
     </param>
     <param>
       <key>type</key>
-      <value>complex</value>
+      <value>float</value>
     </param>
     <param>
       <key>title</key>
     </param>
     <param>
       <key>v_scale</key>
-      <value>0</value>
+      <value>9</value>
     </param>
     <param>
       <key>v_offset</key>
     </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>
     </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>
     </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>
     <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>
     </param>
     <param>
       <key>title</key>
-      <value>Error</value>
+      <value>Scope Plot</value>
     </param>
     <param>
       <key>samp_rate</key>
     </param>
     <param>
       <key>v_scale</key>
-      <value>3</value>
+      <value>1.25</value>
     </param>
     <param>
       <key>v_offset</key>
     </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>
     <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>
     </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>
     </param>
     <param>
       <key>v_scale</key>
-      <value>1.25</value>
+      <value>.5</value>
     </param>
     <param>
       <key>v_offset</key>
     </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>
     </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>
     </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>id</key>
+      <value>spb</value>
     </param>
     <param>
-      <key>notebook</key>
-      <value>notebook_0,1</value>
+      <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>
     <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_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>
     <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>
index 101dd68d680e23f1a0efd2822ec9d7671419bfe2..1cb95198e67d527c5cee6709dc2d35ab2b83e4c9 100755 (executable)
@@ -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 (executable)
index 0000000..cabbecb
--- /dev/null
@@ -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
index f111e3772121eb774249b1bd2ad424b71083d9a0..98745dfe8d0be899af9099ec5fb164afb0e2e80b 100644 (file)
@@ -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))
 
index dc20ed798b5407a1c51fd0d4caf1053d006dabc5..4e87ff05838bd010c4bc9630f23528b30e537f3d 100644 (file)
   </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>
         </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" >
        <zorder>pktsRcvdEdit</zorder>
        <zorder>pktsCorrectEdit</zorder>
        <zorder>perEdit</zorder>
-       <zorder>rxBox</zorder>
       </widget>
      </widget>
     </item>
       </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>
         </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" >
         <rect>
          <x>10</x>
          <y>10</y>
-         <width>161</width>
+         <width>164</width>
          <height>101</height>
         </rect>
        </property>
          <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>
          </widget>
         </item>
         <item row="2" column="1" >
-         <widget class="QLineEdit" name="alphaFreqEdit" >
+         <widget class="QLineEdit" name="gainFreqEdit" >
           <property name="minimumSize" >
            <size>
             <width>60</width>
          </widget>
         </item>
         <item row="1" column="1" >
-         <widget class="QLineEdit" name="betaTimeEdit" >
+         <widget class="QLineEdit" name="gainPhaseEdit" >
           <property name="maximumSize" >
            <size>
             <width>80</width>
          </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 (file)
index 0000000..14c961a
--- /dev/null
@@ -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 (file)
index 0000000..5a83471
--- /dev/null
@@ -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>&amp;File</string>
+    </property>
+    <addaction name="actionExit" />
+   </widget>
+   <addaction name="menuFile" />
+  </widget>
+  <widget class="QStatusBar" name="statusbar" />
+  <action name="actionExit" >
+   <property name="text" >
+    <string>E&amp;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>
index e28eb0a8cedcbdcfca84a3f69fbacfdb36e80a87..517825cc1b53881bed8a1b78f700185f05fcb161 100644 (file)
@@ -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):
index ad9f741a6309dec1b82106513525ebcb2a324c2f..ee63dcd2b7e2d35a07194ef94fe81840c8269179 100644 (file)
@@ -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)
 
index 41c760cbb2c31fad9a25bcdfa9182a099283a17a..5a13ac49bed9fc7d5e2eefad32c518df63d50bda 100644 (file)
                <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>