From 5ee6b828debbd60e03aff805bfd80e2030715a6f Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@ettus.com>
Date: Tue, 31 Aug 2021 11:49:51 +0200
Subject: uhd: math: Replace wrap-frequency math with a single function

In multiple places in the UHD code, we were doing the same calculation
for a wrapped frequency (wrap it into the first Nyquist zone). This math
was using boost::math, too. Instead of editing every instance, we create
a new function, uhd::math::wrap_frequency(), and replace all of its
separate implementations with this function. The new function also no
longer relies on boost::math::sign.
---
 host/lib/usrp/usrp1/codec_ctrl.cpp | 17 ++++++-----------
 host/lib/usrp/usrp1/io_impl.cpp    | 13 ++++++++-----
 2 files changed, 14 insertions(+), 16 deletions(-)

(limited to 'host/lib/usrp/usrp1')

diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp
index 413caaf67..c5268b3c4 100644
--- a/host/lib/usrp/usrp1/codec_ctrl.cpp
+++ b/host/lib/usrp/usrp1/codec_ctrl.cpp
@@ -12,13 +12,13 @@
 #include <uhd/utils/algorithm.hpp>
 #include <uhd/utils/byteswap.hpp>
 #include <uhd/utils/log.hpp>
+#include <uhd/utils/math.hpp>
 #include <uhd/utils/safe_call.hpp>
 #include <uhdlib/utils/narrow.hpp>
-#include <cstdint>
 #include <boost/assign/list_of.hpp>
 #include <boost/format.hpp>
-#include <boost/math/special_functions/sign.hpp>
 #include <cmath>
+#include <cstdint>
 #include <iomanip>
 #include <tuple>
 
@@ -380,15 +380,10 @@ double usrp1_codec_ctrl_impl::fine_tune(double codec_rate, double target_freq)
 
 void usrp1_codec_ctrl_impl::set_duc_freq(double freq, double rate)
 {
-    double codec_rate = rate * 2;
-
-    // correct for outside of rate (wrap around)
-    freq = std::fmod(freq, rate);
-    if (std::abs(freq) > rate / 2.0)
-        freq -= boost::math::sign(freq) * rate;
-
-    double coarse_freq = coarse_tune(codec_rate, freq);
-    double fine_freq   = fine_tune(codec_rate / 4, freq - coarse_freq);
+    const double codec_rate  = rate * 2;
+    freq                     = uhd::math::wrap_frequency(freq, rate);
+    const double coarse_freq = coarse_tune(codec_rate, freq);
+    const double fine_freq   = fine_tune(codec_rate / 4, freq - coarse_freq);
 
     UHD_LOGGER_DEBUG("USRP1") << "ad9862 tuning result:"
                               << "   requested:   " << freq
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index 5d7b4a77b..713dc4c77 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -14,10 +14,10 @@
 #include "../../transport/super_send_packet_handler.hpp"
 #include <uhd/transport/bounded_buffer.hpp>
 #include <uhd/utils/log.hpp>
+#include <uhd/utils/math.hpp>
 #include <uhd/utils/safe_call.hpp>
 #include <uhd/utils/tasks.hpp>
 #include <boost/format.hpp>
-#include <boost/math/special_functions/sign.hpp>
 #include <boost/thread/thread.hpp>
 #include <atomic>
 #include <chrono>
@@ -582,10 +582,13 @@ void usrp1_impl::update_rates(void)
 
 double usrp1_impl::update_rx_dsp_freq(const size_t dspno, const double freq_)
 {
-    // correct for outside of rate (wrap around)
-    double freq = std::fmod(freq_, _master_clock_rate);
-    if (std::abs(freq) > _master_clock_rate / 2.0)
-        freq -= boost::math::sign(freq) * _master_clock_rate;
+    // Note: The calculation of freq and freq_word could be done by
+    // get_freq_and_freq_word(), which has implemented this algorithm for all
+    // other USRPs.
+    // We'll not refactor this because it's ancient code, but note that
+    // get_freq_and_freq_word() fixes a numerical overflow issue that is not
+    // fixed here.
+    const double freq = uhd::math::wrap_frequency(freq_, _master_clock_rate);
 
     // calculate the freq register word (signed)
     UHD_ASSERT_THROW(std::abs(freq) <= _master_clock_rate / 2.0);
-- 
cgit v1.2.3