commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r4194 - in gnuradio/branches/developers/trondeau/digit


From: trondeau
Subject: [Commit-gnuradio] r4194 - in gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src: lib/general python/gnuradio/blksimpl
Date: Tue, 26 Dec 2006 11:27:52 -0700 (MST)

Author: trondeau
Date: 2006-12-26 11:27:52 -0700 (Tue, 26 Dec 2006)
New Revision: 4194

Added:
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam.py
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py
Modified:
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py
   
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
Log:
merged from digital-wip to digital-wip2 changeset r4010:4193

Modified: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
 2006-12-26 18:16:22 UTC (rev 4193)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
 2006-12-26 18:27:52 UTC (rev 4194)
@@ -133,47 +133,90 @@
   float mm_val=0;
   gr_complex u, x, y;
 
-  while(oo < noutput_items && ii < ni) {
-    d_p_2T = d_p_1T;
-    d_p_1T = d_p_0T;
-    d_p_0T = d_interp->interpolate (&in[ii], d_mu);
+  // This loop writes the error to the second output, if it exists
+  if (write_foptr) {
+    while(oo < noutput_items && ii < ni) {
+      d_p_2T = d_p_1T;
+      d_p_1T = d_p_0T;
+      d_p_0T = d_interp->interpolate (&in[ii], d_mu);
 
-    d_c_2T = d_c_1T;
-    d_c_1T = d_c_0T;
-    d_c_0T = slicer_0deg(d_p_0T);
-
-    x = (d_c_0T - d_c_2T) * conj(d_p_1T);
-    y = (d_p_0T - d_p_2T) * conj(d_c_1T);
-    u = y - x;
-    mm_val = u.real();
-    out[oo++] = d_p_0T;
-
-    // limit mm_val
-    if (mm_val > 1.0)
-      mm_val = 1.0;
-    else if (mm_val < -1.0)
-      mm_val = -1.0;
-
-    d_omega = d_omega + d_gain_omega * mm_val;
-    if (d_omega > d_max_omega)
-      d_omega = d_max_omega;
-    else if (d_omega < d_min_omega)
-      d_omega = d_min_omega;
-
-    d_mu = d_mu + d_omega + d_gain_mu * mm_val;
-    ii += (int)floor(d_mu);
-    d_mu -= floor(d_mu);
-
-    if(d_verbose) {
+      d_c_2T = d_c_1T;
+      d_c_1T = d_c_0T;
+      d_c_0T = slicer_0deg(d_p_0T);
+      
+      x = (d_c_0T - d_c_2T) * conj(d_p_1T);
+      y = (d_p_0T - d_p_2T) * conj(d_c_1T);
+      u = y - x;
+      mm_val = u.real();
+      out[oo++] = d_p_0T;
+      
+      // limit mm_val
+      if (mm_val > 1.0)
+       mm_val = 1.0;
+      else if (mm_val < -1.0)
+       mm_val = -1.0;
+      
+      d_omega = d_omega + d_gain_omega * mm_val;
+      if (d_omega > d_max_omega)
+       d_omega = d_max_omega;
+      else if (d_omega < d_min_omega)
+       d_omega = d_min_omega;
+      
+      d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+      ii += (int)floor(d_mu);
+      d_mu -= floor(d_mu);
+      
+      #if 0
       printf("%f\t%f\n", d_omega, d_mu);
+      #endif
+      
+      // write the error signal to the second output
+      foptr[oo-1] = gr_complex(d_mu,0);
+      
+      if (ii < 0)      // clamp it.  This should only happen with bogus input
+       ii = 0;
     }
+  }
+  // This loop does not write to the second output (ugly, but faster)
+  else {
+    while(oo < noutput_items && ii < ni) {
+      d_p_2T = d_p_1T;
+      d_p_1T = d_p_0T;
+      d_p_0T = d_interp->interpolate (&in[ii], d_mu);
 
-    // write the error signal to the second output
-    if (write_foptr)
-      foptr[oo-1] = gr_complex(d_mu,0);
-
-    if (ii < 0)        // clamp it.  This should only happen with bogus input
-      ii = 0;
+      d_c_2T = d_c_1T;
+      d_c_1T = d_c_0T;
+      d_c_0T = slicer_0deg(d_p_0T);
+      
+      x = (d_c_0T - d_c_2T) * conj(d_p_1T);
+      y = (d_p_0T - d_p_2T) * conj(d_c_1T);
+      u = y - x;
+      mm_val = u.real();
+      out[oo++] = d_p_0T;
+      
+      // limit mm_val
+      if (mm_val > 1.0)
+       mm_val = 1.0;
+      else if (mm_val < -1.0)
+       mm_val = -1.0;
+      
+      d_omega = d_omega + d_gain_omega * mm_val;
+      if (d_omega > d_max_omega)
+       d_omega = d_max_omega;
+      else if (d_omega < d_min_omega)
+       d_omega = d_min_omega;
+      
+      d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+      ii += (int)floor(d_mu);
+      d_mu -= floor(d_mu);
+      
+      if(d_verbose) {
+       printf("%f\t%f\n", d_omega, d_mu);
+      }
+            
+      if (ii < 0)      // clamp it.  This should only happen with bogus input
+       ii = 0;
+    }
   }
 
   if (ii > 0){

Modified: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
  2006-12-26 18:16:22 UTC (rev 4193)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
  2006-12-26 18:27:52 UTC (rev 4194)
@@ -41,10 +41,11 @@
  * \ingroup block
  *
  * This implements the Mueller and Müller (M&M) discrete-time error-tracking 
synchronizer.
- *
- * See "Digital Communication Receivers: Synchronization, Channel
- * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & 
Stefan Fechtel.
- * ISBN 0-471-50275-8.
+ * The complex version here is based on:
+ * Modified Mueller and Muller clock recovery circuit
+ * Based:
+ *    G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller and 
Muller 
+ *    algorithm,"  Electronics Letters, Vol. 31, no. 13,  22 June 1995, pp. 
1032 - 1033.
  */
 class gr_clock_recovery_mm_cc : public gr_block
 {

Modified: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
   2006-12-26 18:16:22 UTC (rev 4193)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
   2006-12-26 18:27:52 UTC (rev 4194)
@@ -31,6 +31,7 @@
        am_demod.py             \
        dbpsk.py                \
        dqpsk.py                \
+       d8psk.py                \
        filterbank.py           \
        fm_demod.py             \
        fm_emph.py              \
@@ -39,6 +40,11 @@
        nbfm_tx.py              \
        pkt.py                  \
        psk.py                  \
+       qam.py                  \
+       qam8.py                 \
+       qam16.py                \
+       qam64.py                \
+       qam256.py               \
        rational_resampler.py   \
        standard_squelch.py     \
        wfm_rcv.py              \

Copied: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py
 (from rev 4193, 
gnuradio/branches/developers/trondeau/digital-wip/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py)
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py
                              (rev 0)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py
      2006-12-26 18:27:52 UTC (rev 4194)
@@ -0,0 +1,377 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+# See gnuradio-examples/python/digital for examples
+
+"""
+differential 8PSK modulation and demodulation.
+"""
+
+from gnuradio import gr, gru, modulation_utils
+from math import pi, sqrt
+import psk
+import cmath
+import Numeric
+from pprint import pprint
+
+# default values (used in __init__ and add_options)
+_def_samples_per_symbol = 3
+_def_excess_bw = 0.35
+_def_gray_code = True
+_def_verbose = False
+_def_log = False
+
+_def_costas_alpha = None
+_def_gain_mu = 7.5e-3
+_def_mu = 0.00
+_def_omega_relative_limit = 0.001
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           DQPSK modulator
+# /////////////////////////////////////////////////////////////////////////////
+
+class d8psk_mod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+        """
+       Hierarchical block for RRC-filtered QPSK modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param gray_code: Tell modulator to Gray code the bits
+        @type gray_code: bool
+        @param verbose: Print information about modulator?
+        @type verbose: bool
+        @param debug: Print modualtion data to files?
+        @type debug: bool
+       """
+
+        self._fg = fg
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._gray_code = gray_code
+
+        if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2:
+            raise TypeError, ("sbp must be an integer >= 2, is %d" % 
samples_per_symbol)
+
+       ntaps = 11 * samples_per_symbol
+ 
+        arity = pow(2,self.bits_per_symbol())
+
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity])
+            
+        self.diffenc = gr.diff_encoder_bb(arity)
+
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, psk.constellation[arity])
+        self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const)
+
+        # pulse shaping filter
+       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)
+            ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, 
self.rrc_taps)
+
+        if verbose:
+            self._print_verbage()
+        
+        if log:
+            self._setup_logging()
+            
+       # Connect & Initialize base class
+        self._fg.connect(self.bytes2chunks, self.symbol_mapper, #self.diffenc,
+                         self.chunks2symbols, self.rrc_filter)
+       gr.hier_block.__init__(self, self._fg, self.bytes2chunks, 
self.rrc_filter)
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 3
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+    def _print_verbage(self):
+        print "bits per symbol = %d" % self.bits_per_symbol()
+        print "Gray code = %s" % self._gray_code
+        print "RS roll-off factor = %f" % self._excess_bw
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self._fg.connect(self.bytes2chunks,
+                         gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat"))
+        self._fg.connect(self.symbol_mapper,
+                         gr.file_sink(gr.sizeof_char, "tx_graycoder.dat"))
+#        self._fg.connect(self.diffenc,
+#                         gr.file_sink(gr.sizeof_char, "tx_diffenc.dat"))      
  
+        self._fg.connect(self.chunks2symbols,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"tx_chunks2symbols.dat"))
+        self._fg.connect(self.rrc_filter,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"tx_rrc_filter.dat"))
+
+    def add_options(parser):
+        """
+        Adds 8PSK modulation-specific options to the standard parser
+        """
+        parser.add_option("", "--excess-bw", type="float", 
default=_def_excess_bw,
+                          help="set RRC excess bandwith factor 
[default=%default] (PSK)")
+        parser.add_option("", "--no-gray-code", dest="gray_code",
+                          action="store_false", default=_def_gray_code,
+                          help="disable gray coding on modulated bits (PSK)")
+    add_options=staticmethod(add_options)
+
+
+    def extract_kwargs_from_options(options):
+        """
+        Given command line options, create dictionary suitable for passing to 
__init__
+        """
+        return modulation_utils.extract_kwargs_from_options(d8psk_mod.__init__,
+                                                            ('self', 'fg'), 
options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           D8PSK demodulator
+#
+# Differentially coherent detection of differentially encoded 8psk
+# /////////////////////////////////////////////////////////////////////////////
+
+class d8psk_demod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 costas_alpha=_def_costas_alpha,
+                 gain_mu=_def_gain_mu,
+                 mu=_def_mu,
+                 omega_relative_limit=_def_omega_relative_limit,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+        """
+       Hierarchical block for RRC-filtered DQPSK demodulation
+
+       The input is the complex modulated signal at baseband.
+       The output is a stream of bits packed 1 bit per byte (LSB)
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param costas_alpha: loop filter gain
+        @type costas_alphas: float
+        @param gain_mu: for M&M block
+        @type gain_mu: float
+        @param mu: for M&M block
+        @type mu: float
+        @param omega_relative_limit: for M&M block
+        @type omega_relative_limit: float
+        @param gray_code: Tell modulator to Gray code the bits
+        @type gray_code: bool
+        @param verbose: Print information about modulator?
+        @type verbose: bool
+        @param debug: Print modualtion data to files?
+        @type debug: bool
+       """
+
+        self._fg = fg
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._costas_alpha = costas_alpha
+        self._gain_mu = gain_mu
+        self._mu = mu
+        self._omega_relative_limit = omega_relative_limit
+        self._gray_code = gray_code
+
+        if samples_per_symbol < 2:
+            raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol
+
+        arity = pow(2,self.bits_per_symbol())
+ 
+        # Automatic gain control
+        scale = (1.0/16384.0)
+        self.pre_scaler = gr.multiply_const_cc(scale)   # scale the signal 
from full-range to +-1
+        #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
+        self.agc = gr.feedforward_agc_cc(16, 1.0)
+
+        if 0:
+            # Costas loop (carrier tracking)
+            if self._costas_alpha is None:   # If no alpha value was specified 
by the user
+                alpha_dir = {2:0.075, 3:0.09, 4:0.09, 5:0.095, 6:0.10, 7:0.105}
+                self._costas_alpha = alpha_dir[self._samples_per_symbol]
+        
+            costas_order = 4        
+            # The value of beta is now set to be underdamped; this value can 
have a huge impact on the
+            # performance of QPSK. Set to 0.25 for critically damped or higher 
for underdamped responses.
+            beta = .35 * self._costas_alpha * self._costas_alpha
+            self.costas_loop = gr.costas_loop_cc(self._costas_alpha, beta, 
0.02, -0.02, costas_order)
+        
+        # RRC data filter
+        ntaps = 11 * samples_per_symbol
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            self._samples_per_symbol, # gain
+            self._samples_per_symbol, # sampling rate
+            1.0,                      # symbol rate
+            self._excess_bw,          # excess bandwidth (roll-off factor)
+            ntaps)
+
+        self.rrc_filter=gr.fir_filter_ccf(1, self.rrc_taps)
+
+        # symbol clock recovery
+        omega = self._samples_per_symbol
+        gain_omega = .25 * self._gain_mu * self._gain_mu
+        self.clock_recovery=gr.clock_recovery_mm_cc(omega, gain_omega,
+                                                    self._mu, self._gain_mu,
+                                                    self._omega_relative_limit)
+
+        self.diffdec = gr.diff_decoder_bb(arity)
+
+        # find closest constellation point
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, psk.constellation[arity])
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity])
+
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol())
+
+        if verbose:
+            self._print_verbage()
+        
+        if log:
+            self._setup_logging()
+ 
+        # Connect & Initialize base class
+        if 0:
+            self._fg.connect(self.pre_scaler, self.agc, #self.costas_loop,
+                             self.rrc_filter, self.clock_recovery,
+                             self.diffdec, self.slicer, self.symbol_mapper,
+                             self.unpack)
+        else:
+            self._fg.connect(self.pre_scaler, self.agc, #self.costas_loop,
+                             self.rrc_filter, self.clock_recovery,
+                             self.slicer, self.symbol_mapper,
+                             self.unpack)
+        gr.hier_block.__init__(self, self._fg, self.pre_scaler, self.unpack)
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 3
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+    def _print_verbage(self):
+        print "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 "Costas Loop alpha = %.5f"     % self._costas_alpha
+        print "M&M symbol sync gain = %.5f"  % self._gain_mu
+        print "M&M symbol sync mu = %.5f"    % self._mu
+        print "M&M omega relative limit = %.5f" % self._omega_relative_limit
+        
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self._fg.connect(self.pre_scaler,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_prescaler.dat"))
+        self._fg.connect(self.agc,
+                         gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat"))
+#        self._fg.connect(self.costas_loop,
+#                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_costas_loop.dat"))
+#        self._fg.connect((self.costas_loop,1),
+#                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_costas_error.dat"))
+        self._fg.connect(self.rrc_filter,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_rrc_filter.dat"))
+        self._fg.connect(self.clock_recovery,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_clock_recovery.dat"))
+        self._fg.connect((self.clock_recovery,1),
+                        gr.file_sink(gr.sizeof_gr_complex, 
"rx_clock_recovery_error.dat"))
+        self._fg.connect(self.slicer,
+                         gr.file_sink(gr.sizeof_char, "rx_slicer.dat"))
+#        self._fg.connect(self.diffdec,
+#                         gr.file_sink(gr.sizeof_char, "rx_diffdec.dat"))      
  
+        self._fg.connect(self.symbol_mapper,
+                         gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat"))
+        self._fg.connect(self.unpack,
+                         gr.file_sink(gr.sizeof_char, "rx_unpack.dat"))
+
+    def add_options(parser):
+        """
+        Adds modulation-specific options to the standard parser
+        """
+        parser.add_option("", "--excess-bw", type="float", 
default=_def_excess_bw,
+                          help="set RRC excess bandwith factor 
[default=%default] (PSK)")
+        parser.add_option("", "--no-gray-code", dest="gray_code",
+                          action="store_false", default=_def_gray_code,
+                          help="disable gray coding on modulated bits (PSK)")
+        parser.add_option("", "--costas-alpha", type="float", default=None,
+                          help="set Costas loop alpha value [default=%default] 
(PSK)")
+        parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu,
+                          help="set M&M symbol sync loop gain mu value 
[default=%default] (PSK)")
+        parser.add_option("", "--mu", type="float", default=_def_mu,
+                          help="set M&M symbol sync loop mu value 
[default=%default] (PSK)")
+    add_options=staticmethod(add_options)
+
+    def extract_kwargs_from_options(options):
+        """
+        Given command line options, create dictionary suitable for passing to 
__init__
+        """
+        return modulation_utils.extract_kwargs_from_options(
+            d8psk_demod.__init__, ('self', 'fg'), options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+#
+# Add these to the mod/demod registry
+#
+modulation_utils.add_type_1_mod('d8psk', d8psk_mod)
+modulation_utils.add_type_1_demod('d8psk', d8psk_demod)

Modified: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py
      2006-12-26 18:16:22 UTC (rev 4193)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py
      2006-12-26 18:27:52 UTC (rev 4194)
@@ -88,7 +88,7 @@
        ntaps = 11 * self._samples_per_symbol
 
         arity = pow(2,self.bits_per_symbol())
-       
+        
         # turn bytes into k-bit vectors
         self.bytes2chunks = \
           gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
@@ -99,18 +99,18 @@
             self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity])
 
         self.diffenc = gr.diff_encoder_bb(arity)
-        
+
+        print psk.constellation[arity]
         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)
+           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)
             ntaps)
-
        self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol,
                                                    self.rrc_taps)
 
@@ -162,15 +162,15 @@
     def _setup_logging(self):
         print "Modulation logging turned on."
         self._fg.connect(self.bytes2chunks,
-                         gr.file_sink(gr.sizeof_char, "bytes2chunks.dat"))
+                         gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat"))
         self._fg.connect(self.symbol_mapper,
-                         gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+                         gr.file_sink(gr.sizeof_char, "tx_graycoder.dat"))
         self._fg.connect(self.diffenc,
-                         gr.file_sink(gr.sizeof_char, "diffenc.dat"))
+                         gr.file_sink(gr.sizeof_char, "tx_diffenc.dat"))
         self._fg.connect(self.chunks2symbols,
-                         gr.file_sink(gr.sizeof_gr_complex, 
"chunks2symbols.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"tx_chunks2symbols.dat"))
         self._fg.connect(self.rrc_filter,
-                         gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"tx_rrc_filter.dat"))
               
 
 # /////////////////////////////////////////////////////////////////////////////
@@ -299,7 +299,7 @@
             self._fg.connect(self.pre_scaler, self.agc,
                              self.rrc_filter, self.clock_recovery, 
self.diffdec,
                              self.slicer, self.symbol_mapper, self.unpack)
-
+        self._fg.connect(self.agc, gr.file_sink(gr.sizeof_gr_complex, 
"dbpsk_in.dat"))
         gr.hier_block.__init__(self, self._fg, self.pre_scaler, self.unpack)
 
     def samples_per_symbol(self):
@@ -373,7 +373,6 @@
         return modulation_utils.extract_kwargs_from_options(
                  dbpsk_demod.__init__, ('self', 'fg'), options)
     extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
-
 #
 # Add these to the mod/demod registry
 #

Modified: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py
      2006-12-26 18:16:22 UTC (rev 4193)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py
      2006-12-26 18:27:52 UTC (rev 4194)
@@ -40,8 +40,8 @@
 _def_log = False
 
 _def_costas_alpha = None
-_def_gain_mu = 0.03
-_def_mu = 0.05
+_def_gain_mu = 0.01
+_def_mu = 0.00
 _def_omega_relative_limit = 0.005
 
 
@@ -140,15 +140,15 @@
     def _setup_logging(self):
         print "Modulation logging turned on."
         self._fg.connect(self.bytes2chunks,
-                         gr.file_sink(gr.sizeof_char, "bytes2chunks.dat"))
+                         gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat"))
         self._fg.connect(self.symbol_mapper,
-                         gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+                         gr.file_sink(gr.sizeof_char, "tx_graycoder.dat"))
         self._fg.connect(self.diffenc,
-                         gr.file_sink(gr.sizeof_char, "diffenc.dat"))        
+                         gr.file_sink(gr.sizeof_char, "tx_diffenc.dat"))       
 
         self._fg.connect(self.chunks2symbols,
-                         gr.file_sink(gr.sizeof_gr_complex, 
"chunks2symbols.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"tx_chunks2symbols.dat"))
         self._fg.connect(self.rrc_filter,
-                         gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"tx_rrc_filter.dat"))
 
     def add_options(parser):
         """
@@ -234,7 +234,6 @@
         # Automatic gain control
         scale = (1.0/16384.0)
         self.pre_scaler = gr.multiply_const_cc(scale)   # scale the signal 
from full-range to +-1
-        #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
         self.agc = gr.feedforward_agc_cc(16, 1.0)
        
         # Costas loop (carrier tracking)
@@ -266,14 +265,12 @@
                                                     self._mu, self._gain_mu,
                                                     self._omega_relative_limit)
 
-        self.diffdec = gr.diff_phasor_cc()
-        #self.diffdec = gr.diff_decoder_bb(arity)
+        self.diffdec = gr.diff_decoder_bb(arity)
 
         # find closest constellation point
         rot = 1
-        #rot = .707 + .707j
+        rot = .707 + .707j
         rotated_const = map(lambda pt: pt * rot, psk.constellation[arity])
-        #print "rotated_const = %s" % rotated_const
 
         self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
 
@@ -281,7 +278,6 @@
             self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity])
         else:
             self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity])
-
         
         # unpack the k bit vector into a stream of bits
         self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol())
@@ -295,7 +291,7 @@
         # Connect & Initialize base class
         self._fg.connect(self.pre_scaler, self.agc, self.costas_loop,
                          self.rrc_filter, self.clock_recovery,
-                         self.diffdec, self.slicer, self.symbol_mapper,
+                         self.slicer, self.diffdec, self.symbol_mapper,
                          self.unpack)
         gr.hier_block.__init__(self, self._fg, self.pre_scaler, self.unpack)
 
@@ -319,27 +315,27 @@
     def _setup_logging(self):
         print "Modulation logging turned on."
         self._fg.connect(self.pre_scaler,
-                         gr.file_sink(gr.sizeof_gr_complex, "prescaler.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_prescaler.dat"))
         self._fg.connect(self.agc,
-                         gr.file_sink(gr.sizeof_gr_complex, "agc.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat"))
         self._fg.connect(self.costas_loop,
-                         gr.file_sink(gr.sizeof_gr_complex, "costas_loop.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_costas_loop.dat"))
         self._fg.connect((self.costas_loop,1),
-                         gr.file_sink(gr.sizeof_gr_complex, 
"costas_error.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_costas_error.dat"))
         self._fg.connect(self.rrc_filter,
-                         gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_rrc_filter.dat"))
         self._fg.connect(self.clock_recovery,
-                         gr.file_sink(gr.sizeof_gr_complex, 
"clock_recovery.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_clock_recovery.dat"))
         self._fg.connect((self.clock_recovery,1),
-                        gr.file_sink(gr.sizeof_gr_complex, 
"clock_recovery_error.dat"))
+                         gr.file_sink(gr.sizeof_gr_complex, 
"rx_clock_recovery_error.dat"))
         self._fg.connect(self.diffdec,
-                         gr.file_sink(gr.sizeof_gr_complex, "diffdec.dat"))    
    
+                         gr.file_sink(gr.sizeof_char, "rx_diffdec.dat"))       
 
         self._fg.connect(self.slicer,
-                         gr.file_sink(gr.sizeof_char, "slicer.dat"))
+                         gr.file_sink(gr.sizeof_char, "rx_slicer.dat"))
         self._fg.connect(self.symbol_mapper,
-                         gr.file_sink(gr.sizeof_char, "gray_decoder.dat"))
+                         gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat"))
         self._fg.connect(self.unpack,
-                         gr.file_sink(gr.sizeof_char, "unpack.dat"))
+                         gr.file_sink(gr.sizeof_char, "rx_unpack.dat"))
 
     def add_options(parser):
         """

Modified: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
        2006-12-26 18:16:22 UTC (rev 4193)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
        2006-12-26 18:27:52 UTC (rev 4194)
@@ -19,12 +19,30 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-from math import pi, sqrt
-import cmath
+from math import pi, sqrt, log10
+import math
 
+# The following algorithm generates Gray coded constellations for M-PSK for 
M=[2,4,8]
 def make_constellation(m):
-    return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)]
+    # number of bits/symbol (log2(M))
+    k = int(log10(m) / log10(2.0))
+
+    coeff = 1
+    const_map = []
+    bits = [0]*3
+    for i in range(m):
+        # get a vector of the k bits to use in this mapping
+        bits[3-k:3] = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(k)]
+
+        theta = 
-(2*bits[0]-1)*(2*pi/m)*(bits[0]+abs(bits[1]-bits[2])+2*bits[1])
+        re = math.cos(theta)
+        im = math.sin(theta)
+        const_map.append(complex(re, im))   # plug it into the constellation
         
+    # return the constellation; by default, it is normalized
+    return const_map
+
+        
 # Common definition of constellations for Tx and Rx
 constellation = {
     2 : make_constellation(2),           # BPSK
@@ -35,18 +53,18 @@
 # -----------------------
 # Do Gray code
 # -----------------------
-# binary to gray coding
+# binary to gray coding -- constellation does Gray coding
 binary_to_gray = {
-    2 : (0, 1),
-    4 : (0, 1, 3, 2),
-    8 : (0, 1, 3, 2, 7, 6, 4, 5)
+    2 : range(2),
+    4 : range(4),
+    8 : range(8)
     }
    
 # gray to binary
 gray_to_binary = {
-    2 : (0, 1),
-    4 : (0, 1, 3, 2),
-    8 : (0, 1, 3, 2, 6, 7, 5, 4)
+    2 : range(2),
+    4 : range(4),
+    8 : range(8)
     }
 
 # -----------------------
@@ -54,14 +72,14 @@
 # -----------------------
 # identity mapping
 binary_to_ungray = {
-    2 : (0, 1),
-    4 : (0, 1, 2, 3),
-    8 : (0, 1, 2, 3, 4, 5, 6, 7)
+    2 : range(2),
+    4 : range(4), #[0, 1, 3, 2],
+    8 : range(8)
     }
     
 # identity mapping
 ungray_to_binary = {
-    2 : (0, 1),
-    4 : (0, 1, 2, 3),
-    8 : (0, 1, 2, 3, 4, 5, 6, 7)
+    2 : range(2),
+    4 : range(4),
+    8 : range(8)
     }

Copied: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam.py
 (from rev 4193, 
gnuradio/branches/developers/trondeau/digital-wip/gnuradio-core/src/python/gnuradio/blksimpl/qam.py)
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam.py
                                (rev 0)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam.py
        2006-12-26 18:27:52 UTC (rev 4194)
@@ -0,0 +1,113 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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 math import pi, sqrt
+import math
+
+# These constellations are generated for Gray coding when symbos [1, ..., m] 
are used
+# Mapping to Gray coding is therefore unnecessary
+
+def make_constellation(m):
+    # number of bits/symbol (log2(M))
+    k = int(math.log10(m) / math.log10(2.0))
+
+    coeff = 1
+    const_map = []
+    for i in range(m):
+        a = (i&(0x01 << k-1)) >> k-1
+        b = (i&(0x01 << k-2)) >> k-2
+        bits_i = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(2, k, 2)]
+        bits_q = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(3, k, 2)]
+
+        ss = 0
+        ll = len(bits_i)
+        for ii in range(ll):
+            rr = 0
+            for jj in range(ll-ii):
+                rr = abs(bits_i[jj] - rr)
+            ss += rr*pow(2.0, ii+1)
+        re = (2*a-1)*(ss+1)
+        
+        ss = 0
+        ll = len(bits_q)
+        for ii in range(ll):
+            rr = 0
+            for jj in range(ll-ii):
+                rr = abs(bits_q[jj] - rr)
+            ss += rr*pow(2.0, ii+1)
+        im = (2*b-1)*(ss+1)
+
+        a = max(re, im)
+        if a > coeff:
+            coeff = a
+        const_map.append(complex(re, im))
+
+    norm_map = [complex(i.real/coeff, i.imag/coeff) for i in const_map]
+    return norm_map
+        
+# Common definition of constellations for Tx and Rx
+constellation = {
+    4 :  make_constellation(4),           # QAM4 (QPSK)
+    8 :  make_constellation(8),           # QAM8
+    16:  make_constellation(16),          # QAM16
+    64:  make_constellation(64),          # QAM64
+    256: make_constellation(256)          # QAM256
+    }
+
+# -----------------------
+# Do Gray code
+# -----------------------
+# binary to gray coding
+binary_to_gray = {
+    4 : range(4),
+    8 : range(8),
+    16: range(16),
+    64: range(64),
+    256: range(256)
+    }
+   
+# gray to binary
+gray_to_binary = {
+    4 : range(4),
+    8 : range(8),
+    16: range(16),
+    64: range(64),
+    256: range(256)
+    }
+
+# -----------------------
+# Don't Gray code
+# -----------------------
+# identity mapping
+binary_to_ungray = {
+    4 : range(4),
+    8 : range(8),
+    16: range(16),
+    64: range(64)
+    }
+    
+# identity mapping
+ungray_to_binary = {
+    4 : range(4),
+    8 : range(8),
+    16: range(16),
+    64: range(64)
+    }

Copied: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py
 (from rev 4193, 
gnuradio/branches/developers/trondeau/digital-wip/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py)
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py
                              (rev 0)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py
      2006-12-26 18:27:52 UTC (rev 4194)
@@ -0,0 +1,205 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+# See gnuradio-examples/python/digital for examples
+
+"""
+QAM16 modulation and demodulation.
+"""
+
+from gnuradio import gr, gru, modulation_utils
+from math import pi, sqrt
+import qam
+import cmath
+import Numeric
+from pprint import pprint
+
+# default values (used in __init__ and add_options)
+_def_samples_per_symbol = 2
+_def_excess_bw = 0.35
+_def_gray_code = True
+_def_verbose = False
+_def_log = False
+
+_def_costas_alpha = None
+_def_gain_mu = 0.03
+_def_mu = 0.05
+_def_omega_relative_limit = 0.005
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM16 modulator
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam16_mod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        """
+       Hierarchical block for RRC-filtered QPSK modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param gray_code: Tell modulator to Gray code the bits
+        @type gray_code: bool
+        @param verbose: Print information about modulator?
+        @type verbose: bool
+        @param debug: Print modualtion data to files?
+        @type debug: bool
+       """
+
+        self._fg = fg
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._gray_code = gray_code
+
+        if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2:
+            raise TypeError, ("sbp must be an integer >= 2, is %d" % 
samples_per_symbol)
+
+       ntaps = 11 * samples_per_symbol
+ 
+        arity = pow(2, self.bits_per_symbol())
+
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity])
+            
+        self.diffenc = gr.diff_encoder_bb(arity)
+
+        rot = 1.0
+        print "constellation with %d arity" % arity
+        rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+        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)
+            ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, 
self.rrc_taps)
+
+        if verbose:
+            self._print_verbage()
+        
+        if log:
+            self._setup_logging()
+            
+       # Connect & Initialize base class
+        self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc,
+                         self.chunks2symbols, self.rrc_filter)
+       gr.hier_block.__init__(self, self._fg, self.bytes2chunks, 
self.rrc_filter)
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 4
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+    def _print_verbage(self):
+        print "bits per symbol = %d" % self.bits_per_symbol()
+        print "Gray code = %s" % self._gray_code
+        print "RRS roll-off factor = %f" % self._excess_bw
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self._fg.connect(self.bytes2chunks,
+                         gr.file_sink(gr.sizeof_char, "bytes2chunks.dat"))
+        self._fg.connect(self.symbol_mapper,
+                         gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+        self._fg.connect(self.diffenc,
+                         gr.file_sink(gr.sizeof_char, "diffenc.dat"))        
+        self._fg.connect(self.chunks2symbols,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"chunks2symbols.dat"))
+        self._fg.connect(self.rrc_filter,
+                         gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat"))
+
+    def add_options(parser):
+        """
+        Adds QAM modulation-specific options to the standard parser
+        """
+        parser.add_option("", "--excess-bw", type="float", 
default=_def_excess_bw,
+                          help="set RRC excess bandwith factor 
[default=%default] (PSK)")
+        parser.add_option("", "--no-gray-code", dest="gray_code",
+                          action="store_false", default=_def_gray_code,
+                          help="disable gray coding on modulated bits (PSK)")
+    add_options=staticmethod(add_options)
+
+
+    def extract_kwargs_from_options(options):
+        """
+        Given command line options, create dictionary suitable for passing to 
__init__
+        """
+        return modulation_utils.extract_kwargs_from_options(qam16_mod.__init__,
+                                                            ('self', 'fg'), 
options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM16 demodulator
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam16_demod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 costas_alpha=_def_costas_alpha,
+                 gain_mu=_def_gain_mu,
+                 mu=_def_mu,
+                 omega_relative_limit=_def_omega_relative_limit,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        # do this
+        pass
+    
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 4
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+#
+# Add these to the mod/demod registry
+#
+modulation_utils.add_type_1_mod('qam16', qam16_mod)
+#modulation_utils.add_type_1_demod('qam16', qam16_demod)

Copied: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py
 (from rev 4193, 
gnuradio/branches/developers/trondeau/digital-wip/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py)
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py
                             (rev 0)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py
     2006-12-26 18:27:52 UTC (rev 4194)
@@ -0,0 +1,205 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+# See gnuradio-examples/python/digital for examples
+
+"""
+QAM256 modulation and demodulation.
+"""
+
+from gnuradio import gr, gru, modulation_utils
+from math import pi, sqrt
+import qam
+import cmath
+import Numeric
+from pprint import pprint
+
+# default values (used in __init__ and add_options)
+_def_samples_per_symbol = 2
+_def_excess_bw = 0.35
+_def_gray_code = True
+_def_verbose = False
+_def_log = False
+
+_def_costas_alpha = None
+_def_gain_mu = 0.03
+_def_mu = 0.05
+_def_omega_relative_limit = 0.005
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM256 modulator
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam256_mod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        """
+       Hierarchical block for RRC-filtered QPSK modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param gray_code: Tell modulator to Gray code the bits
+        @type gray_code: bool
+        @param verbose: Print information about modulator?
+        @type verbose: bool
+        @param debug: Print modualtion data to files?
+        @type debug: bool
+       """
+
+        self._fg = fg
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._gray_code = gray_code
+
+        if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2:
+            raise TypeError, ("sbp must be an integer >= 2, is %d" % 
samples_per_symbol)
+
+       ntaps = 11 * samples_per_symbol
+ 
+        arity = pow(2, self.bits_per_symbol())
+
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity])
+            
+        self.diffenc = gr.diff_encoder_bb(arity)
+
+        rot = 1.0
+        print "constellation with %d arity" % arity
+        rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+        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)
+            ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, 
self.rrc_taps)
+
+        if verbose:
+            self._print_verbage()
+        
+        if log:
+            self._setup_logging()
+            
+       # Connect & Initialize base class
+        self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc,
+                         self.chunks2symbols, self.rrc_filter)
+       gr.hier_block.__init__(self, self._fg, self.bytes2chunks, 
self.rrc_filter)
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 8
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+    def _print_verbage(self):
+        print "bits per symbol = %d" % self.bits_per_symbol()
+        print "Gray code = %s" % self._gray_code
+        print "RRS roll-off factor = %f" % self._excess_bw
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self._fg.connect(self.bytes2chunks,
+                         gr.file_sink(gr.sizeof_char, "bytes2chunks.dat"))
+        self._fg.connect(self.symbol_mapper,
+                         gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+        self._fg.connect(self.diffenc,
+                         gr.file_sink(gr.sizeof_char, "diffenc.dat"))        
+        self._fg.connect(self.chunks2symbols,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"chunks2symbols.dat"))
+        self._fg.connect(self.rrc_filter,
+                         gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat"))
+
+    def add_options(parser):
+        """
+        Adds QAM modulation-specific options to the standard parser
+        """
+        parser.add_option("", "--excess-bw", type="float", 
default=_def_excess_bw,
+                          help="set RRC excess bandwith factor 
[default=%default] (PSK)")
+        parser.add_option("", "--no-gray-code", dest="gray_code",
+                          action="store_false", default=_def_gray_code,
+                          help="disable gray coding on modulated bits (PSK)")
+    add_options=staticmethod(add_options)
+
+
+    def extract_kwargs_from_options(options):
+        """
+        Given command line options, create dictionary suitable for passing to 
__init__
+        """
+        return 
modulation_utils.extract_kwargs_from_options(qam256_mod.__init__,
+                                                            ('self', 'fg'), 
options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM256 demodulator
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam256_demod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 costas_alpha=_def_costas_alpha,
+                 gain_mu=_def_gain_mu,
+                 mu=_def_mu,
+                 omega_relative_limit=_def_omega_relative_limit,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        # do this
+        pass
+    
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 8
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+#
+# Add these to the mod/demod registry
+#
+modulation_utils.add_type_1_mod('qam256', qam256_mod)
+#modulation_utils.add_type_1_demod('qam256', qam256_demod)

Copied: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py
 (from rev 4193, 
gnuradio/branches/developers/trondeau/digital-wip/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py)
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py
                              (rev 0)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py
      2006-12-26 18:27:52 UTC (rev 4194)
@@ -0,0 +1,205 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+# See gnuradio-examples/python/digital for examples
+
+"""
+differential QPSK modulation and demodulation.
+"""
+
+from gnuradio import gr, gru, modulation_utils
+from math import pi, sqrt
+import qam
+import cmath
+import Numeric
+from pprint import pprint
+
+# default values (used in __init__ and add_options)
+_def_samples_per_symbol = 2
+_def_excess_bw = 0.35
+_def_gray_code = True
+_def_verbose = False
+_def_log = False
+
+_def_costas_alpha = None
+_def_gain_mu = 0.03
+_def_mu = 0.05
+_def_omega_relative_limit = 0.005
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM64 modulator
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam64_mod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        """
+       Hierarchical block for RRC-filtered QPSK modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param gray_code: Tell modulator to Gray code the bits
+        @type gray_code: bool
+        @param verbose: Print information about modulator?
+        @type verbose: bool
+        @param debug: Print modualtion data to files?
+        @type debug: bool
+       """
+
+        self._fg = fg
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._gray_code = gray_code
+
+        if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2:
+            raise TypeError, ("sbp must be an integer >= 2, is %d" % 
samples_per_symbol)
+
+       ntaps = 11 * samples_per_symbol
+ 
+        arity = pow(2, self.bits_per_symbol())
+
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity])
+            
+        self.diffenc = gr.diff_encoder_bb(arity)
+
+        rot = 1.0
+        print "constellation with %d arity" % arity
+        rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+        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)
+            ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, 
self.rrc_taps)
+
+        if verbose:
+            self._print_verbage()
+        
+        if log:
+            self._setup_logging()
+            
+       # Connect & Initialize base class
+        self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc,
+                         self.chunks2symbols, self.rrc_filter)
+       gr.hier_block.__init__(self, self._fg, self.bytes2chunks, 
self.rrc_filter)
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 6
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+    def _print_verbage(self):
+        print "bits per symbol = %d" % self.bits_per_symbol()
+        print "Gray code = %s" % self._gray_code
+        print "RRS roll-off factor = %f" % self._excess_bw
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self._fg.connect(self.bytes2chunks,
+                         gr.file_sink(gr.sizeof_char, "bytes2chunks.dat"))
+        self._fg.connect(self.symbol_mapper,
+                         gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+        self._fg.connect(self.diffenc,
+                         gr.file_sink(gr.sizeof_char, "diffenc.dat"))        
+        self._fg.connect(self.chunks2symbols,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"chunks2symbols.dat"))
+        self._fg.connect(self.rrc_filter,
+                         gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat"))
+
+    def add_options(parser):
+        """
+        Adds QAM modulation-specific options to the standard parser
+        """
+        parser.add_option("", "--excess-bw", type="float", 
default=_def_excess_bw,
+                          help="set RRC excess bandwith factor 
[default=%default] (PSK)")
+        parser.add_option("", "--no-gray-code", dest="gray_code",
+                          action="store_false", default=_def_gray_code,
+                          help="disable gray coding on modulated bits (PSK)")
+    add_options=staticmethod(add_options)
+
+
+    def extract_kwargs_from_options(options):
+        """
+        Given command line options, create dictionary suitable for passing to 
__init__
+        """
+        return modulation_utils.extract_kwargs_from_options(qam64_mod.__init__,
+                                                            ('self', 'fg'), 
options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM16 demodulator
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam64_demod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 costas_alpha=_def_costas_alpha,
+                 gain_mu=_def_gain_mu,
+                 mu=_def_mu,
+                 omega_relative_limit=_def_omega_relative_limit,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        # do this
+        pass
+    
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 6
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+#
+# Add these to the mod/demod registry
+#
+modulation_utils.add_type_1_mod('qam64', qam64_mod)
+#modulation_utils.add_type_1_demod('qam16', qam16_demod)

Copied: 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py
 (from rev 4193, 
gnuradio/branches/developers/trondeau/digital-wip/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py)
===================================================================
--- 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py
                               (rev 0)
+++ 
gnuradio/branches/developers/trondeau/digital-wip2/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py
       2006-12-26 18:27:52 UTC (rev 4194)
@@ -0,0 +1,205 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+# See gnuradio-examples/python/digital for examples
+
+"""
+QAM8 modulation and demodulation.
+"""
+
+from gnuradio import gr, gru, modulation_utils
+from math import pi, sqrt
+import qam
+import cmath
+import Numeric
+from pprint import pprint
+
+# default values (used in __init__ and add_options)
+_def_samples_per_symbol = 2
+_def_excess_bw = 0.35
+_def_gray_code = True
+_def_verbose = False
+_def_log = False
+
+_def_costas_alpha = None
+_def_gain_mu = 0.03
+_def_mu = 0.05
+_def_omega_relative_limit = 0.005
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM8 modulator
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam8_mod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        """
+       Hierarchical block for RRC-filtered QPSK modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param samples_per_symbol: samples per symbol >= 2
+       @type samples_per_symbol: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param gray_code: Tell modulator to Gray code the bits
+        @type gray_code: bool
+        @param verbose: Print information about modulator?
+        @type verbose: bool
+        @param debug: Print modualtion data to files?
+        @type debug: bool
+       """
+
+        self._fg = fg
+        self._samples_per_symbol = samples_per_symbol
+        self._excess_bw = excess_bw
+        self._gray_code = gray_code
+
+        if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2:
+            raise TypeError, ("sbp must be an integer >= 2, is %d" % 
samples_per_symbol)
+
+       ntaps = 11 * samples_per_symbol
+ 
+        arity = pow(2, self.bits_per_symbol())
+
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
+
+        if self._gray_code:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity])
+        else:
+            self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity])
+            
+        self.diffenc = gr.diff_encoder_bb(arity)
+
+        rot = 1.0
+        print "constellation with %d arity" % arity
+        rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+        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)
+            ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, 
self.rrc_taps)
+
+        if verbose:
+            self._print_verbage()
+        
+        if log:
+            self._setup_logging()
+            
+       # Connect & Initialize base class
+        self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc,
+                         self.chunks2symbols, self.rrc_filter)
+       gr.hier_block.__init__(self, self._fg, self.bytes2chunks, 
self.rrc_filter)
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 3
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+    def _print_verbage(self):
+        print "bits per symbol = %d" % self.bits_per_symbol()
+        print "Gray code = %s" % self._gray_code
+        print "RRS roll-off factor = %f" % self._excess_bw
+
+    def _setup_logging(self):
+        print "Modulation logging turned on."
+        self._fg.connect(self.bytes2chunks,
+                         gr.file_sink(gr.sizeof_char, "bytes2chunks.dat"))
+        self._fg.connect(self.symbol_mapper,
+                         gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+        self._fg.connect(self.diffenc,
+                         gr.file_sink(gr.sizeof_char, "diffenc.dat"))        
+        self._fg.connect(self.chunks2symbols,
+                         gr.file_sink(gr.sizeof_gr_complex, 
"chunks2symbols.dat"))
+        self._fg.connect(self.rrc_filter,
+                         gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat"))
+
+    def add_options(parser):
+        """
+        Adds QAM modulation-specific options to the standard parser
+        """
+        parser.add_option("", "--excess-bw", type="float", 
default=_def_excess_bw,
+                          help="set RRC excess bandwith factor 
[default=%default] (PSK)")
+        parser.add_option("", "--no-gray-code", dest="gray_code",
+                          action="store_false", default=_def_gray_code,
+                          help="disable gray coding on modulated bits (PSK)")
+    add_options=staticmethod(add_options)
+
+
+    def extract_kwargs_from_options(options):
+        """
+        Given command line options, create dictionary suitable for passing to 
__init__
+        """
+        return modulation_utils.extract_kwargs_from_options(qam8_mod.__init__,
+                                                            ('self', 'fg'), 
options)
+    extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           QAM8 demodulator
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+class qam8_demod(gr.hier_block):
+
+    def __init__(self, fg,
+                 samples_per_symbol=_def_samples_per_symbol,
+                 excess_bw=_def_excess_bw,
+                 costas_alpha=_def_costas_alpha,
+                 gain_mu=_def_gain_mu,
+                 mu=_def_mu,
+                 omega_relative_limit=_def_omega_relative_limit,
+                 gray_code=_def_gray_code,
+                 verbose=_def_verbose,
+                 log=_def_log):
+
+        # do this
+        pass
+    
+    def bits_per_symbol(self=None):   # staticmethod that's also callable on 
an instance
+        return 3
+    bits_per_symbol = staticmethod(bits_per_symbol)      # make it a static 
method.  RTFM
+
+#
+# Add these to the mod/demod registry
+#
+modulation_utils.add_type_1_mod('qam8', qam8_mod)
+#modulation_utils.add_type_1_demod('qam8', qam8_demod)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]