diff options
Diffstat (limited to 'host/include')
-rw-r--r-- | host/include/uhd/types/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/include/uhd/types/dict.ipp | 11 | ||||
-rw-r--r-- | host/include/uhd/types/ranges.hpp | 89 | ||||
-rw-r--r-- | host/include/uhd/types/ranges.ipp | 168 | ||||
-rw-r--r-- | host/include/uhd/usrp/mimo_usrp.hpp | 2 |
5 files changed, 253 insertions, 18 deletions
diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index a96976b5e..1d2c0c41c 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -25,6 +25,7 @@ INSTALL(FILES mac_addr.hpp metadata.hpp otw_type.hpp + ranges.ipp ranges.hpp serial.hpp stream_cmd.hpp diff --git a/host/include/uhd/types/dict.ipp b/host/include/uhd/types/dict.ipp index ba05d5272..f037d7988 100644 --- a/host/include/uhd/types/dict.ipp +++ b/host/include/uhd/types/dict.ipp @@ -46,12 +46,11 @@ namespace uhd{ /* NOP */ } - template <typename Key, typename Val> - template <typename InputIterator> - dict<Key, Val>::dict(InputIterator first, InputIterator last){ - for(InputIterator it = first; it != last; it++){ - _map.push_back(*it); - } + template <typename Key, typename Val> template <typename InputIterator> + dict<Key, Val>::dict(InputIterator first, InputIterator last): + _map(first, last) + { + /* NOP */ } template <typename Key, typename Val> diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp index a2057d1c8..206c64726 100644 --- a/host/include/uhd/types/ranges.hpp +++ b/host/include/uhd/types/ranges.hpp @@ -19,28 +19,95 @@ #define INCLUDED_UHD_TYPES_RANGES_HPP #include <uhd/config.hpp> +#include <uhd/utils/pimpl.hpp> +#include <vector> namespace uhd{ /*! - * The gain range struct describes possible gain settings. - * The mimumum gain, maximum gain, and step size are in dB. + * A range object describes a set of discrete values of the form: + * y = start + step*n, where n is an integer between 0 and (stop - start)/step */ - struct UHD_API gain_range_t{ - float min, max, step; - gain_range_t(float min = 0.0, float max = 0.0, float step = 0.0); + template <typename T> class range_t{ + public: + /*! + * Create a range from a single value. + * The step size will be taken as zero. + * \param value the only possible value in this range + */ + range_t(const T &value = T(0)); + + /*! + * Create a range from a full set of values. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range + */ + range_t(const T &start, const T &stop, const T &step = T(0)); + + //! Get the start value for this range. + const T start(void) const; + + //! Get the stop value for this range. + const T stop(void) const; + + //! Get the step value for this range. + const T step(void) const; + + private: UHD_PIMPL_DECL(impl) _impl; }; /*! - * The frequency range struct describes possible frequency settings. - * Because tuning is very granular (sub-Hz), step size is not listed. - * The mimumum frequency and maximum frequency are in Hz. + * A meta-range object holds a list of individual ranges. */ - struct UHD_API freq_range_t{ - double min, max; - freq_range_t(double min = 0.0, double max = 0.0); + template <typename T> struct meta_range_t : std::vector<range_t<T> >{ + + //! A default constructor for an empty meta-range + meta_range_t(void); + + /*! + * Input iterator constructor: + * Makes boost::assign::list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template <typename InputIterator> + meta_range_t(InputIterator first, InputIterator last); + + /*! + * A convenience constructor for a single range. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range + */ + meta_range_t(const T &start, const T &stop, const T &step = T(0)); + + //! Get the overall start value for this meta-range. + const T start(void) const; + + //! Get the overall stop value for this meta-range. + const T stop(void) const; + + //! Get the overall step value for this meta-range. + const T step(void) const; + + /*! + * Clip the target value to a possible range value. + * \param value the value to clip to this range + * \param clip_step if true, clip to steps as well + * \return a value that is in one of the ranges + */ + const T clip(const T &value, bool clip_step = false) const; + }; + typedef meta_range_t<float> gain_range_t; + typedef meta_range_t<double> freq_range_t; + } //namespace uhd +#include <uhd/types/ranges.ipp> + #endif /* INCLUDED_UHD_TYPES_RANGES_HPP */ diff --git a/host/include/uhd/types/ranges.ipp b/host/include/uhd/types/ranges.ipp new file mode 100644 index 000000000..8b602a24d --- /dev/null +++ b/host/include/uhd/types/ranges.ipp @@ -0,0 +1,168 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_RANGES_IPP +#define INCLUDED_UHD_TYPES_RANGES_IPP + +#include <boost/math/special_functions/round.hpp> +#include <boost/foreach.hpp> +#include <algorithm> +#include <stdexcept> +#include <iostream> + +namespace uhd{ + + /******************************************************************* + * range_t implementation code + ******************************************************************/ + template <typename T> struct range_t<T>::impl{ + impl(const T &start, const T &stop, const T &step): + start(start), stop(stop), step(step) + { + /* NOP */ + } + const T start, stop, step; + }; + + template <typename T> range_t<T>::range_t(const T &value): + _impl(UHD_PIMPL_MAKE(impl, (value, value, T(0)))) + { + /* NOP */ + } + + template <typename T> range_t<T>::range_t( + const T &start, const T &stop, const T &step + ): + _impl(UHD_PIMPL_MAKE(impl, (start, stop, step))) + { + if (stop < start){ + throw std::invalid_argument("cannot make range where stop < start"); + } + } + + template <typename T> const T range_t<T>::start(void) const{ + return _impl->start; + } + + template <typename T> const T range_t<T>::stop(void) const{ + return _impl->stop; + } + + template <typename T> const T range_t<T>::step(void) const{ + return _impl->step; + } + + /******************************************************************* + * meta_range_t implementation code + ******************************************************************/ + + namespace /*anon*/{ + template <typename T> inline + void check_meta_range_monotonic(const meta_range_t<T> &mr){ + if (mr.empty()){ + throw std::runtime_error("meta-range cannot be empty"); + } + for (size_t i = 1; i < mr.size(); i++){ + if (mr.at(i).start() < mr.at(i-1).stop()){ + throw std::runtime_error("meta-range is not monotonic"); + } + } + } + } //namespace /*anon*/ + + + template <typename T> meta_range_t<T>::meta_range_t(void){ + /* NOP */ + } + + template <typename T> template <typename InputIterator> + meta_range_t<T>::meta_range_t( + InputIterator first, InputIterator last + ): + std::vector<range_t<T> >(first, last) + { + /* NOP */ + } + + template <typename T> meta_range_t<T>::meta_range_t( + const T &start, const T &stop, const T &step + ): + std::vector<range_t<T> > (1, range_t<T>(start, stop, step)) + { + /* NOP */ + } + + template <typename T> const T meta_range_t<T>::start(void) const{ + check_meta_range_monotonic(*this); + T min_start = this->front().start(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + min_start = std::min(min_start, r.start()); + } + return min_start; + } + + template <typename T> const T meta_range_t<T>::stop(void) const{ + check_meta_range_monotonic(*this); + T max_stop = this->front().stop(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + max_stop = std::max(max_stop, r.stop()); + } + return max_stop; + } + + template <typename T> const T meta_range_t<T>::step(void) const{ + check_meta_range_monotonic(*this); + std::vector<T> non_zero_steps; + range_t<T> last = this->front(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + //steps at each range + if (r.step() > T(0)) non_zero_steps.push_back(r.step()); + //and steps in-between ranges + T ibtw_step = r.start() - last.stop(); + if (ibtw_step > T(0)) non_zero_steps.push_back(ibtw_step); + //store ref to last + last = r; + } + if (non_zero_steps.empty()) return T(0); //all zero steps, its zero... + return *std::min_element(non_zero_steps.begin(), non_zero_steps.end()); + } + + template <typename T> const T meta_range_t<T>::clip( + const T &value, bool clip_step + ) const{ + check_meta_range_monotonic(*this); + T last_stop = this->front().stop(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + //in-between ranges, clip to nearest + if (value < r.start()){ + return (std::abs(value - r.start()) < std::abs(value - last_stop))? + r.start() : last_stop; + } + //in this range, clip here + if (value <= r.stop()){ + if (not clip_step or r.step() == T(0)) return value; + return boost::math::round((value - r.start())/r.step())*r.step() + r.start(); + } + //continue on to the next range + last_stop = r.stop(); + } + return last_stop; + } + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_RANGES_IPP */ diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp index a2092f04f..977559b0b 100644 --- a/host/include/uhd/usrp/mimo_usrp.hpp +++ b/host/include/uhd/usrp/mimo_usrp.hpp @@ -200,7 +200,7 @@ namespace uhd{ namespace usrp{ namespace /*anon*/{ static inline freq_range_t add_dsp_shift(const freq_range_t &range, wax::obj dsp){ double codec_rate = dsp[DSP_PROP_CODEC_RATE].as<double>(); - return freq_range_t(range.min - codec_rate/2.0, range.max + codec_rate/2.0); + return freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0); } /*********************************************************************** |