diff options
| author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-02-24 10:39:22 +0100 | 
|---|---|---|
| committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2017-02-24 10:39:22 +0100 | 
| commit | ebe96d69b44d73875f922a7fc59da02695969b00 (patch) | |
| tree | e20362ae9ee188ba4850276042c743892e1d8102 /src | |
| parent | c6ddb4451138005bbf678ee75d6de690a165faa2 (diff) | |
| download | dabmod-ebe96d69b44d73875f922a7fc59da02695969b00.tar.gz dabmod-ebe96d69b44d73875f922a7fc59da02695969b00.tar.bz2 dabmod-ebe96d69b44d73875f922a7fc59da02695969b00.zip  | |
Change phase of TII carriers
This adapts the patch contributed by Piratfm to the next branch
Diffstat (limited to 'src')
| -rw-r--r-- | src/DabMod.cpp | 7 | ||||
| -rw-r--r-- | src/DabModulator.cpp | 5 | ||||
| -rw-r--r-- | src/TII.cpp | 75 | ||||
| -rw-r--r-- | src/TII.h | 49 | 
4 files changed, 94 insertions, 42 deletions
diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 526670d..37db71a 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -588,9 +588,10 @@ int launch_modulator(int argc, char* argv[])  #endif          /* Read TII parameters from config file */ -        tiiConfig.enable  = pt.get("tii.enable", 0); -        tiiConfig.comb    = pt.get("tii.comb", 0); -        tiiConfig.pattern = pt.get("tii.pattern", 0); +        tiiConfig.enable       = pt.get("tii.enable", 0); +        tiiConfig.comb         = pt.get("tii.comb", 0); +        tiiConfig.pattern      = pt.get("tii.pattern", 0); +        tiiConfig.old_variant  = pt.get("tii.old_variant", 0);      }      etiLog.level(info) << "Starting up version " << diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 827b73f..678d175 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -187,9 +187,11 @@ int DabModulator::process(Buffer* dataOut)                  (float)mySpacing * (float)myOutputRate / 2048000.0f, cic_ratio);          shared_ptr<TII> tii; +        shared_ptr<PhaseReference> tiiRef;          try { -            tii = make_shared<TII>(myDabMode, myTiiConfig); +            tii = make_shared<TII>(myDabMode, myTiiConfig, myEtiSource.getFp());              rcs.enrol(tii.get()); +            tiiRef = make_shared<PhaseReference>(mode);          }          catch (TIIError& e) {              etiLog.level(error) << "Could not initialise TII: " << e.what(); @@ -331,6 +333,7 @@ int DabModulator::process(Buffer* dataOut)          myFlowgraph->connect(cifNull, cifSig);          myFlowgraph->connect(cifDiff, cifSig);          if (tii) { +            myFlowgraph->connect(tiiRef, tii);              myFlowgraph->connect(tii, cifSig);          } diff --git a/src/TII.cpp b/src/TII.cpp index 15543d0..6bc3f0d 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -2,7 +2,7 @@     Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty     the Queen in Right of Canada (Communications Research Center Canada) -   Copyright (C) 2015 +   Copyright (C) 2017     Matthias P. Braendli, matthias.braendli@mpb.li      http://opendigitalradio.org @@ -106,22 +106,23 @@ const int pattern_tm1_2_4[][8] = { // {{{      {1,1,1,0,1,0,0,0},      {1,1,1,1,0,0,0,0} }; // }}} -TII::TII(unsigned int dabmode, tii_config_t& tii_config) : -    ModInput(), +TII::TII(unsigned int dabmode, tii_config_t& tii_config, unsigned phase) : +    ModCodec(),      RemoteControllable("tii"),      m_dabmode(dabmode), -    m_conf(tii_config), -    m_insert(true) +    m_conf(tii_config)  {      PDEBUG("TII::TII(%u) @ %p\n", dabmode, this);      RC_ADD_PARAMETER(enable, "enable TII [0-1]");      RC_ADD_PARAMETER(comb, "TII comb number [0-23]");      RC_ADD_PARAMETER(pattern, "TII pattern number [0-69]"); +    RC_ADD_PARAMETER(old_variant, "select old TII variant for old (buggy) receivers [0-1]");      switch (m_dabmode) {          case 1:              m_carriers = 1536; +            m_insert = (phase & 0x40) ? false : true;              if (not(0 <= m_conf.pattern and m_conf.pattern <= 69) ) {                  throw TIIError("TII::TII pattern not valid!"); @@ -129,6 +130,7 @@ TII::TII(unsigned int dabmode, tii_config_t& tii_config) :              break;          case 2:              m_carriers = 384; +            m_insert = (phase & 0x01) ? false : true;              if (not(0 <= m_conf.pattern and m_conf.pattern <= 69) ) {                  throw TIIError("TII::TII pattern not valid!"); @@ -153,8 +155,8 @@ TII::TII(unsigned int dabmode, tii_config_t& tii_config) :          throw TIIError("TII::TII comb not valid!");      } -    m_dataIn.clear(); -    m_dataIn.resize(m_carriers); +    m_enabled_carriers.clear(); +    m_enabled_carriers.resize(m_carriers);      prepare_pattern();  } @@ -169,28 +171,47 @@ const char* TII::name()      // Calculate name on demand because comb and pattern are      // modifiable through RC      std::stringstream ss; -    ss << "TII(comb:" << m_conf.comb << ", pattern:" << m_conf.pattern << ")"; +    ss << "TII(comb:" << m_conf.comb << +        ", pattern:" << m_conf.pattern << +        ", variant:" << (m_conf.old_variant ? "old" : "new") << ")";      m_name = ss.str();      return m_name.c_str();  } -int TII::process(Buffer* dataOut) +int TII::process(Buffer* dataIn, Buffer* dataOut)  {      PDEBUG("TII::process(dataOut: %p)\n",              dataOut); +    if (    (dataIn == NULL) or +            (dataIn->getLength() != m_carriers * sizeof(complexf))) { +        throw TIIError("TII::process input size not valid!"); +    } + +    dataOut->setLength(m_carriers * sizeof(complexf)); +    bzero(dataOut->getData(), dataOut->getLength());      if (m_conf.enable and m_insert) { -        boost::mutex::scoped_lock lock(m_dataIn_mutex); -        dataOut->setData(&m_dataIn[0], m_carriers * sizeof(complexf)); -    } -    else { -        dataOut->setLength(m_carriers * sizeof(complexf)); -        bzero(dataOut->getData(), dataOut->getLength()); +        boost::mutex::scoped_lock lock(m_enabled_carriers_mutex); +        complexf* in = reinterpret_cast<complexf*>(dataIn->getData()); +        complexf* out = reinterpret_cast<complexf*>(dataOut->getData()); + +        for (size_t i = 0; i < m_enabled_carriers.size(); i+=2) { +            //BAD implementation: +            // setting exactly the same phase of the signal for lower adjacent +            // frequency +            if (m_enabled_carriers[i]) { +                out[i] = m_conf.old_variant ? in[i+1] : in[i]; +            } + +            if (m_enabled_carriers[i+1]) { +                out[i+1] = in[i+1]; +            } +        }      } -    // TODO wrong! Must align with frames containing the right data +    // Align with frames containing the right data (when FC.fp is first quarter)      m_insert = not m_insert;      return 1; @@ -199,23 +220,25 @@ int TII::process(Buffer* dataOut)  void TII::enable_carrier(int k) {      int ix = m_carriers/2 + k; -    if (ix < 0 or ix+1 >= (ssize_t)m_dataIn.size()) { +    if (ix < 0 or ix+1 >= (ssize_t)m_enabled_carriers.size()) {          throw TIIError("TII::enable_carrier invalid k!");      } -    // TODO power of the carrier ? -    m_dataIn.at(ix) = 1.0; -    m_dataIn.at(ix+1) = 1.0; // TODO verify if +1 is really correct +    m_enabled_carriers[ix] = true; +    // NULL frequency is never enabled. +    if (ix > 1 and (ix-1 != 768)) { +        m_enabled_carriers[ix-1] = true; +    }  }  void TII::prepare_pattern() {      int comb = m_conf.comb; // Convert from unsigned to signed -    boost::mutex::scoped_lock lock(m_dataIn_mutex); +    boost::mutex::scoped_lock lock(m_enabled_carriers_mutex);      // Clear previous pattern -    for (size_t i = 0; i < m_dataIn.size(); i++) { -        m_dataIn[i] = 0.0; +    for (size_t i = 0; i < m_enabled_carriers.size(); i++) { +        m_enabled_carriers[i] = false;      }      // This could be written more efficiently, but since it is @@ -309,6 +332,9 @@ void TII::set_parameter(const std::string& parameter, const std::string& value)          m_conf.comb = new_comb;          prepare_pattern();      } +    else if (parameter == "old_variant") { +        ss >> m_conf.old_variant; +    }      else {          stringstream ss;          ss << "Parameter '" << parameter << @@ -330,6 +356,9 @@ const std::string TII::get_parameter(const std::string& parameter) const      else if (parameter == "comb") {          ss << m_conf.comb;      } +    else if (parameter == "old_variant") { +        ss << (m_conf.old_variant ? 1 : 0); +    }      else {          ss << "Parameter '" << parameter <<              "' is not exported by controllable " << get_rc_name(); @@ -2,7 +2,7 @@     Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty     the Queen in Right of Canada (Communications Research Center Canada) -   Copyright (C) 2015 +   Copyright (C) 2017     Matthias P. Braendli, matthias.braendli@mpb.li      http://opendigitalradio.org @@ -43,11 +43,33 @@  struct tii_config_t  { -    tii_config_t() : enable(false), comb(0), pattern(0) {} +    tii_config_t() : enable(false), comb(0), pattern(0), old_variant(false) {}      bool enable;      int comb;      int pattern; + +    /* EN 300 401 clause 14.8 describes how to generate the TII signal, and +     * defines z_{m,0,k}: +     * +     * z_{m,0,k} = A_{c,p}(k) e^{j \psi_k} + A_{c,p}(k-1) e^{j \psi{k-1}} +     * +     * What was implemented in the old variant was +     * +     * z_{m,0,k} = A_{c,p}(k) e^{j \psi_k} + A_{c,p}(k-1) e^{j \psi{k}} +     *                                                              ^ +     *                                                              | +     *                                                  Wrong phase on the second +     *                                                  carrier of the pair. +     * +     * Correctly implemented decoders ought to be able to decode such a TII, +     * but will not be able to correctly estimate the delay of different +     * transmitters. +     * +     * The option 'old_variant' allows the user to choose between this +     * old incorrect implementation and the new conforming one. +     */ +    bool old_variant;  };  class TIIError : public std::runtime_error { @@ -58,13 +80,15 @@ class TIIError : public std::runtime_error {              std::runtime_error(msg) {}  }; -class TII : public ModInput, public RemoteControllable +class TII : public ModCodec, public RemoteControllable  {      public: -        TII(unsigned int dabmode, tii_config_t& tii_config); +        TII(unsigned int dabmode, tii_config_t& tii_config, unsigned phase);          virtual ~TII(); +        TII(const TII&) = delete; +        TII& operator=(const TII&) = delete; -        int process(Buffer* dataOut); +        int process(Buffer* dataIn, Buffer* dataOut);          const char* name();          /******* REMOTE CONTROL ********/ @@ -74,13 +98,12 @@ class TII : public ModInput, public RemoteControllable          virtual const std::string get_parameter(                  const std::string& parameter) const; -      protected: -        // Fill m_dataIn with the correct carriers for the pattern/comb +        // Fill m_enabled_carriers with the correct carriers for the pattern/comb          // combination          void prepare_pattern(void); -        // prerequisites: calling thread must hold m_dataIn mutex +        // prerequisites: calling thread must hold m_enabled_carriers mutex          void enable_carrier(int k);          // Configuration settings @@ -96,14 +119,10 @@ class TII : public ModInput, public RemoteControllable          std::string m_name; -        // m_dataIn is read by modulator thread, and written +        // m_enabled_carriers is read by modulator thread, and written          // to by RC thread. -        mutable boost::mutex m_dataIn_mutex; -        std::vector<std::complex<float> > m_dataIn; - -    private: -        TII(const TII&); -        TII& operator=(const TII&); +        mutable boost::mutex m_enabled_carriers_mutex; +        std::vector<bool> m_enabled_carriers;  };  | 
