summaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-11-11 12:23:38 -0800
committerJosh Blum <josh@joshknows.com>2010-11-11 12:23:38 -0800
commit5da1e3e2d683eecce1f0e888d90caef40661e98e (patch)
tree3d3975e2b71da80835d4e1b5aed02cbeb1489661 /host/include
parent314efb09459582b39ea2985bd8f9beba703076e4 (diff)
parent06e2e1e02fdc93eb00f6cf0d532ffc2943feaf06 (diff)
downloaduhd-5da1e3e2d683eecce1f0e888d90caef40661e98e.tar.gz
uhd-5da1e3e2d683eecce1f0e888d90caef40661e98e.tar.bz2
uhd-5da1e3e2d683eecce1f0e888d90caef40661e98e.zip
Merge branch 'ranges'
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/types/CMakeLists.txt1
-rw-r--r--host/include/uhd/types/dict.ipp11
-rw-r--r--host/include/uhd/types/ranges.hpp89
-rw-r--r--host/include/uhd/types/ranges.ipp168
-rw-r--r--host/include/uhd/usrp/mimo_usrp.hpp2
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);
}
/***********************************************************************