diff --git a/include/elen90089/constellation_decoder_cf.h b/include/elen90089/constellation_decoder_cf.h
index 779e6ae624a2c99815969dc8bbfed2100fc81b7c..bb2c50b4e347799c6fd77609da78035e381e0d6d 100644
--- a/include/elen90089/constellation_decoder_cf.h
+++ b/include/elen90089/constellation_decoder_cf.h
@@ -35,7 +35,7 @@ namespace elen90089 {
  * constellation, e.g., the bps. If a length tag name is provided, the value
  * of this tag will be scaled by the current bps.
  */
-class ELEN90089_API constellation_decoder_cf : virtual public gr::sync_interpolator
+class ELEN90089_API constellation_decoder_cf : virtual public gr::block
 {
 public:
     typedef std::shared_ptr<constellation_decoder_cf> sptr;
diff --git a/lib/constellation_decoder_cf_impl.cc b/lib/constellation_decoder_cf_impl.cc
index dc22feea4eb440888965189110706cc196313754..b410fcd65fcd9b19a8435fa0655275722ddc4743 100644
--- a/lib/constellation_decoder_cf_impl.cc
+++ b/lib/constellation_decoder_cf_impl.cc
@@ -23,14 +23,13 @@ constellation_decoder_cf::sptr constellation_decoder_cf::make(int bps,
 constellation_decoder_cf_impl::constellation_decoder_cf_impl(int bps,
                                                              bool soft_decisions,
                                                              const std::string& length_tag_name)
-    : gr::sync_interpolator("constellation_decoder_cf",
-                            gr::io_signature::make(1, 1, sizeof(gr_complex)),
-                            gr::io_signature::make(1, 1, sizeof(float)),
-                            bps),
+    : gr::block("constellation_decoder_cf",
+                gr::io_signature::make(1, 1, sizeof(gr_complex)),
+                gr::io_signature::make(1, 1, sizeof(float))),
       d_soft_decisions(soft_decisions),
-      d_length_tag_key(pmt::PMT_NIL),
-      d_bps_new(-1)
+      d_length_tag_key(pmt::PMT_NIL)
 {
+    set_bps(bps);
     if(!length_tag_name.empty()) {
         d_length_tag_key = pmt::intern(length_tag_name);
     }
@@ -53,12 +52,13 @@ constellation_decoder_cf_impl::~constellation_decoder_cf_impl() { }
 
 int constellation_decoder_cf_impl::bps() const 
 {
-    return interpolation();
+    return d_bps;
 }
 
 void constellation_decoder_cf_impl::set_bps(int bps)
 {
-    set_interpolation(bps);
+    assert(bps > 0 && bps < 5);
+    d_bps = bps;
 }
 
 bool constellation_decoder_cf_impl::soft_decisions() const 
@@ -71,75 +71,81 @@ void constellation_decoder_cf_impl::set_soft_decisions(bool soft_decisions)
     d_soft_decisions = soft_decisions;
 }
 
-int constellation_decoder_cf_impl::work(int noutput_items,
-                                        gr_vector_const_void_star &input_items,
-                                        gr_vector_void_star &output_items)
+void constellation_decoder_cf_impl::forecast(int noutput_items,
+                                             gr_vector_int &ninput_items_required)
+{
+    ninput_items_required[0] = noutput_items/d_bps;
+}
+
+int constellation_decoder_cf_impl::general_work(int noutput_items,
+                                                gr_vector_int &ninput_items,
+                                                gr_vector_const_void_star &input_items,
+                                                gr_vector_void_star &output_items)
 {
     auto in = static_cast<const gr_complex*>(input_items[0]);
-    auto out = static_cast<float*>(output_items[0]);
-    
-    // update bps from last time as needed
-    if (d_bps_new > 0) {
-        set_interpolation(d_bps_new);
-        d_bps_new = -1;
-    }
-    int bps = interpolation();
-    int nin = noutput_items / bps;
- 
+    auto out = static_cast<float*>(output_items[0]);    
+    int nin = std::min(ninput_items[0], noutput_items/d_bps);
+
     // get bps tags in window
     std::vector<gr::tag_t> tags;
     get_tags_in_window(tags, 0, 0, nin, pmt::mp("bps"));
 
     // look for change in bps in this window
+    int bps_new = -1;
     int nread = nitems_read(0);
     for(gr::tag_t tag : tags) {
         int value = pmt::to_long(tag.value);
-        assert(value > 0 && value < 5);
-        if(value != bps) {
-            d_bps_new = value;
+        if(value != d_bps) {
+            bps_new = value;
             nin = tag.offset - nread;
             break;
         }
     }
     tags.clear();
-   
+
     // decoding with current constellation
-    digital::constellation_sptr constel = d_constel[bps];
+    digital::constellation_sptr constel = d_constel[d_bps];
     if (d_soft_decisions) {
         std::vector<float> bits;
         for(int i = 0; i < nin; i++) {
             bits = constel->soft_decision_maker(in[i]);
             for (size_t j = 0; j < bits.size(); j++) {
-                out[bps*i + j] = bits[j];
+                out[d_bps*i + j] = bits[j];
             }
         }
     } else { // hard decisions
         for(int i = 0; i < nin; i++) {
             int bits = constel->decision_maker(&in[i]);
-            for (size_t j = 0; j < bps; j++) {
-                int bit = 0x1 & (bits >> (bps - j - 1));
-                out[bps*i + j] = (float)bit;
+            for (size_t j = 0; j < d_bps; j++) {
+                int bit = 0x1 & (bits >> (d_bps - j - 1));
+                out[d_bps*i + j] = (float)bit;
             }
         }
     }
+    int nout = d_bps*nin;
 
     // manually propagate tags in window to safely handle changes in 
     // interpolation rate (bps)
     get_tags_in_window(tags, 0, 0, nin);
     int nwritten = nitems_written(0);
     for(gr::tag_t tag : tags) {
-        int offset = bps*(tag.offset - nread) + nwritten;
+        int offset = d_bps*(tag.offset - nread) + nwritten;
 
         pmt::pmt_t value = tag.value;
         if(tag.key == d_length_tag_key) {
             int length = pmt::to_long(value);
-            value = pmt::from_long(bps*length);
+            value = pmt::from_long(d_bps*length);
         }
 
         add_item_tag(0, offset, tag.key, value, tag.srcid);
     }
 
-    return bps*nin;
+    consume_each(nin);
+
+    if(bps_new > 0)
+        set_bps(bps_new);
+
+    return nout;
 }
 
 } /* namespace elen90089 */
diff --git a/lib/constellation_decoder_cf_impl.h b/lib/constellation_decoder_cf_impl.h
index 7c8d93aaa63dad2ae3109406c473cd4b73b9b327..da6809338ecfa38fdaf478de52337b2ed3218671 100644
--- a/lib/constellation_decoder_cf_impl.h
+++ b/lib/constellation_decoder_cf_impl.h
@@ -18,10 +18,10 @@ namespace elen90089 {
 class constellation_decoder_cf_impl : public constellation_decoder_cf
 {
 private:
+    int d_bps;
     bool d_soft_decisions;
     pmt::pmt_t d_length_tag_key;
     
-    int d_bps_new;
     std::map<int, digital::constellation_sptr> d_constel;
 
 public:
@@ -39,9 +39,13 @@ public:
 
     void set_soft_decisions(bool soft_decisions) override;
 
-    int work(int noutput_items,
-             gr_vector_const_void_star &input_items,
-             gr_vector_void_star &output_items);
+    void forecast(int noutput_items,
+                  gr_vector_int &ninput_items_required);
+
+    int general_work(int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items);
 };
 
 } // namespace elen90089
diff --git a/lib/symbol_mapper_c_impl.cc b/lib/symbol_mapper_c_impl.cc
index 7a8956b2ba408b47088fd962a380e96e5e4aba64..86298b3bcd671d98caae23eeaaeb72205b5dd5ec 100644
--- a/lib/symbol_mapper_c_impl.cc
+++ b/lib/symbol_mapper_c_impl.cc
@@ -45,7 +45,7 @@ symbol_mapper_c_impl::symbol_mapper_c_impl(constel_t constel_header,
     d_qpsk = digital::constellation_calcdist::make(
         {gr_complex(-1, -1), gr_complex( 1, -1),
          gr_complex(-1,  1), gr_complex( 1,  1)}, // constel
-        {0x0, 0x2, 0x3, 0x1},                     // pre_diff_code
+        {0x0, 0x1, 0x2, 0x3},                     // pre_diff_code
         4,                                        // rotational_symmetry
         1,                                        // dimensionality
         digital::constellation::POWER_NORMALIZATION);
diff --git a/python/bindings/constellation_decoder_cf_python.cc b/python/bindings/constellation_decoder_cf_python.cc
index 77684fd5dcecdd71682e5a4e8d58789aae9de293..84a6456ba91ba752c3cffb57269d32808b2ce9ef 100644
--- a/python/bindings/constellation_decoder_cf_python.cc
+++ b/python/bindings/constellation_decoder_cf_python.cc
@@ -14,7 +14,7 @@
 /* BINDTOOL_GEN_AUTOMATIC(0)                                                       */
 /* BINDTOOL_USE_PYGCCXML(0)                                                        */
 /* BINDTOOL_HEADER_FILE(constellation_decoder_cf.h)                                */
-/* BINDTOOL_HEADER_FILE_HASH(6676402190669fcc53daed62a6ba41cc)                     */
+/* BINDTOOL_HEADER_FILE_HASH(f6872219a4fd76e21292843d4b70e2d7)                     */
 /***********************************************************************************/
 
 #include <pybind11/complex.h>
@@ -32,14 +32,15 @@ void bind_constellation_decoder_cf(py::module& m)
     using constellation_decoder_cf = ::gr::elen90089::constellation_decoder_cf;
 
     py::class_<constellation_decoder_cf,
-               gr::sync_interpolator,
+               gr::block,
+               gr::basic_block,
                std::shared_ptr<constellation_decoder_cf>>(m, "constellation_decoder_cf", D(constellation_decoder_cf))
 
         .def(py::init(&constellation_decoder_cf::make),
              py::arg("bps"),
              py::arg("soft_decisions") = true,
              py::arg("length_tag_name") = "",
-             D(constellation_decoder_cf,make))
+             D(constellation_decoder_cf, make))
 
         .def("bps",
              &constellation_decoder_cf::bps,